def create_object(self): instance = super(WorkingUnitAdmin, self).create_object() instance.date = to_user_timezone(datetime.today()) latest = WorkingUnit.query.get_by_user().first() if latest is not None: instance.start_time = latest.start_time instance.end_time = latest.end_time instance.break_minutes = latest.break_minutes instance.project = latest.project instance.task = latest.task else: instance.start_time = to_user_timezone(datetime.utcnow()) instance.break_minutes = 60 return instance
def index(year=None, month=None): today = to_user_timezone(datetime.today()) year = year or today.year month = month or today.month d = date(year, month, 1) hours = 0.0 weekly_hours = {} if current_user.is_authenticated(): times = WorkingUnit.query.get_by_year_and_month(year, month) if times.first(): d = times.first().date for time in times: hours += time.working_time wh = weekly_hours.setdefault(time.week, 0.0) weekly_hours[time.week] = wh + time.working_time else: times = [] return render_template( "index.html", times=times, hours=hours, weekly_hours=weekly_hours, date=d, projects=get_projects(), companies=get_companies(), dates=get_dates(), )
def timeuntil(d, now=None): """ Like timesince, but returns a string measuring the time until the given time. """ if not now: if getattr(d, 'tzinfo', None): now = to_user_timezone(datetime.datetime.now()) now = datetime.datetime.now(LocalTimezone(d)) else: now = datetime.datetime.now() return timesince(now, d)
def timesince(d, now=None): """ Takes two datetime objects and returns the time between d and now as a nicely formatted string, e.g. "10 minutes". If d occurs after now, then "0 minutes" is returned. Units used are years, months, weeks, days, hours, and minutes. Seconds and microseconds are ignored. Up to two adjacent units will be displayed. For example, "2 weeks, 3 days" and "1 year, 3 months" are possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not. Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since """ chunks = ( (60 * 60 * 24 * 365, lambda n: ngettext('year', 'years', n)), (60 * 60 * 24 * 30, lambda n: ngettext('month', 'months', n)), (60 * 60 * 24 * 7, lambda n: ngettext('week', 'weeks', n)), (60 * 60 * 24, lambda n: ngettext('day', 'days', n)), (60 * 60, lambda n: ngettext('hour', 'hours', n)), (60, lambda n: ngettext('minute', 'minutes', n)) ) # Convert datetime.date to datetime.datetime for comparison. if not isinstance(d, datetime.datetime): d = datetime.datetime(d.year, d.month, d.day) if now and not isinstance(now, datetime.datetime): now = datetime.datetime(now.year, now.month, now.day) if not now: if d.tzinfo: now = to_user_timezone(datetime.datetime.now()) else: now = datetime.datetime.now() # ignore microsecond part of 'd' since we removed it from 'now' delta = now - (d - datetime.timedelta(0, 0, d.microsecond)) since = delta.days * 24 * 60 * 60 + delta.seconds if since <= 0: # d is in the future compared to now, stop processing. return u'0 ' + gettext('minutes') for i, (seconds, name) in enumerate(chunks): count = since // seconds if count != 0: break s = gettext('%(number)d %(type)s', number=count, type=name(count)) if i + 1 < len(chunks): # Now get the second item seconds2, name2 = chunks[i + 1] count2 = (since - (seconds * count)) // seconds2 if count2 != 0: s += gettext(', %(number)d %(type)s', number=count2, type=name2(count2)) return s
def update_time_zone(): form = UserTimeZoneForm(request.form, obj=g.user) if form.validate_on_submit(): form.populate_obj(g.user) db.session.commit() babel_refresh() flash(u'Your time zone was successfully updated.', 'success') now = to_user_timezone(datetime.utcnow()) user_tz_names = (format_datetime(now, 'zzzz'), format_datetime(now, 'zzz')) return jsonify(success=True, time_zone=form.time_zone.data, csrf=form.csrf_token.data, user_tz_names=user_tz_names) flash(u'There was an error updating your time zone.', 'error') return jsonify(success=False)
def some_random_view(): t = datetime.utcnow() return render_template('mod3/root.html', time=to_user_timezone(t))
def add(): if not g.user.is_team_leader(): flash(u'You must be a team leader to add a match.', 'error') return redirect(url_for('my_matches')) opponents = Opponent.query.\ filter(Opponent.team_id.in_(g.user.team_leader_teams)).\ order_by(Opponent.name.asc()).all() servers = Server.query.\ filter(Server.team_id.in_(g.user.team_leader_teams)).\ order_by('server_name') competitions = Competition.query.order_by('competition_name') form = AddMatchForm() form.team_id.choices = [ (t, g.user.teams[t].name) for t in g.user.team_leader_teams ] form.competition_id.choices = [(c.id, c.name) for c in competitions ] form.server_id.choices = [ (s.id, s.name) for s in servers ] form.opponent_id.choices = [ (o.id, o.name) for o in opponents ] if request.method == 'GET': if request.values.get('new_opponent_id'): form.opponent_id.data = int(request.values.get('new_opponent_id')) elif request.values.get('new_server_id'): form.server_id.data = int(request.values.get('new_server_id')) # default to tomorrow at 9pm form.date.data = datetime.datetime.combine((\ to_user_timezone(datetime.datetime.utcnow()) \ + datetime.timedelta(days=1))\ .date(),\ datetime.time(21)) form.date.label.text += ' (in %s)' \ % format_datetime(form.date.data, 'zzzz') if form.validate_on_submit(): if not g.user.is_team_leader(form.team_id.data): flash(u'You must be a team leader to add a match.', 'error') else: date = to_utc(form.date.data) match = Match(team_id=form.team_id.data, date=date, comments=form.comments.data, password=form.password.data, opponent_id=form.opponent_id.data, competition_id=form.competition_id.data, creator_user_id=g.user.id, server_id=form.server_id.data) db.session.add(match) db.session.commit() team_date = matches_datetime_format_full_for_team(date, \ g.user.teams[form.team_id.data].time_zone) date_short = matches_datetime_format(date) team_date_short = matches_datetime_format_for_team(date, \ g.user.teams[form.team_id.data].time_zone) email_vars = { 'date' : matches_datetime_format_full(date), 'team_date' : team_date, 'date_short' : date_short, 'team_date_short' : team_date_short, 'team' : g.user.teams[form.team_id.data].name, 'opponent' : match.opponent.name, 'opponent_tag' : match.opponent.tag, 'competition' : match.competition.name, 'server' : match.server.name, 'address' : match.server.address, 'password' : match.password, 'comments' : match.comments, 'match_url' : abs_url_for('show', match_id=match.id), 'settings_url' : abs_url_for('account.settings') } subject = "[tardyrush] New Match "\ "on %(date_short)s vs. %(opponent_tag)s" %\ email_vars team_subject = "[tardyrush] New Match "\ "on %(team_date_short)s vs. %(opponent_tag)s" %\ email_vars lines = [ "A new match has been added." ] lines.append("") lines.append( "%(team)s vs. %(opponent)s" % email_vars ) lines.append( "%%(date)s" % email_vars ) lines.append("") lines.append( "Competition: %(competition)s" % email_vars ) lines.append( "Server: %(server)s" % email_vars ) lines.append( "Address: %(address)s" % email_vars ) if len(email_vars['password']): lines.append( "Password: %(password)s" % email_vars ) lines.append("") if len(email_vars['comments']): lines.append( "Comments:" ) lines.append( "%(comments)s" % email_vars ) lines.append("") lines.append( "Set your status: %(match_url)s" % email_vars ) lines.append("") lines.append( "Change your settings: %(settings_url)s" % email_vars ) lines.append("") raw_message = "\n".join(lines) message = raw_message % email_vars team_message = raw_message % { 'date' : email_vars['team_date'] } # now notify players of new match via email players = db.session.query(User).\ select_from(join(User, TeamPlayer)).\ filter(TeamPlayer.team_id==form.team_id.data).\ filter(User.email_settings==User.EmailMatchAdded) if form.send_notification.data: try: with mail.connect() as conn: for p in players: try: msg = Message(recipients=[p.email], body=message, subject=subject, sender=Sender) conn.send(msg) app.logger.info("Sent mail to: %s" % p.email) except Exception, e: app.logger.error("Error sending mail: %s, %s" % \ (p.email, e)) except Exception, e: app.logger.error("Error sending mail: %s" % e) # now notify players of new match via forum post if form.post_on_forums.data: forum_post = ForumBotQueuedPost(team_id=match.team_id, game_id=match.competition.game_id, match_id=match.id, subject=team_subject, message=team_message) db.session.add(forum_post) db.session.commit() flash(u'The match was successfully added.', 'success') return redirect(url_for('my_matches'))
def show(match_id, action): match = Match.query.filter_by(id=match_id).first() if not match: flash(u"That match doesn't exist.", "error") return redirect(url_for('my_matches')) if not g.user.is_on_team(match.team_id): flash(u'You must be on the team to view its match availability.', "error") return redirect(url_for('all')) if match.date < datetime.datetime.utcnow(): up_prev = 'previous' else: up_prev = 'upcoming' if action == 'edit': if not g.user.is_team_leader(match.team_id): flash(u'You must be a team leader to edit this match.', 'error') return redirect(url_for('my_matches')) servers = Server.query.\ filter_by(team_id=match.team_id).\ order_by('server_name') form = MatchForm(request.form, obj=match) form.competition_id.choices = [(c.id, c.name) for c in Competition.query.order_by('competition_name')] form.server_id.choices = [ (s.id, s.name) for s in servers ] form.team_id.choices = [ (t, g.user.teams[t].name) for t in g.user.team_leader_teams ] form.opponent_id.choices = [ (o.id, o.name) for o in \ Opponent.query.filter_by(team_id=match.team_id).\ order_by(Opponent.name.asc()).all() ] players = {} for p in match.players: players[p.user_id] = p.user.name if request.method == 'GET': if request.values.get('new_opponent_id'): form.opponent_id.data = int(request.values.get('new_opponent_id')) elif request.values.get('new_server_id'): form.server_id.data = int(request.values.get('new_server_id')) form.date.data = to_user_timezone(form.date.data) form.date.label.text += ' (in %s)' \ % format_datetime(form.date.data, 'zzzz') if form.validate_on_submit(): form.date.data = to_utc(form.date.data) to_delete = [] for f in form.players: if f.delete.data: to_delete.append(f.user_id.data) form.populate_obj(match) if len(to_delete): MatchPlayer.query.\ filter_by(match_id=match_id).\ filter(MatchPlayer.user_id.in_(to_delete)).delete(False) db.session.commit() flash(u'The match was successfully updated.', 'success') if request.values.get('from') == 'single': return redirect(url_for('show', match_id=match_id)) return redirect(url_for('my_matches')) oform = OpponentForm() sform = ServerForm() tzform = UserTimeZoneForm(obj=g.user) return rt('matches/form.html', form=form, players=players, page={'top':'my_matches', 'sub':up_prev}, when=up_prev, adding=False, user_now=to_user_timezone(datetime.datetime.utcnow()), tzform=tzform, oform=oform, sform=sform, team_id=g.user.team_leader_teams[0], match_id=match.id) elif action == 'delete': if not g.user.is_team_leader(match.team_id): flash(u'You must be a team leader to edit this match.', 'error') return redirect(url_for('my_matches')) if request.method == 'POST': db.session.delete(match) db.session.commit() flash(u'The match was successfully deleted.', 'success') return redirect(url_for('my_matches')) elif action == 'status': if not g.user.is_on_team(match.team_id): flash(u'You must be on this team to change your status.', 'error') return redirect(url_for('my_matches')) if up_prev == 'previous': flash(u'You cannot change your status on a past match.', 'error') return redirect(url_for('my_previous_matches')) form = MatchPlayerStatusForm(request.form) if form.validate_on_submit(): if request.values.get('s') == 'available': player_status = MatchPlayer.StatusAvailable elif request.values.get('s') == 'maybe': player_status = MatchPlayer.StatusMaybe elif request.values.get('s') == 'unavailable': player_status = MatchPlayer.StatusUnavailable else: player_status = None if player_status is None: flash(u'That status is not valid!', 'error') else: try: mu = MatchPlayer.query.filter_by(match_id=match.id, user_id=g.user.id).one() mu.status = player_status except NoResultFound: mu = MatchPlayer(match_id=match.id, user_id=g.user.id, status=player_status) except Exception, e: app.logger.error('Error finding MatchPlayer: %s, %s' % \ (g.user.id, e)) flash(u'Something bad happened. Please try again.', 'error') return redirect(url_for('my_matches')) mu.date_updated = datetime.datetime.utcnow() db.session.add(mu) db.session.commit() if request.values.get('api') == '1': psp = mu.pretty_status return jsonify(success=True, csrf=form.csrf_token.data, match_id=match.id, user_id=g.user.id, user_name=g.user.name, player_status=player_status, player_status_pretty=psp) if request.values.get('from') == 'single': return redirect(url_for('show', match_id=match_id))
message=team_message) db.session.add(forum_post) db.session.commit() flash(u'The match was successfully added.', 'success') return redirect(url_for('my_matches')) oform = OpponentForm() sform = ServerForm() tzform = UserTimeZoneForm(obj=g.user) return rt('matches/form.html', page={'top':'my_matches', 'sub':'add_match'}, adding=True, team_id=g.user.team_leader_teams[0], user_now=to_user_timezone(datetime.datetime.utcnow()), tzform=tzform, oform=oform, sform=sform, form=form) @matches.route('/match/<int:match_id>/', defaults={'action':''}) @matches.route('/match/<int:match_id>/<action>/', methods=('GET','POST')) @require_login() def show(match_id, action): match = Match.query.filter_by(id=match_id).first() if not match: flash(u"That match doesn't exist.", "error") return redirect(url_for('my_matches')) if not g.user.is_on_team(match.team_id):
def add(cmatch_id, action): if not g.user.is_team_leader(): flash(u'You must be a team leader to add results.', 'error') return redirect(url_for('matches.my_matches')) if cmatch_id > 0: corr_match_id = cmatch_id adding = False corr_match = CompletedMatch.query.filter_by(id=cmatch_id).first() if not corr_match: flash(u"That result doesn't exist.", "error") return redirect(url_for('matches.my_matches')) else: cmatch_id = 0 adding = True corr_match_id = request.values.get('match_id') corr_match = Match.query.filter_by(id=corr_match_id).\ filter(Match.team_id.in_(g.user.team_leader_teams)).first() if not corr_match: flash(u'Corresponding availability match not found.', 'error') return redirect(url_for('matches.my_matches')) if corr_match.date > datetime.datetime.utcnow(): flash(u'Cannot add results to match in the future.', 'error') return redirect(url_for('matches.my_matches')) if len(corr_match.results): flash(u'Results have already been added.', 'error') return redirect(url_for('add', cmatch_id=corr_match.results[0].id, action='edit')) opponents = Opponent.query.\ filter(Opponent.team_id.in_(g.user.team_leader_teams)).\ order_by(Opponent.name.asc()).all() servers = Server.query.\ filter(Server.team_id.in_(g.user.team_leader_teams)).\ order_by('server_name') if not adding: form = CompletedMatchForm(request.form, obj=corr_match) if request.method == 'GET': tz = to_user_timezone(corr_match.date_played) form.date_played.data = tz form.date_played.label.text += \ ' (in %s)' % format_datetime(tz, 'zzzz') else: form = CompletedMatchForm() if request.method == 'GET': tz = to_user_timezone(corr_match.date) form.date_played.data = tz form.date_played.label.text += \ ' (in %s)' % format_datetime(tz, 'zzzz') form.match_id.data = int(corr_match_id) form.team_id.choices = [ (corr_match.team_id, g.user.teams[corr_match.team_id].name) ] form.competition_id.choices = [ (corr_match.competition.id, corr_match.competition.name) ] form.server_id.choices = [ (corr_match.server.id, corr_match.server.name) ] form.opponent_id.choices = [ (corr_match.opponent.id, corr_match.opponent.name) ] form.team_id.data = corr_match.team_id form.competition_id.data = corr_match.competition_id form.server_id.data = corr_match.server_id form.opponent_id.data = corr_match.opponent_id #cutoff = datetime.datetime.utcnow() + datetime.timedelta(hours=2) #recent_matches = Match.query.\ # filter(Match.team_id.in_(g.user.team_leader_teams)).\ # filter(Match.date < cutoff).\ # order_by(Match.date.desc()).all() #form.match_id.choices = [ (m.id, "%s vs %s" % (m.date, # m.opponent.tag)) for m in recent_matches ] maps = Map.query.filter_by(game_id=corr_match.competition.game_id).\ order_by(Map.name.asc()).all() map_choices = [ (m.id, m.name) for m in maps ] sides = Side.query.filter_by(game_id=corr_match.competition.game_id).\ order_by(Side.name.asc()).all() side_choices = [ (s.id, s.name) for s in sides ] gametypes = GameType.query.\ filter_by(game_id=corr_match.competition.game_id).\ order_by(GameType.name.asc()).\ all() gametype_choices = [ (gt.id, gt.name) for gt in gametypes ] players = Team.query.filter_by(id=corr_match.team_id).first().\ players.all() player_choices = \ sorted([ (p.user_id, p.user.name) for p in players ], key=lambda x: x[1].lower()) if adding and request.method == 'GET': form.rounds.append_entry() for e in form.rounds.entries: e.map_id.choices = map_choices e.side_id.choices = side_choices e.gametype_id.choices = gametype_choices if adding and request.method == 'GET': e.players.append_entry() for ep in e.players.entries: ep.user_id.choices = player_choices forfeit_result = request.values.get('forfeit_result') if form.validate_on_submit(): if not g.user.is_team_leader(form.team_id.data): flash(u'Invalid team', 'error') elif not len(form.rounds) and not forfeit_result: flash(u'Invalid rounds', 'error') else: error = False date = to_utc(form.date_played.data) if adding: cmatch = CompletedMatch(team_id=form.team_id.data, date_created=datetime.datetime.utcnow(), opponent_id=form.opponent_id.data, competition_id=form.competition_id.data, creator_user_id=g.user.id, server_id=form.server_id.data, match_id=corr_match.id) else: cmatch = corr_match for r in cmatch.rounds.all(): cmatch.rounds.remove(r) cmatch.date_played = date cmatch.comments = form.comments.data if forfeit_result in ('1', '0'): cmatch.final_result_method = CompletedMatch.FinalResultByForfeit cmatch.draws = 0 if forfeit_result == '1': cmatch.wins = 1 cmatch.losses = 0 else: cmatch.wins = 0 cmatch.losses = 1 if adding: db.session.add(cmatch) db.session.commit() flash(u'The results were successfully saved.', 'success') return redirect(url_for('matches.my_previous_matches')) else: cmatch.final_result_method = form.final_result_method.data cmatch.wins = 0 cmatch.losses = 0 cmatch.draws = 0 if adding: db.session.add(cmatch) db.session.flush() total_wins = 0 total_losses = 0 total_draws = 0 round_wins = 0 round_losses = 0 round_draws = 0 round_num = 1 for r in form.rounds: rnd = CompletedMatchRound(cmatch_id=cmatch.id, round_id=round_num, map_id=r.map_id.data, side_id=r.side_id.data, gametype_id=r.gametype_id.data, wins=r.wins.data, losses=r.losses.data, draws=r.draws.data) cmatch.rounds.append(rnd) db.session.flush() if not len(r.players): flash(u'No players found', 'error') error = True break total_wins += rnd.wins total_losses += rnd.losses total_draws += rnd.draws if rnd.wins > rnd.losses: round_wins += 1 elif rnd.wins < rnd.losses: round_losses += 1 else: round_draws += 1 player_set = set() for p in r.players: if p.user_id.data in player_set: errmsg = u'You have duplicate players in round %d. ' %\ round_num errmsg += 'A player may appear in a round only once.' flash(errmsg, 'error') error = True break player_set.add(p.user_id.data) player = CompletedMatchPlayer(cmatch_id=cmatch.id, round_id=round_num, user_id=p.user_id.data, kills=p.kills.data, deaths=p.deaths.data, off_objs=p.off_objs.data, def_objs=p.def_objs.data, score=p.score.data) rnd.players.append(player) if error: break round_num += 1 if cmatch.final_result_method == CompletedMatch.FinalResultByScore: cmatch.wins = total_wins cmatch.losses = total_losses cmatch.draws = total_draws else: cmatch.wins = round_wins cmatch.losses = round_losses cmatch.draws = round_draws if error: db.session.rollback() else: db.session.commit() flash(u'The results were successfully saved.', 'success') return redirect(url_for('matches.my_previous_matches')) return rt('results/form.html', page={'top':'my_matches', 'sub':'previous'}, adding=adding, player_choices=player_choices, map_choices=map_choices, side_choices=side_choices, gametype_choices=gametype_choices, corr_match=corr_match, form=form)
def add(cmatch_id, action): if not g.user.is_team_leader(): flash(u'You must be a team leader to add results.', 'error') return redirect(url_for('matches.my_matches')) if cmatch_id > 0: corr_match_id = cmatch_id adding = False corr_match = CompletedMatch.query.filter_by(id=cmatch_id).first() if not corr_match: flash(u"That result doesn't exist.", "error") return redirect(url_for('matches.my_matches')) else: cmatch_id = 0 adding = True corr_match_id = request.values.get('match_id') corr_match = Match.query.filter_by(id=corr_match_id).\ filter(Match.team_id.in_(g.user.team_leader_teams)).first() if not corr_match: flash(u'Corresponding availability match not found.', 'error') return redirect(url_for('matches.my_matches')) if corr_match.date > datetime.datetime.utcnow(): flash(u'Cannot add results to match in the future.', 'error') return redirect(url_for('matches.my_matches')) if len(corr_match.results): flash(u'Results have already been added.', 'error') return redirect( url_for('add', cmatch_id=corr_match.results[0].id, action='edit')) opponents = Opponent.query.\ filter(Opponent.team_id.in_(g.user.team_leader_teams)).\ order_by(Opponent.name.asc()).all() servers = Server.query.\ filter(Server.team_id.in_(g.user.team_leader_teams)).\ order_by('server_name') if not adding: form = CompletedMatchForm(request.form, obj=corr_match) if request.method == 'GET': tz = to_user_timezone(corr_match.date_played) form.date_played.data = tz form.date_played.label.text += \ ' (in %s)' % format_datetime(tz, 'zzzz') else: form = CompletedMatchForm() if request.method == 'GET': tz = to_user_timezone(corr_match.date) form.date_played.data = tz form.date_played.label.text += \ ' (in %s)' % format_datetime(tz, 'zzzz') form.match_id.data = int(corr_match_id) form.team_id.choices = [(corr_match.team_id, g.user.teams[corr_match.team_id].name)] form.competition_id.choices = [(corr_match.competition.id, corr_match.competition.name)] form.server_id.choices = [(corr_match.server.id, corr_match.server.name)] form.opponent_id.choices = [(corr_match.opponent.id, corr_match.opponent.name)] form.team_id.data = corr_match.team_id form.competition_id.data = corr_match.competition_id form.server_id.data = corr_match.server_id form.opponent_id.data = corr_match.opponent_id #cutoff = datetime.datetime.utcnow() + datetime.timedelta(hours=2) #recent_matches = Match.query.\ # filter(Match.team_id.in_(g.user.team_leader_teams)).\ # filter(Match.date < cutoff).\ # order_by(Match.date.desc()).all() #form.match_id.choices = [ (m.id, "%s vs %s" % (m.date, # m.opponent.tag)) for m in recent_matches ] maps = Map.query.filter_by(game_id=corr_match.competition.game_id).\ order_by(Map.name.asc()).all() map_choices = [(m.id, m.name) for m in maps] sides = Side.query.filter_by(game_id=corr_match.competition.game_id).\ order_by(Side.name.asc()).all() side_choices = [(s.id, s.name) for s in sides] gametypes = GameType.query.\ filter_by(game_id=corr_match.competition.game_id).\ order_by(GameType.name.asc()).\ all() gametype_choices = [(gt.id, gt.name) for gt in gametypes] players = Team.query.filter_by(id=corr_match.team_id).first().\ players.all() player_choices = \ sorted([ (p.user_id, p.user.name) for p in players ], key=lambda x: x[1].lower()) if adding and request.method == 'GET': form.rounds.append_entry() for e in form.rounds.entries: e.map_id.choices = map_choices e.side_id.choices = side_choices e.gametype_id.choices = gametype_choices if adding and request.method == 'GET': e.players.append_entry() for ep in e.players.entries: ep.user_id.choices = player_choices forfeit_result = request.values.get('forfeit_result') if form.validate_on_submit(): if not g.user.is_team_leader(form.team_id.data): flash(u'Invalid team', 'error') elif not len(form.rounds) and not forfeit_result: flash(u'Invalid rounds', 'error') else: error = False date = to_utc(form.date_played.data) if adding: cmatch = CompletedMatch( team_id=form.team_id.data, date_created=datetime.datetime.utcnow(), opponent_id=form.opponent_id.data, competition_id=form.competition_id.data, creator_user_id=g.user.id, server_id=form.server_id.data, match_id=corr_match.id) else: cmatch = corr_match for r in cmatch.rounds.all(): cmatch.rounds.remove(r) cmatch.date_played = date cmatch.comments = form.comments.data if forfeit_result in ('1', '0'): cmatch.final_result_method = CompletedMatch.FinalResultByForfeit cmatch.draws = 0 if forfeit_result == '1': cmatch.wins = 1 cmatch.losses = 0 else: cmatch.wins = 0 cmatch.losses = 1 if adding: db.session.add(cmatch) db.session.commit() flash(u'The results were successfully saved.', 'success') return redirect(url_for('matches.my_previous_matches')) else: cmatch.final_result_method = form.final_result_method.data cmatch.wins = 0 cmatch.losses = 0 cmatch.draws = 0 if adding: db.session.add(cmatch) db.session.flush() total_wins = 0 total_losses = 0 total_draws = 0 round_wins = 0 round_losses = 0 round_draws = 0 round_num = 1 for r in form.rounds: rnd = CompletedMatchRound(cmatch_id=cmatch.id, round_id=round_num, map_id=r.map_id.data, side_id=r.side_id.data, gametype_id=r.gametype_id.data, wins=r.wins.data, losses=r.losses.data, draws=r.draws.data) cmatch.rounds.append(rnd) db.session.flush() if not len(r.players): flash(u'No players found', 'error') error = True break total_wins += rnd.wins total_losses += rnd.losses total_draws += rnd.draws if rnd.wins > rnd.losses: round_wins += 1 elif rnd.wins < rnd.losses: round_losses += 1 else: round_draws += 1 player_set = set() for p in r.players: if p.user_id.data in player_set: errmsg = u'You have duplicate players in round %d. ' %\ round_num errmsg += 'A player may appear in a round only once.' flash(errmsg, 'error') error = True break player_set.add(p.user_id.data) player = CompletedMatchPlayer(cmatch_id=cmatch.id, round_id=round_num, user_id=p.user_id.data, kills=p.kills.data, deaths=p.deaths.data, off_objs=p.off_objs.data, def_objs=p.def_objs.data, score=p.score.data) rnd.players.append(player) if error: break round_num += 1 if cmatch.final_result_method == CompletedMatch.FinalResultByScore: cmatch.wins = total_wins cmatch.losses = total_losses cmatch.draws = total_draws else: cmatch.wins = round_wins cmatch.losses = round_losses cmatch.draws = round_draws if error: db.session.rollback() else: db.session.commit() flash(u'The results were successfully saved.', 'success') return redirect(url_for('matches.my_previous_matches')) return rt('results/form.html', page={ 'top': 'my_matches', 'sub': 'previous' }, adding=adding, player_choices=player_choices, map_choices=map_choices, side_choices=side_choices, gametype_choices=gametype_choices, corr_match=corr_match, form=form)
def add(): if not g.user.is_team_leader(): flash(u'You must be a team leader to add a match.', 'error') return redirect(url_for('my_matches')) opponents = Opponent.query.\ filter(Opponent.team_id.in_(g.user.team_leader_teams)).\ order_by(Opponent.name.asc()).all() servers = Server.query.\ filter(Server.team_id.in_(g.user.team_leader_teams)).\ order_by('server_name') competitions = Competition.query.order_by('competition_name') form = AddMatchForm() form.team_id.choices = [(t, g.user.teams[t].name) for t in g.user.team_leader_teams] form.competition_id.choices = [(c.id, c.name) for c in competitions] form.server_id.choices = [(s.id, s.name) for s in servers] form.opponent_id.choices = [(o.id, o.name) for o in opponents] if request.method == 'GET': if request.values.get('new_opponent_id'): form.opponent_id.data = int(request.values.get('new_opponent_id')) elif request.values.get('new_server_id'): form.server_id.data = int(request.values.get('new_server_id')) # default to tomorrow at 9pm form.date.data = datetime.datetime.combine((\ to_user_timezone(datetime.datetime.utcnow()) \ + datetime.timedelta(days=1))\ .date(),\ datetime.time(21)) form.date.label.text += ' (in %s)' \ % format_datetime(form.date.data, 'zzzz') if form.validate_on_submit(): if not g.user.is_team_leader(form.team_id.data): flash(u'You must be a team leader to add a match.', 'error') else: date = to_utc(form.date.data) match = Match(team_id=form.team_id.data, date=date, comments=form.comments.data, password=form.password.data, opponent_id=form.opponent_id.data, competition_id=form.competition_id.data, creator_user_id=g.user.id, server_id=form.server_id.data) db.session.add(match) db.session.commit() team_date = matches_datetime_format_full_for_team(date, \ g.user.teams[form.team_id.data].time_zone) date_short = matches_datetime_format(date) team_date_short = matches_datetime_format_for_team(date, \ g.user.teams[form.team_id.data].time_zone) email_vars = { 'date': matches_datetime_format_full(date), 'team_date': team_date, 'date_short': date_short, 'team_date_short': team_date_short, 'team': g.user.teams[form.team_id.data].name, 'opponent': match.opponent.name, 'opponent_tag': match.opponent.tag, 'competition': match.competition.name, 'server': match.server.name, 'address': match.server.address, 'password': match.password, 'comments': match.comments, 'match_url': abs_url_for('show', match_id=match.id), 'settings_url': abs_url_for('account.settings') } subject = "[tardyrush] New Match "\ "on %(date_short)s vs. %(opponent_tag)s" %\ email_vars team_subject = "[tardyrush] New Match "\ "on %(team_date_short)s vs. %(opponent_tag)s" %\ email_vars lines = ["A new match has been added."] lines.append("") lines.append("%(team)s vs. %(opponent)s" % email_vars) lines.append("%%(date)s" % email_vars) lines.append("") lines.append("Competition: %(competition)s" % email_vars) lines.append("Server: %(server)s" % email_vars) lines.append("Address: %(address)s" % email_vars) if len(email_vars['password']): lines.append("Password: %(password)s" % email_vars) lines.append("") if len(email_vars['comments']): lines.append("Comments:") lines.append("%(comments)s" % email_vars) lines.append("") lines.append("Set your status: %(match_url)s" % email_vars) lines.append("") lines.append("Change your settings: %(settings_url)s" % email_vars) lines.append("") raw_message = "\n".join(lines) message = raw_message % email_vars team_message = raw_message % {'date': email_vars['team_date']} # now notify players of new match via email players = db.session.query(User).\ select_from(join(User, TeamPlayer)).\ filter(TeamPlayer.team_id==form.team_id.data).\ filter(User.email_settings==User.EmailMatchAdded) if form.send_notification.data: try: with mail.connect() as conn: for p in players: try: msg = Message(recipients=[p.email], body=message, subject=subject, sender=Sender) conn.send(msg) app.logger.info("Sent mail to: %s" % p.email) except Exception, e: app.logger.error("Error sending mail: %s, %s" % \ (p.email, e)) except Exception, e: app.logger.error("Error sending mail: %s" % e) # now notify players of new match via forum post if form.post_on_forums.data: forum_post = ForumBotQueuedPost( team_id=match.team_id, game_id=match.competition.game_id, match_id=match.id, subject=team_subject, message=team_message) db.session.add(forum_post) db.session.commit() flash(u'The match was successfully added.', 'success') return redirect(url_for('my_matches'))
def show(match_id, action): match = Match.query.filter_by(id=match_id).first() if not match: flash(u"That match doesn't exist.", "error") return redirect(url_for('my_matches')) if not g.user.is_on_team(match.team_id): flash(u'You must be on the team to view its match availability.', "error") return redirect(url_for('all')) if match.date < datetime.datetime.utcnow(): up_prev = 'previous' else: up_prev = 'upcoming' if action == 'edit': if not g.user.is_team_leader(match.team_id): flash(u'You must be a team leader to edit this match.', 'error') return redirect(url_for('my_matches')) servers = Server.query.\ filter_by(team_id=match.team_id).\ order_by('server_name') form = MatchForm(request.form, obj=match) form.competition_id.choices = [ (c.id, c.name) for c in Competition.query.order_by('competition_name') ] form.server_id.choices = [(s.id, s.name) for s in servers] form.team_id.choices = [(t, g.user.teams[t].name) for t in g.user.team_leader_teams] form.opponent_id.choices = [ (o.id, o.name) for o in \ Opponent.query.filter_by(team_id=match.team_id).\ order_by(Opponent.name.asc()).all() ] players = {} for p in match.players: players[p.user_id] = p.user.name if request.method == 'GET': if request.values.get('new_opponent_id'): form.opponent_id.data = int( request.values.get('new_opponent_id')) elif request.values.get('new_server_id'): form.server_id.data = int(request.values.get('new_server_id')) form.date.data = to_user_timezone(form.date.data) form.date.label.text += ' (in %s)' \ % format_datetime(form.date.data, 'zzzz') if form.validate_on_submit(): form.date.data = to_utc(form.date.data) to_delete = [] for f in form.players: if f.delete.data: to_delete.append(f.user_id.data) form.populate_obj(match) if len(to_delete): MatchPlayer.query.\ filter_by(match_id=match_id).\ filter(MatchPlayer.user_id.in_(to_delete)).delete(False) db.session.commit() flash(u'The match was successfully updated.', 'success') if request.values.get('from') == 'single': return redirect(url_for('show', match_id=match_id)) return redirect(url_for('my_matches')) oform = OpponentForm() sform = ServerForm() tzform = UserTimeZoneForm(obj=g.user) return rt('matches/form.html', form=form, players=players, page={ 'top': 'my_matches', 'sub': up_prev }, when=up_prev, adding=False, user_now=to_user_timezone(datetime.datetime.utcnow()), tzform=tzform, oform=oform, sform=sform, team_id=g.user.team_leader_teams[0], match_id=match.id) elif action == 'delete': if not g.user.is_team_leader(match.team_id): flash(u'You must be a team leader to edit this match.', 'error') return redirect(url_for('my_matches')) if request.method == 'POST': db.session.delete(match) db.session.commit() flash(u'The match was successfully deleted.', 'success') return redirect(url_for('my_matches')) elif action == 'status': if not g.user.is_on_team(match.team_id): flash(u'You must be on this team to change your status.', 'error') return redirect(url_for('my_matches')) if up_prev == 'previous': flash(u'You cannot change your status on a past match.', 'error') return redirect(url_for('my_previous_matches')) form = MatchPlayerStatusForm(request.form) if form.validate_on_submit(): if request.values.get('s') == 'available': player_status = MatchPlayer.StatusAvailable elif request.values.get('s') == 'maybe': player_status = MatchPlayer.StatusMaybe elif request.values.get('s') == 'unavailable': player_status = MatchPlayer.StatusUnavailable else: player_status = None if player_status is None: flash(u'That status is not valid!', 'error') else: try: mu = MatchPlayer.query.filter_by(match_id=match.id, user_id=g.user.id).one() mu.status = player_status except NoResultFound: mu = MatchPlayer(match_id=match.id, user_id=g.user.id, status=player_status) except Exception, e: app.logger.error('Error finding MatchPlayer: %s, %s' % \ (g.user.id, e)) flash(u'Something bad happened. Please try again.', 'error') return redirect(url_for('my_matches')) mu.date_updated = datetime.datetime.utcnow() db.session.add(mu) db.session.commit() if request.values.get('api') == '1': psp = mu.pretty_status return jsonify(success=True, csrf=form.csrf_token.data, match_id=match.id, user_id=g.user.id, user_name=g.user.name, player_status=player_status, player_status_pretty=psp) if request.values.get('from') == 'single': return redirect(url_for('show', match_id=match_id))
flash(u'The match was successfully added.', 'success') return redirect(url_for('my_matches')) oform = OpponentForm() sform = ServerForm() tzform = UserTimeZoneForm(obj=g.user) return rt('matches/form.html', page={ 'top': 'my_matches', 'sub': 'add_match' }, adding=True, team_id=g.user.team_leader_teams[0], user_now=to_user_timezone(datetime.datetime.utcnow()), tzform=tzform, oform=oform, sform=sform, form=form) @matches.route('/match/<int:match_id>/', defaults={'action': ''}) @matches.route('/match/<int:match_id>/<action>/', methods=('GET', 'POST')) @require_login() def show(match_id, action): match = Match.query.filter_by(id=match_id).first() if not match: flash(u"That match doesn't exist.", "error") return redirect(url_for('my_matches'))