import Network.HTTP import Directory import qualified Data.Map as M import Data.List (sortBy) import Control.Monad import Control.Applicative import System.Environment import IO (isreading, readby) = (">", "<") get_friends_resp user = do let fname = "friends_" ++ user ++ ".txt" cached <- doesFileExist fname if cached then readFile fname else do body <- simpleHTTP (getRequest $ "http://www.livejournal.com/misc/fdata.bml?user="++user) >>= getResponseBody writeFile fname body return body get_friends user marker = map (drop 2) . filter ((== marker) . take 1) . lines <$> get_friends_resp user process_friend n marker (mp, k) user = do putStr $ "\r" ++ (show k) ++ "/" ++ (show n) hFlush stdout readers <- get_friends user marker return $ (foldl (\m u -> M.insertWith (+) u 1 m) mp readers, k+1) collect friends marker = do (m,_) <- foldM (process_friend (length friends) marker) (M.empty, 1) friends let lst = filter (\(u,k) -> k > 1) $ M.toList m return $ map (\(u,k) -> (u,k, elem u friends)) $ sortBy (\(_,k1) (_,k2) -> compare k2 k1) lst mkline include_friends (u,k,f) = let line = (show k) ++ " " ++ u ++ " " in if include_friends then line ++ (if f then "*" else "") ++ "
\n" else if f then "" else line ++ "
\n" get_cothinkers username = do friends <- get_friends username isreading cothinkers <- concat . map (mkline False) <$> collect friends readby influencers <- concat . map (mkline True) <$> collect friends isreading let answer = "

Cothinkers

" ++ "who read your friends

" ++ cothinkers ++ "

Influencers

who your friends read

" ++ influencers ++ "

" writeFile "cothinkers.html" answer putStrLn "\ndone!\n" main = do args <- getArgs case args of [] -> putStrLn "usage: cothinkers username" username : _ -> get_cothinkers username