packages feed

mahoro-0.1.2: Parsers/Thread.hs

-- | Parsers/Thread.hs
-- A module which contain functions for split thread on ports and
-- parse it all together.

module Parsers.Thread (
    ThreadSettings(..),
    parseThread,
    parsePosts
) where

import Parsers.Post

import Data.Maybe
import Text.Regex.Posix
import Text.HTML.TagSoup
import Codec.Binary.UTF8.String
import Data.List.Utils


-- | Settings for post parser.
data ThreadSettings = ThreadSettings
    { sThreadSplitter :: String
    , sAfterSplit     :: Bool
    }

-- | Post with number.
type NPost = (Integer, Post)


-- | Parse thread on main page.
parseThread :: ThreadSettings -> PostSettings -> Integer -> String -> [NPost]
parseThread tSets pSets lastPost body =
    let threads = split (sThreadSplitter tSets) body

        p [] = []
        p [number] | lastPost < number = [number]
        p _  = []

    in if length threads < 2
       then []
       else let thread = if sAfterSplit tSets
                         then head $ tail threads
                         else head threads
            in universalParser p pSets thread


-- | Parse full thread.
parsePosts :: PostSettings -> Integer -> String -> [NPost]
parsePosts pSets lastPost body =
    let p [] = []
        p numbers | lastPost == 0 = [last numbers]
        p numbers = reverse $ take 10 $ reverse $
                      dropWhile (<=lastPost) numbers

    in universalParser p pSets body


-- | Universal parser.
universalParser :: ([Integer] -> [Integer]) -> PostSettings -> String -> [NPost]
universalParser p pSets body =
    let chunks = split (sPostSplitter pSets) body
        nposts' = map (\chunk -> (parseNumber chunk, chunk)) chunks
        needed = p $ map fst nposts'

        parseNumber = read . filter (`elem` ['0'..'9']) .
                       flip (=~) (sPostNumberTag pSets)
        parseNPost (number, chunk) =
          if number `elem` needed
          then Just (number, parsePost pSets $ parseTags $ decodeString chunk)
          else Nothing
    in catMaybes $ map parseNPost nposts'