diff --git a/.gitignore b/.gitignore index 9214229..dd7261c 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ People.db +.idea +__pycache__ *.pyc +*.swp diff --git a/HighScore.py b/HighScore.py index 5d45e12..67f411a 100755 --- a/HighScore.py +++ b/HighScore.py @@ -1,43 +1,42 @@ -#!/usr/bin/python +#!/usr/bin/python3 + # -*- coding: utf-8 -*- +""" +Simple script to display the current High score and also who is currently logged in. +""" -import sqlite3 as lite +import itertools +from peewee import * +from models import Person import requests import os import time +db = SqliteDatabase('People.db', **{}) + while True: os.system('clear') - con = lite.connect('People.db') - with con: - cur = con.cursor() - - print("------------ Highscore -----------") - - cur.execute("SELECT * FROM People ORDER BY totalTime DESC") - rows = cur.fetchall() - - for i in range(0, len(rows)): - print(str(i+1) + ": " + str(rows[i][2]).ljust(10) + - " score: " + str(rows[i][4])) - - print("------------- People online ------") - - cur.execute("SELECT * FROM People WHERE isHere = 1") - rows = cur.fetchall() - - # display som people - for row in rows: - print(str(row[2]).ljust(10)) - - # prata med dorropnare och be dem tana - try: - if len(rows)>0: - requests.get('http://192.168.42.10:5000/light/on', timeout=0.1) - else: - requests.get('http://192.168.42.10:5000/light/off', timeout=0.1) - except (requests.exceptions.Timeout, requests.ConnectionError): - pass + print('{:-^39}'.format('High score')) + + high_score = Person.select().order_by(Person.total_time.desc()) + + for person, i in zip(high_score, itertools.count(start=1)): + print('{:>2}: {:<14} score: {:>13f}'.format(i, person.nick, person.total_time)) + + print('{:-^39}'.format('People online')) + + online_persons = Person.select().where(Person.is_here == True) + for person in online_persons: + print(person.nick) + + # If there are people present, turn on the lights and vice versa. + try: + if len(online_persons) > 0: + requests.get('http://192.168.42.10:5000/light/on', timeout=0.1) + else: + requests.get('http://192.168.42.10:5000/light/off', timeout=0.1) + except (requests.exceptions.Timeout, requests.ConnectionError): + pass time.sleep(3) diff --git a/blipper.py b/blipper.py index 82fa7ac..9c4b22e 100755 --- a/blipper.py +++ b/blipper.py @@ -1,72 +1,91 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: utf-8 -*- """Simple script for registering members coming and going. """ -import sqlite3 as lite +from peewee import * +from models import Person import time import requests import hasher import getpass -while True: - while True: + +db = SqliteDatabase('People.db', **{}) + + +def login_logout(person: Person): + if person.is_here: + person.is_here = False + time_spent = time.time() - person.last_login + person.total_time = person.total_time + time_spent + + print('{:-^47}'.format('')) + print('Goodbye {} your highscore is: {:f}'.format(person.nick, person.total_time)) + print('{:-^47}'.format('')) + + person.save() + try: - temp = getpass.getpass("Blip me! ") - rfId = hasher.encode(temp) - break - except ValueError: - print("Blip not recognised") - print("") - - con = lite.connect('People.db') - with con: - cur = con.cursor() - cur.execute("SELECT * FROM People WHERE blipId = ?", (rfId,)) - data = cur.fetchone() - - if data is None: # there is no user with this ID tag - print("-----------------------------------------------") - print('There is no rfidtag named ', rfId, ' creating instance!') - - nick_temp = input("input your nick: ") - temp = cur.lastrowid - if temp is None: - temp_id = 1 - else: - temp_id = temp + 1 - - cur.execute("INSERT INTO People VALUES (?,?,?,?,?,?);", - (temp_id, rfId, nick_temp, 1, 0, time.time())) - requests.put('http://127.0.0.1:5001/', json = {'who': nick_temp, 'what': "login"}) + requests.put('http://127.0.0.1:5001/', json={'who': person.nick, 'what': "logout"}, timeout=0.001) + requests.get('http://192.168.42.12:5000/', timeout=0.001) + except TimeoutError: + pass + + else: + person.is_here = True + person.last_login = time.time() + + print('{:-^47}'.format('')) + print('Welcome {}'.format(person.nick)) + print('{:-^47}'.format('')) + + person.save() + + requests.put('http://127.0.0.1:5001/', json={'who': person.nick, 'what': "login"}) + try: + requests.get('http://192.168.42.12:5000/', timeout=0.001) + except TimeoutError: + pass + + +def create_person(rf_id: int): + print('{:-^47}'.format('')) + print('There is no rfidtag named {} creating instance!'.format(rf_id)) + + nick = input('Input your nick: ') + new_member = Person(nick=nick) + new_member.last_login = time.time() + new_member.blip_id = rf_id + new_member.is_here = True + new_member.total_time = 0 + + new_member.save() + + requests.put('http://127.0.0.1:5001/', json={'who': nick, 'what': "login"}) + try: + requests.get('http://192.168.42.12:5000/', timeout=0.001) + except TimeoutError: + pass + + print('you now exist and are logged in! don\'t forget to logout!') + print('{:-^47}'.format('')) + +if __name__ == '__main__': + + db.connect() + + while True: + while True: try: - requests.get('http://192.168.42.12:5000/',timeout=0.001) - except: - print(" ") - print('you now exist and are logged in! dont forget to logout!') - print("-----------------------------------------------") - else: # there is user with this ID tag - if data[3] is 1: # is logged in => log hen out - time_spent = time.time() - data[5] - new_total_time = time_spent + data[4] - cur.execute("UPDATE People SET totalTime=?, isHere=? WHERE blipId=?", - (new_total_time, 0, rfId)) - requests.put('http://127.0.0.1:5001/', json = {'who': str(data[2]), 'what': "logout"}) - try: - requests.get('http://192.168.42.12:5000/',timeout=0.001) - except: - print(" ") - print("-----------------------------------------------") - print("Goodbye " + str(data[2]) + " your highscore is: " + - str(new_total_time)) - print("-----------------------------------------------") - - else: # is not logged in => log hen in - cur.execute("UPDATE People SET lastLogin=?, isHere=? WHERE blipId=?", - (time.time(), 1, rfId)) - requests.put('http://127.0.0.1:5001/', json = {'who': str(data[2]), 'what': "login"}) - try: - requests.get('http://192.168.42.12:5000/',timeout=0.001) - except: - print(" ") - print("-----------------------------------------------") - print("Welcome " + str(data[2])) - print("-----------------------------------------------") + temp = getpass.getpass("Blip me! ") + rfId = hasher.encode(temp) + break + except ValueError: + print("Blip not recognised") + + print('') + + try: + user = Person.get(Person.blip_id == rfId) + login_logout(user) + except Person.DoesNotExist: + create_person(rfId) diff --git a/convert_db.py b/convert_db.py index 41f4e1b..335f694 100644 --- a/convert_db.py +++ b/convert_db.py @@ -1,26 +1,101 @@ import hasher import sqlite3 as lite +import time +import shutil -con = lite.connect('People.db') -con.row_factory = lite.Row - -salt = b"AhBaik4auv3Seihu" - -with con: - - cur = con.cursor() - - cur.execute("SELECT * FROM People;") - - rows = cur.fetchall() - - hashed = [] - - for row in rows: - #hashedId = hashlib.sha512(salt+str.encode(str(row["blipId"]))).hexdigest() - hashedId = hasher.encode(str(row["blipId"])) - hashedRow = [hashedId, row["blipId"]] - hashed.append(hashedRow) - - cur.executemany("UPDATE People SET blipId =? WHERE blipId =?", hashed) - +from models import Person, LegacyPerson, DbVersion +from peewee import * + +db = SqliteDatabase('People.db', **{}) + + +def convert_from_legacy(): + + # check if Colcum Id exist ( and not id) and also that blippId is not sha512 (should be varchar) + # Create Model update 1 + # move data from People to Updated table, while moving update the ID to a functioning one. + # rename People + # rename Updated table to People + + with lite.connect('People.db') as con: + + con.row_factory = lite.Row + cur = con.cursor() + cur.execute('PRAGMA TABLE_INFO({})'.format('People')) + rows = cur.fetchall() + + # See if we can find old table structure. + old_blip = False + old_id = False + + for row in rows: + if row[1] == 'Id' and row[2] == 'INT': + old_id = True + print(row[1], row[2]) + + if row[1] == 'blipId' and row[2] == 'INT': + old_blip = True + print(row[1], row[2]) + + if old_blip and old_id: + # rename table + cur.execute('Alter table People rename to People_legacy') + + # Transfer data with peewee + db.connect() + db.create_tables([Person]) + for user in LegacyPerson.select(): + hash_blip = hasher.encode(str(user.blip_id)) + Person.create(nick=user.nick, blip_id=hash_blip, is_here=user.is_here, + last_login=user.last_login, total_time=user.total_time) + db.close() + + # Check and remove old table + with lite.connect('People.db') as con: + + con.row_factory = lite.Row + cur = con.cursor() + + cur.execute('select * from People') + rows = cur.fetchall() + + people_len = len(rows) + + cur.execute('SELECT * FROM People_legacy') + rows = cur.fetchall() + + legacy_len = len(rows) + + if people_len == legacy_len: + cur.execute('DROP TABLE People_legacy') + + +def check_db_version_and_apply_fixes(): + + + # Check db version + db.connect() + try: + db.create_tables([DbVersion]) + # if there isnt any DbVersion then this is a legacy db + db_version = 0 + except OperationalError: + # Ok at least a managed version of the DB was installed. + + + + if db__version == 0: + backup_db() + convert_from_legacy() + + # Update db version + +def backup_db(): + time_str = str(time.time()) + db_backup_file = 'People_' + time_str + '.db' + + shutil.copy('People.db', db_backup_file) + + +if __name__ == '__main__': + check_db_version_and_apply_fixes() \ No newline at end of file diff --git a/hasher.py b/hasher.py index 8f41771..1e66f5a 100644 --- a/hasher.py +++ b/hasher.py @@ -1,6 +1,7 @@ import hashlib -salt = "AhBaik4auv3Seihu" +salt = 'AhBaik4auv3Seihu' -def encode(clearString): - return hashlib.sha512(str.encode(salt + clearString)).hexdigest() + +def encode(clear_string): + return hashlib.sha512(str.encode(salt + clear_string)).hexdigest() diff --git a/logout_all.py b/logout_all.py index 5ba16ed..5b2370b 100755 --- a/logout_all.py +++ b/logout_all.py @@ -1,5 +1,10 @@ import sqlite3 as lite -con = lite.connect('People.db') +import os + +path, _ = os.path.split(os.path.realpath(__file__)) +db_path = os.path.join(path, 'People.db') + +con = lite.connect(db_path) with con: cur = con.cursor() cur.execute("UPDATE People SET isHere = 0") diff --git a/models.py b/models.py new file mode 100644 index 0000000..e72c94e --- /dev/null +++ b/models.py @@ -0,0 +1,38 @@ +from peewee import * + +db = SqliteDatabase('People.db', **{}) + + +class Person(Model): + nick = TextField(db_column='Nick', null=False) + blip_id = FixedCharField(db_column='blipId', null=False, max_length=128) + is_here = BooleanField(db_column='isHere', null=False, default=False) + last_login = FloatField(db_column='lastLogin', null=False, default=0.0) # FLOAT + total_time = FloatField(db_column='totalTime', null=True, default=0.0) # FLOAT + + class Meta: + database = db + db_table = 'People' + + +class DbVersion(Model): + version = IntegerField(db_column='version', null=False) + date_updated = DateTimeField() + date_released = DateTimeField(null=False) + + class Meta: + database = db + db_table = 'DbVersion' + + +class LegacyPerson(Model): + Id = IntegerField(db_column='Id', null=False) + nick = TextField(db_column='Nick', null=False) + blip_id = IntegerField(db_column='blipId', null=False) + is_here = BooleanField(db_column='isHere', null=False, default=False) + last_login = FloatField(db_column='lastLogin', null=False, default=0.0) # FLOAT + total_time = FloatField(db_column='totalTime', null=True, default=0.0) # FLOAT + + class Meta: + database = db + db_table = 'People_legacy' diff --git a/setup_db.py b/setup_db.py index ad48183..9f080f2 100755 --- a/setup_db.py +++ b/setup_db.py @@ -1,25 +1,45 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -"""Dev script to setup a test database. """ +""" Dev script to setup a test database. """ -import sqlite3 as lite import time +import argparse +import os import hasher -con = lite.connect('People.db') +from models import Person +from peewee import * -with con: +db = SqliteDatabase('People.db', **{}) +db_file = 'People.db' - cur = con.cursor() +if __name__ == '__main__': - cur.execute("DROP TABLE IF EXISTS People") - cur.execute( - "CREATE TABLE People(Id INT, blipId INT, Nick TEXT, isHere INT," + - "totalTime FLOAT, lastLogin FLOAT)" - ) + parser = argparse.ArgumentParser(prog='setup_db', + description='Setup db for the time system') - temp_id = 1 - rfId = hasher.encode("2016050010") - nick_temp = 'Dalsmo' - cur.execute("INSERT INTO People VALUES (?,?,?,?,?,?);", - (temp_id, rfId, nick_temp, 1, 0, time.time())) + parser.add_argument('--remove', help='Remove the old db first.', + action="store_true") + parser.add_argument('action', choices=('dev', 'production'), + help='What type of db to setup.') + + args = parser.parse_args() + + if os.path.isfile(db_file): + if args.remove: + os.remove(db_file) + else: # Backup db + os.rename(db_file, db_file + ".bak_" + time.strftime("%Y%m%d-%H:%M")) + + db.connect() + + db.create_tables([Person]) + + if args.action == 'dev': + rf_id = hasher.encode('1234') + tester = Person(nick='tester', blip_id=rf_id, is_here=False) + tester.last_login = time.time() + tester.total_time = 0 + tester.save() + + db.close()