Browse Source

Add player last location on map

feature_tests
Burathar 4 years ago
parent
commit
aee2de4a3b
  1. 2
      app/__init__.py
  2. 22
      app/models.py
  3. 4
      app/routes.py
  4. BIN
      app/static/assets/leaflet/images/marker-icon-2x-black.png
  5. BIN
      app/static/assets/leaflet/images/marker-icon-2x-blue.png
  6. BIN
      app/static/assets/leaflet/images/marker-icon-2x-gold.png
  7. BIN
      app/static/assets/leaflet/images/marker-icon-2x-green.png
  8. BIN
      app/static/assets/leaflet/images/marker-icon-2x-grey.png
  9. BIN
      app/static/assets/leaflet/images/marker-icon-2x-orange.png
  10. BIN
      app/static/assets/leaflet/images/marker-icon-2x-red.png
  11. BIN
      app/static/assets/leaflet/images/marker-icon-2x-violet.png
  12. BIN
      app/static/assets/leaflet/images/marker-icon-2x-yellow.png
  13. BIN
      app/static/assets/leaflet/images/marker-icon-black.png
  14. BIN
      app/static/assets/leaflet/images/marker-icon-blue.png
  15. BIN
      app/static/assets/leaflet/images/marker-icon-gold.png
  16. BIN
      app/static/assets/leaflet/images/marker-icon-green.png
  17. BIN
      app/static/assets/leaflet/images/marker-icon-grey.png
  18. BIN
      app/static/assets/leaflet/images/marker-icon-orange.png
  19. BIN
      app/static/assets/leaflet/images/marker-icon-red.png
  20. BIN
      app/static/assets/leaflet/images/marker-icon-violet.png
  21. BIN
      app/static/assets/leaflet/images/marker-icon-yellow.png
  22. BIN
      app/static/assets/leaflet/images/marker-shadow.png
  23. 29
      app/templates/game_dashboard.html

2
app/__init__.py

@ -9,6 +9,7 @@ from flask_bootstrap import Bootstrap @@ -9,6 +9,7 @@ from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_moment import Moment
app = Flask(__name__)
@ -18,6 +19,7 @@ db = SQLAlchemy(app) @@ -18,6 +19,7 @@ db = SQLAlchemy(app)
migrate = Migrate(app, db)
login = LoginManager(app)
login.login_view = 'login'
moment = Moment(app)
from app import routes, models, errors

22
app/models.py

@ -9,7 +9,9 @@ import json @@ -9,7 +9,9 @@ import json
from json import JSONEncoder
from datetime import datetime
import pytz
from flask_moment import Moment
moment = Moment()
class Role(Enum):
none = 0
@ -80,6 +82,9 @@ class Game(db.Model): @@ -80,6 +82,9 @@ class Game(db.Model):
lazy='select',
backref=db.backref('game', lazy='joined'))
def last_player_locations(self):
return [player.last_location(self) for player in self.players if player.locations]
class Player(UserMixin, db.Model):
""" !Always call set_auth_hash() after creating new instance! """
__tablename__ = 'player'
@ -143,10 +148,11 @@ class Player(UserMixin, db.Model): @@ -143,10 +148,11 @@ class Player(UserMixin, db.Model):
if not self.locations:
return None
if game is None:
return max(location.timestamp for location in self.locations)
return max(location for location in self.locations)
game_start = game.start_time or datetime.min
game_end = game.end_time or datetime.max
return max(location.timestamp for location in self.locations if location.timestamp > game_start and location.timestamp < game_end)
return max((location for location in self.locations if location.timestamp > game_start and location.timestamp < game_end),
key=lambda location: location.timestamp)
@login.user_loader
def load_user(id):
@ -188,6 +194,18 @@ class Location(db.Model): @@ -188,6 +194,18 @@ class Location(db.Model):
latitude = db.Column(db.Numeric(precision=15, scale=10, asdecimal=False, decimal_return_scale=None),nullable=False)
timestamp = db.Column(db.DateTime, server_default=func.now(), nullable=False)
def __str__(self):
return f'{self.longitude}, {self.latitude}'
class LocationEncoder(JSONEncoder):
def default(self, location):
return {
'player_name' : location.player.name,
'longitude' : location.longitude,
'latitude' : location.latitude,
'timestamp_utc' : str(location.timestamp)
}
class Notification(db.Model):
__tablename__ = 'notification'
id = db.Column(db.Integer, primary_key=True)

4
app/routes.py

