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 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 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 % ( 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')) ) ) 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 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) 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) 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()