Browse Source

enforce game start,end, and state, add been found to gameplayerinfo

testing
Burathar 4 years ago
parent
commit
b4e508e020
  1. 13
      app/main/forms.py
  2. 57
      app/main/routes.py
  3. 7
      app/models/game.py
  4. 13
      app/templates/_game_player_info.html
  5. 27
      app/templates/create_game.html
  6. 7
      app/templates/game_owner_dashboard.html

13
app/main/forms.py

@ -3,17 +3,19 @@ from flask_wtf.file import FileField, FileAllowed, FileRequired @@ -3,17 +3,19 @@ from flask_wtf.file import FileField, FileAllowed, FileRequired
from wtforms import StringField, SubmitField, DateTimeField, BooleanField, HiddenField, FloatField, SelectField
from wtforms.validators import InputRequired, DataRequired, ValidationError, Length, NumberRange
from pytz import timezone
from app.models import Objective
from app.models import Objective, Game
from app import Config
class CreateGameForm(FlaskForm):
game_name = StringField('Game Name', validators=[InputRequired(), Length(min=0, max=64)])
state = SelectField('Game State', coerce=int, validators=[InputRequired()])
start_time_disabled = BooleanField('No start time')
start_time = DateTimeField(id='datetimepicker_start', format="%d-%m-%Y %H:%M")
end_time_disabled = BooleanField('No end time')
end_time = DateTimeField(id='datetimepicker_end', format="%d-%m-%Y %H:%M")
timezone = HiddenField(validators=[DataRequired()])
submit = SubmitField('Create')
old_name = ''
def validate_start_time(self, start_time):
self.date_time_validator(self.start_time_disabled, start_time)
@ -29,6 +31,15 @@ class CreateGameForm(FlaskForm): @@ -29,6 +31,15 @@ class CreateGameForm(FlaskForm):
date_time_utc = clientzone.localize(date_time.data).astimezone(timezone('UTC'))
date_time.data = date_time_utc
def validate_game_name(self, game_name):
if game_name.data == '':
return
if game_name.data == self.old_name:
return
game = Game.query.filter_by(name=game_name.data).first()
if game is not None:
raise ValidationError('Please use a different name.')
class ObjectiveForm(FlaskForm):
objective_name = StringField('Objective Name', validators=[Length(min=0, max=64)])
latitude = FloatField('Latitude', validators=[DataRequired(), NumberRange(min=-90, max=90)])

57
app/main/routes.py

