]> gitweb @ CieloNegro.org - Rakka.git/blobdiff - Rakka/Resource/PageEntity.hs
continue working on page search
[Rakka.git] / Rakka / Resource / PageEntity.hs
index 0b5459447419ffab669650e8f08f5bd1c6abe381..1dd185f3b8d4e3269d401c412545c918897ed619 100644 (file)
@@ -10,6 +10,7 @@ import           Control.Arrow.ArrowList
 import           Control.Monad.Trans
 import           Data.Char
 import           Data.Maybe
+import           Data.Time
 import           Network.HTTP.Lucu
 import           Network.HTTP.Lucu.Utils
 import           Network.URI hiding (path)
@@ -19,8 +20,10 @@ 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.Namespace
 import           Text.XML.HXT.Arrow.WriteDocument
 import           Text.XML.HXT.Arrow.XmlArrow
@@ -76,14 +79,6 @@ handleRedirect env
     = proc redir
     -> returnA -< do mType <- getEntityType
                      case mType of
-                       MIMEType "application" "xhtml+xml" _
-                           -> do BaseURI baseURI <- getSysConf (envSysConf env)
-                                 let uri = mkPageFragmentURI
-                                           baseURI
-                                           (redirDest redir)
-                                           ("Redirect:" ++ redirName redir)
-                                 redirect Found uri
-
                        MIMEType "text" "xml" _
                            -> do setContentType mType
                                  [resultStr] <- liftIO $ runX ( setErrorMsgHandler False fail
@@ -96,24 +91,21 @@ handleRedirect env
                                                               )
                                  output resultStr
 
-                       _   -> fail ("internal error: getEntityType returned " ++ show mType)
+                       _   -> 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 -< do -- text/x-rakka の場合は、内容が動的に生成され
-                        -- てゐる可能性があるので、ETag も
-                        -- Last-Modified も返す事が出來ない。
-                        case entityType page of
-                          MIMEType "text" "x-rakka" _
-                              -> return ()
-                          _   -> case entityRevision page of
-                                   0   -> foundTimeStamp (entityLastMod page) -- 0 はデフォルトページ
-                                   rev -> foundEntity (strongETag $ show rev) (entityLastMod page)
-
-                        outputXmlPage tree (entityToXHTML env)
+          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
@@ -130,9 +122,11 @@ entityToXHTML env
           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")
+          feeds <- arrIO0 (findFeeds (envStorage env)) -< ()
+
+          pageTitle    <- listA (readSubPage env) -< (Just name, Just page, "PageTitle")
+          leftSideBar  <- listA (readSubPage env) -< (Just name, Just page, "SideBar/Left")
+          rightSideBar <- listA (readSubPage env) -< (Just name, Just page, "SideBar/Right")
           pageBody     <- listA (makeMainXHTML (envStorage env) (envSysConf env) (envInterpTable env)) -< page
 
           ( eelem "/"
@@ -156,6 +150,14 @@ entityToXHTML env
                            += sattr "type" "text/css"
                            += attr "href" (arr id >>> mkText)
                          )
+                      += ( constL feeds
+                           >>>
+                           eelem "link"
+                           += sattr "rel"   "alternate"
+                           += sattr "type"  "application/rss+xml"
+                           += attr  "title" (txt siteName <+> txt " - " <+> mkText)
+                           += attr  "href"  (arr (mkFeedURIStr baseURI) >>> mkText)
+                         )
                       += ( constL scriptSrc
                            >>>
                            eelem "script"
@@ -207,9 +209,98 @@ entityToXHTML env
                ) ) -<< 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
+            -> a (Maybe PageName, Maybe XmlTree, PageName) XmlTree
 readSubPage env
     = proc (mainPageName, mainPage, subPageName) ->
       do subPage  <- getPageA (envStorage env) >>> arr fromJust >>> xmlizePage -< (subPageName, Nothing)
@@ -238,7 +329,7 @@ handleGetPageListing env
                             )
                        )
                   ) -< (dir, items)
-          returnA -< outputXmlPage tree (pageListingToXHTML env)
+          returnA -< outputXmlPage' tree (pageListingToXHTML env) -- FIXME: rss 對應
 
 
 pageListingToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree
@@ -254,9 +345,9 @@ pageListingToXHTML env
           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")
+          pageTitle    <- listA (readSubPage env) -< (Just name, Nothing, "PageTitle")
+          leftSideBar  <- listA (readSubPage env) -< (Just name, Nothing, "SideBar/Left")
+          rightSideBar <- listA (readSubPage env) -< (Just name, Nothing, "SideBar/Right")
 
           ( eelem "/"
             += ( eelem "html"
@@ -350,7 +441,7 @@ handlePageNotFound env
                        )
                   ) -< name
           returnA -< do setStatus NotFound
-                        outputXmlPage tree (notFoundToXHTML env)
+                        outputXmlPage' tree (notFoundToXHTML env)
 
 
 notFoundToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree
@@ -366,9 +457,9 @@ notFoundToXHTML env
           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")
+          pageTitle    <- listA (readSubPage env) -< (Just name, Nothing, "PageTitle")
+          leftSideBar  <- listA (readSubPage env) -< (Just name, Nothing, "SideBar/Left")
+          rightSideBar <- listA (readSubPage env) -< (Just name, Nothing, "SideBar/Right")
 
           ( eelem "/"
             += ( eelem "html"
@@ -450,3 +541,18 @@ handleDelete env name
     = do userID <- getUserID env
          status <- deletePage (envStorage env) userID name
          setStatus status
+
+
+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 srPageName result)
+
+
+mkFeedURIStr :: URI -> PageName -> String
+mkFeedURIStr baseURI name
+    = uriToString id (mkFeedURI baseURI name) ""
\ No newline at end of file