|  |  |  | @ -1,5 +1,5 @@@@ -1,5 +1,5 @@ | 
			
		
	
		
			
				
					|  |  |  |  | from secrets import token_hex | 
			
		
	
		
			
				
					|  |  |  |  | from datetime import datetime | 
			
		
	
		
			
				
					|  |  |  |  | from datetime import datetime, timedelta | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | from flask_login import UserMixin | 
			
		
	
		
			
				
					|  |  |  |  | from sqlalchemy.ext.associationproxy import association_proxy | 
			
		
	
	
		
			
				
					|  |  |  | @ -42,23 +42,47 @@ class User(UserMixin, db.Model):@@ -42,23 +42,47 @@ class User(UserMixin, db.Model): | 
			
		
	
		
			
				
					|  |  |  |  |             return False | 
			
		
	
		
			
				
					|  |  |  |  |         return check_password_hash(self.password_hash, password) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def locations_during_game(self, game): | 
			
		
	
		
			
				
					|  |  |  |  |     def locations_during_game(self, game, offset=0): | 
			
		
	
		
			
				
					|  |  |  |  |         ''' | 
			
		
	
		
			
				
					|  |  |  |  |         Returns users locations during game. | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             Parameters: | 
			
		
	
		
			
				
					|  |  |  |  |                 game (Game): If specified, only locations within start- and endtime of game wil be returned | 
			
		
	
		
			
				
					|  |  |  |  |                 offset (int): Offset in minutes. Only locations older than this amount of minutes will be returned. | 
			
		
	
		
			
				
					|  |  |  |  |         ''' | 
			
		
	
		
			
				
					|  |  |  |  |         # pylint: disable=not-an-iterable | 
			
		
	
		
			
				
					|  |  |  |  |         if not self.locations: | 
			
		
	
		
			
				
					|  |  |  |  |             return None | 
			
		
	
		
			
				
					|  |  |  |  |         if game is None: | 
			
		
	
		
			
				
					|  |  |  |  |             return self.locations | 
			
		
	
		
			
				
					|  |  |  |  |             if offset == 0: | 
			
		
	
		
			
				
					|  |  |  |  |                 return self.locations | 
			
		
	
		
			
				
					|  |  |  |  |             return [location for location in self.locations | 
			
		
	
		
			
				
					|  |  |  |  |                     if datetime.utcnow() - location.timestamp > timedelta(minutes=offset)] | 
			
		
	
		
			
				
					|  |  |  |  |         game_start = game.start_time or datetime.min | 
			
		
	
		
			
				
					|  |  |  |  |         game_end = game.end_time or datetime.max | 
			
		
	
		
			
				
					|  |  |  |  |         return [location for location in self.locations if location.timestamp > game_start and location.timestamp < game_end] | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def last_location(self, game=None): | 
			
		
	
		
			
				
					|  |  |  |  |         if offset == 0: | 
			
		
	
		
			
				
					|  |  |  |  |             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 | 
			
		
	
		
			
				
					|  |  |  |  |                 and datetime.utcnow() - location.timestamp > timedelta(minutes=offset)] | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def last_location(self, game=None, offset=0): | 
			
		
	
		
			
				
					|  |  |  |  |         ''' | 
			
		
	
		
			
				
					|  |  |  |  |         Returns users last recorded location. | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             Parameters: | 
			
		
	
		
			
				
					|  |  |  |  |                 game (Game): If specified, only locations within start- and endtime of game wil be returned | 
			
		
	
		
			
				
					|  |  |  |  |                 offset (int): Offset in minutes. Only locations older than this amount of minutes will be returned. | 
			
		
	
		
			
				
					|  |  |  |  |         ''' | 
			
		
	
		
			
				
					|  |  |  |  |         # pylint: disable=[not-an-iterable, unsubscriptable-object] | 
			
		
	
		
			
				
					|  |  |  |  |         if not self.locations: | 
			
		
	
		
			
				
					|  |  |  |  |             return None | 
			
		
	
		
			
				
					|  |  |  |  |         if game is None: | 
			
		
	
		
			
				
					|  |  |  |  |             return self.locations[-1] | 
			
		
	
		
			
				
					|  |  |  |  |         locations_during_game = self.locations_during_game(game) | 
			
		
	
		
			
				
					|  |  |  |  |             locations = self.locations_during_game(game=None, offset=offset) | 
			
		
	
		
			
				
					|  |  |  |  |             return locations[-1] if locations else None | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         locations_during_game = self.locations_during_game(game, offset=offset) | 
			
		
	
		
			
				
					|  |  |  |  |         return locations_during_game[-1] if locations_during_game else None | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     def role_in_game(self, game): | 
			
		
	
	
		
			
				
					|  |  |  | 
 |