From 13d8dbb4135f290a80577f6fca09d9488e861a18 Mon Sep 17 00:00:00 2001 From: emkael Date: Mon, 31 Jul 2017 19:44:32 +0200 Subject: Factoring out DB operations --- playoff.py | 23 ++++++----------------- playoff/db.py | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 playoff/db.py diff --git a/playoff.py b/playoff.py index 9537ef4..fe29b97 100644 --- a/playoff.py +++ b/playoff.py @@ -1,5 +1,4 @@ import glob, json, os, readline, shutil, socket, sys -import mysql.connector from datetime import datetime from urlparse import urljoin from playoff import sql as p_sql @@ -24,18 +23,8 @@ settings = json.load(open(settings_file)) teams = settings['teams'] leaderboard = [None] * len(teams) -database = mysql.connector.connect( - user=settings['database']['user'], - password=settings['database']['pass'], - host=settings['database']['host'], - port=settings['database']['port'] -) -db_cursor = database.cursor(buffered=True) - -def db_fetch(db, sql, params): - db_cursor.execute(sql.replace('#db#', db), params) - row = db_cursor.fetchone() - return row +from playoff.db import PlayoffDB +db = PlayoffDB(settings['database']) def get_shortname(fullname): for team in settings['teams']: @@ -144,12 +133,12 @@ def get_match_info(match): info.winner_matches = list(set(info.winner_matches)) info.loser_matches = list(set(info.loser_matches)) try: - row = db_fetch(match['database'], p_sql.PREFIX, ()) + row = db.fetch(match['database'], p_sql.PREFIX, ()) info.link = '%srunda%d.html' % (row[0], match['round']) except Exception as e: pass try: - row = db_fetch(match['database'], p_sql.MATCH_RESULTS, (match['table'], match['round'])) + row = db.fetch(match['database'], p_sql.MATCH_RESULTS, (match['table'], match['round'])) info.teams[0].name = row[0] info.teams[1].name = row[1] info.teams[0].score = row[3] + row[5] @@ -187,8 +176,8 @@ def get_match_info(match): ) if len([team for team in match_teams if team is not None]) > 0 else '' try: - towels = db_fetch(match['database'], p_sql.TOWEL_COUNT, (match['table'], match['round'])) - row = [0 if r is None else r for r in db_fetch(match['database'], p_sql.BOARD_COUNT, (match['table'], match['round']))] + towels = db.fetch(match['database'], p_sql.TOWEL_COUNT, (match['table'], match['round'])) + row = [0 if r is None else r for r in db.fetch(match['database'], p_sql.BOARD_COUNT, (match['table'], match['round']))] if row[1] > 0: info.running = int(row[1]) if row[1] >= row[0] - towels[0]: diff --git a/playoff/db.py b/playoff/db.py new file mode 100644 index 0000000..aa0c2e2 --- /dev/null +++ b/playoff/db.py @@ -0,0 +1,19 @@ +import mysql.connector + +class PlayoffDB(object): + + db_cursor = None + + def __init__(self, settings): + self.database = mysql.connector.connect( + user=settings['user'], + password=settings['pass'], + host=settings['host'], + port=settings['port'] + ) + self.db_cursor = self.database.cursor(buffered=True) + + def fetch(self, db, sql, params): + self.db_cursor.execute(sql.replace('#db#', db), params) + row = self.db_cursor.fetchone() + return row -- cgit v1.2.3 From 46b24f530191dd443a4edb451b5f5573a875a5ca Mon Sep 17 00:00:00 2001 From: emkael Date: Mon, 31 Jul 2017 20:04:02 +0200 Subject: Factoring out settings loading mechanism --- playoff.py | 21 ++++----------------- playoff/settings.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 playoff/settings.py diff --git a/playoff.py b/playoff.py index fe29b97..ee15319 100644 --- a/playoff.py +++ b/playoff.py @@ -1,25 +1,12 @@ -import glob, json, os, readline, shutil, socket, sys +import os, shutil, socket from datetime import datetime from urlparse import urljoin from playoff import sql as p_sql from playoff import template as p_temp -def complete_filename(text, state): - return (glob.glob(text+'*')+[None])[state] - -if len(sys.argv) > 1: - settings_file = sys.argv[1] -else: - readline.set_completer_delims(' \t\n;') - readline.parse_and_bind("tab: complete") - readline.set_completer(complete_filename) - settings_file = raw_input('JSON settings file: ') - -if not os.path.exists(settings_file): - print 'Settings file "%s" not found' % settings_file - sys.exit(1) - -settings = json.load(open(settings_file)) +from playoff.settings import PlayoffSettings +s = PlayoffSettings() +settings = s.get() teams = settings['teams'] leaderboard = [None] * len(teams) diff --git a/playoff/settings.py b/playoff/settings.py new file mode 100644 index 0000000..dd7399d --- /dev/null +++ b/playoff/settings.py @@ -0,0 +1,31 @@ +import glob, json, os, readline, sys + +def complete_filename(text, state): + return (glob.glob(text+'*')+[None])[state] + +class PlayoffSettings: + + def __init__(self): + self.interactive = False + if len(sys.argv) > 1: + settings_file = sys.argv[1] + else: + self.interactive = True + readline.set_completer_delims(' \t\n;') + readline.parse_and_bind("tab: complete") + readline.set_completer(complete_filename) + settings_file = raw_input('JSON settings file: ') + + if not os.path.exists(settings_file): + raise IOError('Settings file %s not found' % settings_file) + + self.settings = json.load(open(settings_file)) + + def has_section(self, key): + return key in self.settings + + def get(self, *keys): + section = self.settings + for key in keys: + section = section[key] + return section -- cgit v1.2.3 From 3be82c96951e7d98a76272b593e6b99e921fabdd Mon Sep 17 00:00:00 2001 From: emkael Date: Mon, 31 Jul 2017 20:31:03 +0200 Subject: Spliting spaghetti code into functions --- playoff.py | 227 ++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 127 insertions(+), 100 deletions(-) diff --git a/playoff.py b/playoff.py index ee15319..2f93ad8 100644 --- a/playoff.py +++ b/playoff.py @@ -3,30 +3,23 @@ from datetime import datetime from urlparse import urljoin from playoff import sql as p_sql from playoff import template as p_temp - -from playoff.settings import PlayoffSettings -s = PlayoffSettings() -settings = s.get() -teams = settings['teams'] -leaderboard = [None] * len(teams) - from playoff.db import PlayoffDB -db = PlayoffDB(settings['database']) +from playoff.settings import PlayoffSettings -def get_shortname(fullname): - for team in settings['teams']: +def get_shortname(fullname, teams): + for team in teams: if team[0] == fullname: return team[1] return fullname -def get_team_image(fullname): - for team in settings['teams']: +def get_team_image(fullname, teams): + for team in teams: if team[0] == fullname and len(team) > 2: if team[2] is not None: return p_temp.LEADERBOARD_ROW_FLAG % (team[2]) return '' -def get_match_table(match): +def get_match_table(match, teams, page_settings): rows = '' for team in match.teams: rows += p_temp.MATCH_TEAM_ROW % ( @@ -34,60 +27,59 @@ def get_match_table(match): 'loser' if team.name == match.loser else '']).strip(), match.link, team.name, - ' / '.join([get_shortname(name) for name in team.name.split('
')]), + ' / '.join([get_shortname(name, teams) for name in team.name.split('
')]), match.link, team.score ) html = p_temp.MATCH_TABLE.decode('utf8') % ( - int(settings['page']['width'] * 0.75), - int(settings['page']['width'] * 0.25), + int(page_settings['width'] * 0.75), + int(page_settings['width'] * 0.25), rows ) if match.running > 0: html += p_temp.MATCH_RUNNING % (match.link, match.running) return html -def get_match_grid(grid, matches, width, height): +def get_match_grid(grid, phases, matches, page_settings, width, height, teams, canvas_settings): grid_boxes = '' col_no = 0 for column in grid: - grid_x = col_no * (settings['page']['width'] + settings['page']['margin']) + grid_x = col_no * (page_settings['width'] + page_settings['margin']) grid_header = p_temp.MATCH_GRID_PHASE_RUNNING if len([match for match in column if match is not None and matches[match].running > 0]) > 0 else p_temp.MATCH_GRID_PHASE grid_boxes += grid_header % ( - settings['phases'][col_no]['link'], - settings['page']['width'], + phases[col_no]['link'], + page_settings['width'], grid_x, - settings['phases'][col_no]['title'] + phases[col_no]['title'] ) row_no = 0 column_height = height / len(column) for match in column: - grid_y = int(row_no * column_height + 0.5 * (column_height - settings['page']['height'])) + grid_y = int(row_no * column_height + 0.5 * (column_height - page_settings['height'])) if match is not None: grid_boxes += p_temp.MATCH_BOX % ( grid_x, grid_y, match, ' '.join([str(m) for m in matches[match].winner_matches]) if matches[match].winner_matches is not None else '', ' '.join([str(m) for m in matches[match].loser_matches]) if matches[match].loser_matches is not None else '', - get_match_table(matches[match]) + get_match_table(matches[match], teams, page_settings) ) row_no += 1 col_no += 1 - canvas_settings = [] - if 'canvas' in settings: - for setting, value in settings['canvas'].iteritems(): - canvas_settings.append( - 'data-%s="%s"' % (setting.replace('_', '-'), str(value)) - ) - return p_temp.MATCH_GRID % (width, height, width, height, ' '.join(canvas_settings), grid_boxes) + canvas_attrs = [] + for setting, value in canvas_settings.iteritems(): + canvas_attrs.append( + 'data-%s="%s"' % (setting.replace('_', '-'), str(value)) + ) + return p_temp.MATCH_GRID % (width, height, width, height, ' '.join(canvas_attrs), grid_boxes) -def get_leaderboard_table(leaderboard): +def get_leaderboard_table(leaderboard, teams): if len([t for t in leaderboard if t is not None]) == 0: return '' position = 1 rows = '' for team in leaderboard: - rows += p_temp.LEADERBOARD_ROW % (position, get_team_image(team), team or '') + rows += p_temp.LEADERBOARD_ROW % (position, get_team_image(team, teams), team or '') position +=1 html = p_temp.LEADERBOARD.decode('utf8') % (rows) return html @@ -105,9 +97,7 @@ class Match: winner_matches = None loser_matches = None -match_info = {} - -def get_match_info(match): +def get_match_info(match, match_info, teams, db): info = Match() info.teams = [Team(), Team()] info.winner_matches = [] @@ -175,82 +165,119 @@ def get_match_info(match): pass return info -grid = [] -for phase in settings['phases']: - phase_grid = [None] * (len(phase['dummies']) + len(phase['matches']) if 'dummies' in phase else len(phase['matches'])) - phase_pos = 0 - for match in phase['matches']: - if 'dummies' in phase: - while phase_pos in phase['dummies']: - phase_pos += 1 - match_info[match['id']] = get_match_info(match) - match_info[match['id']].link = phase['link'] if match_info[match['id']].link is None else urljoin(phase['link'], match_info[match['id']].link) - phase_grid[phase_pos] = match['id'] - phase_pos += 1 - grid.append(phase_grid) +def generate_phases(phases): + grid = [] + for phase in phases: + phase_grid = [None] * (len(phase['dummies']) + len(phase['matches']) if 'dummies' in phase else len(phase['matches'])) + phase_pos = 0 + for match in phase['matches']: + if 'dummies' in phase: + while phase_pos in phase['dummies']: + phase_pos += 1 + phase_grid[phase_pos] = match['id'] + phase_pos += 1 + grid.append(phase_grid) + return grid -for team in settings['teams']: - if len(team) > 3: - leaderboard[team[3]-1] = team[0] +def fill_match_info(phases, teams, db): + match_info = {} + for phase in phases: + for match in phase['matches']: + match_info[match['id']] = get_match_info(match, match_info, teams, db) + match_info[match['id']].link = phase['link'] if match_info[match['id']].link is None else urljoin(phase['link'], match_info[match['id']].link) + return match_info -leaderboard_teams = {} -for phase in settings['phases']: - for match in phase['matches']: - if 'winner' in match: - winner_key = tuple(match['winner']) - if winner_key not in leaderboard_teams: - leaderboard_teams[winner_key] = [] - leaderboard_teams[winner_key].append(match_info[match['id']].winner) - if 'loser' in match: - loser_key = tuple(match['loser']) - if loser_key not in leaderboard_teams: - leaderboard_teams[loser_key] = [] - leaderboard_teams[loser_key].append(match_info[match['id']].loser) +def prefill_leaderboard(teams): + leaderboard = [None] * len(teams) + for team in teams: + if len(team) > 3: + leaderboard[team[3]-1] = team[0] + return leaderboard -for positions, teams in leaderboard_teams.iteritems(): - positions = list(positions) - if len(positions) == len([team for team in teams if team is not None]): - for table_team in settings['teams']: - if table_team[0] in teams: - position = positions.pop(0) - leaderboard[position-1] = table_team[0] +def fill_leaderboard(phases, teams): + leaderboard_teams = {} + leaderboard = prefill_leaderboard(teams) + for phase in phases: + for match in phase['matches']: + if 'winner' in match: + winner_key = tuple(match['winner']) + if winner_key not in leaderboard_teams: + leaderboard_teams[winner_key] = [] + leaderboard_teams[winner_key].append(match_info[match['id']].winner) + if 'loser' in match: + loser_key = tuple(match['loser']) + if loser_key not in leaderboard_teams: + leaderboard_teams[loser_key] = [] + leaderboard_teams[loser_key].append(match_info[match['id']].loser) -grid_columns = len(settings['phases']) -grid_rows = max([len(phase['matches']) + len(phase['dummies']) if 'dummies' in phase else len(phase['matches']) for phase in settings['phases']]) -grid_height = grid_rows * (settings['page']['height'] + settings['page']['margin']) - settings['page']['margin'] -grid_width = grid_columns * (settings['page']['width'] + settings['page']['margin']) - settings['page']['margin'] + for positions, teams in leaderboard_teams.iteritems(): + positions = list(positions) + if len(positions) == len([team for team in teams if team is not None]): + for table_team in teams: + if table_team[0] in teams: + position = positions.pop(0) + leaderboard[position-1] = table_team[0] + return leaderboard -content = ( - p_temp.PAGE % ( +def generate_content(grid, phases, match_info, teams, grid_width, grid_height, page_settings, canvas_settings): + return p_temp.PAGE % ( p_temp.PAGE_HEAD % ( - p_temp.PAGE_HEAD_REFRESH % (settings['page']['refresh']) if settings['page']['refresh'] > 0 else '', - settings['page']['title'] + p_temp.PAGE_HEAD_REFRESH % (page_settings['refresh']) if page_settings['refresh'] > 0 else '', + page_settings['title'] ), p_temp.PAGE_BODY % ( - settings['page']['logoh'], - get_match_grid(grid, match_info, grid_width, grid_height), - get_leaderboard_table(leaderboard), + page_settings['logoh'], + get_match_grid(grid, phases, match_info, page_settings, grid_width, grid_height, teams, canvas_settings), + get_leaderboard_table(leaderboard, teams), p_temp.PAGE_BODY_FOOTER.decode('utf8') % (datetime.now().strftime('%Y-%m-%d o %H:%M')) ) - )).encode('utf8') + ) -output = open(settings['output'], 'w') -output.write(content) -output.close() +def write_content(content, output_file): + output = open(output_file, 'w') + output.write(content.encode('utf8')) + output.close() + return os.path.dirname(output_file) -output_path = os.path.dirname(settings['output']) -script_output_path = os.path.join(output_path, 'sklady/playoff.js') +def copy_scripts(output_path): + script_path = 'sklady/playoff.js' + script_output_path = os.path.join(output_path, script_path) + shutil.copy(unicode(os.path.join(os.path.dirname(__file__), 'playoff.js')), + unicode(script_output_path)) + return script_output_path -shutil.copy(unicode(os.path.join(os.path.dirname(__file__), 'playoff.js')), - unicode(script_output_path)) +def send_files(goniec_settings, path, files): + if goniec_settings['enabled']: + try: + base_path = path.strip(os.sep) + os.sep + content_files = [filename.replace(base_path, '') for filename in files if filename.startswith(base_path)] + content_lines = [base_path] + content_files + ['bye', ''] + print '\n'.join(content_lines) + goniec = socket.socket() + goniec.connect((goniec_settings['host'], goniec_settings['port'])) + goniec.sendall('\n'.join(content_lines)) + goniec.close() + except socket.error: + pass + +s = PlayoffSettings() +db = PlayoffDB(s.get('database')) + +phase_settings = s.get('phases') +grid = generate_phases(phase_settings) +match_info = fill_match_info(phase_settings, s.get('teams'), db) +leaderboard = fill_leaderboard(phase_settings, s.get('teams')) + +page_settings = s.get('page') +grid_columns = len(phase_settings) +grid_rows = max([len(phase['matches']) + len(phase['dummies']) if 'dummies' in phase else len(phase['matches']) for phase in phase_settings]) +grid_height = grid_rows * (page_settings['height'] + page_settings['margin']) - page_settings['margin'] +grid_width = grid_columns * (page_settings['width'] + page_settings['margin']) - page_settings['margin'] + +content = generate_content(grid, phase_settings, match_info, s.get('teams'), grid_width, grid_height, page_settings, s.get('canvas') if s.has_section('canvas') else {}) + +output_file = s.get('output') +output_path = write_content(content, output_file) +script_path = copy_scripts(output_path) +send_files(s.get('goniec'), output_path, [output_file, script_path]) -if settings['goniec']['enabled']: - try: - content_lines = [(output_path.strip('/') + '/').replace('/', '\\')] + [os.path.basename(settings['output']), 'sklady/playoff.js'] + ['bye', ''] - print '\n'.join(content_lines) - goniec = socket.socket() - goniec.connect((settings['goniec']['host'], settings['goniec']['port'])) - goniec.sendall('\n'.join(content_lines)) - goniec.close() - except socket.error: - pass -- cgit v1.2.3 From 85d798ae2eeab73062303f1561c58f23e84d29da Mon Sep 17 00:00:00 2001 From: emkael Date: Mon, 31 Jul 2017 20:42:57 +0200 Subject: Full encapsulation --- playoff.py | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/playoff.py b/playoff.py index 2f93ad8..8a2a9e3 100644 --- a/playoff.py +++ b/playoff.py @@ -1,8 +1,8 @@ import os, shutil, socket from datetime import datetime from urlparse import urljoin -from playoff import sql as p_sql -from playoff import template as p_temp +import playoff.sql as p_sql +import playoff.template as p_temp from playoff.db import PlayoffDB from playoff.settings import PlayoffSettings @@ -194,7 +194,7 @@ def prefill_leaderboard(teams): leaderboard[team[3]-1] = team[0] return leaderboard -def fill_leaderboard(phases, teams): +def fill_leaderboard(phases, teams, match_info): leaderboard_teams = {} leaderboard = prefill_leaderboard(teams) for phase in phases: @@ -219,7 +219,7 @@ def fill_leaderboard(phases, teams): leaderboard[position-1] = table_team[0] return leaderboard -def generate_content(grid, phases, match_info, teams, grid_width, grid_height, page_settings, canvas_settings): +def generate_content(grid, phases, match_info, teams, grid_width, grid_height, page_settings, canvas_settings, leaderboard): return p_temp.PAGE % ( p_temp.PAGE_HEAD % ( p_temp.PAGE_HEAD_REFRESH % (page_settings['refresh']) if page_settings['refresh'] > 0 else '', @@ -260,24 +260,26 @@ def send_files(goniec_settings, path, files): except socket.error: pass -s = PlayoffSettings() -db = PlayoffDB(s.get('database')) +def main(): + s = PlayoffSettings() + db = PlayoffDB(s.get('database')) -phase_settings = s.get('phases') -grid = generate_phases(phase_settings) -match_info = fill_match_info(phase_settings, s.get('teams'), db) -leaderboard = fill_leaderboard(phase_settings, s.get('teams')) + phase_settings = s.get('phases') + grid = generate_phases(phase_settings) + match_info = fill_match_info(phase_settings, s.get('teams'), db) + leaderboard = fill_leaderboard(phase_settings, s.get('teams'), match_info) -page_settings = s.get('page') -grid_columns = len(phase_settings) -grid_rows = max([len(phase['matches']) + len(phase['dummies']) if 'dummies' in phase else len(phase['matches']) for phase in phase_settings]) -grid_height = grid_rows * (page_settings['height'] + page_settings['margin']) - page_settings['margin'] -grid_width = grid_columns * (page_settings['width'] + page_settings['margin']) - page_settings['margin'] + page_settings = s.get('page') + grid_columns = len(phase_settings) + grid_rows = max([len(phase['matches']) + len(phase['dummies']) if 'dummies' in phase else len(phase['matches']) for phase in phase_settings]) + grid_height = grid_rows * (page_settings['height'] + page_settings['margin']) - page_settings['margin'] + grid_width = grid_columns * (page_settings['width'] + page_settings['margin']) - page_settings['margin'] -content = generate_content(grid, phase_settings, match_info, s.get('teams'), grid_width, grid_height, page_settings, s.get('canvas') if s.has_section('canvas') else {}) + content = generate_content(grid, phase_settings, match_info, s.get('teams'), grid_width, grid_height, page_settings, s.get('canvas') if s.has_section('canvas') else {}, leaderboard) -output_file = s.get('output') -output_path = write_content(content, output_file) -script_path = copy_scripts(output_path) -send_files(s.get('goniec'), output_path, [output_file, script_path]) + output_file = s.get('output') + output_path = write_content(content, output_file) + script_path = copy_scripts(output_path) + send_files(s.get('goniec'), output_path, [output_file, script_path]) +main() -- cgit v1.2.3 From bd5fd6a6596dd7625019c6c0f0ff043597cda837 Mon Sep 17 00:00:00 2001 From: emkael Date: Mon, 31 Jul 2017 20:45:13 +0200 Subject: Renaming module to avoid ambiguity --- jfr_playoff/__init__.py | 0 jfr_playoff/db.py | 19 +++++++ jfr_playoff/settings.py | 31 ++++++++++++ jfr_playoff/sql.py | 34 +++++++++++++ jfr_playoff/template.py | 128 ++++++++++++++++++++++++++++++++++++++++++++++++ playoff.py | 8 +-- playoff/__init__.py | 0 playoff/db.py | 19 ------- playoff/settings.py | 31 ------------ playoff/sql.py | 34 ------------- playoff/template.py | 128 ------------------------------------------------ 11 files changed, 216 insertions(+), 216 deletions(-) create mode 100644 jfr_playoff/__init__.py create mode 100644 jfr_playoff/db.py create mode 100644 jfr_playoff/settings.py create mode 100644 jfr_playoff/sql.py create mode 100644 jfr_playoff/template.py delete mode 100644 playoff/__init__.py delete mode 100644 playoff/db.py delete mode 100644 playoff/settings.py delete mode 100644 playoff/sql.py delete mode 100644 playoff/template.py diff --git a/jfr_playoff/__init__.py b/jfr_playoff/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/jfr_playoff/db.py b/jfr_playoff/db.py new file mode 100644 index 0000000..aa0c2e2 --- /dev/null +++ b/jfr_playoff/db.py @@ -0,0 +1,19 @@ +import mysql.connector + +class PlayoffDB(object): + + db_cursor = None + + def __init__(self, settings): + self.database = mysql.connector.connect( + user=settings['user'], + password=settings['pass'], + host=settings['host'], + port=settings['port'] + ) + self.db_cursor = self.database.cursor(buffered=True) + + def fetch(self, db, sql, params): + self.db_cursor.execute(sql.replace('#db#', db), params) + row = self.db_cursor.fetchone() + return row diff --git a/jfr_playoff/settings.py b/jfr_playoff/settings.py new file mode 100644 index 0000000..dd7399d --- /dev/null +++ b/jfr_playoff/settings.py @@ -0,0 +1,31 @@ +import glob, json, os, readline, sys + +def complete_filename(text, state): + return (glob.glob(text+'*')+[None])[state] + +class PlayoffSettings: + + def __init__(self): + self.interactive = False + if len(sys.argv) > 1: + settings_file = sys.argv[1] + else: + self.interactive = True + readline.set_completer_delims(' \t\n;') + readline.parse_and_bind("tab: complete") + readline.set_completer(complete_filename) + settings_file = raw_input('JSON settings file: ') + + if not os.path.exists(settings_file): + raise IOError('Settings file %s not found' % settings_file) + + self.settings = json.load(open(settings_file)) + + def has_section(self, key): + return key in self.settings + + def get(self, *keys): + section = self.settings + for key in keys: + section = section[key] + return section diff --git a/jfr_playoff/sql.py b/jfr_playoff/sql.py new file mode 100644 index 0000000..76ea728 --- /dev/null +++ b/jfr_playoff/sql.py @@ -0,0 +1,34 @@ +MATCH_RESULTS = ''' +SELECT t1.fullname, t2.fullname, matches.carry, matches.vph, matches.vpv, matches.corrh, matches.corrv +FROM #db#.matches matches +JOIN #db#.teams t1 + ON t1.id = #db#.matches.homet +JOIN #db#.teams t2 + ON t2.id = #db#.matches.visit +WHERE matches.tabl = %s AND matches.rnd = %s +''' + +BOARD_COUNT = ''' +SELECT segmentsperround*boardspersegment, SUM(sc1.contract IS NOT NULL AND sc2.contract IS NOT NULL) +FROM #db#.scores sc1 +JOIN #db#.scores sc2 + ON sc1.rnd = sc2.rnd + AND sc1.segment = sc2.segment + AND sc1.tabl = sc2.tabl + AND sc1.board = sc2.board + AND sc1.room = 1 + AND sc2.room = 2 +JOIN #db#.admin +WHERE sc1.tabl = %s AND sc1.rnd = %s +''' + +TOWEL_COUNT = ''' +SELECT #db#.admin.boardspersegment * SUM(#db#.segments.towel > 0) +FROM #db#.segments +JOIN #db#.admin +WHERE #db#.segments.tabl = %s AND #db#.segments.rnd = %s +''' + +PREFIX = ''' +SELECT shortname FROM #db#.admin +''' diff --git a/jfr_playoff/template.py b/jfr_playoff/template.py new file mode 100644 index 0000000..8713ab9 --- /dev/null +++ b/jfr_playoff/template.py @@ -0,0 +1,128 @@ +#encoding=utf-8 + +MATCH_TABLE = ''' + + + + + +%s +
  wynik 
+''' + +MATCH_TEAM_ROW = ''' + + %s  + + + %.1f  + + + +''' + +MATCH_RUNNING = ''' + + +%d + + +''' + +MATCH_GRID = ''' +
+ +%s + +
+''' + +MATCH_GRID_PHASE = ''' + +%s + +''' + +MATCH_GRID_PHASE_RUNNING = ''' + + +%s + + +''' + +MATCH_BOX = ''' +
+%s +
+''' + +LEADERBOARD = ''' + + + + + + + + + + + +%s +
 KLASYFIKACJA KOŃCOWA 
 
 miejsce  drużyna 
+''' + +LEADERBOARD_ROW = ''' + +%d + + %s  %s  + + +''' + +LEADERBOARD_ROW_FLAG = ''' + +''' + +PAGE_HEAD = ''' + + + + + + +%s +%s + + +''' + +PAGE_HEAD_REFRESH = ''' + +''' + +PAGE_BODY = ''' + +%s +%s +%s +%s +''' + +PAGE_BODY_FOOTER = ''' +

 Admin ©Jan Romański'2005, PlayOff ©Michał Klichowicz'2017, strona wygenerowana %s

+''' + +PAGE = ''' + + + +%s + + +%s + + +''' diff --git a/playoff.py b/playoff.py index 8a2a9e3..bb3e141 100644 --- a/playoff.py +++ b/playoff.py @@ -1,10 +1,10 @@ import os, shutil, socket from datetime import datetime from urlparse import urljoin -import playoff.sql as p_sql -import playoff.template as p_temp -from playoff.db import PlayoffDB -from playoff.settings import PlayoffSettings +import jfr_playoff.sql as p_sql +import jfr_playoff.template as p_temp +from jfr_playoff.db import PlayoffDB +from jfr_playoff.settings import PlayoffSettings def get_shortname(fullname, teams): for team in teams: diff --git a/playoff/__init__.py b/playoff/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/playoff/db.py b/playoff/db.py deleted file mode 100644 index aa0c2e2..0000000 --- a/playoff/db.py +++ /dev/null @@ -1,19 +0,0 @@ -import mysql.connector - -class PlayoffDB(object): - - db_cursor = None - - def __init__(self, settings): - self.database = mysql.connector.connect( - user=settings['user'], - password=settings['pass'], - host=settings['host'], - port=settings['port'] - ) - self.db_cursor = self.database.cursor(buffered=True) - - def fetch(self, db, sql, params): - self.db_cursor.execute(sql.replace('#db#', db), params) - row = self.db_cursor.fetchone() - return row diff --git a/playoff/settings.py b/playoff/settings.py deleted file mode 100644 index dd7399d..0000000 --- a/playoff/settings.py +++ /dev/null @@ -1,31 +0,0 @@ -import glob, json, os, readline, sys - -def complete_filename(text, state): - return (glob.glob(text+'*')+[None])[state] - -class PlayoffSettings: - - def __init__(self): - self.interactive = False - if len(sys.argv) > 1: - settings_file = sys.argv[1] - else: - self.interactive = True - readline.set_completer_delims(' \t\n;') - readline.parse_and_bind("tab: complete") - readline.set_completer(complete_filename) - settings_file = raw_input('JSON settings file: ') - - if not os.path.exists(settings_file): - raise IOError('Settings file %s not found' % settings_file) - - self.settings = json.load(open(settings_file)) - - def has_section(self, key): - return key in self.settings - - def get(self, *keys): - section = self.settings - for key in keys: - section = section[key] - return section diff --git a/playoff/sql.py b/playoff/sql.py deleted file mode 100644 index 76ea728..0000000 --- a/playoff/sql.py +++ /dev/null @@ -1,34 +0,0 @@ -MATCH_RESULTS = ''' -SELECT t1.fullname, t2.fullname, matches.carry, matches.vph, matches.vpv, matches.corrh, matches.corrv -FROM #db#.matches matches -JOIN #db#.teams t1 - ON t1.id = #db#.matches.homet -JOIN #db#.teams t2 - ON t2.id = #db#.matches.visit -WHERE matches.tabl = %s AND matches.rnd = %s -''' - -BOARD_COUNT = ''' -SELECT segmentsperround*boardspersegment, SUM(sc1.contract IS NOT NULL AND sc2.contract IS NOT NULL) -FROM #db#.scores sc1 -JOIN #db#.scores sc2 - ON sc1.rnd = sc2.rnd - AND sc1.segment = sc2.segment - AND sc1.tabl = sc2.tabl - AND sc1.board = sc2.board - AND sc1.room = 1 - AND sc2.room = 2 -JOIN #db#.admin -WHERE sc1.tabl = %s AND sc1.rnd = %s -''' - -TOWEL_COUNT = ''' -SELECT #db#.admin.boardspersegment * SUM(#db#.segments.towel > 0) -FROM #db#.segments -JOIN #db#.admin -WHERE #db#.segments.tabl = %s AND #db#.segments.rnd = %s -''' - -PREFIX = ''' -SELECT shortname FROM #db#.admin -''' diff --git a/playoff/template.py b/playoff/template.py deleted file mode 100644 index 8713ab9..0000000 --- a/playoff/template.py +++ /dev/null @@ -1,128 +0,0 @@ -#encoding=utf-8 - -MATCH_TABLE = ''' - - - - - -%s -
  wynik 
-''' - -MATCH_TEAM_ROW = ''' - - %s  - - - %.1f  - - - -''' - -MATCH_RUNNING = ''' - - -%d - - -''' - -MATCH_GRID = ''' -
- -%s - -
-''' - -MATCH_GRID_PHASE = ''' - -%s - -''' - -MATCH_GRID_PHASE_RUNNING = ''' - - -%s - - -''' - -MATCH_BOX = ''' -
-%s -
-''' - -LEADERBOARD = ''' - - - - - - - - - - - -%s -
 KLASYFIKACJA KOŃCOWA 
 
 miejsce  drużyna 
-''' - -LEADERBOARD_ROW = ''' - -%d - - %s  %s  - - -''' - -LEADERBOARD_ROW_FLAG = ''' - -''' - -PAGE_HEAD = ''' - - - - - - -%s -%s - - -''' - -PAGE_HEAD_REFRESH = ''' - -''' - -PAGE_BODY = ''' - -%s -%s -%s -%s -''' - -PAGE_BODY_FOOTER = ''' -

 Admin ©Jan Romański'2005, PlayOff ©Michał Klichowicz'2017, strona wygenerowana %s

-''' - -PAGE = ''' - - - -%s - - -%s - - -''' -- cgit v1.2.3 From b1bf9357d573fe4a03d98ea1da7e01c292233c5d Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 00:38:10 +0200 Subject: File and Goniec operations moved to separate class --- jfr_playoff/filemanager.py | 47 ++++++++++++++++++++++++++++++++++++++++++++++ playoff.py | 36 +++++------------------------------ 2 files changed, 52 insertions(+), 31 deletions(-) create mode 100644 jfr_playoff/filemanager.py diff --git a/jfr_playoff/filemanager.py b/jfr_playoff/filemanager.py new file mode 100644 index 0000000..64ac6d9 --- /dev/null +++ b/jfr_playoff/filemanager.py @@ -0,0 +1,47 @@ +import os, shutil, socket +import __main__ + +class PlayoffFileManager(object): + + def __init__(self, settings): + self.settings = settings + self.goniec = self.settings.get('goniec') + self.output_file = self.settings.get('output') + self.output_path = os.path.dirname(self.output_file).strip(os.sep) + os.sep + self.files = set() + + def reset(self): + self.files.empty() + + def register_file(self, path): + if path.startswith(self.output_path): + self.files.add(path.replace(self.output_path, '')) + + + def write_content(self, content): + output = open(self.output_file, 'w') + output.write(content.encode('utf8')) + output.close() + self.register_file(self.output_file) + return self.output_file + + def copy_scripts(self, script_path='sklady/playoff.js'): + script_output_path = os.path.join(self.output_path, script_path) + shutil.copy( + unicode(os.path.join(os.path.dirname(__main__.__file__), 'playoff.js')), + unicode(script_output_path) + ) + self.register_file(script_output_path) + return script_output_path + + def send_files(self): + if self.goniec['enabled']: + try: + content_lines = [self.output_path] + list(self.files) + ['bye', ''] + print '\n'.join(content_lines) + goniec = socket.socket() + goniec.connect((self.goniec['host'], self.goniec['port'])) + goniec.sendall('\n'.join(content_lines)) + goniec.close() + except socket.error: + pass diff --git a/playoff.py b/playoff.py index bb3e141..08b2344 100644 --- a/playoff.py +++ b/playoff.py @@ -1,4 +1,3 @@ -import os, shutil, socket from datetime import datetime from urlparse import urljoin import jfr_playoff.sql as p_sql @@ -233,32 +232,7 @@ def generate_content(grid, phases, match_info, teams, grid_width, grid_height, p ) ) -def write_content(content, output_file): - output = open(output_file, 'w') - output.write(content.encode('utf8')) - output.close() - return os.path.dirname(output_file) - -def copy_scripts(output_path): - script_path = 'sklady/playoff.js' - script_output_path = os.path.join(output_path, script_path) - shutil.copy(unicode(os.path.join(os.path.dirname(__file__), 'playoff.js')), - unicode(script_output_path)) - return script_output_path - -def send_files(goniec_settings, path, files): - if goniec_settings['enabled']: - try: - base_path = path.strip(os.sep) + os.sep - content_files = [filename.replace(base_path, '') for filename in files if filename.startswith(base_path)] - content_lines = [base_path] + content_files + ['bye', ''] - print '\n'.join(content_lines) - goniec = socket.socket() - goniec.connect((goniec_settings['host'], goniec_settings['port'])) - goniec.sendall('\n'.join(content_lines)) - goniec.close() - except socket.error: - pass +from jfr_playoff.filemanager import PlayoffFileManager def main(): s = PlayoffSettings() @@ -277,9 +251,9 @@ def main(): content = generate_content(grid, phase_settings, match_info, s.get('teams'), grid_width, grid_height, page_settings, s.get('canvas') if s.has_section('canvas') else {}, leaderboard) - output_file = s.get('output') - output_path = write_content(content, output_file) - script_path = copy_scripts(output_path) - send_files(s.get('goniec'), output_path, [output_file, script_path]) + file_manager = PlayoffFileManager(s) + file_manager.write_content(content) + file_manager.copy_scripts() + file_manager.send_files() main() -- cgit v1.2.3 From 30c5d797391156b633d5077b8ea120ff61b9a1c4 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 00:49:55 +0200 Subject: Data operations factored out to separate class --- jfr_playoff/data.py | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++ playoff.py | 145 ++----------------------------------------- 2 files changed, 177 insertions(+), 140 deletions(-) create mode 100644 jfr_playoff/data.py diff --git a/jfr_playoff/data.py b/jfr_playoff/data.py new file mode 100644 index 0000000..370a5eb --- /dev/null +++ b/jfr_playoff/data.py @@ -0,0 +1,172 @@ +from urlparse import urljoin +from db import PlayoffDB +import sql as p_sql + +class Team: + name = '' + score = 0.0 + +class Match: + teams = None + running = 0 + link = None + winner = None + loser = None + winner_matches = None + loser_matches = None + +class PlayoffData(object): + def __init__(self, settings): + self.settings = settings + self.database = PlayoffDB(self.settings.get('database')) + self.phases = self.settings.get('phases') + self.teams = self.settings.get('teams') + self.match_info = {} + self.leaderboard = [] + + def generate_phases(self): + grid = [] + for phase in self.phases: + phase_count = len(phase['matches']) + if 'dummies' in phase: + phase_count += len(phase['dummies']) + phase_grid = [None] * phase_count + phase_pos = 0 + for match in phase['matches']: + if 'dummies' in phase: + while phase_pos in phase['dummies']: + phase_pos += 1 + phase_grid[phase_pos] = match['id'] + phase_pos += 1 + grid.append(phase_grid) + return grid + + def fill_match_info(self): + self.match_info = {} + for phase in self.phases: + for match in phase['matches']: + self.match_info[match['id']] = self.get_match_info(match) + self.match_info[match['id']].link = phase['link'] if self.match_info[match['id']].link is None else urljoin( + phase['link'], self.match_info[match['id']].link) + return self.match_info + + def get_match_info(self, match): + info = Match() + info.teams = [Team(), Team()] + info.winner_matches = [] + info.loser_matches = [] + for i in range(0, 2): + if 'winner' in match['teams'][i]: + info.winner_matches += match['teams'][i]['winner'] + if 'loser' in match['teams'][i]: + info.loser_matches += match['teams'][i]['loser'] + info.winner_matches = list(set(info.winner_matches)) + info.loser_matches = list(set(info.loser_matches)) + try: + row = self.database.fetch(match['database'], p_sql.PREFIX, ()) + info.link = '%srunda%d.html' % (row[0], match['round']) + except Exception as e: + pass + try: + row = self.database.fetch(match['database'], p_sql.MATCH_RESULTS, (match['table'], match['round'])) + info.teams[0].name = row[0] + info.teams[1].name = row[1] + info.teams[0].score = row[3] + row[5] + info.teams[1].score = row[4] + row[6] + if row[2] > 0: + info.teams[0].score += row[2] + else: + info.teams[1].score -= row[2] + except Exception as e: + for i in range(0, 2): + if isinstance(match['teams'][i], basestring): + info.teams[i].name = match['teams'][i] + elif isinstance(match['teams'][i], list): + info.teams[i].name = '
'.join(match['teams'][i]) + else: + match_teams = [] + if 'winner' in match['teams'][i]: + match_teams += [ + self.match_info[winner_match].winner + for winner_match in match['teams'][i]['winner'] + ] + if 'loser' in match['teams'][i]: + match_teams += [ + self.match_info[loser_match].loser + for loser_match in match['teams'][i]['loser'] + ] + if 'place' in match['teams'][i]: + match_teams += [ + self.teams[place-1][0] + for place in match['teams'][i]['place'] + ] + info.teams[i].name = '
'.join([ + team if team is not None else '??' + for team in match_teams] + ) if len([team for team in match_teams if team is not None]) > 0 else '' + try: + towels = self.database.fetch(match['database'], p_sql.TOWEL_COUNT, (match['table'], match['round'])) + row = [0 if r is None else r for r in self.database.fetch(match['database'], p_sql.BOARD_COUNT, (match['table'], match['round']))] + if row[1] > 0: + info.running = int(row[1]) + if row[1] >= row[0] - towels[0]: + info.running = 0 + info.winner = info.teams[0].name if info.teams[0].score > info.teams[1].score else info.teams[1].name + info.loser = info.teams[1].name if info.teams[0].score > info.teams[1].score else info.teams[0].name + except Exception as e: + pass + return info + + def prefill_leaderboard(self, teams): + self.leaderboard = [None] * len(teams) + for team in teams: + if len(team) > 3: + self.leaderboard[team[3]-1] = team[0] + return self.leaderboard + + def fill_leaderboard(self): + self.prefill_leaderboard(self.teams) + leaderboard_teams = {} + for phase in self.phases: + for match in phase['matches']: + if 'winner' in match: + winner_key = tuple(match['winner']) + if winner_key not in leaderboard_teams: + leaderboard_teams[winner_key] = [] + leaderboard_teams[winner_key].append(self.match_info[match['id']].winner) + if 'loser' in match: + loser_key = tuple(match['loser']) + if loser_key not in leaderboard_teams: + leaderboard_teams[loser_key] = [] + leaderboard_teams[loser_key].append(self.match_info[match['id']].loser) + for positions, position_teams in leaderboard_teams.iteritems(): + positions = list(positions) + if len(positions) == len([team for team in position_teams if team is not None]): + for table_team in self.teams: + if table_team[0] in position_teams: + position = positions.pop(0) + self.leaderboard[position-1] = table_team[0] + return self.leaderboard + + def get_dimensions(self): + return ( + len(self.phases), + max([ + len(phase['matches']) + len(phase['dummies']) + if 'dummies' in phase + else len(phase['matches']) + for phase in self.phases + ]) + ) + + def get_shortname(self, fullname): + for team in self.teams: + if team[0] == fullname: + return team[1] + return fullname + + def get_team_image(self, fullname): + for team in self.teams: + if team[0] == fullname and len(team) > 2: + return team[2] + return None diff --git a/playoff.py b/playoff.py index 08b2344..0043e03 100644 --- a/playoff.py +++ b/playoff.py @@ -1,8 +1,6 @@ from datetime import datetime from urlparse import urljoin -import jfr_playoff.sql as p_sql import jfr_playoff.template as p_temp -from jfr_playoff.db import PlayoffDB from jfr_playoff.settings import PlayoffSettings def get_shortname(fullname, teams): @@ -83,140 +81,6 @@ def get_leaderboard_table(leaderboard, teams): html = p_temp.LEADERBOARD.decode('utf8') % (rows) return html -class Team: - name = '' - score = 0.0 - -class Match: - teams = None - running = 0 - link = None - winner = None - loser = None - winner_matches = None - loser_matches = None - -def get_match_info(match, match_info, teams, db): - info = Match() - info.teams = [Team(), Team()] - info.winner_matches = [] - info.loser_matches = [] - for i in range(0, 2): - if 'winner' in match['teams'][i]: - info.winner_matches += match['teams'][i]['winner'] - if 'loser' in match['teams'][i]: - info.loser_matches += match['teams'][i]['loser'] - info.winner_matches = list(set(info.winner_matches)) - info.loser_matches = list(set(info.loser_matches)) - try: - row = db.fetch(match['database'], p_sql.PREFIX, ()) - info.link = '%srunda%d.html' % (row[0], match['round']) - except Exception as e: - pass - try: - row = db.fetch(match['database'], p_sql.MATCH_RESULTS, (match['table'], match['round'])) - info.teams[0].name = row[0] - info.teams[1].name = row[1] - info.teams[0].score = row[3] + row[5] - info.teams[1].score = row[4] + row[6] - if row[2] > 0: - info.teams[0].score += row[2] - else: - info.teams[1].score -= row[2] - except Exception as e: - for i in range(0, 2): - if isinstance(match['teams'][i], basestring): - info.teams[i].name = match['teams'][i] - elif isinstance(match['teams'][i], list): - info.teams[i].name = '
'.join(match['teams'][i]) - else: - match_teams = [] - if 'winner' in match['teams'][i]: - match_teams += [ - match_info[winner_match].winner - for winner_match in match['teams'][i]['winner'] - ] - if 'loser' in match['teams'][i]: - match_teams += [ - match_info[loser_match].loser - for loser_match in match['teams'][i]['loser'] - ] - if 'place' in match['teams'][i]: - match_teams += [ - teams[place-1][0] - for place in match['teams'][i]['place'] - ] - info.teams[i].name = '
'.join([ - team if team is not None else '??' - for team in match_teams] - ) if len([team for team in match_teams if team is not None]) > 0 else '' - - try: - towels = db.fetch(match['database'], p_sql.TOWEL_COUNT, (match['table'], match['round'])) - row = [0 if r is None else r for r in db.fetch(match['database'], p_sql.BOARD_COUNT, (match['table'], match['round']))] - if row[1] > 0: - info.running = int(row[1]) - if row[1] >= row[0] - towels[0]: - info.running = 0 - info.winner = info.teams[0].name if info.teams[0].score > info.teams[1].score else info.teams[1].name - info.loser = info.teams[1].name if info.teams[0].score > info.teams[1].score else info.teams[0].name - except Exception as e: - pass - return info - -def generate_phases(phases): - grid = [] - for phase in phases: - phase_grid = [None] * (len(phase['dummies']) + len(phase['matches']) if 'dummies' in phase else len(phase['matches'])) - phase_pos = 0 - for match in phase['matches']: - if 'dummies' in phase: - while phase_pos in phase['dummies']: - phase_pos += 1 - phase_grid[phase_pos] = match['id'] - phase_pos += 1 - grid.append(phase_grid) - return grid - -def fill_match_info(phases, teams, db): - match_info = {} - for phase in phases: - for match in phase['matches']: - match_info[match['id']] = get_match_info(match, match_info, teams, db) - match_info[match['id']].link = phase['link'] if match_info[match['id']].link is None else urljoin(phase['link'], match_info[match['id']].link) - return match_info - -def prefill_leaderboard(teams): - leaderboard = [None] * len(teams) - for team in teams: - if len(team) > 3: - leaderboard[team[3]-1] = team[0] - return leaderboard - -def fill_leaderboard(phases, teams, match_info): - leaderboard_teams = {} - leaderboard = prefill_leaderboard(teams) - for phase in phases: - for match in phase['matches']: - if 'winner' in match: - winner_key = tuple(match['winner']) - if winner_key not in leaderboard_teams: - leaderboard_teams[winner_key] = [] - leaderboard_teams[winner_key].append(match_info[match['id']].winner) - if 'loser' in match: - loser_key = tuple(match['loser']) - if loser_key not in leaderboard_teams: - leaderboard_teams[loser_key] = [] - leaderboard_teams[loser_key].append(match_info[match['id']].loser) - - for positions, teams in leaderboard_teams.iteritems(): - positions = list(positions) - if len(positions) == len([team for team in teams if team is not None]): - for table_team in teams: - if table_team[0] in teams: - position = positions.pop(0) - leaderboard[position-1] = table_team[0] - return leaderboard def generate_content(grid, phases, match_info, teams, grid_width, grid_height, page_settings, canvas_settings, leaderboard): return p_temp.PAGE % ( @@ -236,12 +100,13 @@ from jfr_playoff.filemanager import PlayoffFileManager def main(): s = PlayoffSettings() - db = PlayoffDB(s.get('database')) phase_settings = s.get('phases') - grid = generate_phases(phase_settings) - match_info = fill_match_info(phase_settings, s.get('teams'), db) - leaderboard = fill_leaderboard(phase_settings, s.get('teams'), match_info) + from jfr_playoff.data import PlayoffData + data = PlayoffData(s) + grid = data.generate_phases() + match_info = data.fill_match_info() + leaderboard = data.fill_leaderboard() page_settings = s.get('page') grid_columns = len(phase_settings) -- cgit v1.2.3 From 86b6207e42a61b18318ac7ef34eb603df740db04 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 00:50:52 +0200 Subject: HTML content generation factored out to separate class --- jfr_playoff/generator.py | 103 ++++++++++++++++++++++++++++++++++++++++++ playoff.py | 114 ++--------------------------------------------- 2 files changed, 106 insertions(+), 111 deletions(-) create mode 100644 jfr_playoff/generator.py diff --git a/jfr_playoff/generator.py b/jfr_playoff/generator.py new file mode 100644 index 0000000..80405cd --- /dev/null +++ b/jfr_playoff/generator.py @@ -0,0 +1,103 @@ +from datetime import datetime +import template as p_temp +from data import PlayoffData + +class PlayoffGenerator(object): + def __init__(self, settings): + self.settings = settings + self.data = PlayoffData(self.settings) + self.page = self.settings.get('page') + self.canvas = {} + if self.settings.has_section('canvas'): + self.canvas = self.settings.get('canvas') + + def generate_content(self): + return p_temp.PAGE % ( + p_temp.PAGE_HEAD % ( + p_temp.PAGE_HEAD_REFRESH % (self.page['refresh']) if self.page['refresh'] > 0 else '', + self.page['title'] + ), + p_temp.PAGE_BODY % ( + self.page['logoh'], + self.get_match_grid(self.data.get_dimensions(), self.data.generate_phases(), self.data.fill_match_info()), + self.get_leaderboard_table(self.data.fill_leaderboard()), + p_temp.PAGE_BODY_FOOTER.decode('utf8') % (datetime.now().strftime('%Y-%m-%d o %H:%M')) + ) + ) + + def get_match_table(self, match): + rows = '' + for team in match.teams: + rows += p_temp.MATCH_TEAM_ROW % ( + ' '.join(['winner' if team.name == match.winner else '', + 'loser' if team.name == match.loser else '']).strip(), + match.link, + team.name, + ' / '.join([self.data.get_shortname(name) for name in team.name.split('
')]), + match.link, + team.score + ) + html = p_temp.MATCH_TABLE.decode('utf8') % ( + int(self.page['width'] * 0.75), + int(self.page['width'] * 0.25), + rows + ) + if match.running > 0: + html += p_temp.MATCH_RUNNING % (match.link, match.running) + return html + + def get_match_grid(self, dimensions, grid, matches): + grid_width = dimensions[0] * ( + self.page['width'] + self.page['margin'] + ) - self.page['margin'] + grid_height = dimensions[1] * ( + self.page['height'] + self.page['margin'] + ) - self.page['margin'] + grid_boxes = '' + col_no = 0 + for column in grid: + grid_x = col_no * (self.page['width'] + self.page['margin']) + grid_header = p_temp.MATCH_GRID_PHASE_RUNNING if len([ + match for match in column if match is not None and matches[match].running > 0 + ]) > 0 else p_temp.MATCH_GRID_PHASE + grid_boxes += grid_header % ( + self.settings.get('phases', col_no, 'link'), + self.page['width'], + grid_x, + self.settings.get('phases', col_no, 'title') + ) + row_no = 0 + column_height = grid_height / len(column) + for match in column: + grid_y = int(row_no * column_height + 0.5 * (column_height - self.page['height'])) + if match is not None: + grid_boxes += p_temp.MATCH_BOX % ( + grid_x, grid_y, + match, + ' '.join([str(m) for m in matches[match].winner_matches]) if matches[match].winner_matches is not None else '', + ' '.join([str(m) for m in matches[match].loser_matches]) if matches[match].loser_matches is not None else '', + self.get_match_table(matches[match]) + ) + row_no += 1 + col_no += 1 + canvas_attrs = [] + for setting, value in self.canvas.iteritems(): + canvas_attrs.append( + 'data-%s="%s"' % (setting.replace('_', '-'), str(value)) + ) + return p_temp.MATCH_GRID % (grid_width, grid_height, grid_width, grid_height, ' '.join(canvas_attrs), grid_boxes) + + def get_leaderboard_table(self, leaderboard): + if len([t for t in leaderboard if t is not None]) == 0: + return '' + position = 1 + rows = '' + for team in leaderboard: + rows += p_temp.LEADERBOARD_ROW % (position, self.get_flag(team), team or '') + position +=1 + html = p_temp.LEADERBOARD.decode('utf8') % (rows) + return html + + def get_flag(self, team): + flag = self.data.get_team_image(team) + return '' if flag is None else p_temp.LEADERBOARD_ROW_FLAG % (flag) diff --git a/playoff.py b/playoff.py index 0043e03..2049532 100644 --- a/playoff.py +++ b/playoff.py @@ -1,120 +1,12 @@ -from datetime import datetime -from urlparse import urljoin -import jfr_playoff.template as p_temp from jfr_playoff.settings import PlayoffSettings - -def get_shortname(fullname, teams): - for team in teams: - if team[0] == fullname: - return team[1] - return fullname - -def get_team_image(fullname, teams): - for team in teams: - if team[0] == fullname and len(team) > 2: - if team[2] is not None: - return p_temp.LEADERBOARD_ROW_FLAG % (team[2]) - return '' - -def get_match_table(match, teams, page_settings): - rows = '' - for team in match.teams: - rows += p_temp.MATCH_TEAM_ROW % ( - ' '.join(['winner' if team.name == match.winner else '', - 'loser' if team.name == match.loser else '']).strip(), - match.link, - team.name, - ' / '.join([get_shortname(name, teams) for name in team.name.split('
')]), - match.link, - team.score - ) - html = p_temp.MATCH_TABLE.decode('utf8') % ( - int(page_settings['width'] * 0.75), - int(page_settings['width'] * 0.25), - rows - ) - if match.running > 0: - html += p_temp.MATCH_RUNNING % (match.link, match.running) - return html - -def get_match_grid(grid, phases, matches, page_settings, width, height, teams, canvas_settings): - grid_boxes = '' - col_no = 0 - for column in grid: - grid_x = col_no * (page_settings['width'] + page_settings['margin']) - grid_header = p_temp.MATCH_GRID_PHASE_RUNNING if len([match for match in column if match is not None and matches[match].running > 0]) > 0 else p_temp.MATCH_GRID_PHASE - grid_boxes += grid_header % ( - phases[col_no]['link'], - page_settings['width'], - grid_x, - phases[col_no]['title'] - ) - row_no = 0 - column_height = height / len(column) - for match in column: - grid_y = int(row_no * column_height + 0.5 * (column_height - page_settings['height'])) - if match is not None: - grid_boxes += p_temp.MATCH_BOX % ( - grid_x, grid_y, - match, - ' '.join([str(m) for m in matches[match].winner_matches]) if matches[match].winner_matches is not None else '', - ' '.join([str(m) for m in matches[match].loser_matches]) if matches[match].loser_matches is not None else '', - get_match_table(matches[match], teams, page_settings) - ) - row_no += 1 - col_no += 1 - canvas_attrs = [] - for setting, value in canvas_settings.iteritems(): - canvas_attrs.append( - 'data-%s="%s"' % (setting.replace('_', '-'), str(value)) - ) - return p_temp.MATCH_GRID % (width, height, width, height, ' '.join(canvas_attrs), grid_boxes) - -def get_leaderboard_table(leaderboard, teams): - if len([t for t in leaderboard if t is not None]) == 0: - return '' - position = 1 - rows = '' - for team in leaderboard: - rows += p_temp.LEADERBOARD_ROW % (position, get_team_image(team, teams), team or '') - position +=1 - html = p_temp.LEADERBOARD.decode('utf8') % (rows) - return html - - -def generate_content(grid, phases, match_info, teams, grid_width, grid_height, page_settings, canvas_settings, leaderboard): - return p_temp.PAGE % ( - p_temp.PAGE_HEAD % ( - p_temp.PAGE_HEAD_REFRESH % (page_settings['refresh']) if page_settings['refresh'] > 0 else '', - page_settings['title'] - ), - p_temp.PAGE_BODY % ( - page_settings['logoh'], - get_match_grid(grid, phases, match_info, page_settings, grid_width, grid_height, teams, canvas_settings), - get_leaderboard_table(leaderboard, teams), - p_temp.PAGE_BODY_FOOTER.decode('utf8') % (datetime.now().strftime('%Y-%m-%d o %H:%M')) - ) - ) - +from jfr_playoff.generator import PlayoffGenerator from jfr_playoff.filemanager import PlayoffFileManager def main(): s = PlayoffSettings() - phase_settings = s.get('phases') - from jfr_playoff.data import PlayoffData - data = PlayoffData(s) - grid = data.generate_phases() - match_info = data.fill_match_info() - leaderboard = data.fill_leaderboard() - - page_settings = s.get('page') - grid_columns = len(phase_settings) - grid_rows = max([len(phase['matches']) + len(phase['dummies']) if 'dummies' in phase else len(phase['matches']) for phase in phase_settings]) - grid_height = grid_rows * (page_settings['height'] + page_settings['margin']) - page_settings['margin'] - grid_width = grid_columns * (page_settings['width'] + page_settings['margin']) - page_settings['margin'] - - content = generate_content(grid, phase_settings, match_info, s.get('teams'), grid_width, grid_height, page_settings, s.get('canvas') if s.has_section('canvas') else {}, leaderboard) + generator = PlayoffGenerator(s) + content = generator.generate_content() file_manager = PlayoffFileManager(s) file_manager.write_content(content) -- cgit v1.2.3 From 66fab46d7edc0c20d0c74c74daca70d022f9a5c6 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 01:25:10 +0200 Subject: main() called only if playoff.py is an entry script --- playoff.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/playoff.py b/playoff.py index 2049532..83d3dc3 100644 --- a/playoff.py +++ b/playoff.py @@ -13,4 +13,5 @@ def main(): file_manager.copy_scripts() file_manager.send_files() -main() +if __name__ == '__main__': + main() -- cgit v1.2.3 From 316abb20f7262efc3dd006d65429dfa9e8226c9c Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 01:25:32 +0200 Subject: Waiting for key input in interactive mode --- playoff.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/playoff.py b/playoff.py index 83d3dc3..b04cade 100644 --- a/playoff.py +++ b/playoff.py @@ -13,5 +13,8 @@ def main(): file_manager.copy_scripts() file_manager.send_files() + if s.interactive: + raw_input('Press any key to continue...') + if __name__ == '__main__': main() -- cgit v1.2.3 From 437666456efe3d3088838855989bc9f876531d98 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 01:35:43 +0200 Subject: Error handling in interactive mode does not abort key input confirmation --- jfr_playoff/settings.py | 15 +++++++++------ playoff.py | 23 ++++++++++++++--------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/jfr_playoff/settings.py b/jfr_playoff/settings.py index dd7399d..d81d8a8 100644 --- a/jfr_playoff/settings.py +++ b/jfr_playoff/settings.py @@ -7,24 +7,27 @@ class PlayoffSettings: def __init__(self): self.interactive = False + self.settings_file = None if len(sys.argv) > 1: - settings_file = sys.argv[1] + self.settings_file = sys.argv[1] else: self.interactive = True + + def load(self): + if self.settings_file is None: readline.set_completer_delims(' \t\n;') readline.parse_and_bind("tab: complete") readline.set_completer(complete_filename) - settings_file = raw_input('JSON settings file: ') - - if not os.path.exists(settings_file): - raise IOError('Settings file %s not found' % settings_file) + self.settings_file = raw_input('JSON settings file: ') - self.settings = json.load(open(settings_file)) + self.settings = json.load(open(self.settings_file)) def has_section(self, key): + self.load() return key in self.settings def get(self, *keys): + self.load() section = self.settings for key in keys: section = section[key] diff --git a/playoff.py b/playoff.py index b04cade..59038f8 100644 --- a/playoff.py +++ b/playoff.py @@ -1,20 +1,25 @@ +import traceback from jfr_playoff.settings import PlayoffSettings from jfr_playoff.generator import PlayoffGenerator from jfr_playoff.filemanager import PlayoffFileManager def main(): - s = PlayoffSettings() - generator = PlayoffGenerator(s) - content = generator.generate_content() + try: + s = PlayoffSettings() - file_manager = PlayoffFileManager(s) - file_manager.write_content(content) - file_manager.copy_scripts() - file_manager.send_files() + generator = PlayoffGenerator(s) + content = generator.generate_content() - if s.interactive: - raw_input('Press any key to continue...') + file_manager = PlayoffFileManager(s) + file_manager.write_content(content) + file_manager.copy_scripts() + file_manager.send_files() + except: + print traceback.format_exc() + finally: + if s.interactive: + raw_input('Press any key to continue...') if __name__ == '__main__': main() -- cgit v1.2.3 From 022f2cc6d067769a6c8e56601c0238aac69ec9ab Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 01:37:21 +0200 Subject: Load config file only once --- jfr_playoff/settings.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jfr_playoff/settings.py b/jfr_playoff/settings.py index d81d8a8..e69b1d3 100644 --- a/jfr_playoff/settings.py +++ b/jfr_playoff/settings.py @@ -6,6 +6,7 @@ def complete_filename(text, state): class PlayoffSettings: def __init__(self): + self.settings = None self.interactive = False self.settings_file = None if len(sys.argv) > 1: @@ -20,7 +21,8 @@ class PlayoffSettings: readline.set_completer(complete_filename) self.settings_file = raw_input('JSON settings file: ') - self.settings = json.load(open(self.settings_file)) + if self.settings is None: + self.settings = json.load(open(self.settings_file)) def has_section(self, key): self.load() -- cgit v1.2.3 From c2cdc9bdab6cbbffa7b825f0277c49f49afac6cf Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 01:46:12 +0200 Subject: Meaningful variable name --- playoff.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/playoff.py b/playoff.py index 59038f8..48da011 100644 --- a/playoff.py +++ b/playoff.py @@ -6,19 +6,19 @@ from jfr_playoff.filemanager import PlayoffFileManager def main(): try: - s = PlayoffSettings() + settings = PlayoffSettings() - generator = PlayoffGenerator(s) + generator = PlayoffGenerator(settings) content = generator.generate_content() - file_manager = PlayoffFileManager(s) + file_manager = PlayoffFileManager(settings) file_manager.write_content(content) file_manager.copy_scripts() file_manager.send_files() except: print traceback.format_exc() finally: - if s.interactive: + if settings.interactive: raw_input('Press any key to continue...') if __name__ == '__main__': -- cgit v1.2.3 From ab1a44e39152f11560f7e0e823708914ca181e73 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 02:25:38 +0200 Subject: Match info retrieval refactored into separate methods --- jfr_playoff/data.py | 105 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 43 deletions(-) diff --git a/jfr_playoff/data.py b/jfr_playoff/data.py index 370a5eb..5c1ba04 100644 --- a/jfr_playoff/data.py +++ b/jfr_playoff/data.py @@ -1,4 +1,5 @@ from urlparse import urljoin +import mysql from db import PlayoffDB import sql as p_sql @@ -50,9 +51,64 @@ class PlayoffData(object): phase['link'], self.match_info[match['id']].link) return self.match_info + def get_match_link(self, match): + try: + row = self.database.fetch(match['database'], p_sql.PREFIX, ()) + if row is not None: + if len(row) > 0: + return '%srunda%d.html' % (row[0], match['round']) + except mysql.connector.Error: + return None + return None + + def get_db_match_teams(self, match): + teams = [Team(), Team()] + row = self.database.fetch(match['database'], p_sql.MATCH_RESULTS, (match['table'], match['round'])) + teams[0].name = row[0] + teams[1].name = row[1] + teams[0].score = row[3] + row[5] + teams[1].score = row[4] + row[6] + if row[2] > 0: + teams[0].score += row[2] + else: + teams[1].score -= row[2] + return teams + + def get_config_match_teams(self, match): + teams = [Team(), Team()] + for i in range(0, 2): + if isinstance(match['teams'][i], basestring): + teams[i].name = match['teams'][i] + elif isinstance(match['teams'][i], list): + teams[i].name = '
'.join(match['teams'][i]) + else: + match_teams = [] + if 'winner' in match['teams'][i]: + match_teams += [ + self.match_info[winner_match].winner + for winner_match in match['teams'][i]['winner'] + ] + if 'loser' in match['teams'][i]: + match_teams += [ + self.match_info[loser_match].loser + for loser_match in match['teams'][i]['loser'] + ] + if 'place' in match['teams'][i]: + match_teams += [ + self.teams[place-1][0] + for place in match['teams'][i]['place'] + ] + teams[i].name = '
'.join([ + team if team is not None else '??' + for team in match_teams] + ) if len([ + team for team in match_teams if team is not None + ]) > 0 else '' + return teams + + def get_match_info(self, match): info = Match() - info.teams = [Team(), Team()] info.winner_matches = [] info.loser_matches = [] for i in range(0, 2): @@ -62,48 +118,11 @@ class PlayoffData(object): info.loser_matches += match['teams'][i]['loser'] info.winner_matches = list(set(info.winner_matches)) info.loser_matches = list(set(info.loser_matches)) + info.link = self.get_match_link(match) try: - row = self.database.fetch(match['database'], p_sql.PREFIX, ()) - info.link = '%srunda%d.html' % (row[0], match['round']) - except Exception as e: - pass - try: - row = self.database.fetch(match['database'], p_sql.MATCH_RESULTS, (match['table'], match['round'])) - info.teams[0].name = row[0] - info.teams[1].name = row[1] - info.teams[0].score = row[3] + row[5] - info.teams[1].score = row[4] + row[6] - if row[2] > 0: - info.teams[0].score += row[2] - else: - info.teams[1].score -= row[2] - except Exception as e: - for i in range(0, 2): - if isinstance(match['teams'][i], basestring): - info.teams[i].name = match['teams'][i] - elif isinstance(match['teams'][i], list): - info.teams[i].name = '
'.join(match['teams'][i]) - else: - match_teams = [] - if 'winner' in match['teams'][i]: - match_teams += [ - self.match_info[winner_match].winner - for winner_match in match['teams'][i]['winner'] - ] - if 'loser' in match['teams'][i]: - match_teams += [ - self.match_info[loser_match].loser - for loser_match in match['teams'][i]['loser'] - ] - if 'place' in match['teams'][i]: - match_teams += [ - self.teams[place-1][0] - for place in match['teams'][i]['place'] - ] - info.teams[i].name = '
'.join([ - team if team is not None else '??' - for team in match_teams] - ) if len([team for team in match_teams if team is not None]) > 0 else '' + info.teams = self.get_db_match_teams(match) + except (mysql.connector.Error, TypeError, IndexError): + info.teams = self.get_config_match_teams(match) try: towels = self.database.fetch(match['database'], p_sql.TOWEL_COUNT, (match['table'], match['round'])) row = [0 if r is None else r for r in self.database.fetch(match['database'], p_sql.BOARD_COUNT, (match['table'], match['round']))] @@ -113,7 +132,7 @@ class PlayoffData(object): info.running = 0 info.winner = info.teams[0].name if info.teams[0].score > info.teams[1].score else info.teams[1].name info.loser = info.teams[1].name if info.teams[0].score > info.teams[1].score else info.teams[0].name - except Exception as e: + except (mysql.connector.Error, TypeError, KeyError): pass return info -- cgit v1.2.3 From 8e470272fea69a26c7d860c20433c9a0007f0b2e Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 02:27:54 +0200 Subject: DTOs moved to separate submodule --- jfr_playoff/data.py | 14 +------------- jfr_playoff/dto.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 13 deletions(-) create mode 100644 jfr_playoff/dto.py diff --git a/jfr_playoff/data.py b/jfr_playoff/data.py index 5c1ba04..6c3f0ed 100644 --- a/jfr_playoff/data.py +++ b/jfr_playoff/data.py @@ -2,19 +2,7 @@ from urlparse import urljoin import mysql from db import PlayoffDB import sql as p_sql - -class Team: - name = '' - score = 0.0 - -class Match: - teams = None - running = 0 - link = None - winner = None - loser = None - winner_matches = None - loser_matches = None +from dto import * class PlayoffData(object): def __init__(self, settings): diff --git a/jfr_playoff/dto.py b/jfr_playoff/dto.py new file mode 100644 index 0000000..d34b01d --- /dev/null +++ b/jfr_playoff/dto.py @@ -0,0 +1,14 @@ +class Team(object): + name = '' + score = 0.0 + +class Match(object): + teams = None + running = 0 + link = None + winner = None + loser = None + winner_matches = None + loser_matches = None + +__all__ = ['Team', 'Match'] -- cgit v1.2.3 From 904f476b1cb17f83a369e1b03440b00809535fc1 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 02:35:02 +0200 Subject: Playoff phase is now also stored as DTO, arbitrary setting reads factored out of content generator --- jfr_playoff/data.py | 9 ++++++--- jfr_playoff/dto.py | 7 ++++++- jfr_playoff/generator.py | 14 +++++++------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/jfr_playoff/data.py b/jfr_playoff/data.py index 6c3f0ed..2a965d1 100644 --- a/jfr_playoff/data.py +++ b/jfr_playoff/data.py @@ -19,15 +19,18 @@ class PlayoffData(object): phase_count = len(phase['matches']) if 'dummies' in phase: phase_count += len(phase['dummies']) - phase_grid = [None] * phase_count + phase_object = Phase() + phase_object.title = phase['title'] + phase_object.link = phase['link'] + phase_object.matches = [None] * phase_count phase_pos = 0 for match in phase['matches']: if 'dummies' in phase: while phase_pos in phase['dummies']: phase_pos += 1 - phase_grid[phase_pos] = match['id'] + phase_object.matches[phase_pos] = match['id'] phase_pos += 1 - grid.append(phase_grid) + grid.append(phase_object) return grid def fill_match_info(self): diff --git a/jfr_playoff/dto.py b/jfr_playoff/dto.py index d34b01d..9a72a12 100644 --- a/jfr_playoff/dto.py +++ b/jfr_playoff/dto.py @@ -11,4 +11,9 @@ class Match(object): winner_matches = None loser_matches = None -__all__ = ['Team', 'Match'] +class Phase(object): + title = None + link = None + matches = [] + +__all__ = ['Team', 'Match', 'Phase'] diff --git a/jfr_playoff/generator.py b/jfr_playoff/generator.py index 80405cd..81ca6c9 100644 --- a/jfr_playoff/generator.py +++ b/jfr_playoff/generator.py @@ -55,21 +55,21 @@ class PlayoffGenerator(object): ) - self.page['margin'] grid_boxes = '' col_no = 0 - for column in grid: + for phase in grid: grid_x = col_no * (self.page['width'] + self.page['margin']) grid_header = p_temp.MATCH_GRID_PHASE_RUNNING if len([ - match for match in column if match is not None and matches[match].running > 0 + match for match in phase.matches if match is not None and matches[match].running > 0 ]) > 0 else p_temp.MATCH_GRID_PHASE grid_boxes += grid_header % ( - self.settings.get('phases', col_no, 'link'), + phase.link, self.page['width'], grid_x, - self.settings.get('phases', col_no, 'title') + phase.title ) row_no = 0 - column_height = grid_height / len(column) - for match in column: - grid_y = int(row_no * column_height + 0.5 * (column_height - self.page['height'])) + match_height = grid_height / len(phase.matches) + for match in phase.matches: + grid_y = int(row_no * match_height + 0.5 * (match_height - self.page['height'])) if match is not None: grid_boxes += p_temp.MATCH_BOX % ( grid_x, grid_y, -- cgit v1.2.3 From cf11f2639f965c70dd8237580a23e7441c670693 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 02:46:00 +0200 Subject: Fixed set() method --- jfr_playoff/filemanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jfr_playoff/filemanager.py b/jfr_playoff/filemanager.py index 64ac6d9..8dc8b85 100644 --- a/jfr_playoff/filemanager.py +++ b/jfr_playoff/filemanager.py @@ -11,7 +11,7 @@ class PlayoffFileManager(object): self.files = set() def reset(self): - self.files.empty() + self.files.clear() def register_file(self, path): if path.startswith(self.output_path): -- cgit v1.2.3 From 7f76c56ab258c8978c39507eb997852e2280449d Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 02:50:24 +0200 Subject: Code style improved --- jfr_playoff/data.py | 51 +++++++++++++++++++++++++++++++--------------- jfr_playoff/db.py | 7 +++++-- jfr_playoff/filemanager.py | 4 +++- jfr_playoff/generator.py | 48 ++++++++++++++++++++++++++++++++----------- jfr_playoff/settings.py | 7 +++++-- 5 files changed, 84 insertions(+), 33 deletions(-) diff --git a/jfr_playoff/data.py b/jfr_playoff/data.py index 2a965d1..3952c64 100644 --- a/jfr_playoff/data.py +++ b/jfr_playoff/data.py @@ -1,8 +1,8 @@ from urlparse import urljoin import mysql -from db import PlayoffDB -import sql as p_sql -from dto import * +from jfr_playoff.db import PlayoffDB +from jfr_playoff.dto import Team, Match, Phase +import jfr_playoff.sql as p_sql class PlayoffData(object): def __init__(self, settings): @@ -38,8 +38,12 @@ class PlayoffData(object): for phase in self.phases: for match in phase['matches']: self.match_info[match['id']] = self.get_match_info(match) - self.match_info[match['id']].link = phase['link'] if self.match_info[match['id']].link is None else urljoin( - phase['link'], self.match_info[match['id']].link) + if self.match_info[match['id']].link is None: + self.match_info[match['id']].link = phase['link'] + else: + self.match_info[match['id']].link = urljoin( + phase['link'], self.match_info[match['id']].link + ) return self.match_info def get_match_link(self, match): @@ -54,7 +58,10 @@ class PlayoffData(object): def get_db_match_teams(self, match): teams = [Team(), Team()] - row = self.database.fetch(match['database'], p_sql.MATCH_RESULTS, (match['table'], match['round'])) + row = self.database.fetch( + match['database'], p_sql.MATCH_RESULTS, + (match['table'], match['round']) + ) teams[0].name = row[0] teams[1].name = row[1] teams[0].score = row[3] + row[5] @@ -89,12 +96,12 @@ class PlayoffData(object): self.teams[place-1][0] for place in match['teams'][i]['place'] ] - teams[i].name = '
'.join([ - team if team is not None else '??' - for team in match_teams] - ) if len([ - team for team in match_teams if team is not None - ]) > 0 else '' + known_teams = [team for team in match_teams if team is not None] + if len(known_teams) > 0: + teams[i].name = '
'.join([ + team if team is not None else '??' for team in match_teams]) + else: + teams[i].name = '' return teams @@ -115,14 +122,26 @@ class PlayoffData(object): except (mysql.connector.Error, TypeError, IndexError): info.teams = self.get_config_match_teams(match) try: - towels = self.database.fetch(match['database'], p_sql.TOWEL_COUNT, (match['table'], match['round'])) - row = [0 if r is None else r for r in self.database.fetch(match['database'], p_sql.BOARD_COUNT, (match['table'], match['round']))] + towels = self.database.fetch( + match['database'], p_sql.TOWEL_COUNT, + (match['table'], match['round']) + ) + row = [0 if r is None + else r for r in + self.database.fetch( + match['database'], p_sql.BOARD_COUNT, + (match['table'], match['round']) + )] if row[1] > 0: info.running = int(row[1]) if row[1] >= row[0] - towels[0]: info.running = 0 - info.winner = info.teams[0].name if info.teams[0].score > info.teams[1].score else info.teams[1].name - info.loser = info.teams[1].name if info.teams[0].score > info.teams[1].score else info.teams[0].name + if info.teams[0].score > info.teams[1].score: + info.winner = info.teams[0].name + info.loser = info.teams[1].name + else: + info.loser = info.teams[0].name + info.winner = info.teams[1].name except (mysql.connector.Error, TypeError, KeyError): pass return info diff --git a/jfr_playoff/db.py b/jfr_playoff/db.py index aa0c2e2..8457dd4 100644 --- a/jfr_playoff/db.py +++ b/jfr_playoff/db.py @@ -13,7 +13,10 @@ class PlayoffDB(object): ) self.db_cursor = self.database.cursor(buffered=True) - def fetch(self, db, sql, params): - self.db_cursor.execute(sql.replace('#db#', db), params) + def get_cursor(self): + return self.db_cursor + + def fetch(self, db_name, sql, params): + self.db_cursor.execute(sql.replace('#db#', db_name), params) row = self.db_cursor.fetchone() return row diff --git a/jfr_playoff/filemanager.py b/jfr_playoff/filemanager.py index 8dc8b85..06374dd 100644 --- a/jfr_playoff/filemanager.py +++ b/jfr_playoff/filemanager.py @@ -1,4 +1,6 @@ -import os, shutil, socket +import os +import shutil +import socket import __main__ class PlayoffFileManager(object): diff --git a/jfr_playoff/generator.py b/jfr_playoff/generator.py index 81ca6c9..7237c9f 100644 --- a/jfr_playoff/generator.py +++ b/jfr_playoff/generator.py @@ -1,6 +1,6 @@ from datetime import datetime -import template as p_temp -from data import PlayoffData +import jfr_playoff.template as p_temp +from jfr_playoff.data import PlayoffData class PlayoffGenerator(object): def __init__(self, settings): @@ -14,14 +14,22 @@ class PlayoffGenerator(object): def generate_content(self): return p_temp.PAGE % ( p_temp.PAGE_HEAD % ( - p_temp.PAGE_HEAD_REFRESH % (self.page['refresh']) if self.page['refresh'] > 0 else '', + p_temp.PAGE_HEAD_REFRESH % ( + self.page['refresh'] + ) if self.page['refresh'] > 0 else '', self.page['title'] ), p_temp.PAGE_BODY % ( self.page['logoh'], - self.get_match_grid(self.data.get_dimensions(), self.data.generate_phases(), self.data.fill_match_info()), + self.get_match_grid( + self.data.get_dimensions(), + self.data.generate_phases(), + self.data.fill_match_info() + ), self.get_leaderboard_table(self.data.fill_leaderboard()), - p_temp.PAGE_BODY_FOOTER.decode('utf8') % (datetime.now().strftime('%Y-%m-%d o %H:%M')) + p_temp.PAGE_BODY_FOOTER.decode('utf8') % ( + datetime.now().strftime('%Y-%m-%d o %H:%M') + ) ) ) @@ -29,11 +37,16 @@ class PlayoffGenerator(object): rows = '' for team in match.teams: rows += p_temp.MATCH_TEAM_ROW % ( - ' '.join(['winner' if team.name == match.winner else '', - 'loser' if team.name == match.loser else '']).strip(), + ' '.join([ + 'winner' if team.name == match.winner else '', + 'loser' if team.name == match.loser else '' + ]).strip(), match.link, team.name, - ' / '.join([self.data.get_shortname(name) for name in team.name.split('
')]), + ' / '.join([ + self.data.get_shortname(name) for name in + team.name.split('
') + ]), match.link, team.score ) @@ -74,8 +87,14 @@ class PlayoffGenerator(object): grid_boxes += p_temp.MATCH_BOX % ( grid_x, grid_y, match, - ' '.join([str(m) for m in matches[match].winner_matches]) if matches[match].winner_matches is not None else '', - ' '.join([str(m) for m in matches[match].loser_matches]) if matches[match].loser_matches is not None else '', + ' '.join([ + str(m) for m in + matches[match].winner_matches + ]) if matches[match].winner_matches is not None else '', + ' '.join([ + str(m) for m in + matches[match].loser_matches + ]) if matches[match].loser_matches is not None else '', self.get_match_table(matches[match]) ) row_no += 1 @@ -85,7 +104,12 @@ class PlayoffGenerator(object): canvas_attrs.append( 'data-%s="%s"' % (setting.replace('_', '-'), str(value)) ) - return p_temp.MATCH_GRID % (grid_width, grid_height, grid_width, grid_height, ' '.join(canvas_attrs), grid_boxes) + return p_temp.MATCH_GRID % ( + grid_width, grid_height, + grid_width, grid_height, + ' '.join(canvas_attrs), + grid_boxes + ) def get_leaderboard_table(self, leaderboard): if len([t for t in leaderboard if t is not None]) == 0: @@ -94,7 +118,7 @@ class PlayoffGenerator(object): rows = '' for team in leaderboard: rows += p_temp.LEADERBOARD_ROW % (position, self.get_flag(team), team or '') - position +=1 + position += 1 html = p_temp.LEADERBOARD.decode('utf8') % (rows) return html diff --git a/jfr_playoff/settings.py b/jfr_playoff/settings.py index e69b1d3..3ed1774 100644 --- a/jfr_playoff/settings.py +++ b/jfr_playoff/settings.py @@ -1,9 +1,12 @@ -import glob, json, os, readline, sys +import glob +import json +import readline +import sys def complete_filename(text, state): return (glob.glob(text+'*')+[None])[state] -class PlayoffSettings: +class PlayoffSettings(object): def __init__(self): self.settings = None -- cgit v1.2.3 From ca21319b59b3188582b70a78965729b9131dd409 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 13:41:27 +0200 Subject: Additional properties in DTOs --- jfr_playoff/data.py | 12 +++++++++--- jfr_playoff/dto.py | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/jfr_playoff/data.py b/jfr_playoff/data.py index 3952c64..997b038 100644 --- a/jfr_playoff/data.py +++ b/jfr_playoff/data.py @@ -10,11 +10,12 @@ class PlayoffData(object): self.database = PlayoffDB(self.settings.get('database')) self.phases = self.settings.get('phases') self.teams = self.settings.get('teams') + self.grid = [] self.match_info = {} self.leaderboard = [] def generate_phases(self): - grid = [] + self.grid = [] for phase in self.phases: phase_count = len(phase['matches']) if 'dummies' in phase: @@ -30,14 +31,18 @@ class PlayoffData(object): phase_pos += 1 phase_object.matches[phase_pos] = match['id'] phase_pos += 1 - grid.append(phase_object) - return grid + self.grid.append(phase_object) + return self.grid def fill_match_info(self): self.match_info = {} for phase in self.phases: for match in phase['matches']: self.match_info[match['id']] = self.get_match_info(match) + if self.match_info[match['id']].running > 0: + for phase_obj in self.grid: + if match['id'] in phase_obj.matches: + phase_obj.running = True if self.match_info[match['id']].link is None: self.match_info[match['id']].link = phase['link'] else: @@ -107,6 +112,7 @@ class PlayoffData(object): def get_match_info(self, match): info = Match() + info.id = match['id'] info.winner_matches = [] info.loser_matches = [] for i in range(0, 2): diff --git a/jfr_playoff/dto.py b/jfr_playoff/dto.py index 9a72a12..bf3e16a 100644 --- a/jfr_playoff/dto.py +++ b/jfr_playoff/dto.py @@ -3,6 +3,7 @@ class Team(object): score = 0.0 class Match(object): + id = None teams = None running = 0 link = None @@ -15,5 +16,6 @@ class Phase(object): title = None link = None matches = [] + running = False __all__ = ['Team', 'Match', 'Phase'] -- cgit v1.2.3 From dcedfd436f73e73ed425ce7f6ac4ceacfc26cbb6 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 13:41:46 +0200 Subject: Refactoring match grid generation --- jfr_playoff/generator.py | 86 ++++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/jfr_playoff/generator.py b/jfr_playoff/generator.py index 7237c9f..7b9760e 100644 --- a/jfr_playoff/generator.py +++ b/jfr_playoff/generator.py @@ -59,55 +59,63 @@ class PlayoffGenerator(object): html += p_temp.MATCH_RUNNING % (match.link, match.running) return html + def get_phase_header(self, phase, position): + if phase.running: + grid_header = p_temp.MATCH_GRID_PHASE_RUNNING + else: + grid_header = p_temp.MATCH_GRID_PHASE + return grid_header % ( + phase.link, + self.page['width'], + position, + phase.title + ) + + def get_match_box(self, match, position): + if match is not None: + return p_temp.MATCH_BOX % ( + position[0], position[1], + match.id, + ' '.join([ + str(m) for m in match.winner_matches + ]) if match.winner_matches is not None else '', + ' '.join([ + str(m) for m in match.loser_matches + ]) if match.loser_matches is not None else '', + self.get_match_table(match) + ) + return '' + def get_match_grid(self, dimensions, grid, matches): - grid_width = dimensions[0] * ( - self.page['width'] + self.page['margin'] - ) - self.page['margin'] - grid_height = dimensions[1] * ( - self.page['height'] + self.page['margin'] - ) - self.page['margin'] + canvas_size = ( + dimensions[0] * ( + self.page['width'] + self.page['margin'] + ) - self.page['margin'], + dimensions[1] * ( + self.page['height'] + self.page['margin'] + ) - self.page['margin'] + ) grid_boxes = '' col_no = 0 for phase in grid: grid_x = col_no * (self.page['width'] + self.page['margin']) - grid_header = p_temp.MATCH_GRID_PHASE_RUNNING if len([ - match for match in phase.matches if match is not None and matches[match].running > 0 - ]) > 0 else p_temp.MATCH_GRID_PHASE - grid_boxes += grid_header % ( - phase.link, - self.page['width'], - grid_x, - phase.title - ) + grid_boxes += self.get_phase_header(phase, grid_x) + match_height = canvas_size[1] / len(phase.matches) row_no = 0 - match_height = grid_height / len(phase.matches) for match in phase.matches: - grid_y = int(row_no * match_height + 0.5 * (match_height - self.page['height'])) - if match is not None: - grid_boxes += p_temp.MATCH_BOX % ( - grid_x, grid_y, - match, - ' '.join([ - str(m) for m in - matches[match].winner_matches - ]) if matches[match].winner_matches is not None else '', - ' '.join([ - str(m) for m in - matches[match].loser_matches - ]) if matches[match].loser_matches is not None else '', - self.get_match_table(matches[match]) - ) + grid_y = int(row_no * match_height + + 0.5 * (match_height - self.page['height'])) + grid_boxes += self.get_match_box( + matches[match] if match is not None else None, + (grid_x, grid_y)) row_no += 1 col_no += 1 - canvas_attrs = [] - for setting, value in self.canvas.iteritems(): - canvas_attrs.append( - 'data-%s="%s"' % (setting.replace('_', '-'), str(value)) - ) return p_temp.MATCH_GRID % ( - grid_width, grid_height, - grid_width, grid_height, - ' '.join(canvas_attrs), + canvas_size[0], canvas_size[1], + canvas_size[0], canvas_size[1], + ' '.join(['data-%s="%s"' % ( + setting.replace('_', '-'), str(value) + ) for setting, value in self.canvas.iteritems()]), grid_boxes ) -- cgit v1.2.3 From 126729817b8626a597b61bcc59f8a6441e480691 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 13:42:49 +0200 Subject: Import sort in all files --- jfr_playoff/data.py | 7 +++++-- jfr_playoff/db.py | 1 + jfr_playoff/filemanager.py | 2 ++ jfr_playoff/generator.py | 2 ++ jfr_playoff/settings.py | 1 + playoff.py | 6 ++++-- 6 files changed, 15 insertions(+), 4 deletions(-) diff --git a/jfr_playoff/data.py b/jfr_playoff/data.py index 997b038..b54d1ae 100644 --- a/jfr_playoff/data.py +++ b/jfr_playoff/data.py @@ -1,8 +1,11 @@ from urlparse import urljoin + import mysql -from jfr_playoff.db import PlayoffDB -from jfr_playoff.dto import Team, Match, Phase + import jfr_playoff.sql as p_sql +from jfr_playoff.db import PlayoffDB +from jfr_playoff.dto import Match, Phase, Team + class PlayoffData(object): def __init__(self, settings): diff --git a/jfr_playoff/db.py b/jfr_playoff/db.py index 8457dd4..19ec2fb 100644 --- a/jfr_playoff/db.py +++ b/jfr_playoff/db.py @@ -1,5 +1,6 @@ import mysql.connector + class PlayoffDB(object): db_cursor = None diff --git a/jfr_playoff/filemanager.py b/jfr_playoff/filemanager.py index 06374dd..2c443b4 100644 --- a/jfr_playoff/filemanager.py +++ b/jfr_playoff/filemanager.py @@ -1,8 +1,10 @@ import os import shutil import socket + import __main__ + class PlayoffFileManager(object): def __init__(self, settings): diff --git a/jfr_playoff/generator.py b/jfr_playoff/generator.py index 7b9760e..e3e8221 100644 --- a/jfr_playoff/generator.py +++ b/jfr_playoff/generator.py @@ -1,7 +1,9 @@ from datetime import datetime + import jfr_playoff.template as p_temp from jfr_playoff.data import PlayoffData + class PlayoffGenerator(object): def __init__(self, settings): self.settings = settings diff --git a/jfr_playoff/settings.py b/jfr_playoff/settings.py index 3ed1774..3b765bc 100644 --- a/jfr_playoff/settings.py +++ b/jfr_playoff/settings.py @@ -3,6 +3,7 @@ import json import readline import sys + def complete_filename(text, state): return (glob.glob(text+'*')+[None])[state] diff --git a/playoff.py b/playoff.py index 48da011..c335b55 100644 --- a/playoff.py +++ b/playoff.py @@ -1,7 +1,9 @@ import traceback -from jfr_playoff.settings import PlayoffSettings -from jfr_playoff.generator import PlayoffGenerator + from jfr_playoff.filemanager import PlayoffFileManager +from jfr_playoff.generator import PlayoffGenerator +from jfr_playoff.settings import PlayoffSettings + def main(): -- cgit v1.2.3 From de7260322d60eeb5fd0afa57ec2e250ce7f52261 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 14:05:59 +0200 Subject: Settings are not used as class attributes once loaded, so can remain local to constructor --- jfr_playoff/data.py | 7 +++---- jfr_playoff/filemanager.py | 9 +++++---- jfr_playoff/generator.py | 9 ++++----- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/jfr_playoff/data.py b/jfr_playoff/data.py index b54d1ae..db65393 100644 --- a/jfr_playoff/data.py +++ b/jfr_playoff/data.py @@ -9,10 +9,9 @@ from jfr_playoff.dto import Match, Phase, Team class PlayoffData(object): def __init__(self, settings): - self.settings = settings - self.database = PlayoffDB(self.settings.get('database')) - self.phases = self.settings.get('phases') - self.teams = self.settings.get('teams') + self.database = PlayoffDB(settings.get('database')) + self.phases = settings.get('phases') + self.teams = settings.get('teams') self.grid = [] self.match_info = {} self.leaderboard = [] diff --git a/jfr_playoff/filemanager.py b/jfr_playoff/filemanager.py index 2c443b4..03dbaf7 100644 --- a/jfr_playoff/filemanager.py +++ b/jfr_playoff/filemanager.py @@ -8,10 +8,11 @@ import __main__ class PlayoffFileManager(object): def __init__(self, settings): - self.settings = settings - self.goniec = self.settings.get('goniec') - self.output_file = self.settings.get('output') - self.output_path = os.path.dirname(self.output_file).strip(os.sep) + os.sep + self.goniec = settings.get('goniec') + self.output_file = settings.get('output') + self.output_path = os.path.dirname( + self.output_file + ).strip(os.sep) + os.sep self.files = set() def reset(self): diff --git a/jfr_playoff/generator.py b/jfr_playoff/generator.py index e3e8221..bc2a388 100644 --- a/jfr_playoff/generator.py +++ b/jfr_playoff/generator.py @@ -6,12 +6,11 @@ from jfr_playoff.data import PlayoffData class PlayoffGenerator(object): def __init__(self, settings): - self.settings = settings - self.data = PlayoffData(self.settings) - self.page = self.settings.get('page') + self.data = PlayoffData(settings) + self.page = settings.get('page') self.canvas = {} - if self.settings.has_section('canvas'): - self.canvas = self.settings.get('canvas') + if settings.has_section('canvas'): + self.canvas = settings.get('canvas') def generate_content(self): return p_temp.PAGE % ( -- cgit v1.2.3 From ca6c87f457f49cf33f357984d7642b1c83a0eefb Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 14:06:25 +0200 Subject: Code formatting --- jfr_playoff/data.py | 38 ++++++++++++++++---------------------- jfr_playoff/db.py | 3 +-- jfr_playoff/dto.py | 4 +++- jfr_playoff/filemanager.py | 11 ++++++----- jfr_playoff/generator.py | 36 +++++++++++++----------------------- jfr_playoff/settings.py | 1 + jfr_playoff/sql.py | 6 ++++-- jfr_playoff/template.py | 2 +- 8 files changed, 45 insertions(+), 56 deletions(-) diff --git a/jfr_playoff/data.py b/jfr_playoff/data.py index db65393..6fc3c4b 100644 --- a/jfr_playoff/data.py +++ b/jfr_playoff/data.py @@ -49,8 +49,7 @@ class PlayoffData(object): self.match_info[match['id']].link = phase['link'] else: self.match_info[match['id']].link = urljoin( - phase['link'], self.match_info[match['id']].link - ) + phase['link'], self.match_info[match['id']].link) return self.match_info def get_match_link(self, match): @@ -67,8 +66,7 @@ class PlayoffData(object): teams = [Team(), Team()] row = self.database.fetch( match['database'], p_sql.MATCH_RESULTS, - (match['table'], match['round']) - ) + (match['table'], match['round'])) teams[0].name = row[0] teams[1].name = row[1] teams[0].score = row[3] + row[5] @@ -91,27 +89,24 @@ class PlayoffData(object): if 'winner' in match['teams'][i]: match_teams += [ self.match_info[winner_match].winner - for winner_match in match['teams'][i]['winner'] - ] + for winner_match in match['teams'][i]['winner']] if 'loser' in match['teams'][i]: match_teams += [ self.match_info[loser_match].loser - for loser_match in match['teams'][i]['loser'] - ] + for loser_match in match['teams'][i]['loser']] if 'place' in match['teams'][i]: match_teams += [ self.teams[place-1][0] - for place in match['teams'][i]['place'] - ] + for place in match['teams'][i]['place']] known_teams = [team for team in match_teams if team is not None] if len(known_teams) > 0: teams[i].name = '
'.join([ - team if team is not None else '??' for team in match_teams]) + team if team is not None + else '??' for team in match_teams]) else: teams[i].name = '' return teams - def get_match_info(self, match): info = Match() info.id = match['id'] @@ -132,14 +127,12 @@ class PlayoffData(object): try: towels = self.database.fetch( match['database'], p_sql.TOWEL_COUNT, - (match['table'], match['round']) - ) + (match['table'], match['round'])) row = [0 if r is None else r for r in self.database.fetch( match['database'], p_sql.BOARD_COUNT, - (match['table'], match['round']) - )] + (match['table'], match['round']))] if row[1] > 0: info.running = int(row[1]) if row[1] >= row[0] - towels[0]: @@ -170,15 +163,18 @@ class PlayoffData(object): winner_key = tuple(match['winner']) if winner_key not in leaderboard_teams: leaderboard_teams[winner_key] = [] - leaderboard_teams[winner_key].append(self.match_info[match['id']].winner) + leaderboard_teams[winner_key].append( + self.match_info[match['id']].winner) if 'loser' in match: loser_key = tuple(match['loser']) if loser_key not in leaderboard_teams: leaderboard_teams[loser_key] = [] - leaderboard_teams[loser_key].append(self.match_info[match['id']].loser) + leaderboard_teams[loser_key].append( + self.match_info[match['id']].loser) for positions, position_teams in leaderboard_teams.iteritems(): positions = list(positions) - if len(positions) == len([team for team in position_teams if team is not None]): + if len(positions) == len([ + team for team in position_teams if team is not None]): for table_team in self.teams: if table_team[0] in position_teams: position = positions.pop(0) @@ -192,9 +188,7 @@ class PlayoffData(object): len(phase['matches']) + len(phase['dummies']) if 'dummies' in phase else len(phase['matches']) - for phase in self.phases - ]) - ) + for phase in self.phases])) def get_shortname(self, fullname): for team in self.teams: diff --git a/jfr_playoff/db.py b/jfr_playoff/db.py index 19ec2fb..b94f3d5 100644 --- a/jfr_playoff/db.py +++ b/jfr_playoff/db.py @@ -10,8 +10,7 @@ class PlayoffDB(object): user=settings['user'], password=settings['pass'], host=settings['host'], - port=settings['port'] - ) + port=settings['port']) self.db_cursor = self.database.cursor(buffered=True) def get_cursor(self): diff --git a/jfr_playoff/dto.py b/jfr_playoff/dto.py index bf3e16a..f5e08ef 100644 --- a/jfr_playoff/dto.py +++ b/jfr_playoff/dto.py @@ -2,6 +2,7 @@ class Team(object): name = '' score = 0.0 + class Match(object): id = None teams = None @@ -12,10 +13,11 @@ class Match(object): winner_matches = None loser_matches = None + class Phase(object): title = None link = None matches = [] running = False -__all__ = ['Team', 'Match', 'Phase'] +__all__ = ('Team', 'Match', 'Phase') diff --git a/jfr_playoff/filemanager.py b/jfr_playoff/filemanager.py index 03dbaf7..5cd2a80 100644 --- a/jfr_playoff/filemanager.py +++ b/jfr_playoff/filemanager.py @@ -22,7 +22,6 @@ class PlayoffFileManager(object): if path.startswith(self.output_path): self.files.add(path.replace(self.output_path, '')) - def write_content(self, content): output = open(self.output_file, 'w') output.write(content.encode('utf8')) @@ -33,16 +32,18 @@ class PlayoffFileManager(object): def copy_scripts(self, script_path='sklady/playoff.js'): script_output_path = os.path.join(self.output_path, script_path) shutil.copy( - unicode(os.path.join(os.path.dirname(__main__.__file__), 'playoff.js')), - unicode(script_output_path) - ) + unicode(os.path.join( + os.path.dirname(__main__.__file__), 'playoff.js')), + unicode(script_output_path)) self.register_file(script_output_path) return script_output_path def send_files(self): if self.goniec['enabled']: try: - content_lines = [self.output_path] + list(self.files) + ['bye', ''] + content_lines = [self.output_path] + \ + list(self.files) + \ + ['bye', ''] print '\n'.join(content_lines) goniec = socket.socket() goniec.connect((self.goniec['host'], self.goniec['port'])) diff --git a/jfr_playoff/generator.py b/jfr_playoff/generator.py index bc2a388..5868750 100644 --- a/jfr_playoff/generator.py +++ b/jfr_playoff/generator.py @@ -16,23 +16,18 @@ class PlayoffGenerator(object): return p_temp.PAGE % ( p_temp.PAGE_HEAD % ( p_temp.PAGE_HEAD_REFRESH % ( - self.page['refresh'] - ) if self.page['refresh'] > 0 else '', - self.page['title'] - ), + self.page['refresh']) + if self.page['refresh'] > 0 else '', + self.page['title']), p_temp.PAGE_BODY % ( self.page['logoh'], self.get_match_grid( self.data.get_dimensions(), self.data.generate_phases(), - self.data.fill_match_info() - ), + self.data.fill_match_info()), self.get_leaderboard_table(self.data.fill_leaderboard()), p_temp.PAGE_BODY_FOOTER.decode('utf8') % ( - datetime.now().strftime('%Y-%m-%d o %H:%M') - ) - ) - ) + datetime.now().strftime('%Y-%m-%d o %H:%M')))) def get_match_table(self, match): rows = '' @@ -46,16 +41,13 @@ class PlayoffGenerator(object): team.name, ' / '.join([ self.data.get_shortname(name) for name in - team.name.split('
') - ]), + team.name.split('
')]), match.link, - team.score - ) + team.score) html = p_temp.MATCH_TABLE.decode('utf8') % ( int(self.page['width'] * 0.75), int(self.page['width'] * 0.25), - rows - ) + rows) if match.running > 0: html += p_temp.MATCH_RUNNING % (match.link, match.running) return html @@ -69,8 +61,7 @@ class PlayoffGenerator(object): phase.link, self.page['width'], position, - phase.title - ) + phase.title) def get_match_box(self, match, position): if match is not None: @@ -83,8 +74,7 @@ class PlayoffGenerator(object): ' '.join([ str(m) for m in match.loser_matches ]) if match.loser_matches is not None else '', - self.get_match_table(match) - ) + self.get_match_table(match)) return '' def get_match_grid(self, dimensions, grid, matches): @@ -94,8 +84,7 @@ class PlayoffGenerator(object): ) - self.page['margin'], dimensions[1] * ( self.page['height'] + self.page['margin'] - ) - self.page['margin'] - ) + ) - self.page['margin']) grid_boxes = '' col_no = 0 for phase in grid: @@ -126,7 +115,8 @@ class PlayoffGenerator(object): position = 1 rows = '' for team in leaderboard: - rows += p_temp.LEADERBOARD_ROW % (position, self.get_flag(team), team or '') + rows += p_temp.LEADERBOARD_ROW % ( + position, self.get_flag(team), team or '') position += 1 html = p_temp.LEADERBOARD.decode('utf8') % (rows) return html diff --git a/jfr_playoff/settings.py b/jfr_playoff/settings.py index 3b765bc..da92458 100644 --- a/jfr_playoff/settings.py +++ b/jfr_playoff/settings.py @@ -7,6 +7,7 @@ import sys def complete_filename(text, state): return (glob.glob(text+'*')+[None])[state] + class PlayoffSettings(object): def __init__(self): diff --git a/jfr_playoff/sql.py b/jfr_playoff/sql.py index 76ea728..b01bd08 100644 --- a/jfr_playoff/sql.py +++ b/jfr_playoff/sql.py @@ -1,5 +1,6 @@ MATCH_RESULTS = ''' -SELECT t1.fullname, t2.fullname, matches.carry, matches.vph, matches.vpv, matches.corrh, matches.corrv +SELECT t1.fullname, t2.fullname, matches.carry, + matches.vph, matches.vpv, matches.corrh, matches.corrv FROM #db#.matches matches JOIN #db#.teams t1 ON t1.id = #db#.matches.homet @@ -9,7 +10,8 @@ WHERE matches.tabl = %s AND matches.rnd = %s ''' BOARD_COUNT = ''' -SELECT segmentsperround*boardspersegment, SUM(sc1.contract IS NOT NULL AND sc2.contract IS NOT NULL) +SELECT segmentsperround*boardspersegment, + SUM(sc1.contract IS NOT NULL AND sc2.contract IS NOT NULL) FROM #db#.scores sc1 JOIN #db#.scores sc2 ON sc1.rnd = sc2.rnd diff --git a/jfr_playoff/template.py b/jfr_playoff/template.py index 8713ab9..99e6225 100644 --- a/jfr_playoff/template.py +++ b/jfr_playoff/template.py @@ -1,4 +1,4 @@ -#encoding=utf-8 +# -*- coding: utf-8 -*- MATCH_TABLE = ''' -- cgit v1.2.3 From ea45ac59d69f0b731298a9a99888c1932272c816 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 15:44:01 +0200 Subject: README updated --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6986b67..f77545c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ Dla wersji skryptowej: Instalacja ---------- -Dla wersji skompilowanej: [ściągnąć](https://emkael.github.io/_files/teamy-playoff/playoff-1.0.2.zip), rozpakować, upewnić się, że [`playoff.js`](playoff.js) jest w katalogu pliku wykonywalnego. +Dla wersji skompilowanej: [ściągnąć](https://emkael.github.io/_files/teamy-playoff/playoff-1.0.2.zip), rozpakować, upewnić się, że [`playoff.js`](playoff.js) jest w katalogu pliku wykonywalnego. +Wersja testowa (bez rewolucji funkcjonalności, po prostu po mocnej przebudowie kodu źródłowego): [1.0.3-beta](https://emkael.github.io/_files/teamy-playoff/playoff-1.0.3-beta.zip). Dla wersji skryptowej: sklonować to repozytorium. @@ -51,8 +52,7 @@ prefiksów turniejów oraz numerów rund * fazy powinny być określone raczej chronologicznie (czytaj: nie testowano, co się stanie, jeśli określimy np., że w meczu fazy 2 ma zagrać zwycięzca z fazy 4), ale nie powinno być problemu z "przeskakiwaniem" -faz (czyli awansem zwycięzcy z fazy 1 od razu do fazy 3), przy czym -takiej sytuacji też nie testowano (rysować się powinno, ale ubytki estetyczne są prawie pewne) +faz (czyli awansem zwycięzcy z fazy 1 od razu do fazy 3) * program wymaga działania Webmastera (wyniki czytane są z takiego miejsca bazy, do którego pisze Webmaster, a z jakichś powodów nie pisze Admin przy zamykaniu rundy/segmentu), więc nawet w przypadku grania -- cgit v1.2.3 From 1187e697eae30f222c7483d111e523c3a4e18a0a Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 15:44:38 +0200 Subject: Updating ignored files list --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2117c09..ee704a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.pyc *.json +playoff-*.zip build/* dist/* -- cgit v1.2.3 From 5dbd3883e1c2ae92b26a336e1237beeaf075c3ad Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 1 Aug 2017 15:45:28 +0200 Subject: Version bump to 1.0.2.99 (1.0.3-beta) --- .version | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.version b/.version index 9a566fe..7377239 100644 --- a/.version +++ b/.version @@ -1,8 +1,8 @@ # UTF-8 VSVersionInfo( ffi=FixedFileInfo( - filevers=(1, 0, 2, 0), - prodvers=(1, 0, 2, 0), + filevers=(1, 0, 2, 99), + prodvers=(1, 0, 2, 99), # Contains a bitmask that specifies the valid bits 'flags' mask=0x3f, # Contains a bitmask that specifies the Boolean attributes of the file. @@ -26,10 +26,10 @@ VSVersionInfo( u'040904b0', # 0x0409(1033)= English, 0x04b0(1200)= UTF-8 [StringStruct(u'CompanyName', u'emkael.info'), StringStruct(u'ProductName', u'teamy_playoff'), - StringStruct(u'ProductVersion', u'1, 0, 2, 0'), + StringStruct(u'ProductVersion', u'1, 0, 2, 99'), StringStruct(u'InternalName', u'teamy_playoff'), StringStruct(u'OriginalFilename', u'playoff.exe'), - StringStruct(u'FileVersion', u'1, 0, 2, 0'), + StringStruct(u'FileVersion', u'1, 0, 2, 99'), StringStruct( u'FileDescription', u'Play-off visualisation for JFR Teamy events'), -- cgit v1.2.3 From 40d09a61727d3c960a816def07fb319853a90116 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 8 Aug 2017 14:31:31 +0200 Subject: Parsing canvas lines offsets as numeric values Fixes #1 --- playoff.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/playoff.js b/playoff.js index 1763d59..b2f7a4b 100644 --- a/playoff.js +++ b/playoff.js @@ -61,9 +61,9 @@ var playoff = { var box = boxes_idx[from[f]]; var line = [ Math.floor(parseInt(box.style.left) + parseInt(box.clientWidth)), - Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + this.settings[type + '_v_offset']), - Math.floor(parseInt(box.style.left) + parseInt(box.clientWidth) + this.settings[type + '_h_offset']), - Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + this.settings[type + '_v_offset']) + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + parseFloat(this.settings[type + '_v_offset'])), + Math.floor(parseInt(box.style.left) + parseInt(box.clientWidth) + parseFloat(this.settings[type + '_h_offset'])), + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + parseFloat(this.settings[type + '_v_offset'])) ]; horizontal_from.push(line); for (var l in horizontal_from) { @@ -90,9 +90,9 @@ var playoff = { var box = boxes_idx[to[t]]; var line = [ parseInt(box.style.left), - Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + this.settings[type + '_v_offset']), - Math.floor(parseInt(box.style.left) - this.settings[type + '_h_offset']), - Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + this.settings[type + '_v_offset']) + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + parseFloat(this.settings[type + '_v_offset'])), + Math.floor(parseInt(box.style.left) - parseFloat(this.settings[type + '_h_offset'])), + Math.floor(parseInt(box.style.top) + 0.5 * parseInt(box.clientHeight) + parseFloat(this.settings[type + '_v_offset'])) ]; horizontal_to.push(line); for (var l in horizontal_to) { @@ -119,11 +119,11 @@ var playoff = { (vertical_from[1] + vertical_from[3]) / 2 ], [ - this.settings[type + '_h_offset'] / 2 + (vertical_from[0] + vertical_from[2] + vertical_to[0] + vertical_to[2]) / 4, + parseFloat(this.settings[type + '_h_offset']) / 2 + (vertical_from[0] + vertical_from[2] + vertical_to[0] + vertical_to[2]) / 4, (vertical_from[1] + vertical_from[3]) / 2 ], [ - this.settings[type + '_h_offset'] / 2 + (vertical_from[0] + vertical_from[2] + vertical_to[0] + vertical_to[2]) / 4, + parseFloat((this.settings[type + '_h_offset']) / 2 + (vertical_from[0] + vertical_from[2] + vertical_to[0] + vertical_to[2]) / 4, (vertical_to[1] + vertical_to[3]) / 2 ], [ -- cgit v1.2.3