First fully functional website
This commit is contained in:
parent
0c424ccb3d
commit
c5eef007aa
10 changed files with 514 additions and 26 deletions
BIN
icons/user_link.png
Normal file
BIN
icons/user_link.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
BIN
icons/user_new.png
Normal file
BIN
icons/user_new.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
109
modules/Account.py
Normal file
109
modules/Account.py
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
# AGPL 3 or any later version
|
||||||
|
# (C) J.Y.Amihud ( Blender Dumbass )
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
import hashlib
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from getpass import getpass
|
||||||
|
|
||||||
|
from modules import Set
|
||||||
|
from modules import markdown
|
||||||
|
from modules.Common import *
|
||||||
|
|
||||||
|
|
||||||
|
def Load(name):
|
||||||
|
|
||||||
|
folder = Set.Folder()+"/accounts/"
|
||||||
|
try:
|
||||||
|
with open(folder+name+".json") as o:
|
||||||
|
return json.load(o)
|
||||||
|
except:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def Save(account):
|
||||||
|
|
||||||
|
name = account.get("username", "")
|
||||||
|
folder = Set.Folder()+"/accounts/"
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(folder+name+".json", "w") as save:
|
||||||
|
json.dump(account, save, indent=4)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Cannot save account!", e)
|
||||||
|
|
||||||
|
def Account():
|
||||||
|
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
from modules import Help
|
||||||
|
Help.Accounts()
|
||||||
|
|
||||||
|
if "--list" in sys.argv:
|
||||||
|
List()
|
||||||
|
|
||||||
|
elif "--add" in sys.argv:
|
||||||
|
try:
|
||||||
|
account = sys.argv[ sys.argv.index("--add") + 1]
|
||||||
|
if "--" in account: 1/0 # Failing this for the error message.
|
||||||
|
Add(account)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Account name wasn't specified!")
|
||||||
|
print('Use: $ python3 run.py --account --add blenderdumbass')
|
||||||
|
|
||||||
|
elif "--edit" in sys.argv:
|
||||||
|
try:
|
||||||
|
account = sys.argv[ sys.argv.index("--edit") + 1]
|
||||||
|
if "--" in account: 1/0 # Failing this for the error message.
|
||||||
|
Edit(account)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Account name wasn't specified!")
|
||||||
|
print('Use: $ python3 run.py --account --edit blenderdumbass')
|
||||||
|
|
||||||
|
|
||||||
|
def List():
|
||||||
|
|
||||||
|
folder = Set.Folder()+"/accounts"
|
||||||
|
for account in os.listdir(folder):
|
||||||
|
if account.endswith(".json"):
|
||||||
|
print(account.replace(".json", ""))
|
||||||
|
|
||||||
|
def Add(name):
|
||||||
|
|
||||||
|
# Adds a new account.
|
||||||
|
|
||||||
|
account = Load(name)
|
||||||
|
if account:
|
||||||
|
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Account already exists.")
|
||||||
|
|
||||||
|
account = {
|
||||||
|
"username":name,
|
||||||
|
"bio":"",
|
||||||
|
"invite_codes":{},
|
||||||
|
"invited":[],
|
||||||
|
"invited_by":"",
|
||||||
|
"password":hashlib.sha512(getpass("Account's Password: ").encode("utf-8")).hexdigest(),
|
||||||
|
"title":name,
|
||||||
|
"email":"",
|
||||||
|
"website":"",
|
||||||
|
"mastodon":"",
|
||||||
|
"matrix":"",
|
||||||
|
"sessions":{}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Save(account)
|
||||||
|
|
||||||
|
print(clr["bold"]+clr["tbyl"]+name+clr["norm"]+" is added."+clr["norm"])
|
||||||
|
|
||||||
|
def Edit(name):
|
||||||
|
|
||||||
|
folder = Set.Folder()+"/accounts/"
|
||||||
|
os.system("nano "+folder+name+".json")
|
|
@ -52,7 +52,10 @@ def Simplify(text, extrasimple=True):
|
||||||
|
|
||||||
good = "QWERTYUIOPLKJHGFDSAZXCVBNMqwertyuiopasdfghjklzxcvbnm.1234567890-_:* "
|
good = "QWERTYUIOPLKJHGFDSAZXCVBNMqwertyuiopasdfghjklzxcvbnm.1234567890-_:* "
|
||||||
|
|
||||||
if extrasimple:
|
if extrasimple == "file":
|
||||||
|
good = "QWERTYUIOPLKJHGFDSAZXCVBNMqwertyuiopasdfghjklzxcvbnm.1234567890-_"
|
||||||
|
|
||||||
|
elif extrasimple:
|
||||||
good = "qwertyuiopasdfghjklzxcvbnm.1234567890-_:"
|
good = "qwertyuiopasdfghjklzxcvbnm.1234567890-_:"
|
||||||
text = text.lower()
|
text = text.lower()
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,13 @@ def Help():
|
||||||
print()
|
print()
|
||||||
print(clr["tdyl"]+"--help"+clr["norm"]+" - Prints this Help Page.")
|
print(clr["tdyl"]+"--help"+clr["norm"]+" - Prints this Help Page.")
|
||||||
print(clr["tdyl"]+"--run"+clr["norm"]+" - Run the server.")
|
print(clr["tdyl"]+"--run"+clr["norm"]+" - Run the server.")
|
||||||
|
print()
|
||||||
print(clr["tdyl"]+"--set"+clr["norm"]+" - Use for changing settings.")
|
print(clr["tdyl"]+"--set"+clr["norm"]+" - Use for changing settings.")
|
||||||
|
print(clr["tdyl"]+"--account"+clr["norm"]+" - Manage Accounts.")
|
||||||
|
print()
|
||||||
print(clr["tdyl"]+"--config"+clr["norm"]+" - Edit config file directly, bypassing --set.")
|
print(clr["tdyl"]+"--config"+clr["norm"]+" - Edit config file directly, bypassing --set.")
|
||||||
print(clr["tdyl"]+"--folder"+clr["norm"]+" - Open the folder of the website's data.")
|
print(clr["tdyl"]+"--folder"+clr["norm"]+" - Open the folder of the website's data.")
|
||||||
|
print()
|
||||||
print(clr["tdyl"]+"--transfer"+clr["norm"]+"- Transfers legacy website data to the new format.")
|
print(clr["tdyl"]+"--transfer"+clr["norm"]+"- Transfers legacy website data to the new format.")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
@ -32,3 +36,15 @@ def Set():
|
||||||
print(clr["tdyl"]+"--add_tab"+clr["norm"]+" - Adds a category of articles.")
|
print(clr["tdyl"]+"--add_tab"+clr["norm"]+" - Adds a category of articles.")
|
||||||
print(clr["tdyl"]+"--edit_tab"+clr["norm"]+" - Edit the config of a category.")
|
print(clr["tdyl"]+"--edit_tab"+clr["norm"]+" - Edit the config of a category.")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
def Accounts():
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(clr["bold"]+" BDServer Account Help "+clr["norm"])
|
||||||
|
print()
|
||||||
|
print(" Account is used to manage website's accounts.")
|
||||||
|
print()
|
||||||
|
print(clr["tdyl"]+"--add"+clr["norm"]+" - Add a new account.")
|
||||||
|
print(clr["tdyl"]+"--list"+clr["norm"]+" - List accounts.")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,13 @@ def Transfer(location):
|
||||||
|
|
||||||
account = accounts[username]
|
account = accounts[username]
|
||||||
|
|
||||||
|
# We are updating the invites
|
||||||
|
invite_codes = account.pop("invite_codes")
|
||||||
|
account["invite_codes"] = {}
|
||||||
|
|
||||||
|
for code in invite_codes:
|
||||||
|
account["invite_codes"][code] = "Unknown"
|
||||||
|
|
||||||
# We are adding some new stuff to accounts
|
# We are adding some new stuff to accounts
|
||||||
|
|
||||||
account["title"] = username # Visible title
|
account["title"] = username # Visible title
|
||||||
|
|
|
@ -138,6 +138,22 @@ def moderates(moderator, user):
|
||||||
|
|
||||||
if moderator == user:
|
if moderator == user:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
if rank(moderator, Accounts) < rank(user, Accounts):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def rank(account, Accounts=None):
|
||||||
|
|
||||||
|
if not Accounts:
|
||||||
|
Accounts = accounts()
|
||||||
|
|
||||||
|
if account not in Accounts:
|
||||||
|
return 1000000
|
||||||
|
|
||||||
|
if not Accounts[account].get("invited_by") or Accounts[account].get("invited_by") == account:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return 1 + rank(Accounts[account].get("invited_by"), Accounts)
|
||||||
|
|
||||||
def articles(tab):
|
def articles(tab):
|
||||||
|
|
||||||
|
@ -530,8 +546,16 @@ def AccountPage(server, account):
|
||||||
html = html + '<div class="middle_section_article">'
|
html = html + '<div class="middle_section_article">'
|
||||||
|
|
||||||
html = html + '<div class="dark_box">'
|
html = html + '<div class="dark_box">'
|
||||||
html = html +"<center><h1>"+Accounts.get(account, {}).get("title", account)+"</h1></center>"
|
html = html +"<center><h1>"+Accounts.get(account, {}).get("title", account)+"</h1>"
|
||||||
|
|
||||||
|
# Rank
|
||||||
|
|
||||||
|
Rank = rank(account)
|
||||||
|
html = html + Button("Rank "+str(Rank), "", icon="analytics")
|
||||||
|
|
||||||
|
|
||||||
|
html = html + '</center>'
|
||||||
|
|
||||||
# Website
|
# Website
|
||||||
|
|
||||||
website = Safe(Accounts.get(account, {}).get("website" , ""))
|
website = Safe(Accounts.get(account, {}).get("website" , ""))
|
||||||
|
@ -561,16 +585,19 @@ def AccountPage(server, account):
|
||||||
if mastodon:
|
if mastodon:
|
||||||
|
|
||||||
# It could be mastodon url and not handle.
|
# It could be mastodon url and not handle.
|
||||||
if "/" in mastodon:
|
try:
|
||||||
mastodon = mastodon.replace("https://", "").replace("http://", "")
|
if "/" in mastodon:
|
||||||
mastodon = mastodon.split("/")[1]+"@"+mastodon.split("/")[0]
|
mastodon = mastodon.replace("https://", "").replace("http://", "")
|
||||||
|
mastodon = mastodon.split("/")[1]+"@"+mastodon.split("/")[0]
|
||||||
|
|
||||||
mastolink = "https://"+mastodon[1:].split("@")[1]+"/@"+mastodon[1:].split("@")[0]
|
mastolink = "https://"+mastodon[1:].split("@")[1]+"/@"+mastodon[1:].split("@")[0]
|
||||||
|
|
||||||
html = html + '<center>'
|
html = html + '<center>'
|
||||||
html = html + '<img style="vertical-align: middle" src="/icon/mastodon">'
|
html = html + '<img style="vertical-align: middle" src="/icon/mastodon">'
|
||||||
html = html + '<a href="'+mastolink+'"> '+mastodon+'</a>'
|
html = html + '<a href="'+mastolink+'"> '+mastodon+'</a>'
|
||||||
html = html + '</center>'
|
html = html + '</center>'
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
# Matrix
|
# Matrix
|
||||||
|
|
||||||
|
@ -593,11 +620,11 @@ def AccountPage(server, account):
|
||||||
|
|
||||||
html = html + '</div>'
|
html = html + '</div>'
|
||||||
|
|
||||||
html = html + '<div class="dark_box">'
|
invited_by = Accounts.get(account, {}).get("invited_by", "")
|
||||||
html = html +"<center>Invited by:<br>"+User(Accounts.get(account, {}).get("invited_by", account))+"</center>"
|
if invited_by:
|
||||||
|
html = html + '<div class="dark_box">'
|
||||||
|
html = html +"<center>Invited by:<br>"+User(invited_by)+"</center>"
|
||||||
html = html + '</div>'
|
html = html + '</div>'
|
||||||
|
|
||||||
bio = Safe(Accounts.get(account, {}).get("bio" , ""))
|
bio = Safe(Accounts.get(account, {}).get("bio" , ""))
|
||||||
if bio:
|
if bio:
|
||||||
|
@ -670,13 +697,17 @@ def LoginPage(server):
|
||||||
|
|
||||||
html = html + """
|
html = html + """
|
||||||
|
|
||||||
|
<div class="middle_section_article">
|
||||||
|
|
||||||
|
<div class="dark_box">
|
||||||
|
|
||||||
<form action="do_login">
|
<form action="do_login">
|
||||||
|
|
||||||
<img style="vertical-align: middle" src="/icon/user">
|
<img style="vertical-align: middle" src="/icon/user">
|
||||||
<input class="button" style="width:36.5%" maxlength="500" id="user_name" required="" name="user_name" pattern="[A-Za-z0-9]*" placeholder="Username..."></input>
|
<input class="button" style="width:90%" maxlength="500" id="user_name" required="" name="user_name" pattern="[A-Za-z0-9\.\-\_\]*" placeholder="Username..."></input>
|
||||||
<br>
|
<br>
|
||||||
<img style="vertical-align: middle" src="/icon/lock">
|
<img style="vertical-align: middle" src="/icon/lock">
|
||||||
<input class="button" style="width:36.5%" maxlength="500" id="password" type="password" required="" name="password" placeholder="Password..."></input><br>
|
<input class="button" style="width:90%" maxlength="500" id="password" type="password" required="" name="password" placeholder="Password..."></input><br>
|
||||||
|
|
||||||
<button class="button" type="submit">
|
<button class="button" type="submit">
|
||||||
<img style="vertical-align: middle" src="/icon/unlock">
|
<img style="vertical-align: middle" src="/icon/unlock">
|
||||||
|
@ -685,20 +716,123 @@ def LoginPage(server):
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<br>
|
</div></div>
|
||||||
|
|
||||||
Don't have an account? <a href="/register">Register</a>.
|
<div class="checklist_section_article">
|
||||||
|
|
||||||
|
<div class="dark_box">
|
||||||
|
|
||||||
|
Don't have an account? <br>
|
||||||
"""
|
"""
|
||||||
|
html = html + Button("Register", "/register", icon="user_new")
|
||||||
|
|
||||||
|
|
||||||
|
send(server, html, 200)
|
||||||
|
|
||||||
html = html + '</center>'
|
def RegisterPage(server):
|
||||||
|
|
||||||
|
user = validate(server.cookie)
|
||||||
|
|
||||||
|
config = Set.Load()
|
||||||
|
Accounts = accounts()
|
||||||
|
f = Set.Folder()
|
||||||
|
|
||||||
|
code = server.parsed.get("code", [""])[0]
|
||||||
|
userexists = server.parsed.get("userexists", [""])[0]
|
||||||
|
wrongcode = server.parsed.get("wrongcode", [""])[0]
|
||||||
|
|
||||||
|
# Generating <head>
|
||||||
|
html = head(title = "Login",
|
||||||
|
description = "Login",
|
||||||
|
config = config
|
||||||
|
)
|
||||||
|
|
||||||
|
html = html + Button(config.get("title", "My Website"), "/", image=config.get("favicon", "/icon/internet"))
|
||||||
|
|
||||||
|
html = html + '<center>'
|
||||||
|
|
||||||
|
|
||||||
|
html = html + """
|
||||||
|
|
||||||
|
<div class="middle_section_article">
|
||||||
|
|
||||||
|
<div class="dark_box">
|
||||||
|
|
||||||
|
<form action="do_register">
|
||||||
|
"""
|
||||||
|
|
||||||
|
if wrongcode:
|
||||||
|
html = html + "Invalid Invite Code.<br><br>"
|
||||||
|
|
||||||
|
if not code and not user:
|
||||||
|
html = html + """
|
||||||
|
|
||||||
|
<img style="vertical-align: middle" src="/icon/user_link">
|
||||||
|
<input class="button" style="width:90%" maxlength="500" id="code" required="" name="code" placeholder="Invite code..."></input>
|
||||||
|
|
||||||
|
"""
|
||||||
|
username = ""
|
||||||
|
|
||||||
|
else:
|
||||||
|
for account in Accounts:
|
||||||
|
if code in Accounts[account].get("invite_codes", []):
|
||||||
|
username = Simplify(Accounts[account]["invite_codes"][code], "file")
|
||||||
|
|
||||||
|
html = html + '<center>Invited by:<br><br>'
|
||||||
|
html = html + User(account)+'<br>'
|
||||||
|
html = html + '<input type="hidden" name="code" value="'+code+'">'
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
|
||||||
|
|
||||||
|
if userexists:
|
||||||
|
html = html + "Username is taken.<br><br>"
|
||||||
|
|
||||||
|
html = html + """<img style="vertical-align: middle" src="/icon/user">
|
||||||
|
<input class="button" style="width:90%" maxlength="500" id="user_name" required="" name="user_name" pattern="[A-Za-z0-9\.\-\_\]*" placeholder="Username..." value=\""""+username+""""></input>
|
||||||
|
<br>
|
||||||
|
<img style="vertical-align: middle" src="/icon/lock">
|
||||||
|
<input class="button" style="width:90%" maxlength="500" id="password" type="password" required="" name="password" placeholder="Password..."></input><br>
|
||||||
|
|
||||||
|
<button class="button" type="submit">
|
||||||
|
<img style="vertical-align: middle" src="/icon/user_new">
|
||||||
|
Register
|
||||||
|
</button>
|
||||||
|
"""
|
||||||
|
|
||||||
|
elif code:
|
||||||
|
html = html + "Share this page with those you invited."
|
||||||
|
|
||||||
|
else:
|
||||||
|
html = html + "<br>You already registered and logged in."
|
||||||
|
|
||||||
|
html = html + """
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<div class="checklist_section_article">
|
||||||
|
|
||||||
|
<div class="dark_box">
|
||||||
|
|
||||||
|
Have an account? <br>
|
||||||
|
"""
|
||||||
|
html = html + Button("Login", "/login", icon="unlock")
|
||||||
|
|
||||||
|
|
||||||
send(server, html, 200)
|
send(server, html, 200)
|
||||||
|
|
||||||
def SettingsPage(server):
|
def SettingsPage(server):
|
||||||
|
|
||||||
user = validate(server.cookie)
|
user = validate(server.cookie)
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
Redirect(server, "/login")
|
||||||
|
return
|
||||||
|
|
||||||
config = Set.Load()
|
config = Set.Load()
|
||||||
|
|
||||||
# Generating <head>
|
# Generating <head>
|
||||||
|
@ -757,12 +891,71 @@ def SettingsPage(server):
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Current Logged in Sessions
|
||||||
|
|
||||||
|
sessions = user.get("sessions", {})
|
||||||
|
|
||||||
|
html = html + '<div class="dark_box" id="sessions">'
|
||||||
|
html = html + '<center><h2>Active Sessions</h2>'
|
||||||
|
|
||||||
|
for cookie in sessions:
|
||||||
|
|
||||||
|
session = sessions[cookie]
|
||||||
|
|
||||||
|
CancelButton = Button("Log Out", "/log_out?cookie="+cookie, icon="cancel")
|
||||||
|
if server.cookie == cookie:
|
||||||
|
html = html + '<br><img title="This Session" style="vertical-align: middle" src="/icon/checked">'
|
||||||
|
else:
|
||||||
|
html = html + '<br><img title="Other Browser" style="vertical-align: middle" src="/icon/unchecked">'
|
||||||
|
html = html + '<input class="button" style="width:50%" value="' + session + '">'+CancelButton
|
||||||
|
|
||||||
|
html = html + '<br><br>'
|
||||||
|
html = html + '</center>'
|
||||||
|
html = html + '</div>'
|
||||||
|
|
||||||
|
# Invites and Invite codes
|
||||||
|
|
||||||
|
invite_codes = user.get("invite_codes", {})
|
||||||
|
|
||||||
|
html = html + '<div class="dark_box" id="invites">'
|
||||||
|
html = html + '<center><h2>Invites</h2></center>'
|
||||||
|
|
||||||
|
for code in invite_codes:
|
||||||
|
|
||||||
|
nick = invite_codes[code]
|
||||||
|
|
||||||
|
Open = ""
|
||||||
|
if code == server.parsed.get("code", [""])[0]:
|
||||||
|
Open = "open"
|
||||||
|
|
||||||
|
html = html + '<details '+Open+' class="dark_box"><summary id="invite_'+code+'" class="button">'
|
||||||
|
html = html + '<img style="vertical-align: middle" src="/icon/user">'+nick
|
||||||
|
html = html + '</summary><br>'
|
||||||
|
html = html + '<img style="vertical-align: middle" src="/icon/user_link">'
|
||||||
|
html = html + '<input class="button" style="width:90%" value="' + code + '">'
|
||||||
|
html = html + Button("Share Link", "/register?code="+code, icon="link")
|
||||||
|
html = html + Button("Cancel", "/cancel_invite?code="+code, icon="cancel")
|
||||||
|
html = html + '</details>'
|
||||||
|
|
||||||
|
html = html + """
|
||||||
|
|
||||||
|
<form action="/create_invite">
|
||||||
|
|
||||||
|
<input name="nick" class="button" required="" style="width:50%" placeholder="Name of the person you invite">
|
||||||
|
|
||||||
|
<button class="button" type="submit">
|
||||||
|
<img style="vertical-align: middle" src="/icon/user_new">
|
||||||
|
Invite
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
send(server, html, 200)
|
send(server, html, 200)
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
|
@ -1078,7 +1271,7 @@ def LoginButton(server):
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
html = html + '<a class="button" href="/login">'
|
html = html + '<a class="button" href="/login">'
|
||||||
html = html + '<img style="vertical-align: middle" src="/icon/user"> Login'
|
html = html + '<img style="vertical-align: middle" src="/icon/unlock"> Login'
|
||||||
html = html + '</a>'
|
html = html + '</a>'
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -1161,10 +1354,109 @@ def Login(server):
|
||||||
|
|
||||||
Redirect(server, "/")
|
Redirect(server, "/")
|
||||||
|
|
||||||
|
def Register(server):
|
||||||
|
|
||||||
|
# If by mistake we are logged in
|
||||||
|
user = validate(server.cookie)
|
||||||
|
if user:
|
||||||
|
Redirect(server, "/register")
|
||||||
|
|
||||||
|
username = Simplify(server.parsed.get("user_name", [""])[0], "file")
|
||||||
|
code = server.parsed.get("code", [""])[0]
|
||||||
|
password = server.parsed.get("password" , [""])[0]
|
||||||
|
hashed = hashlib.sha512(password.encode("utf-8")).hexdigest()
|
||||||
|
|
||||||
|
Accounts = accounts()
|
||||||
|
|
||||||
|
# We avoid username swappage
|
||||||
|
if username in Accounts or not username:
|
||||||
|
if code:
|
||||||
|
Redirect(server, "/register?code="+code+"&userexists=True#user_name")
|
||||||
|
else:
|
||||||
|
Redirect(server, "/register?userexists=True#user_name")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Validating the invite code
|
||||||
|
|
||||||
|
invited_by = ""
|
||||||
|
for account in Accounts:
|
||||||
|
if code in Accounts[account].get("invite_codes", []):
|
||||||
|
invited_by = account
|
||||||
|
break
|
||||||
|
|
||||||
|
if not invited_by:
|
||||||
|
Redirect(server, "/register?wrongcode=True")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Now we can finally make our account.
|
||||||
|
|
||||||
|
# New account first
|
||||||
|
account = {
|
||||||
|
"username":username,
|
||||||
|
"bio":"",
|
||||||
|
"invite_codes":{},
|
||||||
|
"invited":[],
|
||||||
|
"invited_by":invited_by,
|
||||||
|
"password":hashed,
|
||||||
|
"title":username,
|
||||||
|
"email":"",
|
||||||
|
"website":"",
|
||||||
|
"mastodon":"",
|
||||||
|
"matrix":"",
|
||||||
|
"sessions":{
|
||||||
|
server.cookie:server.headers.get("User-Agent")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f = Set.Folder()
|
||||||
|
folder = f+"/accounts"
|
||||||
|
|
||||||
|
with open(folder+"/"+username+".json", "w") as save:
|
||||||
|
json.dump(account, save, indent=4)
|
||||||
|
|
||||||
|
# Now the invitor changes
|
||||||
|
|
||||||
|
account = Accounts[invited_by]
|
||||||
|
del account["invite_codes"][code]
|
||||||
|
account["invited"].append(username)
|
||||||
|
|
||||||
|
with open(folder+"/"+account.get("username", "")+".json", "w") as save:
|
||||||
|
json.dump(account, save, indent=4)
|
||||||
|
|
||||||
|
Redirect(server, "/settings")
|
||||||
|
|
||||||
|
def LogOut(server):
|
||||||
|
|
||||||
|
user = validate(server.cookie)
|
||||||
|
cookie = server.parsed.get("cookie", [""])[0]
|
||||||
|
|
||||||
|
# This might be an attack. So we don't want that.
|
||||||
|
if cookie not in user.get("sessions",{}):
|
||||||
|
Redirect(server, "/")
|
||||||
|
return
|
||||||
|
|
||||||
|
del user["sessions"][cookie]
|
||||||
|
|
||||||
|
f = Set.Folder()
|
||||||
|
folder = f+"/accounts"
|
||||||
|
with open(folder+"/"+user.get("username", "")+".json", "w") as save:
|
||||||
|
json.dump(user, save, indent=4)
|
||||||
|
|
||||||
|
# If the user logged out this session
|
||||||
|
if cookie == server.cookie:
|
||||||
|
Redirect(server, "/")
|
||||||
|
|
||||||
|
else:
|
||||||
|
Redirect(server, "/settings#sessions")
|
||||||
|
|
||||||
|
|
||||||
def UpdateAccount(server):
|
def UpdateAccount(server):
|
||||||
|
|
||||||
user = validate(server.cookie)
|
user = validate(server.cookie)
|
||||||
|
if not user:
|
||||||
|
Redirect(server, "/login")
|
||||||
|
return
|
||||||
|
|
||||||
keys = [
|
keys = [
|
||||||
"title",
|
"title",
|
||||||
"avatar",
|
"avatar",
|
||||||
|
@ -1259,6 +1551,14 @@ def DoComment(server):
|
||||||
else:
|
else:
|
||||||
number = int(number)
|
number = int(number)
|
||||||
if moderates(user.get("username"), article["comments"]["comments"][number]["username"]):
|
if moderates(user.get("username"), article["comments"]["comments"][number]["username"]):
|
||||||
|
|
||||||
|
# Making sure moderators done get credit for small edits
|
||||||
|
# in comments.
|
||||||
|
|
||||||
|
originalcommet = article["comments"]["comments"][number]
|
||||||
|
if originalcommet.get("username") in Accounts:
|
||||||
|
comment["username"] = originalcommet["username"]
|
||||||
|
|
||||||
article["comments"]["comments"][number] = comment
|
article["comments"]["comments"][number] = comment
|
||||||
|
|
||||||
|
|
||||||
|
@ -1311,3 +1611,36 @@ def DeleteComment(server):
|
||||||
redirect = "#comments"
|
redirect = "#comments"
|
||||||
|
|
||||||
Redirect(server, url+redirect)
|
Redirect(server, url+redirect)
|
||||||
|
|
||||||
|
def CancelInvite(server):
|
||||||
|
|
||||||
|
user = validate(server.cookie)
|
||||||
|
code = server.parsed.get("code", [""])[0]
|
||||||
|
if user:
|
||||||
|
del user["invite_codes"][code]
|
||||||
|
f = Set.Folder()
|
||||||
|
folder = f+"/accounts"
|
||||||
|
with open(folder+"/"+user.get("username", "")+".json", "w") as save:
|
||||||
|
json.dump(user, save, indent=4)
|
||||||
|
Redirect(server, "/settings#invites")
|
||||||
|
|
||||||
|
else:
|
||||||
|
Redirect(server, "/")
|
||||||
|
|
||||||
|
def CreateInvite(server):
|
||||||
|
|
||||||
|
user = validate(server.cookie)
|
||||||
|
nick = server.parsed.get("nick", [""])[0]
|
||||||
|
if not nick: nick = "Unknown"
|
||||||
|
code = RandString()
|
||||||
|
if user:
|
||||||
|
user["invite_codes"][code] = nick
|
||||||
|
|
||||||
|
f = Set.Folder()
|
||||||
|
folder = f+"/accounts"
|
||||||
|
with open(folder+"/"+user.get("username", "")+".json", "w") as save:
|
||||||
|
json.dump(user, save, indent=4)
|
||||||
|
Redirect(server, "/settings?code="+code+"#invite_"+code)
|
||||||
|
|
||||||
|
else:
|
||||||
|
Redirect(server, "/")
|
||||||
|
|
|
@ -74,6 +74,9 @@ class handler(BaseHTTPRequestHandler):
|
||||||
elif self.path[1:].startswith("login"):
|
elif self.path[1:].startswith("login"):
|
||||||
Render.LoginPage(self)
|
Render.LoginPage(self)
|
||||||
|
|
||||||
|
elif self.path[1:].startswith("register"):
|
||||||
|
Render.RegisterPage(self)
|
||||||
|
|
||||||
elif self.path[1:].startswith("settings"):
|
elif self.path[1:].startswith("settings"):
|
||||||
Render.SettingsPage(self)
|
Render.SettingsPage(self)
|
||||||
|
|
||||||
|
@ -86,9 +89,21 @@ class handler(BaseHTTPRequestHandler):
|
||||||
elif self.path[1:].startswith("update_account"):
|
elif self.path[1:].startswith("update_account"):
|
||||||
Render.UpdateAccount(self)
|
Render.UpdateAccount(self)
|
||||||
|
|
||||||
|
elif self.path[1:].startswith("create_invite"):
|
||||||
|
Render.CreateInvite(self)
|
||||||
|
|
||||||
|
elif self.path[1:].startswith("cancel_invite"):
|
||||||
|
Render.CancelInvite(self)
|
||||||
|
|
||||||
|
elif self.path[1:].startswith("log_out"):
|
||||||
|
Render.LogOut(self)
|
||||||
|
|
||||||
elif self.path[1:].startswith("do_login"):
|
elif self.path[1:].startswith("do_login"):
|
||||||
Render.Login(self)
|
Render.Login(self)
|
||||||
|
|
||||||
|
elif self.path[1:].startswith("do_register"):
|
||||||
|
Render.Register(self)
|
||||||
|
|
||||||
elif self.path.startswith("/graph/"):
|
elif self.path.startswith("/graph/"):
|
||||||
url = self.path[6:]
|
url = self.path[6:]
|
||||||
if "?" in url: url = url[:url.find("?")]
|
if "?" in url: url = url[:url.find("?")]
|
||||||
|
|
|
@ -45,7 +45,7 @@ def Save(data):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(Folder()+"/config.json", "w") as save:
|
with open(Folder()+"/config.json", "w") as save:
|
||||||
json.dump(data, save, indent=4, sort_keys=True)
|
json.dump(data, save, indent=4)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Cannot save config!", e)
|
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Cannot save config!", e)
|
||||||
|
@ -221,3 +221,4 @@ def SetFavicon(filename):
|
||||||
Save(config)
|
Save(config)
|
||||||
|
|
||||||
print("New favicon is set at "+clr["bold"]+Folder()+"/pictures/favicon.png"+clr["norm"])
|
print("New favicon is set at "+clr["bold"]+Folder()+"/pictures/favicon.png"+clr["norm"])
|
||||||
|
|
||||||
|
|
4
run.py
4
run.py
|
@ -15,6 +15,10 @@ elif "--set" in sys.argv:
|
||||||
from modules import Set
|
from modules import Set
|
||||||
Set.Set()
|
Set.Set()
|
||||||
|
|
||||||
|
elif "--account" in sys.argv:
|
||||||
|
from modules import Account
|
||||||
|
Account.Account()
|
||||||
|
|
||||||
elif "--config" in sys.argv:
|
elif "--config" in sys.argv:
|
||||||
from modules import Set
|
from modules import Set
|
||||||
data = Set.Load() # Making sure
|
data = Set.Load() # Making sure
|
||||||
|
|
Loading…
Add table
Reference in a new issue