initial build
This commit is contained in:
parent
ef8a139e71
commit
d6467b2a8f
162
.gitignore
vendored
Normal file
162
.gitignore
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
database.db
|
16
.vscode/launch.json
vendored
Normal file
16
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python: Current Project",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "main.py",
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": true
|
||||
}
|
||||
]
|
||||
}
|
27
main.py
Normal file
27
main.py
Normal file
@ -0,0 +1,27 @@
|
||||
from models.utils import DatabaseUtils
|
||||
from ui.selection_menu import SelectionMenu
|
||||
from ui.input_menu import InputMenu
|
||||
from services.encryption import Encryption
|
||||
from models.database import Database
|
||||
|
||||
def main():
|
||||
# main_menu = SelectionMenu("Main Menu").add_option("Login", damn).add_option("Exit", damn).display()
|
||||
# action = main_menu.input_option()
|
||||
# action()
|
||||
|
||||
# main_form = InputMenu("User Information")
|
||||
# main_form.add_option("USERNAME", "STR", "Username", 1, 254)
|
||||
# main_form.add_option("PASSWORD", "STR", "Password", 1, 254)
|
||||
# main_form.add_option("AGE", "INT", "Age", 5, 100)
|
||||
|
||||
# main_form.do_input()
|
||||
|
||||
# print(main_form.get_value("USERNAME"))
|
||||
Database.init()
|
||||
DatabaseUtils.init_city_data()
|
||||
|
||||
|
||||
def damn():
|
||||
print("dsdd")
|
||||
|
||||
main()
|
0
models/__init__.py
Normal file
0
models/__init__.py
Normal file
58
models/city.py
Normal file
58
models/city.py
Normal file
@ -0,0 +1,58 @@
|
||||
import sqlite3
|
||||
|
||||
class City:
|
||||
def __init__(self, connection : sqlite3.Connection, id, name):
|
||||
self.connection = connection
|
||||
self.id = id
|
||||
self.name = name
|
||||
|
||||
def load_by_id(self):
|
||||
cur = self.connection.cursor()
|
||||
row = cur.execute("SELECT * FROM cities WHERE id = ?", (self.id,)).fetchone()
|
||||
|
||||
if row == None:
|
||||
return False
|
||||
|
||||
self._set_row_values(row)
|
||||
|
||||
cur.close()
|
||||
return True
|
||||
|
||||
def load_by_name(self):
|
||||
cur = self.connection.cursor()
|
||||
row = cur.execute("SELECT * FROM cities WHERE name = ?", (self.name,)).fetchone()
|
||||
|
||||
if row == None:
|
||||
return False
|
||||
|
||||
self._set_row_values(row)
|
||||
|
||||
cur.close()
|
||||
return True
|
||||
|
||||
def save(self):
|
||||
cur = self.connection.cursor()
|
||||
cur.execute("""
|
||||
INSERT INTO cities
|
||||
(id, name) VALUES (?, ?)
|
||||
""", (self.id, self.name))
|
||||
|
||||
self.connection.commit()
|
||||
cur.close()
|
||||
return True
|
||||
|
||||
def update(self):
|
||||
cur = self.connection.cursor()
|
||||
cur.execute("""
|
||||
UPDATE cities SET
|
||||
name = ?,
|
||||
WHERE id = ?
|
||||
""", (self.name, self.id))
|
||||
|
||||
self.connection.commit()
|
||||
cur.close()
|
||||
return True
|
||||
|
||||
def _set_row_values(self, row):
|
||||
self.id = row[0]
|
||||
self.name = row[1]
|
63
models/database.py
Normal file
63
models/database.py
Normal file
@ -0,0 +1,63 @@
|
||||
from multiprocessing import connection
|
||||
import sqlite3
|
||||
|
||||
from models.city import City
|
||||
|
||||
class Database:
|
||||
connection: sqlite3.Connection = None
|
||||
|
||||
@staticmethod
|
||||
def init():
|
||||
# Open connection with database
|
||||
con = sqlite3.connect("./database.db")
|
||||
Database.connection = con
|
||||
|
||||
Database._init_log_table()
|
||||
Database._init_user_table()
|
||||
Database._init_city_table()
|
||||
|
||||
@staticmethod
|
||||
def _init_log_table():
|
||||
cursor = Database.connection.cursor()
|
||||
q = cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS logs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT,
|
||||
date TEXT,
|
||||
time TEXT,
|
||||
description TEXT,
|
||||
additional_information TEXT,
|
||||
suspicious BOOL
|
||||
)
|
||||
""")
|
||||
cursor.close()
|
||||
|
||||
@staticmethod
|
||||
def _init_user_table():
|
||||
cursor = Database.connection.cursor()
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
firstname TEXT,
|
||||
lastname TEXT,
|
||||
address TEXT,
|
||||
zipcode TEXT,
|
||||
city_id INTEGER,
|
||||
email TEXT,
|
||||
phone TEXT,
|
||||
password TEXT,
|
||||
role TEXT
|
||||
)
|
||||
""")
|
||||
cursor.close()
|
||||
|
||||
@staticmethod
|
||||
def _init_city_table():
|
||||
cursor = Database.connection.cursor()
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS cities (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT
|
||||
)
|
||||
""")
|
||||
cursor.close()
|
61
models/log.py
Normal file
61
models/log.py
Normal file
@ -0,0 +1,61 @@
|
||||
import sqlite3
|
||||
|
||||
|
||||
class Log:
|
||||
def __init__(self, connection : sqlite3.Connection, id = None, username = None, date = None, time = None, description = None, additional_information = None, suspicious = None):
|
||||
self.connection = connection
|
||||
self.id = id
|
||||
self.username = username
|
||||
self.date = date
|
||||
self.time = time
|
||||
self.description = description
|
||||
self.additional_information = additional_information
|
||||
self.suspicious = suspicious
|
||||
|
||||
def load_by_id(self):
|
||||
cur = self.connection.cursor()
|
||||
row = cur.execute("SELECT * FROM logs WHERE id = ?", (self.id,)).fetchone()
|
||||
|
||||
if row == None:
|
||||
return False
|
||||
|
||||
self._set_row_values(row)
|
||||
|
||||
cur.close()
|
||||
return True
|
||||
|
||||
def save(self):
|
||||
cur = self.connection.cursor()
|
||||
cur.execute("""
|
||||
INSERT INTO logs
|
||||
(id, username, date, time, description, additional_information, suspicious) VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
""", (self.id, self.username, self.date, self.time, self.description, self.additional_information, self.suspicious))
|
||||
|
||||
self.connection.commit()
|
||||
cur.close()
|
||||
return True
|
||||
|
||||
def update(self):
|
||||
cur = self.connection.cursor()
|
||||
cur.execute("""
|
||||
UPDATE logs SET
|
||||
username = ?,
|
||||
date = ?,
|
||||
description = ?,
|
||||
additional_information = ?,
|
||||
suspicious = ?,
|
||||
WHERE id = ?
|
||||
""", (self.firstname, self.lastname, self.zipcode, self.city_id, self.email, self.phone, self.password, self.role, self.id))
|
||||
|
||||
self.connection.commit()
|
||||
cur.close()
|
||||
return True
|
||||
|
||||
def _set_row_values(self, row):
|
||||
self.id = row[0]
|
||||
self.username = row[1]
|
||||
self.date = row[2]
|
||||
self.time = row[3]
|
||||
self.description = row[4]
|
||||
self.additional_information = row[5]
|
||||
self.suspicious = row[6]
|
72
models/user.py
Normal file
72
models/user.py
Normal file
@ -0,0 +1,72 @@
|
||||
import sqlite3
|
||||
from models.database import Database
|
||||
|
||||
class User:
|
||||
def __init__(self, connection : sqlite3.Connection, id = None, firstname = None, lastname = None, address = None, zipcode = None, city_id = None, email = None, phone = None, password = None, role = None):
|
||||
self.connection = connection
|
||||
self.id = id
|
||||
self.firstname = firstname
|
||||
self.lastname = lastname
|
||||
self.address = address
|
||||
self.zipcode = zipcode
|
||||
self.city_id = city_id
|
||||
self.email = email
|
||||
self.phone = phone
|
||||
self.password = password
|
||||
self.role = role
|
||||
|
||||
def load_by_id(self):
|
||||
cur = Database.connection.cursor()
|
||||
row = cur.execute("SELECT * FROM users WHERE id = ?", (self.id,)).fetchone()
|
||||
|
||||
if row == None:
|
||||
return False
|
||||
|
||||
self._set_row_values(row)
|
||||
|
||||
cur.close()
|
||||
return True
|
||||
|
||||
def save(self):
|
||||
cur = Database.connection.cursor()
|
||||
cur.execute("""
|
||||
INSERT INTO users
|
||||
(id, fistname, lastname, address, zipcode, city_id, email, phone, password, role) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""", (self.id, self.firstname, self.lastname, self.zipcode, self.city_id, self.email, self.phone, self.password, self.role))
|
||||
|
||||
Database.connection.commit()
|
||||
cur.close()
|
||||
return True
|
||||
|
||||
def update(self):
|
||||
cur = Database.connection.cursor()
|
||||
cur.execute("""
|
||||
UPDATE users SET
|
||||
fistname = ?,
|
||||
lastname = ?,
|
||||
address = ?,
|
||||
zipcode = ?,
|
||||
city_id = ?,
|
||||
email = ?,
|
||||
phone = ?,
|
||||
password = ?,
|
||||
role = ?,
|
||||
WHERE id = ?
|
||||
""", (self.firstname, self.lastname, self.zipcode, self.city_id, self.email, self.phone, self.password, self.role, self.id))
|
||||
|
||||
Database.connection.commit()
|
||||
cur.close()
|
||||
return True
|
||||
|
||||
def _set_row_values(self, row):
|
||||
self.id = row[0]
|
||||
self.firstname = row[1]
|
||||
self.lastname = row[2]
|
||||
self.address = row[3]
|
||||
self.zipcode = row[4]
|
||||
self.city_id = row[5]
|
||||
self.email = row[6]
|
||||
self.phone = row[7]
|
||||
self.password = row[8]
|
||||
self.role = row[9]
|
||||
|
46
models/utils.py
Normal file
46
models/utils.py
Normal file
@ -0,0 +1,46 @@
|
||||
from models.city import City
|
||||
from models.database import Database
|
||||
|
||||
class DatabaseUtils:
|
||||
|
||||
@staticmethod
|
||||
def init_city_data():
|
||||
new_city = City(Database.connection, None, "Haastrecht")
|
||||
if not new_city.load_by_name():
|
||||
new_city.save()
|
||||
|
||||
new_city = City(Database.connection, None, "Gouda")
|
||||
if not new_city.load_by_name():
|
||||
new_city.save()
|
||||
|
||||
new_city = City(Database.connection, None, "Rotterdam")
|
||||
if not new_city.load_by_name():
|
||||
new_city.save()
|
||||
|
||||
new_city = City(Database.connection, None, "Bruinisse")
|
||||
if not new_city.load_by_name():
|
||||
new_city.save()
|
||||
|
||||
new_city = City(Database.connection, None, "Amsterdam")
|
||||
if not new_city.load_by_name():
|
||||
new_city.save()
|
||||
|
||||
new_city = City(Database.connection, None, "Goes")
|
||||
if not new_city.load_by_name():
|
||||
new_city.save()
|
||||
|
||||
new_city = City(Database.connection, None, "Zoetermeer")
|
||||
if not new_city.load_by_name():
|
||||
new_city.save()
|
||||
|
||||
new_city = City(Database.connection, None, "Breda")
|
||||
if not new_city.load_by_name():
|
||||
new_city.save()
|
||||
|
||||
new_city = City(Database.connection, None, "Eindhoven")
|
||||
if not new_city.load_by_name():
|
||||
new_city.save()
|
||||
|
||||
new_city = City(Database.connection, None, "Almere")
|
||||
if not new_city.load_by_name():
|
||||
new_city.save()
|
0
services/__init__.py
Normal file
0
services/__init__.py
Normal file
19
services/checksum.py
Normal file
19
services/checksum.py
Normal file
@ -0,0 +1,19 @@
|
||||
import random
|
||||
|
||||
class IdChecksum:
|
||||
@staticmethod
|
||||
def generate():
|
||||
while True:
|
||||
init_num = random.randint(1, 9)
|
||||
id = [random.randint(0, 9) for _ in range(9)]
|
||||
id.insert(0, init_num)
|
||||
if IdChecksum.is_valid(id):
|
||||
return "".join(str(x) for x in id)
|
||||
|
||||
@staticmethod
|
||||
def is_valid(checksum):
|
||||
sum_digits = sum(checksum[:-1])
|
||||
if sum_digits % 10 == checksum[-1]:
|
||||
return True
|
||||
else:
|
||||
return False
|
25
services/encryption.py
Normal file
25
services/encryption.py
Normal file
@ -0,0 +1,25 @@
|
||||
class Encryption:
|
||||
@staticmethod
|
||||
def vigenere(text: str, key: str, encrypt=True):
|
||||
result = ''
|
||||
|
||||
for i in range(len(text)):
|
||||
letter_n = ord(text[i])
|
||||
key_n = ord(key[i % len(key)])
|
||||
|
||||
if encrypt:
|
||||
value = (letter_n + key_n) % 1114112
|
||||
else:
|
||||
value = (letter_n - key_n) % 1114112
|
||||
|
||||
result += chr(value)
|
||||
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def encrypt(text: str, key: str):
|
||||
return Encryption.vigenere(text=text, key=key, encrypt=True)
|
||||
|
||||
@staticmethod
|
||||
def decrypt(text: str, key: str):
|
||||
return Encryption.vigenere(text=text, key=key, encrypt=False)
|
0
ui/__init__.py
Normal file
0
ui/__init__.py
Normal file
49
ui/input_menu.py
Normal file
49
ui/input_menu.py
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
class InputMenu:
|
||||
|
||||
def __init__(self, title):
|
||||
self._title = title
|
||||
self._fields = []
|
||||
|
||||
def add_option(self, key, type, title, min, max):
|
||||
self._fields.append({"key": key, "title": title, "type": type, "value": None, "min": min, "max": max})
|
||||
return self
|
||||
|
||||
def do_input(self):
|
||||
print("")
|
||||
print(f"/--[ {self._title} ]----------------------------")
|
||||
|
||||
for i in range(len(self._fields)):
|
||||
data = None
|
||||
|
||||
while True:
|
||||
data = input(f"| ({self._fields[i]['title']}) => ")
|
||||
if self._fields[i]['type'] == "STR":
|
||||
if len(data) > self._fields[i]['min'] and len(data) <= self._fields[i]['max']:
|
||||
self._fields[i]['value'] = data
|
||||
break
|
||||
else:
|
||||
print("| Invalid input! Try again. \n|")
|
||||
|
||||
elif self._fields[i]['type'] == "INT":
|
||||
try:
|
||||
num = int(data)
|
||||
if num > self._fields[i]['min'] and num <= self._fields[i]['max']:
|
||||
self._fields[i]['value'] = data
|
||||
break
|
||||
else:
|
||||
print("| Invalid input! Try again. \n|")
|
||||
except:
|
||||
print("| Invalid input! Try again. \n|")
|
||||
else:
|
||||
exit("Invalid input type!")
|
||||
|
||||
print(f"\-------------------------------")
|
||||
print("")
|
||||
return self
|
||||
|
||||
def get_value(self, key):
|
||||
for i in range(len(self._fields)):
|
||||
if self._fields[i]["key"] == key:
|
||||
return self._fields[i]["value"]
|
||||
return None
|
34
ui/selection_menu.py
Normal file
34
ui/selection_menu.py
Normal file
@ -0,0 +1,34 @@
|
||||
class SelectionMenu:
|
||||
|
||||
def __init__(self, title):
|
||||
self.title = title
|
||||
self.options = []
|
||||
|
||||
def add_option(self, title, callback):
|
||||
self.options.append({"title": title, "callback": callback})
|
||||
return self
|
||||
|
||||
def display(self):
|
||||
print("")
|
||||
print(f"/--[ {self.title} ]----------------------------")
|
||||
for i in range(len(self.options)):
|
||||
print(f"| {i}). {self.options[i]['title']}")
|
||||
print(f"\-------------------------------")
|
||||
print("")
|
||||
return self
|
||||
|
||||
def input_option(self):
|
||||
try:
|
||||
data = input("Selection: ")
|
||||
index = int(data)
|
||||
if index < 0 or index > len(self.options) - 1:
|
||||
print("Please enter in a valid selection.")
|
||||
return self.input_option()
|
||||
return self.options[index]['callback']
|
||||
except:
|
||||
print("Please enter in a valid selection.")
|
||||
return self.input_option()
|
||||
|
||||
|
||||
|
||||
|
0
views/__init__.py
Normal file
0
views/__init__.py
Normal file
Loading…
x
Reference in New Issue
Block a user