Notifications

This commit is contained in:
BlenderDumbass 2024-11-25 23:01:02 +02:00
parent 97610443a3
commit 6268f6b9d2
2 changed files with 191 additions and 8 deletions

View file

@ -359,8 +359,6 @@ def ListPage(server, tab):
<div class="flexity"> <div class="flexity">
""" """
print(page)
rendered = 0 rendered = 0
@ -826,8 +824,9 @@ def SettingsPage(server):
user = validate(server.cookie) user = validate(server.cookie)
# Authorization check
if not user: if not user:
Redirect(server, "/login") AccessDenied(server)
return return
config = Set.Load() config = Set.Load()
@ -948,9 +947,26 @@ def SettingsPage(server):
</button> </button>
</form> </form>
</div>
</div>
""" """
notifications = user.get("notifications","")
if notifications:
html = html + '<div class="checklist_section_article">'
for notification in notifications:
html = html + '<div class="article_box">'
html = html + '<br><a href="/read_notification?code='+notification.get("code", "")+'">'
html = html + notification.get("text", "Notification")
html = html + '</a><br><br>'
html = html + '</div>'
send(server, html, 200) send(server, html, 200)
@ -1080,7 +1096,6 @@ def Graph(server, url):
enddate = datetime.strptime(sorted(list(dates.keys()), reverse=True)[-1], dateformat) enddate = datetime.strptime(sorted(list(dates.keys()), reverse=True)[-1], dateformat)
alldays = int((startdate - enddate).days) alldays = int((startdate - enddate).days)
print(alldays)
for n, date in enumerate(sorted(dates, reverse=True)): for n, date in enumerate(sorted(dates, reverse=True)):
@ -1272,11 +1287,18 @@ def LoginButton(server):
html = html + '</a>' html = html + '</a>'
else: else:
notifications = len(user.get("notifications", []))
sup = ""
if notifications:
sup = '<sup>'+str(notifications)+'</sup>'
html = html + '<a class="button" href="/settings">' html = html + '<a class="button" href="/settings">'
avatar = Safe(user.get("avatar", "")) avatar = Safe(user.get("avatar", ""))
if not avatar: avatar = "/pictures/monkey.png" if not avatar: avatar = "/pictures/monkey.png"
html = html + '<img style="height:40px;vertical-align: middle" src="'+avatar+'"> ' html = html + '<img style="height:40px;vertical-align: middle" src="'+avatar+'"> '
html = html + user.get("title", user.get("username", "Anonymous")) html = html + user.get("title", user.get("username", "Anonymous"))
html = html + sup
html = html + '</a>' html = html + '</a>'
html = html + '</div>' html = html + '</div>'
@ -1284,6 +1306,51 @@ def LoginButton(server):
return html return html
def NotFound(server):
config = Set.Load()
html = head(title = "404 Not Found",
description = "404 Not Found",
config = config
)
html = html + Button(config.get("title", "My Website"), "/", image=config.get("favicon", "/icon/internet"))
html = html + """
<center>
<div class="article_box">
<h1>404 Not Found</h1>
</center>
"""
send(server, html, 404)
def AccessDenied(server):
config = Set.Load()
html = head(title = "403 Access Denied",
description = "403 Access Denied",
config = config
)
html = html + Button(config.get("title", "My Website"), "/", image=config.get("favicon", "/icon/internet"))
html = html + """
<center>
<div class="article_box">
<h1>403 Access Denied</h1>
</center>
"""
send(server, html, 404)
### ###
def Redirect(server, url): def Redirect(server, url):
@ -1421,10 +1488,19 @@ def Register(server):
json.dump(account, save, indent=4) json.dump(account, save, indent=4)
Redirect(server, "/settings") Redirect(server, "/settings")
# Notification
Notify(invited_by, "/account/"+Safe(username), "@"+Safe(username)+" has registered from your invitation.")
def LogOut(server): def LogOut(server):
user = validate(server.cookie) user = validate(server.cookie)
# Authorization check
if not user:
AccessDenied(server)
return
cookie = server.parsed.get("cookie", [""])[0] cookie = server.parsed.get("cookie", [""])[0]
# This might be an attack. So we don't want that. # This might be an attack. So we don't want that.
@ -1450,8 +1526,10 @@ def LogOut(server):
def UpdateAccount(server): def UpdateAccount(server):
user = validate(server.cookie) user = validate(server.cookie)
# Authorization check
if not user: if not user:
Redirect(server, "/login") AccessDenied(server)
return return
keys = [ keys = [
@ -1489,6 +1567,8 @@ def DoComment(server):
number = server.parsed.get("number", [""])[0] number = server.parsed.get("number", [""])[0]
request = server.parsed.get("request", [""])[0] request = server.parsed.get("request", [""])[0]
wasnumber = number
metadata = Set.Folder()+"/tabs"+url+"/metadata.json" metadata = Set.Folder()+"/tabs"+url+"/metadata.json"
try: try:
@ -1568,13 +1648,41 @@ def DoComment(server):
if not number: if not number:
placeRedirect = "#comments" placeRedirect = "#comments"
number = "" number = ""
Redirect(server, url+placeRedirect+str(number)) Redirect(server, url+placeRedirect+str(number))
if not wasnumber:
# Notification
username = user.get("username", nick)
if username != article.get("author"):
Notify(article.get("author"), url+placeRedirect+str(number), "@"+Safe(username)+" commented: <br><br> <b>"+article.get("title", "")+"</b><br><br><i>"+Safe(text[:200])+"</i>")
# Mention notifications
searchText = text.lower()
for account in Accounts:
# The author already got the notification.
if account == article.get("author"):
continue
name = Accounts[account].get("title", account)
if account.lower() in searchText or name.lower() in searchText:
Notify(account,
url+placeRedirect+str(number),
"@"+Safe(username)+" mentioned you: <br><br> <b>"+article.get("title", "")+"</b><br><br><i>"+Safe(text[:200])+"</i>")
def DeleteComment(server): def DeleteComment(server):
user = validate(server.cookie) user = validate(server.cookie)
# Authorization check
if not user:
AccessDenied(server)
return
url = server.parsed.get("url", ["/"])[0] url = server.parsed.get("url", ["/"])[0]
if not url.startswith("/"): url = "/" + url if not url.startswith("/"): url = "/" + url
@ -1612,6 +1720,12 @@ def DeleteComment(server):
def CancelInvite(server): def CancelInvite(server):
user = validate(server.cookie) user = validate(server.cookie)
# Authorization check
if not user:
AccessDenied(server)
return
code = server.parsed.get("code", [""])[0] code = server.parsed.get("code", [""])[0]
if user: if user:
del user["invite_codes"][code] del user["invite_codes"][code]
@ -1627,6 +1741,12 @@ def CancelInvite(server):
def CreateInvite(server): def CreateInvite(server):
user = validate(server.cookie) user = validate(server.cookie)
# Authorization check
if not user:
AccessDenied(server)
return
nick = server.parsed.get("nick", [""])[0] nick = server.parsed.get("nick", [""])[0]
if not nick: nick = "Unknown" if not nick: nick = "Unknown"
code = RandString() code = RandString()
@ -1641,3 +1761,62 @@ def CreateInvite(server):
else: else:
Redirect(server, "/") Redirect(server, "/")
def Notify(username, link, text):
Accounts = accounts()
try:
account = Accounts[username]
if "notifications" not in account:
account["notifications"] = []
notification = {
"link":link,
"text":text,
"code":RandString(20)
}
account["notifications"].append(notification)
f = Set.Folder()
folder = f+"/accounts"
with open(folder+"/"+account.get("username", "")+".json", "w") as save:
json.dump(account, save, indent=4)
except Exception as e:
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Unable to set notification!", e, link, text)
def ReadNotification(server):
user = validate(server.cookie)
# Authorization check
if not user:
AccessDenied(server)
return
code = server.parsed.get("code", [""])[0]
try:
# Apparently I'm stupid to use a link here.
# But I already commited to it and I'm editing
# on a live server. So here we go... O.o
for n, notification in enumerate(user.get("notifications")):
if notification.get("code") == code:
break
n = user["notifications"].pop(n)
f = Set.Folder()
folder = f+"/accounts"
with open(folder+"/"+user.get("username", "")+".json", "w") as save:
json.dump(user, save, indent=4)
Redirect(server, n.get("link", "/"))
except Exception as e:
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Unable to read notification!", e)

View file

@ -105,6 +105,10 @@ class handler(BaseHTTPRequestHandler):
elif self.path[1:].startswith("do_register"): elif self.path[1:].startswith("do_register"):
Render.Register(self) Render.Register(self)
elif self.path[1:].startswith("read_notification"):
Render.ReadNotification(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("?")]
@ -137,7 +141,7 @@ class handler(BaseHTTPRequestHandler):
self.wfile.write(f) self.wfile.write(f)
else: else:
Render.Redirect(self, "/") Render.NotFound(self)
config = Set.Load() config = Set.Load()
PORT = config.get("port", 8080) PORT = config.get("port", 8080)