API petitions, sign petitions by subscribing to mastodon and such

This commit is contained in:
BlenderDumbass 2024-12-05 15:54:16 +02:00
parent 6cd369b043
commit 7750afc5b9
3 changed files with 232 additions and 38 deletions

50
modules/API.py Normal file
View file

@ -0,0 +1,50 @@
# AGPL 3 or any later version
# (C) J.Y.Amihud ( Blender Dumbass )
import os
import json
import time
import email
import random
import hashlib
import urllib.parse
import urllib.request
from datetime import datetime
from modules import Set
from modules.Common import *
def Get(url, data=None, headers={}):
if data:
data = json.dumps(data).encode("utf-8")
req = urllib.request.Request(url, data=data, headers=headers)
f = urllib.request.urlopen(req, timeout=10)
data = json.loads(f.read().decode('utf-8'))
return data
def Value(url, keys):
data = Get(url)
for key in keys:
data = data[key]
return data
def Petition(article):
petition = article.get("petition", {})
api = petition.get("api", {})
timestamp = api.get("timestamp",0)
# 5 minutes delay
if time.time() - 300 < timestamp:
return
value = int(Value(api.get("api", ""), api.get("keys", [])))
article["petition"]["api"]["timestamp"] = time.time()
article["petition"]["signed"] = value
f = Set.Folder()
with open(f+"/tabs"+article.get("url", "")+"/metadata.json", "w") as save:
json.dump(article, save, indent=4)

View file

@ -118,14 +118,12 @@ def VerifyPage(server):
# If we recieved the code. # If we recieved the code.
if code not in verifying: if code not in verifying:
print("code not in verifying") Render.Error(server, "Wrong Code!")
Render.AccessDenied(server)
return return
if verifying[code] != user.get("email"): if verifying[code] != user.get("email"):
print("email wrong") Render.Error(server, "Wrong Code!")
Render.AccessDenied(server)
return return
user["email_verified"] = True user["email_verified"] = True
@ -165,7 +163,7 @@ def SignPetition(server):
email = server.parsed.get("email", [""])[0] email = server.parsed.get("email", [""])[0]
if email in Article.get("petition", {}).get("signatures", []): if email in Article.get("petition", {}).get("signatures", []):
Render.AccessDenied(server) Render.Error(server, "You already signed!")
return return
if not code: if not code:
@ -222,8 +220,7 @@ def SignPetition(server):
# If we recieved the code. # If we recieved the code.
if code not in verifying: if code not in verifying:
print("code not in verifying") Render.Error(server, "Wrong Code!")
Render.AccessDenied(server)
return return

View file