@ -2,7 +2,7 @@ from flask import render_template, flash, redirect, url_for, request, abort, sen @@ -2,7 +2,7 @@ from flask import render_template, flash, redirect, url_for, request, abort, sen
from flask_login import login_user, logout_user, current_user, login_required
from sqlalchemy import and_
from app import app, db
from app.models import Player, Game, Role, GamePlayer, Objective, ObjectiveMinimalEncoder
from app.models import Player, Game, Role, GamePlayer, Objective, ObjectiveMinimalEncoder, LocationEncoder
from app.forms import LoginForm, RegistrationForm, CreateGameForm, ObjectiveForm
import json
import qrcode
@ -69,7 +69,7 @@ def game_dashboard(game_name): @@ -69,7 +69,7 @@ def game_dashboard(game_name):
#game = Game.query.filter(Game.game_players.any(and_(GamePlayer.player.has(Player.name == current_user.name), GamePlayer.role == 'owner'))).first_or_404()
game = Game.query.filter_by(name = game_name).first_or_404()
if not is_game_owner(game): abort(403)
return render_template('game_dashboard.html', title = 'Game Dashboard', game=game, json=json, encoder=ObjectiveMinimalEncoder)
return render_template('game_dashboard.html', title = 'Game Dashboard', game=game, json=json, objective_encoder=ObjectiveMinimalEncoder, location_encoder=LocationEncoder)
@app.route('/game/<game_name>/player/<player_name>')
@login_required

BIN
app/static/assets/leaflet/images/marker-icon-2x-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
app/static/assets/leaflet/images/marker-icon-2x-blue.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
app/static/assets/leaflet/images/marker-icon-2x-gold.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
app/static/assets/leaflet/images/marker-icon-2x-green.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
app/static/assets/leaflet/images/marker-icon-2x-grey.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
app/static/assets/leaflet/images/marker-icon-2x-orange.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
app/static/assets/leaflet/images/marker-icon-2x-red.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
app/static/assets/leaflet/images/marker-icon-2x-violet.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
app/static/assets/leaflet/images/marker-icon-2x-yellow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
app/static/assets/leaflet/images/marker-icon-black.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
app/static/assets/leaflet/images/marker-icon-blue.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
app/static/assets/leaflet/images/marker-icon-gold.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
app/static/assets/leaflet/images/marker-icon-green.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
app/static/assets/leaflet/images/marker-icon-grey.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
app/static/assets/leaflet/images/marker-icon-orange.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
app/static/assets/leaflet/images/marker-icon-red.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
app/static/assets/leaflet/images/marker-icon-violet.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
app/static/assets/leaflet/images/marker-icon-yellow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
app/static/assets/leaflet/images/marker-shadow.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 618 B

After

Width:  |  Height:  |  Size: 608 B

29
app/templates/game_dashboard.html

@ -32,7 +32,10 @@ @@ -32,7 +32,10 @@
<td>{{ player.found_objectives | selectattr('game', '==', game)|list|length}}</td>
<td>{{ player.caught_players | selectattr('game', '==', game)|list|length}}</td>
<td>{{ player.caught_by_players | selectattr('game', '==', game)|list|length}}</td>
<td>{{ player.last_location(game) }}<td>
<td>{% with location = player.last_location(game) %}
{% if location %}{{ moment(location.timestamp).fromNow()}}: {% endif %}
{{ location }}
<td>{% endwith %}
</tr>
{% endfor %}
</tbody>
@ -77,6 +80,7 @@ @@ -77,6 +80,7 @@
{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
<script type="text/javascript", crossorigin="anonymous">
// Leaflet Map
var map = L.map( 'map', {
@ -92,7 +96,7 @@ @@ -92,7 +96,7 @@
attribution: 'Kaartgegevens &copy; <a href="kadaster.nl">Kadaster</a>'
}).addTo( map );
var objectives = JSON.parse('{{ json.dumps(game.objectives, cls=encoder)|safe }}')
var objectives = JSON.parse('{{ json.dumps(game.objectives, cls=objective_encoder)|safe }}')
for (var i = 0; i < objectives.length; i++){
var objectiveMarker = L.marker([
@ -102,8 +106,27 @@ @@ -102,8 +106,27 @@
objectiveMarker.bindTooltip(`<b>${objectives[i]['name']}</b><br>
${objectives[i]['hash']}`).openPopup();
}
var greenIcon = new L.Icon({
iconUrl: "{{ url_for('static', filename='assets/leaflet/images/marker-icon-2x-green.png') }}",
shadowUrl: "{{ url_for('static', filename='assets/leaflet/images/marker-shadow.png') }}",
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
var players = JSON.parse('{{ json.dumps(game.last_player_locations(), cls=location_encoder)|safe }}')
for (var i = 0; i < players.length; i++){
var playerMarker = L.marker([
players[i]['latitude'],
players[i]['longitude']
], {icon: greenIcon}).addTo(map);
var timestamp_utc = moment.utc(players[i]['timestamp_utc']).toDate()
var timestamp_local = moment(timestamp_utc).local().format('YYYY-MM-DD HH:mm');
playerMarker.bindTooltip(`<b>${players[i]['player_name']}</b><br>
${timestamp_local}`).openPopup();
}
</script>
{% endblock %}
Loading…
Cancel
Save