Basic petition functionality
This commit is contained in:
parent
8f060242bb
commit
6cd369b043
4 changed files with 223 additions and 27 deletions
BIN
icons/petition.png
Normal file
BIN
icons/petition.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
108
modules/Email.py
108
modules/Email.py
|
@ -73,7 +73,7 @@ def VerifyPage(server):
|
||||||
|
|
||||||
<div class="dark_box">
|
<div class="dark_box">
|
||||||
|
|
||||||
<form action="email_verify">
|
<form action="/email_verify">
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
<br>
|
<br>
|
||||||
|
@ -135,8 +135,113 @@ def VerifyPage(server):
|
||||||
with open(folder+"/"+user.get("username", "")+".json", "w") as save:
|
with open(folder+"/"+user.get("username", "")+".json", "w") as save:
|
||||||
json.dump(user, save, indent=4)
|
json.dump(user, save, indent=4)
|
||||||
|
|
||||||
|
del verifying[code]
|
||||||
|
|
||||||
Render.Redirect(server, "/settings#email")
|
Render.Redirect(server, "/settings#email")
|
||||||
|
|
||||||
|
def SignPetition(server):
|
||||||
|
|
||||||
|
config = Set.Load()
|
||||||
|
|
||||||
|
# Generating <head>
|
||||||
|
html = Render.head(title = "Verify Email",
|
||||||
|
description = "Verify Email",
|
||||||
|
config = config
|
||||||
|
)
|
||||||
|
|
||||||
|
html = html + Render.Button(config.get("title", "My Website"), "/", image=config.get("favicon", "/icon/internet"))
|
||||||
|
|
||||||
|
article = server.parsed.get("article", [""])[0]
|
||||||
|
print(article)
|
||||||
|
|
||||||
|
Articles = Render.allArticles()
|
||||||
|
if article not in Articles:
|
||||||
|
Render.AccessDenied(server)
|
||||||
|
return
|
||||||
|
|
||||||
|
Article = Articles[article]
|
||||||
|
|
||||||
|
code = server.parsed.get("code", [""])[0]
|
||||||
|
email = server.parsed.get("email", [""])[0]
|
||||||
|
|
||||||
|
if email in Article.get("petition", {}).get("signatures", []):
|
||||||
|
Render.AccessDenied(server)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not code:
|
||||||
|
|
||||||
|
html = html + """
|
||||||
|
|
||||||
|
<div class="middle_section_article">
|
||||||
|
|
||||||
|
<div class="dark_box">
|
||||||
|
|
||||||
|
<form action="/sign_petition">
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<br>
|
||||||
|
You have recieved an email with a code.<br><br>
|
||||||
|
<small>It could be in spam.</small>
|
||||||
|
<br><br>
|
||||||
|
<input type="hidden" name="article" value='"""+article+"""'>
|
||||||
|
<input class="button" name="code" required placeholder="Your code...">
|
||||||
|
<br>
|
||||||
|
<button class="button" type="submit">
|
||||||
|
<img alt="[icon ok]" style="vertical-align: middle" src="/icon/ok">
|
||||||
|
Verify
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</center>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
"""
|
||||||
|
code = RandString(10)
|
||||||
|
verifying[code] = email
|
||||||
|
|
||||||
|
text = """
|
||||||
|
<center>
|
||||||
|
Your Verification Code
|
||||||
|
<br>
|
||||||
|
<div class="toot">"""+code+"""
|
||||||
|
</div>
|
||||||
|
</center>
|
||||||
|
"""
|
||||||
|
|
||||||
|
text = Format(text)
|
||||||
|
|
||||||
|
Send(email, "Verification Code", text)
|
||||||
|
|
||||||
|
Render.send(server, html, 200)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
# If we recieved the code.
|
||||||
|
|
||||||
|
if code not in verifying:
|
||||||
|
print("code not in verifying")
|
||||||
|
Render.AccessDenied(server)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
Article["petition"]["signed"] += 1
|
||||||
|
Article["petition"]["signatures"].append(verifying[code])
|
||||||
|
|
||||||
|
f = Set.Folder()
|
||||||
|
with open(f+"/tabs"+article+"/metadata.json", "w") as save:
|
||||||
|
json.dump(Article, save, indent=4)
|
||||||
|
|
||||||
|
|
||||||
|
del verifying[code]
|
||||||
|
|
||||||
|
Render.Redirect(server, article)
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
def Format(text):
|
def Format(text):
|
||||||
|
|
||||||
config = Set.Load()
|
config = Set.Load()
|
||||||
|
@ -160,4 +265,3 @@ def Format(text):
|
||||||
|
|
||||||
return html
|
return html
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -259,7 +259,7 @@ def allArticles():
|
||||||
data = json.load(o)
|
data = json.load(o)
|
||||||
data["tab"] = tab
|
data["tab"] = tab
|
||||||
data["url"] = "/"+tab+"/"+article
|
data["url"] = "/"+tab+"/"+article
|
||||||
articles[article] = data
|
articles[data["url"]] = data
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
pass
|
pass
|
||||||
|
@ -566,6 +566,50 @@ def ArticlePage(server, url):
|
||||||
|
|
||||||
html = html + '</div>'
|
html = html + '</div>'
|
||||||
|
|
||||||
|
# Petition
|
||||||
|
|
||||||
|
petition = Articles.get(article, {}).get("petition", "")
|
||||||
|
if petition:
|
||||||
|
|
||||||
|
html = html + '<div class="dark_box"> <center>'
|
||||||
|
html = html + '<h2><img alt="[icon petition]" style="vertical-align: middle" src="/icon/petition">'
|
||||||
|
html = html + 'Petition</h2></center>'
|
||||||
|
|
||||||
|
try:
|
||||||
|
frac = petition.get("signed", 0) / int(petition.get("goal", 1))
|
||||||
|
except:
|
||||||
|
frac = 0
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
"""
|
||||||
|
|
||||||
|
html = html + '</div>'
|
||||||
|
|
||||||
|
# License
|
||||||
License = Articles.get(article, {}).get("license", "")
|
License = Articles.get(article, {}).get("license", "")
|
||||||
if License:
|
if License:
|
||||||
html = html + '<div class="dark_box"> <center>'
|
html = html + '<div class="dark_box"> <center>'
|
||||||
|
@ -1346,45 +1390,53 @@ def EditorPage(server):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# Optional release options
|
# Optional Petition
|
||||||
|
|
||||||
if rank(user.get("username","")) == 0:
|
if rank(user.get("username","")) == 0:
|
||||||
|
|
||||||
|
|
||||||
|
petition = article.get("petition", {})
|
||||||
|
petition_goal = petition.get("goal", 0)
|
||||||
|
|
||||||
|
|
||||||
html = html + """
|
html = html + """
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary class="button">
|
<summary class="button">
|
||||||
<img alt="[icon unlock]" style="vertical-align: middle" src="/icon/unlock">
|
<img alt="[icon petition]" style="vertical-align: middle" src="/icon/petition">
|
||||||
Unlock
|
Petition
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
<div class="dark_box">
|
<div class="dark_box">
|
||||||
<br>
|
<br>
|
||||||
<br>
|
|
||||||
<center><small>
|
|
||||||
For unlockable files that will be published after a certain statistics is reached.
|
|
||||||
</small></center>
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
<img alt="[icon file]" style="vertical-align: middle" src="/icon/file">
|
<img alt="[icon ok]" style="vertical-align: middle" src="/icon/ok">
|
||||||
<input class="button" style="width:90%" name="unlock_file" placeholder="Unlocked File ( on the server )">
|
<input class="button" type="number" style="width:90%" name="petition_goal" placeholder="Goal ( How Many Signatures )" value='"""+str(petition_goal)+"""'>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary class="button">
|
||||||
|
<img alt="[icon analytics]" style="vertical-align: middle" src="/icon/analytics">
|
||||||
|
From API
|
||||||
|
</summary>
|
||||||
|
|
||||||
<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="unlock_file" placeholder="API to check">
|
<input class="button" style="width:90%" name="petition_api" placeholder="API to check ( should be JSON )">
|
||||||
<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="unlock_file" 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 )">
|
||||||
<br>
|
|
||||||
|
|
||||||
<img alt="[icon ok]" style="vertical-align: middle" src="/icon/ok">
|
|
||||||
<input class="button" style="width:90%" name="unlock_file" placeholder="Goal ( should be a number )">
|
|
||||||
<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="unlock_file" placeholder="Statistic's Name">
|
<input class="button" style="width:90%" name="petition_api_title" placeholder="Statistic's Name">
|
||||||
<br>
|
<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 )">
|
||||||
|
<br>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1456,6 +1508,15 @@ def ArticlePreview(article, Tabs, cookie=""):
|
||||||
if article.get("thumbnail"):
|
if article.get("thumbnail"):
|
||||||
html = html + '<center><a href="'+url+'"><img alt="[thumbnail]" src="'+article["thumbnail"]+'"></a></center>'
|
html = html + '<center><a href="'+url+'"><img alt="[thumbnail]" src="'+article["thumbnail"]+'"></a></center>'
|
||||||
|
|
||||||
|
petition = article.get("petition", "")
|
||||||
|
if petition:
|
||||||
|
try:
|
||||||
|
frac = petition.get("signed", 0) / int(petition.get("goal", 1))
|
||||||
|
except:
|
||||||
|
frac = 0
|
||||||
|
|
||||||
|
html = html + ProgressBar(frac)
|
||||||
|
|
||||||
author = article.get("author", "")
|
author = article.get("author", "")
|
||||||
if author:
|
if author:
|
||||||
html = html + '<br><center>'+User( author )+'</center>'
|
html = html + '<br><center>'+User( author )+'</center>'
|
||||||
|
@ -1811,6 +1872,17 @@ def LoginButton(server):
|
||||||
|
|
||||||
return html
|
return html
|
||||||
|
|
||||||
|
def ProgressBar(frac):
|
||||||
|
|
||||||
|
title = str(round(frac*100,1))+"%"
|
||||||
|
|
||||||
|
frac = min(1, frac)
|
||||||
|
frac = max(0, frac)
|
||||||
|
|
||||||
|
html = '<div title="'+title+'" class="back_progress">'
|
||||||
|
html = html + '<div title="'+title+'" class="front_progress", style="width:'+str(frac*100)+'%">'
|
||||||
|
html = html + '</div></div>'
|
||||||
|
return html
|
||||||
|
|
||||||
def NotFound(server):
|
def NotFound(server):
|
||||||
|
|
||||||
|
@ -2330,6 +2402,12 @@ def Publish(server):
|
||||||
recording = server.parsed.get("recording", [""])[0]
|
recording = server.parsed.get("recording", [""])[0]
|
||||||
|
|
||||||
|
|
||||||
|
# Petition data
|
||||||
|
petition_goal = server.parsed.get("petition_goal", [""])[0]
|
||||||
|
petition_api = server.parsed.get("petition_api", [""])[0]
|
||||||
|
petition_api_key = server.parsed.get("petition_api_key", [""])[0]
|
||||||
|
petition_api_title = server.parsed.get("petition_api_title", [""])[0]
|
||||||
|
petition_api_link = server.parsed.get("petition_api_link", [""])[0]
|
||||||
|
|
||||||
# If this tab doesn't exist, this is an error.
|
# If this tab doesn't exist, this is an error.
|
||||||
if tab not in Tabs:
|
if tab not in Tabs:
|
||||||
|
@ -2384,6 +2462,22 @@ def Publish(server):
|
||||||
metadata["recording"] = recording
|
metadata["recording"] = recording
|
||||||
metadata["thumbnail"] = thumbnail
|
metadata["thumbnail"] = thumbnail
|
||||||
|
|
||||||
|
# Petition
|
||||||
|
|
||||||
|
if petition_goal:
|
||||||
|
|
||||||
|
petition = metadata.get("petition", {
|
||||||
|
"signed":0,
|
||||||
|
"signatures":[]
|
||||||
|
})
|
||||||
|
|
||||||
|
try:
|
||||||
|
petition["goal"] = int(petition_goal)
|
||||||
|
except:
|
||||||
|
petition["goal"] = 1
|
||||||
|
|
||||||
|
metadata["petition"] = petition
|
||||||
|
|
||||||
# Save the changes
|
# Save the changes
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -16,6 +16,7 @@ import os
|
||||||
|
|
||||||
from modules import Set
|
from modules import Set
|
||||||
from modules import Render
|
from modules import Render
|
||||||
|
from modules import Email
|
||||||
from modules.Common import *
|
from modules.Common import *
|
||||||
|
|
||||||
class handler(BaseHTTPRequestHandler):
|
class handler(BaseHTTPRequestHandler):
|
||||||
|
@ -172,8 +173,6 @@ class handler(BaseHTTPRequestHandler):
|
||||||
Render.EditorPage(self)
|
Render.EditorPage(self)
|
||||||
|
|
||||||
elif self.path[1:].startswith("email_verify"):
|
elif self.path[1:].startswith("email_verify"):
|
||||||
|
|
||||||
from modules import Email
|
|
||||||
Email.VerifyPage(self)
|
Email.VerifyPage(self)
|
||||||
|
|
||||||
elif self.path[1:].startswith("register"):
|
elif self.path[1:].startswith("register"):
|
||||||
|
@ -203,9 +202,8 @@ class handler(BaseHTTPRequestHandler):
|
||||||
elif self.path[1:].startswith("log_out"):
|
elif self.path[1:].startswith("log_out"):
|
||||||
Render.LogOut(self)
|
Render.LogOut(self)
|
||||||
|
|
||||||
|
elif self.path[1:].startswith("sign_petition"):
|
||||||
|
Email.SignPetition(self)
|
||||||
|
|
||||||
|
|
||||||
elif self.path[1:].startswith("read_notification"):
|
elif self.path[1:].startswith("read_notification"):
|
||||||
Render.ReadNotification(self)
|
Render.ReadNotification(self)
|
||||||
|
|
Loading…
Add table
Reference in a new issue