]> gitweb @ CieloNegro.org - Rakka.git/commitdiff
implemented binary file preview/upload
authorpho <pho@cielonegro.org>
Sun, 6 Jan 2008 08:55:52 +0000 (17:55 +0900)
committerpho <pho@cielonegro.org>
Sun, 6 Jan 2008 08:55:52 +0000 (17:55 +0900)
darcs-hash:20080106085552-62b54-560383c5e58f1408c5f8365f9ab160cf4d14116d.gz

Rakka.cabal
Rakka/Page.hs
Rakka/Resource/Render.hs
js/Makefile
js/base64.js [new file with mode: 0644]
js/editPage.js
js/localFile.js [new file with mode: 0644]

index afca2002dff8e3b48e209d37c8fc03ea48ce1d2e..f6da68d152cb404cbe9e103e4d257958f4cd18c9 100644 (file)
@@ -29,9 +29,11 @@ Extra-Source-Files:
     configure.ac
     js/Makefile
     js/base.js
+    js/base64.js
     js/editPage.js
     js/jquery-1.2.1.js
     js/jquery-dom.js
+    js/localFile.js
     js/screen.js
 
 Flag build-test-suite
index d6a93696725b6e280423564e0d1b59ddfde32b60..f701d92078e757a0ada421d7d54f33e8d4d2b609 100644 (file)
@@ -339,8 +339,7 @@ parseEntity
     = proc (name, tree)
     -> do updateInfo <- maybeA parseUpdateInfo -< tree
 
-          mimeType <- (getXPathTreesInDoc "/page/@type/text()" >>> getText
-                       >>> arr read) -< tree
+          mimeTypeStr <- withDefault (getXPathTreesInDoc "/page/@type/text()" >>> getText) "" -< tree
 
           lang     <- maybeA (getXPathTreesInDoc "/page/@lang/text()"     >>> getText) -< tree
           fileName <- maybeA (getXPathTreesInDoc "/page/@filename/text()" >>> getText) -< tree
@@ -372,6 +371,14 @@ parseEntity
                       (Just text, Nothing    ) -> (False, L.pack $ UTF8.encode text )
                       (Nothing  , Just binary) -> (True , L.pack $ B64.decode binary)
                       _                        -> error "one of textData or binaryData is required"
+              mimeType
+                  =  if isBinary then
+                         if null mimeTypeStr then
+                             guessMIMEType content
+                         else
+                             read mimeTypeStr
+                     else
+                         read mimeTypeStr
 
           returnA -< Entity {
                         entityName       = name
index 670edd88273aef65dade948c1a6627a5d04fa73d..778ca2114dba15d8945674510b1c70abc70c3a55 100644 (file)
@@ -3,23 +3,19 @@ module Rakka.Resource.Render
     )
     where
 
+import qualified Codec.Binary.Base64 as B64
 import           Control.Arrow
 import           Control.Arrow.ArrowIO
 import           Control.Arrow.ArrowList
 import           Control.Monad.Trans
-import qualified Codec.Binary.UTF8.String as UTF8
-import qualified Data.ByteString.Lazy as Lazy
-import qualified Data.Map as M
+import qualified Data.ByteString.Lazy as Lazy (ByteString, pack)
+import qualified Data.ByteString.Lazy.Char8 as L8 hiding (ByteString)
 import           Network.HTTP.Lucu
 import           Network.HTTP.Lucu.Utils
 import           Rakka.Environment
 import           Rakka.Page
 import           Rakka.Utils
-import           Rakka.Wiki
 import           Rakka.Wiki.Engine
-import           Rakka.Wiki.Parser
-import           Rakka.Wiki.Interpreter
-import           Text.ParserCombinators.Parsec
 import           Text.XML.HXT.Arrow.Namespace
 import           Text.XML.HXT.Arrow.WriteDocument
 import           Text.XML.HXT.Arrow.XmlArrow
@@ -66,12 +62,18 @@ resRender env
 -}
 handleRender :: Environment -> PageName -> Resource ()
 handleRender env name
-    = do bin    <- inputLBS defaultLimit
+    = do entity <- inputLBS defaultLimit
          cTypeM <- getContentType
 
