summaryrefslogtreecommitdiff
path: root/jfr_playoff/tournamentinfo
diff options
context:
space:
mode:
authoremkael <emkael@tlen.pl>2019-12-30 12:49:54 +0100
committeremkael <emkael@tlen.pl>2019-12-30 12:49:54 +0100
commit7a598f65372b1b694d222946fd6269033bde0e54 (patch)
treee33fb74aad63756f0b3c94f12e29aff6c97064ed /jfr_playoff/tournamentinfo
parentf77bac9b5406c6bf6b1c819f155164568ef4af36 (diff)
New package structure for result info classes
Diffstat (limited to 'jfr_playoff/tournamentinfo')
-rw-r--r--jfr_playoff/tournamentinfo/__init__.py58
-rw-r--r--jfr_playoff/tournamentinfo/jfrdb.py60
-rw-r--r--jfr_playoff/tournamentinfo/jfrhtml.py92
-rw-r--r--jfr_playoff/tournamentinfo/tcjson.py62
4 files changed, 0 insertions, 272 deletions
diff --git a/jfr_playoff/tournamentinfo/__init__.py b/jfr_playoff/tournamentinfo/__init__.py
deleted file mode 100644
index 21cd62a..0000000
--- a/jfr_playoff/tournamentinfo/__init__.py
+++ /dev/null
@@ -1,58 +0,0 @@
-from jfr_playoff.logger import PlayoffLogger
-from jfr_playoff.data import ResultInfo
-
-
-class TournamentInfoClient(object):
- def __init__(self, settings, database=None):
- self.settings = settings
- self.database = database
-
- def get_results_link(self, suffix):
- pass
-
- def is_finished(self):
- pass
-
- def get_tournament_results(self):
- pass
-
- def get_exceptions(self, method):
- pass
-
-
-class TournamentInfo(ResultInfo):
- def __init__(self, settings, database):
- self.settings = settings
- ResultInfo.__init__(self, settings, database)
-
- def fill_client_list(self, settings, database):
- clients = []
- from jfr_playoff.tournamentinfo.jfrdb import JFRDbTournamentInfo
- from jfr_playoff.tournamentinfo.jfrhtml import JFRHtmlTournamentInfo
- from jfr_playoff.tournamentinfo.tcjson import TCJsonTournamentInfo
- if (database is not None) and ('database' in settings):
- clients.append(JFRDbTournamentInfo(settings, database))
- if 'link' in settings:
- if settings['link'].endswith('leaderb.html'):
- clients.append(JFRHtmlTournamentInfo(settings))
- clients.append(TCJsonTournamentInfo(settings))
- return clients
-
- def get_tournament_results(self):
- teams = self.call_client('get_tournament_results', [])
- if self.is_finished():
- final_positions = self.settings.get('final_positions', [])
- PlayoffLogger.get('tournamentinfo').info(
- 'setting final positions from tournament results: %s',
- final_positions)
- for position in final_positions:
- if len(teams) >= position:
- teams[position-1] = (teams[position-1] + [None] * 4)[0:4]
- teams[position-1][3] = position
- return teams
-
- def is_finished(self):
- return self.call_client('is_finished', True)
-
- def get_results_link(self, suffix='leaderb.html'):
- return self.call_client('get_results_link', None, suffix)
diff --git a/jfr_playoff/tournamentinfo/jfrdb.py b/jfr_playoff/tournamentinfo/jfrdb.py
deleted file mode 100644
index 0f39b47..0000000
--- a/jfr_playoff/tournamentinfo/jfrdb.py
+++ /dev/null
@@ -1,60 +0,0 @@
-import jfr_playoff.sql as p_sql
-
-from jfr_playoff.logger import PlayoffLogger
-from jfr_playoff.tournamentinfo import TournamentInfoClient
-
-SWISS_TIE_WARNING = 'tie detected in swiss %s.' + \
- ' Make sure to resolve the tie by arranging teams' + \
- ' in configuration file.'
-
-
-class JFRDbTournamentInfo(TournamentInfoClient):
- def get_exceptions(self, method):
- return (IOError, TypeError, IndexError, KeyError)
-
- def get_results_link(self, suffix='leaderb.html'):
- row = self.database.fetch(
- self.settings['database'], p_sql.PREFIX, ())
- if row is not None:
- if len(row) > 0:
- link = row[0] + suffix
- PlayoffLogger.get('tournament.jfrdb').info(
- 'generating tournament-specific link from DB %s prefix: %s -> %s',
- self.settings['database'], suffix, link)
- return link
- raise ValueError('unable to fetch db link')
-
- def is_finished(self):
- finished = self.database.fetch(
- self.settings['database'], p_sql.SWISS_ENDED, {})
- PlayoffLogger.get('tournament.jfrdb').info(
- 'fetching tournament finished status from DB %s: %s',
- self.settings['database'], finished)
- return (len(finished) > 0) and (finished[0] > 0)
-
- def get_tournament_results(self):
- 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])
- PlayoffLogger.get('tournament.jfrdb').info(
- 'fetched tournament results from database %s: %s',
- self.settings['database'], swiss_results)
- prev_result = None
- for team in swiss_results:
- if prev_result == team[1]:
- PlayoffLogger.get('tournament.jfrdb').warning(
- SWISS_TIE_WARNING, self.settings['database'])
- prev_result = team[1]
- db_teams = [[team[0], team[3], team[4]] for team in swiss_results]
- PlayoffLogger.get('tournament.jfrdb').info(
- 'fetched team list from database %s: %s',
- self.settings['database'], db_teams)
- return db_teams
diff --git a/jfr_playoff/tournamentinfo/jfrhtml.py b/jfr_playoff/tournamentinfo/jfrhtml.py
deleted file mode 100644
index 8f40c55..0000000
--- a/jfr_playoff/tournamentinfo/jfrhtml.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from math import ceil
-import re
-
-from jfr_playoff.logger import PlayoffLogger
-from jfr_playoff.remote import RemoteUrl as p_remote
-from jfr_playoff.tournamentinfo import TournamentInfoClient
-
-
-class JFRHtmlTournamentInfo(TournamentInfoClient):
- def get_exceptions(self, method):
- if method == 'get_results_link':
- return (KeyError, ValueError)
- return (TypeError, IndexError, KeyError, IOError, ValueError)
-
- def get_results_link(self, suffix='leaderb.html'):
- link = re.sub(r'leaderb.html$', suffix, self.settings['link'])
- PlayoffLogger.get('tournament.jfrhtml').info(
- 'generating tournament-specific link from leaderboard link %s: %s -> %s',
- self.settings['link'], suffix, link)
- return link
-
- def is_finished(self):
- PlayoffLogger.get('tournament.jfrhtml').info(
- 'fetching tournament finished status from HTML: %s',
- self.settings['link'])
- leaderboard = p_remote.fetch(self.settings['link'])
- leaderb_heading = leaderboard.select('td.bdnl12')[0].text
- contains_digits = any(char.isdigit() for char in leaderb_heading)
- PlayoffLogger.get('tournament.jfrhtml').info(
- 'tournament header from HTML: %s, %s',
- leaderb_heading,
- 'contains digits' if contains_digits else "doesn't contain digits")
- non_zero_scores = [
- imps.text
- for imps
- in leaderboard.select('td.bdc small')
- if imps.text != '0-0']
- PlayoffLogger.get('tournament.jfrhtml').info(
- 'tournament leaderboard from HTML: has %d non-zero scores',
- len(non_zero_scores))
- finished = (not contains_digits) and (len(non_zero_scores) > 0)
- PlayoffLogger.get('tournament.jfrhtml').info(
- 'tournament leaderboard from HTML indicates finished: %s',
- finished)
- return finished
-
- def get_tournament_results(self):
- PlayoffLogger.get('tournament.jfrhtml').info(
- 'fetching tournament results from leaderboard URL: %s',
- self.settings['link'])
- 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)
- PlayoffLogger.get('tournament.jfrhtml').info(
- 'read tournament results from leaderboard: %s', teams)
- 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)
- PlayoffLogger.get('tournament.jfrhtml').info(
- 'reading team shortnames from traveller: %s', 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')
- PlayoffLogger.get('tournament.jfrhtml').info(
- 'shortname for %s: %s', team[0], team[1])
- break
- PlayoffLogger.get('tournament.jfrhtml').info(
- 'tournament results from HTML: %s', teams)
- return teams
diff --git a/jfr_playoff/tournamentinfo/tcjson.py b/jfr_playoff/tournamentinfo/tcjson.py
deleted file mode 100644
index 5a81ef3..0000000
--- a/jfr_playoff/tournamentinfo/tcjson.py
+++ /dev/null
@@ -1,62 +0,0 @@
-import json
-import urlparse
-
-from jfr_playoff.logger import PlayoffLogger
-from jfr_playoff.remote import RemoteUrl as p_remote
-from jfr_playoff.tournamentinfo import TournamentInfoClient
-
-FLAG_CDN_URL = 'https://cdn.tournamentcalculator.com/flags/'
-
-
-class TCJsonTournamentInfo(TournamentInfoClient):
- def get_exceptions(self, method):
- return (TypeError, IndexError, KeyError, IOError, ValueError)
-
- def get_results_link(self, suffix):
- link = urlparse.urljoin(self.settings['link'], suffix)
- PlayoffLogger.get('tournament.tcjson').info(
- 'generating tournament-specific link from leaderboard link %s: %s -> %s',
- self.settings['link'], suffix, link)
- return link
-
- def is_finished(self):
- settings_json = json.loads(
- p_remote.fetch_raw(self.get_results_link('settings.json')))
- live_results = settings_json['LiveResults']
- last_round = settings_json['LastPlayedRound']
- last_session = settings_json['LastPlayedSession']
- finished = (not live_results) \
- and (last_round > 0) and (last_session > 0)
- PlayoffLogger.get('tournament.tcjson').info(
- 'tournament settings (live = %s, last_round = %d, last_session = %d) indicate finished: %s',
- live_results, last_round, last_session, finished)
- return finished
-
- def get_tournament_results(self):
- results = []
- results_json = json.loads(
- p_remote.fetch_raw(self.get_results_link('results.json')))
- participant_groups = []
- for result in results_json['Results']:
- group = result['ParticipantGroup']
- if group is not None:
- if group not in participant_groups:
- participant_groups.append(group)
- group_id = participant_groups.index(group) + 1
- else:
- group_id = 999999
- participant = result['Participant']
- flag_url = None
- flag = participant['_flag']
- if flag is not None:
- flag_url = self.get_results_link(
- flag['CustomFlagPath']
- if flag['IsCustom']
- else '%s/%s.png' % (FLAG_CDN_URL, flag['CountryNameCode']))
- results.append((
- group_id, result['Place'],
- participant['_name'], participant['_shortName'],
- flag_url))
- PlayoffLogger.get('tournament.tcjson').info(
- 'tournament results fetched: %s' % results)
- return [list(r[2:]) + [None] for r in sorted(results)]