anki-tools-0.1.0.0: src/Anki/Collection.hs
{-|
Module: Anki.Collection
Copyright: (c) 2016 Al Zohali
License: BSD3
Maintainer: Al Zohali <zohl@fmap.me>
Stability: experimental
= Description
Representation of a collection and related definitions.
-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE FlexibleInstances #-}
module Anki.Collection (
Collection(..)
, GlobalOptions(..)
, Tag(..)
) where
import Anki.Common (ModificationTime, AnkiException(..), throwErr)
import Anki.Common (dropPrefixOptions, getTextValue, getJsonValue, fromDictionary)
import Anki.Deck (DeckId, Deck, DeckOptions)
import Anki.Model (ModelId, Model)
import Data.Aeson (Value(..), decode, FromJSON(..), genericParseJSON)
import Data.Text (Text)
import Database.SQLite.Simple (FromRow(..), field)
import Database.SQLite.Simple.FromField (FromField(..))
import Database.SQLite.Simple.Internal (Field(..))
import Database.SQLite.Simple.Ok (Ok(..))
import GHC.Generics (Generic)
import qualified Data.Text as T
-- | Collection as in col table.
data Collection = Collection {
collectionId :: Int -- ^ collection identifier (id)
, collectionCrt :: Int -- TODO check type
, collectionMod :: ModificationTime
, collectionScm :: Int -- TODO check type
, collectionVer :: Int -- TODO check type
, collectionDty :: Int -- TODO check type
, collectionUsn :: Int -- TODO check type
, collectionLs :: Int -- TODO check type
, collectionGlobalOptions :: GlobalOptions -- ^ global options (col.conf)
, collectionModels :: [Model] -- ^ models in the collection(col.models)
, collectionDecks :: [Deck] -- ^ decks in the collection (col.decks)
, collectionDeckOptions :: [DeckOptions] -- ^ deck options (col.dconf)
, collectionTags :: [Tag] -- ^ tags (col.tags)
} deriving (Show, Eq, Generic)
instance FromRow Collection where
fromRow = Collection
<$> field
<*> field
<*> field
<*> field
<*> field
<*> field
<*> field
<*> field
<*> field
<*> field
<*> field
<*> field
<*> field
-- | Global opitions.
data GlobalOptions = GlobalOptions {
goNextPos :: Value -- TODO Int?
, goEstTimes :: Value -- TODO Bool?
, goSortBackwards :: Value -- TODO Bool?
, goSortType :: Value -- TODO String?
, goTimeLim :: Value -- TODO Int?
, goActiveDecks :: [DeckId] -- ^ TODO
, goAddToCur :: Value -- TODO Bool?
, goCurDeck :: Value -- TODO DeckId?
, goCurModel :: ModelId -- ^ TODO
, goLastUnburied :: Value -- TODO Int?
, goCollapseTime :: Value -- TODO Int?
, goActiveCols :: Value -- TODO [String]?
, goSavedFilters :: Value -- TODO [wtf]?
, goDueCounts :: Value -- TODO Bool?
, goNewBury :: Value -- TODO Bool?
, goNewSpread :: Value -- TODO Int?
} deriving (Show, Eq, Generic)
instance FromJSON GlobalOptions where
parseJSON = genericParseJSON dropPrefixOptions
instance FromField GlobalOptions where
fromField f = getTextValue f >>= maybe (throwErr f WrongJsonFormat) return . decode
-- | Tags from col.tags.
data Tag = Tag {
tagName :: String -- ^ tag name (key)
, tagNumber :: Int -- ^ TODO: wtf? (value)
} deriving (Show, Eq)
instance FromField [Tag] where
fromField f = getJsonValue f >>= fromDictionary mkTag f where
mkTag :: Field -> (Text, Value) -> Ok Tag
mkTag f' = \case
(name, Number number) -> return $ Tag (T.unpack name) (round number)
_ -> throwErr f' WrongJsonFormat