@ -12,6 +12,7 @@ import urllib.parse
from datetime import datetime from datetime import datetime
from modules import Set from modules import Set
from modules import API
from modules import markdown from modules import markdown
from modules.Common import * from modules.Common import *
@ -571,8 +572,16 @@ def ArticlePage(server, url):
petition = Articles.get(article, {}).get("petition", "") petition = Articles.get(article, {}).get("petition", "")
if petition: if petition:
petition_error = False
if petition.get("api"):
try:
API.Petition(Articles[article])
except:
petition_error = True
html = html + '<div class="dark_box"> <center>' html = html + '<div class="dark_box"> <center>'
html = html + '<h2><img alt="[icon petition]" style="vertical-align: middle" src="/icon/petition">' html = html + '<h2>'
html = html + 'Petition</h2></center>' html = html + 'Petition</h2></center>'
try: try:
@ -583,29 +592,61 @@ def ArticlePage(server, url):
html = html + ProgressBar(frac) html = html + ProgressBar(frac)
html = html + "<br><center>"+str(petition.get("signed", 0))+" / "+Safe(str(petition.get("goal", 1)))+" Signatures" html = html + "<br><center>"+str(petition.get("signed", 0))+" / "+Safe(str(petition.get("goal", 1)))+" Signatures"
html = html + """ # Last update
if petition.get("api"):
<details>
<summary class="button">
<img alt="[icon petition]" style="vertical-align: middle" src="/icon/petition">
Sign
</summary>
<form action="/sign_petition">
<input type="hidden" name="article" value='/"""+tab+"/"+article+"""'>
<img style="vertical-align: middle" src="/icon/frase">
<input class="button" style="width:90%" required maxlength="200" name="email" placeholder="Email">
<button class="button" type="submit">
<img style="vertical-align: middle" src="/icon/ok">
Submit
</button>
</form> lastUpdate = petition.get("api", {}).get("timestamp", {})
nowTime = time.time()
html = html + '<br><br><small>Last updated: '+TimeDifference(lastUpdate, nowTime)+'</small><br><br>'
</details> if not petition.get("api"):
"""
html = html + """
<details>
<summary class="button">
<img alt="[icon petition]" style="vertical-align: middle" src="/icon/petition">
Sign
</summary>
<form action="/sign_petition">
<input type="hidden" name="article" value='/"""+tab+"/"+article+"""'>
<img style="vertical-align: middle" src="/icon/frase">
<input class="button" style="width:90%" required maxlength="200" name="email" placeholder="Email">
<button class="button" type="submit">
<img style="vertical-align: middle" src="/icon/ok">
Submit
</button>
</form>
</details>
"""
else:
html = html + """
<details>
<summary class="button">
<img alt="[icon petition]" style="vertical-align: middle" src="/icon/petition">
Sign
</summary>
<center>
<br>
This petition is signed by increasing the number of<br>
<i>"""+petition.get("api", {}).get("title", "")+"""</i>
<br><br>
"""+Button("Continue", petition.get("api", {}).get("link", ""), "ok")+"""
</center>
"""
html = html + '</div>' html = html + '</div>'
@ -1395,9 +1436,22 @@ def EditorPage(server):
if rank(user.get("username","")) == 0: if rank(user.get("username","")) == 0:
petition = article.get("petition", {}) petition = article.get("petition", {})
petition_goal = petition.get("goal", 0) petition_goal = petition.get("goal", "")
petition_api = petition.get("api", {}).get("api", "")
petition_api_key = petition.get("api", {}).get("keys", [])
petition_api_title = petition.get("api", {}).get("title", "")
petition_api_link = petition.get("api", {}).get("link", "")
if len(petition_api_key) == 1:
petition_api_key = petition_api_key[0]
else:
key = petition_api_key[0]
for n, i in petition_api_key:
if n != 0:
key = key + "/" + i
petition_api_key = key
html = html + """ html = html + """
@ -1423,19 +1477,19 @@ def EditorPage(server):
<br> <br>
<img alt="[icon link]" style="vertical-align: middle" src="/icon/link"> <img alt="[icon link]" style="vertical-align: middle" src="/icon/link">
<input class="button" style="width:90%" name="petition_api" placeholder="API to check ( should be JSON )"> <input class="button" style="width:90%" name="petition_api" placeholder="API to check ( should be JSON )" value='"""+petition_api+"""'>
<br> <br>
<img alt="[icon checlist]" style="vertical-align: middle" src="/icon/checklist"> <img alt="[icon checlist]" style="vertical-align: middle" src="/icon/checklist">
<input class="button" style="width:90%" name="petition_api_key" placeholder="Key To Look For ( split with / for nested deep data )"> <input class="button" style="width:90%" name="petition_api_key" placeholder="Key To Look For ( split with / for nested deep data )" value='"""+petition_api_key+"""'>
<br> <br>
<img alt="[icon scene]" style="vertical-align: middle" src="/icon/scene"> <img alt="[icon scene]" style="vertical-align: middle" src="/icon/scene">
<input class="button" style="width:90%" name="petition_api_title" placeholder="Statistic's Name"> <input class="button" style="width:90%" name="petition_api_title" placeholder="Statistic's Name" value='"""+petition_api_title+"""'>
<br> <br>
<img alt="[icon link]" style="vertical-align: middle" src="/icon/link"> <img alt="[icon link]" style="vertical-align: middle" src="/icon/link">
<input class="button" style="width:90%" name="petition_api_link" placeholder="Action Link ( where people can increase the number in the API )"> <input class="button" style="width:90%" name="petition_api_link" placeholder="Action Link ( where people can increase the number in the API )" value='"""+petition_api_link+"""'>
<br> <br>
</div> </div>
@ -1928,7 +1982,33 @@ def AccessDenied(server):
send(server, html, 404) send(server, html, 404)
def Error(server, text="Some Error Happened."):
config = Set.Load()
html = head(title = "501 Error",
description = "501 Error",
config = config
)
html = html + Button(config.get("title", "My Website"), "/", image=config.get("favicon", "/icon/internet"))
html = html + """
<center>
<div class="article_box">
<h1>501 Error</h1>
"""+text+"""
<br><br>
</center>
"""
send(server, html, 501)
### ###
def Redirect(server, url, time=0): def Redirect(server, url, time=0):
@ -2475,8 +2555,28 @@ def Publish(server):
petition["goal"] = int(petition_goal) petition["goal"] = int(petition_goal)
except: except:
petition["goal"] = 1 petition["goal"] = 1
# API petition
if petition_api:
petition["api"] = {
"api" :petition_api,
"keys" :petition_api_key.split("/"),
"title":petition_api_title,
"link" :petition_api_link
}
metadata["petition"] = petition
metadata["petition"] = petition
else:
try:
del metadata["petition"]
except:
pass
# Save the changes # Save the changes
@ -2494,7 +2594,16 @@ def Publish(server):
save.write(text) save.write(text)
else: else:
save.write(Safe(text)) save.write(Safe(text))
if metadata.get("petition"):
metadata["url"] = "/"+tab+"/"+name
try:
API.Petition(metadata)
except Exception as e:
Error(server, "Cannot Load API Value<br>\n"+Safe(str(e)))
return
Redirect(server, "/"+tab+"/"+name) Redirect(server, "/"+tab+"/"+name)
@ -2645,7 +2754,45 @@ def ReadNotification(server):
except Exception as e: except Exception as e:
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Unable to read notification!", e) print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Unable to read notification!", e)
def TimeDifference(timeA, timeB):
text = ""
if timeA < timeB:
if timeB - timeA < 10:
text = "now"
return text
elif timeB - timeA < 60:
text = str(int(timeB - timeA))+" seconds ago"
return text
else:
if int( ( timeB - timeA ) / 60 ) == 1:
text = str(int( ( timeB - timeA ) / 60 ))+" minute ago"
else:
text = str(int( ( timeB - timeA ) / 60 ))+" minutes ago"
return text
else:
if timeA - timeA < 10:
text= "now"
return text
elif timeA - timeB < 60:
text = "in "+str(int(timeA - timeB))+" seconds"
return text
else:
if int( ( timeA - timeB ) / 60 ) == 1:
text = "in "+str(int( ( timeA - timeB ) / 60 ))+" minute"
else:
text = "in "+str(int( ( timeA - timeB ) / 60 ))+" minutes"
return text
def RSS(server): def RSS(server):
# Rendering rss feed. # Rendering rss feed.