X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Rakka%2FStorage%2FImpl.hs;h=c9c2de2858320725b75c30396e54e179bcc6b3da;hb=b4c0033f297c28d95ad9298b489126331224bc42;hp=d6d53a4f517d8fdae02fe2deec3e8e5c8b7467cb;hpb=9f49e3384f1925d295355e5f60e94a8ca95039ea;p=Rakka.git diff --git a/Rakka/Storage/Impl.hs b/Rakka/Storage/Impl.hs index d6d53a4..c9c2de2 100644 --- a/Rakka/Storage/Impl.hs +++ b/Rakka/Storage/Impl.hs @@ -2,7 +2,11 @@ module Rakka.Storage.Impl ( getPage' , putPage' , deletePage' + , getDirContents' , startIndexManager + + , getAttachment' + , putAttachment' ) where @@ -13,7 +17,10 @@ import Data.Maybe import Data.Set (Set) import qualified Data.Set as S 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 @@ -24,6 +31,7 @@ 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) @@ -40,11 +48,11 @@ getPage' repos name rev p -> return p -putPage' :: Repository -> Page -> IO StatusCode +putPage' :: Repository -> Maybe String -> Page -> IO StatusCode putPage' = putPageIntoRepository -deletePage' :: Repository -> PageName -> IO StatusCode +deletePage' :: Repository -> Maybe String -> PageName -> IO StatusCode deletePage' = deletePageFromRepository @@ -63,11 +71,38 @@ findChangedPages repos oldRev newRev return . S.unions +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 @@ -123,8 +158,11 @@ openIndex indexDir revFile $ removeFile revFile Right index <- openDatabase indexDir (Writer [Create []]) + 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 @@ -148,16 +186,42 @@ 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 <- getDocAttr index docId "rakka:revision" + >>= return . read . fromJust + 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 + , hpSnippet = snippet + } + + toFragment :: Either String (String, String) -> SnippetFragment + toFragment (Left "") = Boundary + toFragment (Left t) = NormalText t + toFragment (Right (w, _)) = HighlightedWord w updateIndex :: Database