<commit_before>{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wall #-}

module Strava where

import Control.Monad
import Control.Monad.IO.Class (liftIO)
import Data.Time
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH
import qualified Data.Text as T
import qualified Strive as S

import Config

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase|
    Bike
        name T.Text
        stravaId T.Text
        StravaId stravaId
        deriving Eq Show

    Component
        uniqueId T.Text
        UniqueId uniqueId
        name T.Text
        initialMeters Int
        initialSeconds Int
        deriving Eq Show
|]

deriving instance Eq (Unique Bike)

testClient :: IO S.Client
testClient = S.buildClient (Just $ T.pack token)

sync :: S.Client -> IO ()
sync client = do
    Right athlete <- S.getCurrentAthlete client
    let athleteId = S.id `S.get` athlete :: Integer
        athleteBikes = S.bikes `S.get` athlete
        fileName = "athlete_" ++ show athleteId ++ ".sqlite"
    print fileName
    runSqlite (T.pack fileName) $ do
        runMigration migrateAll
        syncBikes athleteBikes
        syncActivities client

syncBikes :: [S.GearSummary] -> SqlPersistM ()
syncBikes bikes = do
    forM_ bikes $ \bike -> do
        let bId = S.id `S.get` bike
            bName = S.name `S.get` bike
            bRec = Bike bId bName
        insertBy bRec >>= \case
            Left dup -> do
                when (entityVal dup /= bRec) $ do
                    Nothing <- replaceUnique (entityKey dup) bRec
                    -- TODO: mark as changed
                    return ()
            Right _key ->
                -- TODO: mark as added
                return ()
    -- TODO: delete removed bikes

syncActivities :: S.Client -> SqlPersistM ()
syncActivities client = do
    getRes <- liftIO $ S.getCurrentActivities client $ S.with
        [ S.set S.after (Just (UTCTime (fromGregorian 1970 0 0) 0))
        , S.set S.perPage 201
        ]
        {-[ S.set S.before (Just (UTCTime (fromGregorian 1970 0 0) 0))
        , S.set S.after (Just (UTCTime (fromGregorian 1970 0 0) 0))
        , S.set S.page 1
        , S.set S.perPage 2
        ]-}
    case getRes of
        Right currentActivities ->
            liftIO $ print $ length currentActivities
        Left err ->
            liftIO $ print err<commit_msg>Generalize upsert<commit_after>{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wall #-}

module Strava where

import Control.Monad
import Control.Monad.IO.Class (liftIO)
import Data.Time
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH
import qualified Data.Text as T
import qualified Strive as S

import Config

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase|
    Bike
        name T.Text
        stravaId T.Text
        StravaId stravaId
        deriving Eq Show

    Component
        uniqueId T.Text
        UniqueId uniqueId
        name T.Text
        initialMeters Int
        initialSeconds Int
        deriving Eq Show
|]

deriving instance Eq (Unique Bike)

testClient :: IO S.Client
testClient = S.buildClient (Just $ T.pack token)

sync :: S.Client -> IO ()
sync client = do
    Right athlete <- S.getCurrentAthlete client
    let athleteId = S.id `S.get` athlete :: Integer
        athleteBikes = S.bikes `S.get` athlete
        fileName = "athlete_" ++ show athleteId ++ ".sqlite"
    print fileName
    runSqlite (T.pack fileName) $ do
        runMigration migrateAll
        syncBikes athleteBikes
        syncActivities client

syncBikes :: [S.GearSummary] -> SqlPersistM ()
syncBikes bikes = do
    forM_ bikes $ \bike -> do
        let bId = S.id `S.get` bike
            bName = S.name `S.get` bike
        uprepsert $ Bike bId bName
    -- TODO: delete removed bikes

uprepsert :: (Eq rec, Eq (Unique rec),
           PersistEntity rec, PersistEntityBackend rec ~ SqlBackend)
          => rec -> SqlPersistM ()
uprepsert rec =
    insertBy rec >>= \case
        Left dup -> do
            when (entityVal dup /= rec) $ do
                Nothing <- replaceUnique (entityKey dup) rec
                -- TODO: mark as changed
                return ()
        Right _key ->
            -- TODO: mark as added
            return ()

syncActivities :: S.Client -> SqlPersistM ()
syncActivities client = do
    getRes <- liftIO $ S.getCurrentActivities client $ S.with
        [ S.set S.after (Just (UTCTime (fromGregorian 1970 0 0) 0))
        , S.set S.perPage 201
        ]
        {-[ S.set S.before (Just (UTCTime (fromGregorian 1970 0 0) 0))
        , S.set S.after (Just (UTCTime (fromGregorian 1970 0 0) 0))
        , S.set S.page 1
        , S.set S.perPage 2
        ]-}
    case getRes of
        Right currentActivities ->
            liftIO $ print $ length currentActivities
        Left err ->
            liftIO $ print err
{'fraction_non_alphanumeric': 0.09787778997438712, 'fraction_numerical': 0.00951335528723015, 'mean_word_length': 2.1784883720930233, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '53299', 'n_tokens_mistral': 1821, 'n_tokens_neox': 1723, 'n_words': 507}