Commits

Marcin Kasperski committed 842d6d1

All unit-tests pass.

  • Participants
  • Parent commits 5e5bd88

Comments (0)

Files changed (5)

File src/mekk/fics/datatypes/game_info.py

     """
     pass
 
+class ExaminedGameExt(namedtuple("ExaminedGame", "game_no, white, black, examiner")):
+    """
+    Information about running examine.
+
+    game_no: int - FICS game number
+    white: white name
+    black: black name
+    examiner: examining player name
+    """
+    pass
+
 #noinspection PyClassicStyleClass
 class SetupGame(namedtuple("SetupGame", "game_no")):
     """

File src/mekk/fics/parsing/reply/info.py

 from mekk.fics.parsing.common import rated_as_bool, numeric_rank, parse_detailed_date
 
 import re
-from mekk.fics.datatypes.game_info import GameInfo, GameSpec
+from mekk.fics.datatypes.game_info import GameInfo, GameSpec, ExaminedGame, ExaminedGameExt
 #import dateutil.parser
 
 re_badgame = re.compile("^(The current range of game numbers is \d+ to \d+|There is no game \d+\.|There is no such game\.)")
 #  anandkvs (2063) vs donnadistruttiva (1960) rated Standard game.
 # starfishSuprise (1462) vs manok (1491) private rated Blitz game.
 
+re_ginfo_examine = re.compile(r"""
+    ^\s*
+    (?P<examiner>[^\s()]+)
+    (?:\([A-Z]+\))*              # (C), (SR), ...
+    \s+
+    is\s+examining
+    \s+
+    (?P<white>[^\s()]+)
+    (?:\([A-Z]+\))*              # (C), (SR), ...
+    \s+vs\s+
+    (?P<black>[^\s()]+)
+    (?:\([A-Z]+\))*              # (C), (SR), ...
+    \s*
+    \.
+    """, re.VERBOSE)
+
+
 re_ginfo_clock = re.compile("^\s*Time controls: (?P<base_sec>\d+) (?P<inc>\d+)")
 re_ginfo_start_time = re.compile("^\s*Time of starting: (?P<start_time>.*)$")
 #  White time 1:25:27    Black time 1:23:58
     if len(lines) >= 4:
         m_lead = re_ginfo_lead.search(lines[0])
         m_players = re_ginfo_players.search(lines[1])
-        m_clock = re_ginfo_clock.search(lines[2])
-        m_start_time = re_ginfo_start_time.search(lines[3])
-        if m_lead and m_players and m_clock and m_start_time:
-            start_time, start_time_zone = parse_detailed_date(m_start_time.group('start_time'))
-            return GameInfo(
+        if m_players:
+            m_clock = re_ginfo_clock.search(lines[2])
+            m_start_time = re_ginfo_start_time.search(lines[3])
+            if m_lead and m_players and m_clock and m_start_time:
+                start_time, start_time_zone = parse_detailed_date(m_start_time.group('start_time'))
+                return GameInfo(
+                    game_no = int(m_lead.group('game_no')),
+                    white_name = PlayerName(m_players.group('white')),
+                    black_name = PlayerName(m_players.group('black')),
+                    white_rating_value = numeric_rank(m_players.group('white_rank')),
+                    black_rating_value = numeric_rank(m_players.group('black_rank')),
+                    start_time = start_time,
+                    start_time_zone = start_time_zone,
+                    game_spec = GameSpec(
+                        game_type = GameType(m_players.group('variant')),
+                        is_rated = rated_as_bool(m_players.group('is_rated')),
+                        is_private = True if m_players.group('is_private') else False,
+                        clock = GameClock(int(m_clock.group('base_sec'))/60,
+                                          int(m_clock.group('inc')))))
+        m_ex = re_ginfo_examine.search(lines[1])
+        if m_ex:
+            return ExaminedGameExt(
                 game_no = int(m_lead.group('game_no')),
-                white_name = PlayerName(m_players.group('white')),
-                black_name = PlayerName(m_players.group('black')),
-                white_rating_value = numeric_rank(m_players.group('white_rank')),
-                black_rating_value = numeric_rank(m_players.group('black_rank')),
-                start_time = start_time,
-                start_time_zone = start_time_zone,
-                game_spec = GameSpec(
-                    game_type = GameType(m_players.group('variant')),
-                    is_rated = rated_as_bool(m_players.group('is_rated')),
-                    is_private = True if m_players.group('is_private') else False,
-                    clock = GameClock(int(m_clock.group('base_sec'))/60,
-                                      int(m_clock.group('inc')))))
+                examiner = PlayerName(m_ex.group('examiner')),
+                white = PlayerName(m_ex.group('white')),
+                black = PlayerName(m_ex.group('black')),
+            )
 
     raise errors.ReplyParsingException(reply_text)
 

File src/mekk/fics/tell_commands/tell_errors.py

     user_msg = "Bad command name or parameters"
 
 class ShortcutAmbiguousKeyword(ShortcutResolvingError):
+    """
+    Many resolutions possible
+    :param given: string specified (for example "li")
+    :type given: str
+    :param available: strings possible (for example ["list", "link"])
+    :type available: [str]
+    """
+
     def __init__(self, given, available):
         self.bad_keyword = given
         self.matching_keywords = available

File src/mekk/fics/test_utils/helpers.py

 except ImportError:
     #noinspection PyUnusedLocal
     def dict_compare(*args,**kwargs):
+        """
+        Fake dict_compare
+        """
         raise Exception("dict_compare not installed")
 
     def assert_dicts_equal(testobj, received, expected):

File tests/test_parser.py

 from mekk.fics.datatypes.color import Color, BLACK, WHITE
 from mekk.fics.datatypes.date import FicsDateInfo
 from mekk.fics.datatypes.game_clock import GameClock
-from mekk.fics.datatypes.game_info import GameReference, ExaminedGame, SetupGame, PlayedGame, GameSpec, GameInfo
+from mekk.fics.datatypes.game_info import GameReference, ExaminedGame, SetupGame, PlayedGame, GameSpec, GameInfo, ExaminedGameExt
 from mekk.fics.datatypes.game_type import GameType
 from mekk.fics.datatypes.list_items import ListContents
 from mekk.fics.datatypes.notifications import  SeekRef, GameJoinInfo, Seek
 """)
         self.failUnless(status)
         self.failUnlessEqual(cmd, "ginfo")
-        self.failUnlessIsInstance(info, ExaminedGame)
+        self.failUnlessIsInstance(info, ExaminedGameExt)
+        self.failUnlessEqual(info.examiner,"MAd")
+        self.failUnlessEqual(info.white,"MAd")
+        self.failUnlessEqual(info.black,"pgv")
+        self.failUnlessEqual(info.game_no,95)
 
     def test_wrong(self):
         cmd, status, info = parse_fics_reply(