player.py 4.23 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 18 18:34:40 2018

@author: Antoine Lima, Leo Reynaert, Domitille Jehenne
"""

import logging
from enum import Enum
Antoine Lima's avatar
Antoine Lima committed
11 12 13 14 15 16
from database import Database, DatabaseError

from PyQt5.QtCore import Qt, QCoreApplication
from PyQt5.QtWidgets import QDialog

from ui.consent_dialog_ui import Ui_Dialog as ConsentDialogUI
17 18

class Side(Enum):
19 20 21 22 23 24
	'''
	Values of the enum are used throughout the code for indexing purposes, not to be changed
	'''
	Undef = -1
	Left  = 0
	Right = 1
Antoine Lima's avatar
Antoine Lima committed
25 26 27 28
	
	@property
	def opposite(self):
		return Side.Right if self==Side.Left else Side.Left 
29

Antoine Lima's avatar
Antoine Lima committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43
class ConsentDialog(QDialog):
	def __init__(self, parent):
		QDialog.__init__(self, parent)
		self.ui = ConsentDialogUI()
		self.ui.setupUi(self)
		
		self.ui.txtConsent.setHtml(QCoreApplication.translate('consent', '''<p>
			You are about to connect yourself for the first time. We will need to access:
			<ul>
				<li>Your Name and Surname</li>
				<li>Your Picture (if public)</li>
				<li>...</li>
			</ul>
			</p> 
44

Antoine Lima's avatar
Antoine Lima committed
45 46 47 48 49 50 51 52 53 54 55 56
			<p>
			It is possible to play withtout connecting yourslef, but this will allow you to keep track of your score and to provide a better experience for you and the ones you play with!
			<br/><br/>
			Do you agree with this?
			</p>'''))
		
	def keyPressEvent(self, e):
		if e.key()==Qt.Key_Return:
			self.accept()
		else:
			self.reject()
		
57
class Player():
Antoine Lima's avatar
Antoine Lima committed
58 59 60 61 62 63
	__query_infos = 'SELECT id, fname, lname, pic FROM Players WHERE rfid==?'
	__query_time_goals_games = 'SELECT SUM(Matchs.duration) AS timePlayed, SUM(Teams.nGoals) AS goalsScored, COUNT(*) AS gamesPlayed FROM Teams INNER JOIN  Matchs ON (Teams.id==Matchs.winningTeam OR Teams.id==Matchs.losingTeam) WHERE (Teams.player1==? OR player2==?)'
	__query_victories = 'SELECT COUNT(*) AS victories FROM Players INNER JOIN Teams ON (Players.id==Teams.player1 OR Players.id==Teams.player2) INNER JOIN  Matchs ON (Teams.id==Matchs.winningTeam) WHERE Players.id==?'

	_placeholder_pic_path = ':ui/img/placeholder_head.jpg'
	
Antoine Lima's avatar
Antoine Lima committed
64 65
	_first_time = True # Debug
	
66
	def __init__(self, id, rfid, fname, lname, pic_path, stats):
67
		self.id = id
68
		self.rfid = rfid
69 70
		self.fname = fname
		self.lname = lname
Antoine Lima's avatar
Antoine Lima committed
71 72 73
		self.pic_path = pic_path if pic_path else Player._placeholder_pic_path # Default pic if None
		self.stats = stats
	
74
	@staticmethod
Antoine Lima's avatar
Antoine Lima committed
75 76 77 78 79 80
	def fromRFID(rfid):
		db = Database.instance()
		
		try:
			# Retrieve generic informations
			id, fname, lname, pic = db.select_one(Player.__query_infos, rfid)
81
			
Antoine Lima's avatar
Antoine Lima committed
82 83 84 85 86 87 88 89 90 91
			# Ask for consent
			if rfid==-2 and Player._first_time:
				import babyfut
				consentDialog = ConsentDialog(babyfut.getMainWin())
				consentDialog.exec()
				
				if not consentDialog.result()==QDialog.Accepted:
					Player._first_time = False
					return PlayerGuest
			
Antoine Lima's avatar
Antoine Lima committed
92
			# Retrieve stats
Antoine Lima's avatar
Antoine Lima committed
93 94 95
			stats = {}
			stats['time_played'], stats['goals_scored'], stats['games_played'] = db.select_one(Player.__query_time_goals_games, id, id)
			stats['victories'], = db.select_one(Player.__query_victories, id)
Antoine Lima's avatar
Antoine Lima committed
96
			
97 98 99 100 101
			for key, val in stats.items():
				if val==None:
					stats[key] = 0
			
			return Player(id, rfid, fname, lname, pic, stats)
102
		
Antoine Lima's avatar
Antoine Lima committed
103 104 105
		except DatabaseError as e:
			logging.warn('DB Error: {}'.format(e))
			return PlayerGuest
106 107 108
	
	def displayImg(self, containerWidget):
		containerWidget.setStyleSheet('border-image: url({});'.format(self.pic_path))
109 110 111 112 113 114 115 116
	
	def save(self):
		'''
		Update or create the player in database
		'''
	
	@property
	def name(self):
117
		return '{} {}'.format(self.fname, self.lname.upper())
Antoine Lima's avatar
Antoine Lima committed
118
		
119
	@property
Antoine Lima's avatar
Antoine Lima committed
120
	def stats_property(self):
121 122 123 124 125
		'''
		Compatibility property allowing to access stats as a object member and not dict
		ex: player.stats['victories'] can be accessed with player.stats_property.victories'
		This is mostly used for sorting players in leaderboard.py
		'''
Antoine Lima's avatar
Antoine Lima committed
126 127 128 129 130 131
		class Stat:
			def __init__(self, stats):
				self.victories = stats['victories']
				self.time_played = stats['time_played']
				self.goals_scored = stats['goals_scored']
				self.games_played = stats['games_played']
132
		
Antoine Lima's avatar
Antoine Lima committed
133
		return Stat(self.stats)
134 135
	
	@staticmethod
Antoine Lima's avatar
Antoine Lima committed
136
	def allStoredPlayers():
137
		return [Player.fromRFID(rfid) for rfid, in Database.instance().select_all_rfid()]
138

139
PlayerGuest = Player.fromRFID(-1)
140
PlayerEmpty = Player(-1, -42, '', '', Player._placeholder_pic_path, {'time_played':'', 'goals_scored':'', 'games_played':'', 'victories': ''})