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

View file

@ -12,6 +12,7 @@ import urllib.parse
from datetime import datetime
from modules import Set
from modules import API
from modules import markdown
from modules.Common import *
@ -571,8 +572,16 @@ def ArticlePage(server, url):
petition = Articles.get(article, {}).get("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 + '<h2><img alt="[icon petition]" style="vertical-align: middle" src="/icon/petition">'
html = html + '<h2>'
html = html + 'Petition</h2></center>'
try:
@ -583,29 +592,61 @@ def ArticlePage(server, url):
html = html + ProgressBar(frac)
html = html + "<br><center>"+str(petition.get("signed", 0))+" / "+Safe(str(petition.get("goal", 1)))+" Signatures"
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>
# Last update
if petition.get("api"):
</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>'
@ -1395,9 +1436,22 @@ def EditorPage(server):
if rank(user.get("username","")) == 0:
petition = article.get("petition", {})
petition_goal = petition.get("goal", 0)
petition = article.get("petition", {})
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 + """
@ -1423,19 +1477,19 @@ def EditorPage(server):
<br>
<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>
<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>
<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>
<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>
</div>
@ -1928,7 +1982,33 @@ def AccessDenied(server):
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):
@ -2475,8 +2555,28 @@ def Publish(server):
petition["goal"] = int(petition_goal)
except:
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
@ -2494,7 +2594,16 @@ def Publish(server):
save.write(text)
else:
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)
@ -2645,7 +2754,45 @@ def ReadNotification(server):
except Exception as 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):
# Rendering rss feed.