X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Rakka%2FStorage%2FImpl.hs;h=55bda719f5f30190bfff48d2711ef4b63afd0593;hb=45bce2c29948649f74ada71f2fa851bdb812e96c;hp=442c412fb4966f906598155227c115dec48e75e2;hpb=4abf7df08bf0a614ea8179e8d1d69a17aac4f197;p=Rakka.git diff --git a/Rakka/Storage/Impl.hs b/Rakka/Storage/Impl.hs index 442c412..55bda71 100644 --- a/Rakka/Storage/Impl.hs +++ b/Rakka/Storage/Impl.hs @@ -1,3 +1,7 @@ +{-# LANGUAGE + OverloadedStrings + , UnicodeSyntax + #-} module Rakka.Storage.Impl ( getPage' , putPage' @@ -9,24 +13,29 @@ module Rakka.Storage.Impl , putAttachment' ) where - +import Control.Applicative import Control.Concurrent import Control.Concurrent.STM +import Control.Exception import Control.Monad import Data.Maybe +import Data.Monoid.Unicode import Data.Set (Set) import qualified Data.Set as S +import Data.Text (Text) +import qualified Data.Text as T import Data.Time +import qualified Data.Time.W3C as W3C import Network.HTTP.Lucu import Network.HTTP.Lucu.Utils import Network.URI import Prelude hiding (words) +import Prelude.Unicode 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 @@ -68,9 +77,7 @@ findAllPages repos rev = do reposPages <- findAllPagesInRevision repos rev findChangedPages :: Repository -> RevNum -> RevNum -> IO (Set PageName) findChangedPages repos 0 newRev = findAllPages repos newRev findChangedPages repos oldRev newRev - = mapM (findChangedPagesAtRevision repos) [oldRev + 1 .. newRev] - >>= - return . S.unions + = liftM S.unions (mapM (findChangedPagesAtRevision repos) [oldRev + 1 .. newRev]) getDirContents' :: Repository -> PageName -> Maybe RevNum -> IO [PageName] @@ -109,7 +116,7 @@ startIndexManager :: FilePath -> Repository -> (Page -> IO Document) -> IO (TCha startIndexManager lsdir repos mkDraft = do chan <- newTChanIO index <- openIndex indexDir revFile - forkIO (loop chan index) + _ <- forkIO (loop chan index `finally` closeDatabase index) return chan where indexDir = lsdir "index" @@ -189,54 +196,51 @@ syncIndex' index revFile repos mkDraft mapM_ (updateIndex index repos mkDraft newRev) (S.toList pages) -searchIndex :: Database -> Condition -> IO SearchResult +searchIndex ∷ Database → Condition → IO SearchResult searchIndex index cond - = do (ids, hint) <- searchDatabase' index cond + = do (ids, hint) ← searchDatabase' index cond let (total, words) = parseHint hint - pages <- mapM (fromId words) ids + pages ← mapM (fromId words) ids return SearchResult { srTotal = total , srPages = pages } where - parseHint :: [(String, Int)] -> (Int, [String]) + parseHint ∷ [(Text, Int)] → (Int, [Text]) parseHint xs = let total = fromJust $ lookup "" xs - words = filter (/= "") $ map fst xs + words = filter ((¬) ∘ T.null) $ map fst xs in (total, words) - fromId :: [String] -> DocumentID -> IO HitPage + fromId ∷ [Text] → 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 + = do uri ← getDocURI index docId + rev ← unsafeInterleaveIO $ + -- FIXME: use Data.Text.Read + read ∘ T.unpack ∘ fromJust + <$> getDocAttr index docId "rakka:revision" + lastMod ← unsafeInterleaveIO $ + zonedTimeToUTC ∘ fromJust ∘ W3C.parse ∘ T.unpack ∘ 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 + pure (trim (≡ Boundary) $ map toFragment sn) + pure HitPage { + hpPageName = decodePageName $ uriPath uri + , hpPageRev = rev + , hpLastMod = lastMod + , hpSummary = summary + , hpSnippet = snippet + } + toFragment ∷ Either Text (Text, Text) -> SnippetFragment + toFragment (Left "" ) = Boundary + toFragment (Left t ) = NormalText t toFragment (Right (w, _)) = HighlightedWord w - updateIndex :: Database -> Repository -> (Page -> IO Document) @@ -252,11 +256,11 @@ updateIndex index repos mkDraft rev name case docIdM of Nothing -> return () Just docId -> do removeDocument index docId [CleaningRemove] - infoM logger ("Removed page " ++ name ++ " from the index") + infoM logger ("Removed page " ⊕ T.unpack name ⊕ " from the index") Just page -> do draft <- mkDraft page putDocument index draft [CleaningPut] - infoM logger ("Indexed page " ++ name ++ " of revision " ++ show (pageRevision page)) + infoM logger ("Indexed page " ⊕ T.unpack name ⊕ " of revision " ⊕ show (pageRevision page)) updateIndexRev :: FilePath -> (RevNum -> IO RevNum) -> IO () @@ -267,7 +271,7 @@ updateIndexRev revFile f = withFile revFile ReadWriteMode update rev <- if eof then return 0 else - hGetLine h >>= return . read + liftM read (hGetLine h) rev' <- f rev hSeek h AbsoluteSeek 0 hSetFileSize h 0