X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Rakka%2FPage.hs;h=24f037bc4a31096cd9f7c60b527062fce3dda1e9;hb=bea735cd0409bc96e2962ee9e97cae5f7bf4d585;hp=16835d5aafd79e247d227e557e93d77eb267e0ea;hpb=0447be1b59496ca4266226ed52d264009cf41899;p=Rakka.git diff --git a/Rakka/Page.hs b/Rakka/Page.hs index 16835d5..24f037b 100644 --- a/Rakka/Page.hs +++ b/Rakka/Page.hs @@ -1,3 +1,8 @@ +-- -*- coding: utf-8 -*- +{-# LANGUAGE + Arrows + , UnicodeSyntax + #-} module Rakka.Page ( PageName , Page(..) @@ -20,40 +25,38 @@ module Rakka.Page , mkObjectURI , mkFragmentURI , mkAuxiliaryURI + , mkFeedURI , mkRakkaURI , xmlizePage , parseXmlizedPage ) where - -import qualified Codec.Binary.Base64 as B64 -import qualified Codec.Binary.UTF8.String as UTF8 -import Control.Arrow -import Control.Arrow.ArrowIO -import Control.Arrow.ArrowList +import Control.Arrow +import qualified Data.Ascii as Ascii +import qualified Data.Text as T import qualified Data.ByteString.Lazy as Lazy (ByteString) import qualified Data.ByteString.Lazy as L hiding (ByteString) -import Data.Char -import Data.Map (Map) +import qualified Data.ByteString.Lazy.Char8 as L8 hiding (ByteString) +import Data.Char +import Data.Map (Map) import qualified Data.Map as M -import Data.Maybe -import Data.Time -import Network.HTTP.Lucu hiding (redirect) -import Network.URI hiding (fragment) -import Rakka.Utils -import Rakka.W3CDateTime -import Subversion.Types -import System.FilePath.Posix -import Text.XML.HXT.Arrow.XmlArrow -import Text.XML.HXT.Arrow.XmlNodeSet -import Text.XML.HXT.DOM.TypeDefs - +import Data.Time +import qualified Data.Time.W3C as W3C +import Network.HTTP.Lucu hiding (redirect) +import Network.URI hiding (fragment) +import Rakka.Utils +import Subversion.Types +import System.FilePath.Posix +import Text.XML.HXT.DOM.TypeDefs +import Text.XML.HXT.XPath +import Text.XML.HXT.Arrow.XmlArrow +import Prelude.Unicode -type PageName = String +type PageName = T.Text -type LanguageTag = String -- See RFC 3066: http://www.ietf.org/rfc/rfc3066.txt -type LanguageName = String -- i.e. "日本語" +type LanguageTag = Ascii -- See RFC 3066: http://www.ietf.org/rfc/rfc3066.txt +type LanguageName = T.Text -- i.e. "日本語" data Page @@ -130,15 +133,6 @@ encodePageName = escapeURIString isSafeChar . UTF8.encodeString . fixPageName fixPageName = (\ (x:xs) -> toUpper x : xs) . map (\ c -> if c == ' ' then '_' else c) -isSafeChar :: Char -> Bool -isSafeChar c - | c == '/' = True - | isReserved c = False - | c > ' ' && c <= '~' = True - | otherwise = False - - --- URI unescape して UTF-8 から decode する。 decodePageName :: FilePath -> PageName decodePageName = UTF8.decodeString . unEscapeString @@ -150,14 +144,14 @@ encodeFragment = escapeURIString isSafeChar . UTF8.encodeString mkPageURI :: URI -> PageName -> URI mkPageURI baseURI name = baseURI { - uriPath = foldl () "/" [uriPath baseURI, encodePageName name ++ ".html"] + uriPath = uriPath baseURI encodePageName name <.> "html" } mkPageFragmentURI :: URI -> PageName -> String -> URI mkPageFragmentURI baseURI name fragment = baseURI { - uriPath = foldl () "/" [uriPath baseURI, encodePageName name ++ ".html"] + uriPath = uriPath baseURI encodePageName name <.> "html" , uriFragment = ('#' : encodeFragment fragment) } @@ -181,6 +175,13 @@ mkAuxiliaryURI baseURI basePath name } +mkFeedURI :: URI -> PageName -> URI +mkFeedURI baseURI name + = baseURI { + uriPath = uriPath baseURI encodePageName name <.> "rdf" + } + + mkRakkaURI :: PageName -> URI mkRakkaURI name = URI { uriScheme = "rakka:" @@ -240,8 +241,9 @@ xmlizePage += ( eelem "page" += sattr "name" (redirName page) += sattr "redirect" (redirDest page) + += sattr "isLocked" (yesOrNo $ redirIsLocked page) += sattr "revision" (show $ redirRevision page) - += sattr "lastModified" (formatW3CDateTime lastMod) + += sattr "lastModified" (W3C.format lastMod) )) -<< () xmlizeEntity :: (ArrowXml a, ArrowChoice a, ArrowIO a) => a Page XmlTree @@ -267,7 +269,7 @@ xmlizePage += sattr "isLocked" (yesOrNo $ entityIsLocked page) += sattr "isBinary" (yesOrNo $ entityIsBinary page) += sattr "revision" (show $ entityRevision page) - += sattr "lastModified" (formatW3CDateTime lastMod) + += sattr "lastModified" (W3C.format lastMod) += ( case entitySummary page of Just s -> eelem "summary" += txt s Nothing -> none @@ -283,7 +285,7 @@ xmlizePage ) += ( if entityIsBinary page then ( eelem "binaryData" - += txt (B64.encode $ L.unpack $ entityContent page) + += txt (L8.unpack $ encodeBase64LBS $ entityContent page) ) else ( eelem "textData" @@ -343,8 +345,8 @@ parseEntity let (isBinary, content) = case (textData, binaryData) of - (Just text, Nothing ) -> (False, L.pack $ UTF8.encode text ) - (Nothing , Just binary) -> (True , L.pack $ B64.decode binary) + (Just text, Nothing ) -> (False, L.pack $ UTF8.encode text) + (Nothing , Just binary) -> (True , L8.pack $ decodeBase64 $ dropWhitespace binary) _ -> error "one of textData or binaryData is required" mimeType = if isBinary then @@ -371,6 +373,9 @@ parseEntity , entityUpdateInfo = updateInfo } +dropWhitespace :: String -> String +{-# INLINE dropWhitespace #-} +dropWhitespace = filter ((¬) ∘ isSpace) parseUpdateInfo :: (ArrowXml a, ArrowChoice a) => a XmlTree UpdateInfo parseUpdateInfo @@ -382,5 +387,3 @@ parseUpdateInfo uiOldRevision = oldRev , uiOldName = oldName } - - \ No newline at end of file