hunk ./Main.hs 1 -{-# LANGUAGE CPP #-} -import Control.Monad -import Data.List -import Data.Maybe -import Network -import Network.HTTP.Lucu -import OpenSSL -import Rakka.Environment -import Rakka.Resource.CheckAuth -import Rakka.Resource.DumpRepos -import Rakka.Resource.Index -import Rakka.Resource.JavaScript -import Rakka.Resource.PageEntity -import Rakka.Resource.Object -import Rakka.Resource.Render -import Rakka.Resource.Search -import Rakka.Resource.SystemConfig --- import Rakka.Resource.TrackBack -import Rakka.Resource.Users -import Rakka.Storage -import Subversion -import System.Console.GetOpt -import System.Directory -import System.Environment -import System.Exit -import System.IO -import System.Log.Handler.Simple -import System.Log.Logger -import System.Posix.Files -import System.Posix.Types -import System.Posix.User - - -logger :: String -logger = "Main" - - -data CmdOpt - = OptPortNum PortNumber - | OptLSDir FilePath - | OptUserName String - | OptGroupName String - | OptLogLevel Priority - | OptDisableStderrLog - | OptRebuildIndex - | OptHelp - deriving (Eq, Show) - - -defaultPort :: PortNumber -defaultPort = toEnum 8080 - -defaultLocalStateDir :: FilePath -defaultLocalStateDir = LOCALSTATEDIR -- replaced by CPP - -defaultUserName :: String -defaultUserName = "daemon" - -defaultGroupName :: String -defaultGroupName = "daemon" - - -defaultLogLevel :: Priority -defaultLogLevel = NOTICE - - -options :: [OptDescr CmdOpt] -options = [ Option ['p'] ["port"] - (ReqArg (OptPortNum . toEnum . read) "NUM") - ("Port number to listen. (default: " ++ show defaultPort ++ ")") - - , Option ['d'] ["localstatedir"] - (ReqArg OptLSDir "DIR") - ("Path to the database directory. (default: " ++ defaultLocalStateDir ++ ")") - - , Option ['u'] ["user"] - (ReqArg OptUserName "USER") - ("Which user to setuid. (default: " ++ defaultUserName ++ ")") - - , Option ['g'] ["group"] - (ReqArg OptGroupName "GROUP") - ("Which user to setgid. (default: " ++ defaultGroupName ++ ")") - - , Option ['l'] ["log-level"] - (ReqArg (OptLogLevel . read) "LEVEL") - ("The lowest log level to show. (default: " ++ show defaultLogLevel ++ ")") - - , Option [] ["disable-stderr-log"] - (NoArg OptDisableStderrLog) - "Disable logging to stderr." - - , Option [] ["rebuild-index"] - (NoArg OptRebuildIndex) - "Rebuild the index database." - - , Option ['h'] ["help"] - (NoArg OptHelp) - "Print this message." - ] - - -printUsage :: IO () -printUsage = do putStrLn "Usage:" - putStrLn " rakka [OPTIONS...]" - putStrLn "" - putStr $ usageInfo "Options:" options - - -main :: IO () -main = withOpenSSL $ - withSubversion $ - do (opts, nonOpts, errors) <- return . getOpt Permute options =<< getArgs - - unless (null errors) - $ do mapM_ putStr errors - exitWith $ ExitFailure 1 - - when (any (\ x -> x == OptHelp) opts) - $ do printUsage - exitWith ExitSuccess - - unless (null nonOpts) - $ do printUsage - exitWith $ ExitFailure 1 - - portNum <- getPortNum opts - uid <- getUserID opts - gid <- getGroupID opts - lsdir <- getLocalStateDir opts - - createLocalStateDir lsdir uid gid - - setGroupID gid - setUserID uid - - setupLogger opts - env <- setupEnv lsdir portNum - - rebuildIndexIfRequested env opts - - infoM logger ("Listening to " ++ show portNum ++ "/tcp...") - runHttpd (envLucuConf env) (resTree env) [fallbackPageEntity env] - - -resTree :: Environment -> ResTree -resTree env - = mkResTree [ ([] , resIndex env) - , (["checkAuth" ], resCheckAuth env) - , (["dumpRepos" ], resDumpRepos env) - , (["js" ], javaScript ) - , (["object" ], resObject env) - , (["render" ], resRender env) - , (["search" ], resSearch env) - , (["search.html" ], resSearch env) - , (["search.xml" ], resSearch env) - , (["systemConfig"], resSystemConfig env) - -- , (["trackback" ], resTrackBack env) - , (["users" ], resUsers env) - ] - - -getPortNum :: [CmdOpt] -> IO PortNumber -getPortNum opts - = do let xs = mapMaybe (\ x -> case x of - OptPortNum n -> Just n - _ -> Nothing) opts - case xs of - [] -> return defaultPort - (x:[]) -> return x - _ -> error "too many --port options." - - -getUserID :: [CmdOpt] -> IO UserID -getUserID opts - = do let xs = mapMaybe (\ x -> case x of - OptUserName n -> Just n - _ -> Nothing) opts - name = case xs of - [] -> defaultUserName - (x:[]) -> x - _ -> error "too many --user options." - - userEnt <- getUserEntryForName name - return $ userID userEnt - - -getGroupID :: [CmdOpt] -> IO GroupID -getGroupID opts - = do let xs = mapMaybe (\ x -> case x of - OptGroupName n -> Just n - _ -> Nothing) opts - name = case xs of - [] -> defaultGroupName - (x:[]) -> x - _ -> error "too many --group options." - - groupEnt <- getGroupEntryForName name - return $ groupID groupEnt - - -getLocalStateDir :: [CmdOpt] -> IO FilePath -getLocalStateDir opts - = do let xs = mapMaybe (\ x -> case x of - OptLSDir n -> Just n - _ -> Nothing) opts - path = case xs of - [] -> defaultLocalStateDir - (x:[]) -> x - _ -> error "too many --localstatedir options." - - return path - - -setupLogger :: [CmdOpt] -> IO () -setupLogger opts - = do let disableStderrLog = find (== OptDisableStderrLog) opts /= Nothing - logHandlers = if disableStderrLog then - [] - else - [verboseStreamHandler stderr DEBUG] - logLevel = fromMaybe defaultLogLevel - $ do OptLogLevel l <- find (\ x -> case x of - OptLogLevel _ -> True - _ -> False) opts - return l - - logHandlers' <- sequence logHandlers - updateGlobalLogger rootLoggerName (setHandlers logHandlers' . setLevel logLevel) - - -createLocalStateDir :: FilePath -> UserID -> GroupID -> IO () -createLocalStateDir path uid gid - = do createDirectoryIfMissing True path - setOwnerAndGroup path uid gid - - -rebuildIndexIfRequested :: Environment -> [CmdOpt] -> IO () -rebuildIndexIfRequested env opts - = do let rebuild = isJust $ find (\ x -> case x of - OptRebuildIndex -> True - _ -> False) opts - when rebuild - $ rebuildIndex (envStorage env) rmfile ./Main.hs hunk ./Makefile 1 -CABAL_FILE = Rakka.cabal -GHC = ghc -EXECUTABLE = sudo ./dist/build/rakka/rakka -p 8989 -l DEBUG -#EXECUTABLE = sudo ./dist/build/rakka/rakka -p 8989 -l DEBUG +RTS -S -A60M -RTS -#EXECUTABLE = sudo ./dist/build/rakka/rakka -p 8989 -l DEBUG +RTS -p -RTS - -build: dist/setup-config Setup - $(MAKE) -C js $@ - ./Setup build - -run: build - $(EXECUTABLE) - -rebuild-index: build - $(EXECUTABLE) --rebuild-index - -dist/setup-config: $(CABAL_FILE) configure Setup Rakka.buildinfo.in - ./Setup configure --disable-optimization -fbuild-test-suite -# ./Setup configure -fhardest-optimization -# ./Setup configure -fenable-profiling - -configure: configure.ac - autoconf - -Setup: Setup.hs - $(GHC) --make Setup - -clean: - $(MAKE) -C js $@ - rm -rf dist Setup Setup.o Setup.hi - find . -name '*~' -exec rm -f {} \; - -install: build - sudo ./Setup install - -test: build - ./Setup test - -sdist: Setup - ./Setup sdist - -.PHONY: build run clean install doc sdist test rmfile ./Makefile hunk ./Rakka/Attachment.hs 1 -module Rakka.Attachment - ( Attachment(..) - ) - where - -import Control.Arrow -import Control.Arrow.ArrowList -import System.IO.Unsafe -import Text.XML.HXT.Arrow.ReadDocument -import Text.XML.HXT.Arrow.WriteDocument -import Text.XML.HXT.Arrow.XmlArrow -import Text.XML.HXT.Arrow.XmlIOStateArrow -import Text.XML.HXT.DOM.TypeDefs -import Text.XML.HXT.DOM.XmlKeywords - - -class Attachment t where - serializeToXmlTree :: (ArrowChoice a, ArrowXml a) => a t XmlTree - deserializeFromXmlTree :: (ArrowChoice a, ArrowXml a) => a XmlTree t - - serializeToString :: t -> String - serializeToString attachment - = unsafePerformIO $ - do [xmlStr] <- runX ( setErrorMsgHandler False fail - >>> - constA attachment - >>> - serializeToXmlTree - >>> - writeDocumentToString [ (a_indent, v_1) ] - ) - return xmlStr - - deserializeFromString :: String -> t - deserializeFromString source - = unsafePerformIO $ - do [ret] <- runX ( setErrorMsgHandler False fail - >>> - readString [ (a_validate , v_0) - , (a_check_namespaces , v_1) - , (a_remove_whitespace, v_0) - ] source - >>> - deserializeFromXmlTree - ) - return ret rmfile ./Rakka/Attachment.hs hunk ./Rakka/Authorization.hs 1 -module Rakka.Authorization - ( AuthDB - , mkAuthDB - , isValidPair - , getUserList - , addUser - , delUser - ) - where - -import qualified Codec.Binary.UTF8.String as UTF8 -import Control.Concurrent.STM -import Control.Monad -import Control.Monad.Trans -import qualified Data.ByteString as B -import Data.Map (Map) -import qualified Data.Map as M hiding (Map) -import Data.Maybe -import OpenSSL.EVP.Base64 -import OpenSSL.EVP.Digest -import Rakka.SystemConfig -import System.Directory -import System.FilePath - - -data AuthDB - = AuthDB { - adbFilePath :: !FilePath - , adbUserMap :: !(TVar UserMap) - } - - -type UserMap = Map String String - - -mkAuthDB :: FilePath -> IO AuthDB -mkAuthDB lsdir - = do let path = lsdir "authDB" - m <- newTVarIO =<< loadUserMap path - return AuthDB { - adbFilePath = path - , adbUserMap = m - } - - -isValidPair :: MonadIO m => AuthDB -> String -> String -> m Bool -isValidPair adb name pass - = liftIO $ do sha1 <- return . fromJust =<< getDigestByName "SHA1" - let hash = digestBS sha1 $ B.pack $ UTF8.encode pass - atomically $ do m <- readTVar (adbUserMap adb) - return (M.lookup name m == Just hash) - - -getUserList :: MonadIO m => AuthDB -> m [String] -getUserList adb - = liftIO $ - atomically $ - do m <- readTVar (adbUserMap adb) - return (M.keys m) - - -addUser :: MonadIO m => AuthDB -> String -> String -> m () -addUser adb name pass - = liftIO $ - do sha1 <- return . fromJust =<< getDigestByName "SHA1" - let hash = digestBS sha1 $ B.pack $ UTF8.encode pass - m <- atomically $ do m <- readTVar (adbUserMap adb) - let m' = M.insert name hash m - writeTVar (adbUserMap adb) m' - return m' - saveUserMap (adbFilePath adb) m - - -delUser :: MonadIO m => AuthDB -> String -> m () -delUser adb name - = liftIO $ - do m <- atomically $ do m <- readTVar (adbUserMap adb) - let m' = M.delete name m - writeTVar (adbUserMap adb) m' - return m' - saveUserMap (adbFilePath adb) m - - -loadUserMap :: FilePath -> IO UserMap -loadUserMap path - = do exist <- doesFileExist path - m <- if exist then - liftM (M.fromList . map decodePair . fromJust . deserializeStringPairs) - (readFile path) - else - return M.empty - sha1 <- return . fromJust =<< getDigestByName "SHA1" - return (initMap sha1 m) - where - decodePair :: (String, String) -> (String, String) - decodePair (name, b64Hash) - = (UTF8.decodeString name, decodeBase64 b64Hash) - - initMap :: Digest -> UserMap -> UserMap - initMap sha1 m - | M.null m = let name = "root" - hash = digest sha1 "" - in - M.singleton name hash - | otherwise = m - - -saveUserMap :: FilePath -> UserMap -> IO () -saveUserMap path m - = writeFile path $ serializeStringPairs $ map encodePair $ M.toList m - where - encodePair :: (String, String) -> (String, String) - encodePair (name, hash) - = (UTF8.encodeString name, encodeBase64 hash) rmfile ./Rakka/Authorization.hs hunk ./Rakka/Environment.hs 1 -module Rakka.Environment - ( Environment(..) - , InterpTable - , setupEnv - ) - where - -import Control.Arrow -import Control.Arrow.ArrowList -import qualified Data.Map as M -import Network -import qualified Network.HTTP.Lucu.Config as LC -import Rakka.Authorization -import Rakka.Page -import Rakka.Storage -import Rakka.SystemConfig -import Rakka.Wiki.Engine -import Rakka.Wiki.Interpreter -import qualified Rakka.Wiki.Interpreter.Base as Base -import qualified Rakka.Wiki.Interpreter.Image as Image -import qualified Rakka.Wiki.Interpreter.PageList as PageList ---import qualified Rakka.Wiki.Interpreter.Trackback as Trackback -import qualified Rakka.Wiki.Interpreter.Outline as Outline -import Subversion.Repository -import System.Directory -import System.FilePath -import System.Log.Logger -import Text.HyperEstraier -import Text.XML.HXT.Arrow.XmlIOStateArrow - - -logger :: String -logger = "Rakka.Environment" - - -data Environment = Environment { - envLocalStateDir :: !FilePath - , envLucuConf :: !LC.Config - , envRepository :: !Repository - , envSysConf :: !SystemConfig - , envStorage :: !Storage - , envInterpTable :: !InterpTable - , envAuthDB :: !AuthDB - } - - -setupEnv :: FilePath -> PortNumber -> IO Environment -setupEnv lsdir portNum - = do let lucuConf = LC.defaultConfig { - LC.cnfServerPort = PortNumber portNum - } - reposPath = lsdir "repos" - interpTable = mkInterpTable - - reposExist <- doesDirectoryExist reposPath - repos <- if reposExist then - do debugM logger ("Found a subversion repository on " ++ reposPath) - openRepository reposPath - else - do noticeM logger ("Creating a subversion repository on " ++ reposPath) - createRepository reposPath [] [] - sysConf <- mkSystemConfig lucuConf repos - storage <- mkStorage lsdir repos (makeDraft' interpTable) - authDB <- mkAuthDB lsdir - - return Environment { - envLocalStateDir = lsdir - , envLucuConf = lucuConf - , envRepository = repos - , envSysConf = sysConf - , envStorage = storage - , envInterpTable = interpTable - , envAuthDB = authDB - } - where - makeDraft' :: InterpTable -> Page -> IO Document - makeDraft' interpTable page - = do [doc] <- runX ( setErrorMsgHandler False fail - >>> - constA page - >>> - xmlizePage - >>> - makeDraft interpTable - ) - return doc - - -mkInterpTable :: InterpTable -mkInterpTable = listToTable $ - foldl (++) [] [ Base.interpreters - , Image.interpreters - , PageList.interpreters - --, Trackback.interpreters - , Outline.interpreters - ] - where - listToTable :: [Interpreter] -> InterpTable - listToTable xs - = M.fromList [ (commandName x, x) | x <- xs ] rmfile ./Rakka/Environment.hs hunk ./Rakka/Page.hs 1 -module Rakka.Page - ( PageName - , Page(..) - , UpdateInfo(..) - , LanguageTag - , LanguageName - - , isRedirect - , isEntity - - , pageName - , pageUpdateInfo - , pageRevision - - , encodePageName - , decodePageName - - , mkPageURI - , mkPageFragmentURI - , mkObjectURI - , mkFragmentURI - , mkAuxiliaryURI - , mkFeedURI - , mkRakkaURI - - , xmlizePage - , parseXmlizedPage - ) - where - -import qualified Codec.Binary.UTF8.String as UTF8 -import qualified Data.ByteString.Lazy as Lazy (ByteString) -import qualified Data.ByteString.Lazy as L hiding (ByteString) -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.Time -import Network.HTTP.Lucu hiding (redirect) -import Network.URI hiding (fragment) -import OpenSSL.EVP.Base64 -import Rakka.Utils -import Rakka.W3CDateTime -import Subversion.Types -import System.FilePath.Posix -import Text.XML.HXT.Arrow -import Text.XML.HXT.XPath - - -type PageName = String - -type LanguageTag = String -- See RFC 3066: http://www.ietf.org/rfc/rfc3066.txt -type LanguageName = String -- i.e. "日本語" - - -data Page - = Redirection { - redirName :: !PageName - , redirDest :: !PageName - , redirIsLocked :: !Bool - , redirRevision :: RevNum - , redirLastMod :: UTCTime - , redirUpdateInfo :: Maybe UpdateInfo - } - | Entity { - entityName :: !PageName - , entityType :: !MIMEType - , entityLanguage :: !(Maybe LanguageTag) - , entityIsTheme :: !Bool -- text/css 以外では無意味 - , entityIsFeed :: !Bool -- text/x-rakka 以外では無意味 - , entityIsLocked :: !Bool - , entityIsBinary :: !Bool - , entityRevision :: RevNum - , entityLastMod :: UTCTime - , entitySummary :: !(Maybe String) - , entityOtherLang :: !(Map LanguageTag PageName) - , entityContent :: !Lazy.ByteString - , entityUpdateInfo :: Maybe UpdateInfo - } - deriving (Show, Eq) - - -data UpdateInfo - = UpdateInfo { - uiOldRevision :: !RevNum - , uiOldName :: !(Maybe PageName) - } - deriving (Show, Eq) - - -isRedirect :: Page -> Bool -isRedirect (Redirection _ _ _ _ _ _) = True -isRedirect _ = False - - -isEntity :: Page -> Bool -isEntity (Entity _ _ _ _ _ _ _ _ _ _ _ _ _) = True -isEntity _ = False - - -pageName :: Page -> PageName -pageName p - | isRedirect p = redirName p - | isEntity p = entityName p - | otherwise = error "neither redirection nor entity" - - -pageUpdateInfo :: Page -> Maybe UpdateInfo -pageUpdateInfo p - | isRedirect p = redirUpdateInfo p - | isEntity p = entityUpdateInfo p - | otherwise = error "neither redirection nor entity" - - -pageRevision :: Page -> RevNum -pageRevision p - | isRedirect p = redirRevision p - | isEntity p = entityRevision p - | otherwise = error "neither redirection nor entity" - - --- UTF-8 に encode してから 0x20 - 0x7E の範圍を除いて URI escape する。 -encodePageName :: PageName -> FilePath -encodePageName = escapeURIString isSafeChar . UTF8.encodeString . fixPageName - where - fixPageName :: PageName -> PageName - fixPageName = (\ (x:xs) -> toUpper x : xs) . map (\ c -> if c == ' ' then '_' else c) - - -decodePageName :: FilePath -> PageName -decodePageName = UTF8.decodeString . unEscapeString - - -encodeFragment :: String -> String -encodeFragment = escapeURIString isSafeChar . UTF8.encodeString - - -mkPageURI :: URI -> PageName -> URI -mkPageURI baseURI name - = baseURI { - uriPath = uriPath baseURI encodePageName name <.> "html" - } - - -mkPageFragmentURI :: URI -> PageName -> String -> URI -mkPageFragmentURI baseURI name fragment - = baseURI { - uriPath = uriPath baseURI encodePageName name <.> "html" - , uriFragment = ('#' : encodeFragment fragment) - } - - -mkFragmentURI :: String -> URI -mkFragmentURI fragment - = nullURI { - uriFragment = ('#' : encodeFragment fragment) - } - - -mkObjectURI :: URI -> PageName -> URI -mkObjectURI baseURI name - = mkAuxiliaryURI baseURI ["object"] name - - -mkAuxiliaryURI :: URI -> [String] -> PageName -> URI -mkAuxiliaryURI baseURI basePath name - = baseURI { - uriPath = foldl () "/" ([uriPath baseURI] ++ basePath ++ [encodePageName name]) - } - - -mkFeedURI :: URI -> PageName -> URI -mkFeedURI baseURI name - = baseURI { - uriPath = uriPath baseURI encodePageName name <.> "rdf" - } - - -mkRakkaURI :: PageName -> URI -mkRakkaURI name = URI { - uriScheme = "rakka:" - , uriAuthority = Nothing - , uriPath = encodePageName name - , uriQuery = "" - , uriFragment = "" - } - - -{- - - - - blah blah... - -- 存在しない場合もある - - -- 存在しない場合もある - - - - - - blah blah... - - - SKJaHKS8JK/DH8KS43JDK2aKKaSFLLS... - - - - --} -xmlizePage :: (ArrowXml a, ArrowChoice a, ArrowIO a) => a Page XmlTree -xmlizePage - = proc page - -> if isRedirect page then - xmlizeRedirection -< page - else - xmlizeEntity -< page - where - xmlizeRedirection :: (ArrowXml a, ArrowChoice a, ArrowIO a) => a Page XmlTree - xmlizeRedirection - = proc page - -> do lastMod <- arrIO (utcToLocalZonedTime . redirLastMod) -< page - ( eelem "/" - += ( eelem "page" - += sattr "name" (redirName page) - += sattr "redirect" (redirDest page) - += sattr "isLocked" (yesOrNo $ redirIsLocked page) - += sattr "revision" (show $ redirRevision page) - += sattr "lastModified" (formatW3CDateTime lastMod) - )) -<< () - - xmlizeEntity :: (ArrowXml a, ArrowChoice a, ArrowIO a) => a Page XmlTree - xmlizeEntity - = proc page - -> do lastMod <- arrIO (utcToLocalZonedTime . entityLastMod) -< page - ( eelem "/" - += ( eelem "page" - += sattr "name" (pageName page) - += sattr "type" (show $ entityType page) - += ( case entityLanguage page of - Just x -> sattr "lang" x - Nothing -> none - ) - += ( case entityType page of - MIMEType "text" "css" _ - -> sattr "isTheme" (yesOrNo $ entityIsTheme page) - MIMEType "text" "x-rakka" _ - -> sattr "isFeed" (yesOrNo $ entityIsFeed page) - _ - -> none - ) - += sattr "isLocked" (yesOrNo $ entityIsLocked page) - += sattr "isBinary" (yesOrNo $ entityIsBinary page) - += sattr "revision" (show $ entityRevision page) - += sattr "lastModified" (formatW3CDateTime lastMod) - += ( case entitySummary page of - Just s -> eelem "summary" += txt s - Nothing -> none - ) - += ( if M.null (entityOtherLang page) then - none - else - selem "otherLang" - [ eelem "link" - += sattr "lang" lang - += sattr "page" name - | (lang, name) <- M.toList (entityOtherLang page) ] - ) - += ( if entityIsBinary page then - ( eelem "binaryData" - += txt (L8.unpack $ encodeBase64LBS $ entityContent page) - ) - else - ( eelem "textData" - += txt (UTF8.decode $ L.unpack $ entityContent page) - ) - ) - )) -<< () - - -parseXmlizedPage :: (ArrowXml a, ArrowChoice a) => a (PageName, XmlTree) Page -parseXmlizedPage - = proc (name, tree) - -> do updateInfo <- maybeA parseUpdateInfo -< tree - redirect <- maybeA (getXPathTreesInDoc "/page/@redirect/text()" >>> getText) -< tree - isLocked <- (withDefault (getXPathTreesInDoc "/page/@isLocked/text()" >>> getText) "no" - >>> parseYesOrNo) -< tree - case redirect of - Nothing -> parseEntity -< (name, tree) - Just dest -> returnA -< (Redirection { - redirName = name - , redirDest = dest - , redirIsLocked = isLocked - , redirRevision = undefined - , redirLastMod = undefined - , redirUpdateInfo = updateInfo - }) - - -parseEntity :: (ArrowXml a, ArrowChoice a) => a (PageName, XmlTree) Page -parseEntity - = proc (name, tree) - -> do updateInfo <- maybeA parseUpdateInfo -< tree - - mimeTypeStr <- withDefault (getXPathTreesInDoc "/page/@type/text()" >>> getText) "" -< tree - - lang <- maybeA (getXPathTreesInDoc "/page/@lang/text()" >>> getText) -< tree - - isTheme <- (withDefault (getXPathTreesInDoc "/page/@isTheme/text()" >>> getText) "no" - >>> parseYesOrNo) -< tree - isFeed <- (withDefault (getXPathTreesInDoc "/page/@isFeed/text()" >>> getText) "no" - >>> parseYesOrNo) -< tree - isLocked <- (withDefault (getXPathTreesInDoc "/page/@isLocked/text()" >>> getText) "no" - >>> parseYesOrNo) -< tree - - summary <- (maybeA (getXPathTreesInDoc "/page/summary/text()" - >>> getText - >>> deleteIfEmpty)) -< tree - - otherLang <- listA (getXPathTreesInDoc "/page/otherLang/link" - >>> - (getAttrValue0 "lang" - &&& - getAttrValue0 "page")) -< tree - - textData <- maybeA (getXPathTreesInDoc "/page/textData/text()" >>> getText) -< tree - binaryData <- maybeA (getXPathTreesInDoc "/page/binaryData/text()" >>> getText) -< tree - - let (isBinary, content) - = case (textData, binaryData) of - (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 - if null mimeTypeStr then - guessMIMEType content - else - read mimeTypeStr - else - read mimeTypeStr - - returnA -< Entity { - entityName = name - , entityType = mimeType - , entityLanguage = lang - , entityIsTheme = isTheme - , entityIsFeed = isFeed - , entityIsLocked = isLocked - , entityIsBinary = isBinary - , entityRevision = undefined - , entityLastMod = undefined - , entitySummary = summary - , entityOtherLang = M.fromList otherLang - , entityContent = content - , entityUpdateInfo = updateInfo - } - where - dropWhitespace :: String -> String - dropWhitespace [] = [] - dropWhitespace (x:xs) - | x == ' ' || x == '\t' || x == '\n' - = dropWhitespace xs - | otherwise - = x : dropWhitespace xs - - -parseUpdateInfo :: (ArrowXml a, ArrowChoice a) => a XmlTree UpdateInfo -parseUpdateInfo - = proc tree - -> do uInfo <- getXPathTreesInDoc "/page/updateInfo" -< tree - oldRev <- (getAttrValue0 "oldRevision" >>> arr read) -< uInfo - oldName <- maybeA (getXPathTrees "/updateInfo/move/@from/text()" >>> getText) -< uInfo - returnA -< UpdateInfo { - uiOldRevision = oldRev - , uiOldName = oldName - } - - rmfile ./Rakka/Page.hs hunk ./Rakka/Resource/CheckAuth.hs 1 -module Rakka.Resource.CheckAuth - ( resCheckAuth - ) - where - -import Network.HTTP.Lucu -import Rakka.Environment -import Rakka.Resource - - -resCheckAuth :: Environment -> ResourceDef -resCheckAuth env - = ResourceDef { - resUsesNativeThread = False - , resIsGreedy = False - , resGet - = Just $ - do userID <- getUserID env - case userID of - Just _ -> setStatus NoContent - Nothing -> setStatus Forbidden - , resHead = Nothing - , resPost = Nothing - , resPut = Nothing - , resDelete = Nothing - } rmfile ./Rakka/Resource/CheckAuth.hs hunk ./Rakka/Resource/DumpRepos.hs 1 -module Rakka.Resource.DumpRepos - ( resDumpRepos - ) - where - -import Control.Monad.Trans -import Network.HTTP.Lucu -import Rakka.Environment -import Subversion.Repository - -resDumpRepos :: Environment -> ResourceDef -resDumpRepos env - = ResourceDef { - resUsesNativeThread = False - , resIsGreedy = False - , resGet = Just $ dumpRepos $ envRepository env - , resHead = Nothing - , resPost = Nothing - , resPut = Nothing - , resDelete = Nothing - } - - -dumpRepos :: Repository -> Resource () -dumpRepos repos - = do setContentType $ read "application/octet-stream" - -- FIXME: 最終更新時刻が判るはず。 - dump <- liftIO $ dumpRepository repos Nothing Nothing False True - outputLBS dump rmfile ./Rakka/Resource/DumpRepos.hs hunk ./Rakka/Resource/Index.hs 1 -module Rakka.Resource.Index - ( resIndex - ) - where - -import Network.HTTP.Lucu -import Rakka.Environment -import Rakka.Page -import Rakka.SystemConfig - - -resIndex :: Environment -> ResourceDef -resIndex env - = ResourceDef { - resUsesNativeThread = False - , resIsGreedy = False - , resGet - = Just $ do BaseURI baseURI <- getSysConf (envSysConf env) - DefaultPage name <- getSysConf (envSysConf env) - redirect Found (mkPageURI baseURI name) - , resHead = Nothing - , resPost = Nothing - , resPut = Nothing - , resDelete = Nothing - } - rmfile ./Rakka/Resource/Index.hs hunk ./Rakka/Resource/Object.hs 1 --- -*- Coding: utf-8 -*- -module Rakka.Resource.Object - ( resObject - ) - where - -import Network.HTTP.Lucu -import Network.HTTP.Lucu.Utils -import Rakka.Environment -import Rakka.Page -import Rakka.Storage -import Rakka.SystemConfig - - -resObject :: Environment -> ResourceDef -resObject env - = ResourceDef { - resUsesNativeThread = False - , resIsGreedy = True - , resGet = Just $ getPathInfo >>= handleGet env . toPageName - , resHead = Nothing - , resPost = Nothing - , resPut = Nothing - , resDelete = Nothing - } - where - toPageName :: [String] -> PageName - toPageName = decodePageName . joinWith "/" - - -handleGet :: Environment -> PageName -> Resource () -handleGet env name - = do pageM <- getPage (envStorage env) name Nothing - case pageM of - Nothing -> foundNoEntity Nothing - Just page -> if isEntity page then - handleGetEntity page - else - handleRedirect env page - - -{- - HTTP/1.1 302 Found - Location: http://example.org/object/Destination --} -handleRedirect :: Environment -> Page -> Resource () -handleRedirect env redir - = do BaseURI baseURI <- getSysConf (envSysConf env) - redirect Found (mkObjectURI baseURI $ redirName redir) - - -{- - HTTP/1.1 200 OK - Content-Type: image/png - - ... --} -handleGetEntity :: Page -> Resource () -handleGetEntity page - = do case entityRevision page of - 0 -> foundTimeStamp (entityLastMod page) -- 0 はデフォルトページ - rev -> foundEntity (strongETag $ show rev) (entityLastMod page) - - setContentType (entityType page) - outputLBS (entityContent page) rmfile ./Rakka/Resource/Object.hs hunk ./Rakka/Resource/PageEntity.hs 1 -module Rakka.Resource.PageEntity - ( fallbackPageEntity - ) - where - -import qualified Codec.Binary.UTF8.String as UTF8 -import Control.Monad.Trans -import qualified Data.ByteString.Lazy as L hiding (ByteString) -import Data.Char -import qualified Data.Map as M -import Data.Maybe -import Data.Time -import Network.HTTP.Lucu -import Network.URI hiding (path) -import Rakka.Environment -import Rakka.Page -import Rakka.Resource -import Rakka.Storage -import Rakka.SystemConfig -import Rakka.Utils -import Rakka.W3CDateTime -import Rakka.Wiki.Engine -import System.FilePath.Posix -import Text.HyperEstraier hiding (getText) -import Text.XML.HXT.Arrow -import Text.XML.HXT.XPath - - -fallbackPageEntity :: Environment -> [String] -> IO (Maybe ResourceDef) -fallbackPageEntity env path - | null path = return Nothing - | null $ head path = return Nothing - | isLower $ head $ head path = return Nothing -- 先頭の文字が小文字であってはならない - | otherwise - = return $ Just $ ResourceDef { - resUsesNativeThread = False - , resIsGreedy = True - , resGet = Just $ handleGet env (toPageName path) - , resHead = Nothing - , resPost = Nothing - , resPut = Just $ handlePut env (toPageName path) - , resDelete = Just $ handleDelete env (toPageName path) - } - where - toPageName :: [String] -> PageName - toPageName = decodePageName . dropExtension . joinPath - - -handleGet :: Environment -> PageName -> Resource () -handleGet env name - = do BaseURI baseURI <- getSysConf (envSysConf env) - runIdempotentA baseURI $ proc () - -> do pageM <- getPageA (envStorage env) -< (name, Nothing) - case pageM of - Nothing - -> do items <- getDirContentsA (envStorage env) -< (name, Nothing) - case items of - [] -> handlePageNotFound env -< name - _ -> handleGetPageListing env -< (name, items) - Just page - -> if isEntity page then - handleGetEntity env -< page - else - handleRedirect env -< page - - -{- - HTTP/1.1 302 Found - Location: http://example.org/Destination.html#Redirect:Source --} -handleRedirect :: (ArrowXml a, ArrowIO a) => Environment -> a Page (Resource ()) -handleRedirect env - = proc redir - -> returnA -< do mType <- getEntityType - case mType of - MIMEType "text" "xml" _ - -> do setContentType mType - [resultStr] <- liftIO $ runX ( setErrorMsgHandler False fail - >>> - constA redir - >>> - xmlizePage - >>> - writeDocumentToString [ (a_indent , v_1 ) - , (a_output_encoding, utf8) - , (a_no_xml_pi , v_0 ) ] - ) - output resultStr - - _ -> do BaseURI baseURI <- getSysConf (envSysConf env) - let uri = mkPageFragmentURI - baseURI - (redirDest redir) - ("Redirect:" ++ redirName redir) - redirect Found uri - - -handleGetEntity :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a Page (Resource ()) -handleGetEntity env - = proc page - -> do tree <- xmlizePage -< page - returnA -< outputXmlPage tree [ (MIMEType "application" "xhtml+xml" [], entityToXHTML env) - , (MIMEType "application" "rss+xml" [], entityToRSS env) - ] - - -entityToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree -entityToXHTML env - = proc page - -> do SiteName siteName <- getSysConfA (envSysConf env) -< () - BaseURI baseURI <- getSysConfA (envSysConf env) -< () - StyleSheet styleSheet <- getSysConfA (envSysConf env) -< () - GlobalLock isGLocked <- getSysConfA (envSysConf env) -< () - - name <- (getXPathTreesInDoc "/page/@name/text()" >>> getText) -< page - isLocked <- (getXPathTreesInDoc "/page/@isLocked/text()" >>> getText >>> parseYesOrNo) -< page - - let cssHref = [uriToString id (mkObjectURI baseURI styleSheet) ""] - scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI "js" }) ""] - - pageTitle <- listA (readSubPage env) -< (name, Just page, "PageTitle") - leftSideBar <- listA (readSubPage env) -< (name, Just page, "SideBar/Left") - rightSideBar <- listA (readSubPage env) -< (name, Just page, "SideBar/Right") - pageBody <- listA (makeMainXHTML (envStorage env) (envSysConf env) (envInterpTable env)) -< page - - ( eelem "/" - += ( eelem "html" - += sattr "xmlns" "http://www.w3.org/1999/xhtml" - += ( getXPathTreesInDoc "/page/@lang" - `guards` - qattr (mkQName "xml" "lang" "") - ( getXPathTreesInDoc "/page/@lang/text()" ) - ) - += ( eelem "head" - += ( eelem "title" - += txt siteName - += txt " - " - += getXPathTreesInDoc "/page/@name/text()" - ) - += ( constL cssHref - >>> - eelem "link" - += sattr "rel" "stylesheet" - += sattr "type" "text/css" - += attr "href" (arr id >>> mkText) - ) - += mkFeedList env - += ( constL scriptSrc - >>> - eelem "script" - += sattr "type" "text/javascript" - += attr "src" (arr id >>> mkText) - ) - += ( eelem "script" - += sattr "type" "text/javascript" - += txt ("Rakka.baseURI=\"" ++ uriToString id baseURI "" ++ "\";") - += txt ("Rakka.isLocked=" ++ trueOrFalse isLocked ++ ";") - += txt ("Rakka.isGlobalLocked=" ++ trueOrFalse isGLocked ++ ";") - ) - += mkGlobalJSList env - ) - += ( eelem "body" - += ( eelem "div" - += sattr "class" "header" - ) - += ( eelem "div" - += sattr "class" "center" - += ( eelem "div" - += sattr "class" "title" - += constL pageTitle - ) - += ( eelem "div" - += sattr "class" "body" - += constL pageBody - ) - ) - += ( eelem "div" - += sattr "class" "footer" - ) - += ( eelem "div" - += sattr "class" "left sideBar" - += ( eelem "div" - += sattr "class" "content" - += constL leftSideBar - ) - ) - += ( eelem "div" - += sattr "class" "right sideBar" - += ( eelem "div" - += sattr "class" "content" - += constL rightSideBar - ) - ) - ) - >>> - uniqueNamespacesFromDeclAndQNames - ) ) -<< page - - -entityToRSS :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree -entityToRSS env - = proc page - -> do SiteName siteName <- getSysConfA (envSysConf env) -< () - BaseURI baseURI <- getSysConfA (envSysConf env) -< () - - name <- (getXPathTreesInDoc "/page/@name/text()" >>> getText) -< page - summary <- maybeA (getXPathTreesInDoc "/page/summary/text()" >>> getText) -< page - pages <- makePageLinkList (envStorage env) (envSysConf env) (envInterpTable env) -< page - - ( eelem "/" - += ( eelem "rdf:RDF" - += sattr "xmlns" "http://purl.org/rss/1.0/" - += sattr "xmlns:rdf" "http://www.w3.org/1999/02/22-rdf-syntax-ns#" - += sattr "xmlns:dc" "http://purl.org/dc/elements/1.1/" - += sattr "xmlns:trackback" "http://madskills.com/public/xml/rss/module/trackback/" - += ( eelem "channel" - += sattr "rdf:about" (uriToString id (mkFeedURI baseURI name) "") - += ( eelem "title" - += txt siteName - += txt " - " - += getXPathTreesInDoc "/page/@name/text()" - ) - += ( eelem "link" - += txt (uriToString id baseURI "") - ) - += ( eelem "description" - += txt (case summary of - Nothing -> "RSS Feed for " ++ siteName - Just s -> s) - ) - += ( eelem "items" - += ( eelem "rdf:Seq" - += ( constL pages - >>> - eelem "rdf:li" - += attr "resource" (arr (mkPageURIStr baseURI) >>> mkText) - ) - ) - ) - ) - += ( constL pages - >>> - arr (\ n -> (n, Nothing)) - >>> - getPageA (envStorage env) - >>> - arr fromJust - >>> - eelem "item" - += attr "rdf:about" (arr (mkPageURIStr baseURI . entityName) >>> mkText) - += ( eelem "title" - += (arr entityName >>> mkText) - ) - += ( eelem "link" - += (arr (mkPageURIStr baseURI . entityName) >>> mkText) - ) - += ( arrL (\ p -> case entitySummary p of - Nothing -> [] - Just s -> [s]) - >>> - eelem "description" - += mkText - ) - += ( eelem "dc:date" - += ( arrIO (utcToLocalZonedTime . entityLastMod) - >>> - arr formatW3CDateTime - >>> - mkText - ) - ) - += ( eelem "trackback:ping" - += attr "rdf:resource" (arr (mkTrackbackURIStr baseURI . entityName) >>> mkText) - ) - ) - >>> - uniqueNamespacesFromDeclAndQNames - ) ) -<< page - where - mkPageURIStr :: URI -> PageName -> String - mkPageURIStr baseURI name - = uriToString id (mkPageURI baseURI name) "" - - mkTrackbackURIStr :: URI -> PageName -> String - mkTrackbackURIStr baseURI name - = uriToString id (mkAuxiliaryURI baseURI ["trackback"] name) "" - - -readSubPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) => - Environment - -> a (PageName, Maybe XmlTree, PageName) XmlTree -readSubPage env - = proc (mainPageName, mainPage, subPageName) -> - do langM <- case mainPage of - Nothing - -> returnA -< Nothing - Just p - -> maybeA (getXPathTreesInDoc "/page/@lang/text()" >>> getText) -< p - subPage <- getPageA (envStorage env) >>> arr fromJust -< (subPageName, Nothing) - localSubPage <- case langM of - Nothing - -> returnA -< subPage - Just l - -> localize (envStorage env) -< (l, subPage) - subPageXml <- xmlizePage -< localSubPage - subXHTML <- makeSubXHTML (envStorage env) (envSysConf env) (envInterpTable env) - -< (Just mainPageName, mainPage, subPageXml) - returnA -< subXHTML - where - localize :: (ArrowChoice a, ArrowIO a) => Storage -> a (LanguageTag, Page) Page - localize sto - = proc (lang, origPage) - -> do let otherLang = entityOtherLang origPage - localName = M.lookup lang otherLang - case localName of - Nothing - -> returnA -< origPage - Just ln - -> do localPage <- getPageA sto -< (ln, Nothing) - returnA -< case localPage of - Nothing -> origPage - Just p -> p - - -{- - - - - --} -handleGetPageListing :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a (PageName, [PageName]) (Resource ()) -handleGetPageListing env - = proc (dir, items) - -> do tree <- ( eelem "/" - += ( eelem "pageListing" - += attr "path" (arr fst >>> mkText) - += ( arrL snd - >>> - ( eelem "page" - += attr "name" (arr id >>> mkText) - ) - ) - ) - ) -< (dir, items) - returnA -< outputXmlPage' tree (pageListingToXHTML env) -- FIXME: rss 對應 - - -pageListingToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree -pageListingToXHTML env - = proc pageListing - -> do SiteName siteName <- getSysConfA (envSysConf env) -< () - BaseURI baseURI <- getSysConfA (envSysConf env) -< () - StyleSheet styleSheet <- getSysConfA (envSysConf env) -< () - GlobalLock isGLocked <- getSysConfA (envSysConf env) -< () - - name <- (getXPathTreesInDoc "/pageListing/@path/text()" >>> getText) -< pageListing - - let cssHref = [uriToString id (mkObjectURI baseURI styleSheet) ""] - scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI "js" }) ""] - - pageTitle <- listA (readSubPage env) -< (name, Nothing, "PageTitle") - leftSideBar <- listA (readSubPage env) -< (name, Nothing, "SideBar/Left") - rightSideBar <- listA (readSubPage env) -< (name, Nothing, "SideBar/Right") - - ( eelem "/" - += ( eelem "html" - += sattr "xmlns" "http://www.w3.org/1999/xhtml" - += ( eelem "head" - += ( eelem "title" - += txt siteName - += txt " - " - += getXPathTreesInDoc "/pageListing/@path/text()" - ) - += ( constL cssHref - >>> - eelem "link" - += sattr "rel" "stylesheet" - += sattr "type" "text/css" - += attr "href" (arr id >>> mkText) - ) - += mkFeedList env - += ( constL scriptSrc - >>> - eelem "script" - += sattr "type" "text/javascript" - += attr "src" (arr id >>> mkText) - ) - += ( eelem "script" - += sattr "type" "text/javascript" - += txt ("Rakka.baseURI = \"" ++ uriToString id baseURI "" ++ "\";") - += txt ("Rakka.isGlobalLocked=" ++ trueOrFalse isGLocked ++ ";") - ) - += mkGlobalJSList env - ) - += ( eelem "body" - += ( eelem "div" - += sattr "class" "header" - ) - += ( eelem "div" - += sattr "class" "center" - += ( eelem "div" - += sattr "class" "title" - += constL pageTitle - ) - += ( eelem "div" - += sattr "class" "body" - += ( eelem "ul" - += ( getXPathTreesInDoc "/pageListing/page/@name/text()" - >>> - eelem "li" - += ( eelem "a" - += attr "href" ( getText - >>> - arr (\ x -> uriToString id (mkPageURI baseURI x) "") - >>> - mkText - ) - += this - ) - ) - ) - ) - ) - += ( eelem "div" - += sattr "class" "footer" - ) - += ( eelem "div" - += sattr "class" "left sideBar" - += ( eelem "div" - += sattr "class" "content" - += constL leftSideBar - ) - ) - += ( eelem "div" - += sattr "class" "right sideBar" - += ( eelem "div" - += sattr "class" "content" - += constL rightSideBar - ) - ) - ) - >>> - uniqueNamespacesFromDeclAndQNames - ) ) -<< pageListing - - -{- - --} -handlePageNotFound :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a PageName (Resource ()) -handlePageNotFound env - = proc name - -> do tree <- ( eelem "/" - += ( eelem "pageNotFound" - += attr "name" (arr id >>> mkText) - ) - ) -< name - returnA -< do setStatus NotFound - outputXmlPage' tree (notFoundToXHTML env) - - -notFoundToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree -notFoundToXHTML env - = proc pageNotFound - -> do SiteName siteName <- getSysConfA (envSysConf env) -< () - BaseURI baseURI <- getSysConfA (envSysConf env) -< () - StyleSheet styleSheet <- getSysConfA (envSysConf env) -< () - GlobalLock isGLocked <- getSysConfA (envSysConf env) -< () - - name <- (getXPathTreesInDoc "/pageNotFound/@name/text()" >>> getText) -< pageNotFound - - let cssHref = [uriToString id (mkObjectURI baseURI styleSheet) ""] - scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI "js" }) ""] - - pageTitle <- listA (readSubPage env) -< (name, Nothing, "PageTitle") - leftSideBar <- listA (readSubPage env) -< (name, Nothing, "SideBar/Left") - rightSideBar <- listA (readSubPage env) -< (name, Nothing, "SideBar/Right") - - ( eelem "/" - += ( eelem "html" - += sattr "xmlns" "http://www.w3.org/1999/xhtml" - += ( eelem "head" - += ( eelem "title" - += txt siteName - += txt " - " - += getXPathTreesInDoc "/pageNotFound/@name/text()" - ) - += ( constL cssHref - >>> - eelem "link" - += sattr "rel" "stylesheet" - += sattr "type" "text/css" - += attr "href" (arr id >>> mkText) - ) - += mkFeedList env - += ( constL scriptSrc - >>> - eelem "script" - += sattr "type" "text/javascript" - += attr "src" (arr id >>> mkText) - ) - += ( eelem "script" - += sattr "type" "text/javascript" - += txt ("Rakka.baseURI = \"" ++ uriToString id baseURI "" ++ "\";") - += txt ("Rakka.isGlobalLocked=" ++ trueOrFalse isGLocked ++ ";") - ) - += mkGlobalJSList env - ) - += ( eelem "body" - += ( eelem "div" - += sattr "class" "header" - ) - += ( eelem "div" - += sattr "class" "center" - += ( eelem "div" - += sattr "class" "title" - += constL pageTitle - ) - += ( eelem "div" - += sattr "class" "body" - += txt "404 Not Found (FIXME)" -- FIXME - ) - ) - += ( eelem "div" - += sattr "class" "footer" - ) - += ( eelem "div" - += sattr "class" "left sideBar" - += ( eelem "div" - += sattr "class" "content" - += constL leftSideBar - ) - ) - += ( eelem "div" - += sattr "class" "right sideBar" - += ( eelem "div" - += sattr "class" "content" - += constL rightSideBar - ) - ) - ) - >>> - uniqueNamespacesFromDeclAndQNames - ) ) -<< pageNotFound - - -handlePut :: Environment -> PageName -> Resource () -handlePut env name - = do userID <- getUserID env - runXmlA env "rakka-page-1.0.rng" $ proc tree - -> do page <- parseXmlizedPage -< (name, tree) - status <- putPageA (envStorage env) -< (userID, page) - returnA -< setStatus status - - -handleDelete :: Environment -> PageName -> Resource () -handleDelete env name - = do userID <- getUserID env - status <- deletePage (envStorage env) userID name - setStatus status - - -mkFeedList :: (ArrowIO a, ArrowXml a) => Environment -> a b XmlTree -mkFeedList env - = proc _ -> do SiteName siteName <- getSysConfA (envSysConf env) -< () - BaseURI baseURI <- getSysConfA (envSysConf env) -< () - - feed <- unlistA <<< arrIO0 (findFeeds $ envStorage env) -< () - - ( eelem "link" - += sattr "rel" "alternate" - += sattr "type" "application/rss+xml" - += attr "title" (txt siteName <+> txt " - " <+> mkText) - += attr "href" (arr (mkFeedURIStr baseURI) >>> mkText) ) -<< feed - - -findFeeds :: Storage -> IO [PageName] -findFeeds sto - = do cond <- newCondition - setPhrase cond "[UVSET]" - addAttrCond cond "rakka:isFeed STREQ yes" - setOrder cond "@uri STRA" - result <- searchPages sto cond - return (map hpPageName $ srPages result) - - -mkGlobalJSList :: (ArrowIO a, ArrowXml a, ArrowChoice a) => Environment -> a b XmlTree -mkGlobalJSList env - = proc _ -> do BaseURI baseURI <- getSysConfA (envSysConf env) -< () - - scriptName <- unlistA <<< arrIO0 (findJavaScripts $ envStorage env) -< () - pageM <- getPageA (envStorage env) -< (scriptName, Nothing) - - case pageM of - Nothing -> none -< () - Just page - | isEntity page - -> ( if entityIsBinary page then - ( eelem "script" - += sattr "type" "text/javascript" - += attr "src" (arr (mkObjectURIStr baseURI . pageName) >>> mkText) ) - else - ( eelem "script" - += sattr "type" "text/javascript" - += (arr (UTF8.decode . L.unpack . entityContent) >>> mkText) ) - ) -<< page - | otherwise - -> none -< () - - -findJavaScripts :: Storage -> IO [PageName] -findJavaScripts sto - = do cond <- newCondition - setPhrase cond "[UVSET]" - addAttrCond cond "@title STRBW Global/" - addAttrCond cond "@type STRBW text/javascript" - setOrder cond "@uri STRA" - result <- searchPages sto cond - return (map hpPageName $ srPages result) - - -mkFeedURIStr :: URI -> PageName -> String -mkFeedURIStr baseURI name - = uriToString id (mkFeedURI baseURI name) "" - - -mkObjectURIStr :: URI -> PageName -> String -mkObjectURIStr baseURI name - = uriToString id (mkObjectURI baseURI name) "" rmfile ./Rakka/Resource/PageEntity.hs hunk ./Rakka/Resource/Render.hs 1 -module Rakka.Resource.Render - ( resRender - ) - where - -import Control.Arrow -import Control.Arrow.ArrowIO -import Control.Arrow.ArrowList -import Control.Monad.Trans -import qualified Data.ByteString.Lazy as Lazy -import Network.HTTP.Lucu -import Network.HTTP.Lucu.Utils -import OpenSSL.EVP.Base64 -import Rakka.Environment -import Rakka.Page -import Rakka.Utils -import Rakka.Wiki.Engine -import Text.XML.HXT.Arrow.Namespace -import Text.XML.HXT.Arrow.WriteDocument -import Text.XML.HXT.Arrow.XmlArrow -import Text.XML.HXT.Arrow.XmlIOStateArrow -import Text.XML.HXT.DOM.TypeDefs -import Text.XML.HXT.DOM.XmlKeywords - - -resRender :: Environment -> ResourceDef -resRender env - = ResourceDef { - resUsesNativeThread = False - , resIsGreedy = True - , resGet = Nothing - , resHead = Nothing - , resPost = Just $ getPathInfo >>= handleRender env . toPageName - , resPut = Nothing - , resDelete = Nothing - } - where - toPageName :: [String] -> PageName - toPageName = decodePageName . joinWith "/" - - -{- - --- Request --- - POST /render/Foo/Bar HTTP/1.0 - Content-Type: text/x-rakka - - = foo = - blah blah... - - --- Response --- - HTTP/1.1 200 OK - Content-Type: text/xml - - - foo - - blah blah... - - --} -handleRender :: Environment -> PageName -> Resource () -handleRender env name - = do entity <- inputLBS defaultLimit - cTypeM <- getContentType - - let (bin, cType) = case cTypeM of - Just (MIMEType "application" "x-rakka-base64-stream" _) - -> let b = decodeBase64LBS entity - in - (b, guessMIMEType b) - Just t - -> (entity, t) - Nothing - -> (entity, guessMIMEType entity) - - setContentType $ read "text/xml" - [xmlStr] <- liftIO $ runX ( setErrorMsgHandler False fail - >>> - constA (name, cType, bin) - >>> - render env - >>> - writeDocumentToString [ (a_indent , v_1) - , (a_output_encoding, utf8) - , (a_no_xml_pi , v_0) ] - ) - output xmlStr - - -render :: (ArrowXml a, ArrowChoice a, ArrowIO a) => - Environment - -> a (PageName, MIMEType, Lazy.ByteString) XmlTree -render env - = proc (pName, pType, pBin) - -> do pageBody <- listA (makePreviewXHTML (envStorage env) (envSysConf env) (envInterpTable env)) - -< (pName, pType, pBin) - - ( eelem "/" - += ( eelem "renderResult" - += sattr "name" pName - += constL pageBody - >>> - uniqueNamespacesFromDeclAndQNames - ) ) -<< () - rmfile ./Rakka/Resource/Render.hs hunk ./Rakka/Resource/Search.hs 1 -module Rakka.Resource.Search - ( resSearch - ) - where - -import qualified Codec.Binary.UTF8.Generic as UTF8 -import Control.Monad.Trans -import Data.List -import Data.Maybe -import Data.Time -import Network.HTTP.Lucu -import Network.HTTP.Lucu.RFC1123DateTime -import Network.URI hiding (query, fragment) -import Rakka.Environment -import Rakka.Page -import Rakka.Resource -import Rakka.Storage -import Rakka.SystemConfig -import Rakka.Utils -import Rakka.W3CDateTime -import Rakka.Wiki.Engine -import System.FilePath -import Text.HyperEstraier hiding (getText) -import Text.XML.HXT.Arrow -import Text.XML.HXT.XPath - - -resSearch :: Environment -> ResourceDef -resSearch env - = ResourceDef { - resUsesNativeThread = False - , resIsGreedy = False - , resGet = Just $ handleSearch env - , resHead = Nothing - , resPost = Nothing - , resPut = Nothing - , resDelete = Nothing - } - - -resultsPerSection :: Int -resultsPerSection = 10 - - -maxSectionWindowSize :: Int -maxSectionWindowSize = 10 - - -findQueryParam :: String -> [FormData] -> Maybe String -findQueryParam name qps - = do fd <- find (\ qp -> fdName qp == name) qps - return $ UTF8.toString $ fdContent fd - -{- - - - - aaa foo bbb - - - ... - --} -handleSearch :: Environment -> Resource () -handleSearch env - = do params <- getQueryForm - - let query = fromMaybe "" $ findQueryParam "q" params - order = findQueryParam "order" params - from = fromMaybe 0 - $ fmap read $ findQueryParam "from" params - to = fromMaybe (from + resultsPerSection) - $ fmap read $ findQueryParam "to" params - - cond <- liftIO $ mkCond query order from to - result <- searchPages (envStorage env) cond - - let to' = min (from + length (srPages result)) to - - BaseURI baseURI <- getSysConf (envSysConf env) - runIdempotentA baseURI $ proc () - -> do tree <- ( eelem "/" - += ( eelem "searchResult" - += sattr "query" query - += ( case order of - Just o -> sattr "order" o - Nothing -> none - ) - += sattr "from" (show from) - += sattr "to" (show to') - += sattr "total" (show $ srTotal result) - += ( constL (srPages result) - >>> - mkPageElem - ) - ) - ) -< () - returnA -< outputXmlPage' tree (searchResultToXHTML env) - where - mkCond :: String -> Maybe String -> Int -> Int -> IO Condition - mkCond query order from to - = do cond <- newCondition - setPhrase cond query - case order of - Just o -> setOrder cond o - Nothing -> return () - setSkip cond from - setMax cond (to - from + 1) - return cond - - mkPageElem :: (ArrowChoice a, ArrowXml a, ArrowIO a) => a HitPage XmlTree - mkPageElem = ( eelem "page" - += attr "name" (arr hpPageName >>> mkText) - += attr "lastModified" ( arrIO (utcToLocalZonedTime . hpLastMod) - >>> - arr formatW3CDateTime - >>> - mkText - ) - += ( arrL hpSnippet - >>> - mkSnippetTree - ) - ) - - mkSnippetTree :: (ArrowChoice a, ArrowXml a) => a SnippetFragment XmlTree - mkSnippetTree = proc fragment - -> case fragment of - Boundary -> eelem "boundary" -< () - NormalText t -> mkText -< t - HighlightedWord w -> ( eelem "hit" - += mkText - ) -< w - - -searchResultToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree -searchResultToXHTML env - = proc tree - -> do SiteName siteName <- getSysConfA (envSysConf env) -< () - BaseURI baseURI <- getSysConfA (envSysConf env) -< () - StyleSheet styleSheet <- getSysConfA (envSysConf env) -< () - GlobalLock isGLocked <- getSysConfA (envSysConf env) -< () - - let cssHref = [uriToString id (mkObjectURI baseURI styleSheet) ""] - scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI "js" }) ""] - - pageTitle <- listA (readSubPage env) -< "PageTitle" - leftSideBar <- listA (readSubPage env) -< "SideBar/Left" - rightSideBar <- listA (readSubPage env) -< "SideBar/Right" - - ( eelem "/" - += ( eelem "html" - += sattr "xmlns" "http://www.w3.org/1999/xhtml" - += ( eelem "head" - += ( eelem "title" - += txt siteName - += txt " - " - += getXPathTreesInDoc "/searchResult/@query/text()" - ) - += ( constL cssHref - >>> - eelem "link" - += sattr "rel" "stylesheet" - += sattr "type" "text/css" - += attr "href" (arr id >>> mkText) - ) - += ( constL scriptSrc - >>> - eelem "script" - += sattr "type" "text/javascript" - += attr "src" (arr id >>> mkText) - ) - += ( eelem "script" - += sattr "type" "text/javascript" - += txt ("Rakka.baseURI=\"" ++ uriToString id baseURI "" ++ "\";") - += txt ("Rakka.isGlobalLocked=" ++ trueOrFalse isGLocked ++ ";") - += txt "Rakka.isSpecialPage=true;" - ) - ) - += ( eelem "body" - += ( eelem "div" - += sattr "class" "header" - ) - += ( eelem "div" - += sattr "class" "center" - += ( eelem "div" - += sattr "class" "title" - += constL pageTitle - ) - += ( eelem "div" - += sattr "class" "body" - += ( eelem "h1" - += txt "Search Result" - ) - += ( eelem "div" - += sattr "class" "searchStat" - += txt "Search result for " - += ( eelem "span" - += sattr "class" "queryString" - += getXPathTreesInDoc "/searchResult/@query/text()" - ) - += txt ": found " - += getXPathTreesInDoc "/searchResult/@total/text()" - += txt " pages." - ) - += ( getXPathTreesInDoc "/searchResult/page" - >>> - formatItem baseURI - ) - += ( ( ( getXPathTreesInDoc "/searchResult/@query/text()" - >>> - getText - ) - &&& - maybeA ( getXPathTreesInDoc "/searchResult/@order/text()" - >>> - getText - ) - &&& - ( getXPathTreesInDoc "/searchResult/@from/text()" - >>> - getText - >>> - arr ((`div` resultsPerSection) . read) - ) - &&& - ( getXPathTreesInDoc "/searchResult/@total/text()" - >>> - getText - >>> - arr ((+ 1) . (`div` resultsPerSection) . (\ x -> x - 1) . read) - ) - ) - >>> - ( ((> 1) . snd . snd . snd) - `guardsP` - formatPager baseURI - ) - ) - ) - ) - += ( eelem "div" - += sattr "class" "footer" - ) - += ( eelem "div" - += sattr "class" "left sideBar" - += ( eelem "div" - += sattr "class" "content" - += constL leftSideBar - ) - ) - += ( eelem "div" - += sattr "class" "right sideBar" - += ( eelem "div" - += sattr "class" "content" - += constL rightSideBar - ) - ) - ) - >>> - uniqueNamespacesFromDeclAndQNames - ) ) -<< tree - where - formatItem :: (ArrowXml a, ArrowChoice a, ArrowIO a) => URI -> a XmlTree XmlTree - formatItem baseURI - = ( eelem "div" - += sattr "class" "searchResult" - += ( eelem "a" - += attr "href" ( getAttrValue "name" - >>> - arr (\ x -> uriToString id (mkPageURI baseURI x) "") - >>> - mkText - ) - += (getAttrValue "name" >>> mkText) - ) - += ( eelem "div" - += sattr "class" "date" - += ( getAttrValue "lastModified" - >>> - arr (zonedTimeToUTC . fromJust . parseW3CDateTime) - >>> - arrIO utcToLocalZonedTime - >>> - arr formatRFC1123DateTime - >>> - mkText - ) - ) - += ( eelem "p" - += ( getChildren - >>> - choiceA [ isText :-> this - , hasName "boundary" :-> txt " ... " - , hasName "hit" :-> ( eelem "span" - += sattr "class" "highlighted" - += getChildren - ) - ] - ) - ) - ) - - formatPager :: (ArrowChoice a, ArrowXml a) => URI -> a (String, (Maybe String, (Int, Int))) XmlTree - formatPager baseURI - = ( eelem "div" - += sattr "class" "pager" - += txt "Page." - += ( ( arr fst - &&& - arr (fst . snd) - &&& - arr (fst . snd . snd) - &&& - ( arr (snd . snd) - >>> - mkSectionWindow - ) - ) - >>> - proc (query, (order, (currentSection, section))) - -> if currentSection == section then - ( txt " " - <+> - eelem "span" - += sattr "class" "currentSection" - += (arr show >>> mkText) - ) -< section - else - ( txt " " - <+> - eelem "a" - += attr "href" ( mkSectionURI baseURI - >>> - uriToText - ) - += (arr (show . snd . snd) >>> mkText) - ) -< (query, (order, section)) - ) - ) - - mkSectionWindow :: ArrowList a => a (Int, Int) Int - mkSectionWindow - = proc (currentSection, totalSections) - -> let windowWidth = min maxSectionWindowSize totalSections - windowBegin = currentSection - (windowWidth `div` 2) - (begin, end) = if windowBegin < 0 then - -- 左に溢れた - (0, windowWidth - 1) - else - if windowBegin + windowWidth >= totalSections then - -- 右に溢れた - (totalSections - windowWidth, totalSections - 1) - else - -- どちらにも溢れない - (windowBegin, windowBegin + windowWidth - 1) - in - arrL id -< [begin .. end] - - - mkSectionURI :: Arrow a => URI -> a (String, (Maybe String, Int)) URI - mkSectionURI baseURI - = arr $ \ (query, (order, section)) - -> baseURI { - uriPath = uriPath baseURI "search.html" - , uriQuery = '?' : mkQueryString ( [ ("q" , query) - , ("from", show $ section * resultsPerSection) - , ("to" , show $ (section + 1) * resultsPerSection - 1) - ] - ++ - case order of - Just o -> [("order", o)] - Nothing -> [] - ) - } - - uriToText :: ArrowXml a => a URI XmlTree - uriToText = arr (\ uri -> uriToString id uri "") >>> mkText - - --- FIXME: localize -readSubPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) => - Environment -> a PageName XmlTree -readSubPage env - = proc (subPageName) -> - do subPage <- getPageA (envStorage env) >>> arr fromJust >>> xmlizePage -< (subPageName, Nothing) - subXHTML <- makeSubXHTML (envStorage env) (envSysConf env) (envInterpTable env) -< (Nothing, Nothing, subPage) - returnA -< subXHTML rmfile ./Rakka/Resource/Search.hs hunk ./Rakka/Resource/SystemConfig.hs 1 -module Rakka.Resource.SystemConfig - ( resSystemConfig - ) - where - -import Data.Maybe -import Network.HTTP.Lucu -import Rakka.Environment -import Rakka.Resource -import Rakka.SystemConfig -import Text.XML.HXT.Arrow -import Text.XML.HXT.XPath - - --- FIXME: --- GET /systemConfig ==> 全設定値を返す --- GET /systemConfig/siteName ==> siteName を返す --- PUT /systemConfig/siteName ==> siteName を設定 -resSystemConfig :: Environment -> ResourceDef -resSystemConfig env - = ResourceDef { - resUsesNativeThread = False - , resIsGreedy = False - , resGet = Just $ handleGet env - , resHead = Nothing - , resPost = Nothing - , resPut = Just $ handlePut env - , resDelete = Nothing - } - - -{- - - Rakka - MainPage - --} -handleGet :: Environment -> Resource () -handleGet env - = runIdempotentA' $ proc () - -> do tree <- mkSystemConfigTree env -< () - returnA -< outputXml tree - - -mkSystemConfigTree :: (ArrowXml a, ArrowIO a) => Environment -> a b XmlTree -mkSystemConfigTree env - = let sc = envSysConf env - in - proc _ - -> do siteName @ (SiteName _) <- getSysConfA sc -< () - baseURI @ (BaseURI _) <- getSysConfA sc -< () - defaultPage @ (DefaultPage _) <- getSysConfA sc -< () - styleSheet @ (StyleSheet _) <- getSysConfA sc -< () - languages @ (Languages _) <- getSysConfA sc -< () - globalLock @ (GlobalLock _) <- getSysConfA sc -< () - - ( eelem "/" - += ( eelem "systemConfig" - += ( eelem "value" - += sattr "path" (confPath siteName) - += txt (serialize siteName) - ) - += ( eelem "value" - += sattr "path" (confPath baseURI) - += txt (serialize baseURI) - ) - += ( eelem "value" - += sattr "path" (confPath defaultPage) - += txt (serialize defaultPage) - ) - += ( eelem "value" - += sattr "path" (confPath styleSheet) - += txt (serialize styleSheet) - ) - += ( eelem "value" - += sattr "path" (confPath languages) - += txt (serialize languages) - ) - += ( eelem "value" - += sattr "path" (confPath globalLock) - += txt (serialize globalLock) - ) - ) ) -<< () - - -handlePut :: Environment -> Resource () -handlePut env - = do let sc = envSysConf env - - userID <- getUserID env - case userID of - Nothing - -> setStatus Forbidden - Just uid - -> runXmlA env "rakka-config-1.0.rng" $ proc tree - -> do listA ( getXPathTreesInDoc "/systemConfig/value" - >>> - choiceA [ branch (undefined :: SiteName ) - , branch (undefined :: BaseURI ) - , branch (undefined :: DefaultPage) - , branch (undefined :: StyleSheet ) - , branch (undefined :: Languages ) - , branch (undefined :: GlobalLock ) - ] - ) -< tree - returnA -< setStatus Ok - where - branch :: forall a c. (ArrowXml a, ArrowIO a, SysConfValue c) => - c - -> IfThen (a XmlTree XmlTree) (a XmlTree StatusCode) - branch c - = hasAttrValue "path" (== confPath c) - :-> - ( getChildren - >>> getText - >>> arr (fromJust . (deserialize :: String -> Maybe c)) - >>> setSysConfA sc uid ) + rmfile ./Rakka/Resource/SystemConfig.hs hunk ./Rakka/Resource/TrackBack.hs 1 -module Rakka.Resource.TrackBack - ( resTrackBack - ) - where - -import qualified Codec.Binary.UTF8.String as UTF8 -import Control.Arrow -import Control.Arrow.ArrowList -import Control.Monad.Trans -import Data.List -import Data.Maybe -import Data.Time -import Network.Browser -import Network.HTTP -import Network.HTTP.Lucu -import Network.HTTP.Lucu.Response -import Network.HTTP.Lucu.Utils -import Network.URI -import Rakka.Environment -import Rakka.Page -import Rakka.Storage -import Rakka.SystemConfig -import Rakka.TrackBack -import Text.XML.HXT.Arrow.WriteDocument -import Text.XML.HXT.Arrow.XmlArrow -import Text.XML.HXT.Arrow.XmlIOStateArrow -import Text.XML.HXT.DOM.TypeDefs -import Text.XML.HXT.DOM.XmlKeywords - - -data TBResponse - = NoError - | Error !Int !String - deriving (Show, Eq) - - -resTrackBack :: Environment -> ResourceDef -resTrackBack env - = ResourceDef { - resUsesNativeThread = False - , resIsGreedy = True - , resGet = Nothing - , resHead = Nothing - , resPost = Just $ getPathInfo >>= handlePost env . toPageName - , resPut = Nothing - , resDelete = Nothing - } - where - toPageName :: [String] -> PageName - toPageName = decodePageName . joinWith "/" - - -handlePost :: Environment -> PageName -> Resource () -handlePost env name - = do form <- inputForm defaultLimit - tbParamM <- validateTrackBack form - case tbParamM of - Nothing - -> return () - Just tbParam - -> do cited <- liftIO $ checkCitation tbParam name - if cited then - do pageM <- getPage (envStorage env) name Nothing - case pageM of - Nothing -> setStatus NotFound - Just page -> addTB tbParam page - else - outputResponse (Error 1 "Failed to confirm if your entry contains any citation to this page.") - where - addTB :: TrackBack -> Page -> Resource () - addTB tbParam page - | isRedirect page - = do BaseURI baseURI <- getSysConf (envSysConf env) - redirect TemporaryRedirect (mkPageURI baseURI $ redirName page) - | otherwise - = do tbListM <- return . fromMaybe [] =<< getAttachment (envStorage env) (pageName page) "trackbacks" Nothing - st <- putAttachment (envStorage env) Nothing Nothing (pageName page) "trackbacks" (tbParam : tbListM) - if isSuccessful st then - outputResponse NoError - else - setStatus st - - -validateTrackBack :: [(String, String)] -> Resource (Maybe TrackBack) -validateTrackBack form - = do let title = get' "title" - excerpt = get' "excerpt" - blogName = get' "blog_name" - case get' "url" of - Nothing - -> do outputResponse (Error 1 "Parameter `url' is missing.") - return Nothing - Just u - -> case parseURI u of - Nothing - -> do outputResponse (Error 1 "Parameter `url' is malformed.") - return Nothing - Just url - -> do time <- liftIO getCurrentTime - return $ Just TrackBack { - tbTitle = title - , tbExcerpt = excerpt - , tbURL = url - , tbBlogName = blogName - , tbTime = time - } - where - get' :: String -> Maybe String - get' = fmap UTF8.decodeString . flip lookup form - - -outputResponse :: TBResponse -> Resource () -outputResponse res - = do setContentType $ read "text/xml" - [xmlStr] <- liftIO $ runX ( setErrorMsgHandler False fail - >>> - mkResponseTree - >>> - writeDocumentToString [ (a_indent , v_1 ) - , (a_output_encoding, utf8) - , (a_no_xml_pi , v_0 ) ] - ) - output xmlStr - where - mkResponseTree :: ArrowXml a => a b XmlTree - mkResponseTree - = proc _ - -> ( eelem "/" - += ( eelem "response" - += ( eelem "error" - += txt (case res of - NoError -> "0" - Error code _ -> show code) - ) - += ( case res of - NoError -> none - Error _ msg -> ( eelem "message" - += txt msg - ) - ) - ) - ) -< () - - -checkCitation :: TrackBack -> PageName -> IO Bool -checkCitation param name - = do (_, res) <- browse $ - do setAllowRedirects True - setErrHandler (\ _ -> return ()) - setOutHandler (\ _ -> return ()) - request $ defaultGETRequest $ tbURL param - case rspCode res of - (2, 0, 0) - -> return (encodePageName name `isInfixOf` rspBody res) - _ -> return False rmfile ./Rakka/Resource/TrackBack.hs hunk ./Rakka/Resource/Users.hs 1 -module Rakka.Resource.Users - ( resUsers - ) - where - -import Control.Monad -import Control.Monad.Trans -import Data.Maybe -import Network.HTTP.Lucu -import Rakka.Authorization -import Rakka.Environment -import Rakka.Resource -import Text.XML.HXT.Arrow hiding (when) - - -resUsers :: Environment -> ResourceDef -resUsers env - = ResourceDef { - resUsesNativeThread = False - , resIsGreedy = True - , resGet = Just $ handleGet env - , resHead = Nothing - , resPost = Nothing - , resPut = Just $ handlePut env - , resDelete = Just $ handleDelete env - } - - -{- - [GET /users] - - - - ... - - - [GET /users/foo] - 204 No Content - - [GET /users/nonexistent] - 404 Not Found --} -handleGet :: Environment -> Resource () -handleGet env - = do userID <- getUserID env - when (isNothing userID) - $ abort Forbidden [] Nothing - - path <- getPathInfo - case path of - [] -> returnUserList - [name] -> returnUser name - _ -> foundNoEntity Nothing - where - returnUserList :: Resource () - returnUserList - = do users <- liftIO $ getUserList $ envAuthDB env - runIdempotentA' $ proc () - -> do tree <- ( eelem "/" - += ( eelem "users" - += ( constL users - >>> - ( eelem "user" - += attr "id" mkText - ) - ) - ) - ) -< () - returnA -< outputXml tree - - returnUser :: String -> Resource () - returnUser name - = do users <- liftIO $ getUserList $ envAuthDB env - if any (== name) users - then setStatus NoContent - else foundNoEntity Nothing - - -{- - > PUT /users/foo HTTP/1.1 - > Content-Type: text/plain - > - > password - - < HTTP/1.1 201 Created --} -handlePut :: Environment -> Resource () -handlePut env - = do userID <- getUserID env - when (isNothing userID) - $ abort Forbidden [] Nothing - - path <- getPathInfo - case path of - [name] -> do mimeType <- getContentType - case mimeType of - Nothing - -> abort BadRequest [] (Just "Missing Content-Type") - Just (MIMEType "text" "plain" _) - -> do pass <- input defaultLimit - addUser (envAuthDB env) name pass - Just t - -> abort UnsupportedMediaType [] (Just $ "Unsupported media type: " ++ show t) - setStatus Created - _ -> abort BadRequest [] (Just "Invalid URI") - - -handleDelete :: Environment -> Resource () -handleDelete env - = do userID <- getUserID env - when (isNothing userID) - $ abort Forbidden [] Nothing - - path <- getPathInfo - case path of - [name] -> delUser (envAuthDB env) name - _ -> abort BadRequest [] (Just "Invalid URI") - setStatus NoContent rmfile ./Rakka/Resource/Users.hs rmdir ./Rakka/Resource hunk ./Rakka/Resource.hs 1 -module Rakka.Resource - ( runIdempotentA - , runIdempotentA' - , runXmlA - , getEntityType - , outputXmlPage - , outputXmlPage' - , outputXml - , getUserID - ) - where - -import qualified Codec.Binary.UTF8.String as UTF8 -import Control.Arrow -import Control.Arrow.ArrowList -import Control.Monad -import Control.Monad.Trans -import Network.HTTP.Lucu -import Network.HTTP.Lucu.Utils -import Network.URI hiding (path) -import Rakka.Authorization -import Rakka.Environment -import Rakka.Validation -import System.FilePath.Posix -import System.Log.Logger -import Text.XML.HXT.Arrow.ReadDocument -import Text.XML.HXT.Arrow.WriteDocument -import Text.XML.HXT.Arrow.XmlIOStateArrow -import Text.XML.HXT.DOM.TypeDefs -import Text.XML.HXT.DOM.XmlKeywords - - -logger :: String -logger = "Rakka.Resource" - - --- "/" ==> "/" --- "/foo" ==> "/foo.html" --- "/foo/" ==> "/foo.html" --- "/foo.bar/" ==> "/foo.bar" --- "/foo.bar" ==> "/foo.bar" -canonicalizeURI :: URI -> Resource () -canonicalizeURI baseURI - = do rPath <- return . uriPath =<< getRequestURI - let newURI = baseURI { uriPath = uriPath baseURI newPath } - newPath = foldl () "/" newPath' - newPath' = case [x | x <- splitBy (== '/') rPath, x /= ""] of - [] -> [] - path -> case break (== '.') $ last path of - (_, "") -> let basePieces = reverse $ tail $ reverse path - lastPiece = last path - in - basePieces ++ [lastPiece ++ ".html"] - (_, _) -> path - when (rPath /= newPath) - $ abort MovedPermanently - [("Location", uriToString id newURI $ "")] - Nothing - - -runIdempotentA :: URI -> IOSArrow () (Resource c) -> Resource c -runIdempotentA baseURI a - = do canonicalizeURI baseURI - [rsrc] <- liftIO $ runX ( setErrorMsgHandler False fail - >>> - constA () - >>> - a - ) - rsrc - - -runIdempotentA' :: IOSArrow () (Resource c) -> Resource c -runIdempotentA' a - = do [rsrc] <- liftIO $ runX ( setErrorMsgHandler False fail - >>> - constA () - >>> - a - ) - rsrc - - -runXmlA :: Environment -> FilePath -> IOSArrow XmlTree (Resource c) -> Resource c -runXmlA env schemaPath a - = do inputA <- getInputXmlA env schemaPath - [rsrc] <- liftIO $ runX ( inputA - >>> - setErrorMsgHandler False fail - >>> - a - ) - rsrc - - --- well-formed でない時は 400 Bad Request になり、valid でない時は 422 --- Unprocessable Entity になる。入力の型が XML でない時は 415 --- Unsupported Media Type を返す。 -getInputXmlA :: Environment -> FilePath -> Resource (IOSArrow b XmlTree) -getInputXmlA env schemaPath - = do reader <- getInputReader - validator <- getValidator env schemaPath - return ( setErrorMsgHandler False (abort BadRequest [] . Just) - >>> - reader - >>> - setErrorMsgHandler False (abort UnprocessableEntitiy [] . Just) - >>> - validator - ) - - -getInputReader :: Resource (IOSArrow b XmlTree) -getInputReader - = do mimeType <- getContentType - case mimeType of - Nothing - -> getFailingReader BadRequest [] (Just "Missing Content-Type") - Just (MIMEType "text" "xml" _) - -> getXmlReader - Just (MIMEType "application" "xml" _) - -> getXmlReader - Just t - -> getFailingReader UnsupportedMediaType [] (Just $ "Unsupported media type: " ++ show t) - where - getXmlReader - = do req <- input defaultLimit - liftIO $ debugM logger req - return $ readString [ (a_validate , v_0) - , (a_check_namespaces , v_1) - , (a_remove_whitespace, v_0) - ] (UTF8.decodeString req) - getFailingReader code headers msg - = return $ proc _ -> abortA -< (code, (headers, msg)) - - -getEntityType :: Resource MIMEType -getEntityType - = do uri <- getRequestURI - let ext = reverse $ takeWhile (/= '.') $ reverse $ uriPath uri - case lookup ext extMap of - Just mType -> return mType - Nothing -> abort NotFound [] (Just $ "Unsupported entity type: " ++ ext) - where - extMap :: [(String, MIMEType)] - extMap = [ ("html", read "application/xhtml+xml") - , ( "rdf", read "application/rss+xml" ) - , ( "xml", read "text/xml" ) - ] - - -outputXmlPage :: XmlTree -> [(MIMEType, IOSArrow XmlTree XmlTree)] -> Resource () -outputXmlPage tree formatters - = do mType <- getEntityType - setContentType mType - let formatter = case lookup mType formatters of - Just f -> f - Nothing -> this - [resultStr] <- liftIO $ runX ( setErrorMsgHandler False fail - >>> - constA tree - >>> - formatter - >>> - writeDocumentToString [ (a_indent , v_1 ) - , (a_output_encoding, utf8) - , (a_no_xml_pi , v_0 ) ] - ) - output resultStr - - -outputXmlPage' :: XmlTree -> IOSArrow XmlTree XmlTree -> Resource () -outputXmlPage' tree toXHTML - = outputXmlPage tree [(MIMEType "application" "xhtml+xml" [], toXHTML)] - - -outputXml :: XmlTree -> Resource () -outputXml tree - = do setContentType (MIMEType "text" "xml" []) - [xmlStr] <- liftIO $ runX ( setErrorMsgHandler False fail - >>> - constA tree - >>> - writeDocumentToString [ (a_indent , v_1 ) - , (a_output_encoding, utf8) - , (a_no_xml_pi , v_0 ) ] - ) - output xmlStr - - -getUserID :: Environment -> Resource (Maybe String) -getUserID env - = do auth <- getAuthorization - case auth of - Just (BasicAuthCredential userID password) - -> do valid <- isValidPair (envAuthDB env) userID password - if valid then - return (Just userID) - else - return Nothing - _ -> return Nothing rmfile ./Rakka/Resource.hs hunk ./Rakka/Storage/DefaultPage.hs 1 -module Rakka.Storage.DefaultPage - ( findAllDefaultPages - , getDefaultDirContents - , loadDefaultPage - ) - where - -import Control.Arrow -import Control.Arrow.ArrowIO -import Control.Arrow.ArrowList -import Data.Set (Set) -import qualified Data.Set as S -import Data.Time.Clock.POSIX -import Paths_Rakka -- Cabal が用意する。 -import Rakka.Page -import System.Directory -import System.FilePath -import System.FilePath.Find hiding (fileName, modificationTime) -import System.Posix.Files -import Text.XML.HXT.Arrow.ReadDocument -import Text.XML.HXT.Arrow.XmlIOStateArrow -import Text.XML.HXT.DOM.XmlKeywords - - -doesLocalDirExist :: IO Bool -doesLocalDirExist = doesDirectoryExist "defaultPages" - - -findAllDefaultPages :: IO (Set PageName) -findAllDefaultPages - -- ./defaultPages が存在するなら、その中を探す。無ければ Cabal で - -- defaultPages を探す。 - = do localDirExists <- doesLocalDirExist - if localDirExists then - findAllIn "defaultPages" - else - -- FIXME: この getDataFileName の使ひ方は undocumented - findAllIn =<< getDataFileName "defaultPages" - where - findAllIn :: FilePath -> IO (Set PageName) - findAllIn dirPath - = find always (fileType ==? RegularFile) dirPath - >>= - return . S.fromList . map (decodePageName . makeRelative dirPath . dropExtension) - - -getDefaultDirContents :: PageName -> IO (Set PageName) -getDefaultDirContents dir - -- ./defaultPages が存在するなら、その中を探す。無ければ Cabal で - -- defaultPages を探す。 - = do localDirExists <- doesLocalDirExist - if localDirExists then - getDir' "defaultPages" - else - -- FIXME: この getDataFileName の使ひ方は undocumented - getDir' =<< getDataFileName "defaultPages" - where - getDir' :: FilePath -> IO (Set PageName) - getDir' basePath - = do let childDirPath = basePath encodePageName dir - exists <- doesDirectoryExist childDirPath - if exists then - getDirectoryContents childDirPath - >>= - return . S.fromList . map (m basePath) . filter f - else - return S.empty - - m :: FilePath -> FilePath -> PageName - m basePath = (dir ) . decodePageName . makeRelative basePath . dropExtension - - f :: FilePath -> Bool - f "." = False - f ".." = False - f _ = True - - -loadDefaultPage :: PageName -> IO (Maybe Page) -loadDefaultPage name - -- ./defaultPages が存在するなら、./defaultPages/Foo.xml を探す。無 - -- ければ Cabal で defaultPages/Foo.xml を探す。 - = do let pagePath = "defaultPages" encodePageName name <.> "xml" - - localDirExists <- doesLocalDirExist - if localDirExists then - tryLoad pagePath - else - tryLoad =<< getDataFileName pagePath - where - tryLoad :: FilePath -> IO (Maybe Page) - tryLoad fpath - = do exists <- doesFileExist fpath - if exists then - return . Just =<< loadPageFile name fpath - else - return Nothing - - -loadPageFile :: PageName -> FilePath -> IO Page -loadPageFile name path - = do [page] <- runX ( setErrorMsgHandler False fail - >>> - constA (name, path) - >>> - loadPageFileA - ) - return page - - -loadPageFileA :: IOStateArrow s (PageName, FilePath) Page -loadPageFileA - = proc (name, fpath) -> - do tree <- readFromDocument [ (a_validate , v_0) - , (a_check_namespaces , v_1) - , (a_remove_whitespace, v_1) - ] -< fpath - lastMod <- arrIO (\ x -> getFileStatus x - >>= - return . posixSecondsToUTCTime . fromRational . toRational . modificationTime) - -< fpath - page <- parseXmlizedPage -< (name, tree) - - if isEntity page then - returnA -< page { - entityRevision = 0 - , entityLastMod = lastMod - } - else - returnA -< page { - redirRevision = 0 - , redirLastMod = lastMod - } rmfile ./Rakka/Storage/DefaultPage.hs hunk ./Rakka/Storage/Impl.hs 1 -module Rakka.Storage.Impl - ( getPage' - , putPage' - , deletePage' - , getDirContents' - , startIndexManager - - , getAttachment' - , putAttachment' - ) - where - -import Control.Concurrent -import Control.Concurrent.STM -import Control.Monad -import Data.Maybe -import Data.Set (Set) -import qualified Data.Set as S -import Data.Time -import Network.HTTP.Lucu -import Network.HTTP.Lucu.Utils -import Network.URI -import Prelude hiding (words) -import Rakka.Attachment -import Rakka.Page -import Rakka.Storage.DefaultPage -import Rakka.Storage.Repos -import Rakka.Storage.Types -import Rakka.W3CDateTime -import Subversion.Types -import Subversion.FileSystem -import Subversion.Repository -import System.Directory -import System.FilePath -import System.IO -import System.IO.Unsafe -import System.Log.Logger -import Text.HyperEstraier hiding (WriteLock) - - -logger :: String -logger = "Rakka.Storage" - - -getPage' :: Repository -> PageName -> Maybe RevNum -> IO (Maybe Page) -getPage' repos name rev - = do page <- loadPageInRepository repos name rev - case page of - Nothing -> loadDefaultPage name - p -> return p - - -putPage' :: Repository -> Maybe String -> Page -> IO StatusCode -putPage' = putPageIntoRepository - - -deletePage' :: Repository -> Maybe String -> PageName -> IO StatusCode -deletePage' = deletePageFromRepository - - -findAllPages :: Repository -> RevNum -> IO (Set PageName) -findAllPages _ 0 = findAllDefaultPages -findAllPages repos rev = do reposPages <- findAllPagesInRevision repos rev - defaultPages <- findAllDefaultPages - return (reposPages `S.union` defaultPages) - - -findChangedPages :: Repository -> RevNum -> RevNum -> IO (Set PageName) -findChangedPages repos 0 newRev = findAllPages repos newRev -findChangedPages repos oldRev newRev - = liftM S.unions (mapM (findChangedPagesAtRevision repos) [oldRev + 1 .. newRev]) - - -getDirContents' :: Repository -> PageName -> Maybe RevNum -> IO [PageName] -getDirContents' repos name rev - = do reposPages <- getDirContentsInRevision repos name rev - defaultPages <- getDefaultDirContents name - return $ S.toList (reposPages `S.union` defaultPages) - - -getCurrentRevNum :: Repository -> IO RevNum -getCurrentRevNum repos - = getRepositoryFS repos >>= getYoungestRev - - -getAttachment' :: Attachment a => - Repository - -> PageName - -> String - -> Maybe RevNum - -> IO (Maybe a) -getAttachment' = loadAttachmentInRepository - - -putAttachment' :: Attachment a => - Repository - -> Maybe String - -> Maybe RevNum - -> PageName - -> String - -> a - -> IO StatusCode -putAttachment' = putAttachmentIntoRepository - - -startIndexManager :: FilePath -> Repository -> (Page -> IO Document) -> IO (TChan IndexReq) -startIndexManager lsdir repos mkDraft - = do chan <- newTChanIO - index <- openIndex indexDir revFile - _ <- forkIO (loop chan index) - return chan - where - indexDir = lsdir "index" - revFile = lsdir "indexRev" - - loop :: TChan IndexReq -> Database -> IO () - loop chan index - = do req <- atomically $ readTChan chan - case req of - RebuildIndex - -> do noticeM logger "Rebuilding the H.E. index..." - closeDatabase index - removeDirectoryRecursive indexDir - index' <- openIndex indexDir revFile - syncIndex' index' revFile repos mkDraft - loop chan index' - - SyncIndex - -> do syncIndex' index revFile repos mkDraft - loop chan index - - SearchIndex cond var - -> do result <- searchIndex index cond - atomically $ putTMVar var result - loop chan index - - --- casket を R/W モードで開く。成功したらそのまま返し、失敗したら --- indexDir と revFile を削除してから casket を R/W モードで開く。 -openIndex :: FilePath -> FilePath -> IO Database -openIndex indexDir revFile - = do ret <- openDatabase indexDir (Writer []) - case ret of - Right index - -> do debugM logger ("Opened an H.E. index on " ++ indexDir) - return index - - Left err - -> do noticeM logger ("Failed to open an H.E. index on " - ++ indexDir ++ ": " ++ show err) - - indexExists <- doesDirectoryExist indexDir - when indexExists - $ removeDirectoryRecursive indexDir - - revFileExists <- doesFileExist revFile - when revFileExists - $ removeFile revFile - - Right index <- openDatabase indexDir (Writer [Create []]) - addAttrIndex index "@mdate" SeqIndex - addAttrIndex index "@type" StrIndex - addAttrIndex index "@uri" SeqIndex - addAttrIndex index "rakka:revision" SeqIndex - addAttrIndex index "rakka:isTheme" StrIndex - addAttrIndex index "rakka:isFeed" StrIndex - noticeM logger ("Created an H.E. index on " ++ indexDir) - - return index - - -syncIndex' :: Database -> FilePath -> Repository -> (Page -> IO Document) -> IO () -syncIndex' index revFile repos mkDraft - = updateIndexRev revFile $ \ oldRev -> - do debugM logger ("The index revision is currently " ++ show oldRev) - - newRev <- getCurrentRevNum repos - debugM logger ("The repository revision is currently " ++ show newRev) - - when (oldRev == 0 || newRev /= oldRev) - $ syncIndex'' oldRev newRev - return newRev - where - syncIndex'' :: RevNum -> RevNum -> IO () - syncIndex'' oldRev newRev - = do pages <- findChangedPages repos oldRev newRev - mapM_ (updateIndex index repos mkDraft newRev) (S.toList pages) - - -searchIndex :: Database -> Condition -> IO SearchResult -searchIndex index cond - = do (ids, hint) <- searchDatabase' index cond - let (total, words) = parseHint hint - pages <- mapM (fromId words) ids - return SearchResult { - srTotal = total - , srPages = pages - } - where - parseHint :: [(String, Int)] -> (Int, [String]) - parseHint xs - = let total = fromJust $ lookup "" xs - words = filter (/= "") $ map fst xs - in - (total, words) - - fromId :: [String] -> DocumentID -> IO HitPage - fromId words docId - = do uri <- getDocURI index docId - rev <- unsafeInterleaveIO $ - liftM (read . fromJust) - (getDocAttr index docId "rakka:revision") - lastMod <- unsafeInterleaveIO $ - liftM (zonedTimeToUTC . fromJust . parseW3CDateTime . fromJust) - (getDocAttr index docId "@mdate") - summary <- unsafeInterleaveIO $ - getDocAttr index docId "rakka:summary" - snippet <- unsafeInterleaveIO $ - do doc <- getDocument index docId [NoAttributes, NoKeywords] - sn <- makeSnippet doc words 300 80 80 - return (trim (== Boundary) $ map toFragment sn) - return HitPage { - hpPageName = decodePageName $ uriPath uri - , hpPageRev = rev - , hpLastMod = lastMod - , hpSummary = summary - , hpSnippet = snippet - } - - toFragment :: Either String (String, String) -> SnippetFragment - toFragment (Left "") = Boundary - toFragment (Left t) = NormalText t - toFragment (Right (w, _)) = HighlightedWord w - - -updateIndex :: Database - -> Repository - -> (Page -> IO Document) - -> RevNum - -> PageName - -> IO () -updateIndex index repos mkDraft rev name - = do pageM <- getPage' repos name (Just rev) - case pageM of - -- ページが削除された - Nothing - -> do docIdM <- getDocIdByURI index (mkRakkaURI name) - case docIdM of - Nothing -> return () - Just docId -> do removeDocument index docId [CleaningRemove] - infoM logger ("Removed page " ++ name ++ " from the index") - Just page - -> do draft <- mkDraft page - putDocument index draft [CleaningPut] - infoM logger ("Indexed page " ++ name ++ " of revision " ++ show (pageRevision page)) - - -updateIndexRev :: FilePath -> (RevNum -> IO RevNum) -> IO () -updateIndexRev revFile f = withFile revFile ReadWriteMode update - where - update :: Handle -> IO () - update h = do eof <- hIsEOF h - rev <- if eof then - return 0 - else - liftM read (hGetLine h) - rev' <- f rev - hSeek h AbsoluteSeek 0 - hSetFileSize h 0 - hPutStrLn h (show rev') rmfile ./Rakka/Storage/Impl.hs hunk ./Rakka/Storage/Repos.hs 1 --- -*- coding: utf-8 -*- -module Rakka.Storage.Repos - ( findAllPagesInRevision - , getDirContentsInRevision - , findChangedPagesAtRevision - , loadPageInRepository - , putPageIntoRepository - , deletePageFromRepository - , loadAttachmentInRepository - , putAttachmentIntoRepository - ) - where - -import Codec.Binary.UTF8.String -import Control.Monad -import Data.List -import qualified Data.Map as M -import Data.Maybe -import Data.Set (Set) -import qualified Data.Set as S hiding (Set) -import Data.Time -import Network.HTTP.Lucu hiding (redirect) -import Rakka.Attachment -import Rakka.Page -import Rakka.SystemConfig -import Rakka.Utils -import Rakka.W3CDateTime -import Subversion.FileSystem -import Subversion.FileSystem.DirEntry -import Subversion.FileSystem.Revision -import Subversion.FileSystem.Root -import Subversion.FileSystem.Transaction -import Subversion.Repository -import Subversion.Types -import System.FilePath.Posix - - -mkPagePath :: PageName -> FilePath -mkPagePath name - = "/pages" encodePageName name <.> "page" - - -mkDirPath :: PageName -> FilePath -mkDirPath dir - = "/pages" encodePageName dir - - -mkAttachmentPath :: PageName -> String -> FilePath -mkAttachmentPath pName aName - = "/attachments" encodePageName pName <.> "page" aName - - -mkAttachmentDirPath :: PageName -> FilePath -mkAttachmentDirPath pName - = "/attachments" encodePageName pName <.> "page" - - -findAllPagesInRevision :: Repository -> RevNum -> IO (Set PageName) -findAllPagesInRevision repos rev - = do fs <- getRepositoryFS repos - withRevision fs rev - $ do exists <- isDirectory root - if exists then - traverse root - else - return S.empty - where - root :: FilePath - root = "/pages" - - traverse :: FilePath -> Rev (Set PageName) - traverse dir - = liftM S.unions (getDirEntries dir >>= mapM (traverse' dir)) - - traverse' :: FilePath -> DirEntry -> Rev (Set PageName) - traverse' dir entry - = let path = dir entName entry - in - do kind <- checkPath path - case kind of - NoNode -> return S.empty - FileNode -> return $ S.singleton (decodePath path) - DirNode -> traverse path - - decodePath :: FilePath -> PageName - decodePath = decodePageName . makeRelative root . dropExtension - - -getDirContentsInRevision :: Repository -> PageName -> Maybe RevNum -> IO (Set PageName) -getDirContentsInRevision repos dir rev - = do fs <- getRepositoryFS repos - rev' <- case rev of - Nothing -> getYoungestRev fs - Just r -> return r - withRevision fs rev' - $ do exists <- isDirectory path - if exists then - return . S.fromList =<< getDir' - else - return S.empty - where - path :: FilePath - path = mkDirPath dir - - getDir' :: Rev [PageName] - getDir' = liftM (map entToName) (getDirEntries path) - - entToName :: DirEntry -> PageName - entToName = (dir ) . decodePageName . dropExtension . entName - - -findChangedPagesAtRevision :: Repository -> RevNum -> IO (Set PageName) -findChangedPagesAtRevision repos rev - = do fs <- getRepositoryFS repos - withRevision fs rev - $ liftM (foldl accumulatePages S.empty . map fst) getPathsChanged - where - accumulatePages :: Set PageName -> FilePath -> Set PageName - accumulatePages s path - | "/pages/" `isPrefixOf` path && ".page" `isSuffixOf` path - = let encoded = makeRelative "/pages" $ dropExtension path - name = decodePageName encoded - in - S.insert name s - | otherwise - = s - - -loadPageInRepository :: Repository -> PageName -> Maybe RevNum -> IO (Maybe Page) -loadPageInRepository repos name rev - = do fs <- getRepositoryFS repos - rev' <- case rev of - Nothing -> getYoungestRev fs - Just r -> return r - withRevision fs rev' - $ do exists <- isFile path - if exists then - return . Just =<< loadPage' fs - else - return Nothing - where - path :: FilePath - path = mkPagePath name - - loadPage' :: FileSystem -> Rev Page - loadPage' fs - = do mType <- liftM (fmap (read . chomp)) (getNodeProp path "svn:mime-type") - case mType of - Just (MIMEType "application" "x-rakka-redirection" _) - -> loadPageRedirect fs - _ - -> loadPageEntity fs - - loadPageEntity :: FileSystem -> Rev Page - loadPageEntity fs - = do props <- getNodePropList path - hist <- getNodeHistory True path - content <- getFileContentsLBS path - - let pageRev = fst $ head hist - mimeType = read - $ fromMaybe "text/x-rakka" - $ fmap chomp (lookup "svn:mime-type" props) - - lastMod <- unsafeIOToFS $ - liftM (fromJust . parseW3CDateTime . chomp . fromJust) - (getRevisionProp' fs pageRev "svn:date") - - return Entity { - entityName = name - , entityType = mimeType - , entityLanguage = fmap chomp (lookup "rakka:lang" props) - , entityIsTheme = any ((== "rakka:isTheme") . fst) props - , entityIsFeed = any ((== "rakka:isFeed") . fst) props - , entityIsLocked = any ((== "rakka:isLocked") . fst) props - , entityIsBinary = case mimeType of - MIMEType "text" _ _ - -> any ((== "rakka:isBinary") . fst) props - _ - -> True - , entityRevision = pageRev - , entityLastMod = zonedTimeToUTC lastMod - , entitySummary = fmap decodeString (lookup "rakka:summary" props) - , entityOtherLang = fromMaybe M.empty - $ fmap - (M.fromList . fromJust . deserializeStringPairs . decodeString) - (lookup "rakka:otherLang" props) - , entityContent = content - , entityUpdateInfo = undefined - } - - loadPageRedirect :: FileSystem -> Rev Page - loadPageRedirect fs - = do hist <- getNodeHistory True path - content <- getFileContents path - - let pageRev = fst $ head hist - dest = chomp $ decodeString content - - lastMod <- unsafeIOToFS $ - liftM (fromJust . parseW3CDateTime . chomp . fromJust) - (getRevisionProp' fs pageRev "svn:date") - - isLocked <- liftM isJust (getNodeProp path "rakka:isLocked") - - return Redirection { - redirName = name - , redirDest = dest - , redirIsLocked = isLocked - , redirRevision = pageRev - , redirLastMod = zonedTimeToUTC lastMod - , redirUpdateInfo = undefined - } - - -putPageIntoRepository :: Repository -> Maybe String -> Page -> IO StatusCode -putPageIntoRepository repos userID page - = do let name = pageName page - author = fromMaybe "[Rakka]" userID - case pageUpdateInfo page of - Just ui - -> do let oldRev = uiOldRevision ui - denied <- case uiOldName ui of - Nothing -> checkDenial oldRev name - Just oldName -> checkDenial oldRev oldName - if denied then - return Forbidden - else - do rev <- if oldRev == 0 then - getRepositoryFS repos >>= getYoungestRev - else - return oldRev - ret <- doReposTxn - repos - rev - author - (Just "Automatic commit by Rakka for page update") - $ do - case uiOldName ui of - Nothing -> return () - Just oldName -> do exists <- isFile (mkPagePath oldName) - when exists - $ do movePage (uiOldRevision ui) oldName name - moveAttachments (uiOldRevision ui) oldName name - exists <- isFile (mkPagePath name) - unless exists - $ createPage name - updatePage name - case ret of - Left _ -> return Conflict - Right _ -> return Created - Nothing - -> do fs <- getRepositoryFS repos - rev <- getYoungestRev fs - ret <- doReposTxn - repos - rev - author - (Just "Automatic commit by Rakka for page creation") - $ do createPage name - updatePage name - case ret of - Left _ -> return Conflict - Right _ -> return Created - where - checkDenial :: RevNum -> PageName -> IO Bool - checkDenial rev name - = do fs <- getRepositoryFS repos - withRevision fs rev - $ do exists <- isFile (mkPagePath name) - if exists then - do prop <- getNodeProp (mkPagePath name) "rakka:isLocked" - case prop of - Just _ -> return (isNothing userID) -- 施錠されてゐるので匿名では駄目 - Nothing -> return False - else - return False -- FIXME: 本當は defaultPage の locked 屬性をどうのこうの… - - movePage :: RevNum -> PageName -> PageName -> Txn () - movePage oldRev oldName newName - = do let oldPath = mkPagePath oldName - newPath = mkPagePath newName - createParentDirectories newPath - copyEntry oldRev oldPath newPath - deleteEntry oldPath - deleteEmptyParentDirectories oldPath - - moveAttachments :: RevNum -> PageName -> PageName -> Txn () - moveAttachments oldRev oldName newName - = do let oldPath = mkAttachmentDirPath oldName - newPath = mkAttachmentDirPath newName - createParentDirectories newPath - copyEntry oldRev oldPath newPath - deleteEntry oldPath - deleteEmptyParentDirectories oldPath - - createPage :: PageName -> Txn () - createPage name - = do let path = mkPagePath name - createParentDirectories path - makeFile path - - updatePage :: PageName -> Txn () - updatePage name - | isRedirect page = updatePageRedirect name - | isEntity page = updatePageEntity name - | otherwise = fail "neither redirection nor page" - - updatePageRedirect :: PageName -> Txn () - updatePageRedirect name - = do let path = mkPagePath name - setNodeProp path "svn:mime-type" (Just "application/x-rakka-redirection") - setNodeProp path "rakka:lang" Nothing - setNodeProp path "rakka:isTheme" Nothing - setNodeProp path "rakka:isFeed" Nothing - setNodeProp path "rakka:isLocked" (encodeFlag $ redirIsLocked page) - setNodeProp path "rakka:isBinary" Nothing - setNodeProp path "rakka:summary" Nothing - setNodeProp path "rakka:otherLang" Nothing - applyText path Nothing (encodeString (redirDest page) ++ "\n") - - updatePageEntity :: PageName -> Txn () - updatePageEntity name - = do let path = mkPagePath name - setNodeProp path "svn:mime-type" ((Just . show . entityType) page) - setNodeProp path "rakka:lang" (entityLanguage page) - setNodeProp path "rakka:isTheme" (encodeFlag $ entityIsTheme page) - setNodeProp path "rakka:isFeed" (encodeFlag $ entityIsFeed page) - setNodeProp path "rakka:isLocked" (encodeFlag $ entityIsLocked page) - setNodeProp path "rakka:isBinary" (encodeFlag $ entityIsBinary page) - setNodeProp path "rakka:summary" (fmap encodeString $ entitySummary page) - setNodeProp path "rakka:otherLang" (let otherLang = entityOtherLang page - in - if M.null otherLang then - Nothing - else - Just (encodeString $ serializeStringPairs $ M.toList otherLang)) - applyTextLBS path Nothing (entityContent page) - - encodeFlag :: Bool -> Maybe String - encodeFlag True = Just "*" - encodeFlag False = Nothing - - -createParentDirectories :: FilePath -> Txn () -createParentDirectories path - = do let parentPath = takeDirectory path - kind <- checkPath parentPath - case kind of - NoNode -> do createParentDirectories parentPath - makeDirectory parentPath - FileNode -> fail ("createParentDirectories: already exists a file: " ++ parentPath) - DirNode -> return () - - -deletePageFromRepository :: Repository -> Maybe String -> PageName -> IO StatusCode -deletePageFromRepository repos userID name - = do let pagePath = mkPagePath name - attachmentPath = mkAttachmentDirPath name - fs <- getRepositoryFS repos - rev <- getYoungestRev fs - status <- withRevision fs rev - $ do exists <- isFile pagePath - if exists then - do prop <- getNodeProp pagePath "rakka:isLocked" - return $ case prop of - Just _ - -> if isNothing userID then - -- 施錠されてゐるので匿名では駄目 - Forbidden - else - NoContent - Nothing - -> NoContent - else - return NotFound - when (status == NoContent) - $ ( (doReposTxn repos - rev - "[Rakka]" - (Just "Automatic commit by Rakka for page deleting") - $ do deleteEntry pagePath - deleteEmptyParentDirectories pagePath - - attachmentExists <- isDirectory attachmentPath - when attachmentExists - $ do deleteEntry attachmentPath - deleteEmptyParentDirectories attachmentPath) - >> return () ) - return status - - -deleteEmptyParentDirectories :: FilePath -> Txn () -deleteEmptyParentDirectories path - = do let parentPath = takeDirectory path - contents <- getDirEntries parentPath - when (null contents) - $ do deleteEntry parentPath - deleteEmptyParentDirectories parentPath - - -loadAttachmentInRepository :: forall a. Attachment a => - Repository - -> PageName - -> String - -> Maybe RevNum - -> IO (Maybe a) -loadAttachmentInRepository repos pName aName rev - = do fs <- getRepositoryFS repos - rev' <- case rev of - Nothing -> getYoungestRev fs - Just r -> return r - withRevision fs rev' - $ do exists <- isFile path - if exists then - return . Just =<< loadAttachment' - else - return Nothing - where - path :: FilePath - path = mkAttachmentPath pName aName - - loadAttachment' :: Rev a - loadAttachment' = liftM (deserializeFromString . decodeString) (getFileContents path) - - -putAttachmentIntoRepository :: Attachment a => - Repository - -> Maybe String - -> Maybe RevNum - -> PageName - -> String - -> a - -> IO StatusCode -putAttachmentIntoRepository repos userID oldRev pName aName attachment - = do let author = fromMaybe "[Rakka]" userID - path = mkAttachmentPath pName aName - fs <- getRepositoryFS repos - oldRev' <- case oldRev of - Nothing -> getYoungestRev fs - Just r -> return r - ret <- doReposTxn - repos - oldRev' - author - (Just "Automatic commit by Rakka for putting attachment") - $ do exists <- isFile path - unless exists - $ do createParentDirectories path - makeFile path - applyText path Nothing (encodeString $ serializeToString attachment) - case ret of - Left _ -> return Conflict - Right _ -> return NoContent rmfile ./Rakka/Storage/Repos.hs hunk ./Rakka/Storage/Types.hs 1 -module Rakka.Storage.Types - ( Storage(..) - , IndexReq(..) - , SearchResult(..) - , HitPage(..) - , SnippetFragment(..) - ) - where - -import Control.Concurrent.STM -import Data.Time -import Rakka.Page -import Subversion.Repository -import Subversion.Types -import Text.HyperEstraier hiding (WriteLock) - - -data Storage - = Storage { - stoRepository :: !Repository - , stoIndexChan :: !(TChan IndexReq) - } - - -data IndexReq - = RebuildIndex - | SyncIndex - | SearchIndex !Condition !(TMVar SearchResult) - - -data SearchResult - = SearchResult { - srTotal :: !Int - , srPages :: ![HitPage] - } - deriving (Show, Eq) - - -data HitPage - = HitPage { - hpPageName :: !PageName - , hpPageRev :: RevNum - , hpLastMod :: UTCTime - , hpSummary :: Maybe String - , hpSnippet :: [SnippetFragment] - } - deriving (Show, Eq) - - -data SnippetFragment - = Boundary - | NormalText !String - | HighlightedWord !String - deriving (Show, Eq) + rmfile ./Rakka/Storage/Types.hs rmdir ./Rakka/Storage hunk ./Rakka/Storage.hs 1 -module Rakka.Storage - ( Storage - - -- re-export from Rakka.Storage.Types - , SearchResult(..) - , HitPage(..) - , SnippetFragment(..) - - , mkStorage -- private - - , getPage - , putPage - , deletePage - - , getPageA - , putPageA - , deletePageA - - , getAttachment - , putAttachment - - , getDirContents - , getDirContentsA - - , searchPages - - , rebuildIndex - ) - where - -import Control.Arrow.ArrowIO -import Control.Concurrent.STM -import Control.Monad.Trans -import Network.HTTP.Lucu -import Rakka.Attachment -import Rakka.Page -import Rakka.Storage.Impl -import Rakka.Storage.Types -import Subversion.Types -import Subversion.Repository -import Text.HyperEstraier hiding (WriteLock) - - -mkStorage :: FilePath -> Repository -> (Page -> IO Document) -> IO Storage -mkStorage lsdir repos mkDraft - = do chan <- startIndexManager lsdir repos mkDraft - let sto = Storage { - stoRepository = repos - , stoIndexChan = chan - } - syncIndex sto - return sto - - -getPage :: MonadIO m => Storage -> PageName -> Maybe RevNum -> m (Maybe Page) -getPage = ((liftIO .) .) . getPage' . stoRepository - - -putPage :: MonadIO m => Storage -> Maybe String -> Page -> m StatusCode -putPage sto userID page - = liftIO $ do st <- putPage' (stoRepository sto) userID page - syncIndex sto - return st - - -deletePage :: MonadIO m => Storage -> Maybe String -> PageName -> m StatusCode -deletePage sto userID name - = liftIO $ do st <- deletePage' (stoRepository sto) userID name - syncIndex sto - return st - - -getPageA :: ArrowIO a => Storage -> a (PageName, Maybe RevNum) (Maybe Page) -getPageA = arrIO2 . getPage - - -putPageA :: ArrowIO a => Storage -> a (Maybe String, Page) StatusCode -putPageA = arrIO2 . putPage - - -deletePageA :: ArrowIO a => Storage -> a (Maybe String, PageName) StatusCode -deletePageA = arrIO2 . deletePage - - -getDirContents :: MonadIO m => Storage -> PageName -> Maybe RevNum -> m [PageName] -getDirContents = ((liftIO .) .) . getDirContents' . stoRepository - - -getDirContentsA :: ArrowIO a => Storage -> a (PageName, Maybe RevNum) [PageName] -getDirContentsA = arrIO2 . getDirContents - - -searchPages :: MonadIO m => Storage -> Condition -> m SearchResult -searchPages sto cond - = liftIO $ - do var <- newEmptyTMVarIO - atomically $ writeTChan (stoIndexChan sto) (SearchIndex cond var) - atomically $ takeTMVar var - - -rebuildIndex :: MonadIO m => Storage -> m () -rebuildIndex sto - = liftIO $ atomically $ writeTChan (stoIndexChan sto) RebuildIndex - - -syncIndex :: Storage -> IO () -syncIndex sto - = atomically $ writeTChan (stoIndexChan sto) SyncIndex - - -getAttachment :: (Attachment a, MonadIO m) => - Storage - -> PageName - -> String - -> Maybe RevNum - -> m (Maybe a) -getAttachment = (((liftIO .) .) .) . getAttachment' . stoRepository - - -putAttachment :: (Attachment a, MonadIO m) => - Storage - -> Maybe String - -> Maybe RevNum - -> PageName - -> String - -> a - -> m StatusCode -putAttachment = (((((liftIO .) .) .) .) .) . putAttachment' . stoRepository rmfile ./Rakka/Storage.hs hunk ./Rakka/SystemConfig.hs 1 -module Rakka.SystemConfig - ( SystemConfig - , SysConfValue(..) - - , mkSystemConfig -- private - - , getSysConf - , getSysConfA - - , setSysConf - , setSysConfA - - , SiteName(..) - , BaseURI(..) - , DefaultPage(..) - , StyleSheet(..) - , Languages(..) - , GlobalLock(..) - - , serializeStringPairs - , deserializeStringPairs - ) - where - -import Codec.Binary.UTF8.String -import Control.Arrow.ArrowIO -import Control.Concurrent.STM -import Control.Monad -import Control.Monad.Trans -import qualified Data.ByteString.Char8 as C8 -import qualified Data.ByteString.Lazy as L -import Data.Dynamic -import Data.Map (Map) -import qualified Data.Map as M -import Data.Maybe -import GHC.Conc (unsafeIOToSTM) -import Network -import qualified Network.HTTP.Lucu.Config as LC -import Network.HTTP.Lucu.Utils -import Network.HTTP.Lucu hiding (Config) -import Network.URI hiding (path) -import Rakka.Page -import Rakka.Utils -import Subversion.FileSystem -import Subversion.FileSystem.Revision -import Subversion.FileSystem.Root -import Subversion.FileSystem.Transaction -import Subversion.Repository -import Subversion.Types -import System.FilePath.Posix -import System.Log.Logger - - -logger :: String -logger = "Rakka.SystemConfig" - - -data SystemConfig = SystemConfig { - scLucuConf :: !LC.Config - , scRepository :: !Repository - , scCache :: !(TVar (Map FilePath Dynamic)) - } - - -class (Typeable a, Show a, Eq a) => SysConfValue a where - confPath :: a -> FilePath - serialize :: a -> String - deserialize :: String -> Maybe a - defaultValue :: SystemConfig -> a - - -mkSystemConfig :: LC.Config -> Repository -> IO SystemConfig -mkSystemConfig lc repos - = do cache <- newTVarIO M.empty - return SystemConfig { - scLucuConf = lc - , scRepository = repos - , scCache = cache - } - -getSysConf :: forall m a. (MonadIO m, SysConfValue a) => SystemConfig -> m a -getSysConf sc - = liftIO $ - atomically $ - do let path = confPath (undefined :: a) - - cache <- readTVar (scCache sc) - - case M.lookup path cache of - Just val -> return $ fromJust $ fromDynamic val - Nothing -> do val <- unsafeIOToSTM (getSysConf' sc) - writeTVar (scCache sc) (M.insert path (toDyn val) cache) - return val - - -getSysConf' :: forall a. SysConfValue a => SystemConfig -> IO a -getSysConf' sc - = do let path = fromConfPath $ confPath (undefined :: a) - - fs <- getRepositoryFS (scRepository sc) - rev <- getYoungestRev fs - value <- withRevision fs rev - $ do exists <- isFile path - case exists of - True - -> do str <- getFileContentsLBS path - return $ Just $ chomp $ decode $ L.unpack str - False - -> return Nothing - - case value of - Just str - -> case deserialize str of - Just val - -> do debugM logger ("Got a config value at `" ++ path ++ "': " ++ show val) - return val - Nothing - -> fail ("Got an invalid config value at `" ++ path ++ "': " ++ str) - Nothing - -> do let val = defaultValue sc - debugM logger ("Got no config value at `" ++ path ++ "'. Defaulting to " ++ show val) - return val - - -setSysConf :: forall m a. (MonadIO m, SysConfValue a) => SystemConfig -> String -> a -> m StatusCode -setSysConf sc userID value - = liftIO $ - do let path = confPath (undefined :: a) - - current <- getSysConf sc - if current == value - then return NotModified - else do atomically $ do cache <- readTVar (scCache sc) - writeTVar (scCache sc) (M.delete path cache) - setSysConf' sc userID value - - -setSysConf' :: forall a. SysConfValue a => SystemConfig -> String -> a -> IO StatusCode -setSysConf' sc userID value - = do let path = fromConfPath $ confPath (undefined :: a) - str = L.pack $ encode $ serialize value ++ "\n" - repos = scRepository sc - fs <- getRepositoryFS repos - rev <- getYoungestRev fs - ret <- doReposTxn - repos - rev - userID - (Just "Automatic commit by Rakka for systemConfig update") - $ do exists <- isFile path - unless exists - $ createValueEntry path - applyTextLBS path Nothing str - case ret of - Left _ -> return Conflict - Right _ -> do debugM logger ("Set a config value at `" ++ path ++ "': " ++ show value) - return Created - where - createValueEntry :: FilePath -> Txn () - createValueEntry path - = do createParentDirectories path - makeFile path - - createParentDirectories :: FilePath -> Txn () - createParentDirectories path - = do let parentPath = takeDirectory path - kind <- checkPath parentPath - case kind of - NoNode -> do createParentDirectories parentPath - makeDirectory parentPath - FileNode -> fail ("createParentDirectories: already exists a file: " ++ parentPath) - DirNode -> return () - - -getSysConfA :: (ArrowIO a, SysConfValue c) => SystemConfig -> a b c -getSysConfA = arrIO0 . getSysConf - - -setSysConfA :: (ArrowIO a, SysConfValue c) => SystemConfig -> String -> a c StatusCode -setSysConfA = (arrIO .) . setSysConf - - -fromConfPath :: FilePath -> FilePath -fromConfPath = ("/config" ) - - -serializeStringPairs :: [(String, String)] -> String -serializeStringPairs = joinWith "\n" . map serializePair' - where - serializePair' :: (String, String) -> String - serializePair' (a, b) = a ++ " " ++ b - - -deserializeStringPairs :: String -> Maybe [(String, String)] -deserializeStringPairs = mapM deserializePair' . lines - where - deserializePair' :: String -> Maybe (String, String) - deserializePair' s = case break (== ' ') s of - (a, ' ':b) -> Just (a, b) - _ -> Nothing - - - -{- config values -} - -newtype SiteName = SiteName String deriving (Show, Typeable, Eq) -instance SysConfValue SiteName where - confPath _ = "siteName" - serialize (SiteName name) = name - deserialize = Just . SiteName - defaultValue _ = SiteName "Rakka" - - -newtype BaseURI = BaseURI URI deriving (Show, Typeable, Eq) -instance SysConfValue BaseURI where - confPath _ = "baseURI" - serialize (BaseURI uri) = uriToString id uri "" - deserialize uri = fmap BaseURI - $ do parsed <- parseURI uri - when (uriPath parsed == "" ) (fail undefined) - when (last (uriPath parsed) /= '/') (fail undefined) - when (uriQuery parsed /= "" ) (fail undefined) - when (uriFragment parsed /= "" ) (fail undefined) - return parsed - defaultValue sc - = let conf = scLucuConf sc - host = C8.unpack $ LC.cnfServerHost conf - port = case LC.cnfServerPort conf of - PortNumber num -> fromIntegral num :: Int - _ -> undefined - defaultURI - = "http://" ++ host ++ -- FIXME: consider IPv6 address - (if port == 80 - then "" - else ':' : show port) ++ "/" - in - BaseURI $ fromJust $ parseURI defaultURI - - -newtype DefaultPage = DefaultPage String deriving (Show, Typeable, Eq) -instance SysConfValue DefaultPage where - confPath _ = "defaultPage" - serialize (DefaultPage name) = name - deserialize = Just . DefaultPage - defaultValue _ = DefaultPage "MainPage" - - -newtype StyleSheet = StyleSheet String deriving (Show, Typeable, Eq) -instance SysConfValue StyleSheet where - confPath _ = "styleSheet" - serialize (StyleSheet name) = name - deserialize = Just . StyleSheet - defaultValue _ = StyleSheet "StyleSheet/Default" - - -newtype Languages = Languages (Map LanguageTag LanguageName) deriving (Show, Typeable, Eq) -instance SysConfValue Languages where - confPath _ = "languages" - serialize (Languages langs) = serializeStringPairs (M.toList langs) - deserialize = fmap (Languages . M.fromList) . deserializeStringPairs - defaultValue _ - = Languages $ M.fromList [ ("en", "English" ) - , ("es", "Español" ) - , ("de", "Deutsch" ) - , ("fi", "Suomi" ) - , ("fr", "Français" ) - , ("ga", "Gaeilge" ) - , ("gd", "Gàidhlig" ) - , ("ja", "日本語" ) - , ("pt", "Português") - , ("sv", "Svenska" ) - ] - - -newtype GlobalLock = GlobalLock Bool deriving (Show, Typeable, Eq) -instance SysConfValue GlobalLock where - confPath _ = "globalLock" - serialize (GlobalLock isLocked) - | isLocked = "*" - | otherwise = "" - deserialize "*" = Just (GlobalLock True) - deserialize "" = Just (GlobalLock False) - deserialize _ = Nothing - defaultValue _ = GlobalLock False rmfile ./Rakka/SystemConfig.hs hunk ./Rakka/TrackBack.hs 1 -module Rakka.TrackBack - ( TrackBack(..) - ) - where - -import Data.Maybe -import Data.Time -import Network.URI -import Rakka.Attachment -import Rakka.Utils -import Rakka.W3CDateTime -import Text.XML.HXT.Arrow -import Text.XML.HXT.DOM.TypeDefs - - -data TrackBack - = TrackBack { - tbTitle :: !(Maybe String) - , tbExcerpt :: !(Maybe String) - , tbURL :: !URI - , tbBlogName :: !(Maybe String) - , tbTime :: !UTCTime - } - deriving (Show, Eq) - - -{- - - - excerpt... - - ... - --} -instance Attachment [TrackBack] where - serializeToXmlTree - = proc trackbacks - -> ( eelem "/" - += ( eelem "trackbacks" - += ( arrL id - >>> - tbToTree - ) - ) - ) -< trackbacks - where - tbToTree :: ArrowXml a => a TrackBack XmlTree - tbToTree - = proc tb - -> let title = case tbTitle tb of - Nothing -> none - Just t -> sattr "title" t - excerpt = case tbExcerpt tb of - Nothing -> none - Just e -> txt e - url = sattr "url" (uriToString id (tbURL tb) "") - blogName = case tbBlogName tb of - Nothing -> none - Just n -> sattr "blogName" n - time = sattr "time" (formatW3CDateTime $ utcToZonedTime utc (tbTime tb)) - in - ( eelem "trackback" - += title - += url - += blogName - += time - += excerpt - ) -<< () - - deserializeFromXmlTree - = proc doc -> listA (getXPathTreesInDoc "/trackbacks/trackback" >>> treeToTb) -< doc - where - treeToTb :: (ArrowChoice a, ArrowXml a) => a XmlTree TrackBack - treeToTb - = proc tree - -> do title <- maybeA (getAttrValue0 "title") -< tree - url <- ( getAttrValue0 "url" - >>> - arr (fromJust . parseURI) - ) -< tree - time <- ( getAttrValue0 "time" - >>> - arr (zonedTimeToUTC . fromJust . parseW3CDateTime) - ) -< tree - blogName <- maybeA (getAttrValue0 "blogName") -< tree - excerpt <- maybeA ( getChildren - >>> - getText - ) -< tree - returnA -< TrackBack { - tbTitle = title - , tbExcerpt = excerpt - , tbURL = url - , tbBlogName = blogName - , tbTime = time - } rmfile ./Rakka/TrackBack.hs hunk ./Rakka/Utils.hs 1 -module Rakka.Utils - ( yesOrNo - , trueOrFalse - , parseYesOrNo - , maybeA - , deleteIfEmpty - , chomp - , guessMIMEType - , isSafeChar - , mkQueryString - ) - where - -import qualified Codec.Binary.UTF8.String as UTF8 -import Control.Arrow -import Control.Arrow.ArrowList -import qualified Data.ByteString.Lazy as Lazy (ByteString) -import qualified Data.ByteString.Lazy.Char8 as L8 hiding (ByteString) -import Magic -import Network.HTTP.Lucu -import Network.URI -import System.IO.Unsafe - - -yesOrNo :: Bool -> String -yesOrNo True = "yes" -yesOrNo False = "no" - - -trueOrFalse :: Bool -> String -trueOrFalse True = "true" -trueOrFalse False = "false" - - -parseYesOrNo :: ArrowChoice a => a String Bool -parseYesOrNo - = proc str -> do case str of - "yes" -> returnA -< True - "no" -> returnA -< False - _ -> returnA -< error ("Expected yes or no: " ++ str) - - -maybeA :: (ArrowList a, ArrowChoice a) => a b c -> a b (Maybe c) -maybeA a = listA a - >>> - proc xs -> case xs of - [] -> returnA -< Nothing - (x:_) -> returnA -< Just x - - -deleteIfEmpty :: (ArrowList a, ArrowChoice a) => a String String -deleteIfEmpty - = proc str -> do case str of - "" -> none -< () - _ -> returnA -< str - - -chomp :: String -> String -chomp = reverse . snd . break (/= '\n') . reverse - - -guessMIMEType :: Lazy.ByteString -> MIMEType -guessMIMEType = read . unsafePerformIO . magicString magic . L8.unpack - where - magic :: Magic - magic = unsafePerformIO - $ do m <- magicOpen [MagicMime] - magicLoadDefault m - return m - - -isSafeChar :: Char -> Bool -isSafeChar c - | c == '/' = True - | isReserved c = False - | c > ' ' && c <= '~' = True - | otherwise = False - - -mkQueryString :: [(String, String)] -> String -mkQueryString [] = "" -mkQueryString ((k, v) : xs) = encode k ++ "=" ++ encode v ++ - if xs == [] then - "" - else - ';' : mkQueryString(xs) - where - encode :: String -> String - encode = escapeURIString isSafeChar . UTF8.encodeString + rmfile ./Rakka/Utils.hs hunk ./Rakka/Validation.hs 1 -module Rakka.Validation - ( getValidator - ) - where - -import Control.Arrow -import Control.Arrow.ArrowList -import Control.Arrow.ArrowTree -import Control.Monad.Reader -import Paths_Rakka -- Cabal が用意する。 -import Rakka.Environment -import System.Directory -import System.FilePath -import Text.XML.HXT.Arrow.XmlArrow -import Text.XML.HXT.Arrow.XmlIOStateArrow -import Text.XML.HXT.DOM.TypeDefs -import qualified Text.XML.HXT.RelaxNG.Schema as S -import Text.XML.HXT.RelaxNG.Validator - - -loadSchema :: FilePath -> IO (IOSArrow XmlTree XmlTree) -loadSchema fpath - = do [schema] <- runX ( setErrorMsgHandler False fail - >>> - readForRelax [] fpath - >>> - perform (validateWithRelaxAndHandleErrors S.relaxSchemaArrow) - >>> - createSimpleForm [] True True True - >>> - perform ( getErrors - >>> - getChildren >>> getAttrValue "desc" - >>> - arr ("Relax NG validation: " ++ ) - >>> - mkError c_err - >>> - filterErrorMsg - ) - ) - return $ validateDocumentWithRelax schema - - -doesLocalDirExist :: IO Bool -doesLocalDirExist = doesDirectoryExist "schemas" - - -getValidator :: MonadIO m => Environment -> FilePath -> m (IOSArrow XmlTree XmlTree) -getValidator _ fname - = liftIO $ - do let schemaPath = "schemas" fname - - localDirExists <- doesLocalDirExist - if localDirExists then - loadSchema schemaPath - else - getDataFileName ("schemas" fname) >>= loadSchema rmfile ./Rakka/Validation.hs hunk ./Rakka/W3CDateTime.hs 1 -module Rakka.W3CDateTime - ( formatW3CDateTime - , parseW3CDateTime - ) - where - -import Control.Monad -import Data.Time -import Prelude hiding (min) -import Text.ParserCombinators.Parsec -import Text.Printf - - -formatW3CDateTime :: ZonedTime -> String -formatW3CDateTime zonedTime - = formatLocalTime (zonedTimeToLocalTime zonedTime) - ++ - formatTimeZone (zonedTimeZone zonedTime) - where - formatLocalTime :: LocalTime -> String - formatLocalTime localTime - = let (year, month, day) = toGregorian (localDay localTime) - timeOfDay = localTimeOfDay localTime - (secInt, secFrac) = properFraction (todSec timeOfDay) - in - printf "%04d-%02d-%02dT%02d:%02d:%02d" - year - month - day - (todHour timeOfDay) - (todMin timeOfDay) - (secInt :: Int) - ++ - (if secFrac == 0 - then "" - else tail (show secFrac)) - - formatTimeZone :: TimeZone -> String - formatTimeZone tz - = case timeZoneMinutes tz of - offset | offset < 0 -> '-' : (showTZ $ negate offset) - | offset == 0 -> "Z" - | otherwise -> '+' : showTZ offset - - showTZ :: Int -> String - showTZ offset - = let hour = offset `div` 60 - minute = offset - hour * 60 - in - show2 hour ++ ":" ++ show2 minute - - show2 :: Int -> String - show2 n | n < 10 = '0' : show n - | otherwise = show n - - -parseW3CDateTime :: String -> Maybe ZonedTime -parseW3CDateTime src - = case parse w3cDateTime "" src of - Right zt -> Just zt - Left _ -> Nothing - -w3cDateTime :: Parser ZonedTime -w3cDateTime = do year <- liftM read (count 4 digit) - mon <- option 1 (char '-' >> liftM read (count 2 digit)) - day <- option 1 (char '-' >> liftM read (count 2 digit)) - (hour, min, sec, offMin) - <- option (0, 0, 0, 0) time - eof - - let julianDay = fromGregorian year mon day - timeOfDay = TimeOfDay hour min (fromRational $ toRational sec) - localTime = LocalTime julianDay timeOfDay - timeZone = minutesToTimeZone offMin - zonedTime = ZonedTime localTime timeZone - - return zonedTime - where - time :: Parser (Int, Int, Double, Int) - time = do _ <- char 'T' - hour <- liftM read (count 2 digit) - _ <- char ':' - min <- liftM read (count 2 digit) - sec <- option 0 $ do _ <- char ':' - secInt <- count 2 digit - secFrac <- option "" $ do c <- char '.' - cs <- many1 digit - return (c:cs) - return $ read (secInt ++ secFrac) - offMin <- (char 'Z' >> return 0) - <|> - (do sign <- (char '+' >> return 1) - <|> - (char '-' >> return (-1)) - h <- liftM read (count 2 digit) - _ <- char ':' - m <- liftM read (count 2 digit) - return $ sign * h * 60 + m) - return (hour, min, sec, offMin) + rmfile ./Rakka/W3CDateTime.hs hunk ./Rakka/Wiki/Engine.hs 1 -module Rakka.Wiki.Engine - ( InterpTable - , makeMainXHTML - , makeSubXHTML - , makePreviewXHTML - , makePageLinkList - , makeDraft - ) - where - -import qualified Codec.Binary.UTF8.String as UTF8 -import qualified Data.ByteString.Lazy as Lazy -import qualified Data.ByteString.Lazy.Char8 as L8 hiding (ByteString) -import Data.Map (Map) -import qualified Data.Map as M -import Data.Maybe -import Network.HTTP.Lucu -import Network.URI -import OpenSSL.EVP.Base64 -import Rakka.Page -import Rakka.Storage -import Rakka.SystemConfig -import Rakka.Utils -import Rakka.Wiki -import Rakka.Wiki.Parser -import Rakka.Wiki.Formatter -import Rakka.Wiki.Interpreter -import Text.HyperEstraier hiding (getText) -import Text.ParserCombinators.Parsec -import Text.XML.HXT.Arrow hiding (err) -import Text.XML.HXT.XPath - - -type InterpTable = Map String Interpreter - - -wikifyPage :: (ArrowXml a, ArrowChoice a) => InterpTable -> a XmlTree WikiPage -wikifyPage interpTable - = proc tree - -> do pType <- getXPathTreesInDoc "/page/@type/text()" >>> getText >>> arr read -< tree - textData <- maybeA (getXPathTreesInDoc "/page/textData/text()" >>> getText) -< tree - base64Data <- maybeA (getXPathTreesInDoc "/page/binaryData/text()" >>> getText) -< tree - - let dataURI = fmap (binToURI pType) base64Data - - case pType of - MIMEType "text" "x-rakka" _ - -> case parse (wikiPage $ cmdTypeOf interpTable) "" (fromJust textData) of - Left err -> wikifyParseError -< err - Right xs -> returnA -< xs - - MIMEType "image" _ _ - -- - -> returnA -< [ Paragraph [Image (Left $ fromJust dataURI) Nothing] ] - - _ -> if isJust dataURI then - -- - -- application/zip - -- - returnA -< [ Paragraph [ Anchor - [("href", show dataURI)] - [Text (show pType)] - ] - ] - else - -- pre - returnA -< [ Preformatted [Text $ fromJust textData] ] - where - binToURI :: MIMEType -> String -> URI - binToURI pType base64Data - = nullURI { - uriScheme = "data:" - , uriPath = show pType ++ ";base64," ++ (stripWhiteSpace base64Data) - } - - stripWhiteSpace :: String -> String - stripWhiteSpace [] = [] - stripWhiteSpace (x:xs) - | x `elem` " \t\n" = stripWhiteSpace xs - | otherwise = x : stripWhiteSpace xs - - -wikifyBin :: (ArrowXml a, ArrowChoice a) => InterpTable -> a (MIMEType, Lazy.ByteString) WikiPage -wikifyBin interpTable - = proc (pType, pBin) - -> do let text = UTF8.decode $ Lazy.unpack pBin - dataURI = binToURI pType pBin - - case pType of - MIMEType "text" "x-rakka" _ - -> case parse (wikiPage $ cmdTypeOf interpTable) "" text of - Left err -> wikifyParseError -< err - Right xs -> returnA -< xs - - MIMEType "image" _ _ - -- - -> returnA -< [ Paragraph [Image (Left dataURI) Nothing] ] - - - _ - -- - -- application/zip (19372 bytes) - -- - -> returnA -< [ Paragraph [ Anchor - [("href", show dataURI)] - [Text (show pType ++ - " (" ++ - show (Lazy.length pBin) ++ - " bytes)")] - ] - ] - where - binToURI :: MIMEType -> Lazy.ByteString -> URI - binToURI m b - = nullURI { - uriScheme = "data:" - , uriPath = show m ++ ";base64," ++ (L8.unpack $ encodeBase64LBS b) - } - - -cmdTypeOf :: InterpTable -> String -> Maybe CommandType -cmdTypeOf interpTable name - = fmap commandType (M.lookup name interpTable) - - -makeMainXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => - Storage - -> SystemConfig - -> InterpTable - -> a XmlTree XmlTree -makeMainXHTML sto sysConf interpTable - = proc tree - -> do BaseURI baseURI <- getSysConfA sysConf -< () - wiki <- wikifyPage interpTable -< tree - pName <- getXPathTreesInDoc "/page/@name/text()" >>> getText -< tree - interpreted <- interpretCommands sto sysConf interpTable - -< (Just pName, Just tree, Just wiki, wiki) - formatWikiBlocks -< (baseURI, interpreted) - - -makeSubXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => - Storage - -> SystemConfig - -> InterpTable - -> a (Maybe PageName, Maybe XmlTree, XmlTree) XmlTree -makeSubXHTML sto sysConf interpTable - = proc (mainPageName, mainPage, subPage) - -> do BaseURI baseURI <- getSysConfA sysConf -< () - mainWiki <- case mainPage of - Just page - -> do wiki <- wikifyPage interpTable -< page - returnA -< Just (page, wiki) - Nothing - -> returnA -< Nothing - subWiki <- wikifyPage interpTable -< subPage - interpreted <- interpretCommands sto sysConf interpTable - -< (mainPageName, fmap fst mainWiki, fmap snd mainWiki, subWiki) - formatWikiBlocks -< (baseURI, interpreted) - - -makePreviewXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => - Storage - -> SystemConfig - -> InterpTable - -> a (PageName, MIMEType, Lazy.ByteString) XmlTree -makePreviewXHTML sto sysConf interpTable - = proc (name, pageType, pageBin) - -> do BaseURI baseURI <- getSysConfA sysConf -< () - wiki <- wikifyBin interpTable -< (pageType, pageBin) - interpreted <- interpretCommands sto sysConf interpTable - -< (Just name, Nothing, Just wiki, wiki) - formatWikiBlocks -< (baseURI, interpreted) - - -interpretCommands :: (ArrowXml a, ArrowChoice a, ArrowIO a) => - Storage - -> SystemConfig - -> InterpTable - -> a (Maybe PageName, Maybe XmlTree, Maybe WikiPage, WikiPage) WikiPage -interpretCommands sto sysConf interpTable - = proc (name, mainPage, mainWiki, targetWiki) - -> let ctx = InterpreterContext { - ctxPageName = name - , ctxMainPage = mainPage - , ctxMainWiki = mainWiki - , ctxTargetWiki = targetWiki - , ctxStorage = sto - , ctxSysConf = sysConf - } - in - arrIO2 (mapM . interpBlock) -< (ctx, targetWiki) - where - interpElem :: InterpreterContext -> Element -> IO Element - interpElem ctx (Block b) = interpBlock ctx b >>= return . Block - interpElem ctx (Inline i) = interpInline ctx i >>= return . Inline - - interpBlock :: InterpreterContext -> BlockElement -> IO BlockElement - interpBlock ctx (List lType lItems) = mapM (interpListItem ctx) lItems >>= return . List lType - interpBlock ctx (DefinitionList defs) = mapM (interpDefinition ctx) defs >>= return . DefinitionList - interpBlock ctx (Preformatted inlines) = mapM (interpInline ctx) inlines >>= return . Preformatted - interpBlock ctx (Paragraph inlines) = mapM (interpInline ctx) inlines >>= return . Paragraph - interpBlock ctx (Div attrs elems) = mapM (interpElem ctx) elems >>= return . Div attrs - interpBlock ctx (BlockCmd bcmd) = interpBlockCommand ctx bcmd - interpBlock _ x = return x - - interpInline :: InterpreterContext -> InlineElement -> IO InlineElement - interpInline ctx (Italic inlines) = mapM (interpInline ctx) inlines >>= return . Italic - interpInline ctx (Bold inlines) = mapM (interpInline ctx) inlines >>= return . Bold - interpInline ctx (Span attrs inlines) = mapM (interpInline ctx) inlines >>= return . Span attrs - interpInline ctx (Anchor attrs inlines) = mapM (interpInline ctx) inlines >>= return . Anchor attrs - interpInline ctx (InlineCmd icmd) = interpInlineCommand ctx icmd - interpInline _ x = return x - - interpListItem :: InterpreterContext -> ListItem -> IO ListItem - interpListItem = mapM . interpElem - - interpDefinition :: InterpreterContext -> Definition -> IO Definition - interpDefinition ctx (Definition term desc) - = do term' <- mapM (interpInline ctx) term - desc' <- mapM (interpInline ctx) desc - return (Definition term' desc') - - interpBlockCommand :: InterpreterContext -> BlockCommand -> IO BlockElement - interpBlockCommand ctx cmd - = case M.lookup (bCmdName cmd) interpTable of - Nothing - -> fail ("no such interpreter: " ++ bCmdName cmd) - - Just interp - -> bciInterpret interp ctx cmd - >>= - interpBlock ctx - - interpInlineCommand :: InterpreterContext -> InlineCommand -> IO InlineElement - interpInlineCommand ctx cmd - = case M.lookup (iCmdName cmd) interpTable of - Nothing - -> fail ("no such interpreter: " ++ iCmdName cmd) - - Just interp - -> iciInterpret interp ctx cmd - >>= - interpInline ctx - - -makeDraft :: (ArrowXml a, ArrowChoice a, ArrowIO a) => InterpTable -> a XmlTree Document -makeDraft interpTable - = proc tree -> - do redir <- maybeA (getXPathTreesInDoc "/page/@redirect") -< tree - case redir of - Nothing -> makeEntityDraft -< tree - Just _ -> makeRedirectDraft -< tree - where - makeEntityDraft :: (ArrowXml a, ArrowChoice a, ArrowIO a) => a XmlTree Document - makeEntityDraft - = proc tree -> - do doc <- arrIO0 newDocument -< () - - pName <- getXPathTreesInDoc "/page/@name/text()" >>> getText -< tree - pType <- getXPathTreesInDoc "/page/@type/text()" >>> getText -< tree - pLastMod <- getXPathTreesInDoc "/page/@lastModified/text()" >>> getText -< tree - pIsLocked <- getXPathTreesInDoc "/page/@isLocked/text()" >>> getText -< tree - pIsBinary <- getXPathTreesInDoc "/page/@isBinary/text()" >>> getText -< tree - pRevision <- getXPathTreesInDoc "/page/@revision/text()" >>> getText -< tree - pLang <- maybeA (getXPathTreesInDoc "/page/@lang/text()" >>> getText) -< tree - pIsTheme <- maybeA (getXPathTreesInDoc "/page/@isTheme/text()" >>> getText) -< tree - pIsFeed <- maybeA (getXPathTreesInDoc "/page/@isFeed/text()" >>> getText) -< tree - pSummary <- maybeA (getXPathTreesInDoc "/page/summary/text()" >>> getText) -< tree - - arrIO2 setURI -< (doc, Just $ mkRakkaURI pName) - arrIO2 (flip setAttribute "@title" ) -< (doc, Just pName) - arrIO2 (flip setAttribute "@type" ) -< (doc, Just pType) - arrIO2 (flip setAttribute "@mdate" ) -< (doc, Just pLastMod) - arrIO2 (flip setAttribute "@lang" ) -< (doc, pLang) - arrIO2 (flip setAttribute "rakka:isLocked") -< (doc, Just pIsLocked) - arrIO2 (flip setAttribute "rakka:isBinary") -< (doc, Just pIsBinary) - arrIO2 (flip setAttribute "rakka:revision") -< (doc, Just pRevision) - arrIO2 (flip setAttribute "rakka:summary" ) -< (doc, pSummary) - - arrIO2 addHiddenText -< (doc, pName) - - case pSummary of - Just s -> arrIO2 addHiddenText -< (doc, s) - Nothing -> returnA -< () - - -- otherLang はリンク先ページ名を hidden text で入れる。 - otherLangs <- listA (getXPathTreesInDoc "/page/otherLang/link/@page/text()" >>> getText) -< tree - listA ( (arr fst &&& arrL snd) - >>> - arrIO2 addHiddenText - >>> - none - ) -< (doc, otherLangs) - - case read pType of - MIMEType "text" "css" _ - -> arrIO2 (flip setAttribute "rakka:isTheme") -< (doc, pIsTheme) - - MIMEType "text" "x-rakka" _ - -- wikify して興味のある部分を addText する。 - -> do arrIO2 (flip setAttribute "rakka:isFeed") -< (doc, pIsFeed) - wiki <- wikifyPage interpTable -< tree - arrIO2 (mapM_ . addBlockText) -< (doc, wiki) - - MIMEType _ _ _ - -> returnA -< () - - returnA -< doc - - makeRedirectDraft :: (ArrowXml a, ArrowChoice a, ArrowIO a) => a XmlTree Document - makeRedirectDraft - = proc tree -> - do doc <- arrIO0 newDocument -< () - - pName <- getXPathTreesInDoc "/page/@name/text()" >>> getText -< tree - pRedir <- getXPathTreesInDoc "/page/@redirect/text()" >>> getText -< tree - pIsLocked <- getXPathTreesInDoc "/page/@isLocked/text()" >>> getText -< tree - pRevision <- getXPathTreesInDoc "/page/@revision/text()" >>> getText -< tree - pLastMod <- getXPathTreesInDoc "/page/@lastModified/text()" >>> getText -< tree - - arrIO2 setURI -< (doc, Just $ mkRakkaURI pName) - arrIO2 (flip setAttribute "@title" ) -< (doc, Just pName) - arrIO2 (flip setAttribute "@type" ) -< (doc, Just "application/x-rakka-redirection") - arrIO2 (flip setAttribute "@mdate" ) -< (doc, Just pLastMod) - arrIO2 (flip setAttribute "rakka:isLocked") -< (doc, Just pIsLocked) - arrIO2 (flip setAttribute "rakka:revision") -< (doc, Just pRevision) - - -- リダイレクト先ページ名はテキストとして入れる - arrIO2 addText -< (doc, pRedir) - - returnA -< doc - - addElemText :: Document -> Element -> IO () - addElemText doc (Block b) = addBlockText doc b - addElemText doc (Inline i) = addInlineText doc i - - addBlockText :: Document -> BlockElement -> IO () - addBlockText doc (Heading _ text) = addText doc text - addBlockText _ HorizontalLine = return () - addBlockText doc (List _ items) = mapM_ (addListItemText doc) items - addBlockText doc (DefinitionList defs) = mapM_ (addDefinitionText doc) defs - addBlockText doc (Preformatted inlines) = mapM_ (addInlineText doc) inlines - addBlockText doc (Paragraph inlines) = mapM_ (addInlineText doc) inlines - addBlockText doc (Div _ elems) = mapM_ (addElemText doc) elems - addBlockText _ EmptyBlock = return () - addBlockText doc (BlockCmd bcmd) = addBlockCmdText doc bcmd - - addInlineText :: Document -> InlineElement -> IO () - addInlineText doc (Text text) = addText doc text - addInlineText doc (Italic inlines) = mapM_ (addInlineText doc) inlines - addInlineText doc (Bold inlines) = mapM_ (addInlineText doc) inlines - addInlineText doc (ObjectLink page Nothing) = addText doc page - addInlineText doc (ObjectLink page (Just text)) = addHiddenText doc page - >> addText doc text - addInlineText doc (PageLink page fragm Nothing) = addText doc (fromMaybe "" page ++ fromMaybe "" fragm) - addInlineText doc (PageLink page fragm (Just text)) = addHiddenText doc (fromMaybe "" page ++ fromMaybe "" fragm) - >> addText doc text - addInlineText doc (ExternalLink uri Nothing) = addText doc (uriToString id uri "") - addInlineText doc (ExternalLink uri (Just text)) = addHiddenText doc (uriToString id uri "") - >> addText doc text - addInlineText _ (LineBreak _) = return () - addInlineText doc (Span _ inlines) = mapM_ (addInlineText doc) inlines - addInlineText doc (Image src alt) = do case src of - Left uri -> addHiddenText doc (uriToString id uri "") - Right page -> addHiddenText doc page - case alt of - Just text -> addHiddenText doc text - Nothing -> return () - addInlineText doc (Anchor _ inlines) = mapM_ (addInlineText doc) inlines - addInlineText _ (Input _) = return () - addInlineText _ EmptyInline = return () - addInlineText doc (InlineCmd icmd) = addInlineCmdText doc icmd - - addListItemText :: Document -> ListItem -> IO () - addListItemText = mapM_ . addElemText - - addDefinitionText :: Document -> Definition -> IO () - addDefinitionText doc (Definition term desc) - = do mapM_ (addInlineText doc) term - mapM_ (addInlineText doc) desc - - addBlockCmdText :: Document -> BlockCommand -> IO () - addBlockCmdText doc (BlockCommand _ _ blocks) = mapM_ (addBlockText doc) blocks - - addInlineCmdText :: Document -> InlineCommand -> IO () - addInlineCmdText doc (InlineCommand _ _ inlines) = mapM_ (addInlineText doc) inlines - - -makePageLinkList :: (ArrowXml a, ArrowChoice a, ArrowIO a) => - Storage - -> SystemConfig - -> InterpTable - -> a XmlTree [PageName] -makePageLinkList sto sysConf interpTable - = proc tree - -> do wiki <- wikifyPage interpTable -< tree - pName <- getXPathTreesInDoc "/page/@name/text()" >>> getText -< tree - interpreted <- interpretCommands sto sysConf interpTable - -< (Just pName, Just tree, Just wiki, wiki) - returnA -< concatMap extractFromBlock interpreted - where - extractFromElem :: Element -> [PageName] - extractFromElem (Block b) = extractFromBlock b - extractFromElem (Inline i) = extractFromInline i - - extractFromBlock :: BlockElement -> [PageName] - extractFromBlock (List _ items) = concatMap extractFromListItem items - extractFromBlock (DefinitionList defs) = concatMap extractFromDefinition defs - extractFromBlock (Preformatted inlines) = concatMap extractFromInline inlines - extractFromBlock (Paragraph inlines) = concatMap extractFromInline inlines - extractFromBlock (Div _ elems) = concatMap extractFromElem elems - extractFromBlock _ = [] - - extractFromInline :: InlineElement -> [PageName] - extractFromInline (Italic inlines) = concatMap extractFromInline inlines - extractFromInline (Bold inlines) = concatMap extractFromInline inlines - extractFromInline (Span _ inlines) = concatMap extractFromInline inlines - extractFromInline (PageLink (Just name) _ _) = [name] - extractFromInline _ = [] - - extractFromListItem :: ListItem -> [PageName] - extractFromListItem = concatMap extractFromElem - - extractFromDefinition :: Definition -> [PageName] - extractFromDefinition (Definition term desc) - = concatMap extractFromInline term - ++ - concatMap extractFromInline desc - - -wikifyParseError :: Arrow a => a ParseError WikiPage -wikifyParseError = proc err - -> returnA -< [Div [("class", "error")] - [ Block (Preformatted [Text (show err)]) ]] rmfile ./Rakka/Wiki/Engine.hs hunk ./Rakka/Wiki/Formatter.hs 1 -module Rakka.Wiki.Formatter - ( formatWikiBlocks - ) - where - -import Control.Arrow -import Control.Arrow.ArrowIf -import Control.Arrow.ArrowList -import Control.Arrow.ArrowTree -import Data.Maybe -import Network.URI hiding (fragment) -import Rakka.Page -import Rakka.Wiki -import Text.XML.HXT.Arrow.XmlArrow -import Text.XML.HXT.DOM.TypeDefs - - -formatWikiBlocks :: (ArrowXml a, ArrowChoice a) => a (URI, [BlockElement]) XmlTree -formatWikiBlocks - = proc (baseURI, blocks) - -> do block <- arrL id -< blocks - tree <- formatBlock -< (baseURI, block) - attachXHtmlNS -< tree - - -formatElement :: (ArrowXml a, ArrowChoice a) => a (URI, Element) XmlTree -formatElement - = proc (baseURI, e) - -> case e of - Block b -> formatBlock -< (baseURI, b) - Inline i -> formatInline -< (baseURI, i) - - -formatBlock :: (ArrowXml a, ArrowChoice a) => a (URI, BlockElement) XmlTree -formatBlock - = proc (baseURI, block) - -> case block of - Heading level text - -> formatHeading -< (level, text) - - HorizontalLine - -> eelem "hr" -< () - - list@(List _ _) - -> formatListElement -< (baseURI, list) - - DefinitionList list - -> formatDefinitionList -< (baseURI, list) - - Preformatted inlines - -> formatPreformatted -< (baseURI, inlines) - - Paragraph inlines - -> formatParagraph -< (baseURI, inlines) - - Div attrs contents - -> formatElem "div" -< (baseURI, attrs, contents) - - EmptyBlock - -> none -< () - - _ -> arr (error . ("formatBlock: unsupported BlockElement: " ++) . show) -< block - where - formatElem :: (ArrowXml a, ArrowChoice a) => - String - -> a (URI, [Attribute], [Element]) XmlTree - formatElem name - = proc (baseURI, attrs, contents) - -> ( eelem name - += ( arrL (fst . snd) - >>> - attrFromPair - ) - += ( (arr fst &&& arrL (snd . snd)) - >>> - formatElement - ) - ) -< (baseURI, (attrs, contents)) - - -formatHeading :: ArrowXml a => a (Int, String) XmlTree -formatHeading - = proc (level, text) - -> mkelem ("h" ++ show level) - [ sattr "id" text ] - [ txt text ] -<< () - - -formatListElement :: (ArrowXml a, ArrowChoice a) => a (URI, BlockElement) XmlTree -formatListElement - = proc (baseURI, list) - -> let tag = case listType list of - Bullet -> "ul" - Numbered -> "ol" - in - ( eelem tag - += ( (constA baseURI &&& constL (listItems list)) - >>> - formatListItem - ) - ) -<< () - where - formatListItem :: (ArrowXml a, ArrowChoice a) => a (URI, ListItem) XmlTree - formatListItem - = proc (baseURI, item) - -> eelem "li" - += ( (arr fst &&& arrL snd) - >>> - formatElement - ) -< (baseURI, item) - - -formatDefinitionList :: (ArrowXml a, ArrowChoice a) => a (URI, [Definition]) XmlTree -formatDefinitionList - = proc (baseURI, list) - -> ( eelem "dl" - += ( (arr fst &&& arrL snd) - >>> - formatDefinition - ) - ) -< (baseURI, list) - where - formatDefinition :: (ArrowXml a, ArrowChoice a) => a (URI, Definition) XmlTree - formatDefinition - = proc (baseURI, def) - -> ( eelem "dt" - += ( (arr fst &&& arrL (defTerm . snd)) - >>> - formatInline - ) - <+> - eelem "dd" - += ( (arr fst &&& arrL (defDesc . snd)) - >>> - formatInline - ) - ) -< (baseURI, def) - - -formatPreformatted :: (ArrowXml a, ArrowChoice a) => a (URI, [InlineElement]) XmlTree -formatPreformatted - = eelem "pre" - += ( (arr fst &&& arrL snd) - >>> - formatInline - ) - - -formatParagraph :: (ArrowXml a, ArrowChoice a) => a (URI, [InlineElement]) XmlTree -formatParagraph - = eelem "p" - += ( (arr fst &&& arrL snd) - >>> - formatInline - ) - - -formatInline :: (ArrowXml a, ArrowChoice a) => a (URI, InlineElement) XmlTree -formatInline - = proc (baseURI, i) - -> case i of - Text text - -> mkText -< text - - Italic contents - -> formatElem "i" -< (baseURI, [], contents) - - Bold contents - -> formatElem "b" -< (baseURI, [], contents) - - link@(ObjectLink _ _) - -> formatObjectLink -< (baseURI, link) - - link@(PageLink _ _ _) - -> formatPageLink -< (baseURI, link) - - link@(ExternalLink _ _) - -> formatExternalLink -< link - - LineBreak attrs - -> formatElem "br" -< (baseURI, attrs, []) - - Span attrs contents - -> formatElem "span" -< (baseURI, attrs, contents) - - img@(Image _ _) - -> formatImage -< (baseURI, img) - - Anchor attrs contents - -> formatElem "a" -< (baseURI, attrs, contents) - - Input attrs - -> formatElem "input" -< (baseURI, attrs, []) - - EmptyInline - -> none -< () - - _ -> arr (error . ("formatInline: unsupported InlineElement: " ++) . show) -< i - where - formatElem :: (ArrowXml a, ArrowChoice a) => - String - -> a (URI, [Attribute], [InlineElement]) XmlTree - formatElem name - = proc (baseURI, attrs, contents) - -> ( eelem name - += ( arrL (fst . snd) - >>> - attrFromPair - ) - += ( (arr fst &&& arrL (snd . snd)) - >>> - formatInline - ) - ) -< (baseURI, (attrs, contents)) - - -attrFromPair :: (ArrowXml a) => a (String, String) XmlTree -attrFromPair = proc (name, value) - -> attr name (txt value) -<< () - - -formatObjectLink :: (ArrowXml a) => a (URI, InlineElement) XmlTree -formatObjectLink - = proc (baseURI, ObjectLink page text) - -> let uri = mkObjectURI baseURI page - href = uriToString id uri "" - label = fromMaybe ("{" ++ page ++ "}") text - in - mkAnchor -< (href, label) - - -formatPageLink :: (ArrowXml a) => a (URI, InlineElement) XmlTree -formatPageLink - = proc (baseURI, PageLink page fragment text) - -> let uri = case (page, fragment) of - (Just x, Just y) -> mkPageFragmentURI baseURI x y - (Just x, Nothing) -> mkPageURI baseURI x - (Nothing, Just y) -> mkFragmentURI y - _ -> undefined - href = uriToString id uri "" - dLabel = fromMaybe "" page ++ fromMaybe "" (fmap ('#':) fragment) - label = fromMaybe dLabel text - in - mkAnchor -< (href, label) - - -formatImage :: (ArrowXml a) => a (URI, InlineElement) XmlTree -formatImage = proc (baseURI, Image src alt) - -> let uri = case src of - Left u -> u - Right name -> mkObjectURI baseURI name - href = uriToString id uri "" - in - ( eelem "img" - += sattr "src" href - += ( case alt of - Just x -> sattr "alt" x - Nothing -> none - ) - ) -<< () - - -formatExternalLink :: (ArrowXml a) => a InlineElement XmlTree -formatExternalLink - = proc (ExternalLink uri text) - -> let href = uriToString id uri "" - label = fromMaybe href text - in - mkAnchor -< (href, label) - - -mkAnchor :: (ArrowXml a) => a (String, String) XmlTree -mkAnchor = eelem "a" - += attr "href" (arr fst >>> mkText) - += (arr snd >>> mkText) - - -attachXHtmlNS :: (ArrowXml a) => a XmlTree XmlTree -attachXHtmlNS = processTopDown (changeQName attach `when` isElem) - where - attach :: QName -> QName - attach = setNamePrefix' (newXName "xhtml") . - setNamespaceUri' (newXName "http://www.w3.org/1999/xhtml") rmfile ./Rakka/Wiki/Formatter.hs hunk ./Rakka/Wiki/Interpreter/Base.hs 1 -module Rakka.Wiki.Interpreter.Base - ( interpreters - ) - where - -import Data.Map (Map) -import qualified Data.Map as M -import Data.Maybe -import Rakka.Page -import Rakka.SystemConfig -import Rakka.Wiki -import Rakka.Wiki.Interpreter -import Text.XML.HXT.Arrow -import Text.XML.HXT.XPath - - -interpreters :: [Interpreter] -interpreters = [ lineBreakInterp - , spanInterp - , divInterp - , pageNameInterp - , otherLangsInterp - , newPageInterp - , editPageInterp - , loginInterp - , searchFieldInterp - , configurationInterp - ] - - -lineBreakInterp :: Interpreter -lineBreakInterp = InlineCommandInterpreter { - iciName = "br" - , iciInterpret - = \ _ (InlineCommand _ attrs _) -> return $ LineBreak attrs - } - - -spanInterp :: Interpreter -spanInterp = InlineCommandInterpreter { - iciName = "span" - , iciInterpret - = \ _ (InlineCommand _ attrs contents) -> return $ Span attrs contents - } - - -divInterp :: Interpreter -divInterp = BlockCommandInterpreter { - bciName = "div" - , bciInterpret - = \ _ (BlockCommand _ attrs contents) - -> return $ Div attrs (map Block contents) - } - - -pageNameInterp :: Interpreter -pageNameInterp = InlineCommandInterpreter { - iciName = "pageName" - , iciInterpret - = \ ctx _ -> return $ Text (fromMaybe "" $ ctxPageName ctx) - } - - -otherLangsInterp :: Interpreter -otherLangsInterp - = BlockCommandInterpreter { - bciName = "inOtherLanguages" - , bciInterpret - = \ ctx _ -> - let linkTable = case ctxMainPage ctx of - Just page -> runLA ( getXPathTreesInDoc "/page/otherLang/link" - >>> - ( getAttrValue0 "lang" - &&& - getAttrValue0 "page" - ) - ) page - Nothing -> [] - in - case linkTable of - [] -> return EmptyBlock - _ -> do Languages langTable <- getSysConf (ctxSysConf ctx) - let merged = mergeTables langTable linkTable - return $ mkLangList merged - } - where - mergeTables :: Map LanguageTag LanguageName - -> [(LanguageTag, PageName)] - -> [(LanguageName, PageName)] - mergeTables _ [] = [] - mergeTables m (x:xs) = let (langTag, name) = x - langName = fromMaybe langTag (M.lookup langTag m) - in - (langName, name) : mergeTables m xs - - mkLangList :: [(LanguageName, PageName)] -> BlockElement - mkLangList = List Bullet . map mkLangLink - - mkLangLink :: (LanguageName, PageName) -> ListItem - mkLangLink (langName, name) - = [Inline (PageLink (Just name) Nothing (Just langName))] - - --- -newPageInterp :: Interpreter -newPageInterp - = InlineCommandInterpreter { - iciName = "newPage" - , iciInterpret - = \ _ (InlineCommand _ args _) -> - let label = fromMaybe "Create new page" (lookup "label" args) - attrs = [ ("type" , "button") - , ("value" , label) - , ("onclick", "Rakka.newPage()") - , ("class" , "newButton controls") - ] - in - return (Input attrs) - } - - --- -editPageInterp :: Interpreter -editPageInterp - = InlineCommandInterpreter { - iciName = "editPage" - , iciInterpret - = \ ctx (InlineCommand _ args _) -> - let name = fromMaybe (fromMaybe "" $ ctxPageName ctx) (lookup "page" args) - label = fromMaybe "Edit this page" (lookup "label" args) - attrs = [ ("type" , "button") - , ("value" , label) - , ("onclick", "Rakka.editPage(\"" ++ name ++ "\")") - , ("class" , "editButton controls") - ] - in - return (Input attrs) - } - - --- -loginInterp :: Interpreter -loginInterp - = InlineCommandInterpreter { - iciName = "login" - , iciInterpret - = \ _ _ -> - let attrs = [ ("type" , "button") - , ("value", "Login") - , ("class", "loginButton controls") - ] - in - return (Input attrs) - } - - --- -searchFieldInterp :: Interpreter -searchFieldInterp - = InlineCommandInterpreter { - iciName = "searchField" - , iciInterpret - = \ _ _ -> - let attrs = [ ("type" , "text") - , ("class", "searchField") - ] - in - return (Input attrs) - } - --- -configurationInterp :: Interpreter -configurationInterp - = InlineCommandInterpreter { - iciName = "configuration" - , iciInterpret - = \ _ _ -> - let attrs = [ ("type" , "button") - , ("value", "Configuration") - , ("class", "configButton controls") - ] - in - return (Input attrs) - } rmfile ./Rakka/Wiki/Interpreter/Base.hs hunk ./Rakka/Wiki/Interpreter/Image.hs 1 -module Rakka.Wiki.Interpreter.Image - ( interpreters - ) - where - -import Network.URI -import Rakka.Page -import Rakka.SystemConfig -import Rakka.Wiki.Interpreter -import Rakka.Wiki - - -interpreters :: [Interpreter] -interpreters = [ imageInterp - , imgFrameInterp - ] - - --- [Alternative] -- 空文字列の場合はリンク無し - --- --- ... --- -imageInterp :: Interpreter -imageInterp - = InlineCommandInterpreter { - iciName = "img" - , iciInterpret - = \ ctx (InlineCommand _ attrs _) -> - do BaseURI baseURI <- getSysConf (ctxSysConf ctx) - - let name = case lookup "src" attrs of - Just x -> x - Nothing -> error "\"src\" attribute is missing" - link = case lookup "link" attrs of - Just "" -> Nothing - Just x -> if isURI x then - Just x - else - Just (uriToString id (mkPageURI baseURI x) "") - Nothing -> Just (uriToString id (mkPageURI baseURI name) "") - alt = lookup "alt" attrs - classAttr = case lookup "float" attrs of - Nothing -> "inlineImage" - Just "left" -> "inlineImage leftFloat" - Just "right" -> "inlineImage rightFloat" - Just others -> error ("unknown \"float\" attribute: " ++ others) - result = case link of - Nothing -> Span [("class", classAttr)] [Image (Right name) alt] - Just x -> Anchor [ ("class", classAttr) - , ("href" , x ) ] [Image (Right name) alt] - return result - } - - ---
---
--- --- --- ---
---
--- ... ---
---
-imgFrameInterp :: Interpreter -imgFrameInterp - = BlockCommandInterpreter { - bciName = "imgframe" - , bciInterpret - = \ ctx (BlockCommand _ attrs inside) -> - do BaseURI baseURI <- getSysConf (ctxSysConf ctx) - - let name = case lookup "src" attrs of - Just x -> x - Nothing -> error "\"src\" attribute is missing" - link = case lookup "link" attrs of - Just "" -> Nothing - Just x -> if isURI x then - Just x - else - Just (uriToString id (mkPageURI baseURI x) "") - Nothing -> Just (uriToString id (mkPageURI baseURI name) "") - classAttr = case lookup "float" attrs of - Nothing -> ("class", "imageFrame") - Just "left" -> ("class", "imageFrame leftFloat") - Just "right" -> ("class", "imageFrame rightFloat") - Just others -> error ("unknown \"float\" attribute: " ++ others) - image = case link of - Nothing -> Image (Right name) Nothing - Just x -> Anchor [("href" , x)] [Image (Right name) Nothing] - - return (Div [classAttr] - [ Block (Div [("class", "imageData")] - [ Inline image ]) - , Block (Div [("class", "imageCaption")] - [ Block x | x <- inside ]) - ] - ) - } rmfile ./Rakka/Wiki/Interpreter/Image.hs hunk ./Rakka/Wiki/Interpreter/Outline.hs 1 -module Rakka.Wiki.Interpreter.Outline - ( interpreters - ) - where - -import Data.Maybe -import Rakka.Wiki -import Rakka.Wiki.Interpreter - - -interpreters :: [Interpreter] -interpreters = [ outlineInterp ] - - -outlineInterp :: Interpreter -outlineInterp = BlockCommandInterpreter { - bciName = "outline" - , bciInterpret - = \ ctx _ -> - case ctxMainWiki ctx of - Just tree -> return $ Div [("class", "outline")] [Block $ mkOutline tree] - Nothing -> return EmptyBlock - } - - -mkOutline :: WikiPage -> BlockElement -mkOutline tree = fst (mkOutline' emptyOutline 1 headings) - where - headings :: [BlockElement] - headings = concatMap collectInBlock tree - - collectInBlock :: BlockElement -> [BlockElement] - collectInBlock hd@(Heading _ _) - = [hd] - collectInBlock (Div _ xs) - = concatMap collectInBlock $ catMaybes (map castToBlock xs) - collectInBlock (BlockCmd (BlockCommand _ _ xs)) - = concatMap collectInBlock xs - collectInBlock _ - = [] - - castToBlock :: Element -> Maybe BlockElement - castToBlock (Block e) = Just e - castToBlock _ = Nothing - - -emptyOutline :: BlockElement -emptyOutline = List Bullet [] - - -mkOutline' :: BlockElement -> Int -> [BlockElement] -> (BlockElement, [BlockElement]) -mkOutline' soFar _ [] = (soFar, []) -mkOutline' soFar level (x:xs) - = case x of - Heading n text - | n == level - -- 同じレベルなので soFar に單獨の ListItem を追加して - -- 續行。 - -> let link = PageLink { - linkPage = Nothing - , linkFragment = Just text - , linkText = Just text - } - item = [Inline link] - in - mkOutline' (soFar { listItems = listItems soFar ++ [item] }) n xs - - | n < level - -- 低いレベルなのでここで終了。 - -> (soFar, x:xs) - - | n > level - -- 高いレベルなので再帰して ListElement を作り、 - -- それを soFar の最後の ListItem に追加する。 - -> let (nested, ys) = mkOutline' emptyOutline (level + 1) (x:xs) - itemsSoFar = listItems soFar - - nonLastItems, lastItem :: [ListItem] - (nonLastItems, lastItem) = splitAt (length itemsSoFar - 1) itemsSoFar - - lastItem' :: ListItem - lastItem' = case lastItem of - [] -> [Block nested] - i:[] -> i ++ [Block nested] - _ -> undefined - - soFar' = soFar { listItems = nonLastItems ++ [lastItem'] } - in - mkOutline' soFar' level ys - _ -> undefined + rmfile ./Rakka/Wiki/Interpreter/Outline.hs hunk ./Rakka/Wiki/Interpreter/PageList.hs 1 -module Rakka.Wiki.Interpreter.PageList - ( interpreters - ) - where - -import Control.Monad -import Data.Maybe -import Data.Time -import Network.HTTP.Lucu.RFC1123DateTime -import Network.URI -import Rakka.Storage -import Rakka.SystemConfig -import Rakka.Utils -import Rakka.Wiki -import Rakka.Wiki.Interpreter -import System.FilePath -import Text.HyperEstraier - - -interpreters :: [Interpreter] -interpreters = [ recentUpdatesURLInterp - , recentUpdatesInterp - ] - - -recentUpdatesURLInterp :: Interpreter -recentUpdatesURLInterp - = InlineCommandInterpreter { - iciName = "recentUpdatesURL" - , iciInterpret - = \ ctx _ -> do BaseURI baseURI <- getSysConf (ctxSysConf ctx) - let uri = baseURI { - uriPath = uriPath baseURI "search.html" - , uriQuery = '?' : mkQueryString [ ("q" , "[UVSET]") - , ("order", "@mdate NUMD") - ] - } - return $ ExternalLink uri (Just "List all pages") - } - - ---
---
    ---
  • --- ... ---
    ...
    ---

    --- blah blah... ---

    ---
  • --- ... ---
