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
|
from math import ceil
import re
import mysql
import jfr_playoff.sql as p_sql
from jfr_playoff.remote import RemoteUrl as p_remote
SWISS_TIE_WARNING = 'WARNING: tie detected in swiss %s.' + \
' Make sure to resolve the tie by arranging teams' + \
' in configuration file.'
class TournamentInfo:
def __init__(self, settings, database):
self.settings = settings
self.database = database
def __get_html_results(self):
if 'link' not in self.settings:
raise KeyError('link not configured')
if not self.settings['link'].endswith('leaderb.html'):
raise ValueError('unable to determine tournament results')
leaderboard = p_remote.fetch(self.settings['link'])
result_links = [row.select('a[onmouseover]') for row in leaderboard.find_all('tr') if len(row.select('a[onmouseover]')) > 0]
results = [None] * (len(result_links) * max([len(links) for links in result_links]))
for i in range(0, len(result_links)):
for j in range(0, len(result_links[i])):
results[len(result_links) * j + i] = result_links[i][j]
teams = []
team_links = {}
for team in results:
if team is not None:
team_info = []
fullname = team.text.strip(u'\xa0')
team_links[team['href']] = fullname
team_info.append(fullname)
team_info.append('')
team_image = team.find('img')
if team_image is not None:
team_info.append(team_image['src'].replace('images/', ''))
teams.append(team_info)
for table in range(1, int(ceil(len(teams)/2.0))+1):
table_url = self.get_results_link('1t%d-1.html' % (table))
table_content = p_remote.fetch(table_url)
for link in table_content.select('a.br'):
if link['href'] in team_links:
for team in teams:
if team[0] == team_links[link['href']]:
team[1] = link.text.strip(u'\xa0')
break
return teams
def __get_db_results(self):
if self.database is None:
raise KeyError('database not configured')
if 'database' not in self.settings:
raise KeyError('database not configured')
if 'ties' not in self.settings:
self.settings['ties'] = []
swiss_teams = self.database.fetch_all(
self.settings['database'], p_sql.SWISS_RESULTS, {})
swiss_results = sorted(
swiss_teams,
key=lambda t: self.settings['ties'].index(t[0]) \
if t[0] in self.settings['ties'] else -1)
swiss_results = sorted(
swiss_results, key=lambda t: t[1], reverse=True)
swiss_results = sorted(swiss_results, key=lambda team: team[2])
prev_result = None
for team in swiss_results:
if prev_result == team[1]:
print SWISS_TIE_WARNING % (self.settings['database'])
prev_result = team[1]
db_teams = [[team[0], team[3], team[4]] for team in swiss_results]
return db_teams
def __get_html_finished(self):
if 'link' not in self.settings:
raise KeyError('link not configured')
if not self.settings['link'].endswith('leaderb.html'):
raise ValueError('unable to determine tournament status')
leaderboard = p_remote.fetch(self.settings['link'])
leaderb_heading = leaderboard.select('td.bdnl12')[0].text
non_zero_scores = [imps.text for imps in leaderboard.select('td.bdc small') if imps.text != '0-0']
return (not any(char.isdigit() for char in leaderb_heading)) and (len(non_zero_scores) > 0)
def __get_db_finished(self):
if self.database is None:
raise KeyError('database not configured')
if 'database' not in self.settings:
raise KeyError('database not configured')
finished = self.database.fetch(
self.settings['database'], p_sql.SWISS_ENDED, {})
return (len(finished) > 0) and (finished[0] > 0)
def __get_html_link(self, suffix='leaderb.html'):
if 'link' not in self.settings:
raise KeyError('link not configured')
if not self.settings['link'].endswith('leaderb.html'):
raise ValueError('unable to determine html link')
return re.sub(r'leaderb.html$', suffix, self.settings['link'])
def __get_db_link(self, suffix='leaderb.html'):
if self.database is None:
raise KeyError('database not configured')
if 'database' not in self.settings:
raise KeyError('database not configured')
row = self.database.fetch(
self.settings['database'], p_sql.PREFIX, ())
if row is not None:
if len(row) > 0:
return row[0] + suffix
raise ValueError('unable to fetch db link')
def get_tournament_results(self):
teams = []
try:
teams = self.__get_db_results()
except (mysql.connector.Error, TypeError, IndexError, KeyError):
try:
teams = self.__get_html_results()
except (TypeError, IndexError, KeyError, IOError, ValueError):
pass
if 'final_positions' in self.settings:
for position in self.settings['final_positions']:
if len(teams) >= position:
teams[position-1].append(position)
return teams
def is_finished(self):
try:
return self.__get_db_finished()
except (mysql.connector.Error, TypeError, IndexError, KeyError):
try:
return self.__get_html_finished()
except (TypeError, IndexError, KeyError, IOError, ValueError):
pass
return True
def get_results_link(self, suffix='leaderb.html'):
try:
return self.__get_db_link(suffix)
except (mysql.connector.Error, TypeError, IndexError, KeyError):
try:
return self.__get_html_link(suffix)
except (KeyError, ValueError):
pass
return None
|