def leave_game(): """ Leave game, flash status, redirect back to /home """ alt = ensure_user() if alt: return alt api = API() gameid = request.args.get('gameid', None) if gameid is None: flash("Invalid game ID.") return redirect(url_for('error_page')) try: gameid = int(gameid) except ValueError: flash("Invalid game ID.") return redirect(url_for('error_page')) userid = session['userid'] response = api.leave_game(userid, gameid) if response is api.ERR_USER_NOT_IN_GAME: msg = "You are not registered in game %s." % (gameid,) elif response is api.ERR_NO_SUCH_OPEN_GAME: msg = "Invalid game ID." elif isinstance(response, APIError): msg = "An unknown error occurred leaving game %d, sorry." % (gameid,) else: msg = "You have left game %s." % (gameid,) flash(msg) return redirect(url_for('home_page')) flash(msg) return redirect(url_for('error_page'))
def _main(): """ Does some initialisation, then runs the website. """ # Initialise database api = API() api.create_db() api.initialise_db() api.ensure_open_games() # Run the app locally APP.run(host=APP.config.get('HOST', '0.0.0.0'), port=APP.config.get('PORT', 80), debug=APP.config['DEBUG'], use_reloader=APP.config.get('RELOADER', False))
def ensure_user(): """ Commit user to database and determine userid """ # TODO: REVISIT: automagically hook this into AUTH.required if not is_authenticated(): # user is not authenticated yet return if is_logged_in(): # user is authenticated and authorised (logged in) return if 'screenname' in session: # user had changed screenname but not yet logged in screenname = session['screenname'] else: # regular login screenname = g.user['name'] api = API() req = LoginRequest(identity=g.user['identity'], # @UndefinedVariable email=g.user['email'], # @UndefinedVariable screenname=screenname) result = api.login(req) if result == API.ERR_DUPLICATE_SCREENNAME: session['screenname'] = g.user['name'] # User is authenticated with OpenID, but not yet authorised (logged # in). We redirect them to a page that allows them to choose a # different screenname. if request.endpoint != 'change_screenname': flash("The screenname '%s' is already taken." % (screenname,)) return redirect(url_for('change_screenname')) elif isinstance(result, APIError): flash("Error registering user details.") logging.debug("login error: %s", result) return redirect(url_for('error_page')) else: # If their Google name is "Player <X>", they will not be able to have # their Google name as their screenname. Unless their login errors. session['userid'] = result.userid session['screenname'] = result.screenname req2 = ChangeScreennameRequest(result.userid, "Player %d" % (result.userid,)) if not result.existed and result.screenname != req2.screenname: result2 = api.change_screenname(req2) if isinstance(result2, APIError): flash("Couldn't give you screenname '%s', " "you are stuck with '%s' until you change it." % (req2.screenname, result.screenname)) else: session['screenname'] = req2.screenname flash("You have logged in as '%s'" % (session['screenname'],))
def unauthenticated_game_page(gameid): """ Game page when user is authenticated (i.e. the private view) """ api = API() response = api.get_public_game(gameid) if isinstance(response, APIError): if response is api.ERR_NO_SUCH_RUNNING_GAME: msg = "Invalid game ID." else: msg = "An unknown error occurred retrieving game %d, sorry." % \ (gameid,) flash(msg) return redirect(url_for('error_page')) if response.is_finished(): return _finished_game(response, gameid) else: return _running_game(response, gameid, None, api)
def unsubscribe(): """ Record that the user does not want to receive any more emails, at least until they log in again and in so doing clear that flag. Note that authentication is not required. """ api = API() identity = request.args.get('identity', None) if identity is None: msg = "Invalid request, sorry." else: response = api.unsubscribe(identity) if response is api.ERR_NO_SUCH_USER: msg = "No record of you on Range vs. Range, sorry." elif isinstance(response, APIError): msg = "An unknown error occurred unsubscribing you, sorry." else: msg = "You have been unsubscribed. If you log in again, you will start receiving emails again." # pylint:disable=C0301 flash(msg) return render_template('web/flash.html', title='Unsubscribe')
def change_screenname(): """ Without the user being logged in, give the user the option to change their screenname from what Google OpenID gave us. """ alt = ensure_user() if alt: return alt form = ChangeForm() if form.validate_on_submit(): new_screenname = form.change.data if 'userid' in session: # Having a userid means they're in the database. req = ChangeScreennameRequest(session['userid'], new_screenname) resp = API().change_screenname(req) if resp == API.ERR_DUPLICATE_SCREENNAME: flash("That screenname is already taken.") elif isinstance(resp, APIError): logging.debug("change_screenname error: %s", resp) flash("An error occurred.") else: session['screenname'] = new_screenname flash("Your screenname has been changed to '%s'." % (new_screenname, )) return redirect(url_for('home_page')) else: # User is not logged in. Changing screenname in session is enough. # Now when they go to the home page, ensure_user() will create their # account. session['screenname'] = new_screenname return redirect(url_for('home_page')) current = session['screenname'] if 'screenname' in session \ else g.user['name'] navbar_items = [('', url_for('home_page'), 'Home'), ('', url_for('about_page'), 'About'), ('', url_for('faq_page'), 'FAQ')] return render_template('web/change.html', title='Change Your Screenname', current=current, form=form, navbar_items=navbar_items, is_logged_in=is_logged_in(), is_account=True)
def join_game(): """ Join game, flash status, redirect back to /home """ alt = ensure_user() if alt: return alt api = API() gameid = request.args.get('gameid', None) if gameid is None: flash("Invalid game ID.") return redirect(url_for('error_page')) try: gameid = int(gameid) except ValueError: flash("Invalid game ID.") return redirect(url_for('error_page')) userid = session['userid'] response = api.join_game(userid, gameid) if response is api.ERR_JOIN_GAME_ALREADY_IN: msg = "You are already registered in game %s." % (gameid,) elif response is api.ERR_JOIN_GAME_GAME_FULL: msg = "Game %d is full." % (gameid,) elif response is api.ERR_NO_SUCH_OPEN_GAME: msg = "Invalid game ID." elif response is api.ERR_NO_SUCH_USER: msg = "Oddly, your account does not seem to exist. " + \ "Try logging out and logging back in." logging.debug("userid %d can't register for game %d, " + "because user doesn't exist.", userid, gameid) elif isinstance(response, APIError): msg = "An unknown error occurred joining game %d, sorry." % (gameid,) logging.debug("unrecognised error from api.join_game: %s", response) else: msg = "You have joined game %s." % (gameid,) flash(msg) return redirect(url_for('home_page')) flash(msg) return redirect(url_for('error_page'))
def home_page(): """ Generates the unauthenticated landing page. AKA the main or home page. """ if not is_authenticated(): return render_template('web/landing.html') alt = ensure_user() if alt: return alt api = API() userid = session['userid'] screenname = session['screenname'] open_games = api.get_open_games() if isinstance(open_games, APIError): flash("An unknown error occurred retrieving your open games.") return redirect(url_for("error_page")) my_games = api.get_user_running_games(userid) if isinstance(my_games, APIError): flash("An unknown error occurred retrieving your running games.") return redirect(url_for("error_page")) selected_heading = request.cookies.get("selected-heading", "heading-open") my_games.running_details.sort( key=lambda rg: rg.current_user_details.userid != userid) my_open = [og for og in open_games if any([u.userid == userid for u in og.users])] others_open = [og for og in open_games if not any([u.userid == userid for u in og.users])] form = ChangeForm() navbar_items = [('active', url_for('home_page'), 'Home'), ('', url_for('about_page'), 'About'), ('', url_for('faq_page'), 'FAQ')] return render_template('web/home.html', title='Home', screenname=screenname, userid=userid, change_form=form, r_games=my_games, my_open=my_open, others_open=others_open, my_finished_games=my_games.finished_details, navbar_items=navbar_items, selected_heading=selected_heading, is_logged_in=is_logged_in())
def __init__(self): Cmd.__init__(self) self.api = API()
def analysis_page(): """ Analysis of a particular hand history item. """ gameid = request.args.get('gameid', None) if gameid is None: return error("Invalid game ID.") try: gameid = int(gameid) except ValueError: return error("Invalid game ID (not a number).") api = API() response = api.get_public_game(gameid) if isinstance(response, APIError): if response is api.ERR_NO_SUCH_RUNNING_GAME: msg = "Invalid game ID." else: msg = "An unknown error occurred retrieving game %d, sorry." % \ (gameid,) return error(msg) game = response order = request.args.get('order', None) if order is None: return error("Invalid order.") try: order = int(order) except ValueError: return error("Invalid order (not a number).") try: item = game.history[order] except IndexError: return error("Invalid order (not in game).") if not isinstance(item, dtos.GameItemActionResult): return error("Invalid order (not a bet or raise).") if not item.action_result.is_aggressive: return error("Analysis only for bets right now, sorry.") try: aife = game.analysis[order] except KeyError: return error("Analysis for this action is not ready yet.") street = game.game_details.situation.current_round street_text = aife.STREET_DESCRIPTIONS[street] if item.action_result.is_raise: action_text = "raises to %d" % (item.action_result.raise_total,) else: action_text = "bets %d" % (item.action_result.raise_total,) navbar_items = [('', url_for('home_page'), 'Home'), ('', url_for('about_page'), 'About'), ('', url_for('faq_page'), 'FAQ')] items_aggressive = [i for i in reversed(aife.items) if i.is_aggressive] items_passive = [i for i in aife.items if i.is_passive] items_fold = [i for i in aife.items if i.is_fold] # Could also have a status column or popover or similar: # "good bluff" = +EV # "bad bluff" = -EV on river # "possible semibluff" = -EV on river return render_template('web/analysis.html', gameid=gameid, street_text=street_text, screenname=item.user.screenname, action_text=action_text, items_aggressive=items_aggressive, items_passive=items_passive, items_fold=items_fold, is_raise=aife.is_raise, is_check=aife.is_check, navbar_items=navbar_items, is_logged_in=is_logged_in())