---
-recentUpdatesInterp :: Interpreter -recentUpdatesInterp - = BlockCommandInterpreter { - bciName = "recentUpdates" - , bciInterpret - = \ ctx (BlockCommand _ args _) - -> do let items = fromMaybe 10 $ fmap read $ lookup "items" args - showSummary = fromMaybe True $ fmap parseYesOrNo $ lookup "showSummary" args - onlyEntity = fromMaybe True $ fmap parseYesOrNo $ lookup "onlyEntity" args - onlySummarized = fromMaybe True $ fmap parseYesOrNo $ lookup "onlySummarized" args - sto = ctxStorage ctx - - cond <- newCondition - when onlyEntity - $ addAttrCond cond "@type STRNE application/x-rakka-redirection" - when onlySummarized - $ addAttrCond cond "rakka:summary STRNE" -- summary が空でない - setPhrase cond "[UVSET]" - setOrder cond "@mdate NUMD" - setMax cond items - - result <- searchPages sto cond - mkPageList showSummary (srPages result) - } - where - mkPageList :: Bool -> [HitPage] -> IO BlockElement - mkPageList showSummary pages - = do items <- mapM (mkListItem showSummary) pages - return (Div [("class", "recentUpdates")] - [ Block (List Bullet items) ]) - - mkListItem :: Bool -> HitPage -> IO ListItem - mkListItem showSummary page - = do lastMod <- utcToLocalZonedTime (hpLastMod page) - return ( [ Inline PageLink { - linkPage = Just (hpPageName page) - , linkFragment = Nothing - , linkText = Nothing - } - , Block ( Div [("class", "date")] - [Inline (Text (formatRFC1123DateTime lastMod))] - ) - ] - ++ - case (showSummary, hpSummary page) of - (True, Just s) - -> [ Block (Paragraph [Text s]) ] - _ -> [] - ) rmfile ./Rakka/Wiki/Interpreter/PageList.hs hunk ./Rakka/Wiki/Interpreter/Trackback.hs 1 -module Rakka.Wiki.Interpreter.Trackback - ( interpreters - ) - where - -import Data.Maybe -import Data.Time -import Network.HTTP.Lucu.RFC1123DateTime -import Rakka.Page -import Rakka.Storage -import Rakka.SystemConfig -import Rakka.TrackBack -import Rakka.Wiki -import Rakka.Wiki.Interpreter - - -interpreters :: [Interpreter] -interpreters = [ trackbackURLInterp - , trackbacksInterp - ] - - -trackbackURLInterp :: Interpreter -trackbackURLInterp - = InlineCommandInterpreter { - iciName = "trackbackURL" - , iciInterpret - = \ ctx _ -> case ctxPageName ctx of - Nothing - -> return (Text "No trackbacks for this page.") - Just name - -> do BaseURI baseURI <- getSysConf (ctxSysConf ctx) - let uri = mkAuxiliaryURI baseURI ["trackback"] name - return $ ExternalLink uri (Just "Trackback URL") - } - - -trackbacksInterp :: Interpreter -trackbacksInterp - = BlockCommandInterpreter { - bciName = "trackbacks" - , bciInterpret - = \ ctx _ -> - do trackbacks <- case ctxPageName ctx of - Nothing - -> return [] - Just name - -> liftM (fromMaybe []) - (getAttachment (ctxStorage ctx) name "trackbacks" Nothing) - items <- mapM mkListItem trackbacks - - let divElem = Div [("class", "trackbacks")] [list] - list = Block (List Bullet items) - - return divElem - } - where - mkListItem :: TrackBack -> IO ListItem - mkListItem tb - = do zonedTime <- utcToLocalZonedTime (tbTime tb) - - let anchor = Just (Inline (ExternalLink (tbURL tb) label)) - label = case (tbTitle tb, tbBlogName tb) of - (Nothing , Nothing ) -> Nothing - (Just title, Nothing ) -> Just title - (Nothing , Just blogName) -> Just blogName - (Just title, Just blogName) -> Just (title ++ " (" ++ blogName ++ ")") - date = Just ( Block ( Div [("class", "date")] - [Inline (Text (formatRFC1123DateTime zonedTime))] - ) - ) - excerpt = do e <- tbExcerpt tb - return $ Block $ Paragraph [Text e] - - return $ catMaybes [anchor, date, excerpt] + rmfile ./Rakka/Wiki/Interpreter/Trackback.hs rmdir ./Rakka/Wiki/Interpreter hunk ./Rakka/Wiki/Interpreter.hs 1 -module Rakka.Wiki.Interpreter - ( Interpreter(..) - , InterpreterContext(..) - - , commandName -- private - , commandType -- private - ) - where - -import Rakka.Page -import Rakka.Storage -import Rakka.SystemConfig -import Rakka.Wiki -import Text.XML.HXT.DOM.TypeDefs - - -data Interpreter - = InlineCommandInterpreter { - iciName :: !String - , iciInterpret :: !(InterpreterContext -> InlineCommand -> IO InlineElement) - } - | BlockCommandInterpreter { - bciName :: !String - , bciInterpret :: !(InterpreterContext -> BlockCommand -> IO BlockElement) - } - - -data InterpreterContext - = InterpreterContext { - ctxPageName :: !(Maybe PageName) - , ctxMainPage :: !(Maybe XmlTree) - , ctxMainWiki :: !(Maybe WikiPage) - , ctxTargetWiki :: !WikiPage - , ctxStorage :: !Storage - , ctxSysConf :: !SystemConfig - } - - -commandName :: Interpreter -> String -commandName (InlineCommandInterpreter name _) = name -commandName (BlockCommandInterpreter name _) = name - - -commandType :: Interpreter -> CommandType -commandType (InlineCommandInterpreter _ _) = InlineCommandType -commandType (BlockCommandInterpreter _ _) = BlockCommandType rmfile ./Rakka/Wiki/Interpreter.hs hunk ./Rakka/Wiki/Parser.hs 1 -module Rakka.Wiki.Parser - ( CommandTypeOf - , wikiPage - ) - where - -import Control.Monad -import Data.Maybe -import Network.URI hiding (fragment) -import Rakka.Wiki -import Text.ParserCombinators.Parsec hiding (label) - - -type CommandTypeOf = String -> Maybe CommandType - - -wikiPage :: CommandTypeOf -> Parser WikiPage -wikiPage cmdTypeOf - = do xs <- many (blockElement cmdTypeOf) - skipMany ( comment - <|> - (newline >> return ()) - ) - eof - return xs - - -blockElement :: CommandTypeOf -> Parser BlockElement -blockElement cmdTypeOf - = try $ do skipMany ( comment - <|> - (newline >> return ()) - ) - foldr (<|>) pzero [ heading - , horizontalLine - , listElement cmdTypeOf - , definitionList cmdTypeOf - , verbatim - , leadingSpaced cmdTypeOf - , paragraph cmdTypeOf - , blockCmd cmdTypeOf - ] - - -heading :: Parser BlockElement -heading = foldr (<|>) pzero (map heading' [1..5]) - - "heading" - where - heading' :: Int -> Parser BlockElement - heading' n = do try $ do _ <- count n (char '=') - notFollowedBy (char '=') - ws - x <- notFollowedBy (char '=') >> anyChar - xs <- manyTill anyChar (try $ ws >> ( count n (char '=') - - ("trailing " ++ replicate n '=') - ) - ) - ws - eol - return (Heading n (x:xs)) - - -horizontalLine :: Parser BlockElement -horizontalLine = try ( do _ <- count 4 (char '-') - _ <- many (char '-') - ws - eol - return HorizontalLine - ) - - "horizontal line" - - -listElement :: CommandTypeOf -> Parser BlockElement -listElement cmdTypeOf = listElement' [] - where - listElement' :: [Char] -> Parser BlockElement - listElement' stack - = do t <- oneOf "*#" - ws - xs <- items (stack ++ [t]) - return (List (toType t) xs) - - items :: [Char] -> Parser [ListItem] - items stack = do xs <- many1 $ inlineElement cmdTypeOf - nested <- option Nothing - $ try $ do skipMany comment - _ <- newline - _ <- string stack - liftM Just (listElement' stack) - rest <- items stack - return $ (map Inline xs ++ map Block (catMaybes [nested])) : rest - <|> - (try $ do skipMany comment - _ <- newline - _ <- string stack - ws - items stack - ) - <|> - return [] - - toType :: Char -> ListType - toType '*' = Bullet - toType '#' = Numbered - toType _ = undefined - - -definitionList :: CommandTypeOf -> Parser BlockElement -definitionList cmdTypeOf = liftM DefinitionList (many1 definition) - where - definition :: Parser Definition - definition = do _ <- char ';' - _ <- ws - tHead <- inlineElement cmdTypeOf - tRest <- term - d <- description - return (Definition (tHead:tRest) d) - - "definition list" - - term :: Parser [InlineElement] - term = (char ':' >> ws >> return []) - <|> - (newline >> char ':' >> ws >> return []) - <|> - do x <- inlineElement cmdTypeOf - xs <- term - return (x:xs) - - "term to be defined" - - description :: Parser [InlineElement] - description = do x <- inlineElement cmdTypeOf - xs <- description - return (x:xs) - <|> - try ( do _ <- newline - _ <- char ':' - _ <- ws - xs <- description - return (Text "\n" : xs) - ) - <|> - (newline >> return []) - <|> - (eof >> return []) - - "description of term" - - -verbatim :: Parser BlockElement -verbatim = do _ <- try (string "> string "]>") - return [] - <|> - do x <- anyChar - xs <- verbatim' - return (x:xs) - - -leadingSpaced :: CommandTypeOf -> Parser BlockElement -leadingSpaced cmdTypeOf = liftM Preformatted (char ' ' >> leadingSpaced') - - "leading space" - where - leadingSpaced' :: Parser [InlineElement] - leadingSpaced' = do x <- inlineElement cmdTypeOf - xs <- leadingSpaced' - return (x:xs) - <|> - try ( liftM (Text "\n" :) ( newline - >> - char ' ' - >> - leadingSpaced' - ) - ) - <|> - return [] - - -paragraph :: CommandTypeOf -> Parser BlockElement -paragraph cmdTypeOf = liftM Paragraph paragraph' - where - paragraph' :: Parser [InlineElement] - paragraph' = do x <- inlineElement cmdTypeOf - xs <- try ( do _ <- newline - _ <- eof - return [] - -- \n で文字列が終はってゐたら、ここ - -- で終了。 - ) - <|> - try ( do _ <- newline - _ <- ((oneOf ('\n':blockSymbols) >> pzero) <|> return ()) - ys <- (paragraph' <|> return []) - return (Text "\n" : ys) - -- \n があり、その次に \n または - -- blockSymbols があれば、fail して - -- 最初の newline を讀んだ所まで卷き - -- 戻す。 - - -- FIXME: 本當にそのやうな動作になつ - -- てゐるか?偶然動いてゐるだけではな - -- いか?確かにこの實裝でユニットテス - -- トは通るのだが、私の理解を越えてし - -- まったやうだ。 - ) - <|> - paragraph' - -- それ以外の場合は次の inlineElement から - -- を讀んで見る。但し一つも無くても良い。 - <|> - return [] -- 全部失敗したらここで終了。 - return (x:xs) - - -blockCmd :: CommandTypeOf -> Parser BlockElement -blockCmd cmdTypeOf - = (try $ do (tagName, tagAttrs) <- openTag - case cmdTypeOf tagName of - Just BlockCommandType - -> do xs <- contents - closeTag tagName - return $ BlockCmd BlockCommand { - bCmdName = tagName - , bCmdAttributes = tagAttrs - , bCmdContents = xs - } - - Just InlineCommandType - -> pzero - - _ -> return $ undefinedCmdErr tagName - ) - <|> - (try $ do (tagName, tagAttrs) <- emptyTag - case cmdTypeOf tagName of - Just BlockCommandType - -> return $ BlockCmd BlockCommand { - bCmdName = tagName - , bCmdAttributes = tagAttrs - , bCmdContents = [] - } - - Just InlineCommandType - -> pzero - - _ -> return $ undefinedCmdErr tagName - ) - - "block command" - where - contents :: Parser [BlockElement] - contents = do x <- blockElement cmdTypeOf - xs <- contents - return (x:xs) - <|> - (newline >> contents) - <|> - (comment >> contents) - <|> - return [] - - undefinedCmdErr :: String -> BlockElement - undefinedCmdErr name - = Div [("class", "error")] - [ Block (Paragraph [Text ("The command `" ++ name ++ "' is not defined. " ++ - "Make sure you haven't mistyped.") - ]) - ] - - -inlineElement :: CommandTypeOf -> Parser InlineElement -inlineElement cmdTypeOf - = try $ do skipMany comment - foldr (<|>) pzero [ nowiki - , apostrophes cmdTypeOf - , text - , objLink - , pageLink - , extLink - , inlineCmd cmdTypeOf - ] - - -nowiki :: Parser InlineElement -nowiki = liftM Text (try (string "> nowiki') - where - nowiki' :: Parser String - nowiki' = do _ <- try (string "]>") - return [] - <|> - do x <- anyChar - xs <- nowiki' - return (x:xs) - - -text :: Parser InlineElement -text = liftM (Text . (':' :)) ( char ':' - >> - many (noneOf ('\n':inlineSymbols)) - ) - -- 定義リストとの關係上、コロンは先頭にしか來られない。 - <|> - liftM Text (many1 (noneOf ('\n':inlineSymbols))) - - "text" - - -apostrophes :: CommandTypeOf -> Parser InlineElement -apostrophes cmdTypeOf = foldr (<|>) pzero (map try [apos1, apos2, apos3, apos4, apos5]) - where - apos1 = apos 1 >> return (Text "'") - - apos2 = do apos 2 - xs <- many1 $ inlineElement cmdTypeOf - apos 2 - return (Italic xs) - - apos3 = do apos 3 - xs <- many1 $ inlineElement cmdTypeOf - apos 3 - return (Bold xs) - - apos4 = apos 4 >> return (Text "'") - - apos5 = do apos 5 - xs <- many1 $ inlineElement cmdTypeOf - apos 5 - return (Italic [Bold xs]) - - apos :: Int -> Parser () - apos n = count n (char '\'') >> notFollowedBy (char '\'') - - -objLink :: Parser InlineElement -objLink = do _ <- try (string "[[[") - page <- many1 (noneOf "|]") - label <- option Nothing - (liftM Just (char '|' >> many1 (satisfy (/= ']')))) - _ <- string "]]]" - return $ ObjectLink page label - - "object link" - - -pageLink :: Parser InlineElement -pageLink = do _ <- try (string "[[") - page <- option Nothing - (liftM Just (many1 (noneOf "#|]"))) - fragment <- option Nothing - (liftM Just (char '#' >> many1 (noneOf "|]"))) - label <- option Nothing - (liftM Just (char '|' >> many1 (satisfy (/= ']')))) - - case (page, fragment) of - (Nothing, Nothing) -> pzero - (_, _) -> return () - - _ <- string "]]" - return $ PageLink page fragment label - - "page link" - - -extLink :: Parser InlineElement -extLink = do _ <- char '[' - uriStr <- many1 (noneOf " \t]") - _ <- skipMany (oneOf " \t") - label <- option Nothing - (liftM Just (many1 (noneOf "]"))) - - case parseURI uriStr of - Just uri -> char ']' >> return (ExternalLink uri label) - Nothing -> pzero "absolute URI" - - "external link" - - -inlineCmd :: CommandTypeOf -> Parser InlineElement -inlineCmd cmdTypeOf - = (try $ do (tagName, tagAttrs) <- openTag - case cmdTypeOf tagName of - Just InlineCommandType - -> do xs <- contents - closeTag tagName - return $ InlineCmd InlineCommand { - iCmdName = tagName - , iCmdAttributes = tagAttrs - , iCmdContents = xs - } - _ -> pzero - ) - <|> - (try $ do (tagName, tagAttrs) <- emptyTag - case cmdTypeOf tagName of - Just InlineCommandType - -> return $ InlineCmd InlineCommand { - iCmdName = tagName - , iCmdAttributes = tagAttrs - , iCmdContents = [] - } - _ -> pzero - ) - - "inline command" - where - contents :: Parser [InlineElement] - contents = do x <- inlineElement cmdTypeOf - xs <- contents - return (x:xs) - <|> - (comment >> contents) - <|> - liftM (Text "\n" :) (newline >> contents) - <|> - return [] - - -openTag :: Parser (String, [Attribute]) -openTag = try $ do _ <- char '<' - _ <- many space - name <- many1 letter - _ <- many space - attrs <- many $ do attr <- tagAttr - _ <- many space - return attr - _ <- char '>' - return (name, attrs) - - -emptyTag :: Parser (String, [Attribute]) -emptyTag = try $ do _ <- char '<' - _ <- many space - name <- many1 letter - _ <- many space - attrs <- many $ do attr <- tagAttr - _ <- many space - return attr - _ <- char '/' - _ <- many space - _ <- char '>' - return (name, attrs) - - -closeTag :: String -> Parser () -closeTag name = try $ do _ <- char '<' - _ <- many space - _ <- char '/' - _ <- many space - _ <- string name - _ <- many space - _ <- char '>' - return () - - -tagAttr :: Parser (String, String) -tagAttr = do name <- many1 letter - _ <- char '=' - _ <- char '"' - value <- many (satisfy (/= '"')) - _ <- char '"' - return (name, value) - - -comment :: Parser () -comment = (try (string "") >> case level of - 1 -> return () - n -> skipTillEnd (n - 1)) - <|> - (anyChar >> skipTillEnd level) - - -blockSymbols :: [Char] -blockSymbols = " =-*#;<" - - -inlineSymbols :: [Char] -inlineSymbols = "<[:'" - --- white space -ws :: Parser () -ws = skipMany ( (oneOf " \t" >> return ()) - <|> - comment - ) - --- end of line -eol :: Parser () -eol = (newline >> return ()) - <|> - eof rmfile ./Rakka/Wiki/Parser.hs rmdir ./Rakka/Wiki hunk ./Rakka/Wiki.hs 1 -module Rakka.Wiki - ( WikiPage - - , Element(..) - , Attribute - - , BlockElement(..) - , InlineElement(..) - - , Definition(..) - - , ListType(..) - , ListItem - - , CommandType(..) - , BlockCommand(..) - , InlineCommand(..) - ) - where - -import Network.URI -import Rakka.Page - - -type WikiPage = [BlockElement] - - -data Element - = Block !BlockElement - | Inline !InlineElement - deriving (Eq, Show) - - -type Attribute = (String, String) - - -data BlockElement - = Heading { - headingLevel :: !Int - , headingText :: !String - } - | HorizontalLine - | List { - listType :: !ListType - , listItems :: ![ListItem] - } - | DefinitionList ![Definition] - | Preformatted ![InlineElement] - | Paragraph ![InlineElement] - | Div ![Attribute] ![Element] - | EmptyBlock - | BlockCmd !BlockCommand - deriving (Eq, Show) - - -data InlineElement - = Text !String - | Italic ![InlineElement] - | Bold ![InlineElement] - | ObjectLink { - objLinkPage :: !PageName - , objLinkText :: !(Maybe String) - } - | PageLink { - linkPage :: !(Maybe PageName) - , linkFragment :: !(Maybe String) - , linkText :: !(Maybe String) - } - | ExternalLink { - extLinkURI :: !URI - , extLinkText :: !(Maybe String) - } - | LineBreak ![Attribute] - | Span ![Attribute] ![InlineElement] - | Image { - imgSource :: !(Either URI PageName) - , imgAlt :: !(Maybe String) - } - | Anchor ![Attribute] ![InlineElement] - | Input ![Attribute] - | EmptyInline - | InlineCmd !InlineCommand - deriving (Eq, Show) - - -data ListType - = Bullet - | Numbered - deriving (Eq, Show) - - -type ListItem = [Element] - - -data Definition - = Definition { - defTerm :: ![InlineElement] - , defDesc :: ![InlineElement] - } - deriving (Eq, Show) - - -data CommandType - = InlineCommandType - | BlockCommandType - deriving (Eq, Show) - - -data BlockCommand - = BlockCommand { - bCmdName :: !String - , bCmdAttributes :: ![Attribute] - , bCmdContents :: ![BlockElement] - } - deriving (Eq, Show) - - -data InlineCommand - = InlineCommand { - iCmdName :: !String - , iCmdAttributes :: ![Attribute] - , iCmdContents :: ![InlineElement] - } - deriving (Eq, Show) rmfile ./Rakka/Wiki.hs rmdir ./Rakka hunk ./Rakka.buildinfo.in 1 --- -*- haskell-cabal -*- -Executable: rakka -GHC-Options: - -DLOCALSTATEDIR="@RAKKA_LOCALSTATEDIR@" rmfile ./Rakka.buildinfo.in hunk ./Rakka.cabal 1 -Name: Rakka -Synopsis: RESTful Wiki engine with Subversion backend -Description: - Rakka is a RESTful wiki engine with Subversion backend. Its syntax - is similar to MediaWiki. -Version: 0.1 -License: PublicDomain -Author: PHO -Maintainer: PHO -Stability: experimental -Homepage: http://rakka.cielonegro.org/ -Category: Web -Tested-With: GHC == 6.6.1 -Cabal-Version: >= 1.2 -Build-Type: Custom - -Data-Files: - defaultPages/Feed.xml - defaultPages/Help/SampleImage/Large.xml - defaultPages/Help/SampleImage/Small.xml - defaultPages/Help/Syntax.xml - defaultPages/MainPage.xml - defaultPages/PageTitle.xml - defaultPages/SideBar/Left.xml - defaultPages/SideBar/Right.xml - defaultPages/StyleSheet/CieloNegro/Logo.xml - defaultPages/StyleSheet/CieloNegro/Moon.xml - defaultPages/StyleSheet/CieloNegro.xml - defaultPages/StyleSheet/Default.xml - schemas/rakka-page-1.0.rng - -Extra-Source-Files: - Rakka.buildinfo.in - configure - configure.ac - js/Makefile - js/base.js - js/base64.js - js/editPage.js - js/hexDump.js - js/jquery-1.2.2.js - js/jquery-dom.js - js/localFile.js - js/login.js - js/parseuri.js - js/screen.js - js/search.js - js/uri.js - tests/RakkaUnitTest.hs - tests/WikiParserTest.hs - -Flag build-test-suite - Description: Build the test suite. - Default: False - -Executable rakka - Build-Depends: - FileManip, HTTP, HUnit, HsHyperEstraier, HsOpenSSL, HsSVN >= - 0.3.2, Lucu, base, bytestring, containers, dataenc, directory, - utf8-string, filepath, hslogger, hxt, hxt-xpath, magic, mtl, - network, parsec, stm, time, unix, zlib - Main-Is: - Main.hs - Other-Modules: - Rakka.Attachment - Rakka.Authorization - Rakka.Environment - Rakka.Page - Rakka.Resource - Rakka.Resource.CheckAuth - Rakka.Resource.DumpRepos - Rakka.Resource.Index - Rakka.Resource.JavaScript - Rakka.Resource.Object - Rakka.Resource.PageEntity - Rakka.Resource.Render - Rakka.Resource.Search - Rakka.Resource.SystemConfig - Rakka.Resource.TrackBack - Rakka.Resource.Users - Rakka.Storage - Rakka.Storage.DefaultPage - Rakka.Storage.Repos - Rakka.Storage.Types - Rakka.Storage.Impl - Rakka.SystemConfig - Rakka.TrackBack - Rakka.Utils - Rakka.Validation - Rakka.W3CDateTime - Rakka.Wiki - Rakka.Wiki.Interpreter - Rakka.Wiki.Interpreter.Base - Rakka.Wiki.Interpreter.Image - Rakka.Wiki.Interpreter.PageList - Rakka.Wiki.Interpreter.Trackback - Rakka.Wiki.Interpreter.Outline - Rakka.Wiki.Engine - Rakka.Wiki.Formatter - Rakka.Wiki.Parser - Extensions: - Arrows, ExistentialQuantification, ScopedTypeVariables, DeriveDataTypeable, FlexibleInstances - GHC-Options: - -Wall -threaded - -Executable RakkaUnitTest - if flag(build-test-suite) - Buildable: True - else - Buildable: False - Main-Is: - RakkaUnitTest.hs - Hs-Source-Dirs: - ., tests - Other-Modules: - WikiParserTest - Extensions: - Arrows - GHC-Options: - -Wall -Werror rmfile ./Rakka.cabal hunk ./Setup.hs 1 -#!/usr/bin/env runghc - -import Distribution.Simple -import System.Cmd -import System.Exit - -main = defaultMainWithHooks (autoconfUserHooks { runTests = runTestUnit }) - where - runTestUnit _ _ _ _ - = system "./dist/build/RakkaUnitTest/RakkaUnitTest" >> return () rmfile ./Setup.hs hunk ./configure.ac 1 -AC_INIT([Rakka], [], [pho at cielonegro dot org]) - -AC_CONFIG_SRCDIR([Rakka.cabal]) - - -# $localstatedir has a reference to ${prefix} but the ${prefix} is -# "NONE" at this time. AC_OUTPUT changes the value of ${prefix} from -# "NONE" to $ac_default_prefix but it's too late! -if test "x$prefix" = "xNONE"; then - prefix=$ac_default_prefix -fi - -RAKKA_LOCALSTATEDIR=`eval echo "$localstatedir"`/rakka -AC_SUBST([RAKKA_LOCALSTATEDIR]) - - -AC_CONFIG_FILES([ - Rakka.buildinfo -]) -AC_OUTPUT - rmfile ./configure.ac hunk ./defaultPages/Feed.xml 1 - - - - -]]> - - + rmfile ./defaultPages/Feed.xml hunk ./defaultPages/Help/SampleImage/Large.xml 1 - - - - - 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 - +otaXBkGORXUy42sgLk7wK6kv//Z - - + rmfile ./defaultPages/Help/SampleImage/Large.xml hunk ./defaultPages/Help/SampleImage/Small.xml 1 - - - - - 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 - - + rmfile ./defaultPages/Help/SampleImage/Small.xml rmdir ./defaultPages/Help/SampleImage hunk ./defaultPages/Help/Syntax.xml 1 - - - - - -== nowiki section == -<!nowiki[ -[[Wiki]] markup is ignored here -but the text is reformatted. -]> - -== verbatim section == -<!verbatim[ -[[Wiki]] markup is ignored here - and reformatting is also disabled. -]> - - -blah blah blah... -blah blah blah blah... --- John Doe - ---> - -== Listing == -* foo -** bar -*** baz - -# foo -## bar -### baz - -* foo -*# bar -*#* baz -*# bar - -== Definition == -; AAA : aaa -; BBB -: bbb - -== Link == -* [[Page]] -* [[page]] -* [[space in a page name]] -* [[Page|Link to "Page"]] -* [[Page#Heading]] -* [[#Heading]] -* [[Page#Heading|Link to "Page#Heading"]] -* [[#example]] -* [http://www.google.com/] -* [http://www.google.com/ Google] -* [[[Page]]] -* [[[Page|Link to object of "Page"]]] - - -
example
-]]> -
-
rmfile ./defaultPages/Help/Syntax.xml rmdir ./defaultPages/Help hunk ./defaultPages/MainPage.xml 1 - - - - - - - - foo - - -Another paragraph... - -別の段落...
次の行... -red blue red - -== Subsection == - -* [[Help/Syntax]] -* [http://cielonegro.org/] -* [http://cielonegro.org/ CieloNegro] -]]>
-
rmfile ./defaultPages/MainPage.xml hunk ./defaultPages/PageTitle.xml 1 - - - -]]> - rmfile ./defaultPages/PageTitle.xml hunk ./defaultPages/SideBar/Left.xml 1 - - - - -= Menu = -* [[MainPage|Main]] -* [[Help/Syntax|Syntax Help]] - -]]> - rmfile ./defaultPages/SideBar/Left.xml hunk ./defaultPages/SideBar/Right.xml 1 - - - -* -* -* -* - -= In other languages = - - -= Recent updates = - - - -]]> - rmfile ./defaultPages/SideBar/Right.xml rmdir ./defaultPages/SideBar hunk ./defaultPages/StyleSheet/CieloNegro/Logo.xml 1 - - - - - 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 - TkSuQmCC - - + rmfile ./defaultPages/StyleSheet/CieloNegro/Logo.xml hunk ./defaultPages/StyleSheet/CieloNegro/Moon.xml 1 - - - - - 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 - - + rmfile ./defaultPages/StyleSheet/CieloNegro/Moon.xml rmdir ./defaultPages/StyleSheet/CieloNegro hunk ./defaultPages/StyleSheet/CieloNegro.xml 1 - - - -/* global configuration *******************************************************/ -* { - padding: 0; - margin: 0; -} - -/* layout *********************************************************************/ -.center { - position: absolute; - - overflow: auto; - - top: 20px; - right: 15em; - left: 15em; - bottom: 20px; -} - -.left { - top: 0em; - width: 15em; - left: 0; - bottom: 0; -} - -.right { - top: 0em; - width: 15em; - right: 0; - bottom: 0; -} - -.header { - position: absolute; - height: 20px; - left: 15em; - right: 15em; - top: 0; -} - -.footer { - position: absolute; - height: 20px; - left: 15em; - right: 15em; - bottom: 0; -} - -.sideBar { - position: absolute; - overflow: auto; -} - -/* spacing ********************************************************************/ -input[type="button"] { - padding: 0px; -} - -td, th { - padding: 3px; -} - -option { - padding: 3px 3px 1px 3px; -} - -.title { - padding: 5px 20px; -} - -.title p { - margin: 0; -} - -.body { - padding: 25px 30px; -} - -.body p { - margin: 0 0 0.8em 0; -} - -.sideBar p { - margin: 0.2em 0; -} - -.body h1, .body h2, .body h3, .body h4, .body h5, .body h6 { - margin: 5px 0px; -} - -.body * + h2 { - margin-top: 20px; -} - -.body ul, .body ol { - list-style-position: inside; - margin: 0 0 0.8em 0; -} -.body ul ul, .body ul ol, .body ol ul, .body ol ol { - margin: 0; -} - -.body li { - margin: 3px 5px; -} -.body li li { - margin-left: 20px; -} - -.body dl { - margin: 1em 2em; -} -.body dt { - font-weight: bold; -} -.body dd { - margin-left: 3em; - margin-top: 0.1em; -} -.body dd + dt { - margin-top: 0.9em; -} - -.sideBar h1 { - margin-bottom: 5px; - padding: 0px 5px; -} - -.sideBar .content { - padding: 20px; -} - -.sideBar p { - margin-left: 5px; -} - -.sideBar .outline li { - margin-left: 1em; - padding: 0; -} - -.sideBar li { - padding: 3px; -} - -.sideBar ul, .sideBar ol { - list-style-type: none; - margin-top: 0.4em; - margin-bottom: 0.4em; -} - -.sideBar li + li { - margin-top: 0.3em; -} - -.sideBar * + h1 { - margin-top: 1.2em; -} - -.sideBar .date { - padding: 0.2em 0 0 0; -} - -.sideBar input[type="text"], -.sideBar input[type="password"] { - width: 97%; - padding: 1px; -} - -table.pageEditor { - width: 100%; -} -table.pageEditor.vertical td { - text-align: center; -} -.pageEditor th { - width: 6em; -} -.pageEditor ul { - list-style-type: none; - margin: 0; -} -.pageEditor li { - margin: 0; - padding: 3px; -} -.pageEditor input[type="radio"] { - margin-right: 10px; -} -.pageEditor input[type="checkbox"] { - margin-right: 5px; -} -.pageEditor input[type="text"], -.pageEditor input[type="password"], -.pageEditor input[type="file"], -.pageEditor textarea { - width: 97%; - padding: 3px; -} -.pageEditor input.smallField { - width: 50%; - margin-left: 1em; -} -.pageEditor textarea { - height: 5em; -} -.pageEditor textarea.summary { - height: 5em; -} -.pageEditor textarea.source { - height: 30em; -} -.pageEditor textarea.hexDump { - font-size: 70%; - font-family: monospace; - white-space: pre; - height: 10em; -} -.pageEditor input[type="button"] { - margin: 0 2px; -} - -.searchStat { - margin-bottom: 1.5em; -} - -.searchResult { - margin-bottom: 1.5em; -} - -.pager { - width: 20em; - - margin-left: auto; - margin-right: auto; - - padding: 10px; -} - -.pager a, -.pager .currentSection { - padding: 4px; -} - -/* color and text *************************************************************/ -* { - font-family: sans-serif; -} - -.header, .footer { - background-color: #0e192d; -} - -.sideBar { - background-color: black; - color: white; -} - -.body { - line-height: 1.3; -} - -.center { - background-color: #bbbbbb; -} - -h1, h2, h3, h4, h5, h6 { - font-weight: normal; -} - -hr { - border-color: #555555; - border-width: 1px; - border-style: dashed; -} - -th, td { - border-color: #777777; - border-width: 1px; - border-style: solid; -} -th { - background-color: #aaaaaa; - font-weight: bold; - text-align: center; -} -td { - background-color: #cccccc; -} - -p { - text-indent: 1em; -} - -.title { - background-color: #0e192d; - color: white; - - background-image: url("./CieloNegro/Moon"); - background-repeat: no-repeat; - /* (175px - 20px - 136px) / 2 = 9.5px - * where - * 175px: height of .title - * 20px : height of .head - * 136px: height of ./CieloNegro/Moon - */ - background-position: 100% 9.5px; - - position: relative; - height: 165px; - - border-width: 0 0 10px 0; - border-style: double; - border-color: #bbbbbb; -} - -#logo { - width: 317px; - height: 56px; - - background-image: url("./CieloNegro/Logo"); - - margin-left: 0px; - margin-top: 100px; -} - -.body h1 { - font-size: 200%; -} -.body h2 { - font-size: 150%; -} -.body h3 { - font-size: 130%; -} -.body h4 { - font-size: 110%; -} -.body h5 { - font-size: 90%; -} -.body h1, .body h2, .body h3, .body h4, .body h5 { - background-color: #aaaaaa; - - border-color: #888888; - border-width: 1px; - border-style: solid; - - padding: 0 10px; -} - -a { - color: #000088; - text-decoration: none; -} -a:hover { - text-decoration: underline; -} - -input[type="button"] { - background-color: #333333; - color: #aaaaff; - - border-color: #555555; - border-width: 2px; - border-style: solid; - - border-radius: 10px; - -moz-border-radius: 10px; -} -input[type="button"]:active { - background-color: black; -} -input[type="button"][disabled] { - border-color: #444444; - color: #888888; -} -input[type="button"][disabled]:active { - background-color: #444444; -} - -.sideBar h1 { - font-size: 120%; -} -.sideBar h1, .sideBar h2, .sideBar h3, .sideBar h4, .sideBar h5 { - font-weight: normal; - - color: #aaaaaa; - background-color: #222222; - - border-color: #111111 #333333 #333333 #111111; - border-width: 1px; - border-style: solid; -} - -.sideBar a { - color: #4e8eff; -} - -.sideBar a:visited { - color: #3f73d0; -} - -.sideBar .date { - font-size: 70%; - white-space: nowrap; - color: #999999; -} - -.searchResult .date { - font-size: 70%; - white-space: nowrap; - color: #555555; -} - -.sideBar p { - text-indent: 0; -} - -.sideBar .recentUpdates p, -.sideBar .trackbacks p { - font-size: 90%; -} - -.sideBar .outline li { - list-style-type: disc; - background-color: inherit; -} -.sideBar .outline li li { - list-style-type: circle; -} -.sideBar .outline li li li { - list-style-type: square; -} -.sideBar .outline li li li li { - list-style-type: disc; -} -.sideBar .outline li li li li li { - list-style-type: circle; -} - -.sideBar li { - padding: 3px 5px; - background-color: #0e192d; - - border-radius: 10px; - -moz-border-radius: 10px; -} - -.sideBar input[type="text"], -.sideBar input[type="password"] { - background-color: #333333; - - border-style: inset; - border-width: 1px; - border-color: #333333; -} - -.activeField { - color: white; -} - -.inactiveField { - color: #aaaaaa; -} - -.pageEditor input[type="text"], -.pageEditor input[type="password"], -.pageEditor input[type="file"], -.pageEditor textarea { - border-color: #aaaaaa #eeeeee #eeeeee #aaaaaa; - border-width: 2px; - border-style: solid; - - background-color: #dddddd; -} - -.searchStat { - color: #444444; - font-size: 90%; -} - -.searchResult a { - font-size: 120%; -} -.searchResult { - border-style: dotted; - border-width: 1px 0 0 0; - border-color: #444444; -} - -.highlighted { - background-color: #ffefd5; -} - -.pager { - text-align: center; - - background-color: #b0b0b0; - - border-color: #888888; - border-width: 1px; - border-style: dotted; -} -.pager .currentSection, -.pager a { - border-style: solid; - border-width: 1px; -} -.pager .currentSection { - background-color: #bbbbbb; - border-color: #888888 #bbbbbb #bbbbbb #888888; -} -.pager a { - background-color: #aaaaaa; - border-color: #bbbbbb #999999 #999999 #bbbbbb; -} - -/* float **********************************************************************/ -h1, h2, h3, h4, h5, h6 { - clear: both; -} - -/* image **********************************************************************/ -img { - border-width: 0; -} - -.inlineImage { - margin-top: 5px; - margin-bottom: 5px; -} - -.leftFloat { - float: left; - margin-right: 25px; -} - -.rightFloat { - float: right; - margin-left: 25px; -} - -.imageFrame { - background-color: #999999; - padding: 5px; - - border-color: #888888; - border-width: 1px; - border-style: solid; - - margin-top: 5px; - margin-bottom: 10px; -} - -.imageFrame p { - margin: 0; -} - -.imageData { - text-align: center; -} - -.imageCaption { - margin-top: 3px; -} - -.sideBar .imageFrame { - background-color: #222222; -} - -/* error **********************************************************************/ -.error { - color: red; - background-color: white; - - font-weight: bold; - - border-color: #880000; - border-width: 3px; - border-style: double; - - padding: 10px; -} - -.error p, .error pre { - margin: 0; -} - -.error:before { - content: "Error: " -} - -/* sidebar mask ***************************************************************/ -.sideBarMask { - position: fixed; - - background-color: black; - color: white; - opacity: 0.7; - - z-index: 1; -} - -.sideBarMask .content { - padding: 40px 0; -} - -.sideBarMask .content input[type="button"] { - font-size: 120%; - font-weight: bold; - - background-color: #f5f5f5; - color: #000055; - - border-color: #dddddd; - border-width: 2px; - border-style: solid; - - border-radius: 10px; - -moz-border-radius: 10px; -} - -/* waiting message ************************************************************/ -.waitingMessageBoard { - position: fixed; - left: 0; - top: 0; - right: 0; - bottom: 0; - - z-index: 1; -} - -.waitingMessageBoard p { - font-size: 200%; - - background-color: white; - color: black; - opacity: 0.7; - - position: fixed; - bottom: 1em; - right: 1em; - - text-indent: 0; - padding: 5px 30px; -} - -/* redirection message ********************************************************/ -.redirection { - margin: 5px; - padding: 2px; - - font-size: 80%; - - background-color: #a6a6a6; - color: #333333; - - border-color: #777777; - border-width: 1px; - border-style: dotted -} - -.redirection input[type="button"] { - color: inherit; - background-color: #a0a0a0; - - border-width: 1px; - - border-radius: 5px; - -moz-border-radius: 5px; - - margin-left: 0.8em; -} - -.redirection input[type="button"]:active { - background-color: #888888; -} - -/* preview ********************************************************************/ -.preview { - background-color: #b5b5b5; - - margin: 0 0 20px 0; - padding: 10px; - - border-style: solid; - border-width: 1px; - border-color: #888888; -} - - rmfile ./defaultPages/StyleSheet/CieloNegro.xml hunk ./defaultPages/StyleSheet/Default.xml 1 - - - -/* global configuration *******************************************************/ -* { - padding: 0; - margin: 0; -} - -/* layout *********************************************************************/ -.center { - position: absolute; - - overflow: auto; - - top: 20px; - right: 15em; - left: 15em; - bottom: 20px; -} - -.left { - top: 0em; - width: 15em; - left: 0; - bottom: 0; -} - -.right { - top: 0em; - width: 15em; - right: 0; - bottom: 0; -} - -.header { - position: absolute; - height: 20px; - left: 15em; - right: 15em; - top: 0; -} - -.footer { - position: absolute; - height: 20px; - left: 15em; - right: 15em; - bottom: 0; -} - -.sideBar { - position: absolute; - overflow: auto; -} - -/* spacing ********************************************************************/ -input[type="button"] { - padding: 0px; -} - -td, th { - padding: 3px; -} - -option { - padding: 3px 3px 1px 3px; -} - -.title { - padding: 5px 20px; -} - -.title p { - margin: 0; -} - -.body { - padding: 25px 30px; -} - -.body p { - margin: 0 0 0.8em 0; -} - -.sideBar p { - margin: 0.2em 0; -} - -.body h1, .body h2, .body h3, .body h4, .body h5, .body h6 { - margin: 5px 0px; -} - -.body * + h2 { - margin-top: 20px; -} - -.body ul, .body ol { - list-style-position: inside; - margin: 0 0 0.8em 0; -} -.body ul ul, .body ul ol, .body ol ul, .body ol ol { - margin: 0; -} - -.body li { - margin: 3px 5px; -} -.body li li { - margin-left: 20px; -} - -.body dl { - margin: 1em 2em; -} -.body dt { - font-weight: bold; -} -.body dd { - margin-left: 3em; - margin-top: 0.1em; -} -.body dd + dt { - margin-top: 0.9em; -} - -.sideBar h1 { - margin-bottom: 5px; - padding: 0px 5px; -} - -.sideBar .content { - padding: 20px; -} - -.sideBar p { - margin-left: 5px; -} - -.sideBar .outline li { - margin-left: 1em; - padding: 0; -} - -.sideBar li { - padding: 3px; -} - -.sideBar ul, .sideBar ol { - list-style-type: none; - margin-top: 0.4em; - margin-bottom: 0.4em; -} - -.sideBar li + li { - margin-top: 0.3em; -} - -.sideBar * + h1 { - margin-top: 1.2em; -} - -.sideBar .date { - padding: 0.2em 0 0 0; -} - -.sideBar input[type="text"], -.sideBar input[type="password"] { - width: 97%; - padding: 1px; -} - -table.configPanel { - width: 100%; -} - -table.pageEditor { - width: 100%; -} -table.pageEditor.vertical td { - text-align: center; -} -.pageEditor th { - width: 6em; -} -.pageEditor ul { - list-style-type: none; - margin: 0; -} -.pageEditor li { - margin: 0; - padding: 3px; -} -.pageEditor input[type="radio"] { - margin-right: 10px; -} -.pageEditor input[type="checkbox"] { - margin-right: 5px; -} -.pageEditor input[type="text"], -.pageEditor input[type="password"], -.pageEditor input[type="file"], -.pageEditor textarea { - width: 97%; - padding: 3px; -} -.pageEditor input.smallField { - width: 50%; - margin-left: 1em; -} -.pageEditor textarea { - height: 5em; -} -.pageEditor textarea.summary { - height: 5em; -} -.pageEditor textarea.source { - height: 30em; -} -.pageEditor textarea.hexDump { - font-size: 70%; - font-family: monospace; - white-space: pre; - height: 10em; -} -.pageEditor input[type="button"] { - margin: 0 2px; -} - -.searchStat { - margin-bottom: 1.5em; -} - -.searchResult { - margin-bottom: 1.5em; -} - -.pager { - width: 20em; - - margin-left: auto; - margin-right: auto; - - padding: 10px; -} - -.pager a, -.pager .currentSection { - padding: 4px; -} - -/* color and text *************************************************************/ -* { - font-family: sans-serif; -} - -body { - background-color: white; - color: black; -} - -.body { - line-height: 1.3; -} - -h1, h2, h3, h4, h5, h6 { - font-weight: normal; -} - -hr { - border-color: #bbbbbb; - border-width: 1px; - border-style: dashed; -} - -th, td { - border-color: #dddddd; - border-width: 1px; - border-style: solid; -} -th { - background-color: #eeeeee; - font-weight: bold; - text-align: center; -} -td { - background-color: #fafafa; -} - -p { - text-indent: 1em; -} - -.title { - background-color: #fafafa; - - border-color: #cccccc; - border-width: 0 0 1px 0; - border-style: solid; - - font-size: 1.2em; -} - -.body h1 { - font-size: 200%; -} -.body h2 { - font-size: 150%; -} -.body h3 { - font-size: 130%; -} -.body h4 { - font-size: 110%; -} -.body h5 { - font-size: 90%; -} -.body h1, .body h2, .body h3, .body h4, .body h5 { - background-color: #fafafa; - - border-color: #dddddd; - border-width: 1px; - border-style: solid; - - padding: 0 10px; -} - -a { - color: #008800; - text-decoration: none; -} -a:hover { - text-decoration: underline; -} - -input[type="button"] { - background-color: #f5f5f5; - color: #000055; - - border-color: #dddddd; - border-width: 2px; - border-style: solid; - - border-radius: 10px; - -moz-border-radius: 10px; -} -input[type="button"]:active { - background-color: #999999; -} -input[type="button"][disabled] { - border-color: #e5e5e5; - color: #b5b5b5; -} -input[type="button"][disabled]:active { - background-color: #f5f5f5; -} - -.header, .footer, .sideBar { - background-color: #eeeeee; -} - -.sideBar h1 { - font-size: 120%; -} -.sideBar h1, .sideBar h2, .sideBar h3, .sideBar h4, .sideBar h5 { - font-weight: normal; - - color: #555555; - background-color: #fafafa; - - border-color: #dddddd white white #dddddd; - border-width: 1px; - border-style: solid; -} - -.sideBar .date { - font-size: 70%; - white-space: nowrap; - color: #666666; -} - -.searchResult .date { - font-size: 70%; - white-space: nowrap; - color: #666666; -} - -.sideBar p { - text-indent: 0; -} - -.sideBar .recentUpdates p, -.sideBar .trackbacks p { - font-size: 90%; -} - -.sideBar .outline li { - list-style-type: disc; - background-color: inherit; -} -.sideBar .outline li li { - list-style-type: circle; -} -.sideBar .outline li li li { - list-style-type: square; -} -.sideBar .outline li li li li { - list-style-type: disc; -} -.sideBar .outline li li li li li { - list-style-type: circle; -} - -.sideBar li { - padding: 3px 5px; - background-color: #f5f5f5; - - border-radius: 10px; - -moz-border-radius: 10px; -} - -.sideBar .recentUpdates li, .sideBar .trackbacks li { - background-color: #e0e0e0; -} - -.sideBar input[type="text"], -.sideBar input[type="password"] { - background-color: #dddddd; - - border-style: inset; - border-width: 1px; - border-color: #dddddd; -} - -.activeField { - color: black; -} - -.inactiveField { - color: #888888; -} - -.pageEditor input[type="text"], -.pageEditor input[type="password"], -.pageEditor input[type="file"], -.pageEditor textarea { - border-color: #dddddd #fafafa #fafafa #dddddd; - border-width: 2px; - border-style: solid; - - background-color: white; -} - -.searchStat { - color: #888888; - font-size: 90%; -} - -.searchResult a { - font-size: 120%; -} -.searchResult { - border-style: dotted; - border-width: 1px 0 0 0; - border-color: #aaaaaa; -} - -.highlighted { - background-color: #ffefd5; -} - -.pager { - text-align: center; - - background-color: #f5f5f5; - - border-color: #cccccc; - border-width: 1px; - border-style: dotted; -} -.pager .currentSection, -.pager a { - border-style: solid; - border-width: 1px; -} -.pager .currentSection { - background-color: white; - border-color: #cccccc white white #cccccc; -} -.pager a { - background-color: #e8e8e8; - border-color: white #cccccc #cccccc white; -} - -/* float **********************************************************************/ -h1, h2, h3, h4, h5, h6 { - clear: both; -} - -/* image **********************************************************************/ -img { - border-width: 0; -} - -.inlineImage { - margin-top: 5px; - margin-bottom: 5px; -} - -.leftFloat { - float: left; - margin-right: 25px; -} - -.rightFloat { - float: right; - margin-left: 25px; -} - -.imageFrame { - background-color: #eeeeee; - padding: 5px; - - border-color: #cccccc; - border-width: 1px; - border-style: solid; - - margin-top: 5px; - margin-bottom: 10px; -} - -.imageFrame p { - margin: 0; -} - -.imageData { - text-align: center; -} - -.imageCaption { - margin-top: 3px; -} - -/* error **********************************************************************/ -.error { - color: red; - background-color: white; - - font-weight: bold; - - border-color: #880000; - border-width: 3px; - border-style: double; - - padding: 10px; -} - -.error p, .error pre { - margin: 0; -} - -.error:before { - content: "Error: " -} - -/* sidebar mask ***************************************************************/ -.sideBarMask { - position: fixed; - - background-color: black; - color: white; - opacity: 0.7; - - z-index: 1; -} - -.sideBarMask .content { - padding: 40px 0; -} - -.sideBarMask .content input[type="button"] { - font-size: 120%; - font-weight: bold; -} - -/* waiting message ************************************************************/ -.waitingMessageBoard { - position: fixed; - left: 0; - top: 0; - right: 0; - bottom: 0; - - margin: 0; - padding: 0; - - z-index: 1; -} - -.waitingMessageBoard p { - font-size: 200%; - - background-color: black; - color: white; - opacity: 0.7; - - position: fixed; - bottom: 1em; - right: 1em; - - text-indent: 0; - padding: 5px 30px; -} - -/* redirection message ********************************************************/ -.redirection { - margin: 5px; - padding: 2px; - - font-size: 80%; - - background-color: #fafafa; - color: #888888; - - border-color: #eeeeee; - border-width: 1px; - border-style: dotted -} - -.redirection input[type="button"] { - color: inherit; - background-color: #fcfcfc; - - border-width: 1px; - - border-radius: 5px; - -moz-border-radius: 5px; - - margin-left: 0.8em; -} - -.redirection input[type="button"]:active { - background-color: #eeeeee; -} - -/* preview ********************************************************************/ -.preview { - background-color: #eeeeee; - - margin: 0 0 20px 0; - padding: 10px; - - border-style: solid; - border-width: 1px; - border-color: #bbbbbb; -} - - rmfile ./defaultPages/StyleSheet/Default.xml rmdir ./defaultPages/StyleSheet rmdir ./defaultPages hunk ./js/Makefile 1 -JQUERY_SOURCE = jquery-1.2.6.js -COMPRESSOR = yuicompressor-2.3.5.jar - -SOURCES = \ - $(JQUERY_SOURCE) \ - jquery-dom.js \ - base.js \ - base64.js \ - editPage.js \ - hashedParam.js \ - hexDump.js \ - localFile.js \ - login.js \ - redirection.js \ - parseuri.js \ - screen.js \ - search.js \ - systemConfig.js \ - uri.js \ - $(NULL) - -COMPRESS = java -jar $(COMPRESSOR) --type js --charset UTF-8 - - -build: ../Rakka/Resource/JavaScript.hs - - -packed.js: $(SOURCES) $(COMPRESSOR) - cat $(SOURCES) > $@ -# cat $(SOURCES) | $(COMPRESS) -o $@ - - -../Rakka/Resource/JavaScript.hs: packed.js - lucu-implant-file -o $@ -m Rakka.Resource.JavaScript -t text/javascript packed.js - - -clean: - rm -f ../Rakka/Resource/JavaScript.hs packed.js $(JQUERY_PACKED) - - -$(COMPRESSOR): - @echo "Error: $(COMPRESSOR) has to be placed on this directory." - @echo " See http://www.julienlecomte.net/yuicompressor/" - @exit 1 rmfile ./js/Makefile hunk ./js/base.js 1 -/* Namespace Rakka */ -var Rakka = {}; - -/* These are constants that may be overwritten by HTML itself. */ -Rakka.baseURI = null; -Rakka.isLocked = false; -Rakka.isGlobalLocked = false; -Rakka.isSpecialPage = false; - -/* Common regular expressions */ -Rakka.rePageName = /^[^ a-z.|#\[\]][^ .|#\[\]]*$/; rmfile ./js/base.js hunk ./js/base64.js 1 -(function () { - - var encTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - var decTable = new Array( - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1); - - 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 += encTable.charAt(c1 >> 2); - ret += encTable.charAt((c1 & 0x03) << 4); - ret += "=="; - } - else { - var c2 = src.charCodeAt(i++); - - if (i == len) { - ret += encTable.charAt(c1 >> 2); - ret += encTable.charAt(((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)); - ret += encTable.charAt((c2 & 0x0F) << 2); - ret += "="; - } - else { - var c3 = src.charCodeAt(i++); - - ret += encTable.charAt(c1 >> 2); - ret += encTable.charAt(((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)); - ret += encTable.charAt(((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)); - ret += encTable.charAt(c3 & 0x3F); - } - } - } - - return ret; - }; - - Rakka.decodeBase64 = function (src) { - var len = src.length; - var i = 0; - var ret = ""; - - while (i < len) { - var c1; - do { - c1 = decTable[src.charCodeAt(i++)]; - } while (i < len && c1 == -1); - - if (c1 != -1) { - var c2; - do { - c2 = decTable[src.charCodeAt(i++)]; - } while (i < len && c2 == -1); - - if (c2 != -1) { - - ret += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4)); - - var c3; - do { - c3 = src.charCodeAt(i++); - if (c3 == 61) { - return ret; - } - c3 = decTable[c3]; - } while (i < len && c3 == -1); - - if (c3 != -1) { - ret += String.fromCharCode(((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2)); - - var c4; - do { - c4 = src.charCodeAt(i++); - if (c4 == 61) { - return ret; - } - c4 = decTable[c4]; - } while (i < len && c4 == -1); - - if (c4 != -1) { - ret += String.fromCharCode(((c3 & 0x03) << 6) | c4); - } - } - } - } - } - - return ret; - }; - -})(); + rmfile ./js/base64.js hunk ./js/editPage.js 1 -(function () { - - var $previewHeader = null; - var $previewArea = null; - - Rakka.editPage = function (pageName) { - var $area = Rakka.switchScreen(); - - Rakka.displayWaitingMessage("Loading... please wait."); - - // XML 版のページを取得する。 - $.ajax({ - url : Rakka.baseURI + pageName + ".xml", - success: function (pageXml) { - Rakka.hideWaitingMessage(); - - if (pageXml.documentElement.tagName == "page") { - var $page = $(pageXml).find("page"); - var oldRevision = $page.attr("revision"); - var defaultType - = $page.attr("isBinary") == "yes" ? "binary" - : $page.attr("type") == "text/x-rakka" ? "rakka" - : $page.attr("type") == "text/css" ? "css" - : $page.attr("type") == "text/javascript" ? "js" - : $page.attr("redirect") != null ? "redirect" - : "unknown" - ; - var lang = $page.attr("lang"); - var isLocked = $page.attr("isLocked") == "yes"; - var otherLangs = (function () { - var obj = {}; - $page.find("otherLang > link").each(function () { - obj[this.getAttribute("lang")] = this.getAttribute("page"); - }); - return obj; - })(); - var source - = $page.attr("redirect") != null ? $page.attr("redirect") - : $page.attr("isBinary") == "yes" ? Rakka.decodeBase64($page.find("binaryData").text()) - : $page.find("textData").text() - ; - var summary = $page.find("summary").text(); - - displayPageEditor(pageName, oldRevision, defaultType, lang, isLocked, otherLangs, source, summary); - } - else { - displayPageEditor(pageName, null, "rakka", null, false, {}, null, ""); - } - }, - error : function (req) { - Rakka.hideWaitingMessage(); - - if (req.status == 404) { - displayPageEditor(pageName, null, "rakka", null, false, {}, null, ""); - } - else { - $area.text("Error: " + req.status + " " + req.statusText); - } - } - }); - }; - - Rakka.newPage = function () { - displayPageEditor("", null, "rakka", null, false, {}, null, ""); - }; - - var displayPageEditor = function (pageName, oldRevision, defaultType, lang, isLocked, otherLangs, source, summary) { - var $area = Rakka.switchScreen(); - - $previewHeader = $( $.H1({}, "Preview") ); - $area.append($previewHeader); - $previewHeader.hide(); - - $previewArea = $( $.DIV({className: "preview"}) ); - $area.append($previewArea); - $previewArea.hide(); - - $area.append($.H1({}, pageName == "" ? "Create page" : "Edit page")); - - var isDirty = null; - var makeDirty = function () { - isDirty = true; - }; - - var fldPageName - = $.INPUT({type : "text", value: pageName}); - - $(fldPageName).change(makeDirty); - - var chkIsLocked - = $.INPUT({type : "checkbox", - checked : (isLocked ? "checked" : "")}); - - $(chkIsLocked).change(makeDirty); - - var trIsLocked - = $.TR({}, - $.TH({}, "Page lock"), - $.TD({}, - $.LABEL({}, - chkIsLocked, - "Disallow anonymous users to edit or delete this page"))); - - var btnTypeRakka - = $.INPUT({type : "radio", - name : "type", - checked: (defaultType == "rakka" ? "checked" : "")}); - - $(btnTypeRakka).change(makeDirty); - - var btnTypeCSS - = $.INPUT({type : "radio", - name : "type", - checked: (defaultType == "css" ? "checked" : "")}); - - $(btnTypeCSS).change(makeDirty); - - var btnTypeJS - = $.INPUT({type : "radio", - name : "type", - checked: (defaultType == "js" ? "checked" : "")}); - $(btnTypeJS).change(makeDirty); - - var btnTypeBinary - = $.INPUT({type : "radio", - name : "type", - checked: (defaultType == "binary" ? "checked" : "")}); - - $(btnTypeBinary).change(makeDirty); - - var btnTypeRedirect - = $.INPUT({type : "radio", - name : "type", - checked: (defaultType == "redirect" ? "checked" : "")}); - - $(btnTypeRedirect).change(makeDirty); - - var selPageLang - = $.SELECT({}, - $.OPTION({value: ""}, "(unspecified)"), - (function () { - var options = []; - - $.each(Rakka.getSystemConfig().languages, function (tag, name) { - options.push( - $.OPTION({value: tag}, name)); - }); - - return options; - })()); - - $(selPageLang).change(makeDirty); - - if (lang == null || lang == "") { - $(selPageLang).val($("html").attr("xml:lang")); - } - else { - $(selPageLang).val(lang); - } - - var trPageLang - = $.TR({}, - $.TH({}, "Page language"), - $.TD({}, selPageLang)); - - var trOtherLangs = (function () { - var options = []; - - $.each(Rakka.getSystemConfig().languages, function (tag, name) { - options.push( - $.OPTION({value: tag}, name)); - }); - - var selLang = $.SELECT({}, options); - var fldLink = $.INPUT({type: "text", className: "smallField"}); - - $(selLang).change(function () { - var pageName = otherLangs[$(selLang).val()]; - $(fldLink).val( - pageName == null ? "" : pageName - ); - }).trigger("change"); - - var onLinkChanged = function () { - isDirty = true; - - var lang = $(selLang).val(); - var pageName = $(this).val(); - - if (pageName == "") { - delete otherLangs[lang]; - } - else { - otherLangs[lang] = pageName; - } - }; - $(fldLink).change(onLinkChanged).keyup(onLinkChanged); - - return $.TR({}, - $.TH({}, "Language links"), - $.TD({}, selLang, fldLink)); - })(); - - var fldSummary - = $.TEXTAREA({className: "summary"}, summary); - - $(fldSummary).change(makeDirty); - - var trSummary - = $.TR({}, - $.TH({}, "Summary"), - $.TD({}, fldSummary)); - - var fldRakkaSource - = $.TEXTAREA({className: "source"}, - (defaultType == "rakka" && source != null ? source : "")); - - $(fldRakkaSource).change(makeDirty); - - var fldCSSSource - = $.TEXTAREA({className: "source"}, - (defaultType == "css" && source != null ? source : "")); - - $(fldCSSSource).change(makeDirty); - - var fldJSSource - = $.TEXTAREA({className: "source"}, - (defaultType == "js" && source != null ? source : "")); - - $(fldJSSource).change(makeDirty); - - var uploadFileBin - = (defaultType == "binary" && source != null ? source : ""); - var fldUploadFile - = $.TEXTAREA({className: "hexDump", disabled: true}, Rakka.hexDump(uploadFileBin, 128)); - var btnSelectFile - = $.INPUT({type: "button", value: "Select file..."}); - - $(btnSelectFile).click(function () { - var path = Rakka.selectFile("Select a binary file to upload", "open"); - if (path != null) { - uploadFileBin = Rakka.loadLocalBinaryFile(path); - fldUploadFile.value = Rakka.hexDump(uploadFileBin, 128); - makeDirty(); - } - }); - - var fldRedirect - = $.INPUT({type: "text", value: (defaultType == "redirect" ? source : "")}); - - $(fldRedirect).change(makeDirty); - - var trContent - = $.TR({}, - $.TH({}), - $.TD({}) - ); - - var btnPreview - = $.INPUT({type: "button", value: "Preview page"}); - - $(btnPreview).click(function () { - if (btnTypeRakka.checked) { - previewRakkaPage( - fldPageName.value, fldRakkaSource.value); - } - else if (btnTypeBinary.checked) { - if (uploadFileBin != "") { - previewBinaryPage( - fldPageName.value, uploadFileBin); - } - } - }); - - var btnSubmit - = $.INPUT({type: "button", value: "Submit page"}); - - $(btnSubmit).click(function () { - if (btnTypeRakka.checked) { - submitTextPage( - pageName, - oldRevision, - fldPageName.value, - chkIsLocked.checked, - "text/x-rakka", - $(selPageLang).val(), - otherLangs, - fldSummary.value, - fldRakkaSource.value); - } - else if (btnTypeCSS.checked) { - submitTextPage( - pageName, - oldRevision, - fldPageName.value, - chkIsLocked.checked, - "text/css", - $(selPageLang).val(), - otherLangs, - fldSummary.value, - fldCSSSource.value); - } - else if (btnTypeJS.checked) { - submitTextPage( - pageName, - oldRevision, - fldPageName.value, - chkIsLocked.checked, - "text/javascript", - $(selPageLang).val(), - otherLangs, - fldSummary.value, - fldJSSource.value); - } - else if (btnTypeBinary.checked) { - if (fldUploadFile.value != "") { - submitBinaryPage( - pageName, - oldRevision, - fldPageName.value, - chkIsLocked.checked, - $(selPageLang).val(), - otherLangs, - fldSummary.value, - uploadFileBin); - } - } - else if (btnTypeRedirect.checked) { - submitRedirection( - pageName, - oldRevision, - fldPageName.value, - chkIsLocked.checked, - fldRedirect.value); - } - }); - - var btnDelete - = $.INPUT({type: "button", value: "Delete this page"}); - - $(btnDelete).click(function () { - if (window.confirm("Do you really want to delete this page?")) { - deletePage(pageName); - } - }); - - var updateTRContent = function () { - if (btnTypeRakka.checked) { - $(trPageLang).show(); - $(trOtherLangs).show(); - $(trSummary).show(); - $(trContent).find("th").text("Wiki source"); - $(trContent).find("td").empty().append(fldRakkaSource); - $(btnPreview).show(); - } - else if (btnTypeCSS.checked) { - $(trPageLang).show(); - $(trOtherLangs).show(); - $(trSummary).show(); - $(trContent).find("th").text("CSS source"); - $(trContent).find("td").empty().append(fldCSSSource); - $(btnPreview).hide(); - } - else if (btnTypeJS.checked) { - $(trPageLang).show(); - $(trOtherLangs).show(); - $(trSummary).show(); - $(trContent).find("th").text("JavaScript source"); - $(trContent).find("td").empty().append(fldJSSource); - $(btnPreview).hide(); - } - else if (btnTypeBinary.checked) { - $(trPageLang).show(); - $(trOtherLangs).show(); - $(trSummary).show(); - $(trContent).find("th").text("File"); - $(trContent).find("td").empty().append(fldUploadFile).append(btnSelectFile); - $(btnPreview).show(); - } - else if (btnTypeRedirect.checked) { - $(trPageLang).hide(); - $(trOtherLangs).hide(); - $(trSummary).hide(); - $(trContent).find("th").text("Destination Page"); - $(trContent).find("td").empty().append(fldRedirect); - $(btnPreview).hide(); - } - }; - $(btnTypeRakka ).change(updateTRContent); - $(btnTypeCSS ).change(updateTRContent); - $(btnTypeJS ).change(updateTRContent); - $(btnTypeBinary ).change(updateTRContent); - $(btnTypeRedirect).change(updateTRContent); - updateTRContent(); - - var pageEditor - = $.TABLE({className: "pageEditor"}, - $.TBODY({}, - $.TR({}, - $.TH({}, "Page name"), - $.TD({}, fldPageName) - ), - trIsLocked, - $.TR({}, - $.TH({}, "Page type"), - $.TD({}, - $.UL({}, - $.LI({}, - $.LABEL({}, - btnTypeRakka, - "Wiki page" - ) - ), - $.LI({}, - $.LABEL({}, - btnTypeCSS, - "Style sheet" - ) - ), - $.LI({}, - $.LABEL({}, - btnTypeJS, - "JavaScript" - ) - ), - $.LI({}, - $.LABEL({}, - btnTypeBinary, - "Binary file" - ) - ), - $.LI({}, - $.LABEL({}, - btnTypeRedirect, - "Redirection" - ) - ) - ) - ) - ), - trPageLang, - trOtherLangs, - trSummary, - trContent, - $.TR({}, - $.TH({}), - $.TD({}, btnPreview, btnSubmit, btnDelete) - ) - ) - ); - - var validate = function () { - var isValid = (function () { - if (fldPageName.value.match(Rakka.rePageName) == null) { - return false; - } - - if (btnTypeRedirect.checked) { - if (fldRedirect.value.match(Rakka.rePageName) == null) { - return false; - } - } - else { - for (var tag in otherLangs) { - if (otherLangs[tag].match(Rakka.rePageName) == null) { - return false; - } - } - - if (btnTypeBinary.checked) { - if (uploadFileBin == "") { - return false; - } - } - } - - return true; - })(); - - $(btnSubmit).attr({disabled: (isValid ? "" : "disabled")}); - }; - $(fldPageName) - .add(btnTypeRakka) - .add(btnTypeCSS) - .add(btnTypeJS) - .add(btnTypeBinary) - .add(btnTypeRedirect) - .add($(trOtherLangs).find("input")) - .add(fldUploadFile) - .add(fldRedirect) - .change(validate) - .keyup(validate); - $(btnSelectFile).click(validate); - validate(); - - if (oldRevision == null || oldRevision == 0) { - // 削除不可 - $(btnDelete).hide(); - } - - $area.append(pageEditor); - - if (!Rakka.isLoggedIn() || Rakka.isGlobalLocked) { - $(trIsLocked).hide(); - } - }; - - var previewRakkaPage = function (pageName, source) { - Rakka.displayWaitingMessage("Loading... please wait."); - - var url = Rakka.baseURI + "render/" + encodeURI(pageName); - $.ajax({ - type : "POST", - url : url, - contentType: "text/x-rakka", - data : source, - processData: false, - success : function (resultDoc) { - Rakka.hideWaitingMessage(); - showPreview(resultDoc); - }, - error : function (req) { - Rakka.hideWaitingMessage(); - alert("Error: " + req.status + " " + req.statusText); - } - }); - }; - - var previewBinaryPage = function (pageName, data) { - Rakka.displayWaitingMessage("Loading... please wait."); - - /* Firefox でバイナリを送らうとすると 0x00 の位置で切れてしまふ。*/ - var url = Rakka.baseURI + "render/" + encodeURI(pageName); - $.ajax({ - type : "POST", - url : url, - contentType: "application/x-rakka-base64-stream", - data : Rakka.encodeBase64(data), - processData: false, - success : function (resultDoc) { - Rakka.hideWaitingMessage(); - showPreview(resultDoc); - }, - error : function (req) { - Rakka.hideWaitingMessage(); - alert("Error: " + req.status + " " + req.statusText); - } - }); - }; - - var showPreview = function (doc) { - $previewArea.empty(); - - $previewHeader.show(); - $previewArea.show(); - - var root = doc.documentElement; - var child = root.firstChild; - do { - if (child.nodeType == 1) { - // 要素だったので複製 - $previewArea.append(child.cloneNode(true)); - } - } while (child = child.nextSibling); - - Rakka.scrollToTopLeft(); - }; - - var submitTextPage - = function (pageName, oldRevision, givenPageName, isLocked, mimeType, lang, otherLangs, summary, text) { - var NS = "http://cielonegro.org/schema/Rakka/Page/1.0"; - var doc = document.implementation.createDocument(NS, "page", null); - var page = doc.documentElement; - - if (oldRevision != null) { - // ページ書換時 - var updateInfo = doc.createElementNS(NS, "updateInfo"); - updateInfo.setAttribute("oldRevision", oldRevision); - - if (pageName != givenPageName) { - var move = doc.createElementNS(NS, "move"); - move.setAttribute("from", pageName); - updateInfo.appendChild(move); - } - - page.appendChild(updateInfo); - } - - page.setAttribute("isLocked", isLocked ? "yes" : "no"); - page.setAttribute("type", mimeType); - - if (lang != null && lang != "") { - page.setAttribute("lang", lang); - } - - if (summary != null && summary != "") { - var s = doc.createElementNS(NS, "summary"); - s.appendChild( - doc.createTextNode(summary)); - page.appendChild(s); - } - - var oLang = doc.createElementNS(NS, "otherLang"); - for (var tag in otherLangs) { - var link = doc.createElementNS(NS, "link"); - link.setAttribute("lang", tag); - link.setAttribute("page", otherLangs[tag]); - oLang.appendChild(link); - } - page.appendChild(oLang); - - var textData = doc.createElementNS(NS, "textData"); - textData.appendChild( - doc.createTextNode(text)); - - page.appendChild(textData); - - Rakka.displayWaitingMessage("Submitting... please wait."); - - var url = Rakka.baseURI + encodeURI(givenPageName); - $.ajax({ - type : "PUT", - url : url, - contentType: "text/xml", - data : doc, - processData: false, - beforeSend : function (req) { - Rakka.setAuthorization(req); - }, - success : function () { - window.location.replace(url); - }, - error : function (req) { - Rakka.hideWaitingMessage(); - - var $area = Rakka.switchScreen(); - $area.text("Error: " + req.status + " " + req.statusText); - } - }); - }; - - var submitBinaryPage = function (pageName, oldRevision, givenPageName, isLocked, lang, otherLangs, summary, data) { - var NS = "http://cielonegro.org/schema/Rakka/Page/1.0"; - var doc = document.implementation.createDocument(NS, "page", null); - var page = doc.documentElement; - - if (oldRevision != null) { - // ページ書換時 - var updateInfo = doc.createElementNS(NS, "updateInfo"); - updateInfo.setAttribute("oldRevision", oldRevision); - - if (pageName != givenPageName) { - var move = doc.createElementNS(NS, "move"); - move.setAttribute("from", pageName); - updateInfo.appendChild(move); - } - - page.appendChild(updateInfo); - } - - page.setAttribute("isLocked", isLocked ? "yes" : "no"); - page.setAttribute("type", ""); - - if (lang != null && lang != "") { - page.setAttribute("lang", lang); - } - - if (summary != null) { - var s = doc.createElementNS(NS, "summary"); - s.appendChild( - doc.createTextNode(summary)); - page.appendChild(s); - } - - var oLang = doc.createElementNS(NS, "otherLang"); - for (var tag in otherLangs) { - var link = doc.createElementNS(NS, "link"); - link.setAttribute("lang", tag); - link.setAttribute("page", otherLangs[tag]); - oLang.appendChild(link); - } - page.appendChild(oLang); - - var b64 = Rakka.encodeBase64(data); - var binaryData = doc.createElementNS(NS, "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, - beforeSend : function (req) { - Rakka.setAuthorization(req); - }, - success : function () { - window.location.replace(url); - }, - error : function (req) { - Rakka.hideWaitingMessage(); - - var $area = Rakka.switchScreen(); - $area.text("Error: " + req.status + " " + req.statusText); - } - }); - }; - - var submitRedirection = function (pageName, oldRevision, givenPageName, isLocked, destination) { - var NS = "http://cielonegro.org/schema/Rakka/Page/1.0"; - var doc = document.implementation.createDocument(NS, "page", null); - var page = doc.documentElement; - - if (oldRevision != null) { - // ページ書換時 - var updateInfo = doc.createElementNS(NS, "updateInfo"); - updateInfo.setAttribute("oldRevision", oldRevision); - - if (pageName != givenPageName) { - var move = doc.createElementNS(NS, "move"); - move.setAttribute("from", pageName); - updateInfo.appendChild(move); - } - - page.appendChild(updateInfo); - } - - page.setAttribute("isLocked", isLocked ? "yes" : "no"); - page.setAttribute("redirect", destination); - - Rakka.displayWaitingMessage("Submitting... please wait."); - - var url = Rakka.baseURI + encodeURI(givenPageName); - $.ajax({ - type : "PUT", - url : url, - contentType: "text/xml", - data : doc, - processData: false, - beforeSend : function (req) { - Rakka.setAuthorization(req); - }, - success : function () { - window.location.replace(url); - }, - error : function (req) { - Rakka.hideWaitingMessage(); - - var $area = Rakka.switchScreen(); - $area.text("Error: " + req.status + " " + req.statusText); - } - }); - }; - - var deletePage = function (pageName) { - var url = Rakka.baseURI + encodeURI(pageName); - $.ajax({ - type : "DELETE", - url : url, - beforeSend : function (req) { - Rakka.setAuthorization(req); - }, - success : function () { - window.location.replace(url); - }, - error : function (req) { - Rakka.hideWaitingMessage(); - - var $area = Rakka.switchScreen(); - $area.text("Error: " + req.status + " " + req.statusText); - } - }); - }; - -})(); + rmfile ./js/editPage.js hunk ./js/hashedParam.js 1 -$(document).ready(function () { - - /* Example of hashed params: - * - * /Foo/Bar.html#Redirect:Baz - * /Foo/Bar.html#EditPage - * /Foo/Bar.html#Redirect:Baz|EditPage - */ - - var cached_rawHash; - var cached_map; - - /* - var re_key = /^[^:|]+$/; - var re_value = /^[^|]*$/; - */ - - var getRawHash = function () { - /* Don't use window.location.hash as it isn't portable due to - * an ambiguous specification. - */ - var r = window.location.href; - var i = r.indexOf("#"); - return (i >= 0 - ? r.substr(i + 1) - : ""); - }; - - /* - var setRawHash = function (hash) { - var r = window.location.href; - var i = r.indexOf("#"); - var b = (i >= 0 - ? r.substr(0, i) - : r); - window.location.href = b + "#" + hash; - }; - */ - - var getHashedParamMap = function () { - var raw = getRawHash(); - - if (cached_rawHash != raw) { - var src = decodeURIComponent(raw); - - // Split the source by '|' letters. - cached_map = {}; - $.each(src.split("|"), function () { - // tuple ::= key ':' value - // | key (value is the same as key) - var i = this.indexOf(":"); - if (i >= 0) { - var key = this.substr(0, i); - var val = this.substr(i + 1); - cached_map[key] = val; - } - else { - var key = this; - cached_map[key] = key; - } - }); - - cached_rawHash = raw; - } - - return cached_map; - }; - - Rakka.getHashedParam = function (key) { - return getHashedParamMap()[key]; - }; - - /* - var setHashedParamMap = function (map) { - var tuples = ""; - - $.each(map, function(key, val) { - var tuple = (key == val - ? key - : key + ":" + val); - - tuples = (tuples == "" - ? tuple - : tuples + "|" + tuple); - }); - - cached_map = map; - cached_raw = encodeURIComponent(tuples); - - setRawHash(cached_raw); - }; - - Rakka.setHashedParam = function (key, value) { - var diff = {}; - diff[key] = value; - Rakka.setHashedParams(diff); - }; - - Rakka.setHashedParams = function (diff) { - var orig = getHashedParamMap(); - var next = {}; - - // Copy 'orig' to 'next'. - $.each(orig, function (key, val) { - next[key] = val; - }); - - // Overwrite the content of 'next' with 'diff'. - $.each(diff, function (key, val) { - - if (!key.match(re_key)) { - throw new Error("Invalid key: " + key); - } - if (!val.match(re_value)) { - throw new Error("Invalid value: " + val); - } - - if (diff[key] == null) { - delete next[key]; - } - else { - next[key] = val; - } - }); - - setHashedParamMap(next); - }; - */ -}); + rmfile ./js/hashedParam.js hunk ./js/hexDump.js 1 -(function () { - - var repeat = function (times, str) { - var ret = ""; - - for (var i = 0; i < times; i++) { - ret += str; - } - - return ret; - }; - - var printHex = function (width, num) { - var ret = Number(num).toString(16); - - if (ret.length < width) { - return repeat(width - ret.length, "0") + ret; - } - else { - return ret; - } - }; - - var isPrintableAscii = function (code) { - return (code >= 0x20 && code <= 0x7e); - }; - - Rakka.hexDump = function (data, limit) { - var offset = 0; - var size = Math.min(data.length, limit); - var ret = ""; - - for (; offset < size; offset += 16) { - ret += printHex(8, offset); - ret += " "; - - var begin = offset; - var end = Math.min(offset + 16, size); - - for (var i = begin; i < end; i++) { - var c = data.charCodeAt(i); - - ret += printHex(2, c); - ret += " "; - - if (end - i == 9) { - ret += " "; - } - } - for (var i = end; i < offset + 16; i++) { - ret += " "; - if (end - i == 9) { - ret += " "; - } - } - - ret += " |"; - - for (var i = begin; i < end; i++) { - var c = data.charCodeAt(i); - - if (isPrintableAscii(c)) { - ret += data.charAt(i); - } - else { - ret += "."; - } - } - ret += "|"; - for (var i = end; i < offset + 16; i++) { - ret += " "; - } - - ret += "\n"; - } - - if (data.length > limit) { - ret += printHex(8, offset); - ret += " ...\n"; - } - - return ret; - }; - - })(); + rmfile ./js/hexDump.js hunk ./js/jquery-1.2.6.js 1 -(function(){ -/* - * jQuery 1.2.6 - New Wave Javascript - * - * Copyright (c) 2008 John Resig (jquery.com) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $ - * $Rev: 5685 $ - */ - -// Map over jQuery in case of overwrite -var _jQuery = window.jQuery, -// Map over the $ in case of overwrite - _$ = window.$; - -var jQuery = window.jQuery = window.$ = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context ); -}; - -// A simple way to check for HTML strings or ID strings -// (both of which we optimize for) -var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/, - -// Is it a simple selector - isSimple = /^.[^:#\[\.]*$/, - -// Will speed up references to undefined, and allows munging its name. - undefined; - -jQuery.fn = jQuery.prototype = { - init: function( selector, context ) { - // Make sure that a selection was provided - selector = selector || document; - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this[0] = selector; - this.length = 1; - return this; - } - // Handle HTML strings - if ( typeof selector == "string" ) { - // Are we dealing with HTML string or an ID? - var match = quickExpr.exec( selector ); - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) - selector = jQuery.clean( [ match[1] ], context ); - - // HANDLE: $("#id") - else { - var elem = document.getElementById( match[3] ); - - // Make sure an element was located - if ( elem ){ - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id != match[3] ) - return jQuery().find( selector ); - - // Otherwise, we inject the element directly into the jQuery object - return jQuery( elem ); - } - selector = []; - } - - // HANDLE: $(expr, [context]) - // (which is just equivalent to: $(content).find(expr) - } else - return jQuery( context ).find( selector ); - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) - return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector ); - - return this.setArray(jQuery.makeArray(selector)); - }, - - // The current version of jQuery being used - jquery: "1.2.6", - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - // The number of elements contained in the matched element set - length: 0, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num == undefined ? - - // Return a 'clean' array - jQuery.makeArray( this ) : - - // Return just the object - this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - // Build a new jQuery matched element set - var ret = jQuery( elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Force the current matched set of elements to become - // the specified array of elements (destroying the stack in the process) - // You should use pushStack() in order to do this, but maintain the stack - setArray: function( elems ) { - // Resetting the length to 0, then using the native Array push - // is a super-fast way to populate an object with array-like properties - this.length = 0; - Array.prototype.push.apply( this, elems ); - - return this; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - var ret = -1; - - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem && elem.jquery ? elem[0] : elem - , this ); - }, - - attr: function( name, value, type ) { - var options = name; - - // Look for the case where we're accessing a style value - if ( name.constructor == String ) - if ( value === undefined ) - return this[0] && jQuery[ type || "attr" ]( this[0], name ); - - else { - options = {}; - options[ name ] = value; - } - - // Check to see if we're setting style values - return this.each(function(i){ - // Set all the styles - for ( name in options ) - jQuery.attr( - type ? - this.style : - this, - name, jQuery.prop( this, options[ name ], type, i, name ) - ); - }); - }, - - css: function( key, value ) { - // ignore negative width and height values - if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) - value = undefined; - return this.attr( key, value, "curCSS" ); - }, - - text: function( text ) { - if ( typeof text != "object" && text != null ) - return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); - - var ret = ""; - - jQuery.each( text || this, function(){ - jQuery.each( this.childNodes, function(){ - if ( this.nodeType != 8 ) - ret += this.nodeType != 1 ? - this.nodeValue : - jQuery.fn.text( [ this ] ); - }); - }); - - return ret; - }, - - wrapAll: function( html ) { - if ( this[0] ) - // The elements to wrap the target around - jQuery( html, this[0].ownerDocument ) - .clone() - .insertBefore( this[0] ) - .map(function(){ - var elem = this; - - while ( elem.firstChild ) - elem = elem.firstChild; - - return elem; - }) - .append(this); - - return this; - }, - - wrapInner: function( html ) { - return this.each(function(){ - jQuery( this ).contents().wrapAll( html ); - }); - }, - - wrap: function( html ) { - return this.each(function(){ - jQuery( this ).wrapAll( html ); - }); - }, - - append: function() { - return this.domManip(arguments, true, false, function(elem){ - if (this.nodeType == 1) - this.appendChild( elem ); - }); - }, - - prepend: function() { - return this.domManip(arguments, true, true, function(elem){ - if (this.nodeType == 1) - this.insertBefore( elem, this.firstChild ); - }); - }, - - before: function() { - return this.domManip(arguments, false, false, function(elem){ - this.parentNode.insertBefore( elem, this ); - }); - }, - - after: function() { - return this.domManip(arguments, false, true, function(elem){ - this.parentNode.insertBefore( elem, this.nextSibling ); - }); - }, - - end: function() { - return this.prevObject || jQuery( [] ); - }, - - find: function( selector ) { - var elems = jQuery.map(this, function(elem){ - return jQuery.find( selector, elem ); - }); - - return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? - jQuery.unique( elems ) : - elems ); - }, - - clone: function( events ) { - // Do the clone - var ret = this.map(function(){ - if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) { - // IE copies events bound via attachEvent when - // using cloneNode. Calling detachEvent on the - // clone will also remove the events from the orignal - // In order to get around this, we use innerHTML. - // Unfortunately, this means some modifications to - // attributes in IE that are actually only stored - // as properties will not be copied (such as the - // the name attribute on an input). - var clone = this.cloneNode(true), - container = document.createElement("div"); - container.appendChild(clone); - return jQuery.clean([container.innerHTML])[0]; - } else - return this.cloneNode(true); - }); - - // Need to set the expando to null on the cloned set if it exists - // removeData doesn't work here, IE removes it from the original as well - // this is primarily for IE but the data expando shouldn't be copied over in any browser - var clone = ret.find("*").andSelf().each(function(){ - if ( this[ expando ] != undefined ) - this[ expando ] = null; - }); - - // Copy the events from the original to the clone - if ( events === true ) - this.find("*").andSelf().each(function(i){ - if (this.nodeType == 3) - return; - var events = jQuery.data( this, "events" ); - - for ( var type in events ) - for ( var handler in events[ type ] ) - jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); - }); - - // Return the cloned set - return ret; - }, - - filter: function( selector ) { - return this.pushStack( - jQuery.isFunction( selector ) && - jQuery.grep(this, function(elem, i){ - return selector.call( elem, i ); - }) || - - jQuery.multiFilter( selector, this ) ); - }, - - not: function( selector ) { - if ( selector.constructor == String ) - // test special case where just one selector is passed in - if ( isSimple.test( selector ) ) - return this.pushStack( jQuery.multiFilter( selector, this, true ) ); - else - selector = jQuery.multiFilter( selector, this ); - - var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; - return this.filter(function() { - return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; - }); - }, - - add: function( selector ) { - return this.pushStack( jQuery.unique( jQuery.merge( - this.get(), - typeof selector == 'string' ? - jQuery( selector ) : - jQuery.makeArray( selector ) - ))); - }, - - is: function( selector ) { - return !!selector && jQuery.multiFilter( selector, this ).length > 0; - }, - - hasClass: function( selector ) { - return this.is( "." + selector ); - }, - - val: function( value ) { - if ( value == undefined ) { - - if ( this.length ) { - var elem = this[0]; - - // We need to handle select boxes special - if ( jQuery.nodeName( elem, "select" ) ) { - var index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type == "select-one"; - - // Nothing was selected - if ( index < 0 ) - return null; - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - if ( option.selected ) { - // Get the specifc value for the option - value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value; - - // We don't need an array for one selects - if ( one ) - return value; - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - - // Everything else, we just grab the value - } else - return (this[0].value || "").replace(/\r/g, ""); - - } - - return undefined; - } - - if( value.constructor == Number ) - value += ''; - - return this.each(function(){ - if ( this.nodeType != 1 ) - return; - - if ( value.constructor == Array && /radio|checkbox/.test( this.type ) ) - this.checked = (jQuery.inArray(this.value, value) >= 0 || - jQuery.inArray(this.name, value) >= 0); - - else if ( jQuery.nodeName( this, "select" ) ) { - var values = jQuery.makeArray(value); - - jQuery( "option", this ).each(function(){ - this.selected = (jQuery.inArray( this.value, values ) >= 0 || - jQuery.inArray( this.text, values ) >= 0); - }); - - if ( !values.length ) - this.selectedIndex = -1; - - } else - this.value = value; - }); - }, - - html: function( value ) { - return value == undefined ? - (this[0] ? - this[0].innerHTML : - null) : - this.empty().append( value ); - }, - - replaceWith: function( value ) { - return this.after( value ).remove(); - }, - - eq: function( i ) { - return this.slice( i, i + 1 ); - }, - - slice: function() { - return this.pushStack( Array.prototype.slice.apply( this, arguments ) ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function(elem, i){ - return callback.call( elem, i, elem ); - })); - }, - - andSelf: function() { - return this.add( this.prevObject ); - }, - - data: function( key, value ){ - var parts = key.split("."); - parts[1] = parts[1] ? "." + parts[1] : ""; - - if ( value === undefined ) { - var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); - - if ( data === undefined && this.length ) - data = jQuery.data( this[0], key ); - - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; - } else - return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){ - jQuery.data( this, key, value ); - }); - }, - - removeData: function( key ){ - return this.each(function(){ - jQuery.removeData( this, key ); - }); - }, - - domManip: function( args, table, reverse, callback ) { - var clone = this.length > 1, elems; - - return this.each(function(){ - if ( !elems ) { - elems = jQuery.clean( args, this.ownerDocument ); - - if ( reverse ) - elems.reverse(); - } - - var obj = this; - - if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) - obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); - - var scripts = jQuery( [] ); - - jQuery.each(elems, function(){ - var elem = clone ? - jQuery( this ).clone( true )[0] : - this; - - // execute all scripts after the elements have been injected - if ( jQuery.nodeName( elem, "script" ) ) - scripts = scripts.add( elem ); - else { - // Remove any inner scripts for later evaluation - if ( elem.nodeType == 1 ) - scripts = scripts.add( jQuery( "script", elem ).remove() ); - - // Inject the elements into the document - callback.call( obj, elem ); - } - }); - - scripts.each( evalScript ); - }); - } -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -function evalScript( i, elem ) { - if ( elem.src ) - jQuery.ajax({ - url: elem.src, - async: false, - dataType: "script" - }); - - else - jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); - - if ( elem.parentNode ) - elem.parentNode.removeChild( elem ); -} - -function now(){ - return +new Date; -} - -jQuery.extend = jQuery.fn.extend = function() { - // copy reference to target object - var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; - - // Handle a deep copy situation - if ( target.constructor == Boolean ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target != "object" && typeof target != "function" ) - target = {}; - - // extend jQuery itself if only one argument is passed - if ( length == i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) - // Extend the base object - for ( var name in options ) { - var src = target[ name ], copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) - continue; - - // Recurse if we're merging object values - if ( deep && copy && typeof copy == "object" && !copy.nodeType ) - target[ name ] = jQuery.extend( deep, - // Never move original objects, clone them - src || ( copy.length != null ? [ ] : { } ) - , copy ); - - // Don't bring in undefined values - else if ( copy !== undefined ) - target[ name ] = copy; - - } - - // Return the modified object - return target; -}; - -var expando = "jQuery" + now(), uuid = 0, windowData = {}, - // exclude the following css properties to add px - exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, - // cache defaultView - defaultView = document.defaultView || {}; - -jQuery.extend({ - noConflict: function( deep ) { - window.$ = _$; - - if ( deep ) - window.jQuery = _jQuery; - - return jQuery; - }, - - // See test/unit/core.js for details concerning this function. - isFunction: function( fn ) { - return !!fn && typeof fn != "string" && !fn.nodeName && - fn.constructor != Array && /^[\s[]?function/.test( fn + "" ); - }, - - // check if an element is in a (or is an) XML document - isXMLDoc: function( elem ) { - return elem.documentElement && !elem.body || - elem.tagName && elem.ownerDocument && !elem.ownerDocument.body; - }, - - // Evalulates a script in a global context - globalEval: function( data ) { - data = jQuery.trim( data ); - - if ( data ) { - // Inspired by code by Andrea Giammarchi - // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.getElementsByTagName("head")[0] || document.documentElement, - script = document.createElement("script"); - - script.type = "text/javascript"; - if ( jQuery.browser.msie ) - script.text = data; - else - script.appendChild( document.createTextNode( data ) ); - - // Use insertBefore instead of appendChild to circumvent an IE6 bug. - // This arises when a base node is used (#2709). - head.insertBefore( script, head.firstChild ); - head.removeChild( script ); - } - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); - }, - - cache: {}, - - data: function( elem, name, data ) { - elem = elem == window ? - windowData : - elem; - - var id = elem[ expando ]; - - // Compute a unique ID for the element - if ( !id ) - id = elem[ expando ] = ++uuid; - - // Only generate the data cache if we're - // trying to access or manipulate it - if ( name && !jQuery.cache[ id ] ) - jQuery.cache[ id ] = {}; - - // Prevent overriding the named cache with undefined values - if ( data !== undefined ) - jQuery.cache[ id ][ name ] = data; - - // Return the named cache data, or the ID for the element - return name ? - jQuery.cache[ id ][ name ] : - id; - }, - - removeData: function( elem, name ) { - elem = elem == window ? - windowData : - elem; - - var id = elem[ expando ]; - - // If we want to remove a specific section of the element's data - if ( name ) { - if ( jQuery.cache[ id ] ) { - // Remove the section of cache data - delete jQuery.cache[ id ][ name ]; - - // If we've removed all the data, remove the element's cache - name = ""; - - for ( name in jQuery.cache[ id ] ) - break; - - if ( !name ) - jQuery.removeData( elem ); - } - - // Otherwise, we want to remove all of the element's data - } else { - // Clean up the element expando - try { - delete elem[ expando ]; - } catch(e){ - // IE has trouble directly removing the expando - // but it's ok with using removeAttribute - if ( elem.removeAttribute ) - elem.removeAttribute( expando ); - } - - // Completely remove the data cache - delete jQuery.cache[ id ]; - } - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, length = object.length; - - if ( args ) { - if ( length == undefined ) { - for ( name in object ) - if ( callback.apply( object[ name ], args ) === false ) - break; - } else - for ( ; i < length; ) - if ( callback.apply( object[ i++ ], args ) === false ) - break; - - // A special, fast, case for the most common use of each - } else { - if ( length == undefined ) { - for ( name in object ) - if ( callback.call( object[ name ], name, object[ name ] ) === false ) - break; - } else - for ( var value = object[0]; - i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} - } - - return object; - }, - - prop: function( elem, value, type, i, name ) { - // Handle executable functions - if ( jQuery.isFunction( value ) ) - value = value.call( elem, i ); - - // Handle passing in a number to a CSS property - return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ? - value + "px" : - value; - }, - - className: { - // internal only, use addClass("class") - add: function( elem, classNames ) { - jQuery.each((classNames || "").split(/\s+/), function(i, className){ - if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) - elem.className += (elem.className ? " " : "") + className; - }); - }, - - // internal only, use removeClass("class") - remove: function( elem, classNames ) { - if (elem.nodeType == 1) - elem.className = classNames != undefined ? - jQuery.grep(elem.className.split(/\s+/), function(className){ - return !jQuery.className.has( classNames, className ); - }).join(" ") : - ""; - }, - - // internal only, use hasClass("class") - has: function( elem, className ) { - return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; - } - }, - - // A method for quickly swapping in/out CSS properties to get correct calculations - swap: function( elem, options, callback ) { - var old = {}; - // Remember the old values, and insert the new ones - for ( var name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - callback.call( elem ); - - // Revert the old values - for ( var name in options ) - elem.style[ name ] = old[ name ]; - }, - - css: function( elem, name, force ) { - if ( name == "width" || name == "height" ) { - var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; - - function getWH() { - val = name == "width" ? elem.offsetWidth : elem.offsetHeight; - var padding = 0, border = 0; - jQuery.each( which, function() { - padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; - border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; - }); - val -= Math.round(padding + border); - } - - if ( jQuery(elem).is(":visible") ) - getWH(); - else - jQuery.swap( elem, props, getWH ); - - return Math.max(0, val); - } - - return jQuery.curCSS( elem, name, force ); - }, - - curCSS: function( elem, name, force ) { - var ret, style = elem.style; - - // A helper method for determining if an element's values are broken - function color( elem ) { - if ( !jQuery.browser.safari ) - return false; - - // defaultView is cached - var ret = defaultView.getComputedStyle( elem, null ); - return !ret || ret.getPropertyValue("color") == ""; - } - - // We need to handle opacity special in IE - if ( name == "opacity" && jQuery.browser.msie ) { - ret = jQuery.attr( style, "opacity" ); - - return ret == "" ? - "1" : - ret; - } - // Opera sometimes will give the wrong display answer, this fixes it, see #2037 - if ( jQuery.browser.opera && name == "display" ) { - var save = style.outline; - style.outline = "0 solid black"; - style.outline = save; - } - - // Make sure we're using the right name for getting the float value - if ( name.match( /float/i ) ) - name = styleFloat; - - if ( !force && style && style[ name ] ) - ret = style[ name ]; - - else if ( defaultView.getComputedStyle ) { - - // Only "float" is needed here - if ( name.match( /float/i ) ) - name = "float"; - - name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); - - var computedStyle = defaultView.getComputedStyle( elem, null ); - - if ( computedStyle && !color( elem ) ) - ret = computedStyle.getPropertyValue( name ); - - // If the element isn't reporting its values properly in Safari - // then some display: none elements are involved - else { - var swap = [], stack = [], a = elem, i = 0; - - // Locate all of the parent display: none elements - for ( ; a && color(a); a = a.parentNode ) - stack.unshift(a); - - // Go through and make them visible, but in reverse - // (It would be better if we knew the exact display type that they had) - for ( ; i < stack.length; i++ ) - if ( color( stack[ i ] ) ) { - swap[ i ] = stack[ i ].style.display; - stack[ i ].style.display = "block"; - } - - // Since we flip the display style, we have to handle that - // one special, otherwise get the value - ret = name == "display" && swap[ stack.length - 1 ] != null ? - "none" : - ( computedStyle && computedStyle.getPropertyValue( name ) ) || ""; - - // Finally, revert the display styles back - for ( i = 0; i < swap.length; i++ ) - if ( swap[ i ] != null ) - stack[ i ].style.display = swap[ i ]; - } - - // We should always get a number back from opacity - if ( name == "opacity" && ret == "" ) - ret = "1"; - - } else if ( elem.currentStyle ) { - var camelCase = name.replace(/\-(\w)/g, function(all, letter){ - return letter.toUpperCase(); - }); - - ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; - - // From the awesome hack by Dean Edwards - // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 - - // If we're not dealing with a regular pixel number - // but a number that has a weird ending, we need to convert it to pixels - if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { - // Remember the original values - var left = style.left, rsLeft = elem.runtimeStyle.left; - - // Put in the new values to get a computed value out - elem.runtimeStyle.left = elem.currentStyle.left; - style.left = ret || 0; - ret = style.pixelLeft + "px"; - - // Revert the changed values - style.left = left; - elem.runtimeStyle.left = rsLeft; - } - } - - return ret; - }, - - clean: function( elems, context ) { - var ret = []; - context = context || document; - // !context.createElement fails in IE with an error but returns typeof 'object' - if (typeof context.createElement == 'undefined') - context = context.ownerDocument || context[0] && context[0].ownerDocument || document; - - jQuery.each(elems, function(i, elem){ - if ( !elem ) - return; - - if ( elem.constructor == Number ) - elem += ''; - - // Convert html string into DOM nodes - if ( typeof elem == "string" ) { - // Fix "XHTML"-style tags in all browsers - elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ - return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? - all : - front + ">"; - }); - - // Trim whitespace, otherwise indexOf won't work as expected - var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div"); - - var wrap = - // option or optgroup - !tags.indexOf("", "" ] || - - !tags.indexOf("", "" ] || - - tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && - [ 1, "", "
" ] || - - !tags.indexOf("", "" ] || - - // matched above - (!tags.indexOf("", "" ] || - - !tags.indexOf("", "" ] || - - // IE can't serialize and