]> gitweb.michael.orlitzky.com - dead/htsn-import.git/commitdiff
Add support for the missing [AH]Starter elements in Odds.
authorMichael Orlitzky <michael@orlitzky.com>
Tue, 15 Jul 2014 21:20:16 +0000 (17:20 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Tue, 15 Jul 2014 21:20:16 +0000 (17:20 -0400)
Add a test for the missing [AH]Starter elements in Odds.
Remove the man page note about the (now supported) [AH]Starter elements.

doc/man1/htsn-import.1
src/TSN/XML/Odds.hs
test/shell/import-duplicates.test
test/xml/Odds_XML-missing-starters.xml [new file with mode: 0644]

index f36327c032532e08aee29c8869b2d74df5838aec..616f7e85b82850366a2f6081cb879b51698b5ee3 100644 (file)
@@ -294,18 +294,6 @@ this leads to ambiguity in parsing. We therefore ignore the notes
 entirely (although a hack is employed to facilitate parsing). The same
 thing goes for the newer <League_Name> element.
 
-We've also seen XML on the feed where the home/away starter elements
-exist and have ID attributes but no content. For example,
-
-.nf
-<AStarter ID=\(dq0\(dq></AStarter>
-<HStarter ID=\(dq0\(dq></HStarter>
-.fi
-
-We don't handle this at the moment, but since the starter id/name are
-already optional (we just expect them to be present or missing as a
-pair), it wouldn't be too hard to support.
-
 .IP \[bu]
 \fIweatherxml.dtd\fR
 
index 5174ddb927462266e80af42eb45171bb49975f41..e2ef142b45b272d81ad3dec7b3beda312abb9554 100644 (file)
@@ -147,16 +147,25 @@ instance FromXml OddsGameCasinoXml where
 instance XmlImport OddsGameCasinoXml
 
 
--- * OddsGameTeamXml
+-- * OddsGameTeamXml / OddsGameTeamStarterXml
+
+-- | The XML representation of a \"starter\". It contains both an ID
+--   and a name. The ID does not appear to be optional, but the name
+--   can be absent. When the name is absent, the ID has always been
+--   set to \"0\". This occurs even though the entire starter element
+--   is optional (see 'OddsGameTeamXml' below).
+--
+data OddsGameTeamStarterXml =
+  OddsGameTeamStarterXml {
+    xml_starter_id :: Int,
+    xml_starter_name :: Maybe String }
+  deriving (Eq, Show)
+
 
 -- | The XML representation of a \<HomeTeam\> or \<AwayTeam\>, as
 --   found in \<Game\>s. We can't use the 'Team' representation
 --   directly because there are some other fields we need to parse.
 --
---   The starter id/name could perhaps be combined into an embedded
---   type, but can you make an entire embedded type optional with
---   Maybe? I doubt it works.
---
 data OddsGameTeamXml =
   OddsGameTeamXml {
     xml_team_id         :: String, -- ^ The home/away team IDs
@@ -170,7 +179,7 @@ data OddsGameTeamXml =
     xml_team_rotation_number :: Maybe Int,
     xml_team_abbr            :: String,
     xml_team_name            :: String,
-    xml_team_starter         :: Maybe (Int, String), -- ^ (id, name)
+    xml_team_starter         :: Maybe OddsGameTeamStarterXml,
     xml_team_casinos         :: [OddsGameCasinoXml] }
   deriving (Eq, Show)
 
@@ -309,16 +318,20 @@ instance FromXmlFkTeams OddsGameXml where
         (xml_team_rotation_number xml_home_team),
 
       db_away_team_starter_id =
-        (fst <$> xml_team_starter xml_away_team),
+        (xml_starter_id <$> xml_team_starter xml_away_team),
 
-      db_away_team_starter_name =
-        (snd <$> xml_team_starter xml_away_team),
+      -- Sometimes the starter element is present but the name isn't,
+      -- so we combine the two maybes with join.
+      db_away_team_starter_name = join
+        (xml_starter_name <$> xml_team_starter xml_away_team),
 
       db_home_team_starter_id =
-        (fst <$> xml_team_starter xml_home_team),
+        (xml_starter_id <$> xml_team_starter xml_home_team),
 
-      db_home_team_starter_name =
-        (snd <$> xml_team_starter xml_home_team) }
+      -- Sometimes the starter element is present but the name isn't,
+      -- so we combine the two maybes with join.
+      db_home_team_starter_name = join
+        (xml_starter_name <$> xml_team_starter xml_home_team) }
 
 
 -- | This lets us insert the XML representation 'OddsGameXml' directly.
@@ -582,9 +595,7 @@ pickle_home_team =
         (xpElem "HomeRotationNumber" (xpOption xpInt))
         (xpElem "HomeAbbr" xpText)
         (xpElem "HomeTeamName" xpText)
-        (-- This is an ugly way to get both the HStarter ID attribute
-         -- and contents.
-         xpOption (xpElem "HStarter" $ xpPair (xpAttr "ID" xpInt) xpText))
+        (xpOption pickle_home_starter)
         (xpList pickle_casino)
   where
     from_tuple = uncurryN OddsGameTeamXml
@@ -597,6 +608,32 @@ pickle_home_team =
                                     xml_team_starter,
                                     xml_team_casinos)
 
+
+-- | Portion of the 'OddsGameTeamStarterXml' pickler that is not
+--   specific to the home/away teams.
+--
+pickle_starter :: PU OddsGameTeamStarterXml
+pickle_starter =
+  xpWrap (from_tuple, to_tuple) $
+    xpPair (xpAttr "ID" xpInt) (xpOption xpText)
+  where
+    from_tuple = uncurry OddsGameTeamStarterXml
+    to_tuple OddsGameTeamStarterXml{..} = (xml_starter_id,
+                                           xml_starter_name)
+
+-- | Pickler for an home team 'OddsGameTeamStarterXml'
+--
+pickle_home_starter :: PU OddsGameTeamStarterXml
+pickle_home_starter = xpElem "HStarter" $ pickle_starter
+
+
+-- | Pickler for an away team 'OddsGameTeamStarterXml'
+--
+pickle_away_starter :: PU OddsGameTeamStarterXml
+pickle_away_starter = xpElem "AStarter" $ pickle_starter
+
+
+
 -- | Pickler for an 'OddsGameTeamXml'.
 --
 pickle_away_team :: PU OddsGameTeamXml
@@ -608,9 +645,7 @@ pickle_away_team =
         (xpElem "AwayRotationNumber" (xpOption xpInt))
         (xpElem "AwayAbbr" xpText)
         (xpElem "AwayTeamName" xpText)
-        (-- This is an ugly way to get both the AStarter ID attribute
-         -- and contents.
-         xpOption (xpElem "AStarter" $ xpPair (xpAttr "ID" xpInt) xpText))
+        (xpOption pickle_away_starter)
         (xpList pickle_casino)
   where
     from_tuple = uncurryN OddsGameTeamXml
@@ -721,7 +756,10 @@ test_pickle_of_unpickle_is_identity = testGroup "pickle-unpickle tests"
           "test/xml/Odds_XML-largefile.xml",
 
     check "pickle composed with unpickle is the identity (league name)"
-          "test/xml/Odds_XML-league-name.xml" ]
+          "test/xml/Odds_XML-league-name.xml",
+
+    check "pickle composed with unpickle is the identity (missing starters)"
+          "test/xml/Odds_XML-missing-starters.xml" ]
   where
     check desc path = testCase desc $ do
       (expected, actual) <- pickle_unpickle pickle_message path
