예제 #1
0
def show_fixgen_table(tourney_name, module_list, title, description):
    cgicommon.writeln("<h2>%s</h2>" % (cgicommon.escape(title)))
    if description:
        cgicommon.writeln("<p>")
        cgicommon.writeln(description)
        cgicommon.writeln("</p>")
    cgicommon.writeln("<table class=\"fixgentable\">")
    #cgicommon.writeln("<tr><th class=\"fixgentable fixgenth\"></th><th class=\"fixgentable fixgenth\">Generator</th><th class=\"fixgentable fixgenth\">Description</th></tr>");
    for module_name in module_list:
        fixgen_module = importlib.import_module(module_name)
        cgicommon.writeln("<tr>")
        cgicommon.writeln("<td class=\"fixgentable fixgen\">")
        cgicommon.writeln(
            "<a href=\"/cgi-bin/fixturegen.py?generator=%s&amp;tourney=%s\">" %
            (urllib.parse.quote_plus(module_name),
             urllib.parse.quote_plus(tourney_name)))
        cgicommon.writeln("<img src=\"/images/fixgen/%s.png\" alt=\"%s\" />" %
                          (cgicommon.escape(module_name),
                           cgicommon.escape(fixgen_module.name)))
        cgicommon.writeln("</a>")
        cgicommon.writeln("</td>")
        cgicommon.writeln("<td class=\"fixgentable fixgen\">")
        cgicommon.writeln(
            "<a href=\"/cgi-bin/fixturegen.py?generator=%s&amp;tourney=%s\">%s</a>"
            % (urllib.parse.quote_plus(module_name),
               urllib.parse.quote_plus(tourney_name),
               cgicommon.escape(fixgen_module.name)))
        cgicommon.writeln("</td>")
        #cgicommon.writeln("<td class=\"fixgentable fixgenmodule\">%s</td>" % (cgicommon.escape(module_name)));
        cgicommon.writeln(
            "<td class=\"fixgentable fixgendescription\">%s</td>" %
            (cgicommon.escape(fixgen_module.description)))
        cgicommon.writeln("</tr>")
    cgicommon.writeln("</table>")
예제 #2
0
def show_player_drop_down_box(players, control_name):
    cgicommon.writeln("<select name=\"%s\">" % (control_name))
    cgicommon.writeln("<option value=\"\">-- select player --</option>")
    for p in players:
        cgicommon.writeln(
            "<option value=\"%s\">%s (%g)</option>" % (cgicommon.escape(
                p.name, True), cgicommon.escape(p.name), p.rating))
    cgicommon.writeln("</select>")
예제 #3
0
def show_player_search_form(tourney):
    cgicommon.writeln("<form method=\"GET\" action=\"%s\">" % (cgicommon.escape(baseurl, True)))
    cgicommon.writeln("<input type=\"hidden\" name=\"tourney\" value=\"%s\" />" % (cgicommon.escape(tourney.get_name())))
    cgicommon.writeln("<p>")
    cgicommon.writeln("Search player name: <input type=\"text\" name=\"searchname\" value=\"\" /> ")
    cgicommon.writeln("<input type=\"submit\" name=\"searchsubmit\" value=\"Search\" />")
    cgicommon.writeln("</p>")
    cgicommon.writeln("</form>")
예제 #4
0
파일: home.py 프로젝트: elocemearg/atropine
def print_tourney_table(tourney_list,
                        destination_page,
                        show_last_modified,
                        show_export_html_link=False,
                        show_display_link=False):
    cgicommon.writeln("<table class=\"tourneylist\">")
    cgicommon.writeln("<tr>")
    cgicommon.writeln(
        "<th><a href=\"/cgi-bin/home.py?orderby=%s\">Name</a></th>" %
        ("name_d" if order_by == "name_a" else "name_a"))

    if show_last_modified:
        cgicommon.writeln(
            "<th><a href=\"/cgi-bin/home.py?orderby=%s\">Last modified</a></th>"
            % ("mtime_a" if order_by == "mtime_d" else "mtime_d"))

    if show_display_link or show_export_html_link:
        cgicommon.writeln(
            "<th colspan=\"%d\">Useful links</th>" %
            (2 if show_display_link and show_export_html_link else 1))

    cgicommon.writeln("</tr>")
    for tourney_basename in tourney_list:
        name = tourney_basename[:-3]
        filename = os.path.join(cgicommon.dbdir, tourney_basename)
        st = os.stat(filename)
        modified_time = time.localtime(st.st_mtime)
        cgicommon.writeln("<tr>")
        cgicommon.writeln('<td class=\"tourneylistname\">')
        if destination_page:
            cgicommon.writeln(
                '<a href="%s?tourney=%s">%s</a>' %
                (cgicommon.escape(destination_page, True),
                 urllib.parse.quote_plus(name), cgicommon.escape(name)))
        else:
            cgicommon.writeln(cgicommon.escape(name))
        cgicommon.writeln('</td>')

        if show_last_modified:
            cgicommon.writeln("<td class=\"tourneylistmtime\">%s</td>" %
                              (time.strftime("%d %b %Y %H:%M", modified_time)))

        if show_export_html_link:
            cgicommon.writeln("<td class=\"tourneylistlink\">")
            cgicommon.writeln(
                "<a href=\"/cgi-bin/export.py?tourney=%s&format=html\">Tourney report</a>"
                % (urllib.parse.quote_plus(name)))
            cgicommon.writeln("</td>")
        if show_display_link:
            cgicommon.writeln("<td class=\"tourneylistlink\">")
            cgicommon.writeln(
                "<a href=\"/cgi-bin/display.py?tourney=%s\">Full screen display</a>"
                % (urllib.parse.quote_plus(name)))
            cgicommon.writeln("</td>")

        cgicommon.writeln("</tr>")
    cgicommon.writeln("</table>")
예제 #5
0
def show_division_drop_down_box(control_name, tourney, player):
    num_divisions = tourney.get_num_divisions()
    cgicommon.writeln("<select name=\"%s\">" % (cgicommon.escape(control_name, True)))
    for div in range(num_divisions):
        cgicommon.writeln("<option value=\"%d\" %s >%s (%d active players)</option>" % (div,
                "selected" if (player is not None and div == player.get_division()) or (player is None and div == 0) else "",
                cgicommon.escape(tourney.get_division_name(div)),
                tourney.get_num_active_players(div)))
    cgicommon.writeln("</select>")
예제 #6
0
def include_scripts(dir_name, url_path):
    for filename in sorted(os.listdir(dir_name)):
        if (os.path.isdir(dir_name + "/" + filename)):
            include_scripts(dir_name + "/" + filename,
                            url_path + "/" + filename)
        elif filename[-3:] == ".js":
            base_filename = os.path.basename(filename)
            cgicommon.writeln(
                "<script src=\"%s/%s\"></script>" % (cgicommon.escape(
                    url_path, True), cgicommon.escape(base_filename, True)))
예제 #7
0
def show_player_selection(players, control_name, value):
    cgicommon.writeln("<select name=\"%s\">" %
                      cgicommon.escape(control_name, True))
    for p in players:
        player_name = p.get_name()
        if player_name == value:
            sel = " selected"
        else:
            sel = ""
        cgicommon.writeln(
            "<option value=\"%s\"%s>%s</option>" % (cgicommon.escape(
                player_name, True), sel, cgicommon.escape(player_name)))
    cgicommon.writeln("</select>")
예제 #8
0
def show_player_form(tourney, player):
    num_divisions = tourney.get_num_divisions()
    tourneyname = tourney.get_name()
    if player:
        player_id = player.get_id()
    else:
        player_id = None

    if player:
        cgicommon.writeln("<form method=\"POST\" action=\"%s?tourney=%s&id=%d\">" % (cgicommon.escape(baseurl), urllib.parse.quote_plus(tourneyname), player_id))
    else:
        cgicommon.writeln("<form method=\"POST\" action=\"%s?tourney=%s\">" % (cgicommon.escape(baseurl), urllib.parse.quote_plus(tourneyname)))
    cgicommon.writeln("<table>")
    cgicommon.writeln("<tr><td>Name</td><td><input type=\"text\" name=\"setname\" value=\"%s\" /></td></tr>" % ("" if not player else cgicommon.escape(player.get_name(), True)))
    cgicommon.writeln("<tr><td>Rating</td><td><input style=\"width: 5em;\" type=\"text\" name=\"setrating\" value=\"%g\"/>" % (1000 if not player else player.get_rating()))
    cgicommon.writeln("<span class=\"playercontrolhelp\">(1000 is the default; use 0 to indicate this player is a Prune)</span>")
    cgicommon.writeln("</td></tr>")
    if num_divisions > 1:
        cgicommon.writeln("<tr><td>Division</td>")
        cgicommon.writeln("<td>")
        show_division_drop_down_box("setdivision", tourney, player)
        cgicommon.writeln("</td></tr>")
    cgicommon.writeln("<tr><td>Withdrawn?</td><td><input type=\"checkbox\" name=\"setwithdrawn\" value=\"1\" %s /> <span class=\"playercontrolhelp\">(if ticked, fixture generators will not include this player)</span></td></tr>" % ("checked" if player and player.is_withdrawn() else ""))
    cgicommon.writeln("<tr><td>Requires accessible table?</td><td><input type=\"checkbox\" name=\"setrequiresaccessibletable\" value=\"1\" %s /> <span class=\"playercontrolhelp\">(if ticked, fixture generators will place this player and their opponents on an accessible table, as defined in <a href=\"/cgi-bin/tourneysetup.py?tourney=%s\">General Setup</a>)</span></td></tr>" % (
        "checked" if player and player.is_requiring_accessible_table() else "",
        urllib.parse.quote_plus(tourneyname)
    ))

    if player is None:
        pref = None
    else:
        pref = player.get_preferred_table()
    cgicommon.writeln("<tr><td>Preferred table number</td><td><input type=\"text\" name=\"setpreferredtable\" style=\"width: 5em;\" value=\"%s\" /> <span class=\"playercontrolhelp\">(player will be assigned this table number if possible - if blank, player has no specific table preference)</span></td></tr>" % (cgicommon.escape(str(pref)) if pref is not None else ""))

    cgicommon.writeln("<tr><td>Avoid Prune?</td><td><input type=\"checkbox\" name=\"setavoidprune\" value=\"1\" %s /> <span class=\"playercontrolhelp\">(if ticked, the Swiss fixture generator will behave as if this player has already played a Prune)</span></td></tr>" % ("checked" if player and player.is_avoiding_prune() else ""))
    cgicommon.writeln("</table>")
    cgicommon.writeln("<p>")
    cgicommon.writeln("<input type=\"hidden\" name=\"tourney\" value=\"%s\" />" % (cgicommon.escape(tourneyname, True)))
    if player:
        cgicommon.writeln("<input type=\"hidden\" name=\"id\" value=\"%d\" />" % (player_id))
    
    if player:
        cgicommon.writeln("<input type=\"submit\" name=\"editplayer\" class=\"bigbutton\" value=\"Save Changes\" />")
    else:
        cgicommon.writeln("<input type=\"submit\" name=\"newplayersubmit\" class=\"bigbutton\" value=\"Create Player\" />")
    cgicommon.writeln("</p>")
    cgicommon.writeln("</form>")
