Files
website/python/database.py

412 lines
15 KiB
Python
Executable File

#!/usr/bin/env python3
import mysql.connector as mysql
import os
import json
def readFile(
location,
): # Loads the location of a certain file and returns that file if it is json
with open(location) as f:
return json.load(f)
def command(command): # Will just execute a sql command
db, cursor = connect()
cursor.execute(command)
db.commit()
db.close()
def trueSearch(command): # Will just execute sql command and return result
db, cursor = connect()
cursor.execute(command)
value = cursor.fetchall()
db.close()
return value
def connect(database=""):
dbInfo = readFile(
__file__[: __file__.rindex("/python/database.py") + 1] + "html/config.json"
)
if not database:
database = dbInfo["database"]["name"]
db = mysql.connect(
host=dbInfo["database"]["host"],
password=dbInfo["database"]["password"],
user=dbInfo["database"]["username"],
database=database,
port=dbInfo["database"]["port"],
)
cursor = db.cursor()
return db, cursor
def deleteTable(name): # Will delete a table in the database
db, cursor = connect()
command = "DROP TABLE " + name + ";"
cursor.execute(command)
db.commit()
db.close()
def createTable(name, coulumns): # Will create a table in the database
db, cursor = connect()
command = "CREATE TABLE " + name + " ("
for x in coulumns:
command += x[0]
if x[1] == 0:
command += " varchar(255), "
elif x[1] == 2:
command += " float, "
elif x[1] == 3:
command += " bigint, "
elif x[1] == 4:
command += " text, "
elif x[1] == 5:
command += f" int AUTO_INCREMENT, PRIMARY KEY (`{x[0]}`), "
elif x[1] == 6:
command += " boolean, "
else:
command += " int, "
command = command[: len(command) - 2]
command += ");"
cursor.execute(command)
db.commit()
db.close()
def appendValue(table, value, coulumns=""): # Will add a value to a table
db, cursor = connect()
command = "INSERT INTO " + table + " " + coulumns + " VALUES ("
for x in value:
command += "'" + x + "', "
command = command[: len(command) - 2]
command += ");"
cursor.execute(command)
db.commit()
db.close()
# Will backup a database to a certain location with a name of choosing
def backUp(fileName):
dbInfo = readFile(
__file__[: __file__.rindex("/python/database.py") + 1] + "html/config.json"
)
username = dbInfo["database"]["username"]
password = dbInfo["database"]["password"]
database = dbInfo["database"]["name"]
location = dbInfo["database"]["backupLocation"]
host = dbInfo["database"]["host"]
port = dbInfo["database"]["port"]
locationdata = f"{location}/{fileName}"
if not os.path.exists(location):
os.system(f"mkdir {location}")
os.system(
f"mysqldump -u {username} --host={host} --port={port} --password={password} --result-file={locationdata} {database}"
)
def restore(fileName):
dbInfo = readFile(
__file__[: __file__.rindex("/python/database.py") + 1] + "html/config.json"
)
location = dbInfo["database"]["backupLocation"]
database = dbInfo["database"]["name"]
locationdata = f"{location}/{fileName}"
os.system(f"mysql {database} < {locationdata}")
def search(table, where, search="*"): # searches for value in table
db, cursor = connect()
cursor.execute("SELECT " + search + " FROM " + table + " WHERE " + where + ";")
value2 = cursor.fetchall()
db.close()
try:
value = value2[0]
except:
value = value2
return value
def delete(table, where): # deletes values in table
db, cursor = connect()
cursor.execute("DELETE FROM " + table + " WHERE " + where + ";")
db.commit()
db.close()
def repair(): # Repairs all tables or updates them if needed
# Gets Infomation schema database
dbInfo = readFile(
__file__[: __file__.rindex("/python/database.py") + 1] + "html/config.json"
)
db2, cursor2 = connect("INFORMATION_SCHEMA")
updatedVersions = []
databaseDict = {
"information": [["pointer", 0], ["data", 0]],
"cookies": [["cookie", 0], ["username", 0], ["expire", 1], ["lastIP", 0]],
"internet": [
["hour", 1],
["minute", 1],
["hour2", 1],
["minute2", 1],
["expire", 1],
["id", 1],
],
"log": [["type", 1], ["message", 0], ["time", 1]],
"logType": [["type", 1], ["name", 0], ["color", 0]],
"privileges": [["username", 0], ["privilege", 0]],
"users": [["username", 0], ["password", 0]],
"requests": [["ip", 0], ["time", 1]],
"cookieClicker": [
["username", 0],
["room", 0],
["cookies", 3],
["powerOfCookies", 3],
["cookiesPs", 3],
["powerOfCookiesPs", 3],
["lastUpdate", 3],
],
"localStorage": [["username", 0], ["data", 4]],
"golfGamePlayers": [
["gameID", 1],
["multiplier", 1],
["user", 0],
["points", 1],
["orderID", 1],
["lastMode", 0],
["upToDate", 6],
["turnsSkipped", 1],
["bot", 6],
],
"golfGameCards": [
["gameID", 1],
["user", 0],
["card", 1],
["cardPlacement", 1],
["faceUp", 6],
],
"golfGame": [
["ID", 5],
["deck", 4],
["discard", 4],
["cardNumber", 1],
["flipNumber", 1],
["multiplierForFlip", 1],
["pointsToEnd", 1],
["name", 0],
["password", 0],
["players", 1],
["playersToStart", 1],
["currentPlayer", 1],
["turnStartTime", 1],
["locked", 6],
["decks", 1],
["skipTime", 1],
["timeLeft", 1],
["skipTurns", 1],
["resetPoints", 1],
["bots", 1],
],
"random_stuff": [["type", 0], ["word", 0], ["definition", 4]],
"klumpy": [
["gameID", 5],
["type", 0],
["username", 0],
["score", 1],
["board", 4],
["history", 4],
],
}
changedTables = []
for x in databaseDict:
name = x
trueValues = databaseDict[x]
compareValues = []
for x in trueValues:
compareValues.append(x[0])
cursor2.execute(
f"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='{name}' AND TABLE_SCHEMA='website'"
)
value2 = cursor2.fetchall()
value = []
for x in value2:
value.append(x[0])
if name == "users":
try:
value.remove("USER")
except:
1
try:
value.remove("CURRENT_CONNECTIONS")
except:
1
try:
value.remove("TOTAL_CONNECTIONS")
except:
1
backupValue = value.copy()
for x in value:
try:
compareValues.remove(x)
except:
break
backupValue.remove(x)
if backupValue or compareValues or name == "logType":
try:
deleteTable(name)
except:
1
createTable(name, trueValues)
if name == "logType":
logTypes = readFile(
__file__[: __file__.rindex("/python/database.py") + 1]
+ "html/logTypes.json"
)
for x in logTypes:
appendValue(name, [x["type"], x["name"], x["color"]])
else:
if name == "privileges":
appendValue(name, [dbInfo["database"]["username"], "root"])
elif name == "users":
appendValue(
name,
[
dbInfo["database"]["username"],
dbInfo["database"]["password"],
],
)
changedTables.append(name)
elif (
name == "information"
): # Used to check the information table to see if the database can be updated in a better way.
version = trueSearch("SELECT data FROM information WHERE pointer='version'")
latest_version = "v2.9"
if version: # Checks if the version tag still exists.
try: # In here you can update the version to a new version
version = version[0][0]
if version == "v1.0":
try:
command("ALTER TABLE cookies ADD lastIP varchar(255)")
except Exception:
1
version = "v1.1"
updatedVersions.append("v1.1")
if version == "v1.1":
try:
command("ALTER TABLE cookies ADD lastIP varchar(255)")
except Exception:
1
createTable(
"docker",
[
["link", 0],
["action", 0],
["image", 0],
["password", 0],
["owner", 0],
["port", 1],
["ID", 0],
],
)
createTable("dockerImage", [["realName", 0], ["shortName", 0]])
version = "v2.0"
updatedVersions.append("v2.0")
if version == "v2.0": # Adds support for multiple decks
command("ALTER table golfGame ADD decks int")
command("UPDATE golfGame SET decks='1'")
version = "v2.1"
updatedVersions.append("v2.1")
if version == "v2.1": # Adds support for skip time
command("ALTER table golfGame ADD skipTime int")
command("ALTER table golfGame ADD timeLeft int")
command("UPDATE golfGame SET skipTime='0'")
command("UPDATE golfGame SET timeLeft='0'")
version = "v2.2"
updatedVersions.append("v2.2")
if (
version == "v2.2"
): # Adds support for limited amount of turns to skip
command("ALTER table golfGame ADD skipTurns int")
command("UPDATE golfGame SET skipTurns='0'")
command("ALTER table golfGamePlayers ADD turnsSkipped int")
command("UPDATE golfGamePlayers SET turnsSkipped='0'")
version = "v2.3"
updatedVersions.append("v2.3")
if (
version == "v2.3"
): # Adds support for reset points when hitting a certain multiplier
command("ALTER table golfGame ADD resetPoints int")
command("UPDATE golfGame SET resetPoints='0'")
version = "v2.4"
updatedVersions.append("v2.4")
if version == "v2.4": # Drops support for docker
command("DROP TABLE docker")
command("DROP TABLE dockerImages")
command(
"DELETE FROM privileges WHERE privilege='docker' OR privilege='dockerAdmin'"
)
version = "v2.5"
updatedVersions.append("v2.5")
if version == "v2.5": # Drops support for docker
command("ALTER TABLE golfGamePlayers ADD bot boolean")
command("ALTER TABLE golfGame ADD bots int")
command("ALTER TABLE golfGamePlayers SET bot=0")
command("ALTER TABLE golfGame SET bots=0")
version = "v2.6"
updatedVersions.append("v2.6")
if version == "v2.6":
createTable(
"klumpy",
[
["gameID", 1],
["type", 0],
["username", 0],
["score", 1],
["board", 4],
["history", 4],
],
)
version = "v2.7"
updatedVersions.append("v2.7")
if version == "v2.7":
command("RENAME TABLE klumpy TO klumpy2")
createTable(
"klumpy",
[
["gameID", 5],
["type", 0],
["username", 0],
["score", 1],
["board", 4],
["history", 4],
],
)
command(
"INSERT INTO klumpy (`type`, username, score, board, history) SELECT `type`, username, score, board, history FROM klumpy2"
)
command("DROP TABLE klumpy2")
version = "v2.8"
updatedVersions.append("v2.8")
if version == "v2.8":
command("DROP TABLE space3")
command("DROP TABLE space3likes")
version = "v2.8"
updatedVersions.append("v2.8")
except:
1
# Fixes the version if it is invalid to the latest version
if version != latest_version:
version = latest_version
command("DELETE FROM information WHERE pointer='version'")
command(f"INSERT INTO information VALUES('version', '{version}')")
else:
command(
f"INSERT INTO information VALUES('version', '{latest_version}')"
)
changedTables.append("information")
db2.close()
return changedTables, updatedVersions