@ -13,7 +13,7 @@ from sqlalchemy import and_ @@ -13,7 +13,7 @@ from sqlalchemy import and_
from app import db
from app.main import bp
from app.utils import generate_qr_code, serve_pil_image
from app.models import User, Game, Role, GamePlayer, Objective, ObjectiveMinimalEncoder, \
from app.models import User, Game, Role, GamePlayer, GameState, Objective, ObjectiveMinimalEncoder,\
LocationEncoder, PlayerCaughtPlayer, Review, Location
from app.main.forms import CreateGameForm, ObjectiveForm, PlayerAddForm, UserCreateForm, \
PlayerUpdateForm, CatchBunnyForm
@ -36,9 +36,14 @@ def index(): @@ -36,9 +36,14 @@ def index():
@login_required
def create_game():
form = CreateGameForm()
form.state.choices = [(state.value, state.name) for state in GameState]
if form.validate_on_submit():
game = Game(name=form.game_name.data, start_time=form.start_time.data,
end_time=form.end_time.data)
if Game.query.filter_by(name=form.game_name.data):
flash('Please choose a different game name')
return render_template('create_game.html', title='Create Game', form=form)
game = Game(name=form.game_name.data, start_time=form.start_time.data,
end_time=form.end_time.data, state=GameState(form.state.data))
game.players.append(GamePlayer(user=current_user, role=Role['owner']))
db.session.add(game)
db.session.commit()
@ -46,6 +51,43 @@ def create_game(): @@ -46,6 +51,43 @@ def create_game():
return redirect(url_for('main.game_dashboard', game_name=game.name))
return render_template('create_game.html', title='Create Game', form=form)
@bp.route('/game/<game_name>/change_settings', methods=['GET', 'POST'])
@login_required
def change_game_settings(game_name):
game = Game.query.filter_by(name=game_name).first_or_404()
if not game.owned_by(current_user):
abort(403)
form = CreateGameForm()
form.state.choices = [(state.value, state.name) for state in GameState]
form.old_name = game.name
if request.method == 'GET':
form.state.default = game.state.value
# pylint: disable=no-member
form.process()
form.game_name.data = game.name
if game.start_time:
form.start_time.data = game.start_time
else:
form.start_time_disabled.data = True
form.start_time.data = None
if game.end_time:
form.end_time.data = game.end_time
else:
form.end_time_disabled.data = True
form.end_time.data = None
if form.validate_on_submit():
game.name = form.game_name.data
game.start_time = form.start_time.data
game.end_time = form.end_time.data
game.state = GameState(form.state.data)
db.session.commit()
flash(f"'{game.name}' had been updated!")
return redirect(url_for('main.game_dashboard', game_name=game.name))
return render_template('create_game.html', title='Chage Game Settings', form=form)
@bp.route('/game/<game_name>/delete')
@login_required
def delete_game(game_name):
@ -89,6 +131,9 @@ def catch_bunny(game_name): @@ -89,6 +131,9 @@ def catch_bunny(game_name):
if current_user.role_in_game(game) is not Role.hunter:
flash('Only hunters can catch bunnies!')
abort(403)
if not game.is_active():
flash("Its not possible to catch a bunny before or after a game, or if the game is not in 'started' mode.")
return redirect(url_for('main.game_dashboard', game_name=game.name))
game_bunnies = game.bunnies()
form = CatchBunnyForm()
@ -180,7 +225,6 @@ def add_player(game_name): @@ -180,7 +225,6 @@ def add_player(game_name):
if not game.owned_by(current_user):
abort(403)
form_add = PlayerAddForm()
form_add.role.choices = [(role.value, role.name) for role in Role]
form_create = UserCreateForm()
@ -283,6 +327,9 @@ def objective_qrcode(objective_hash): @@ -283,6 +327,9 @@ def objective_qrcode(objective_hash):
def objective(objective_hash):
objective = Objective.query.filter_by(hash=objective_hash).first_or_404()
if current_user.role_in_game(objective.game) == Role.bunny:
if not objective.game.is_active():
flash("Its not find an objective before or after a game, or if the game is not in 'started' mode.")
return redirect(url_for('main.game_dashboard', game_name=objective.game.name))
player = current_user.player_in(objective.game)
if not objective in player.found_objectives:
player.found_objectives.append(objective)
@ -345,4 +392,4 @@ def user_profile(username): @@ -345,4 +392,4 @@ def user_profile(username):
user = User.query.filter_by(name=username).first_or_404()
if current_user != user:
abort(403)
return render_template('user_profile.html', user=user)
return render_template('user_profile.html', user=user)

7
app/models/game.py

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
from datetime import datetime
from sqlalchemy.ext.associationproxy import association_proxy
from app import db
from .game_state import GameState
@ -64,3 +65,9 @@ class Game(db.Model): @@ -64,3 +65,9 @@ class Game(db.Model):
return [pcp for pcps in
[player.player_caught_players for player in self.players]
for pcp in pcps if pcp.review == Review.none]
def is_active(self):
now = datetime.utcnow()
return now > (self.start_time or datetime.min) and \
now < (self.end_time or datetime.max) and \
self.state == GameState.started

13
app/templates/_game_player_info.html

