Created
          July 4, 2014 21:27 
        
      - 
      
 - 
        
Save jcla1/addb4ab8a20aef2fb862 to your computer and use it in GitHub Desktop.  
Revisions
- 
        
jcla1 created this gist
Jul 4, 2014 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,94 @@ import Data.Function (on) import Data.List (sort, sortBy, groupBy, nub) import Data.List.Utils (replace) import Data.Ord (comparing) import Data.Either (rights) import Control.Monad (liftM) import System.Environment (getArgs) import Text.Parsec.Error (ParseError) import qualified Text.CSV as CSV validPrograms = ["Google Chrome", "Sublime Text 2", "iTerm", "Finder", "Activity Monitor"] -- Maximum time difference between two usages of a program, -- so that these usages would be counted in the same interval, in seconds. maxIntervalDiff = 360 -- Minimum duration of usage of a program to be accounted for in the line-up minUsage = 720 main = do activityRecords <- liftM (concatMap init . rights) getCSVs putStrLn $ processActivityRecords activityRecords getCSVs :: IO [Either ParseError CSV.CSV] getCSVs = mapM CSV.parseCSVFromFile =<< getArgs processActivityRecords :: CSV.CSV -> String processActivityRecords rs = concatRecords otherPrograms allPrograms where concatRecords = (++) `on` flip (++) "\n" . postpareCSV allPrograms = intervalsToCSV "All Programs" allProgramIntervals allProgramIntervals = timesToInterval . sort . nub $ concatMap snd programTimes otherPrograms = concatMap (uncurry intervalsToCSV) . filterPrograms $ mapTimesToInterval programTimes programTimes = cleanGroups . groupBy ((==) `on` fst) . sortBy (comparing fst) $ toProgramTime rs filterPrograms = filterMinUsage . filterValidPrograms postpareCSV :: CSV.CSV -> String postpareCSV = removeQuotes . CSV.printCSV intervalsToCSV :: String -> [(Int, Int)] -> CSV.CSV intervalsToCSV name = map (uncurry (intervalToCSV name)) intervalToCSV :: String -> Int -> Int -> CSV.Record intervalToCSV name s e = [show s, show e, show (e - s), name] mapTimesToInterval :: [(String, [Int])] -> [(String, [(Int, Int)])] mapTimesToInterval = map (\ x -> (fst x, timesToInterval $ snd x)) timesToInterval :: [Int] -> [(Int, Int)] timesToInterval (x:xs) = foldl concatIntervals [(x, x)] xs where concatIntervals (i:is) t = makeInterval i t ++ is makeInterval (start, end) t | t > end && t - end <= maxIntervalDiff = [(start, t)] | start /= end = [(t, t), (start, end)] | otherwise = [(t, t)] filterValidPrograms :: [(String, a)] -> [(String, a)] filterValidPrograms = filter (\ x -> fst x `elem` validPrograms) filterMinUsage :: [(a, [(Int, Int)])] -> [(a, [(Int, Int)])] filterMinUsage = filter (\ (_, is) -> intervalsToDuration is >= minUsage) intervalsToDuration :: [(Int, Int)] -> Int intervalsToDuration = foldl (\ acc (a, b) -> acc + b - a) 0 toProgramTime :: CSV.CSV -> [(String, Int)] toProgramTime = map (\ r -> (r !! 3, adjustTime r)) adjustTime :: CSV.Record -> Int adjustTime (t:tz:_) = (read t :: Int) + case tz of "CEST" -> 7200 "CET" -> 3600 removeQuotes :: String -> String removeQuotes = replace "\"" "" cleanGroups :: [[(a, b)]] -> [(a, [b])] cleanGroups = map (\ x -> (fst $ head x, map snd x)) This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,20 @@ 1404508051,CEST,0,Google Chrome,1,1,15,24.4 1404508067,CEST,1,iTerm,1,0,15,24.3 1404508080,CEST,0,iTerm,1,0,15,24.3 1404508095,CEST,0,iTerm,1,0,15,24.3 1404508111,CEST,0,Google Chrome,1,1,15,24.3 1404508126,CEST,0,iTerm,1,0,14,24.3 1404508140,CEST,0,iTerm,1,0,14,24.3 1404508155,CEST,0,Google Chrome,1,1,14,24.3 1404508170,CEST,0,iTerm,1,0,14,24.3 1404508186,CEST,1,iTerm,1,0,14,24.1 1404508200,CEST,0,iTerm,1,0,14,24.1 1404508216,CEST,0,iTerm,1,0,14,24.1 1404508231,CEST,0,iTerm,1,0,14,24.1 1404508247,CEST,0,iTerm,1,0,14,23.9 1404508260,CEST,0,iTerm,1,0,14,23.9 1404508275,CEST,3,iTerm,1,0,14,23.9 1404508291,CEST,0,Google Chrome,1,1,14,23.9 1404508306,CEST,0,iTerm,1,0,14,23.8 1404508320,CEST,0,iTerm,1,0,14,23.8 1404508335,CEST,0,iTerm,1,0,14,23.8