Browse Source

implement player location update

testing
Burathar 4 years ago
parent
commit
5d58700661
  1. 35
      app/main/routes.py
  2. 6
      app/models/user.py
  3. 2
      app/templates/catch_bunny.html
  4. 2
      app/templates/game_bunny_dashboard.html
  5. 2
      app/templates/game_hunter_dashboard.html
  6. 2
      app/templates/index.html
  7. 45
      app/templates/player_base.html

35
app/main/routes.py

@ -2,7 +2,7 @@ import fnmatch
import json import json
from os import listdir from os import listdir
from pathlib import Path from pathlib import Path
from datetime import datetime from datetime import datetime, timedelta
from flask import render_template, flash, redirect, url_for, request, abort, send_file, current_app, send_from_directory from flask import render_template, flash, redirect, url_for, request, abort, send_file, current_app, send_from_directory
from flask_login import current_user, login_required from flask_login import current_user, login_required
@ -13,8 +13,10 @@ from sqlalchemy import and_
from app import db from app import db
from app.main import bp from app.main import bp
from app.utils import generate_qr_code, serve_pil_image from app.utils import generate_qr_code, serve_pil_image
from app.models import User, Game, Role, GamePlayer, Objective, ObjectiveMinimalEncoder, LocationEncoder, PlayerCaughtPlayer, Review from app.models import User, Game, Role, GamePlayer, Objective, ObjectiveMinimalEncoder, \
from app.main.forms import CreateGameForm, ObjectiveForm, PlayerAddForm, UserCreateForm, PlayerUpdateForm, CatchBunnyForm LocationEncoder, PlayerCaughtPlayer, Review, Location
from app.main.forms import CreateGameForm, ObjectiveForm, PlayerAddForm, UserCreateForm, \
PlayerUpdateForm, CatchBunnyForm
@bp.before_app_request @bp.before_app_request
def before_request(): def before_request():
@ -302,3 +304,30 @@ def objective(objective_hash):
return redirect(url_for('main.game_dashboard', game_name=objective.game.name)) return redirect(url_for('main.game_dashboard', game_name=objective.game.name))
return render_template('objective.html', title='Objective view', return render_template('objective.html', title='Objective view',
objective=objective, owner=True, form=form, qrcode=qrcode) objective=objective, owner=True, form=form, qrcode=qrcode)
@bp.route('/user/<username>/send_location', methods=['POST'])
@login_required
def send_location(username):
user = User.query.filter_by(name=username).first_or_404()
last_location = user.last_location()
latitude = request.form.get('lat', default=None, type=float)
longitude = request.form.get('long', default=None, type=float)
if latitude is None or longitude is None:
return '', 400
# Check if previous two locations are exactly the same, if so, only update timestamp of last location
if last_location:
if datetime.utcnow() - last_location.timestamp < timedelta(milliseconds=1):
return '', 204
if latitude == last_location.latitude and longitude == last_location.longitude and len(user.locations) >= 2:
before_last_location = user.locations[-2]
if before_last_location:
if latitude == before_last_location.latitude and longitude == before_last_location.longitude:
last_location.timestamp = datetime.utcnow()
db.session.commit()
return '', 204
user.locations.append(Location(longitude=longitude, latitude=latitude))
db.session.commit()
return '', 204

6
app/models/user.py

@ -53,12 +53,12 @@ class User(UserMixin, db.Model):
return [location for location in self.locations if location.timestamp > game_start and location.timestamp < game_end] return [location for location in self.locations if location.timestamp > game_start and location.timestamp < game_end]
def last_location(self, game=None): def last_location(self, game=None):
# pylint: disable=not-an-iterable # pylint: disable=[not-an-iterable, unsubscriptable-object]
if not self.locations: if not self.locations:
return None return None
if game is None: if game is None:
return max(self.locations, key=lambda location: location.timestamp) return self.locations[-1]
return max(self.locations_during_game(game), key=lambda location: location.timestamp) return self.locations_during_game(game)[-1]
def role_in_game(self, game): def role_in_game(self, game):
'''Returns the role as Role enum of player in given game. Returns None if player does not participate in game''' '''Returns the role as Role enum of player in given game. Returns None if player does not participate in game'''

2
app/templates/catch_bunny.html

@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'player_base.html' %}
{% import 'bootstrap/wtf.html' as wtf %} {% import 'bootstrap/wtf.html' as wtf %}
{% block player_app_content %} {% block player_app_content %}

2
app/templates/game_bunny_dashboard.html

@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'player_base.html' %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}

2
app/templates/game_hunter_dashboard.html

@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'player_base.html' %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}

2
app/templates/index.html

@ -1,4 +1,4 @@
{% extends 'base.html' %} {% extends 'player_base.html' %}
{% block player_app_content %} {% block player_app_content %}
<h1>Hi, {{ current_user.name }}!</h1> <h1>Hi, {{ current_user.name }}!</h1>

45
app/templates/player_base.html

@ -0,0 +1,45 @@
{% extends 'base.html' %}
{% block app_content %}
<meta name="csrf-token" content="{{ csrf_token() }}">
{% block player_app_content %}{% endblock %}
{% endblock %}
{% block scripts %}
{{ super() }}
<script>
var csrftoken = $('meta[name=csrf-token]').attr('content')
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken)
}
}
})
function sendLocation(position) {
$.ajax({
type: "POST",
url: "{{ url_for('main.send_location', username=current_user.name) }}",
data:{
lat: position.coords.latitude,
long: position.coords.longitude
},
error: function(error) {
console.log(error);
}
});
}
$(document).ready(function(){
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(sendLocation);
} else {
console.log('Geolocation is not supported by this browser.')
}
})
</script>
{% endblock %}
Loading…
Cancel
Save