@@ -745,7 +783,10 @@ test_unpickle_succeeds = testGroup "unpickle tests"
           "test/xml/Odds_XML-largefile.xml",
 
     check "unpickling succeeds (league name)"
-          "test/xml/Odds_XML-league-name.xml" ]
+          "test/xml/Odds_XML-league-name.xml",
+
+    check "unpickling succeeds (missing starters)"
+          "test/xml/Odds_XML-missing-starters.xml" ]
   where
     check desc path = testCase desc $ do
       actual <- unpickleable path pickle_message
@@ -780,6 +821,10 @@ test_on_delete_cascade = testGroup "cascading delete tests"
     check "deleting odds deleted its children (league name)"
           "test/xml/Odds_XML-league-name.xml"
           35 -- 5 casinos, 30 teams
+    ,
+    check "deleting odds deleted its children (missing starters)"
+          "test/xml/Odds_XML-missing-starters.xml"
+          7 -- 5 casinos, 2 teams
     ]
   where
     check desc path expected = testCase desc $ do
index be3dcf592b2ff1a6212b082dd6f117cb8f83b325..8dfddb1c35dd45d6b33890701365337799e32ea6 100644 (file)
@@ -16,15 +16,15 @@ rm -f shelltest.sqlite3
 # and a newsxml that aren't really supposed to import.
 find ./test/xml -maxdepth 1 -name '*.xml' | wc -l
 >>>
