-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathTypes.hs
More file actions
173 lines (140 loc) · 6.06 KB
/
Types.hs
File metadata and controls
173 lines (140 loc) · 6.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ImpredicativeTypes #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Web.Offset.Types where
import Control.Exception (Exception (..))
import Control.Lens hiding (children)
import Control.Monad (mzero)
import Control.Monad.State
import Data.Aeson (FromJSON, Value (..), parseJSON, (.:))
import qualified Data.HashMap.Strict as M
import Data.IntSet (IntSet)
import Data.List (intercalate)
import Data.Maybe (catMaybes, isJust)
import Data.Monoid ((<>))
import Data.Set (Set)
import Data.Text (Text)
import qualified Data.Text as T
import Data.Typeable (Typeable (..))
import Web.Offset.Cache.Types
import Web.Offset.Field
import Web.Offset.HTTP
import Web.Offset.Utils
data Wordpress b =
Wordpress { requestPostSet :: Maybe IntSet
, wpExpireAggregates :: IO Bool
, wpExpirePost :: WPKey -> IO Bool
, cachingGet :: WPKey -> IO Text
, cachingGetRetry :: WPKey -> IO Text
, cachingGetError :: WPKey -> IO (Either StatusCode Text)
, wpLogger :: Text -> IO ()
, cacheInternals :: WordpressInt (StateT b IO Text)
}
type WPLens b s = Lens' s (Wordpress b)
type UserPassword = (Text, Text)
data WordpressConfig m =
WordpressConfig { wpConfEndpoint :: Text
, wpConfRequester :: Either UserPassword Requester
, wpConfCacheBehavior :: CacheBehavior
, wpConfExtraFields :: [Field m]
, wpConfLogger :: Maybe (Text -> IO ())
}
data WordpressInt b =
WordpressInt { wpCacheGet :: WPKey -> IO (Maybe Text)
, wpCacheSet :: WPKey -> Text -> IO ()
, startReqMutex :: WPKey -> IO Bool
, wpRequest :: WPKey -> IO Text
, stopReqMutex :: WPKey -> IO ()
, runRedis :: RunRedis
}
data TaxSpec = TaxPlus Text | TaxMinus Text deriving (Eq, Ord)
data TaxSpecId = TaxPlusId Int | TaxMinusId Int deriving (Eq, Show, Ord)
data CatType
data TagType
type CustomType = Text
instance Show TaxSpec where
show (TaxPlus t) = '+' : T.unpack t
show (TaxMinus t) = '-' : T.unpack t
newtype TaxRes = TaxRes (Int, Text) deriving (Show)
instance FromJSON TaxRes where
parseJSON (Object o) = TaxRes <$> ((,) <$> o .: "id" <*> o .: "slug")
parseJSON _ = mzero
data TaxDict = TaxDict { dict :: [TaxRes]
, desc :: Text} deriving (Show)
type Year = Text
type Month = Text
type Slug = Text
type TaxonomyName = Text
data Filter = TaxFilter TaxonomyName TaxSpecId
| NumFilter Int
| OffsetFilter Int
| UserFilter Text
deriving (Eq, Ord)
instance Show Filter where
show (TaxFilter n t) = show n ++ "_" ++ show t
show (NumFilter n) = "num_" ++ show n
show (OffsetFilter n) = "offset_" ++ show n
show (UserFilter u) = T.unpack $ "user_" <> u
data WPKey = PostKey Int
| PostByPermalinkKey Year Month Slug
| PostsKey (Set Filter)
| PageKey Text
| AuthorKey Int
| TaxDictKey Text
| TaxSlugKey TaxonomyName Slug
| EndpointKey Text
deriving (Eq, Show, Ord)
tagChars :: String
tagChars = ['a'..'z'] ++ "-" ++ digitChars
digitChars :: String
digitChars = ['0'..'9']
instance Read TaxSpec where
readsPrec _ ('+':cs) | not (null cs) && all (`elem` tagChars) cs = [(TaxPlus (T.pack cs), "")]
readsPrec _ ('-':cs) | not (null cs) && all (`elem` tagChars) cs = [(TaxMinus (T.pack cs), "")]
readsPrec _ cs | not (null cs) && all (`elem` tagChars) cs = [(TaxPlus (T.pack cs), "")]
readsPrec _ _ = []
instance Read TaxSpecId where
readsPrec _ ('+':cs) | not (null cs) && all (`elem` digitChars) cs = [(TaxPlusId (read cs), "")]
readsPrec _ ('-':cs) | not (null cs) && all (`elem` digitChars) cs = [(TaxMinusId (read cs), "")]
readsPrec _ cs | not (null cs) && all (`elem` digitChars) cs = [(TaxPlusId (read cs), "")]
readsPrec _ _ = []
data TaxSpecList = TaxSpecList { taxName :: TaxonomyName
, taxList :: [TaxSpec]} deriving (Eq, Ord)
instance Show TaxSpecList where
show (TaxSpecList n ts) = T.unpack n ++ ": " ++ intercalate "," (map show ts)
attrToTaxSpecList :: (Text, Text) -> TaxSpecList
attrToTaxSpecList (k, ts) =
let vs = map readSafe $ T.splitOn "," ts in
if all isJust vs
then TaxSpecList k (catMaybes vs)
else TaxSpecList k []
data WPQuery = WPPostsQuery{ qlimit :: Int
, qnum :: Int
, qoffset :: Int
, qpage :: Int
, qtaxes :: [TaxSpecList]
, quser :: Maybe Text
} deriving (Show)
type StatusCode = Int
data CacheResult a = Successful a -- cache worked as expected
| Retry -- cache didn't work, but keep trying
| Abort StatusCode -- we got a 404 or something, no need to retry
deriving (Show, Functor)
data OffsetException = OtherException Text
| NotAnObject
deriving (Show, Typeable)
instance Exception OffsetException
newtype CacheInProgress = CacheInProgress ()
deriving (Show, Typeable)
instance Exception CacheInProgress
newtype StatusCodeException = StatusCodeException { code :: StatusCode }
deriving (Show, Typeable)
instance Exception StatusCodeException