예제 #9
0
def show_rerate_button(tourney):
    tourney_name = tourney.get_name()
    cgicommon.writeln("<h2>Rerate players by player ID</h2>")
    cgicommon.writeln("<p>")
    cgicommon.writeln("""
    Set the ratings of players in order, by player ID, which corresponds
    to the order in which they appeared in the list you put into the text
    box at the start of the tournament. The player at the top of the list
    (the lowest player ID) gets the highest rating, and the player at the
    bottom of the list (the highest player ID) gets the lowest rating. Any
    player with a rating of zero remains unchanged.""")
    cgicommon.writeln("</p>")
    cgicommon.writeln("<p>")
    cgicommon.writeln("""
    This is useful if when you pasted in the player list you forgot to
    select the option which tells Atropine that they're in rating order,
    and now the Overachievers page thinks they're all seeded the same.
    """)
    cgicommon.writeln("</p>")

    cgicommon.writeln("<p>")
    cgicommon.writeln("""
    If you press this button, it will overwrite all other non-zero ratings
    you may have given the players. That's why you need to tick the box as
    well.
    """)
    cgicommon.writeln("</p>")

    cgicommon.writeln("<p>")
    cgicommon.writeln("<form method=\"POST\" action=\"%s?tourney=%s\">" % (cgicommon.escape(baseurl), urllib.parse.quote_plus(tourney_name)))
    cgicommon.writeln("<input type=\"submit\" name=\"reratebyplayerid\" value=\"Rerate players by player ID\" />")
    cgicommon.writeln("<input type=\"checkbox\" name=\"reratebyplayeridconfirm\" id=\"reratebyplayeridconfirm\" style=\"margin-left: 20px\" />")
    cgicommon.writeln("<label for=\"reratebyplayeridconfirm\">Yes, I'm sure</label>")

    cgicommon.writeln("</form>")
    cgicommon.writeln("</p>")