-26
+27
 >>>= 0
 
 # Run the imports again; we should get complaints about the duplicate
-# xml_file_ids. There are 2 errors for each violation, so we expect 2*22
+# xml_file_ids. There are 2 errors for each violation, so we expect 2*23
 # occurrences of the string 'ERROR'.
 ./dist/build/htsn-import/htsn-import -c 'shelltest.sqlite3' test/xml/*.xml 2>&1 | grep ERROR | wc -l
 >>>
-44
+46
 >>>= 0
 
 # Finally, clean up after ourselves.
diff --git a/test/xml/Odds_XML-missing-starters.xml b/test/xml/Odds_XML-missing-starters.xml
new file mode 100644 (file)
index 0000000..3acb919
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no" ?>\r<!DOCTYPE message PUBLIC "-//TSN//DTD Statistics 1.0/EN" "Odds_XML.dtd">\r<message>\r<XML_File_ID>21434211</XML_File_ID>\r<heading>AAO;BB-ODDS</heading>\r<category>Odds</category>\r<sport>MLB</sport>\r<Title>Las Vegas Major League Baseball Line</Title>\r<Line_Time>Current Line as of 9:30 A.M. ET</Line_Time>\r<League_Name>Inter League</League_Name>\r<Notes>TUESDAY, JULY 15TH</Notes>\r<Notes>85TH All Star Game - Target Field - Minneapolis, MN</Notes>\r<Game>\r<GameID>42056</GameID>\r<Game_Date>07/15/2014</Game_Date>\r<Game_Time>08:00 PM</Game_Time>\r<AwayTeam>\r<AwayTeamID>683</AwayTeamID>\r<AwayRotationNumber>945</AwayRotationNumber>\r<AwayAbbr>NAT</AwayAbbr>\r<AwayTeamName>MLB-National</AwayTeamName>\r<AStarter ID="0"></AStarter>\r<Casino ClientID="116" Name="5Dimes">-103</Casino>\r<Casino ClientID="111" Name="Sports Interaction">-110</Casino>\r<Casino ClientID="104" Name="BOVADA"></Casino>\r<Casino ClientID="121" Name="Mirage"></Casino>\r<Casino ClientID="127" Name="DonBest Consensus">-103</Casino>\r</AwayTeam>\r<HomeTeam>\r<HomeTeamID>684</HomeTeamID>\r<HomeRotationNumber>946</HomeRotationNumber>\r<HomeAbbr>AME</HomeAbbr>\r<HomeTeamName>MLB-American</HomeTeamName>\r<HStarter ID="0"></HStarter>\r<Casino ClientID="116" Name="5Dimes">-107</Casino>\r<Casino ClientID="111" Name="Sports Interaction">-110</Casino>\r<Casino ClientID="104" Name="BOVADA"></Casino>\r<Casino ClientID="121" Name="Mirage"></Casino>\r<Casino ClientID="127" Name="DonBest Consensus">-107</Casino>\r</HomeTeam>\r<Over_Under>\r<Casino ClientID="116" Name="5Dimes">7.5u</Casino>\r<Casino ClientID="111" Name="Sports Interaction">8u</Casino>\r<Casino ClientID="104" Name="BOVADA"></Casino>\r<Casino ClientID="121" Name="Mirage"></Casino>\r<Casino ClientID="127" Name="DonBest Consensus">8u</Casino>\r</Over_Under>\r</Game>\r<time_stamp> July 14, 2014, at 09:29 AM ET </time_stamp>\r</message>\r
\ No newline at end of file