summaryrefslogtreecommitdiff
path: root/jfr_playoff/data/match/tcjson.py
blob: 60f6f81220ef213b4ab5c5c1d6ae08ae6fb1ad34 (plain)
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
import json
import urlparse

from jfr_playoff.data.match import MatchInfoClient
from jfr_playoff.remote import RemoteUrl as p_remote
from jfr_playoff.logger import PlayoffLogger


class TCJsonMatchInfo(MatchInfoClient):
    @property
    def priority(self):
        return 20

    def is_capable(self):
        return ('link' in self.settings) and ('#' in self.settings['link'])

    def get_exceptions(self, method):
        return (TypeError, IndexError, KeyError, IOError, ValueError)

    def _get_results_link(self, suffix):
        return urlparse.urljoin(self.settings['link'], suffix)

    def _get_round_from_link(self, link):
        fragment = urlparse.urlparse(link).fragment
        if len(fragment) < 28:
            # old, shorter TC hashes
            return int(fragment[11:14]), int(fragment[14:17]), False
        # new, longer TC hashes
        return int(fragment[20:26]), int(fragment[26:32]), True

    def get_match_link(self):
        PlayoffLogger.get('match.tcjson').info(
            'match #%d link pre-defined: %s',
            self.settings['id'], self.settings['link'])
        return self.settings['link']

    def _get_results(self, link, table_no):
        session_no, round_no, _ = self._get_round_from_link(link)
        PlayoffLogger.get('match.tcjson').info(
            'link %s -> session %d, round %d', link, session_no, round_no)
        round_results = json.loads(
            p_remote.fetch_raw(
                self._get_results_link(
                    'o%d-%d.json' % (session_no, round_no))))
        table_id = str(table_no)
        for result in round_results['Results']:
            if result['Table'] == table_id:
                return result
        PlayoffLogger.get('match.tcjson').info(
            'results for table %d not found in %s', table_no, link)
        raise ValueError('results not found')

    def fetch_teams(self, teams):
        results = self._get_results(
            self.settings['link'], self.settings['table'])
        sides = [side for side in ['Ns', 'Sn', 'We', 'Ew'] if side in results]
        for idx, side in enumerate(sides):
            teams[idx].name = [results[side]['_name']]
            teams[idx].known_teams = 1
            teams[idx].score = results['Sum1'+side]
        PlayoffLogger.get('match.tcjson').info(
            'scores fetched: %s', teams)
        return teams

    def board_count(self):
        results = self._get_results(
            self.settings['link'], self.settings['table'])
        played = 0
        finished = True
        for segment in results['Segments']:
            PlayoffLogger.get('match.tcjson').info(
                'segment %d: played boards=%d, live=%s, towel=%s, notmeanttobeplayed=%s',
                segment['Segment']+1, segment['BoardsCounted'],
                segment['Live'], segment['Towel'], segment['NotMeantToBePlayed'])
            if not segment['NotMeantToBePlayed']:
                played += segment['BoardsCounted']
                if segment['Live'] or not (
                        (segment['BoardsCounted'] or segment['Towel'])):
                    PlayoffLogger.get('match.tcjson').info(
                        'segment %d not finished', segment['Segment']+1)
                    finished = False
            else:
                PlayoffLogger.get('match.tcjson').info(
                    'segment %d not meant to be played', segment['Segment']+1)
        PlayoffLogger.get('match.tcjson').info(
            'board count: %d, finished: %s', played, finished)
        if finished and not played:
            # toweled match
            played = 1
        return played, played if finished else played+1

    def _get_segment_link(self, base_link, segment_id, table_id):
        session_id, round_id, long_link = self._get_round_from_link(base_link)
        if long_link:
            table_id = '{t:{pad}>12}'.format(t=table_id, pad='0')
            fragment = '#000000SS000000000000%06d%06d%06d%s' % (
                session_id, round_id, segment_id, table_id)
        else:
            table_id = '{t:{pad}>6}'.format(t=table_id, pad='0')
            fragment = '#000SS000000%03d%03d%03d%s' % (
                session_id, round_id, segment_id, table_id)
        return urlparse.urljoin(base_link, fragment)

    def running_link(self):
        settings = json.loads(p_remote.fetch_raw(
            self._get_results_link('settings.json')))
        if settings['ShowOnlyResults']:
            PlayoffLogger.get('match.tcjson').info(
                'ShowOnlyResults active, no running segment link available')
            return self.settings['link']
        results = self._get_results(
            self.settings['link'], self.settings['table'])
        for segment in results['Segments']:
            if segment['Live']:
                link = self._get_segment_link(
                    self.settings['link'],
                    segment['Segment'], results['TableFull'])
                PlayoffLogger.get('match.tcjson').info(
                    'running segment link for segment %d, table %s: %s',
                    segment['Segment']+1, results['TableFull'], link)
                return link
        PlayoffLogger.get('match.tcjson').info(
            'no running segment link available')
        return self.settings['link']