Commit 283f06ef authored by Antoine Lima's avatar Antoine Lima

More privacy measure

+ Renamed onRasp to ON_RASP
parent 4cfbe44c
...@@ -5,11 +5,10 @@ ...@@ -5,11 +5,10 @@
""" """
import os import os
OnRasp = os.uname()[1] == 'raspberrypi' from os.path import dirname, abspath, join, exists
import glob
import sys import sys
import logging import logging
from os.path import dirname, abspath, join
from PyQt5 import QtCore from PyQt5 import QtCore
from PyQt5.QtWidgets import QMainWindow, QApplication from PyQt5.QtWidgets import QMainWindow, QApplication
...@@ -27,6 +26,9 @@ def getMainWin(): ...@@ -27,6 +26,9 @@ def getMainWin():
return widget return widget
return None return None
ON_RASP = os.uname()[1] == 'raspberrypi'
IMG_PATH = getContent('img')
if __name__=='__main__': if __name__=='__main__':
__package__ = 'Babyfut' __package__ = 'Babyfut'
from Babyfut.ui.mainwin import MainWin from Babyfut.ui.mainwin import MainWin
...@@ -43,6 +45,9 @@ if __name__=='__main__': ...@@ -43,6 +45,9 @@ if __name__=='__main__':
app = QApplication(sys.argv) app = QApplication(sys.argv)
myapp = MainWin() myapp = MainWin()
if not exists(IMG_PATH):
os.makedirs(IMG_PATH)
if ReplayThread.isCamAvailable(): if ReplayThread.isCamAvailable():
threadReplay = ReplayThread(Side.Left) threadReplay = ReplayThread(Side.Left)
threadReplay.start() threadReplay.start()
...@@ -65,3 +70,5 @@ if __name__=='__main__': ...@@ -65,3 +70,5 @@ if __name__=='__main__':
finally: finally:
GPIOThread.clean() GPIOThread.clean()
Database.instance().close() Database.instance().close()
for f in glob.glob(join(IMG_PATH, '*')):
os.remove(f)
...@@ -33,6 +33,9 @@ class Database(): ...@@ -33,6 +33,9 @@ class Database():
def _cursor(self): def _cursor(self):
return self._connection.cursor() return self._connection.cursor()
def rfid_exists(self, rfid):
return bool(self._cursor.execute('SELECT rfid FROM Players WHERE rfid==?', (rfid,)).fetchone())
def select_one(self, query, *args): def select_one(self, query, *args):
res = self._cursor.execute(query, args).fetchone() res = self._cursor.execute(query, args).fetchone()
if not res: if not res:
...@@ -58,13 +61,21 @@ class Database(): ...@@ -58,13 +61,21 @@ class Database():
def select_all_rfid(self, debug=False): def select_all_rfid(self, debug=False):
from Babyfut.core.settings import Settings from Babyfut.core.settings import Settings
if Settings['app.mode']=='prod': if Settings['app.mode']=='prod':
return self._cursor.execute('SELECT rfid FROM Players WHERE rfid>0').fetchall() return self._cursor.execute('SELECT rfid FROM Players WHERE rfid>0 AND private==0').fetchall()
else: else:
return self._cursor.execute('SELECT rfid FROM Players WHERE rfid<-1').fetchall() return self._cursor.execute('SELECT rfid FROM Players WHERE rfid<-1 AND private==0').fetchall()
def delete_player(self, playerID): def delete_player(self, playerID):
self._cursor.execute('DELETE FROM Players WHERE id==?', (playerID,)) self._cursor.execute('DELETE FROM Players WHERE id==?', (playerID,))
self._connection.commit() self._connection.commit()
def delete_playerpic(self, playerID):
self._cursor.execute('UPDATE Players SET pic=null WHERE id==?', (playerID,))
self._connection.commit()
def make_player_private(self, playerID):
self._cursor.execute('UPDATE Players SET private=1 WHERE id==?', (playerID,))
self._connection.commit()
def close(self): def close(self):
self._connection.close() self._connection.close()
...@@ -8,10 +8,10 @@ import logging ...@@ -8,10 +8,10 @@ import logging
import pyautogui # PyPi library import pyautogui # PyPi library
from threading import Thread from threading import Thread
from Babyfut.babyfut import OnRasp from Babyfut.babyfut import ON_RASP
from Babyfut.core.player import Side from Babyfut.core.player import Side
if OnRasp: if ON_RASP:
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
class GPIOThread(Thread): class GPIOThread(Thread):
...@@ -29,7 +29,7 @@ class GPIOThread(Thread): ...@@ -29,7 +29,7 @@ class GPIOThread(Thread):
self.dispatcher = dispatcher self.dispatcher = dispatcher
self.continueRunning = True self.continueRunning = True
if OnRasp: if ON_RASP:
GPIO.setwarnings(False) GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) GPIO.setmode(GPIO.BCM)
...@@ -39,7 +39,7 @@ class GPIOThread(Thread): ...@@ -39,7 +39,7 @@ class GPIOThread(Thread):
GPIO.add_event_detect(pin, GPIO.RISING, callback=self.handleButtonPress) GPIO.add_event_detect(pin, GPIO.RISING, callback=self.handleButtonPress)
def run(self): def run(self):
if OnRasp: if ON_RASP:
try: try:
while self.continueRunning: while self.continueRunning:
pass pass
...@@ -59,5 +59,5 @@ class GPIOThread(Thread): ...@@ -59,5 +59,5 @@ class GPIOThread(Thread):
@staticmethod @staticmethod
def clean(): def clean():
if OnRasp: if ON_RASP:
GPIO.cleanup() GPIO.cleanup()
...@@ -62,8 +62,6 @@ class Player(): ...@@ -62,8 +62,6 @@ class Player():
_placeholder_pic_path = ':ui/img/placeholder_head.jpg' _placeholder_pic_path = ':ui/img/placeholder_head.jpg'
_first_time = True # Debug
def __init__(self, id, rfid, fname, lname, pic_path, stats): def __init__(self, id, rfid, fname, lname, pic_path, stats):
self.id = id self.id = id
self.rfid = rfid self.rfid = rfid
...@@ -76,33 +74,37 @@ class Player(): ...@@ -76,33 +74,37 @@ class Player():
def fromRFID(rfid): def fromRFID(rfid):
db = Database.instance() db = Database.instance()
try: if db.rfid_exists(rfid):
# Retrieve generic informations try:
id, fname, lname, pic = db.select_one(Player.__query_infos, rfid) # Retrieve generic informations
id, fname, lname, pic = db.select_one(Player.__query_infos, rfid)
# Ask for consent # Retrieve stats
if rfid==-2 and Player._first_time: stats = {}
consentDialog = ConsentDialog(getMainWin()) stats['time_played'], stats['goals_scored'], stats['games_played'] = db.select_one(Player.__query_time_goals_games, id, id)
consentDialog.exec() stats['victories'], = db.select_one(Player.__query_victories, id)
if not consentDialog.result()==QDialog.Accepted: for key, val in stats.items():
Player._first_time = False if val==None:
return PlayerGuest stats[key] = 0
# Retrieve stats return Player(id, rfid, fname, lname, pic, stats)
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)
for key, val in stats.items(): except DatabaseError as e:
if val==None: logging.warn('DB Error: {}'.format(e))
stats[key] = 0 return PlayerGuest
return Player(id, rfid, fname, lname, pic, stats) else:
### Retrieve player from API
# Ask for consent
consentDialog = ConsentDialog(getMainWin())
consentDialog.exec()
except DatabaseError as e: if consentDialog.result()==QDialog.Accepted:
logging.warn('DB Error: {}'.format(e)) print('todo')
return PlayerGuest return PlayerGuest
else:
return PlayerGuest
def displayImg(self, container_widget): def displayImg(self, container_widget):
self.pic_container = container_widget self.pic_container = container_widget
...@@ -110,6 +112,7 @@ class Player(): ...@@ -110,6 +112,7 @@ class Player():
if self.pic_path.startswith('http'): if self.pic_path.startswith('http'):
# Download from the internet # Download from the internet
container_widget.setStyleSheet('border-image: url({});'.format(Player._placeholder_pic_path)) container_widget.setStyleSheet('border-image: url({});'.format(Player._placeholder_pic_path))
# TODO DOWNLOAD
else: else:
# Already downloaded and stored locally # Already downloaded and stored locally
container_widget.setStyleSheet('border-image: url({});'.format(self.pic_path)) container_widget.setStyleSheet('border-image: url({});'.format(self.pic_path))
...@@ -121,6 +124,14 @@ class Player(): ...@@ -121,6 +124,14 @@ class Player():
pass pass
# DONT SAVE PIC PATH, IT IS CHANGED FOR THE LOCAL PATH # DONT SAVE PIC PATH, IT IS CHANGED FOR THE LOCAL PATH
def forgetPicture():
self.pic_path = Player._placeholder_pic_path
Database.instance().delete_playerpic(self.id)
def make_private():
self.private = True
Database.instance().make_player_private(self.id)
@property @property
def name(self): def name(self):
return '{} {}'.format(self.fname, self.lname.upper()) return '{} {}'.format(self.fname, self.lname.upper())
......
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
from threading import Thread, Event from threading import Thread, Event
from Babyfut.babyfut import getContent, OnRasp from Babyfut.babyfut import getContent, ON_RASP
from Babyfut.core.settings import Settings from Babyfut.core.settings import Settings
if OnRasp: if ON_RASP:
import picamera import picamera
class Replay(Thread): class Replay(Thread):
...@@ -22,7 +22,7 @@ class Replay(Thread): ...@@ -22,7 +22,7 @@ class Replay(Thread):
self.stop_flag = Event() self.stop_flag = Event()
self.stopped_flag = Event() self.stopped_flag = Event()
if OnRasp: if ON_RASP:
self.cam = picamera.PiCamera() self.cam = picamera.PiCamera()
self.cam.resolution = Settings['picam.resolution'] self.cam.resolution = Settings['picam.resolution']
self.cam.framerate = Settings['picam.fps'] self.cam.framerate = Settings['picam.fps']
...@@ -31,11 +31,11 @@ class Replay(Thread): ...@@ -31,11 +31,11 @@ class Replay(Thread):
self.stream = picamera.PiCameraCircularIO(self.cam, seconds=Settings['replay.duration']) self.stream = picamera.PiCameraCircularIO(self.cam, seconds=Settings['replay.duration'])
def start_recording(self): def start_recording(self):
if OnRasp: if ON_RASP:
self.start_flag.set() self.start_flag.set()
def stop_recording(self): def stop_recording(self):
if OnRasp: if ON_RASP:
self.stop_flag.set() self.stop_flag.set()
self.stopped_flag.wait() self.stopped_flag.wait()
...@@ -78,4 +78,4 @@ class Replay(Thread): ...@@ -78,4 +78,4 @@ class Replay(Thread):
@staticmethod @staticmethod
def isCamAvailable(): def isCamAvailable():
return OnRasp # and other checks (ToDo) return ON_RASP # and other checks (ToDo)
...@@ -29,12 +29,10 @@ class LeaderboardItemWidget(QWidget): ...@@ -29,12 +29,10 @@ class LeaderboardItemWidget(QWidget):
self.ui.lblFName.setText(player.fname) self.ui.lblFName.setText(player.fname)
self.ui.lblLName.setText(player.lname) self.ui.lblLName.setText(player.lname)
self.ui.lblVictories.setText (self.ui.lblVictories.text().replace('####', str(player.stats['victories']))) self.ui.lblVictories.setText (self.ui.lblVictories.text().format(player.stats['victories'] ))
self.ui.lblGamesPlayed.setText (self.ui.lblGamesPlayed.text().replace('####', str(player.stats['games_played']))) self.ui.lblGamesPlayed.setText (self.ui.lblGamesPlayed.text().format(player.stats['games_played'] ))
self.ui.lblGoalsScored.setText (self.ui.lblGoalsScored.text().replace('####', str(player.stats['goals_scored']))) self.ui.lblGoalsScored.setText (self.ui.lblGoalsScored.text().format(player.stats['goals_scored'] ))
self.ui.lblMinutesPlayed.setText(self.ui.lblMinutesPlayed.text().replace('####', str(player.stats['time_played']))) self.ui.lblMinutesPlayed.setText(self.ui.lblMinutesPlayed.text().replace('{}', '{0:.2f}').format(player.stats['time_played']/60))
self.ui.pushButton.clicked.connect(lambda: logging.debug('clicked'))
class DeleteDialog(QDialog): class DeleteDialog(QDialog):
class Actions(Enum): class Actions(Enum):
...@@ -50,7 +48,7 @@ class DeleteDialog(QDialog): ...@@ -50,7 +48,7 @@ class DeleteDialog(QDialog):
self.ui.lblTitle.setText(self.ui.lblTitle.text().format(player.name)) self.ui.lblTitle.setText(self.ui.lblTitle.text().format(player.name))
def check(self, rfid): def check(self, rfid):
return rfid == -self.player.id return rfid == self.player.rfid
def action(self): def action(self):
dict_actions = { dict_actions = {
...@@ -91,6 +89,7 @@ class LeaderboardModule(Module): ...@@ -91,6 +89,7 @@ class LeaderboardModule(Module):
def load(self): def load(self):
logging.debug('Loading LeaderboardModule') logging.debug('Loading LeaderboardModule')
self.selectedSort = 0
self.loadList() self.loadList()
self.setFocus() self.setFocus()
...@@ -109,9 +108,9 @@ class LeaderboardModule(Module): ...@@ -109,9 +108,9 @@ class LeaderboardModule(Module):
if action==DeleteDialog.Actions.DeleteAll: if action==DeleteDialog.Actions.DeleteAll:
Database.instance().delete_player(self.deleteDialog.player.id) Database.instance().delete_player(self.deleteDialog.player.id)
elif action==DeleteDialog.Actions.DeletePicture: elif action==DeleteDialog.Actions.DeletePicture:
logging.error('Unimplemented action: delete picture') self.deleteDialog.player.forgetPicture()
elif action==DeleteDialog.Actions.HideAccount: elif action==DeleteDialog.Actions.HideAccount:
logging.error('Unimplemented action: Hide account') self.deleteDialog.player.make_private()
else: else:
logging.error('Unknown action {}'.format(action)) logging.error('Unknown action {}'.format(action))
......
...@@ -7,16 +7,6 @@ ...@@ -7,16 +7,6 @@
<source>Dialog</source> <source>Dialog</source>
<translation>Supression</translation> <translation>Supression</translation>
</message> </message>
<message>
<location filename="../ui/delete_dialog_ui.py" line="48"/>
<source>Deleting {}&apos;s profile</source>
<translation type="obsolete">Supression du profil de {}</translation>
</message>
<message>
<location filename="../ui/delete_dialog_ui.py" line="49"/>
<source>Pass your badge to validate this...</source>
<translation type="obsolete">Passez votre badge pour valider la supression...</translation>
</message>
<message> <message>
<location filename="../ui/consent_dialog_ui.py" line="39"/> <location filename="../ui/consent_dialog_ui.py" line="39"/>
<source>Consent Approval Needed</source> <source>Consent Approval Needed</source>
...@@ -215,31 +205,6 @@ ...@@ -215,31 +205,6 @@
<source>Surname</source> <source>Surname</source>
<translation>Prénom</translation> <translation>Prénom</translation>
</message> </message>
<message>
<location filename="../ui/options_ui.py" line="229"/>
<source>Fran&#xe7;ais</source>
<translation type="obsolete">Français</translation>
</message>
<message>
<location filename="../ui/playerlist_ui.py" line="97"/>
<source>####&#xa0;Victories</source>
<translation type="obsolete">#### Victoires</translation>
</message>
<message>
<location filename="../ui/playerlist_ui.py" line="98"/>
<source>####&#xa0;Goals Scored</source>
<translation type="obsolete">#### Buts Marqués</translation>
</message>
<message>
<location filename="../ui/playerlist_ui.py" line="99"/>
<source>####&#xa0;Games Played</source>
<translation type="obsolete">#### Parties Jouées</translation>
</message>
<message>
<location filename="../ui/playerlist_ui.py" line="100"/>
<source>#### Minutes Played</source>
<translation>#### Minutes Jouées</translation>
</message>
<message> <message>
<location filename="../ui/privacy_ui.py" line="53"/> <location filename="../ui/privacy_ui.py" line="53"/>
<source>Privacy</source> <source>Privacy</source>
...@@ -260,24 +225,38 @@ ...@@ -260,24 +225,38 @@
<source>{} Goals Scored</source> <source>{} Goals Scored</source>
<translation>{} Buts Marqués</translation> <translation>{} Buts Marqués</translation>
</message> </message>
<message encoding="UTF-8"> <message>
<location filename="../ui/options_ui.py" line="229"/>
<source>Français</source>
<translation type="unfinished"></translation>
</message>
<message encoding="UTF-8">
<location filename="../ui/playerlist_ui.py" line="97"/> <location filename="../ui/playerlist_ui.py" line="97"/>
<source>#### Victories</source> <source>{} Victories</source>
<translation type="unfinished"></translation> <comment>Form</comment>
<translation>{} Victoires</translation>
</message> </message>
<message encoding="UTF-8"> <message>
<location filename="../ui/playerlist_ui.py" line="98"/> <location filename="../ui/playerlist_ui.py" line="98"/>
<source>#### Goals Scored</source> <source>{} Goals Scored</source>
<translation type="unfinished"></translation> <comment>Form</comment>
<translation>{} Buts Marqués</translation>
</message> </message>
<message encoding="UTF-8"> <message>
<location filename="../ui/playerlist_ui.py" line="99"/> <location filename="../ui/playerlist_ui.py" line="99"/>
<source>#### Games Played</source> <source>{} Games Played</source>
<comment>Form</comment>
<translation>{} Parties Jouées</translation>
</message>
<message>
<location filename="../ui/playerlist_ui.py" line="100"/>
<source>{} Minutes Played</source>
<comment>Form</comment>
<translation>{} Minutes Jouées</translation>
</message>
<message>
<location filename="../ui/options_ui.py" line="229"/>
<source>Fran&#xe7;ais</source>
<translation type="obsolete">Français</translation>
</message>
<message encoding="UTF-8">
<location filename="../ui/options_ui.py" line="229"/>
<source>Français</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
import os import os
from os.path import join, dirname, abspath from os.path import join, dirname, abspath
import logging import logging
OnRasp = os.uname()[1] == 'raspberrypi'
from PyQt5 import QtWidgets from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QGraphicsBlurEffect, QApplication from PyQt5.QtWidgets import QGraphicsBlurEffect, QApplication
...@@ -27,6 +26,7 @@ class MainWin(QtWidgets.QMainWindow): ...@@ -27,6 +26,7 @@ class MainWin(QtWidgets.QMainWindow):
self.ui.setupUi(self) self.ui.setupUi(self)
self.lang = MainWin.DEFAULT_LANG self.lang = MainWin.DEFAULT_LANG
self._retranslateUI() self._retranslateUI()
self.setWindowTitle('Babyfut')
#Background blur #Background blur
bgBlur = QGraphicsBlurEffect() bgBlur = QGraphicsBlurEffect()
......
...@@ -129,7 +129,7 @@ ...@@ -129,7 +129,7 @@
<item> <item>
<widget class="QLabel" name="lblVictories"> <widget class="QLabel" name="lblVictories">
<property name="text"> <property name="text">
<string>#### Victories</string> <string comment="Form">{} Victories</string>
</property> </property>
</widget> </widget>
</item> </item>
...@@ -149,7 +149,7 @@ ...@@ -149,7 +149,7 @@
<item> <item>
<widget class="QLabel" name="lblGoalsScored"> <widget class="QLabel" name="lblGoalsScored">
<property name="text"> <property name="text">
<string>#### Goals Scored</string> <string comment="Form">{} Goals Scored</string>
</property> </property>
</widget> </widget>
</item> </item>
...@@ -169,7 +169,7 @@ ...@@ -169,7 +169,7 @@
<item> <item>
<widget class="QLabel" name="lblGamesPlayed"> <widget class="QLabel" name="lblGamesPlayed">
<property name="text"> <property name="text">
<string>#### Games Played</string> <string comment="Form">{} Games Played</string>
</property> </property>
</widget> </widget>
</item> </item>
...@@ -189,7 +189,7 @@ ...@@ -189,7 +189,7 @@
<item> <item>
<widget class="QLabel" name="lblMinutesPlayed"> <widget class="QLabel" name="lblMinutesPlayed">
<property name="text"> <property name="text">
<string>#### Minutes Played</string> <string comment="Form">{} Minutes Played</string>
</property> </property>
</widget> </widget>
</item> </item>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment