aboutsummaryrefslogtreecommitdiff
path: root/src/Main.hs~
diff options
context:
space:
mode:
Diffstat (limited to 'src/Main.hs~')
-rw-r--r--src/Main.hs~127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/Main.hs~ b/src/Main.hs~
new file mode 100644
index 0000000..81ef417
--- /dev/null
+++ b/src/Main.hs~
@@ -0,0 +1,127 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+import Data.UUID.V4
+import System.Directory
+import Control.Monad.Extra
+import Data.UUID
+import Data.Char
+import Data.Generics
+import Data.Maybe
+import Data.Text (Text)
+import qualified Data.Text as T
+import Text.Feed.Import
+import Text.Feed.Query
+import Text.Feed.Types
+import Text.RSS.Syntax hiding (RSSItem)
+import Data.XML.Types
+import Data.Time
+import System.Posix.Process
+import System.Posix.Files
+import Network.HostName
+import System.Random
+import System.FilePath
+
+data FeedMetadata = FeedMetadata
+ { title :: Text,
+ author :: Maybe Text,
+ home :: Maybe Text
+ }
+ deriving (Show)
+
+data Message = Message
+ { from :: Text,
+ subject :: Text,
+ date :: Text,
+ messageId :: Text,
+ body :: Text
+-- newsGroup :: Text
+ }
+ deriving (Show)
+
+formatMessage :: Message -> Text
+formatMessage (Message from subject date messageId body) =
+ "MIME-Version: 1.0\n" <> "Date: " <> date <> "\nSubject: " <> subject <>
+ "\nFrom: " <> from <> "\nMessage-ID: " <> messageId <>
+ "\nContent-Type: text/html" <> "\n\n" <> body
+
+getItemAuthor' :: Item -> Maybe Text
+getItemAuthor' item = case getItemAuthor item of
+ Just "" -> Nothing
+ Just author -> Just author
+ Nothing -> Nothing
+
+getItemContent' :: Item -> Maybe Text
+getItemContent' (RSSItem item) =
+ (fmap (T.concat . elementText) . listToMaybe .
+ filter (\e -> namePrefix (elementName e) == Just "content"))
+ $ rssItemOther item
+getItemContent' _ = Nothing
+
+toMessage :: FeedMetadata -> Item -> IO Message
+toMessage (FeedMetadata title author home) item = do
+ messageId <- genMessageId (fromMaybe "" home) (snd <$> getItemId item)
+ return $ Message
+ (fromMaybe title $ orElse (getItemAuthor' item) author)
+ (fromMaybe "Untitled" $ getItemTitle item)
+ (fromMaybe "" $ getItemDate item) -- default should be current date
+ messageId
+ (formatBody (getItemLink item) $
+ (getItemContent item) `orElse` (getItemContent' item) `orElse`
+ (getItemDescription item))
+-- title
+
+formatBody :: Maybe Text -> Maybe Text -> Text
+formatBody link desc =
+ let linkText = case link of
+ Nothing -> ""
+ Just link' -> "Link: " <> link' <> "\n\n" in
+ linkText <> (fromMaybe "" desc)
+
+toFeedMetadata :: Feed -> FeedMetadata
+toFeedMetadata feed =
+ FeedMetadata (getFeedTitle feed) (getFeedAuthor feed) (getFeedHome feed)
+
+genFilename :: FilePath -> IO String
+genFilename root = do
+ epoch <- formatTime defaultTimeLocale "%s" <$> getCurrentTime
+ pid <- getProcessID
+ host <- getHostName
+ rand <- randomRIO (10000, 99999) :: IO Int
+ return $ root </> "new" </> epoch <> "." <> show pid <> "." <>
+ host <> "." <> show rand
+
+genUniqFilename :: FilePath -> IO String
+genUniqFilename root = do
+ filename <- genFilename root
+ exists <- fileExist filename
+ if exists then genUniqFilename root else return filename
+
+hyphenateNonAlNum :: Char -> Char
+hyphenateNonAlNum c
+ | isAlphaNum c = c
+ | otherwise = '-'
+
+genMessageId :: Text -> Maybe Text -> IO Text
+genMessageId feedLink guid = do
+ id <- case guid of
+ Just guid' -> return $ T.map hyphenateNonAlNum guid'
+ Nothing -> toText <$> nextRandom
+ return $
+ "<" <> id <> "@" <> (T.map hyphenateNonAlNum feedLink) <> ".gnu" <> ">"
+
+writeMessage :: FilePath -> Message -> IO ()
+writeMessage root msg =
+ genUniqFilename root >>=
+ \filename -> writeFile filename $ T.unpack (formatMessage msg)
+
+main :: IO ()
+main = do
+ feed <- parseFeedFromFile "./stallman.xml"
+ let root = "./maildir"
+ mapM_ (createDirectoryIfMissing True)
+ [root </> "new", root </> "cur", root </> "tmp"]
+ whenJust feed $
+ \feed' ->
+ mapM_ (\msg ->
+ writeMessage root =<< toMessage (toFeedMetadata feed') msg)
+ (getFeedItems feed')