]> gitweb @ CieloNegro.org - Rakka.git/blobdiff - Rakka/Storage/Impl.hs
HitPage should contain more info
[Rakka.git] / Rakka / Storage / Impl.hs
index fed687f3c1266e992efc7973838cf8f41ced0ffb..442c412fb4966f906598155227c115dec48e75e2 100644 (file)
@@ -16,19 +16,24 @@ 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)
 
@@ -155,6 +160,7 @@ openIndex indexDir revFile
                               $ 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
@@ -183,16 +189,52 @@ syncIndex' index revFile repos mkDraft
                mapM_ (updateIndex index repos mkDraft newRev) (S.toList pages)
 
 
-searchIndex :: Database -> Condition -> IO [(PageName, RevNum)]
+searchIndex :: Database -> Condition -> IO SearchResult
 searchIndex index cond
-    = searchDatabase index cond >>= mapM fromId
+    = do (ids, hint) <- searchDatabase' index cond
+         let (total, words) = parseHint hint
+         pages <- mapM (fromId words) ids
+         return SearchResult {
+                      srTotal = total
+                    , srPages = pages
+                    }
     where
-      fromId :: DocumentID -> IO (PageName, RevNum)
-      fromId docId
-          = do uri <- getDocURI index docId
-               rev <- getDocAttr index docId "rakka:revision"
-                      >>= return . read . fromJust
-               return (decodePageName $ uriPath uri, rev)
+      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 $
+                          getDocAttr index docId "rakka:revision"
+                          >>=
+                          return . read . fromJust
+               lastMod <- unsafeInterleaveIO $
+                          getDocAttr index docId "@mdate"
+                          >>=
+                          return . zonedTimeToUTC . fromJust . parseW3CDateTime . fromJust
+               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