You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
339 lines
9.0 KiB
339 lines
9.0 KiB
import json
|
|
from crypt import crypt
|
|
from time import time
|
|
from time import sleep
|
|
from os.path import exists
|
|
from os import unlink
|
|
from hashlib import md5
|
|
from markdown2 import Markdown
|
|
|
|
class ProxyMarkdown(Markdown):
|
|
def postprocess(self, text):
|
|
return text.replace("src=\"", "src=\"/proxy/")
|
|
|
|
def safechars(string):
|
|
string_safe = ""
|
|
for i in string:
|
|
if i.lower() in "abcdefghijklmnopqrstuvwxyz1234567890-_ ":
|
|
string_safe += i
|
|
return string_safe
|
|
|
|
def json_read(file):
|
|
with open(file, "r") as file_io:
|
|
json_bits = json.load(file_io)
|
|
file_io.close()
|
|
return json_bits
|
|
|
|
def json_sync(file, content, create = False):
|
|
mode = "w"
|
|
if create: mode = "x"
|
|
with open(file, mode) as file_io:
|
|
file_io.write(json.dumps(content, indent=2))
|
|
file_io.close()
|
|
return True
|
|
|
|
config = json_read("config.json")
|
|
|
|
def permcheck(permission, uname="joe"):
|
|
if uname == config["owner"] or config["permissions"][permission]:
|
|
return True
|
|
else: return False
|
|
|
|
def passchk(name, pwd):
|
|
for i in json_read("users.json")["users"]:
|
|
if i["name"] == name:
|
|
if crypt(pwd, str(int(time()))) == i["token"]:
|
|
return True
|
|
else:
|
|
return False
|
|
return None
|
|
|
|
def tokenchk(name, token):
|
|
for i in json_read("users.json")["users"]:
|
|
if i["name"] == name:
|
|
if token == i["token"]:
|
|
return True
|
|
else:
|
|
return False
|
|
return None
|
|
|
|
def uexist(name):
|
|
for i in json_read("users.json")["users"]:
|
|
if i["name"].lower() == name.lower():
|
|
return True
|
|
return False
|
|
|
|
def getUser(name):
|
|
users = json_read("users.json")["users"]
|
|
for user in users:
|
|
if user["name"].lower() == name.lower(): return user
|
|
return None
|
|
|
|
def getUserPos(name):
|
|
try:
|
|
users = json_read("users.json")["users"]
|
|
i = 0
|
|
for user in users:
|
|
if user["name"] == name: return i
|
|
i += 1
|
|
except:
|
|
return None
|
|
|
|
def bexist(name):
|
|
for i in json_read("boards.json")["boards"]:
|
|
if i["name"] == name:
|
|
return i
|
|
return False
|
|
|
|
def newuser(name, password):
|
|
if permcheck("can_create_accounts"):
|
|
pwd = crypt(password, str(int(time())))
|
|
users = json_read("users.json")
|
|
users["users"].append({
|
|
"name": name,
|
|
"token": pwd,
|
|
"credate": int(time()),
|
|
"avatar": None,
|
|
"subscriptions": [],
|
|
"bio": "A new user on Morsel!"
|
|
})
|
|
json_sync("users.json", users)
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def newboard(name, mod):
|
|
if permcheck("can_create_boards", mod):
|
|
boards = json_read("boards.json")
|
|
for i in boards["boards"]:
|
|
if i["name"] == name:
|
|
return False
|
|
boards["boards"].append({
|
|
"name": name,
|
|
"founder": mod,
|
|
"description": "A board on Morsel!",
|
|
"moderators": [mod],
|
|
"credate": int(time()),
|
|
"posts": f"boards/{name}.json"
|
|
})
|
|
json_sync("boards.json", boards)
|
|
json_sync(f"boards/{name}.json",
|
|
{
|
|
"posts": {
|
|
0: {
|
|
"author": mod,
|
|
"credate": int(time()),
|
|
"content": f"Hello, {name}!"
|
|
}
|
|
}
|
|
}, True
|
|
)
|
|
subscribe(mod, name)
|
|
return True
|
|
|
|
def bsetdesc(board, description):
|
|
if bexist(board):
|
|
boards = json_read("boards.json")
|
|
for i in boards["boards"]:
|
|
if i["name"] == board:
|
|
i["description"] = description
|
|
json_sync("boards.json", boards)
|
|
return True
|
|
return False
|
|
|
|
def bprivate(board):
|
|
if bexist(board):
|
|
boards = json_read("boards.json")
|
|
for i in boards["boards"]:
|
|
if i["name"] == board:
|
|
i["private"] = None
|
|
json_sync("boards.json", boards)
|
|
return True
|
|
return False
|
|
def bknight(board, user):
|
|
if bexist(board):
|
|
boards = json_read("boards.json")
|
|
for i in boards["boards"]:
|
|
if i["name"] == board:
|
|
i["moderators"].append(user)
|
|
json_sync("boards.json", boards)
|
|
return True
|
|
return False
|
|
|
|
def subscribe(user, board):
|
|
if bexist(board) and uexist(user) and permcheck("can_subscribe", user):
|
|
users=json_read("users.json")
|
|
users["users"][getUserPos(user)]["subscriptions"].append(board)
|
|
json_sync("users.json", users)
|
|
return True
|
|
return None
|
|
|
|
def unsubscribe(user, board):
|
|
if bexist(board) and uexist(user) and is_subbed(user, board) and permcheck("can_subscribe", user):
|
|
users=json_read("users.json")
|
|
users["users"][getUserPos(user)]["subscriptions"].remove(board)
|
|
json_sync("users.json", users)
|
|
return True
|
|
return None
|
|
|
|
def is_subbed(user, board):
|
|
if bexist(board) and uexist(user):
|
|
user = getUser(user)
|
|
subs = user["subscriptions"]
|
|
for i in subs:
|
|
if i == board:
|
|
return True
|
|
return False
|
|
else: print("Lmao no")
|
|
return None
|
|
|
|
def add_post(user, board, content):
|
|
if bexist(board) and uexist(user) and len(content) < 1000 and permcheck("can_post", user):
|
|
b = json_read("boards.json")["boards"]
|
|
for candidate in b:
|
|
print(candidate["name"], board)
|
|
if candidate["name"] == board:
|
|
posts = json_read(candidate["posts"])
|
|
# this gets the new post ID
|
|
postid = len(posts["posts"])
|
|
posts["posts"][str(postid)] = {
|
|
"author": user,
|
|
"credate": int(time()),
|
|
"content": content
|
|
}
|
|
json_sync(candidate["posts"], posts)
|
|
return True
|
|
print("nope")
|
|
|
|
def libravatar_geturl(user):
|
|
if uexist(user):
|
|
u = getUser(user)
|
|
if u["avatar"] == None:
|
|
return None
|
|
elif len(u["avatar"].split("@")) != 2:
|
|
return u["avatar"]
|
|
else:
|
|
hash = md5(u["avatar"].encode()).hexdigest()
|
|
return f"https://seccdn.libravatar.org/avatar/{hash}?s=64"
|
|
|
|
def getRecentPosts(board, count):
|
|
if bexist(board):
|
|
posts = {}
|
|
b = json_read("boards.json")["boards"]
|
|
for candidate in b:
|
|
print(candidate["name"], board)
|
|
if candidate["name"] == board:
|
|
posts = json_read(candidate["posts"])["posts"]
|
|
if posts == {}:
|
|
return {}
|
|
else:
|
|
array_posts = []
|
|
for post in posts:
|
|
tmp_post = posts[post]
|
|
tmp_post["author_avatar"] = libravatar_geturl(tmp_post["author"])
|
|
tmp_post["content"] = ProxyMarkdown().convert(tmp_post["content"])
|
|
tmp_post["id"] = post
|
|
array_posts.append(tmp_post)
|
|
|
|
array_posts = array_posts[::-1]
|
|
if len(array_posts) > 20: return array_posts[:20]
|
|
else: return array_posts
|
|
|
|
def applyToUser(user, bio, avatar):
|
|
if uexist(user):
|
|
users=json_read("users.json")
|
|
users["users"][getUserPos(user)]["bio"] = bio
|
|
if avatar.lower().strip() != "none": users["users"][getUserPos(user)]["avatar"] = avatar
|
|
else: users["users"][getUserPos(user)]["avatar"] = None
|
|
json_sync("users.json", users)
|
|
return
|
|
|
|
def toggle_follow(follower, followee):
|
|
if permcheck("can_follow", follower):
|
|
follows_json = json_read("follows.json")
|
|
|
|
follower_json = follows_json.get(follower)
|
|
if follower_json == None:
|
|
follows_json[follower] = {}
|
|
follower_json = follows_json[follower]
|
|
follower_json["following"] = []
|
|
follower_json["followers"] = []
|
|
|
|
followee_json = follows_json.get(followee)
|
|
if followee_json == None:
|
|
follows_json[followee] = {}
|
|
followee_json = follows_json[followee]
|
|
followee_json["following"] = []
|
|
followee_json["followers"] = []
|
|
|
|
if follower in followee_json["followers"]:
|
|
follower_json["following"].remove(followee)
|
|
followee_json["followers"].remove(follower)
|
|
else:
|
|
follower_json["following"].append(followee)
|
|
followee_json["followers"].append(follower)
|
|
|
|
json_sync("follows.json", follows_json)
|
|
|
|
def isFollowing(follower, followee):
|
|
follows_json = json_read("follows.json")
|
|
|
|
try:
|
|
if follower in follows_json[followee]["followers"]:
|
|
return True
|
|
else:
|
|
return False
|
|
except:
|
|
return False
|
|
|
|
def getPostById(board, id):
|
|
boards_json = json_read("boards.json")
|
|
posts = None
|
|
for i in boards_json["boards"]:
|
|
if i["name"] == board:
|
|
posts = i["posts"]
|
|
break
|
|
if posts == None: return
|
|
matchpost = json_read(posts)["posts"][str(id)]
|
|
matchpost["content"] = ProxyMarkdown().convert(matchpost["content"])
|
|
return matchpost
|
|
|
|
def delPostById(board, id):
|
|
boards_json = json_read("boards.json")
|
|
postsf = None
|
|
for i in boards_json["boards"]:
|
|
if i["name"] == board:
|
|
postsf = i["posts"]
|
|
break
|
|
if postsf == None: return
|
|
posts_json = json_read(postsf)
|
|
del posts_json["posts"][id]
|
|
json_sync(postsf, posts_json)
|
|
|
|
def getSubbedArray(user, boards):
|
|
subbed = []
|
|
for i in boards["boards"]:
|
|
if is_subbed(user, i["name"]):
|
|
subbed.append(i["name"])
|
|
return subbed
|
|
|
|
def addreply(uname, board, post, message):
|
|
if permcheck("can_reply", uname):
|
|
boards_json = json_read("boards.json")
|
|
jboard = None
|
|
for i in boards_json["boards"]:
|
|
if i["name"] == board:
|
|
jboard = i
|
|
break
|
|
if jboard == None: return jboard
|
|
posts_json = json_read(jboard["posts"])
|
|
if not "replies" in posts_json["posts"][post]:
|
|
posts_json["posts"][post]["replies"] = []
|
|
posts_json["posts"][post]["replies"].append({
|
|
"author": uname,
|
|
"credate": int(time()),
|
|
"content": ProxyMarkdown().convert(message)
|
|
})
|
|
json_sync(jboard["posts"], posts_json)
|
|
return True
|