module Web.Firefox (listPlacesFiles, listHistoryURLs, listAllHistoryURLs)
where
import Database.HDBC (disconnect, fromSql, quickQuery')
import Database.HDBC.Sqlite3 (connectSqlite3, setBusyTimeout)
import Network.URL (importURL, URL)
import Data.List (isSuffixOf)
import Control.Monad (forM)
import Data.Maybe (catMaybes, mapMaybe)
import System.Directory (doesDirectoryExist, getDirectoryContents, getHomeDirectory)
import System.FilePath ((</>))
firefoxDirs = [ ".mozilla" ]
placesFile = "places.sqlite"
timeoutFox = 5
listPlacesFiles :: IO [FilePath]
listPlacesFiles = do
homeDir <- getHomeDirectory
xs <- mapM (getRecursiveContents . (homeDir </>)) firefoxDirs
return $ filter (placesFile `isSuffixOf`) (concat xs)
listAllHistoryURLs :: IO [URL]
listAllHistoryURLs = do
putStrLn $ "Please close your Firefox if you see this message longer than "++show timeoutFox++" seconds..."
places <- listPlacesFiles
xs <- mapM listHistoryURLs places
return $ concat xs
listHistoryURLs :: FilePath -> IO [URL]
listHistoryURLs name = do
putStrLn $ "Going to connect on Firefox SQLite DB: " ++ name
conn <- connectSqlite3 name
setBusyTimeout conn (1000*timeoutFox)
xs <- quickQuery' conn "select url from moz_places order by last_visit_date desc" []
let ys = map (fromSql . head) xs :: [String]
return $ mapMaybe importURL ys
getRecursiveContents :: FilePath -> IO [FilePath]
getRecursiveContents topdir = do
names <- getDirectoryContents topdir
let properNames = filter (`notElem` [".", ".."]) names
paths <- forM properNames $ \name -> do
let path = topdir </> name
isDirectory <- doesDirectoryExist path
if isDirectory
then getRecursiveContents path
else return [path]
return (concat paths)