@ -25,5 +25,18 @@ @@ -25,5 +25,18 @@
<th>End Time</th>
<td>{% if game.end_time %}{{ moment(game.end_time).format('DD-MM-YYYY, hh:mm')}}{% else %}-{% endif %}</td>
</tr>
{% if current_user.role_in_game(game).name == 'bunny' %}
<tr>
<th>Been Found</th>
<td>
<span style="color:green;">{{ current_user.player_caught_by_players | selectattr('catching_player', '==', player) | selectattr('review.name', '==', 'accepted') |list|length}}</span> /
<span style="color:red;">{{ current_user.player_caught_by_players | selectattr('catching_player', '==', player) | selectattr('review.name', '==', 'denied') |list|length}}</span> /
<span style="color:gray;">{{ current_user.player_caught_by_players | selectattr('catching_player', '==', player) | selectattr('review.name', '==', 'none') |list|length}}</span>
<span style="font-size: smaller;">
(<span style="color:green;">Accepted</span>/<span style="color:red;">Denied</span>/<span style="color:gray;">Not reviewed</span>)
</span>
</td>
</tr>
{% endif %}
</table>
</div>

27
app/templates/create_game.html

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
{% endblock %}
{% block app_content %}
<h1>Create a new game</h1>
<h1>{{ title }}</h1>
<div class="col-md-4 col-sm-6 col-xs-8">
<hr>
@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
{{ form.hidden_tag() }}
{{ form.timezone }}
{{ wtf.form_field(form.game_name, class='form-control') }}
{{ wtf.form_field(form.state, class='form-control') }}
{{ form.start_time.label }}
<div class="form-group row">
@ -35,7 +36,11 @@ @@ -35,7 +36,11 @@
{{ wtf.form_field(form.end_time_disabled, class='form-control') }}
</div>
</div>
{% if form.old_name %}
{{ wtf.form_field(form.submit, class='btn btn-primary', value="Update") }}
{% else %}
{{ wtf.form_field(form.submit, class='btn btn-primary') }}
{% endif %}
</form>
<hr>
</div>
@ -50,26 +55,38 @@ @@ -50,26 +55,38 @@
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js"></script>
<script type="text/javascript">
$(function () {
var date = new Date()
'{% if form.start_time_enabled %}'
var startDate = new Date()
'{% else %}'
var startDate = null
'{% endif %}'
'{% if form.end_time_enabled %}'
var endDate = new Date()
'{% else %}'
var endDate = null
'{% endif %}'
$('#datetimepicker_start').datetimepicker({
//useCurrent: false, //Important! See issue #1075
locale: 'en-gb',
format: 'DD-MM-YYYY HH:mm',
keepInvalid: true,
sideBySide: true,
defaultDate: date,
defaultDate: startDate,
timeZone: moment.tz.guess()
});
date.setDate(date.getDate() + 1)
//date.setDate(date.getDate() + 1)
$('#datetimepicker_end').datetimepicker({
//useCurrent: false, //Important! See issue #1075
locale: 'en-gb',
format: 'DD-MM-YYYY HH:mm',
keepInvalid: true,
sideBySide: true,
defaultDate: date,
defaultDate: endDate,
timeZone: moment.tz.guess()
});
var date = new Date()
$("#datetimepicker_start").on("dp.change", function (e) {
$('#datetimepicker_end').data("DateTimePicker").minDate(e.date);
});

7
app/templates/game_owner_dashboard.html

@ -10,11 +10,18 @@ @@ -10,11 +10,18 @@
{% block app_content %}
<h1>{{ game.name }} Dashboard</h1>
<button class="btn btn-danger" onclick="deleteGame()">Delete Game</button>
<a href="{{ url_for('main.change_game_settings', game_name=game.name) }}">
<button class="btn btn-primary">Change Game Settings</button>
</a>
{% if game.unreviewed_bunny_photos() %}
<a href="{{ url_for('main.review_caught_bunny_photos', game_name=game.name) }}">
<button class="btn btn-primary">Review Bunny Photos</button>
</a>
{% endif %}
<br><br>
<p><b>Start Time: </b>{{ game.start_time }}</p>
<p><b>End Time: </b>{{ game.end_time }}</p>
<p><b>State: </b>{{ game.state.name.title() }}</p>
<h2>Players:</h2>
<p><a href="{{ url_for('main.add_player', game_name = game.name) }}">Add player</a></p>
<div class="table-responsive">

Loading…
Cancel
Save