예제 #10
0
    if num_players == 0:
        cgicommon.writeln(
            "<p>This tourney doesn't have any players, so you can't specify teams yet.</p>"
        )
        cgicommon.writeln(
            '<p><a href="/cgi-bin/tourneysetup.py?tourney=%s">Back to Tourney Setup</a></p>'
            % (urllib.parse.quote_plus(tourneyname)))
    else:
        #print '<p><a href="/cgi-bin/tourneysetup.py?tourney=%s">Back to tourney setup</a></p>' % (urllib.quote_plus(tourneyname));
        cgicommon.writeln('<h2>Teams</h2>')
        for team in teams:
            cgicommon.writeln('<p>')
            cgicommon.writeln(
                cgicommon.make_team_dot_html(team) + " " +
                cgicommon.escape(team.get_name()))
            player_name_list = [
                cgicommon.escape(p.get_name()) for (p, pt) in player_teams
                if pt is not None and pt.get_id() == team.get_id()
            ]

            if player_name_list:
                cgicommon.writeln(
                    " (%d): %s" %
                    (len(player_name_list), ", ".join(player_name_list)))
            else:
                cgicommon.writeln(" (no players)")
            cgicommon.writeln('</p>')

        cgicommon.writeln('<h2>Players</h2>')
        cgicommon.writeln(
예제 #11
0
else:
    #print '<p><a href="%s?tourney=%s">%s</a></p>' % (baseurl, urllib.quote_plus(tourneyname), cgicommon.escape(tourneyname));
    if request_method == "POST" and "submit" in form:
        try:
            tourney.set_show_tournament_rating_column(show_tournament_rating)
            tourney.set_tournament_rating_config(tr_bonus, tr_diff_cap)
            tourney.set_rank_method(rank)
            tourney.set_rank_finals(rank_finals)
            cgicommon.show_success_box("Options updated.")
        except countdowntourney.TourneyException as e:
            cgicommon.show_tourney_exception(e)

    cgicommon.writeln(('<form action="%s?tourney=%s" method="post">' %
                       (baseurl, urllib.parse.quote_plus(tourneyname))))
    cgicommon.writeln(('<input type="hidden" name="tourney" value="%s" />' %
                       cgicommon.escape(tourneyname, True)))

    cgicommon.writeln("<h2>Team Setup</h2>")
    cgicommon.writeln("""<p>Atropine can assign each player to one of
two teams. Every match between players on opposing teams gives a point to the
winner's team. The team scores are displayed alongside the standings.</p>""")
    cgicommon.writeln("""<p>
<a href=\"/cgi-bin/teamsetup.py?tourney=%s\">Go to the Team Setup page</a>
</p>""" % (urllib.parse.quote_plus(tourneyname)))

    cgicommon.writeln("<h2>Ranking order</h2>")
    rank = tourney.get_rank_method()
    rank_finals = tourney.get_rank_finals()
    cgicommon.writeln(
        "<p>How do you want to rank players in the standings table?</p>")
    cgicommon.writeln("<div class=\"generalsetupcontrolgroup\">")
예제 #12
0
    cgicommon.writeln("<h1>Tim Down Award</h1>")

    cgicommon.writeln("<form action=\"%s\" method=\"GET\">" % (baseurl))
    cgicommon.writeln("<p>")
    cgicommon.writeln(
        "The Tim Down Award goes to the player whose opponents have the highest average standings position, and who lost "
    )
    cgicommon.writeln(
        "<input type=\"number\" name=\"numlosinggames\" value=\"%d\" min=\"0\" max=\"999\" size=\"3\" />"
        % (num_losing_games))
    cgicommon.writeln("or more games.")
    cgicommon.writeln("</p>")
    cgicommon.writeln("<p>")
    cgicommon.writeln(
        "<input type=\"hidden\" name=\"tourney\" value=\"%s\" />" %
        (cgicommon.escape(tourney_name, True)))
    cgicommon.writeln(
        "<input type=\"submit\" name=\"submit\" value=\"Refresh\" />")
    cgicommon.writeln("</p>")
    cgicommon.writeln("</form>")

    num_divisions = tourney.get_num_divisions()
    for division in range(num_divisions):
        if num_divisions > 1:
            div_name = tourney.get_division_name(division)
            cgicommon.writeln("<h2>%s</h2>" % (cgicommon.escape(div_name)))

        td_standings = tourney.get_tim_down_award_standings(
            division, num_losing_games)

        pos = 0
예제 #13
0
def show_conflict_resolution_box(tourney, games, round_no, stored_revision_no,
                                 stored_revision_timestamp, form):
    tourney_name = tourney.get_name()
    existing_strategy = int_or_none(form.getfirst("conflictstrategy"))

    if existing_strategy is None:
        existing_strategy = CONFLICT_STRATEGY_DO_NOT_EMBLANKIFY

    cgicommon.writeln("""
<script>
function update_conflict_resolution_example(value) {
    var blank_to_non_blank = document.getElementById("cr_blanktononblank");
    var non_blank_to_non_blank = document.getElementById("cr_nonblanktononblank");
    var non_blank_to_blank = document.getElementById("cr_nonblanktoblank");

    if (value == 0) { /* CONFLICT_STRATEGY_FORCE */
        blank_to_non_blank.innerHTML = "88-88";
        non_blank_to_non_blank.innerHTML = "88-88";
        non_blank_to_blank.innerHTML = "-";
    }
    else if (value == 1) { /* CONFLICT_STRATEGY_DO_NOT_EMBLANKIFY */
        blank_to_non_blank.innerHTML = "88-88";
        non_blank_to_non_blank.innerHTML = "88-88";
        non_blank_to_blank.innerHTML = "77-77";
    }
    else if (value == 2) { /* CONFLICT_STRATEGY_ONLY_FILL_BLANKS */
        blank_to_non_blank.innerHTML = "88-88";
        non_blank_to_non_blank.innerHTML = "77-77";
        non_blank_to_blank.innerHTML = "77-77";
    }
    else if (value == 3) { /* CONFLICT_STRATEGY_DISCARD */
        blank_to_non_blank.innerHTML = "-";
        non_blank_to_non_blank.innerHTML = "77-77";
        non_blank_to_blank.innerHTML = "77-77";
    }
}
</script>
    """)

    cgicommon.writeln("<div class=\"conflictresolution\">")
    cgicommon.writeln(
        "<form method=\"POST\" action=\"%s?tourney=%s&amp;round=%d\">" %
        (baseurl, urllib.parse.quote_plus(tourney_name), round_no))
    cgicommon.writeln(
        "<input type=\"hidden\" name=\"tourney\" value=\"%s\" />" %
        (cgicommon.escape(tourney_name, True)))
    cgicommon.writeln("<input type=\"hidden\" name=\"round\" value=\"%d\" />" %
                      (round_no))
    cgicommon.writeln(
        "<input type=\"hidden\" name=\"revision\" value=\"%d\" />" %
        (stored_revision_no))

    # Include the submitted scores in this conflict resolution form, so that
    # when the user presses "Resolve Conflicts" we remember what the original
    # submissions were.
    for g in games:
        input_name = "gamescore_%d_%d" % (g.round_no, g.seq)
        submitted_score = form.getfirst(input_name)
        if submitted_score is not None:
            cgicommon.writeln(
                "<input type=\"hidden\" name=\"%s\" value=\"%s\" />" %
                (cgicommon.escape(input_name),
                 cgicommon.escape(submitted_score, True)))

    score = form.getfirst("gamescore_%d_%d" % (g.round_no, g.seq))
    cgicommon.writeln("<div class=\"conflictresolutiontoprow\">")
    cgicommon.writeln("Last conflicting modification occurred at: %s" %
                      (cgicommon.escape(stored_revision_timestamp)))
    cgicommon.writeln("</div>")

    cgicommon.writeln("<div class=\"conflictresolutionchoicerow\">")
    cgicommon.writeln("<div class=\"conflictresolutionradiobutton\">")
    cgicommon.writeln(
        "<input type=\"radio\" name=\"conflictstrategy\" id=\"conflictstrategydiscard\" value=\"%d\" onchange=\"update_conflict_resolution_example(this.value)\" %s />"
        %
        (CONFLICT_STRATEGY_DISCARD,
         "checked" if existing_strategy == CONFLICT_STRATEGY_DISCARD else ""))
    cgicommon.writeln("</div>")
    cgicommon.writeln("<div class=\"conflictresolutionlabel\">")
    cgicommon.writeln(
        "<label for=\"conflictstrategydiscard\">Discard my submission - go with what's currently in the database.</label>"
    )
    cgicommon.writeln("</div>")
    cgicommon.writeln("</div>")

    cgicommon.writeln("<div class=\"conflictresolutionchoicerow\">")
    cgicommon.writeln("<div class=\"conflictresolutionradiobutton\">")
    cgicommon.writeln(
        "<input type=\"radio\" name=\"conflictstrategy\" id=\"conflictstrategyfillblanks\" value=\"%d\" onchange=\"update_conflict_resolution_example(this.value)\" %s />"
        % (CONFLICT_STRATEGY_ONLY_FILL_BLANKS, "checked"
           if existing_strategy == CONFLICT_STRATEGY_ONLY_FILL_BLANKS else ""))
    cgicommon.writeln("</div>")
    cgicommon.writeln("<div class=\"conflictresolutionlabel\">")
    cgicommon.writeln(
        "<label for=\"conflictstrategyfillblanks\">If a game currently has no result but my submission provides one, fill in that game's result with my submission. Discard any other changes.</label>"
    )
    cgicommon.writeln("</div>")
    cgicommon.writeln("</div>")

    cgicommon.writeln("<div class=\"conflictresolutionchoicerow\">")
    cgicommon.writeln("<div class=\"conflictresolutionradiobutton\">")
    cgicommon.writeln(
        "<input type=\"radio\" name=\"conflictstrategy\" id=\"conflictstrategydonotemblankify\" value=\"%d\" onchange=\"update_conflict_resolution_example(this.value);\" %s />"
        % (CONFLICT_STRATEGY_DO_NOT_EMBLANKIFY, "checked" if existing_strategy
           == CONFLICT_STRATEGY_DO_NOT_EMBLANKIFY else ""))
    cgicommon.writeln("</div>")
    cgicommon.writeln("<div class=\"conflictresolutionlabel\">")
    cgicommon.writeln(
        "<label for=\"conflictstrategydonotemblankify\">If my submission has a result for a game, overwrite the existing result with my submission, but do not overwrite an existing result with a blank one.</label>"
    )
    cgicommon.writeln("</div>")
    cgicommon.writeln("</div>")

    cgicommon.writeln("<div class=\"conflictresolutionchoicerow\">")
    cgicommon.writeln("<div class=\"conflictresolutionradiobutton\">")
    cgicommon.writeln(
        "<input type=\"radio\" name=\"conflictstrategy\" id=\"conflictstrategyforce\" value=\"%d\" onchange=\"update_conflict_resolution_example(this.value);\" %s />"
        % (CONFLICT_STRATEGY_FORCE,
           "checked" if existing_strategy == CONFLICT_STRATEGY_FORCE else ""))
    cgicommon.writeln("</div>")
    cgicommon.writeln("<div class=\"conflictresolutionlabel\">")
    cgicommon.writeln(
        "<label for=\"conflictstrategyforce\">Overwrite everything with my submission, even if that means overwriting existing results with blank results.</label>"
    )
    cgicommon.writeln("</div>")
    cgicommon.writeln("</div>")

    show_conflict_resolution_example(existing_strategy)

    cgicommon.writeln("<div class=\"conflictresolutionbottomrow\">")
    cgicommon.writeln("<div class=\"conflictresolutionsubmit\">")
    cgicommon.writeln(
        "<input type=\"submit\" name=\"save\" value=\"Resolve Conflicts\" />")
    cgicommon.writeln("</div>")
    cgicommon.writeln("</div>")

    cgicommon.writeln("</form>")
    cgicommon.writeln("</div>")
예제 #14
0
def show_view_option_controls(tourney, form, options):
    if not options:
        return
    cgicommon.writeln(
        "<div class=\"teleostoptionheading\">Options for this screen mode</div>"
    )
    for o in options:
        cgicommon.writeln("<div class=\"teleostoption\">")
        name_escaped = "teleost_option_" + cgicommon.escape(o.name, True)
        if o.value is None:
            value_escaped = ""
        else:
            value_escaped = cgicommon.escape(str(o.value), True)

        desc_escaped = cgicommon.escape(o.desc)

        # If $INDENT exists, replace it with a checkbox-width of empty space
        desc_escaped = re.sub(
            "\\$INDENT\\b",
            "<span style=\"visibility: hidden;\"><input type=\"checkbox\" name=\"_placeholder_%s\" /></span>"
            % (name_escaped), desc_escaped, 0)

        m = re.search("\\$CONTROL\\b", desc_escaped)
        if m:
            before_control = desc_escaped[0:m.start()]
            after_control = desc_escaped[m.end():]
        else:
            before_control = desc_escaped
            after_control = ""

        cgicommon.writeln(before_control)

        if o.name in checkbox_to_assoc_field:
            onclick_value = "var numberField = document.getElementById('%s'); var checkboxField = document.getElementById('%s'); numberField.disabled = !checkboxField.checked;" % (
                "teleost_option_" + checkbox_to_assoc_field[o.name],
                name_escaped)
        else:
            onclick_value = None

        disabled_attr = ""
        if o.name in assoc_field_to_checkbox:
            for oo in options:
                if oo.name == assoc_field_to_checkbox[o.name]:
                    try:
                        value = int(oo.value)
                    except ValueError:
                        value = 0

                    if value:
                        disabled_attr = ""
                    else:
                        disabled_attr = "disabled"
                    break

        if o.control_type == countdowntourney.CONTROL_NUMBER:
            cgicommon.writeln(
                "<input type=\"number\" style=\"width: 5em;\" name=\"%s\" id=\"%s\" value=\"%s\" %s />"
                % (name_escaped, name_escaped, value_escaped, disabled_attr))
        elif o.control_type == countdowntourney.CONTROL_CHECKBOX:
            if o.value is not None and int(o.value):
                checked_str = "checked"
            else:
                checked_str = ""
            cgicommon.writeln(
                "<input type=\"checkbox\" name=\"%s\" id=\"%s\" value=\"1\" %s %s />"
                % (name_escaped, name_escaped, checked_str,
                   "" if not onclick_value else "onclick=\"" +
                   re.sub("\"", "\\\"", onclick_value, 0) + "\""))
            cgicommon.writeln(
                "<input type=\"hidden\" name=\"%s\" value=\"1\" />" %
                ("exists_checkbox_" + name_escaped))

        cgicommon.writeln(after_control)

        cgicommon.writeln("</div>")
예제 #15
0
    <a href="/cgi-bin/display.py?tourney=%s"
       target=\"_blank\">
       Open Display Window
       <img src=\"/images/opensinnewwindow.png\"
            alt=\"Opens in new window\"
            title=\"Opens in new window\" />
        </a>""" % (urllib.parse.quote_plus(tourney.name)))
    cgicommon.writeln("</div>")

    cgicommon.writeln("<div class=\"bannercontrol\">")
    cgicommon.writeln("<form action=\"" + baseurl +
                      "?tourney=%s&selectedview=%d\" method=\"POST\">" %
                      (urllib.parse.quote_plus(tourney_name), selected_view))
    cgicommon.writeln(
        "Banner text: <input type=\"text\" name=\"bannertext\" id=\"bannereditbox\" value=\"%s\" size=\"50\" onclick=\"this.select();\" />"
        % (cgicommon.escape(banner_text, True)))
    cgicommon.writeln(
        "<input type=\"submit\" style=\"min-width: 60px;\" name=\"setbanner\" value=\"Set\" />"
    )
    cgicommon.writeln(
        "<input type=\"submit\" style=\"min-width: 60px;\" name=\"clearbanner\" value=\"Clear\" />"
    )
    cgicommon.writeln("</form>")
    cgicommon.writeln("</div>")

    cgicommon.writeln("<div class=\"viewselection\">")
    cgicommon.writeln("<div class=\"viewpreviewandoptions\">")

    cgicommon.writeln("<div class=\"displaysetupview viewnowshowing\">")
    show_now_showing_frame(tourney)
    cgicommon.writeln("<div class=\"viewpreviewcurrent\">")
예제 #16
0
def get_user_form(tourney, settings, div_rounds):
    num_divisions = tourney.get_num_divisions()
    div_num_games = dict()
    div_game_types = dict()

    players = sorted(tourney.get_active_players(), key=lambda x: x.get_name())

    latest_round_no = tourney.get_latest_round_no()
    if latest_round_no is None:
        latest_round_no = 0

    prev_settings = settings.get_previous_settings()
    for key in prev_settings:
        if key not in settings and re.match("^d[0-9]*_groupsize$", key):
            settings[key] = prev_settings[key]
    if settings.get("submitrestore", None):
        for key in prev_settings:
            if key not in ["submit", "submitrestore", "submitplayers"]:
                settings[key] = prev_settings[key]

    elements = []
    elements.append(htmlform.HTMLFormHiddenInput("numgamessubmit", "1"))
    elements.append(
        htmlform.HTMLFormHiddenInput("roundno", str(latest_round_no + 1)))

    # If there's a previously-saved form for this round, offer to load it
    prev_settings = settings.get_previous_settings()
    round_no = int_or_none(prev_settings.get("roundno", None))
    if round_no is not None and round_no == latest_round_no + 1:
        elements.append(
            htmlform.HTMLFragment("<div class=\"infoboxcontainer\">"))
        elements.append(htmlform.HTMLFragment("<div class=\"infoboximage\">"))
        elements.append(
            htmlform.HTMLFragment(
                "<img src=\"/images/info.png\" alt=\"Info\" />"))
        elements.append(htmlform.HTMLFragment("</div>"))
        elements.append(
            htmlform.HTMLFragment("<div class=\"infoboxmessagecontainer\">"))
        elements.append(
            htmlform.HTMLFragment("<div class=\"infoboxmessage\">"))
        elements.append(htmlform.HTMLFragment("<p>"))
        elements.append(
            htmlform.HTMLFragment(
                "There is an incomplete fixtures form saved. Do you want to carry on from where you left off?"
            ))
        elements.append(htmlform.HTMLFragment("</p>"))
        elements.append(htmlform.HTMLFragment("<p>"))
        elements.append(
            htmlform.HTMLFormSubmitButton("submitrestore",
                                          "Restore previously-saved form"))
        elements.append(htmlform.HTMLFragment("</p>"))
        elements.append(htmlform.HTMLFragment("</div></div></div>"))

    # When we pass these settings to fixgen_manual, we don't want it asking
    # awkward questions about the number of players in a group when we're
    # fixing at it two, so tell it that's already been submitted.
    settings["tablesizesubmit"] = "1"

    for div_index in div_rounds:
        num_games_name = "d%d_num_groups" % (div_index)
        game_type_name = "d%d_game_type" % (div_index)

        # For fully-manual, number of players per group is always 2, and
        # we're allowed to put a player on more than one table
        settings["d%d_groupsize" % (div_index)] = "2"
        settings["d%d_allow_player_repetition" % (div_index)] = "1"

        # Also we want fixgen_manual to show the standings table for each
        # division.
        settings["d%d_show_standings" % (div_index)] = "1"

        if settings.get(num_games_name, None) is not None:
            try:
                div_num_games[div_index] = int(settings.get(num_games_name))
                if div_num_games[div_index] < 0:
                    div_num_games[div_index] = 0
            except ValueError:
                div_num_games[div_index] = 0
        else:
            div_num_games[div_index] = 0

        if settings.get(game_type_name, None) is not None:
            try:
                div_game_types[div_index] = settings.get(game_type_name)
                if div_game_types[div_index] in special_round_names:
                    settings["d%d_round_name" %
                             (div_index)] = special_round_names[
                                 div_game_types[div_index]]
            except ValueError:
                div_game_types[div_index] = None

        if num_divisions > 1:
            elements.append(
                htmlform.HTMLFragment(
                    "<h2>%s</h2>" %
                    (cgicommon.escape(tourney.get_division_name(div_index)))))

        elements.append(htmlform.HTMLFragment("<div class=\"fixgenoption\">"))
        num_games_element = htmlform.HTMLFormTextInput(
            "Number of games to create", num_games_name, "")
        elements.append(num_games_element)
        elements.append(htmlform.HTMLFragment("</div>"))

        elements.append(htmlform.HTMLFragment("<div class=\"fixgenoption\">"))
        elements.append(htmlform.HTMLFragment("Create games of this type: "))

        game_type_options = [
            htmlform.HTMLFormDropDownOption(x["code"],
                                            x["name"] + " (" + x["code"] + ")")
            for x in countdowntourney.get_game_types()
        ]
        type_element = htmlform.HTMLFormDropDownBox(
            "d%d_game_type" % (div_index), game_type_options)

        current_setting = settings.get("d%d_game_type" % (div_index))
        if current_setting:
            type_element.set_value(current_setting)
        elements.append(type_element)
        elements.append(htmlform.HTMLFragment("</div>"))

    num_games_total = sum([div_num_games[x] for x in div_num_games])

    if num_games_total == 0 or not (settings.get("numgamessubmit", "")):
        elements.append(htmlform.HTMLFragment("<div class=\"fixgenoption\">"))
        elements.append(htmlform.HTMLFormSubmitButton("submit", "Continue"))
        elements.append(htmlform.HTMLFragment("</div>"))
        return htmlform.HTMLForm(
            "POST", "/cgi-bin/fixturegen.py?tourney=%s" %
            (urllib.parse.quote_plus(tourney.name)), elements)
    else:
        return fixgen_manual.get_user_form(tourney, settings, div_rounds)
예제 #17
0
    if round_no is not None:
        games = tourney.get_games(round_no=round_no)
        rounds = tourney.get_rounds()
        round_name = None
        last_modified_element = None
        for r in rounds:
            if r["num"] == round_no:
                round_name = r.get("name", None)
                break
        if not round_name:
            round_name = "Round " + str(round_no)

        remarks = dict()

        cgicommon.writeln("<h1>Score editor: %s</h1>" %
                          cgicommon.escape(round_name))

        cgicommon.writeln("<p>")
        cgicommon.writeln(
            "<a href=\"/cgi-bin/fixtureedit.py?tourney=%s&amp;round=%d\">Edit fixtures</a>"
            % (urllib.parse.quote_plus(tourney_name), round_no))
        cgicommon.writeln("</p>")

        cgicommon.writeln("<script>")
        cgicommon.writeln("""function set_unsaved_data_warning() {
    if (window.onbeforeunload == null) {
        window.onbeforeunload = function() {
            return 'You have modified scores on this page and not saved them.';
        };
    }
}
예제 #18
0
def get_user_form(tourney, settings, div_rounds):
    num_divisions = tourney.get_num_divisions()
    div_table_sizes = dict()
    players = sorted(tourney.get_active_players(), key=lambda x: x.get_name())

    latest_round_no = tourney.get_latest_round_no()
    if latest_round_no is None:
        latest_round_no = 0

    prev_settings = settings.get_previous_settings()
    for key in prev_settings:
        if key not in settings and re.match("^d[0-9]*_groupsize$", key):
            settings[key] = prev_settings[key]
    if settings.get("submitrestore", None):
        for key in prev_settings:
            if key not in ["submit", "submitrestore", "submitplayers"]:
                settings[key] = prev_settings[key]

    elements = []
    elements.append(htmlform.HTMLFormHiddenInput("tablesizesubmit", "1"))
    elements.append(
        htmlform.HTMLFormHiddenInput("roundno", str(latest_round_no + 1)))

    # If there's a previously-saved form for this round, offer to load it
    prev_settings = settings.get_previous_settings()
    round_no = int_or_none(prev_settings.get("roundno", None))
    if round_no is not None and round_no == latest_round_no + 1:
        elements.append(
            htmlform.HTMLFragment("<div class=\"infoboxcontainer\">"))
        elements.append(htmlform.HTMLFragment("<div class=\"infoboximage\">"))
        elements.append(
            htmlform.HTMLFragment(
                "<img src=\"/images/info.png\" alt=\"Info\" />"))
        elements.append(htmlform.HTMLFragment("</div>"))
        elements.append(
            htmlform.HTMLFragment("<div class=\"infoboxmessagecontainer\">"))
        elements.append(
            htmlform.HTMLFragment("<div class=\"infoboxmessage\">"))
        elements.append(htmlform.HTMLFragment("<p>"))
        elements.append(
            htmlform.HTMLFragment(
                "There is an incomplete fixtures form saved. Do you want to carry on from where you left off?"
            ))
        elements.append(htmlform.HTMLFragment("</p>"))
        elements.append(htmlform.HTMLFragment("<p>"))
        elements.append(
            htmlform.HTMLFormSubmitButton("submitrestore",
                                          "Restore previously-saved form"))
        elements.append(htmlform.HTMLFragment("</p>"))
        elements.append(htmlform.HTMLFragment("</div></div></div>"))

    for div_index in div_rounds:
        div_players = [x for x in players if x.get_division() == div_index]
        table_size = None
        table_size_name = "d%d_groupsize" % (div_index)
        if settings.get(table_size_name, None) is not None:
            try:
                div_table_sizes[div_index] = int(settings.get(table_size_name))
            except ValueError:
                div_table_sizes[div_index] = None
        else:
            div_table_sizes[div_index] = None
        choices = []

        # Number of groups may be specified by fully-manual generator.
        # If it isn't, then use all the players.
        num_groups = int_or_none(settings.get("d%d_num_groups" % (div_index)))
        if num_groups:
            if div_table_sizes[
                    div_index] is not None and div_table_sizes[div_index] <= 0:
                raise countdowntourney.FixtureGeneratorException(
                    "%s: invalid table size for fully-manual setup." %
                    (tourney.get_division_name(div_index)))
        else:
            for size in (2, 3, 4, 5):
                if num_groups or len(div_players) % size == 0:
                    choices.append(
                        htmlform.HTMLFormChoice(
                            str(size), str(size),
                            size == div_table_sizes[div_index]))
            if len(div_players) >= 8:
                choices.append(
                    htmlform.HTMLFormChoice("-5", "5&3",
                                            div_table_sizes[div_index] == -5))

            if not choices:
                raise countdowntourney.FixtureGeneratorException(
                    "%s: number of players (%d) is not compatible with any supported table size."
                    % (tourney.get_division_name(div_index), len(div_players)))

        if num_divisions > 1:
            elements.append(
                htmlform.HTMLFragment(
                    "<h2>%s</h2>" %
                    (cgicommon.escape(tourney.get_division_name(div_index)))))

        elements.append(htmlform.HTMLFragment("<p>"))
        elements.append(
            htmlform.HTMLFormRadioButton(table_size_name, "Players per table",
                                         choices))
        elements.append(htmlform.HTMLFragment("</p>"))

    all_table_sizes_given = True
    for div in div_table_sizes:
        if div_table_sizes.get(div) is None:
            all_table_sizes_given = False

    if not all_table_sizes_given or not (settings.get("tablesizesubmit", "")):
        elements.append(htmlform.HTMLFragment("<p>"))
        elements.append(
            htmlform.HTMLFormSubmitButton(
                "submit", "Submit table sizes and select players"))
        elements.append(htmlform.HTMLFragment("</p>"))
        return htmlform.HTMLForm(
            "POST", "/cgi-bin/fixturegen.py?tourney=%s" %
            (urllib.parse.quote_plus(tourney.name)), elements)

    show_already_assigned_players = bool(settings.get("showallplayers"))

    div_num_slots = dict()
    for div_index in div_rounds:
        num_groups = int_or_none(settings.get("d%d_num_groups" % (div_index)))
        div_players = [x for x in players if x.get_division() == div_index]
        table_size = div_table_sizes[div_index]

        if num_groups:
            # If num_groups is specified, then we can't use the 5&3 setup.
            # If it's any other table setup then the number of player slots is
            # the number of players per table times num_groups.
            if table_size <= 0:
                raise countdowntourney.FixtureGeneratorException(
                    "%s: invalid table size for fully-manual setup" %
                    (tourney.get_division_name(div_index)))
            else:
                num_slots = table_size * num_groups
        else:
            # If num_groups is not specified, then the number if slots is
            # simply the number of active players in this division.
            num_slots = len(div_players)

        div_num_slots[div_index] = num_slots

        if table_size > 0 and num_slots % table_size != 0:
            raise countdowntourney.FixtureGeneratorException(
                "%s: table size of %d is not allowed, as the number of player slots (%d) is not a multiple of it."
                %
                (tourney.get_division_name(div_index), table_size, num_slots))

        if table_size == -5 and num_slots < 8:
            raise countdowntourney.FixtureGeneratorException(
                "%s: can't use table sizes of five and three - you need at least 8 players and you have %d"
                % (tourney.get_division_name(div_index), num_slots))

        if table_size not in (2, 3, 4, 5, -5):
            raise countdowntourney.FixtureGeneratorException(
                "%s: invalid table size: %d" %
                (tourney.get_division_name(div_index), table_size))

    div_set_players = dict()
    div_duplicate_slots = dict()
    div_empty_slots = dict()
    div_invalid_slots = dict()
    div_count_in_standings = dict()
    div_set_text = dict()
    div_game_type = dict()
    all_filled = True
    for div_index in div_rounds:
        div_players = [x for x in players if x.get_division() == div_index]
        num_groups = int_or_none(settings.get("d%d_num_groups" % (div_index)))

        num_slots = div_num_slots[div_index]

        set_players = [None for i in range(0, num_slots)]
        set_text = ["" for i in range(0, num_slots)]

        game_type = settings.get("d%d_game_type" % (div_index))

        if not game_type:
            if not settings.get("submitplayers"):
                count_in_standings = True
            else:
                count_in_standings = settings.get("d%d_heats" % (div_index))
                if count_in_standings is None:
                    count_in_standings = False
                else:
                    count_in_standings = True
        else:
            count_in_standings = (game_type == "P")

        # Slot numbers which contain text that doesn't match any player name
        invalid_slots = []

        allow_player_repetition = int_or_none(
            settings.get("d%d_allow_player_repetition" % (div_index)))
        if allow_player_repetition is None:
            allow_player_repetition = False
        else:
            allow_player_repetition = bool(allow_player_repetition)

        # Ask the user to fill in N little drop-down boxes, where N is the
        # number of players, to decide who's going on what table.
        for player_index in range(0, num_slots):
            name = settings.get("d%d_player%d" % (div_index, player_index))
            if name is None:
                name = ""
            set_text[player_index] = name
            if name:
                set_players[player_index] = lookup_player(div_players, name)
                if set_players[player_index] is None:
                    invalid_slots.append(player_index)
            else:
                set_players[player_index] = None

        # Slot numbers which contain a player already contained in another slot
        duplicate_slots = []

        # Slot numbers which don't contain a player
        empty_slots = []

        player_index = 0
        for p in set_players:
            if player_index in invalid_slots:
                all_filled = False
            elif p is None:
                empty_slots.append(player_index)
                all_filled = False
            else:
                if not allow_player_repetition:
                    count = 0
                    for q in set_players:
                        if q is not None and q.get_name() == p.get_name():
                            count += 1
                    if count > 1:
                        duplicate_slots.append(player_index)
                        all_filled = False
            player_index += 1

        div_set_players[div_index] = set_players
        div_duplicate_slots[div_index] = duplicate_slots
        div_empty_slots[div_index] = empty_slots
        div_invalid_slots[div_index] = invalid_slots
        div_count_in_standings[div_index] = count_in_standings
        div_set_text[div_index] = set_text
        div_game_type[div_index] = game_type

    interface_type = int_or_none(
        settings.get("interfacetype", INTERFACE_AUTOCOMPLETE))

    if all_filled and settings.get("submitplayers"):
        # All slots filled, don't need to ask the user anything more
        return None

    elements = []
    elements.append(
        htmlform.HTMLFormHiddenInput("roundno", str(latest_round_no + 1)))
    elements.append(
        htmlform.HTMLFragment("""<style type=\"text/css\">
table.seltable {
    margin-top: 20px;
}
.seltable td {
    padding: 2px;
    border: 2px solid white;
}
td.tablenumber {
    font-family: "Cabin";
    background-color: blue;
    color: white;
    text-align: center;
    min-width: 1.5em;
}
.duplicateplayer {
    background-color: violet;
}
.emptyslot {
    /*background-color: #ffaa00;*/
}
.invalidslot {
    background-color: red;
}
.validslot {
    background-color: #00cc00;
}
</style>
"""))
    elements.append(
        htmlform.HTMLFragment("""<script>
function set_unsaved_data_warning() {
    if (window.onbeforeunload == null) {
        window.onbeforeunload = function() {
            return "You have modified entries on this page and not submitted them. If you navigate away from the page, these changes will be lost.";
        };
    }
}

function unset_unsaved_data_warning() {
    window.onbeforeunload = null;
}
</script>
"""))

    autocomplete_script = "<script>\n"
    autocomplete_script += "var divPlayerNames = "

    div_player_names = {}
    for div_index in div_rounds:
        name_list = [
            x.get_name() for x in players if x.get_division() == div_index
        ]
        div_player_names[div_index] = name_list
    autocomplete_script += json.dumps(div_player_names, indent=4) + ";\n"

    autocomplete_script += """
function setLastEditedBox(controlId) {
    var lastEdited = document.getElementById("lasteditedinput");
    if (lastEdited != null) {
        lastEdited.value = controlId;
    }
}

function editBoxEdit(divIndex, controlId) {
    var control = document.getElementById(controlId);
    if (control == null)
        return;

    setLastEditedBox(controlId);

    var value = control.value;
    //console.log("editBoxEdit() called, value " + value);
    var previousValue = control.getAttribute("previousvalue");

    /* If the change has made the value longer, then proceed. Otherwise don't
       do any autocompletion because that would interfere with the user's
       attempt to backspace out the text. */
    //console.log("editBoxEdit() called, value " + value + ", previousValue " + previousValue);

    control.setAttribute("previousvalue", value);

    if (previousValue != null && value.length <= previousValue.length) {
        return;
    }

    /* Take the portion of the control's value from the start of the string
       to the start of the selected part. If that string is the start of
       exactly one player's name, then:
       1. Set the control's value to the player's full name
       2. Highlight the added portion
       3. Leave the cursor where it was before.
    */
    var validNames = divPlayerNames[divIndex];
    if (validNames) {
        var lastMatch = null;
        var numMatches = 0;
        var selStart = control.selectionStart;

        // head is the part the user typed in, i.e. the bit not highlighted
        var head = value.toLowerCase().substring(0, selStart);
        for (var i = 0; i < validNames.length; ++i) {
            if (validNames[i].toLowerCase().startsWith(head)) {
                numMatches++;
                lastMatch = validNames[i];
            }
        }

        if (numMatches == 1) {
            control.focus();
            control.value = lastMatch;
            control.setSelectionRange(head.length, lastMatch.length);
        }
    }
}
"""

    autocomplete_script += "</script>\n"
    elements.append(htmlform.HTMLFragment(autocomplete_script))

    elements.append(
        htmlform.HTMLFragment(
            "<p>Enter player names below. Each horizontal row is one group, or table.</p>"
        ))

    choice_data = [("Auto-completing text boxes", INTERFACE_AUTOCOMPLETE),
                   ("Drop-down boxes", INTERFACE_DROP_DOWN),
                   ("Combo boxes (not supported on all browsers)",
                    INTERFACE_DATALIST)]
    choices = [
        htmlform.HTMLFormChoice(str(x[1]), x[0], interface_type == x[1])
        for x in choice_data
    ]
    interface_menu = htmlform.HTMLFormRadioButton(
        "interfacetype", "Player name selection interface", choices)
    elements.append(interface_menu)

    if interface_type == INTERFACE_DROP_DOWN:
        elements.append(htmlform.HTMLFragment("<div class=\"fixgenoption\">"))
        elements.append(
            htmlform.HTMLFormCheckBox(
                "showallplayers",
                "Show all players in drop-down boxes, even those already assigned a table",
                show_already_assigned_players))
        elements.append(htmlform.HTMLFragment("</div>"))

    (acc_tables, acc_default) = tourney.get_accessible_tables()

    table_no = 1
    for div_index in div_rounds:
        div_players = [x for x in players if x.get_division() == div_index]
        player_index = 0
        table_size = div_table_sizes[div_index]
        duplicate_slots = div_duplicate_slots[div_index]
        invalid_slots = div_invalid_slots[div_index]
        empty_slots = div_empty_slots[div_index]
        set_players = div_set_players[div_index]
        set_text = div_set_text[div_index]
        num_slots = div_num_slots[div_index]
        game_type = div_game_type[div_index]

        if num_divisions > 1:
            elements.append(
                htmlform.HTMLFragment(
                    "<h2>%s</h2>" %
                    (cgicommon.escape(tourney.get_division_name(div_index)))))

        if not game_type:
            # Ask the user if they want these games to count towards the
            # standings table (this is pretty much universally yes)
            elements.append(
                htmlform.HTMLFragment("<div class=\"fixgenoption\">"))
            elements.append(
                htmlform.HTMLFormCheckBox(
                    "d%d_heats" % (div_index),
                    "Count the results of these matches in the standings table",
                    div_count_in_standings[div_index]))
            elements.append(htmlform.HTMLFragment("</div>"))

        # Show the table of groups for the user to fill in
        elements.append(htmlform.HTMLFragment("<table class=\"seltable\">\n"))
        prev_table_no = None
        unselected_names = [x.get_name() for x in div_players]

        if table_size > 0:
            table_sizes = [
                table_size for i in range(0, num_slots // table_size)
            ]
        else:
            table_sizes = countdowntourney.get_5_3_table_sizes(num_slots)

        for p in set_players:
            if p and p.get_name() in unselected_names:
                unselected_names.remove(p.get_name())

        for table_size in table_sizes:
            elements.append(htmlform.HTMLFragment("<tr>\n"))
            elements.append(
                htmlform.HTMLFragment(
                    "<td>%s</td><td class=\"tablenumber\">%d</td>\n" %
                    (" &#9855;" if
                     (table_no in acc_tables) != acc_default else "",
                     table_no)))
            if game_type is not None:
                elements.append(
                    htmlform.HTMLFragment(
                        "<td class=\"fixturegametype\">%s</td>" %
                        (cgicommon.escape(game_type, True))))
            for i in range(table_size):
                p = set_players[player_index]
                td_style = ""
                value_is_valid = False
                if player_index in duplicate_slots:
                    td_style = "class=\"duplicateplayer\""
                elif player_index in empty_slots:
                    td_style = "class=\"emptyslot\""
                elif player_index in invalid_slots:
                    td_style = "class=\"invalidslot\""
                else:
                    td_style = "class=\"validslot\""
                    value_is_valid = True
                elements.append(htmlform.HTMLFragment("<td %s>" % td_style))

                # Make a drop down list with every unassigned player in it
                player_option_list = []

                if interface_type == INTERFACE_DROP_DOWN:
                    # Drop-down list needs an initial "nothing selected" option
                    player_option_list.append(
                        htmlform.HTMLFormDropDownOption("", " -- select --"))
                selected_name = ""

                if show_already_assigned_players:
                    name_list = [x.get_name() for x in div_players]
                else:
                    if p:
                        name_list = sorted(unselected_names + [p.get_name()])
                    else:
                        name_list = unselected_names

                for q in name_list:
                    if p is not None and q == p.get_name():
                        selected_name = p.get_name()
                    if interface_type == INTERFACE_DROP_DOWN:
                        player_option_list.append(
                            htmlform.HTMLFormDropDownOption(q, q))
                    else:
                        player_option_list.append(q)
                if interface_type != INTERFACE_DROP_DOWN and not selected_name:
                    selected_name = set_text[player_index]

                # Select the appropriate player
                control_name = "d%d_player%d" % (div_index, player_index)
                if interface_type == INTERFACE_DATALIST:
                    sel = htmlform.HTMLFormComboBox(
                        control_name,
                        player_option_list,
                        other_attrs={
                            "onchange": "set_unsaved_data_warning();"
                        })
                elif interface_type == INTERFACE_DROP_DOWN:
                    sel = htmlform.HTMLFormDropDownBox(
                        control_name,
                        player_option_list,
                        other_attrs={
                            "onchange": "set_unsaved_data_warning();"
                        })
                elif interface_type == INTERFACE_AUTOCOMPLETE:
                    sel = htmlform.HTMLFormTextInput(
                        "",
                        control_name,
                        selected_name,
                        other_attrs={
                            "oninput":
                            "editBoxEdit(%d, \"%s\");" %
                            (div_index, control_name),
                            "onclick":
                            "if (this.selectionStart == this.selectionEnd) { this.select(); }",
                            "id":
                            control_name,
                            "validvalue":
                            "1" if value_is_valid else "0",
                            "previousvalue":
                            selected_name,
                            "class":
                            "playerslot"
                        })
                else:
                    sel = None

                sel.set_value(selected_name)

                elements.append(sel)
                elements.append(htmlform.HTMLFragment("</td>"))
                player_index += 1
            table_no += 1
            elements.append(htmlform.HTMLFragment("</tr>\n"))

        elements.append(htmlform.HTMLFragment("</table>\n"))

        if len(acc_tables) > 0:
            # Warn the user that the table numbers displayed above might not
            # end up being the final table numbers.
            elements.append(
                htmlform.HTMLFragment(
                    "<p style=\"font-size: 10pt\">Note: You have designated accessible tables, so the table numbers above may be automatically reassigned to fulfil accessibility requirements.</p>"
                ))

        # Add the submit button
        elements.append(htmlform.HTMLFragment("<p>\n"))
        elements.append(htmlform.HTMLFormHiddenInput("submitplayers", "1"))
        elements.append(
            htmlform.HTMLFormHiddenInput("lasteditedinput",
                                         "",
                                         other_attrs={"id":
                                                      "lasteditedinput"}))
        elements.append(
            htmlform.HTMLFormSubmitButton("submit",
                                          "Submit",
                                          other_attrs={
                                              "onclick":
                                              "unset_unsaved_data_warning();",
                                              "class": "bigbutton"
                                          }))
        elements.append(htmlform.HTMLFragment("</p>\n"))

        if invalid_slots:
            elements.append(
                htmlform.HTMLFragment(
                    "<p>You have slots with unrecognised player names; these are highlighted in <span style=\"color: red; font-weight: bold;\">red</span>.</p>"
                ))
        if duplicate_slots:
            elements.append(
                htmlform.HTMLFragment(
                    "<p>You have players in multiple slots; these are highlighted in <span style=\"color: violet; font-weight: bold;\">violet</span>.</p>"
                ))

        if unselected_names:
            elements.append(
                htmlform.HTMLFragment(
                    "<p>Players still to be given a table:\n"))
            for i in range(len(unselected_names)):
                name = unselected_names[i]
                elements.append(
                    htmlform.HTMLFragment(
                        "%s%s" %
                        (cgicommon.escape(name, True),
                         "" if i == len(unselected_names) - 1 else ", ")))
            elements.append(htmlform.HTMLFragment("</p>\n"))

        elements.append(
            htmlform.HTMLFormHiddenInput("d%d_groupsize" % (div_index),
                                         str(div_table_sizes[div_index])))

        show_standings = int_or_none(
            settings.get("d%d_show_standings" % (div_index)))
        if show_standings:
            elements.append(
                htmlform.HTMLFormStandingsTable("d%d_standings" % (div_index),
                                                tourney, div_index))

    last_edited_input_name = settings.get("lasteditedinput", "")
    set_element_focus_script = """
<script>
var lastEditedElementName = %s;

var playerBoxes = document.getElementsByClassName("playerslot");
var playerBoxesBefore = [];
var playerBoxesAfter = [];
var foundElement = false;

for (var i = 0; i < playerBoxes.length; ++i) {
    if (playerBoxes[i].name == lastEditedElementName) {
        foundElement = true;
    }
    if (foundElement) {
        playerBoxesAfter.push(playerBoxes[i]);
    }
    else {
        playerBoxesBefore.push(playerBoxes[i]);
    }
}
//console.log("playerBoxesAfter " + playerBoxesAfter.length.toString() + ", playerBoxesBefore " + playerBoxesBefore.length.toString());

/* Give focus to the first text box equal to or after this one which
   does not have a valid value in it. If there are no such text boxes,
   search from the beginning of the document onwards. */
var playerBoxOrder = playerBoxesAfter.concat(playerBoxesBefore);

for (var i = 0; i < playerBoxOrder.length; ++i) {
    var box = playerBoxOrder[i];
    var validValue = box.getAttribute("validvalue");
    if (validValue == null || validValue == "0") {
        box.focus();
        box.select();
        break;
    }
}
</script>
""" % (json.dumps(last_edited_input_name))
    elements.append(htmlform.HTMLFragment(set_element_focus_script))

    form = htmlform.HTMLForm(
        "POST", "/cgi-bin/fixturegen.py?tourney=%s" %
        (urllib.parse.quote_plus(tourney.name)), elements)
    return form
예제 #19
0
            cgicommon.show_success_box("Players successfully rerated by player ID.")
        except countdowntourney.TourneyException as e:
            cgicommon.show_tourney_exception(e)

    if tourney.get_num_games() == 0:
        cgicommon.writeln("<p>No games have been played yet.</p>")
    else:
        cgicommon.writeln("<p>Each player is assigned a seed according to their rating, with the top-rated player in a division being the #1 seed, and so on down. Players are listed here in order of the difference between their position in the standings table and their seed position.</p>")

        num_divisions = tourney.get_num_divisions()
        do_show_rerate_button = False
        for div_index in range(num_divisions):
            div_name = tourney.get_division_name(div_index)
            overachievements = tourney.get_players_overachievements(div_index)
            if num_divisions > 1:
                cgicommon.writeln("<h2>%s</h2>" % (cgicommon.escape(div_name)))
            if not overachievements:
                cgicommon.writeln("<p>There are no players to show.</p>")
                continue
            if tourney.are_player_ratings_uniform(div_index):
                cgicommon.show_warning_box("<p>All the players have the same rating. This means the Overachievers table won't be meaningful. If when you set up the tournament you pasted the players into the player list in order of rating but forgot to tell Atropine you'd done that, try the \"Rerate players by player ID\" button below.</p>")
                do_show_rerate_button = True
            else:
                cgicommon.writeln("<table class=\"miscranktable\">")
                cgicommon.writeln("<tr>")
                cgicommon.writeln("<th></th><th>Player</th><th>Seed</th><th>Pos</th><th>+/-</th>")
                cgicommon.writeln("</tr>")
                pos = 0
                joint = 1
                prev_overachievement = None
                for row in overachievements:
예제 #20
0
    num_losing_games = cgicommon.int_or_none(form.getfirst("numlosinggames", 3))
    if num_losing_games is None or num_losing_games <= 0:
        num_losing_games = 3

    cgicommon.writeln("<div class=\"mainpane\">")

    cgicommon.writeln("<h1>Tuff Luck</h1>")

    cgicommon.writeln("<form action=\"/cgi-bin/tuffluck.py\" method=\"GET\">")
    cgicommon.writeln("<p>")
    cgicommon.writeln("A player's Tuff Luck is their aggregate losing margin over their")
    cgicommon.writeln("<input type=\"number\" name=\"numlosinggames\" value=\"%d\" min=\"1\" max=\"999\" size=\"3\" />" % (num_losing_games))
    cgicommon.writeln("closest losing games, for players who have lost at least that many games.")
    cgicommon.writeln("</p>")
    cgicommon.writeln("<p>")
    cgicommon.writeln("<input type=\"hidden\" name=\"tourney\" value=\"%s\" />" % (cgicommon.escape(tourney_name, True)))
    cgicommon.writeln("<input type=\"submit\" name=\"submit\" value=\"Refresh\" />")
    cgicommon.writeln("</p>")
    cgicommon.writeln("</form>")

    players_tuff_luck = tourney.get_players_tuff_luck(num_losing_games)

    pos = 0
    joint = 1
    prev_tuffness = None
    if not players_tuff_luck:
        cgicommon.writeln("<p>No players have lost %d or more games.</p>" % (num_losing_games))
    else:
        cgicommon.writeln("<table class=\"miscranktable\">")
        cgicommon.writeln("<tr>")
        cgicommon.writeln("<th></th><th>Player</th><th>Margins</th><th>Tuff Luck</th>")
예제 #21
0
        username = state.get("username", "")
    if not password:
        password = state.get("password", "")
    if private_tourney is None:
        private_tourney = state.get("private", None)
        if private_tourney is None:
            private_tourney = tourney.is_broadcast_private()

    upload_on = state.get("publishing", False)

    if exception_text:
        cgicommon.show_error_text(exception_context + ": " + exception_text)
    if delete_success:
        cgicommon.show_success_box(
            "Successfully deleted tourney <strong>%s</strong> from the website."
            % (cgicommon.escape(tourney_name)))

    web_link = colive_url_base + "/" + cgicommon.escape(tourney_name, True)
    web_link_raw = colive_url_base + "/" + tourney_name
    cgicommon.writeln(
        "<p>This will upload the tourney state every few seconds so that games, scores and standings are visible at <a href=\"%s\" target=\"_blank\">%s <img src=\"/images/opensinnewwindow.png\" alt=\"Opens in new window\"/></a></p>"
        % (web_link, web_link))
    cgicommon.writeln("<p>You will need:</p>")
    cgicommon.writeln("<ul>")
    cgicommon.writeln(
        "<li>A username and password for the server at %s. If you don't have these, then ignore this whole feature. Just pretend it doesn't exist.</li>"
        % (cgicommon.escape(uploader.http_server_host)))
    cgicommon.writeln("<li>A connection to the internet.</li>")
    cgicommon.writeln("</ul>")
    cgicommon.writeln(
        "<p>If you lose internet access, uploads will be suspended but everything that doesn't require internet access such as results entry, fixture generation and the public display window will be unaffected. Uploads to the server will resume when the internet connection is restored.</p>"
예제 #22
0
파일: sql.py 프로젝트: elocemearg/atropine
# Write the sidebar, but not the normal sidebar, because that requires a
# tourney, and we might not have a usable one.
cgicommon.writeln("<div class=\"sidebar sqlsidebar\">")

cgicommon.writeln("<div style=\"margin-bottom: 20px;\">")
cgicommon.writeln(
    "<img src=\"/images/eyebergine128.png\" alt=\"Eyebergine\" />")
cgicommon.writeln("</div>")

cgicommon.writeln("<div class=\"sqlsidebarname\">")
if tourney_name:
    cgicommon.writeln(
        "<a href=\"/cgi-bin/tourneysetup.py?tourney=%s\">%s</a>" %
        (urllib.parse.quote_plus(tourney_name),
         cgicommon.escape(tourney_name)))
cgicommon.writeln("</div>")

# Display list of tables and views, which can be expanded to show columns
if db:
    for (tl, object_type) in ((tables, "Tables"), (views, "Views")):
        cgicommon.writeln("<div class=\"sqldictsection\">")
        cgicommon.writeln("<div class=\"sqldictsectionheading\">%s</div>" %
                          (cgicommon.escape(object_type)))
        cgicommon.writeln("<ul class=\"sqldict\">")
        for tab in tl:
            tab_escaped = cgicommon.escape(tab.get_name())
            tab_sq_escaped = "".join(
                [x if x != '\'' else '\\\'' for x in tab.get_name()])
            cgicommon.writeln(
                "<li class=\"tablename handcursor\" onclick=\"clickTableName('%s');\"><span style=\"display: inline-block; min-width: 0.75em;\" id=\"table_expand_symbol_%s\">&#x25b8;</span> %s</li>"
예제 #23
0
def get_user_form(tourney, settings, div_rounds):
    div_group_size = dict()
    div_init_max_rematches = dict()
    div_init_max_win_diff = dict()

    prev_settings = settings.get_previous_settings()
    for key in prev_settings:
        if key not in settings and key != "submit":
            settings[key] = prev_settings[key]

    rounds = tourney.get_rounds();

    num_divisions = tourney.get_num_divisions()

    max_time = int_or_none(settings.get("maxtime", None))
    ignore_rematches_before_round = int_or_none(settings.get("ignorerematchesbefore", None))

    div_ready = []
    for div in range(num_divisions):
        if div in div_rounds:
            div_ready.append(False)
        else:
            div_ready.append(True)

    default_group_size = int_or_none(settings.get("groupsize", None))

    for div_index in sorted(div_rounds):
        group_size = int_or_none(settings.get("d%d_groupsize" % (div_index), None))
        if group_size is None or group_size == 0:
            group_size = default_group_size

        init_max_rematches = int_or_none(settings.get("d%d_initmaxrematches" % (div_index), "0"))

        init_max_win_diff = int_or_none(settings.get("d%d_initmaxwindiff" % (div_index), 0))

        games = tourney.get_games(game_type='P', division=div_index);
        players = [x for x in tourney.get_active_players() if x.division == div_index];

        if max_time is not None and max_time > 0 and group_size in valid_group_sizes and (group_size == -5 or len(players) % group_size == 0):
            div_ready[div_index] = True
#        else:
#            if max_time is None or max_time == 0:
#                max_time = 30;
#            if group_size is None or group_size not in valid_group_sizes:
#                if len(players) % 3 == 0:
#                    group_size = 3
#                elif len(players) % 2 == 0:
#                    group_size = 2
#                elif len(players) % 5 == 0:
#                    group_size = 5
#                elif len(players) >= 8:
#                    group_size = -5
#                elif len(players) % 4 == 0:
#                    group_size = 4
#                else:
#                    group_size = None

        div_group_size[div_index] = group_size
        div_init_max_rematches[div_index] = init_max_rematches
        div_init_max_win_diff[div_index] = init_max_win_diff

    if False not in div_ready and settings.get("submit") is not None:
        return None

    elements = [];
    javascript = """
<script type="text/javascript">
var click_time = 0;
var limit_seconds = 0;
var noticed_results_overdue = false;

var gerunds = ["Reticulating", "Exaggerating", "Refrigerating",
            "Bisecting", "Reordering", "Unseeding", "Reconstituting",
            "Inverting", "Convolving", "Reinventing", "Overpopulating",
            "Unwedging", "Tenderising", "Refactoring", "Frobnicating",
            "Normalising", "Factorising", "Transforming", "Relaying",
            "Decoupling", "Randomising", "Ignoring", "Disposing of",
            "Translating", "Restarting", "Entertaining", "Checking",
            "Verifying", "Flushing", "Contextualising", "Deconstructing",
            "Justifying", "Hacking", "Redrawing", "Reimagining",
            "Reinterpreting", "Reasoning with", "Impersonating",
            "Abbreviating", "Underestimating", "Misappropriating",
            "Constructing", "Preparing", "Redelivering", "Arguing over",
            "Grilling", "Baking", "Poaching", "Washing", "Stealing",
            "Emulsifying", "Discombobulating", "Correcting", "Extracting",
            "Unspooling", "Descaling", "Duplicating", "Overwriting" ];

var nouns = ["seeding list", "rule book", "hypergrid",
            "network services", "timestamps", "multidimensional array",
            "decision tree", "player list", "weighting matrix",
            "instrument panel", "database", "videprinter",
            "standings table", "preclusion rules", "event handlers",
            "dynamic modules", "hypertext", "fixture generator",
            "linked lists", "hash tables", "system clock", "file descriptors",
            "syntax tree", "binary tree", "dictionary", "homework",
            "breakfast", "contextualiser", "splines", "supercluster",
            "record books", "sandwiches", "grouping strategy", "reality",
            "spatula", "Eyebergine", "scripts", "blockchain", "phone charger",
            "fixtures", "associative arrays", "browser window", "subfolders"
            ];

var endings = [
    "Bribing officials", "Talking bollocks", "Feeding cat",
    "Rewinding tape", "Invading privacy", "Falling off cliff",
    "Kicking tyres", "Tapping barometer", "Serving hot",
    "Deploying parachute", "Cleaning up mess", "Straightening tie",
    "Seasoning to taste", "Stealing towels", "Reversing polarity",
    "Untangling headphones", "Compounding misery"
];

function spam_progress_label() {
    var progress = "";
    var pc = 0;
    var ms_elapsed = 0;

    if (limit_seconds != NaN) {
        current_time = new Date();
        ms_elapsed = current_time.getTime() - click_time.getTime();
        pc = Math.floor(ms_elapsed * 100 / (limit_seconds * 1000));
        if (pc > 100) {
            pc = 100;
        }
        progress = pc.toString() + "%";
    }

    if (ms_elapsed < 500) {
        document.getElementById('progresslabel').innerHTML = "Generating fixtures...";
    }
    else if (pc < 100) {
        if (Math.random() < 0.4) {
            var gerund = "";
            var noun = "";

            gerund = gerunds[Math.floor(Math.random() * gerunds.length)];
            noun = nouns[Math.floor(Math.random() * nouns.length)];

            document.getElementById('progresslabel').innerHTML = progress + " " + gerund + " " + noun + "...";
        }
    }
    else if (ms_elapsed < limit_seconds * 1000 + 3000) {
        if (!noticed_results_overdue) {
            var ending = endings[Math.floor(Math.random() * endings.length)];
            document.getElementById('progresslabel').innerHTML = "100% " + ending + "...";
            noticed_results_overdue = true;
        }
    }
    else {
        document.getElementById('progresslabel').innerHTML = "We ought to have finished by now.";
    }
}
function generate_fixtures_clicked() {
    click_time = new Date();
    noticed_results_overdue = false;
    limit_seconds = parseInt(document.getElementById('maxtime').value) * parseInt(document.getElementById('numdivisions').value);
    // document.getElementById('generatefixtures').disabled = true;
    spam_progress_label();
    setInterval(function() { spam_progress_label(); }, 300);
}
</script>""";
    elements.append(htmlform.HTMLFragment(javascript));

    elements.append(htmlform.HTMLFragment("<h2>Overall settings</h2>"))

    div_valid_table_sizes = []
    for div_index in sorted(div_rounds):
        div_players = [x for x in tourney.get_active_players() if x.get_division() == div_index]
        sizes = get_valid_group_sizes(len(div_players), len(rounds))
        div_valid_table_sizes.append(sizes)

    table_sizes_valid_for_all_divs = []
    for size in valid_group_sizes:
        for div_sizes in div_valid_table_sizes:
            if size not in div_sizes:
                break
        else:
            table_sizes_valid_for_all_divs.append(size)
    for size in (3, 2, 5, -5, 4):
        if size in table_sizes_valid_for_all_divs:
            default_default_group_size = size
            break
    else:
        default_default_group_size = None

    
    if num_divisions > 1 and len(table_sizes_valid_for_all_divs) > 0:
        elements.append(htmlform.HTMLFragment("<p>"))
        group_size_choices = [ htmlform.HTMLFormChoice(str(gs),
            "5&3" if gs == -5 else str(gs),
            int_or_none(settings.get("groupsize", default_default_group_size)) == gs) for gs in table_sizes_valid_for_all_divs ]
        elements.append(htmlform.HTMLFormRadioButton("groupsize", "Default players per table", group_size_choices))
        elements.append(htmlform.HTMLFragment("</p>"))

    elements.append(htmlform.HTMLFragment("<p>\n"))
    elements.append(htmlform.HTMLFormTextInput("Fixture generator time limit %s(seconds)" % ("per division " if num_divisions > 1 else ""),
        "maxtime", settings.get("maxtime", "30"),
        other_attrs={"size": "3", "id" : "maxtime"}));
    elements.append(htmlform.HTMLFragment("</p>\n<p>\n"))
    elements.append(htmlform.HTMLFormTextInput("For the purpose of avoiding rematches, disregard games before round ", "ignorerematchesbefore", str(ignore_rematches_before_round) if ignore_rematches_before_round is not None else "", other_attrs={"size": "3"}));
    elements.append(htmlform.HTMLFragment(" (leave blank to count all rematches)"))
    elements.append(htmlform.HTMLFormHiddenInput("numdivisions", str(len(div_rounds)), other_attrs={"id" : "numdivisions"}))
    elements.append(htmlform.HTMLFragment("</p>\n"))
    elements.append(htmlform.HTMLFragment("<hr />\n"))

    for div_index in sorted(div_rounds):
        group_size = div_group_size[div_index]
        init_max_rematches = div_init_max_rematches[div_index]
        init_max_win_diff = div_init_max_win_diff[div_index]
        players = [x for x in tourney.get_active_players() if x.division == div_index];
        div_prefix = "d%d_" % (div_index)

        if num_divisions > 1:
            elements.append(htmlform.HTMLFragment("<h2>%s (%d active players)</h2>" % (cgicommon.escape(tourney.get_division_name(div_index)), len(players))))
        else:
            elements.append(htmlform.HTMLFragment("<h2>Fixture generation (%d active players)</h2>" % (len(players))))

        elements.append(htmlform.HTMLFragment("<p>"))

        div_valid_sizes = get_valid_group_sizes(len(players), len(rounds))
        ticked_group_size = int_or_none(settings.get(div_prefix + "groupsize"))
        if ticked_group_size is None:
            if len(table_sizes_valid_for_all_divs) > 0 and num_divisions > 1:
                # There is a "default table size" option
                ticked_group_size = 0
            else:
                ticked_group_size = get_default_group_size(len(players), len(rounds))
        group_size_choices = [ htmlform.HTMLFormChoice(str(gs), "5&3" if gs == -5 else str(gs), gs == ticked_group_size) for gs in div_valid_sizes ]
        if num_divisions > 1 and len(table_sizes_valid_for_all_divs) > 0:
            group_size_choices = [ htmlform.HTMLFormChoice("0", "Round default (above)", ticked_group_size == 0) ] + group_size_choices

        elements.append(htmlform.HTMLFormRadioButton(div_prefix + "groupsize", "Players per table", group_size_choices))
        elements.append(htmlform.HTMLFragment("</p>\n"))
        elements.append(htmlform.HTMLFragment("<p>Increase the following values if the fixture generator has trouble finding a grouping within the time limit.</p>\n"));
        
        elements.append(htmlform.HTMLFragment("<blockquote>"))
        elements.append(htmlform.HTMLFormTextInput("Initial maximum rematches between players", div_prefix + "initmaxrematches", str(init_max_rematches), other_attrs={"size" : "3"}))
        elements.append(htmlform.HTMLFragment("</blockquote>\n<blockquote>"))
        elements.append(htmlform.HTMLFormTextInput("Initial maximum win count difference between players", div_prefix + "initmaxwindiff", str(init_max_win_diff), other_attrs={"size" : "3"}))
        elements.append(htmlform.HTMLFragment("</blockquote>\n"))
        if num_divisions > 1:
            elements.append(htmlform.HTMLFragment("<hr />\n"))

    elements.append(htmlform.HTMLFormSubmitButton("submit", "Generate Fixtures", other_attrs={"onclick": "generate_fixtures_clicked();", "id": "generatefixtures", "class" : "bigbutton"}));
    elements.append(htmlform.HTMLFragment("<p id=\"progresslabel\">For large numbers of players or unusual formats, fixture generation is not immediate - it can take up to the specified number of seconds, or longer if no permissible configurations are found in that time.</p><hr /><p></p>"));
    elements.append(htmlform.HTMLFragment("<noscript>Your browser doesn't have Javascript enabled, which means you miss out on progress updates while fixtures are being generated.</noscript>"));

    form = htmlform.HTMLForm("POST", "/cgi-bin/fixturegen.py", elements);
    return form;
예제 #24
0
cgicommon.show_sidebar(tourney, show_misc_table_links=True)

cgicommon.writeln("<div class=\"mainpane\">")

rd = tourney.get_current_round()

if rd is None:
    cgicommon.writeln("<h1>Table assignment</h1>")
    cgicommon.writeln("<p>There are no fixtures yet.</p>")
else:
    round_no = rd["num"]
    round_name = rd["name"]

    cgicommon.writeln("<h1>Table assignment: %s</h1>" %
                      (cgicommon.escape(round_name)))
    games = tourney.get_games(round_no)

    # Map of player name -> list of table numbers they're on in this round
    player_name_to_table_list = dict()

    # Map of player name -> player object
    player_name_to_player = dict()

    # Map of table number -> list of players
    table_to_player_list = dict()

    for g in games:
        names = []
        current_player_list = table_to_player_list.get(g.table_no, [])
        for p in [g.p1, g.p2]:
예제 #25
0
                wikitext_date_y = today.year

            wikitext_game_prefix = ""
            for c in tourney_name.upper():
                if c.isupper() or c.isdigit():
                    wikitext_game_prefix += c
            if wikitext_game_prefix[-1].isdigit():
                wikitext_game_prefix += "."

        cgicommon.writeln("<div class=\"mainpane\">")
        cgicommon.writeln("<h1>Tournament report - Wikitext</h1>")
        if errors:
            cgicommon.writeln("<h2>Failed to generate wikitext...</h2>")
            cgicommon.writeln("<blockquote>")
            for txt in errors:
                cgicommon.writeln("<li>%s</li>" % (cgicommon.escape(txt)))
            cgicommon.writeln("</blockquote>")

        cgicommon.writeln("<p>")
        cgicommon.writeln(
            "Select the date the tournament was played, and a string to prefix each game ID. Then generate the wikitext for copy-pasting into a new wiki page."
        )
        cgicommon.writeln("</p>")
        cgicommon.writeln(
            "<form method=\"GET\" action=\"/cgi-bin/export.py\">")
        cgicommon.writeln("<table>")
        cgicommon.writeln("<tr><td>Day</td><td>Month</td><td>Year</td></tr>")
        cgicommon.writeln("<tr>")
        cgicommon.writeln(
            "<td><input type=\"number\" name=\"wikitextday\" value=\"%d\" min=\"1\" max=\"31\" size=\"2\" /></td>"
            % (wikitext_date_d))
예제 #26
0
def fatal_error(text):
    cgicommon.print_html_head("Table Index")
    cgicommon.writeln("<body>")
    cgicommon.writeln("<p>%s</p>" % (cgicommon.escape(text)))
    cgicommon.writeln("</body></html>")
    sys.exit(1)
예제 #27
0
파일: home.py 프로젝트: elocemearg/atropine
cgicommon.writeln("<body>")
cgicommon.writeln("<h1>Welcome to Atropine</h1>")

if cgicommon.is_client_from_localhost():
    # Client is from localhost, so serve the administrator's front page, which
    # produces a menu of tournaments and the ability to create a new one.
    tourney_created = False

    if request_method == "POST" and tourneyname:
        try:
            tourney = countdowntourney.tourney_create(tourneyname,
                                                      cgicommon.dbdir)
            tourney.close()
            cgicommon.show_success_box(
                "Tourney \"%s\" was created successfully." %
                cgicommon.escape(tourneyname))
            cgicommon.writeln("<p>")
            cgicommon.writeln(
                '<a href="/cgi-bin/tourneysetup.py?tourney=%s">Click here to continue</a>'
                % urllib.parse.quote_plus(tourneyname))
            cgicommon.writeln("</p>")
            tourney_created = True
        except countdowntourney.TourneyException as e:
            cgicommon.show_tourney_exception(e)

    if not tourney_created:
        # If name has been filled in, attempt to create tourney

        cgicommon.writeln("<h2>Create new tourney</h2>")
        cgicommon.writeln('<form action="%s" method="POST">' %
                          cgicommon.escape(baseurl, True))
예제 #28
0
def get_user_form(tourney, settings):
    elements = []

    num_players = settings.get("num_players")
    if num_players:
        try:
            num_players = int(num_players)
            num_players_in_tourney = len(tourney.get_active_players())
            if num_players < 2 or num_players > num_players_in_tourney:
                elements.append(
                    htmlform.HTMLFragment(
                        "<p><strong>%d is an invalid number of players: must be between 2 and %d.</strong></p>"
                        % (num_players, num_players_in_tourney)))
                num_players = None
        except ValueError:
            elements.append(
                htmlform.HTMLFragment(
                    "<p><strong>The number of players must be a number.</strong></p>"
                ))
            num_players = None

    player_selection_mode = settings.get("player_sel_mode")
    if player_selection_mode not in ("topntable", "topnrating", "random",
                                     "manual"):
        player_selection_mode = None

    if not num_players:
        # Page 1
        elements.append(
            htmlform.HTMLFormTextInput("How many players?",
                                       "num_players",
                                       "",
                                       other_attrs={"size": "4"}))
        elements.append(htmlform.HTMLFormSubmitButton("submit", "Submit"))
    elif not player_selection_mode:
        # Page 2
        elements.append(
            htmlform.HTMLFragment(
                "<p>How do you want to pick these %d players?</p>" %
                num_players))
        sel_options = []
        sel_options.append(
            htmlform.HTMLFormDropDownOption(
                "topntable", "Top %d players by table position" % num_players))
        sel_options.append(
            htmlform.HTMLFormDropDownOption(
                "topnrating", "Top %d players by rating" % num_players))
        sel_options.append(
            htmlform.HTMLFormDropDownOption(
                "random", "%d players in a random draw" % num_players))
        sel_options.append(
            htmlform.HTMLFormDropDownOption("manual", "Specify draw manually"))
        elements.append(htmlform.HTMLFragment("<p>"))
        elements.append(
            htmlform.HTMLFormDropDownBox("player_sel_mode", sel_options))
        elements.append(htmlform.HTMLFormHiddenInput("page2", "1"))
        elements.append(htmlform.HTMLFragment("</p><p>"))
        elements.append(htmlform.HTMLFormSubmitButton("submit",
                                                      "Pick Players"))
        elements.append(htmlform.HTMLFragment("</p>"))
    else:
        # Page 3

        players = tourney.get_active_players()
        standings = tourney.get_standings()

        # If we've just come from page 2, decide on initial player names in
        # "settings" for seed1 ... seedN.
        if settings.get("page2"):
            del settings["page2"]
            if player_selection_mode == "topntable":
                seed = 1
                for standing in standings[0:num_players]:
                    settings["seed%d" % seed] = standing[1]
                    seed += 1
            elif player_selection_mode == "topnrating":
                players_by_rating = sorted(players,
                                           key=lambda x: x.rating,
                                           reverse=True)
                seed = 1
                for p in players_by_rating[0:num_players]:
                    settings["seed%d" % seed] = p.name
                    seed += 1
            elif player_selection_mode == "random":
                random_player_order = players[:]
                random.shuffle(random_player_order)
                seed = 1
                for p in random_player_order[0:num_players]:
                    settings["seed%d" % seed] = p.name
                    seed += 1

        all_seeds_set = True
        found_dupes = False
        seed_players = [None for i in range(num_players)]

        elements.append(
            htmlform.HTMLFragment(
                "<p>Use the following %d players in the knockout series...</p>"
                % num_players))

        # Make N drop-down boxes, each containing the N players
        for seed_index in range(1, num_players + 1):
            keyname = "seed%d" % seed_index
            current_player_name = settings.get(keyname)

            if current_player_name:
                for p in players:
                    if current_player_name == p.get_name():
                        break
                else:
                    # Don't recognise this player
                    current_player_name = None
            else:
                current_player_name = None

            if not current_player_name:
                all_seeds_set = False

            options = []
            options.append(
                htmlform.HTMLFormDropDownOption("", "--- select player ---",
                                                current_player_name is None))
            for standing in standings:
                player = tourney.get_player_from_name(standing[1])
                player_string = "%d. %s (%d wins, %d draws, %d points)" % (
                    standing[0], player.get_name(), standing[3], standing[5],
                    standing[4])
                options.append(
                    htmlform.HTMLFormDropDownOption(
                        player.get_name(), player_string,
                        (player.get_name() == current_player_name)))
                if player.get_name() == current_player_name:
                    if player in seed_players:
                        # player is already in seed_players, so we have
                        # a duplicate
                        found_dupes = True
                        all_seeds_set = False
                    seed_players[seed_index - 1] = player

            elements.append(htmlform.HTMLFragment("#%d " % seed_index))
            elements.append(
                htmlform.HTMLFormDropDownBox("seed%d" % seed_index, options))
            elements.append(htmlform.HTMLFragment("<br />"))

        if found_dupes:
            elements.append(
                htmlform.HTMLFragment(
                    "<p><strong>Warning</strong>: one or more players appears more than once above. You need to fix this before generating fixtures.</p>"
                ))

        # Are any of the seeds involved in a tie?
        if player_selection_mode == "topntable":
            ties_mentioned = []
            for p in seed_players:
                if p:
                    player_standing = None
                    for s in standings:
                        if s[1] == p.name:
                            player_standing = s
                            break
                    for s in standings:
                        if (s[3] * 2 + s[5]
                                == player_standing[3] * 2 + player_standing[5]
                                and s[4] == player_standing[4]
                                and s[1] != player_standing[1] and
                            (s[1], player_standing[1]) not in ties_mentioned
                                and
                            (player_standing[1], s[1]) not in ties_mentioned):
                            elements.append(
                                htmlform.HTMLFragment(
                                    "<p><strong>Warning:</strong> %s and %s have the same number of wins and points and have been ordered arbitrarily.</p>"
                                    % (player_standing[1], s[1])))
                            ties_mentioned.append((s[1], player_standing[1]))

        elements.append(htmlform.HTMLFormSubmitButton("setseeds",
                                                      "Save Order"))

        if all_seeds_set:
            # All seed positions have a player in them and no player appears
            # more than once.

            # Work out fixtures and display them.
            (rounds, fixtures) = generate_knockout(tourney, seed_players)

            if settings.get("generate"):
                # The fixtures have already been okayed, so nothing more to do
                return None

            html = "<h2>Fixture list</h2>\n"
            html += "<p>The following rounds will be generated</p>\n"
            html += "<blockquote>\n"
            for r in rounds:
                html += "<li>%s</li>\n" % cgicommon.escape(r["name"])
            html += "</blockquote>\n"
            elements.append(htmlform.HTMLFragment(html))

            html = "<p>The following fixtures will be generated</p>\n"
            prev_round_no = None
            html += "<table>"
            for g in fixtures:
                if g.round_no != prev_round_no:
                    round_name = None
                    for r in rounds:
                        if r["round"] == g.round_no:
                            round_name = r["name"]
                            break
                    if not round_name:
                        round_name = "Round %d" % g.round_no
                    html += "<tr><th colspan=\"4\">%s</td></tr>\n" % round_name
                prev_round_no = g.round_no
                html += "<tr>"
                html += "<td>%d</td>" % g.seq
                html += "<td>%s</td>" % str(g.p1)
                html += "<td>v</td>"
                html += "<td>%s</td>" % str(g.p2)
                html += "</tr>"
            html += "</table>"
            elements.append(htmlform.HTMLFragment(html))

            elements.append(
                htmlform.HTMLFragment(
                    "<p>Click the button below to proceed. On the next screen you can review the fixtures and accept them.</p>"
                ))
            elements.append(
                htmlform.HTMLFormSubmitButton("generate",
                                              "Yep, looks good to me"))
        else:
            if "generate" in settings:
                del settings["generate"]

    return htmlform.HTMLForm(
        "POST", "/cgi-bin/fixturegen.py?tourney=%s" %
        urllib.parse.quote_plus(tourney.name), elements)
예제 #29
0
            div_active_player_count = [
                len([
                    p for p in div_players[div_index] if not p.is_withdrawn()
                ]) for div_index in range(num_divisions)
            ]
            div_withdrawn_player_count = [
                len([p for p in div_players[div_index] if p.is_withdrawn()])
                for div_index in range(num_divisions)
            ]

            for div_index in range(num_divisions):
                div_name = tourney.get_division_name(div_index)
                cgicommon.writeln("<tr>")
                cgicommon.writeln("<td class=\"divsummaryname\">%s</td>" %
                                  (cgicommon.escape(div_name)))
                cgicommon.writeln(
                    "<td class=\"divsummaryactiveplayers\">%d</td>" %
                    (div_active_player_count[div_index]))
                cgicommon.writeln(
                    "<td class=\"divsummarywithdrawnplayers\">%d</td>" %
                    (div_withdrawn_player_count[div_index]))
                cgicommon.writeln("<td class=\"divsummaryrename\">")
                cgicommon.writeln(
                    "<div class=\"divrenamecontrols\" id=\"divrenamecontrols%d\">"
                    % (div_index))
                cgicommon.writeln(
                    "<form action=\"%s?tourney=%s\" method=\"POST\">" %
                    (baseurl, urllib.parse.quote_plus(tourneyname)))
                cgicommon.writeln(
                    "<input type=\"hidden\" name=\"tourney\" value=\"%s\" />" %
예제 #30
0
    cgicommon.writeln("<div class=\"prefstaborderrow\">")
    cgicommon.writeln("<div class=\"prefstabordercontrol\">")
    cgicommon.writeln(
        "<input type=\"radio\" name=\"resultstab\" id=\"resultstab_%s\" value=\"%s\" %s />"
        % (option_tab_order, option_tab_order,
           "checked" if tab_order == option_tab_order else ""))
    cgicommon.writeln("<label for=\"resultstab_%s\">" % (option_tab_order))
    cgicommon.writeln(" &rarr; ".join(field_name_list))
    cgicommon.writeln("</label>")
    cgicommon.writeln("</div>")

    cgicommon.writeln("<div class=\"prefstaborderimage\">")
    cgicommon.writeln("<label for=\"resultstab_%s\">" % (option_tab_order))
    cgicommon.writeln(
        "<img src=\"/images/taborder%d.png\" alt=\"%s\" />" %
        (idx + 1, cgicommon.escape("-".join(field_name_list), True)))
    cgicommon.writeln("</label>")
    cgicommon.writeln("</div>")

    cgicommon.writeln("</div>")
    cgicommon.writeln("<div class=\"prefsclear\"></div>")

cgicommon.writeln("<div class=\"prefstaborderfooter\">")
cgicommon.writeln(
    "Saved changes will take effect after you refresh the results entry page.")
cgicommon.writeln("</div>")

cgicommon.writeln("</div>")  # preferencestaborder

cgicommon.writeln("<div class=\"prefsfeedback\">")
cgicommon.writeln("<span class=\"prefssaved\" id=\"prefssavedspan\">")