-         let cType = case cTypeM of
-                       Just t  -> t
-                       Nothing -> guessMIMEType bin
+         let (bin, cType) = case cTypeM of
+                              Just (MIMEType "application" "x-rakka-base64-stream" _)
+                                  -> let b = Lazy.pack $ B64.decode $ L8.unpack entity
+                                     in
+                                       (b, guessMIMEType b)
+                              Just t
+                                  -> (entity, t)
+                              Nothing
+                                  -> (entity, guessMIMEType entity)
 
          setContentType $ read "text/xml"
          [xmlStr] <- liftIO $ runX ( setErrorMsgHandler False fail
index effc48b0c16e51d44a2c781deb7bd51e9db5d67b..a399e6f2fe63a2ecaf33292c430a0cd71c8b516b 100644 (file)
@@ -5,7 +5,9 @@ SOURCES = \
        $(JQUERY_SOURCE) \
        jquery-dom.js \
        base.js \
+       base64.js \
        editPage.js \
+       localFile.js \
        redirection.js \
        screen.js \
        $(NULL)
diff --git a/js/base64.js b/js/base64.js
new file mode 100644 (file)
index 0000000..f4775ae
--- /dev/null
@@ -0,0 +1,41 @@
+(function () {
+
+    var b64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+    Rakka.encodeBase64 = function (src) {
+        var len = src.length;
+        var i   = 0;
+        var ret = "";
+
+        while (i < len) {
+            var c1 = src.charCodeAt(i++);
+            
+            if (i == len) {
+                ret += b64Chars.charAt(c1 >> 2);
+                ret += b64Chars.charAt((c1 & 0x03) << 4);
+                ret += "==";
+            }
+            else {
+                var c2 = src.charCodeAt(i++);
+
+                if (i == len) {
+                    ret += b64Chars.charAt(c1 >> 2);
+                    ret += b64Chars.charAt(((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4));
+                    ret += b64Chars.charAt((c2 & 0x0F) << 2);
+                    ret += "=";
+                }
+                else {
+                    var c3 = src.charCodeAt(i++);
+
+                    ret += b64Chars.charAt(c1 >> 2);
+                    ret += b64Chars.charAt(((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4));
+                    ret += b64Chars.charAt(((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6));
+                    ret += b64Chars.charAt(c3 & 0x3F);
+                }
+            }
+        }
+
+        return ret;
+    };
+
+})();
\ No newline at end of file
index 2dd99510f2080d3d1ec60860344b3e66deee1eb0..a8869fb91b6b01552be1b2341873e92475c24654 100644 (file)
@@ -253,6 +253,30 @@ Rakka.previewRakkaPage = function (pageName, source) {
             Rakka.showPreview(resultDoc);
         },
         error      : function (req) {
+            Rakka.hideWaitingMessage();
+            alert("Error: " + req.status + " " + req.statusText);
+        }
+    });
+};
+
+Rakka.previewBinaryPage = function (pageName, path) {
+    Rakka.displayWaitingMessage("Loading... please wait.");
+
+    /* Firefox でバイナリを送らうとすると 0x00 の位置で切れてしまふ。*/
+    var bin = Rakka.loadLocalBinaryFile(path);
+    var url = Rakka.baseURI + "render/" + encodeURI(pageName);
+    $.ajax({
+        type       : "POST",
+        url        : url,
+        contentType: "application/x-rakka-base64-stream",
+        data       : Rakka.encodeBase64(bin),
+        processData: false,
+        success    : function (resultDoc) {
+            Rakka.hideWaitingMessage();
+            Rakka.showPreview(resultDoc);
+        },
+        error      : function (req) {
+            Rakka.hideWaitingMessage();
             alert("Error: " + req.status + " " + req.statusText);
         }
     });
@@ -323,6 +347,58 @@ Rakka.submitTextPage = function (pageName, oldRevision, givenPageName, mimeType,
     });
 };
 
+Rakka.submitBinaryPage = function (pageName, oldRevision, givenPageName, path) {
+    var doc = document.implementation.createDocument(
+        "http://cielonegro.org/schema/Rakka/Page/1.0", "page", null);
+
+    var page = doc.documentElement;
+
+    if (oldRevision != null) {
+        // ページ書換時
+        var updateInfo = doc.createElement("updateInfo");
+        updateInfo.setAttribute("oldRevision", oldRevision);
+
+        if (pageName != givenPageName) {
+            var move = doc.createElement("move");
+            move.setAttribute("from", pageName);
+            updateInfo.appendChild(move);
+        }
+
+        page.appendChild(updateInfo);
+    }
+
+    page.setAttribute("type", "");
+
+    var bin = Rakka.loadLocalBinaryFile(path);
+    var b64 = Rakka.encodeBase64(bin);
+
+    var binaryData = doc.createElement("binaryData");
+    binaryData.appendChild(
+        doc.createTextNode(b64));
+
+    page.appendChild(binaryData);
+
+    Rakka.displayWaitingMessage("Submitting... please wait.");
+
+    var url = Rakka.baseURI + encodeURI(givenPageName);
+    $.ajax({
+        type       : "PUT",
+        url        : url,
+        contentType: "text/xml",
+        data       : doc,
+        processData: false,
+        success    : function () {
+            window.location.replace(url);
+        },
+        error      : function (req) {
+            Rakka.hideWaitingMessage();
+            
+            var $area = Rakka.switchScreen();
+            $area.text("Error: " + req.status + " " + req.statusText);
+        }
+    });
+};
+
 Rakka.submitRedirection = function (pageName, oldRevision, givenPageName, destination) {
     var doc = document.implementation.createDocument(
         "http://cielonegro.org/schema/Rakka/Page/1.0", "page", null);
diff --git a/js/localFile.js b/js/localFile.js
new file mode 100644 (file)
index 0000000..1a6fbfe
--- /dev/null
@@ -0,0 +1,44 @@
+(function () {
+
+    Rakka.canAccessLocalFile = function () {
+        return $.browser.mozilla;
+    };
+
+    var loadBin_mozilla = function (path) {
+        try {
+            netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+        }
+        catch (e) {
+            alert("Permission to read local file was denied. " +
+                  "Open about:config and check that " +
+                  "signed.applets.codebase_principal_support is set to true.");
+        }
+
+        var localFile
+            = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+        localFile.initWithPath(path);
+
+        var stream
+            = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
+        stream.init(localFile, 0x01, 00004, null);
+
+        var bstream
+            = Components.classes["@mozilla.org/network/buffered-input-stream;1"].getService();
+        bstream.QueryInterface(Components.interfaces.nsIBufferedInputStream);
+        bstream.init(stream, 1000);
+        bstream.QueryInterface(Components.interfaces.nsIInputStream);
+
+        var binary
+            = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
+        binary.setInputStream(stream);
+
+        return binary.readBytes(binary.available());
+    };
+
+    Rakka.loadLocalBinaryFile = function (path) {
+        if ($.browser.mozilla) {
+            return loadBin_mozilla(path);
+        }
+    };
+    
+})();
\ No newline at end of file