GHC-Options:
-fwarn-unused-imports
Build-Depends:
- base, network, unix, encoding, base64-string, hxt, Lucu
+ base, network, unix, encoding, base64-string, hxt, HsSVN, Lucu
Exposed-Modules:
Rakka.Page
+ Rakka.Storage
Other-Modules:
- Rakka.Page.Loader.DefaultPage
+ Rakka.Environment
+ Rakka.Storage.DefaultPage
+ Rakka.Utils
Data-Files:
defaultPages/Main_Page
schemas/rakka-page-1.0.rng
rakka
Main-Is:
Main.hs
+Extensions:
+ Arrows
GHC-Options:
-fwarn-unused-imports
\ No newline at end of file
import Network
import qualified Network.HTTP.Lucu.Config as LC
+import Rakka.Storage
data Environment = Environment {
envLocalStateDir :: FilePath
, envLucuConf :: LC.Config
+ , envStorage :: Storage
}
= do let lucuConf = LC.defaultConfig {
LC.cnfServerPort = PortNumber portNum
}
+ storage <- mkStorage -- FIXME
return $ Environment {
envLocalStateDir = lsdir
, envLucuConf = lucuConf
+ , envStorage = storage
}
\ No newline at end of file
import Data.Encoding.UTF8
import Network.HTTP.Lucu
import Network.URI
+import Subversion.Types
type PageName = String
data Page
= Redirect PageName
| Page {
- pageType :: MIMEType
+ pageName :: PageName
+ , pageType :: MIMEType
, pageIsTheme :: Bool -- text/css 以外では無意味
, pageIsFeed :: Bool -- text/x-rakka 以外では無意味
, pageIsLocked :: Bool
, pageIsBoring :: Bool
+ , pageRevision :: Maybe RevNum
, pageSummary :: Maybe String
, pageOtherLang :: [(String, PageName)]
, pageContent :: LazyByteString
+++ /dev/null
-module Rakka.Page.Loader.DefaultPage
- ( loadDefaultPage
- )
- where
-
-import qualified Codec.Binary.Base64.String as B64
-import Control.Arrow
-import Control.Arrow.ArrowList
-import qualified Data.ByteString.Lazy.Char8 as L8
-import Paths_Rakka -- Cabal が用意する。
-import Rakka.Page
-import Rakka.Utils
-import System.Directory
-import Text.XML.HXT.Arrow.ReadDocument
-import Text.XML.HXT.Arrow.XmlArrow
-import Text.XML.HXT.Arrow.XmlIOStateArrow
-import Text.XML.HXT.Arrow.XmlNodeSet
-import Text.XML.HXT.DOM.TypeDefs
-import Text.XML.HXT.DOM.XmlKeywords
-
-
-loadDefaultPage :: PageName -> IO (Maybe Page)
-loadDefaultPage pageName
- -- ./data/Foo を探した後、Cabal で defaultPages/Foo を探す。
- = do let pagePath = encodePageName pageName
- isInDataDir <- doesFileExist ("./data/" ++ pagePath)
- if isInDataDir then
- return . Just =<< loadPageFile ("./data/" ++ pagePath)
- else
- do fpath <- getDataFileName ("defaultPages/" ++ pagePath)
- isInstalled <- doesFileExist fpath
- if isInstalled then
- return . Just =<< loadPageFile fpath
- else
- return Nothing
-
-
-loadPageFile :: FilePath -> IO Page
-loadPageFile path
- = do [page] <- runX ( constA path
- >>>
- loadPageFileA
- )
- return page
-
-
-loadPageFileA :: IOStateArrow s FilePath Page
-loadPageFileA = ( readFromDocument [ (a_validate , v_0)
- , (a_check_namespaces , v_1)
- , (a_remove_whitespace, v_1)
- ]
- >>>
- parsePage
- )
-
-
-parsePage :: (ArrowXml a, ArrowChoice a) => a XmlTree Page
-parsePage
- = proc tree -> do mimeType <- (getXPathTreesInDoc "/page/@type/text()" >>> getText
- >>> arr read) -< tree
-
- isTheme <- (maybeA (getXPathTreesInDoc "/page/@type/text()" >>> getText)
- >>> defaultTo "no"
- >>> parseYesOrNo) -< tree
- isFeed <- (maybeA (getXPathTreesInDoc "/page/@isFeed/text()" >>> getText)
- >>> defaultTo "no"
- >>> parseYesOrNo) -< tree
- isLocked <- (maybeA (getXPathTreesInDoc "/page/@isLocked/text()" >>> getText)
- >>> defaultTo "no"
- >>> parseYesOrNo) -< tree
- isBoring <- (maybeA (getXPathTreesInDoc "/page/@isBoring/text()" >>> getText)
- >>> defaultTo "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" >>> getText) -< tree
- binaryData <- maybeA (getXPathTreesInDoc "/page/binaryData" >>> getText) -< tree
-
- let content = case (textData, binaryData) of
- (Just text, _ ) -> L8.pack text
- (_ , Just binary) -> L8.pack $ B64.decode binary
-
- returnA -< Page {
- pageType = mimeType
- , pageIsTheme = isTheme
- , pageIsFeed = isFeed
- , pageIsLocked = isLocked
- , pageIsBoring = isBoring
- , pageSummary = summary
- , pageOtherLang = otherLang
- , pageContent = content
- }
\ No newline at end of file
--- /dev/null
+module Rakka.Storage
+ ( Storage
+
+ , mkStorage -- private
+
+ , getPage
+ , savePage
+ )
+ where
+
+import Rakka.Page
+import Rakka.Storage.DefaultPage
+
+
+data Storage = Storage -- FIXME
+
+
+mkStorage :: IO Storage -- FIXME
+mkStorage = return Storage
+
+
+getPage :: Storage -> PageName -> IO (Maybe Page)
+getPage sto name
+ = loadDefaultPage name -- FIXME
+
+
+savePage :: Storage -> PageName -> Page -> IO ()
+savePage sto name page
+ = error "FIXME: not implemented"
--- /dev/null
+module Rakka.Storage.DefaultPage
+ ( loadDefaultPage
+ )
+ where
+
+import qualified Codec.Binary.Base64.String as B64
+import Control.Arrow
+import Control.Arrow.ArrowList
+import qualified Data.ByteString.Lazy.Char8 as L8
+import Paths_Rakka -- Cabal が用意する。
+import Rakka.Page
+import Rakka.Utils
+import System.Directory
+import Text.XML.HXT.Arrow.ReadDocument
+import Text.XML.HXT.Arrow.XmlArrow
+import Text.XML.HXT.Arrow.XmlIOStateArrow
+import Text.XML.HXT.Arrow.XmlNodeSet
+import Text.XML.HXT.DOM.TypeDefs
+import Text.XML.HXT.DOM.XmlKeywords
+
+
+loadDefaultPage :: PageName -> IO (Maybe Page)
+loadDefaultPage pageName
+ -- ./data/Foo を探した後、Cabal で defaultPages/Foo を探す。
+ = do let pagePath = encodePageName pageName
+ isInDataDir <- doesFileExist ("./data/" ++ pagePath)
+ if isInDataDir then
+ return . Just =<< loadPageFile pageName ("./data/" ++ pagePath)
+ else
+ do fpath <- getDataFileName ("defaultPages/" ++ pagePath)
+ isInstalled <- doesFileExist fpath
+ if isInstalled then
+ return . Just =<< loadPageFile pageName fpath
+ else
+ return Nothing
+
+
+loadPageFile :: PageName -> FilePath -> IO Page
+loadPageFile name path
+ = do [page] <- runX ( 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
+ parsePage -< (name, tree)
+
+
+parsePage :: (ArrowXml a, ArrowChoice a) => a (PageName, XmlTree) Page
+parsePage
+ = proc (name, tree)
+ -> do mimeType <- (getXPathTreesInDoc "/page/@type/text()" >>> getText
+ >>> arr read) -< tree
+
+ isTheme <- (maybeA (getXPathTreesInDoc "/page/@type/text()" >>> getText)
+ >>> defaultTo "no"
+ >>> parseYesOrNo) -< tree
+ isFeed <- (maybeA (getXPathTreesInDoc "/page/@isFeed/text()" >>> getText)
+ >>> defaultTo "no"
+ >>> parseYesOrNo) -< tree
+ isLocked <- (maybeA (getXPathTreesInDoc "/page/@isLocked/text()" >>> getText)
+ >>> defaultTo "no"
+ >>> parseYesOrNo) -< tree
+ isBoring <- (maybeA (getXPathTreesInDoc "/page/@isBoring/text()" >>> getText)
+ >>> defaultTo "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" >>> getText) -< tree
+ binaryData <- maybeA (getXPathTreesInDoc "/page/binaryData" >>> getText) -< tree
+
+ let content = case (textData, binaryData) of
+ (Just text, _ ) -> L8.pack text
+ (_ , Just binary) -> L8.pack $ B64.decode binary
+
+ returnA -< Page {
+ pageName = name
+ , pageType = mimeType
+ , pageIsTheme = isTheme
+ , pageIsFeed = isFeed
+ , pageIsLocked = isLocked
+ , pageIsBoring = isBoring
+ , pageRevision = Nothing
+ , pageSummary = summary
+ , pageOtherLang = otherLang
+ , pageContent = content
+ }
\ No newline at end of file