1 {-# LANGUAGE FlexibleInstances #-}
3 {-# LANGUAGE QuasiQuotes #-}
4 {-# LANGUAGE RecordWildCards #-}
5 {-# LANGUAGE TemplateHaskell #-}
6 {-# LANGUAGE TypeFamilies #-}
8 module TSN.XML.EarlyLine (
11 -- * WARNING: these are private but exported to silence warnings
12 EarlyLineConstructor(..),
13 EarlyLineGameConstructor(..) )
17 import Data.Time ( UTCTime(..) )
18 import Data.Tuple.Curry ( uncurryN )
19 import Database.Groundhog.Core ( DefaultKey )
20 import Database.Groundhog.TH (
23 import Text.XML.HXT.Core (
37 import TSN.Codegen ( tsn_codegen_config )
38 import TSN.DbImport ( DbImport(..) )
39 import TSN.Picklers ( xp_time_stamp )
40 import TSN.XmlImport ( XmlImport(..) )
46 -- | The DTD to which this module corresponds. Used to invoke dbimport.
49 dtd = "earlylineXML.dtd"
55 -- * EarlyLine/Message
57 -- | Database representation of a 'Message'. It lacks the \<date\>
58 -- elements since they're really properties of the games that they
63 db_xml_file_id :: Int,
65 db_category :: String,
68 db_time_stamp :: UTCTime }
73 -- | XML Representation of an 'EarlyLine'. It has the same
74 -- fields, but in addition contains the 'xml_dates'.
78 xml_xml_file_id :: Int,
79 xml_heading :: String,
80 xml_category :: String,
83 xml_dates :: [EarlyLineDateXml],
84 xml_time_stamp :: UTCTime }
88 instance ToDb Message where
89 -- | The database analogue of a 'Message' is an 'EarlyLine'.
91 type Db Message = EarlyLine
94 -- | The 'FromXml' instance for 'Message' is required for the
95 -- 'XmlImport' instance.
97 instance FromXml Message where
98 -- | To convert a 'Message' to an 'EarlyLine', we just drop
101 from_xml Message{..} =
103 db_xml_file_id = xml_xml_file_id,
104 db_heading = xml_heading,
105 db_category = xml_category,
106 db_sport = xml_sport,
107 db_title = xml_title,
108 db_time_stamp = xml_time_stamp }
111 -- | This allows us to insert the XML representation 'Message'
114 instance XmlImport Message
118 -- * EarlyLineDateXml
120 -- | XML representation of a \<date\>. It has a \"value\" attribute
121 -- containing the actual date string. As children it contains a
122 -- (non-optional) note, and a game. The note and date value are
123 -- properties of the game as far as I can tell.
125 data EarlyLineDateXml =
127 xml_date_value :: UTCTime,
129 xml_game :: EarlyLineGameXml }
134 -- * EarlyLineGame / EarlyLineGameXml
138 db_early_lines_id :: DefaultKey EarlyLine,
139 db_game_time :: UTCTime, -- ^ Combined date/time
140 db_note :: String, -- ^ Taken from the parent \<date\>
141 db_away_team :: EarlyLineGameTeam,
142 db_home_team :: EarlyLineGameTeam,
143 db_over_under :: String }
145 data EarlyLineGameXml =
147 xml_game_time :: UTCTime, -- ^ Only an ambiguous time string, e.g. \"8:30\"
148 xml_away_team :: EarlyLineGameTeam,
149 xml_home_team :: EarlyLineGameTeam,
150 xml_over_under :: String }
154 -- | XML representation of an earlyline team. It doubles as an
155 -- embedded type within the DB representation 'EarlyLineGame'.
157 data EarlyLineGameTeam =
159 db_rotation_number :: Int,
160 db_line :: Maybe String, -- ^ Can be blank, a Double, or \"off\".
161 db_team_name :: String }
169 instance DbImport Message where
170 dbmigrate = undefined
174 mkPersist tsn_codegen_config [groundhog|
181 - name: unique_early_lines
183 # Prevent multiple imports of the same message.
184 fields: [db_xml_file_id]
187 - entity: EarlyLineGame
188 dbName: early_lines_games
190 - name: EarlyLineGame
192 - name: db_early_lines_id
197 - {name: rotation_number, dbName: away_team_rotation_number}
198 - {name: line, dbName: away_team_line}
199 - {name: team_name, dbName: away_team_name}
202 - {name: rotation_number, dbName: home_team_rotation_number}
203 - {name: line, dbName: home_team_line}
204 - {name: team_name, dbName: home_team_name}
206 - embedded: EarlyLineGameTeam
208 - name: db_rotation_number
209 dbName: rotation_number
222 pickle_message :: PU Message
225 xpWrap (from_tuple, to_tuple) $
226 xp7Tuple (xpElem "XML_File_ID" xpInt)
227 (xpElem "heading" xpText)
228 (xpElem "category" xpText)
229 (xpElem "sport" xpText)
230 (xpElem "title" xpText)
232 (xpElem "time_stamp" xp_time_stamp)
234 from_tuple = uncurryN Message
235 to_tuple m = (xml_xml_file_id m,
243 pickle_date :: PU EarlyLineDateXml
246 xpWrap (from_tuple, to_tuple) $
247 xpTriple (xpAttr "value" undefined)
248 (xpElem "note" xpText)
251 from_tuple = uncurryN EarlyLineDateXml
252 to_tuple m = (xml_date_value m, xml_note m, xml_game m)
255 pickle_game :: PU EarlyLineGameXml
258 xpWrap (from_tuple, to_tuple) $
259 xp4Tuple (xpElem "time" undefined)
262 (xpElem "over_under" xpText)
264 from_tuple = uncurryN EarlyLineGameXml
265 to_tuple m = (xml_game_time m,
272 pickle_away_team :: PU EarlyLineGameTeam
273 pickle_away_team = xpElem "teamA" $ pickle_team
275 pickle_home_team :: PU EarlyLineGameTeam
276 pickle_home_team = xpElem "teamH" $ pickle_team
278 pickle_team :: PU EarlyLineGameTeam
280 xpWrap (from_tuple, to_tuple) $
281 xpTriple (xpAttr "rotation" xpInt)
282 (xpAttr "line" (xpOption xpText))
285 from_tuple = uncurryN EarlyLineGameTeam
286 to_tuple m = (db_rotation_number m, db_line m, db_team_name m)