From 7a598f65372b1b694d222946fd6269033bde0e54 Mon Sep 17 00:00:00 2001 From: emkael Date: Mon, 30 Dec 2019 12:49:54 +0100 Subject: New package structure for result info classes --- jfr_playoff/tournamentinfo/__init__.py | 58 --------------------- jfr_playoff/tournamentinfo/jfrdb.py | 60 ---------------------- jfr_playoff/tournamentinfo/jfrhtml.py | 92 ---------------------------------- jfr_playoff/tournamentinfo/tcjson.py | 62 ----------------------- 4 files changed, 272 deletions(-) delete mode 100644 jfr_playoff/tournamentinfo/__init__.py delete mode 100644 jfr_playoff/tournamentinfo/jfrdb.py delete mode 100644 jfr_playoff/tournamentinfo/jfrhtml.py delete mode 100644 jfr_playoff/tournamentinfo/tcjson.py (limited to 'jfr_playoff/tournamentinfo') 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)] -- cgit v1.2.3