def join_random(request): games = Game.objects(players__ne=request.user.username, state='playing') games.where('this[~num_players] < this[~max_players]') games.order_by('next_ending').limit(1) for game in games: request.session['join_auto'] = game.pk return redirect('game.views.join', game.pk) else: return render(request, 'nogames.html')
def profile(request, username): profile = get_document_or_404(User, username=username) current = Game.objects(players=profile.username, state__in=('playing', 'voting')) current.order_by('next_ending') past = Game.objects(players=profile.username, state__in=('invalid', 'finished')).limit(10) past.order_by('-next_ending') prefs_form = None # if profile == request.user: # initial = PreferencesForm.initial_for(profile) # prefs_form = PreferencesForm(initial=initial) return render(request, 'profile.html', profile=profile, current=current, past=past, prefs_form=prefs_form)
def index(self): form = BallotForm(request.form) form.game.choices = [(str(Game.objects(name=x).first().id), x) for x in Game.objects.distinct('name')] if request.method == 'POST' and form.validate(): game = form.game.data ballot_type = form.ballot_type.data results = self.ballot(game, ballot_type) self._template_args['ballot_results'] = results self._template_args['round'] = self.round return self.render('ballot.html', form=form)
def handle_noargs(self, **options): games = Game.objects(state__in=('playing', 'voting'), next_ending__lte=datetime.now(utc)) for game in games: if game.state == 'playing': if game.num_players < 2: game.update(set__state='invalid') log.debug('advanced game %s from playing to invalid, only %d players', game.pk, game.num_players) else: new_next_ending = game.next_ending + timedelta(minutes=game.minutes_per_round) game.update(set__state='voting', set__next_ending=new_next_ending) log.debug('advanced game %s from playing to voting, next ending %s', game.pk, new_next_ending) elif game.state == 'voting': total_votes = sum(len(play.upvotes) for play in game.plays) if total_votes == 0: game.update(set__state='invalid') log.debug('advanced game %s from voting to invalid, 0 votes', game.pk) else: game.update(set__state='finished') log.debug('advanced game %s from voting to finished', game.pk)
def apply(self, query, value): return query.filter(game__exact=Game.objects(name__exact=value).first().id)
def get_options(self, view): game_list = [(obj.name, obj.name) for obj in Game.objects()] return game_list
def handle_noargs(self, **options): now = datetime.now(utc) leaderboard = Leaderboard.objects._collection bookkeeping = leaderboard.bookkeeping # acquire the "lock" to prevent (potential) other m-r # jobs on leaderboard from running concurrently try: lock = bookkeeping.find_and_modify( query={'_id': 1, 'locked': False}, update={'$set': {'locked': True, 'started_at': now}}, upsert=True, new=True) except OperationFailure: lock = bookkeeping.find_one() diff = (now - lock['started_at']).seconds if 300 < diff and diff < 600: log.info("another leaderboard job running for more than 5 minutes") elif 600 < diff: log.warning("another leaderboard job running for more than 10 minutes") sys.exit(1) try: # find the last updated date in the leaderboard, # or the earliest finished game if no leaderboard # entries exist yet start = lock.get('last_update') if not start: log.debug('running first time') first_game = Game.objects(state='finished') first_game = first_game.order_by('next_ending').first() if first_game: start = first_game.next_ending else: start = datetime.now(utc) end = datetime.now(utc) if end > start: log.info('map-reduce %s to %s', start, end) Game.objects._collection.map_reduce( map=self.map_func, reduce=self.reduce_func, out=leaderboard.name, reduce_output=True, query=Game.objects( state='finished', next_ending__gte=start, next_ending__lt=end)._query ) # iterate each week between start and # end, and ensure indices exist on all # the score fields that they should for d in range(0, (end - start).days + 6, 7): self.ensure_indices(leaderboard, start + timedelta(days=d)) else: log.info('nothing to map-reduce') except: log.exception('error during leaderboard map-reduce') finally: finish = datetime.now(utc) diff = finish - now diff = 86400 * diff.days + diff.seconds log.info('finished, took %ss', diff) bookkeeping.find_and_modify( query={'_id': 1}, update={'$set': {'locked': False, 'last_update': end}})
def index(self): form = RankForm(request.form) form.game.choices = [(str(Game.objects(name=x).first().id), x) for x in Game.objects.distinct('name')] return self.render('rank.html', form=form)