Fixed live editing, corrected many small errors, added more general best practices
This commit is contained in:
parent
e178bbee57
commit
503b26403c
|
@ -1,3 +1,4 @@
|
||||||
database.db
|
database.db
|
||||||
config.ini
|
config.ini
|
||||||
config.ini.example
|
config.ini.example
|
||||||
|
.idea
|
|
@ -14,7 +14,7 @@ To prevent the server from knowing the encryption key, the password you provide
|
||||||
If you wish to change the user's password, set "passwordchange" to "yes" and "newpass" to the new hash.
|
If you wish to change the user's password, set "passwordchange" to "yes" and "newpass" to the new hash.
|
||||||
|
|
||||||
|
|
||||||
Some users use the legacy argon2id mode (by which i mean about 8, so only implement if you feel like it), and to implement argon2id functionality, you hash like this:
|
Some users use the legacy argon2 id mode (by which I mean about 8, so only implement if you feel like it), and to implement argon2 id functionality, you hash like this:
|
||||||
```
|
```
|
||||||
Parallelism should be 1
|
Parallelism should be 1
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ The output should be in the encoded format, not the hashed format
|
||||||
Salt should be the SHA512 of the password
|
Salt should be the SHA512 of the password
|
||||||
```
|
```
|
||||||
|
|
||||||
(Yes i know this is really bad practice, guess why we are replacing it)
|
(Yes I know these are really awful practice, guess why we are replacing it)
|
||||||
|
|
||||||
To test if SHA-3 or argon2 is used, just try the SHA-3 and if 422 gets returned try argon2.
|
To test if SHA-3 or argon2 is used, just try the SHA-3 and if 422 gets returned try argon2.
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
- Switch to WebSockets for updating notes + live updating of note list and more, this involves redoing some APIs
|
- Switch to WebSockets for updating notes + live updating of note list and more, this involves redoing some APIs
|
||||||
- Compress notes to reduce bandwidth and storage
|
- Compress notes to reduce bandwidth and storage
|
||||||
|
- Use OAuth for authentication
|
||||||
- Dedicated domain (not just a subdomain, if anyone can donate a domain let Arzumify know!)
|
- Dedicated domain (not just a subdomain, if anyone can donate a domain let Arzumify know!)
|
||||||
|
|
4
init_db
4
init_db
|
@ -2,19 +2,19 @@
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
def generatedb():
|
def generatedb():
|
||||||
connection = sqlite3.connect("database.db")
|
connection = sqlite3.connect("database.db")
|
||||||
|
|
||||||
with open("schema.sql") as f:
|
with open("schema.sql") as f:
|
||||||
connection.executescript(f.read())
|
connection.executescript(f.read())
|
||||||
|
|
||||||
cur = connection.cursor()
|
|
||||||
|
|
||||||
connection.commit()
|
connection.commit()
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
print("[INFO] Generated database")
|
print("[INFO] Generated database")
|
||||||
|
|
||||||
|
|
||||||
if not os.path.exists("database.db"):
|
if not os.path.exists("database.db"):
|
||||||
generatedb()
|
generatedb()
|
||||||
else:
|
else:
|
||||||
|
|
106
main
106
main
|
@ -8,7 +8,7 @@ import asyncio
|
||||||
from hypercorn.config import Config
|
from hypercorn.config import Config
|
||||||
from hypercorn.asyncio import serve
|
from hypercorn.asyncio import serve
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
from quart import Quart, request, url_for, flash, redirect, session, make_response, send_from_directory, stream_with_context, Response, request
|
from quart import Quart, request
|
||||||
|
|
||||||
# Parse configuration file, and check if anything is wrong with it
|
# Parse configuration file, and check if anything is wrong with it
|
||||||
if not os.path.exists("config.ini"):
|
if not os.path.exists("config.ini"):
|
||||||
|
@ -31,33 +31,38 @@ if SECRET_KEY == "supersecretkey" or SECRET_KEY == "placeholder":
|
||||||
app = Quart(__name__)
|
app = Quart(__name__)
|
||||||
app.config["SECRET_KEY"] = SECRET_KEY
|
app.config["SECRET_KEY"] = SECRET_KEY
|
||||||
|
|
||||||
|
|
||||||
# Database functions
|
# Database functions
|
||||||
def get_db_connection():
|
def get_db_connection():
|
||||||
conn = sqlite3.connect("database.db")
|
conn = sqlite3.connect("database.db")
|
||||||
conn.row_factory = sqlite3.Row
|
conn.row_factory = sqlite3.Row
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
def get_user(id):
|
|
||||||
|
def get_user(identifier):
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
post = conn.execute("SELECT * FROM users WHERE id = ?",
|
post = conn.execute("SELECT * FROM users WHERE id = ?",
|
||||||
(id,)).fetchone()
|
(identifier,)).fetchone()
|
||||||
conn.close()
|
conn.close()
|
||||||
if post is None:
|
if post is None:
|
||||||
return None
|
return None
|
||||||
return post
|
return post
|
||||||
|
|
||||||
def get_note(id):
|
|
||||||
|
def get_note(identifier):
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
post = conn.execute("SELECT * FROM notes WHERE id = ?",
|
post = conn.execute("SELECT * FROM notes WHERE id = ?",
|
||||||
(id,)).fetchone()
|
(identifier,)).fetchone()
|
||||||
conn.close()
|
conn.close()
|
||||||
if post is None:
|
if post is None:
|
||||||
return None
|
return None
|
||||||
return post
|
return post
|
||||||
|
|
||||||
def get_space(id):
|
|
||||||
|
def get_space(identifier):
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
notes = conn.execute("SELECT content, title FROM notes WHERE creator = ? ORDER BY id DESC;", (id,)).fetchall()
|
notes = conn.execute("SELECT content, title FROM notes WHERE creator = ? ORDER BY id DESC;",
|
||||||
|
(identifier,)).fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
spacetaken = 0
|
spacetaken = 0
|
||||||
for x in notes:
|
for x in notes:
|
||||||
|
@ -65,33 +70,35 @@ def get_space(id):
|
||||||
spacetaken = spacetaken + len(x["title"].encode("utf-8"))
|
spacetaken = spacetaken + len(x["title"].encode("utf-8"))
|
||||||
return spacetaken
|
return spacetaken
|
||||||
|
|
||||||
def get_note_count(id):
|
|
||||||
conn = get_db_connection()
|
|
||||||
notes = conn.execute("SELECT content, title FROM notes WHERE creator = ? ORDER BY id DESC;", (id,)).fetchall()
|
|
||||||
conn.close()
|
|
||||||
notecount = 0
|
|
||||||
for x in notes:
|
|
||||||
notecount = notecount + 1
|
|
||||||
return notecount
|
|
||||||
|
|
||||||
def get_session(id):
|
def get_note_count(identifier):
|
||||||
|
conn = get_db_connection()
|
||||||
|
notes = conn.execute("SELECT content, title FROM notes WHERE creator = ? ORDER BY id DESC;",
|
||||||
|
(identifier,)).fetchall()
|
||||||
|
conn.close()
|
||||||
|
return len(notes)
|
||||||
|
|
||||||
|
|
||||||
|
def get_session(identifier):
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
post = conn.execute("SELECT * FROM sessions WHERE session = ?",
|
post = conn.execute("SELECT * FROM sessions WHERE session = ?",
|
||||||
(id,)).fetchone()
|
(identifier,)).fetchone()
|
||||||
conn.close()
|
conn.close()
|
||||||
if post is None:
|
if post is None:
|
||||||
return None
|
return None
|
||||||
return post
|
return post
|
||||||
|
|
||||||
def get_session_from_sessionid(id):
|
|
||||||
|
def get_session_from_sessionid(identifier):
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
post = conn.execute("SELECT * FROM sessions WHERE sessionid = ?",
|
post = conn.execute("SELECT * FROM sessions WHERE sessionid = ?",
|
||||||
(id,)).fetchone()
|
(identifier,)).fetchone()
|
||||||
conn.close()
|
conn.close()
|
||||||
if post is None:
|
if post is None:
|
||||||
return None
|
return None
|
||||||
return post
|
return post
|
||||||
|
|
||||||
|
|
||||||
def check_username_taken(username):
|
def check_username_taken(username):
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
post = conn.execute("SELECT * FROM users WHERE lower(username) = ?",
|
post = conn.execute("SELECT * FROM users WHERE lower(username) = ?",
|
||||||
|
@ -101,6 +108,7 @@ def check_username_taken(username):
|
||||||
return None
|
return None
|
||||||
return post["id"]
|
return post["id"]
|
||||||
|
|
||||||
|
|
||||||
# Disable CORS
|
# Disable CORS
|
||||||
@app.after_request
|
@app.after_request
|
||||||
async def add_cors_headers(response):
|
async def add_cors_headers(response):
|
||||||
|
@ -109,13 +117,16 @@ async def add_cors_headers(response):
|
||||||
response.headers.add("Access-Control-Allow-Methods", "*")
|
response.headers.add("Access-Control-Allow-Methods", "*")
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
# Live editing store
|
# Live editing store
|
||||||
messages = {}
|
messages = {}
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/version", methods=("GET", "POST"))
|
@app.route("/api/version", methods=("GET", "POST"))
|
||||||
async def apiversion():
|
async def apiversion():
|
||||||
return "Burgernotes Version 1.2"
|
return "Burgernotes Version 1.2"
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/signup", methods=("GET", "POST"))
|
@app.route("/api/signup", methods=("GET", "POST"))
|
||||||
async def apisignup():
|
async def apisignup():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
@ -138,7 +149,7 @@ async def apisignup():
|
||||||
if len(password) < 14:
|
if len(password) < 14:
|
||||||
return {}, 422
|
return {}, 422
|
||||||
|
|
||||||
if not check_username_taken(username) == None:
|
if not check_username_taken(username) is None:
|
||||||
return {}, 409
|
return {}, 409
|
||||||
|
|
||||||
hashedpassword = generate_password_hash(password)
|
hashedpassword = generate_password_hash(password)
|
||||||
|
@ -148,7 +159,6 @@ async def apisignup():
|
||||||
(username, hashedpassword, str(time.time())))
|
(username, hashedpassword, str(time.time())))
|
||||||
|
|
||||||
userID = check_username_taken(username)
|
userID = check_username_taken(username)
|
||||||
user = get_user(userID)
|
|
||||||
|
|
||||||
randomCharacters = secrets.token_hex(512)
|
randomCharacters = secrets.token_hex(512)
|
||||||
|
|
||||||
|
@ -161,6 +171,7 @@ async def apisignup():
|
||||||
"key": randomCharacters
|
"key": randomCharacters
|
||||||
}, 200
|
}, 200
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/login", methods=("GET", "POST"))
|
@app.route("/api/login", methods=("GET", "POST"))
|
||||||
async def apilogin():
|
async def apilogin():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
@ -172,13 +183,13 @@ async def apilogin():
|
||||||
|
|
||||||
check_username_thing = check_username_taken(username)
|
check_username_thing = check_username_taken(username)
|
||||||
|
|
||||||
if check_username_thing == None:
|
if check_username_thing is None:
|
||||||
return {}, 401
|
return {}, 401
|
||||||
|
|
||||||
userID = check_username_taken(username)
|
userID = check_username_taken(username)
|
||||||
user = get_user(userID)
|
user = get_user(userID)
|
||||||
|
|
||||||
if not check_password_hash(user["password"], (password)):
|
if not check_password_hash(user["password"], password):
|
||||||
return {}, 401
|
return {}, 401
|
||||||
|
|
||||||
randomCharacters = secrets.token_hex(512)
|
randomCharacters = secrets.token_hex(512)
|
||||||
|
@ -217,6 +228,7 @@ async def apiuserinfo():
|
||||||
}
|
}
|
||||||
return datatemplate
|
return datatemplate
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/listnotes", methods=("GET", "POST"))
|
@app.route("/api/listnotes", methods=("GET", "POST"))
|
||||||
async def apilistnotes():
|
async def apilistnotes():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
@ -241,6 +253,7 @@ async def apilistnotes():
|
||||||
|
|
||||||
return datatemplate, 200
|
return datatemplate, 200
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/exportnotes", methods=("GET", "POST"))
|
@app.route("/api/exportnotes", methods=("GET", "POST"))
|
||||||
async def apiexportnotes():
|
async def apiexportnotes():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
@ -268,6 +281,7 @@ async def apiexportnotes():
|
||||||
|
|
||||||
return datatemplate, 200
|
return datatemplate, 200
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/newnote", methods=("GET", "POST"))
|
@app.route("/api/newnote", methods=("GET", "POST"))
|
||||||
async def apinewnote():
|
async def apinewnote():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
@ -280,12 +294,13 @@ async def apinewnote():
|
||||||
|
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
conn.execute("INSERT INTO notes (title, content, creator, created, edited) VALUES (?, ?, ?, ?, ?)",
|
conn.execute("INSERT INTO notes (title, content, creator, created, edited) VALUES (?, ?, ?, ?, ?)",
|
||||||
(noteName, "", user["id"], str(time.time()), str(time.time())))
|
(noteName, "", user["id"], str(time.time()), str(time.time())))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
return {}, 200
|
return {}, 200
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/readnote", methods=("GET", "POST"))
|
@app.route("/api/readnote", methods=("GET", "POST"))
|
||||||
async def apireadnote():
|
async def apireadnote():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
@ -298,8 +313,8 @@ async def apireadnote():
|
||||||
|
|
||||||
note = get_note(noteId)
|
note = get_note(noteId)
|
||||||
|
|
||||||
if (note != None):
|
if note is not None:
|
||||||
if (user["id"] == note["creator"]):
|
if user["id"] == note["creator"]:
|
||||||
contenttemplate = {
|
contenttemplate = {
|
||||||
"content": note["content"]
|
"content": note["content"]
|
||||||
}
|
}
|
||||||
|
@ -310,6 +325,7 @@ async def apireadnote():
|
||||||
else:
|
else:
|
||||||
return {}, 422
|
return {}, 422
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/waitforedit", methods=("GET", "POST"))
|
@app.route("/api/waitforedit", methods=("GET", "POST"))
|
||||||
async def waitforedit():
|
async def waitforedit():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
@ -317,26 +333,27 @@ async def waitforedit():
|
||||||
secretKey = data["secretKey"]
|
secretKey = data["secretKey"]
|
||||||
userCookie = get_session(secretKey)
|
userCookie = get_session(secretKey)
|
||||||
user = get_user(userCookie["id"])
|
user = get_user(userCookie["id"])
|
||||||
complete = true
|
complete = True
|
||||||
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
while user["id"] not in messages or not messages[user["id"]]:
|
while user["id"] not in messages or not messages[user["id"]]:
|
||||||
await asyncio.sleep(0)
|
await asyncio.sleep(0)
|
||||||
elapsed_time = time.time() - start_time
|
elapsed_time = time.time() - start_time
|
||||||
if elapsed_time >= 20:
|
if elapsed_time >= 20:
|
||||||
|
complete = False
|
||||||
break
|
break
|
||||||
complete = false
|
|
||||||
|
|
||||||
message = messages[user["id"]].pop(0)
|
message = messages[user["id"]].pop(0)
|
||||||
del messages[user["id"]]
|
del messages[user["id"]]
|
||||||
|
|
||||||
if complete == true:
|
if complete:
|
||||||
return {
|
return {
|
||||||
"note": message
|
"note": message
|
||||||
}, 200
|
}, 200
|
||||||
else:
|
else:
|
||||||
return 400
|
return 400
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/editnote", methods=("GET", "POST"))
|
@app.route("/api/editnote", methods=("GET", "POST"))
|
||||||
async def apieditnote():
|
async def apieditnote():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
@ -354,10 +371,11 @@ async def apieditnote():
|
||||||
if get_space(user["id"]) + len(content.encode("utf-8")) > int(MAX_STORAGE):
|
if get_space(user["id"]) + len(content.encode("utf-8")) > int(MAX_STORAGE):
|
||||||
return {}, 418
|
return {}, 418
|
||||||
|
|
||||||
if (note != None):
|
if note is not None:
|
||||||
if (user["id"] == note["creator"]):
|
if user["id"] == note["creator"]:
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
conn.execute("UPDATE notes SET content = ?, title = ?, edited = ? WHERE id = ?", (content, title, str(time.time()), noteId))
|
conn.execute("UPDATE notes SET content = ?, title = ?, edited = ? WHERE id = ?",
|
||||||
|
(content, title, str(time.time()), noteId))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
@ -388,8 +406,8 @@ async def apieditnotetitle():
|
||||||
if get_space(user["id"]) + len(content.encode("utf-8")) > int(MAX_STORAGE):
|
if get_space(user["id"]) + len(content.encode("utf-8")) > int(MAX_STORAGE):
|
||||||
return {}, 418
|
return {}, 418
|
||||||
|
|
||||||
if (note != None):
|
if note is not None:
|
||||||
if (user["id"] == note["creator"]):
|
if user["id"] == note["creator"]:
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
conn.execute("UPDATE notes SET title = ?, edited = ? WHERE id = ?", (content, str(time.time()), noteId))
|
conn.execute("UPDATE notes SET title = ?, edited = ? WHERE id = ?", (content, str(time.time()), noteId))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
@ -414,8 +432,8 @@ async def apiremovenote():
|
||||||
|
|
||||||
note = get_note(noteId)
|
note = get_note(noteId)
|
||||||
|
|
||||||
if (note != None):
|
if note is not None:
|
||||||
if (user["id"] == note["creator"]):
|
if user["id"] == note["creator"]:
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
conn.execute("DELETE FROM notes WHERE id = ?", (noteId,))
|
conn.execute("DELETE FROM notes WHERE id = ?", (noteId,))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
@ -435,7 +453,6 @@ async def apideleteaccount():
|
||||||
secretKey = data["secretKey"]
|
secretKey = data["secretKey"]
|
||||||
|
|
||||||
userCookie = get_session(secretKey)
|
userCookie = get_session(secretKey)
|
||||||
user = get_user(userCookie["id"])
|
|
||||||
|
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
conn.execute("DELETE FROM notes WHERE creator = ?", (userCookie["id"],))
|
conn.execute("DELETE FROM notes WHERE creator = ?", (userCookie["id"],))
|
||||||
|
@ -445,6 +462,7 @@ async def apideleteaccount():
|
||||||
|
|
||||||
return {}, 200
|
return {}, 200
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/sessions/list", methods=("GET", "POST"))
|
@app.route("/api/sessions/list", methods=("GET", "POST"))
|
||||||
async def apisessionslist():
|
async def apisessionslist():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
@ -463,7 +481,7 @@ async def apisessionslist():
|
||||||
for x in sessions:
|
for x in sessions:
|
||||||
device = x["device"]
|
device = x["device"]
|
||||||
thisSession = False
|
thisSession = False
|
||||||
if (x["session"] == secretKey):
|
if x["session"] == secretKey:
|
||||||
thisSession = True
|
thisSession = True
|
||||||
sessiontemplate = {
|
sessiontemplate = {
|
||||||
"id": x["sessionid"],
|
"id": x["sessionid"],
|
||||||
|
@ -474,6 +492,7 @@ async def apisessionslist():
|
||||||
|
|
||||||
return datatemplate, 200
|
return datatemplate, 200
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/sessions/remove", methods=("GET", "POST"))
|
@app.route("/api/sessions/remove", methods=("GET", "POST"))
|
||||||
async def apisessionsremove():
|
async def apisessionsremove():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
@ -486,8 +505,8 @@ async def apisessionsremove():
|
||||||
|
|
||||||
session = get_session_from_sessionid(sessionId)
|
session = get_session_from_sessionid(sessionId)
|
||||||
|
|
||||||
if (session != None):
|
if session is not None:
|
||||||
if (user["id"] == session["id"]):
|
if user["id"] == session["id"]:
|
||||||
conn = get_db_connection()
|
conn = get_db_connection()
|
||||||
conn.execute("DELETE FROM sessions WHERE sessionid = ?", (session["sessionid"],))
|
conn.execute("DELETE FROM sessions WHERE sessionid = ?", (session["sessionid"],))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
@ -521,14 +540,17 @@ async def listusers():
|
||||||
else:
|
else:
|
||||||
return {}, 401
|
return {}, 401
|
||||||
|
|
||||||
|
|
||||||
@app.errorhandler(500)
|
@app.errorhandler(500)
|
||||||
async def burger(e):
|
async def burger():
|
||||||
return {}, 500
|
return {}, 500
|
||||||
|
|
||||||
|
|
||||||
@app.errorhandler(404)
|
@app.errorhandler(404)
|
||||||
async def burger(e):
|
async def burger():
|
||||||
return {}, 404
|
return {}, 404
|
||||||
|
|
||||||
|
|
||||||
# Start server
|
# Start server
|
||||||
hypercornconfig = Config()
|
hypercornconfig = Config()
|
||||||
hypercornconfig.bind = (HOST + ":" + PORT)
|
hypercornconfig.bind = (HOST + ":" + PORT)
|
||||||
|
|
|
@ -5,13 +5,14 @@ import sys
|
||||||
print("type n to cancel")
|
print("type n to cancel")
|
||||||
answer = input("delete user, what is user id?")
|
answer = input("delete user, what is user id?")
|
||||||
|
|
||||||
if (answer == "n"):
|
if answer == "n":
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
def get_db_connection():
|
def get_db_connection():
|
||||||
conn = sqlite3.connect("database.db")
|
connection = sqlite3.connect("database.db")
|
||||||
conn.row_factory = sqlite3.Row
|
connection.row_factory = sqlite3.Row
|
||||||
return conn
|
return connection
|
||||||
|
|
||||||
|
|
||||||
print("deleting notes")
|
print("deleting notes")
|
||||||
|
|
|
@ -22,5 +22,5 @@ CREATE TABLE sessions (
|
||||||
sessionid INTEGER PRIMARY KEY AUTOINCREMENT,
|
sessionid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
session TEXT NOT NULL,
|
session TEXT NOT NULL,
|
||||||
id INTEGER NOT NULL,
|
id INTEGER NOT NULL,
|
||||||
device TEXT NOT NULL DEFAULT "?"
|
device TEXT NOT NULL DEFAULT '?'
|
||||||
);
|
);
|
Loading…
Reference in New Issue