API petitions, sign petitions by subscribing to mastodon and such
This commit is contained in:
parent
6cd369b043
commit
7750afc5b9
3 changed files with 232 additions and 38 deletions
50
modules/API.py
Normal file
50
modules/API.py
Normal 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)
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Reference in a new issue