Commit a3989a83 authored by Antoine Lima's avatar Antoine Lima

Player deletetion from leaderboards

parent 94caf50c
......@@ -11,6 +11,7 @@ pyuic5 --import-from=ui ui/authleague.ui -o ui/authleague_ui.py
pyuic5 --import-from=ui ui/leaderboard.ui -o ui/leaderboard_ui.py
# Custom widgets
pyuic5 --import-from=ui ui/playerlist.ui -o ui/playerlist_ui.py
pyuic5 --import-from=ui ui/playerlist.ui -o ui/playerlist_ui.py
pyuic5 --import-from=ui ui/delete_dialog.ui -o ui/delete_dialog_ui.py
pyrcc5 -root /ui ui/assets.qrc -o ui/assets_rc.py
......@@ -9,6 +9,8 @@ Created on Wed Apr 18 18:34:40 2018
import logging
import sqlite3
from settings import Settings
class DatabaseError(Exception):
pass
......@@ -50,15 +52,23 @@ class Database():
if len(players)<2:
players.append(None)
logging.debug('DB Inserting {} to table Teams'.format((goals, players[0], players[1],)))
self._cursor.execute('INSERT INTO Teams (nGoals, player1, player2) VALUES (?, ?, ?)', (goals, players[0], players[1],))
self._connection.commit()
return self._cursor.execute('SELECT seq FROM sqlite_sequence WHERE name="Teams"').fetchone()[0]
def insert_match(self, start_time, duration, team1, team2):
logging.debug('DB Inserting {} to table Matchs'.format((start_time, duration, team1, team2,)))
self._cursor.execute('INSERT INTO Matchs (timestamp, duration, winningTeam, losingTeam) VALUES (?, ?, ?, ?)', (start_time, duration, team1, team2,))
self._connection.commit()
def select_all_rfid(self, debug=False):
if Settings['app.mode']=='prod':
return self._cursor.execute('SELECT rfid FROM Players WHERE rfid>0').fetchall()
else:
return self._cursor.execute('SELECT rfid FROM Players WHERE rfid<-1').fetchall()
def delete_player(self, playerID):
self._cursor.execute('DELETE FROM Players WHERE id==?', (playerID,))
self._connection.commit()
def close(self):
self._connection.close()
......@@ -21,8 +21,6 @@ from PyQt5.QtCore import QTime, Qt
from ui.main_ui import Ui_MainWindow
from modules import *
from player import Side
from input import GPIOThread
from database import Database
class MainWin(QtWidgets.QMainWindow):
def __init__(self, parent=None):
......@@ -98,6 +96,8 @@ class MainWin(QtWidgets.QMainWindow):
if __name__=='__main__':
from settings import Settings
from input import GPIOThread
from database import Database
from replay import Replay as ReplayThread
try:
......
......@@ -12,8 +12,6 @@ from PyQt5 import QtWidgets
from PyQt5.QtCore import QTime, QTimer, Qt
from PyQt5.QtWidgets import QTableWidgetItem, QComboBox, QApplication
from modules import *
class Module(QtWidgets.QWidget):
def __init__(self, parent, widget):
# UI Setup
......
......@@ -9,18 +9,21 @@ Created on Wed Apr 18 18:34:40 2018
import logging
from operator import attrgetter
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QWidget, QDialog, QListWidgetItem
from PyQt5.QtCore import QTime, Qt, QSize, QItemSelectionModel
from module import Module
import modules
from player import PlayerGuest, Player
from ui.leaderboard_ui import Ui_Form as LeaderboardWidget
from ui.playerlist_ui import Ui_Form as PlayerListWidget
from module import Module
from player import Player, Side
from database import Database
from ui.leaderboard_ui import Ui_Form as LeaderboardWidget
from ui.playerlist_ui import Ui_Form as PlayerListWidget
from ui.delete_dialog_ui import Ui_Dialog as PlayerDeleteDialog
class LeaderboardItemWidget(QtWidgets.QWidget):
class LeaderboardItemWidget(QWidget):
def __init__(self, parent, player):
QtWidgets.QWidget.__init__(self, parent)
QWidget.__init__(self, parent)
self.ui = PlayerListWidget()
self.ui.setupUi(self)
......@@ -35,6 +38,23 @@ class LeaderboardItemWidget(QtWidgets.QWidget):
self.ui.pushButton.clicked.connect(lambda: logging.debug('clicked'))
class DeleteDialog(QDialog):
def __init__(self, parent, player):
print('DeleteDialog {}'.format(player.name))
QDialog.__init__(self, parent)
self.ui = PlayerDeleteDialog()
self.ui.setupUi(self)
self.player = player
self.ui.lblTitle.setText(self.ui.lblTitle.text().format(player.name))
def check(self, rfid):
return rfid == -self.player.id
# Debug
def keyPressEvent(self, e):
if e.key() == Qt.Key_Return:
self.parent().send(modules.LeaderboardModule, rfid=self.player.rfid, source=Side.Right)
class LeaderboardModule(Module):
def __init__(self, parent):
super().__init__(parent, LeaderboardWidget())
......@@ -51,6 +71,7 @@ class LeaderboardModule(Module):
self.sortMethodAttr = ['lname', 'stats_property.victories', 'stats_property.goals_scored', 'stats_property.games_played', 'stats_property.time_played']
self.sortMethodRB[self.selectedSort].setChecked(True)
self.deleteDialog = None
def load(self):
logging.debug('Loading LeaderboardModule')
......@@ -63,6 +84,18 @@ class LeaderboardModule(Module):
def other(self, **kwargs):
logging.debug('Other LeaderboardModule')
for key, val in kwargs.items():
if key=='rfid' and self.deleteDialog and self.deleteDialog.check(val):
Database.instance().delete_player(self.deleteDialog.player.id)
# Reset the dialog and the player list
self.deleteDialog.close()
del self.deleteDialog
self.deleteDialog = None
self.players = []
self.ui.listWidget.clear()
self.loadList()
def changeSort(self, rbSort):
self.selectedSort = self.sortMethodRB.index(rbSort)
......@@ -72,12 +105,12 @@ class LeaderboardModule(Module):
if self.players:
self.ui.listWidget.clear()
else:
self.players = [Player.fromRFID(id) for id in range(-2 , -7, -1)]
self.players = Player.allPlayers()
self.players.sort(key=attrgetter(self.sortMethodAttr[self.selectedSort]), reverse=True)
for player in self.players:
item = QtWidgets.QListWidgetItem()
item = QListWidgetItem()
playerWidget = LeaderboardItemWidget(self.ui.listWidget, player)
item.setSizeHint(playerWidget.size())
self.ui.listWidget.addItem(item)
......@@ -107,6 +140,10 @@ class LeaderboardModule(Module):
elif e.key() == Qt.Key_Right:
newSort = curSort+1 if curSort!=len(self.sortMethodRB)-1 else 0
self.sortMethodRB[newSort].animateClick()
elif e.key() == Qt.Key_Delete:
self.deleteDialog = DeleteDialog(self, self.players[curRow])
self.deleteDialog.open()
def handleExit(self):
self.switchModule(modules.MenuModule)
......@@ -10,7 +10,6 @@ import logging
import sqlite3
from enum import Enum
from database import Database, DatabaseError
class Side(Enum):
'''
......@@ -24,6 +23,8 @@ class Side(Enum):
def opposite(self):
return Side.Right if self==Side.Left else Side.Left
from database import Database, DatabaseError
class Player():
__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==?)'
......@@ -31,8 +32,9 @@ class Player():
_placeholder_pic_path = ':ui/img/placeholder_head.jpg'
def __init__(self, id, fname, lname, pic_path, stats):
def __init__(self, id, rfid, fname, lname, pic_path, stats):
self.id = id
self.rfid = rfid
self.fname = fname
self.lname = lname
self.pic_path = pic_path if pic_path else Player._placeholder_pic_path # Default pic if None
......@@ -51,7 +53,11 @@ class Player():
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)
return Player(id, fname, lname, pic, stats)
for key, val in stats.items():
if val==None:
stats[key] = 0
return Player(id, rfid, fname, lname, pic, stats)
except DatabaseError as e:
logging.warn('DB Error: {}'.format(e))
......@@ -71,6 +77,11 @@ class Player():
@property
def stats_property(self):
'''
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
'''
class Stat:
def __init__(self, stats):
self.victories = stats['victories']
......@@ -79,6 +90,10 @@ class Player():
self.games_played = stats['games_played']
return Stat(self.stats)
@staticmethod
def allPlayers():
return [Player.fromRFID(rfid) for rfid, in Database.instance().select_all_rfid()]
PlayerGuest = Player.fromRFID(-1)
PlayerEmpty = Player(-1, '', '', Player._placeholder_pic_path, {'time_played':'', 'goals_scored':'', 'games_played':'', 'victories': ''})
PlayerEmpty = Player(-1, -42, '', '', Player._placeholder_pic_path, {'time_played':'', 'goals_scored':'', 'games_played':'', 'victories': ''})
......@@ -7,7 +7,6 @@ Created on Wed Apr 18 18:34:40 2018
"""
import json
import main
class MyEncoder(json.JSONEncoder):
def default(self, obj):
......@@ -120,4 +119,5 @@ class SettingsHolder(object):
self.settingsPath = settingsPath
import main
Settings = SettingsHolder(main.MainWin.getContent('settings.json'))
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>720</width>
<height>405</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lblTitle">
<property name="font">
<font>
<pointsize>25</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Deleting {}'s profile</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lblMsg">
<property name="font">
<font>
<pointsize>20</pointsize>
</font>
</property>
<property name="text">
<string>Pass your badge to validate this...</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
......@@ -299,7 +299,7 @@ QRadioButton::indicator {
<bool>true</bool>
</property>
<property name="title">
<string>Number of players per side</string>
<string>League - Number of players per side</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
......
......@@ -68,7 +68,7 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="lblFName">
<widget class="QLabel" name="lblLName">
<property name="minimumSize">
<size>
<width>200</width>
......@@ -94,7 +94,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="lblLName">
<widget class="QLabel" name="lblFName">
<property name="maximumSize">
<size>
<width>200</width>
......
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