This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: export | |
version: 0.1.0.0 | |
build-type: Simple | |
cabal-version: >= 1.10 | |
executable export | |
main-is: export.hs | |
build-depends: base | |
, aeson | |
, time | |
, extra | |
, bytestring | |
, text | |
ghc-options: -threaded | |
default-language: Haskell2010 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE OverloadedStrings #-} | |
module Main where | |
import Data.Aeson | |
import Data.Time.Format.ISO8601 | |
import Control.Monad | |
import Control.Applicative | |
import Data.List.Extra (split) | |
import Data.Time.Clock (UTCTime(..)) | |
import qualified Data.ByteString.Lazy as BS | |
import qualified Data.Text as T | |
import qualified Data.Text.IO as T | |
data ActivityStreams = AS { orderedItems :: [ASItem] } | |
deriving (Show) | |
data ASItem = I | |
{ itemId :: String | |
, asObject :: ASObject | |
, published :: UTCTime | |
, to :: [String] | |
} deriving (Show) | |
data ASObject = | |
Note | |
{ url :: T.Text | |
, content :: T.Text | |
, inReplyTo :: Maybe T.Text | |
} | |
| Boost { boostUrl :: T.Text } | |
deriving (Show) | |
instance FromJSON ActivityStreams where | |
parseJSON (Object v) = AS <$> v .: "orderedItems" | |
parseJSON _ = mzero | |
instance FromJSON ASItem where | |
parseJSON (Object v) = I <$> v .: "id" <*> v .: "object" <*> v .: "published" <*> v .: "to" | |
parseJSON _ = mzero | |
instance FromJSON ASObject where | |
parseJSON (Object v) = Note <$> v .: "url" <*> v .: "content" <*> v .: "inReplyTo" | |
parseJSON (String t) = return $ Boost t | |
parseJSON _ = mzero | |
handleItem :: ASItem -> IO () | |
handleItem item = do | |
let isoDate = iso8601Show $ published item | |
packedDate = T.pack isoDate | |
fileName = concat | |
[ take 10 isoDate -- extracts the YYYY-MM-DD part | |
, "-mastodon:" | |
, (split (== '/') $ itemId item) !! 6 -- extracts the Mastodon post id | |
, ".html" | |
] | |
case asObject item of | |
Note u c r -> do | |
let (folder, replyTo) = | |
case r of | |
Just replyUrl -> ("replies/", [ "in-reply-to: " <> replyUrl ]) | |
Nothing -> ("notes/", []) | |
fullFileName = folder ++ fileName | |
putStrLn $ fullFileName | |
T.writeFile fullFileName $ T.unlines $ | |
[ "---" | |
, "title: ''" | |
, "date: " <> packedDate | |
, "mastodon-original: " <> u | |
] ++ replyTo ++ | |
[ "---" | |
, c | |
] | |
Boost u -> do | |
putStrLn $ "reposts/" ++ fileName | |
T.writeFile ("reposts/" ++ fileName) $ T.unlines | |
[ "---" | |
, "title: ''" | |
, "date: " <> packedDate | |
, "repost-of: " <> u | |
, "---" | |
] | |
main :: IO () | |
main = do | |
contents <- BS.readFile "outbox.json" | |
let maybeAS = eitherDecode contents | |
case maybeAS of | |
Right as -> do | |
putStrLn "Parsed!" | |
let public = "https://www.w3.org/ns/activitystreams#Public" | |
followers = "https://mastodon.social/users/jaklt/followers" | |
filteredItems = filter (\it -> public `elem` to it || followers `elem` to it) | |
$ orderedItems as | |
forM_ (filteredItems) handleItem | |
Left err -> putStrLn err |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment