Initial commit.
This commit is contained in:
@@ -0,0 +1,413 @@
|
||||
# AGPL 3 or any later version
|
||||
# (C) J.Y.Amihud ( Blender Dumbass )
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import json
|
||||
import random
|
||||
import traceback
|
||||
import hashlib
|
||||
import urllib.parse
|
||||
|
||||
from datetime import datetime
|
||||
from getpass import getpass
|
||||
|
||||
from modules import Set
|
||||
from modules import API
|
||||
from modules import Plugins
|
||||
from modules import Analyse
|
||||
from modules import Render
|
||||
from modules import markdown
|
||||
from modules import ActivityPub
|
||||
from modules.Common import *
|
||||
|
||||
def Federation():
|
||||
|
||||
anything = False
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
from modules import Help
|
||||
Help.Federation()
|
||||
anything = True
|
||||
|
||||
|
||||
if "--add" in sys.argv:
|
||||
anything = True
|
||||
try:
|
||||
domain = sys.argv[ sys.argv.index("--add") + 1]
|
||||
if "--" in domain: 1/0 # Failing this for the error message.
|
||||
Add(domain)
|
||||
|
||||
except Exception as e:
|
||||
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Domain wasn't specified!")
|
||||
print('Use: $ python3 run.py --federation --add blog.madiator.com')
|
||||
|
||||
|
||||
if "--remove" in sys.argv:
|
||||
anything = True
|
||||
try:
|
||||
domain = sys.argv[ sys.argv.index("--remove") + 1]
|
||||
if "--" in domain: 1/0 # Failing this for the error message.
|
||||
Remove(domain)
|
||||
|
||||
except Exception as e:
|
||||
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Domain wasn't specified!")
|
||||
print('Use: $ python3 run.py --federation --remove threads.net')
|
||||
|
||||
|
||||
if "--ban" in sys.argv:
|
||||
anything = True
|
||||
try:
|
||||
domain = sys.argv[ sys.argv.index("--ban") + 1]
|
||||
if "--" in domain: 1/0 # Failing this for the error message.
|
||||
Ban(domain)
|
||||
|
||||
except Exception as e:
|
||||
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Domain wasn't specified!")
|
||||
print('Use: $ python3 run.py --federation --ban threads.net')
|
||||
|
||||
if "--unban" in sys.argv:
|
||||
anything = True
|
||||
try:
|
||||
domain = sys.argv[ sys.argv.index("--unban") + 1]
|
||||
if "--" in domain: 1/0 # Failing this for the error message.
|
||||
UnBan(domain)
|
||||
|
||||
except Exception as e:
|
||||
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Domain wasn't specified!")
|
||||
print('Use: $ python3 run.py --federation --unban blog.madiator.com')
|
||||
|
||||
|
||||
if "--list" in sys.argv:
|
||||
anything = True
|
||||
List()
|
||||
|
||||
if "--auto_on" in sys.argv:
|
||||
anything = True
|
||||
AutoOn()
|
||||
|
||||
if "--auto_off" in sys.argv:
|
||||
anything = True
|
||||
AutoOff()
|
||||
|
||||
|
||||
#########
|
||||
|
||||
if not anything:
|
||||
print(clr["bold"]+clr["tdrd"]+"Unknown command!"+clr["norm"])
|
||||
|
||||
def Clean(domain):
|
||||
|
||||
return domain.replace("https://", "").replace("http://", "")
|
||||
|
||||
def Add(domain, silent=False):
|
||||
|
||||
domain = Clean(domain)
|
||||
config = Set.Load()
|
||||
|
||||
if domain == config.get("domain"):
|
||||
return
|
||||
|
||||
if "federation" not in config: config["federation"] = {}
|
||||
if "known_websites" not in config["federation"]: config["federation"]["known_websites"] = []
|
||||
if "suggested_websites" not in config["federation"]: config["federation"]["suggested_websites"] = []
|
||||
if "banned_websites" not in config["federation"]: config["federation"]["banned_websites"] = []
|
||||
|
||||
if domain not in config["federation"]["known_websites"]:
|
||||
|
||||
if domain in config["federation"]["suggested_websites"]:
|
||||
config["federation"]["suggested_websites"].remove(domain)
|
||||
if domain in config["federation"]["banned_websites"]:
|
||||
config["federation"]["banned_websites"].remove(domain)
|
||||
|
||||
config["federation"]["known_websites"].append(domain)
|
||||
|
||||
Set.Save(config)
|
||||
|
||||
if not silent:
|
||||
print(clr["bold"]+clr["tbyl"]+domain+clr["norm"]+" is added for federation.")
|
||||
|
||||
def Suggest(domain, silent=False):
|
||||
|
||||
domain = Clean(domain)
|
||||
config = Set.Load()
|
||||
|
||||
if domain == config.get("domain"):
|
||||
return
|
||||
|
||||
if "federation" not in config: config["federation"] = {}
|
||||
if "suggested_websites" not in config["federation"]: config["federation"]["suggested_websites"] = []
|
||||
|
||||
if domain not in config["federation"]["suggested_websites"]:
|
||||
config["federation"]["suggested_websites"].append(domain)
|
||||
|
||||
Set.Save(config)
|
||||
|
||||
if not silent:
|
||||
print(clr["bold"]+clr["tbyl"]+domain+clr["norm"]+" is suggested for federation.")
|
||||
|
||||
def Remove(domain):
|
||||
|
||||
domain = Clean(domain)
|
||||
|
||||
config = Set.Load()
|
||||
|
||||
if "federation" not in config: config["federation"] = {}
|
||||
if "known_websites" not in config["federation"]: config["federation"]["known_websites"] = []
|
||||
|
||||
try:
|
||||
config["federation"]["known_websites"].remove(domain)
|
||||
|
||||
except:
|
||||
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Domain is not known!")
|
||||
return
|
||||
|
||||
Set.Save(config)
|
||||
Suggest(domain, True)
|
||||
|
||||
print(clr["bold"]+clr["tbyl"]+domain+clr["norm"]+" is removed from federation.")
|
||||
|
||||
def Ban(domain):
|
||||
|
||||
domain = Clean(domain)
|
||||
|
||||
config = Set.Load()
|
||||
|
||||
if "federation" not in config: config["federation"] = {}
|
||||
if "known_websites" not in config["federation"]: config["federation"]["known_websites"] = []
|
||||
if "suggested_websites" not in config["federation"]: config["federation"]["suggested_websites"] = []
|
||||
if "banned_websites" not in config["federation"]: config["federation"]["banned_websites"] = []
|
||||
|
||||
if domain not in config["federation"]["banned_websites"]:
|
||||
|
||||
if domain in config["federation"]["known_websites"]:
|
||||
config["federation"]["known_websites"].remove(domain)
|
||||
if domain in config["federation"]["suggested_websites"]:
|
||||
config["federation"]["suggested_websites"].remove(domain)
|
||||
|
||||
config["federation"]["banned_websites"].append(domain)
|
||||
|
||||
Set.Save(config)
|
||||
|
||||
print(clr["bold"]+clr["tbyl"]+domain+clr["norm"]+" is banned.")
|
||||
|
||||
def UnBan(domain):
|
||||
|
||||
domain = Clean(domain)
|
||||
config = Set.Load()
|
||||
|
||||
if "federation" not in config: config["federation"] = {}
|
||||
if "banned_websites" not in config["federation"]: config["federation"]["banned_websites"] = []
|
||||
|
||||
|
||||
try:
|
||||
config["federation"]["banned_websites"].remove(domain)
|
||||
except:
|
||||
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Domain is not banned!")
|
||||
return
|
||||
|
||||
Set.Save(config)
|
||||
Suggest(domain, True)
|
||||
|
||||
print(clr["bold"]+clr["tbyl"]+domain+clr["norm"]+" is unbanned.")
|
||||
|
||||
def List():
|
||||
|
||||
config = Set.Load()
|
||||
|
||||
print()
|
||||
print(" Federating with:")
|
||||
print()
|
||||
|
||||
for domain in config.get("federation", {}).get("known_websites", []):
|
||||
print(domain)
|
||||
|
||||
print()
|
||||
print(" Suggested:")
|
||||
print()
|
||||
|
||||
for domain in config.get("federation", {}).get("suggested_websites", []):
|
||||
print(domain)
|
||||
|
||||
print()
|
||||
print(" Banned from auto-federating:")
|
||||
print()
|
||||
|
||||
for domain in config.get("federation", {}).get("banned_websites", []):
|
||||
print(domain)
|
||||
|
||||
def AutoOn():
|
||||
|
||||
config = Set.Load()
|
||||
|
||||
if "federation" not in config: config["federation"] = {}
|
||||
config["federation"]["auto"] = True
|
||||
|
||||
Set.Save(config)
|
||||
|
||||
print("Auto-federation is turned on.")
|
||||
|
||||
def AutoOff():
|
||||
|
||||
config = Set.Load()
|
||||
|
||||
if "federation" not in config: config["federation"] = {}
|
||||
config["federation"]["auto"] = False
|
||||
|
||||
Set.Save(config)
|
||||
|
||||
print("Auto-federation is turned off.")
|
||||
|
||||
|
||||
def FederationThread():
|
||||
|
||||
# This thread happens alongside the main website thread.
|
||||
# And is used to request websites various federation
|
||||
# requests.
|
||||
|
||||
while True:
|
||||
|
||||
try:
|
||||
|
||||
time.sleep(600)
|
||||
|
||||
API.PetitionFetch()
|
||||
|
||||
# Fetch() # This needs to be rewritten to not try to fetch AP servers
|
||||
ActivityPub.SendArticles()
|
||||
Analyse.CollectTotals() # Making sure the totals are collected.
|
||||
Plugins.onFEDI()
|
||||
|
||||
|
||||
except KeyboardInterrupt:
|
||||
return
|
||||
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
def Fetch():
|
||||
|
||||
config = Set.Load()
|
||||
|
||||
known = config.get("federation", {}).get("known_websites", [])
|
||||
banned = config.get("federation", {}).get("banned_websites", [])
|
||||
auto = config.get("federation", {}).get("auto", False)
|
||||
|
||||
Articles = Render.allArticles()
|
||||
|
||||
print(" "+consoleForm("Federation "), "Fetching federation data")
|
||||
|
||||
for domain in known:
|
||||
|
||||
if domain in banned:
|
||||
continue
|
||||
|
||||
#print(" "+consoleForm("Federation "), "Fetching:", domain)
|
||||
|
||||
try:
|
||||
data = API.Get("https://"+domain+"/json/federate/"+config.get("domain", ""))
|
||||
except:
|
||||
#print(" "+consoleForm("Federation "), clr["bold"]+clr["tdrd"]+"Failed to fetch:", clr["norm"]+ domain)
|
||||
continue
|
||||
|
||||
# Adding to the known_websites
|
||||
|
||||
for d in data.get("known_websites", []):
|
||||
d = Clean(d)
|
||||
if d not in banned and d not in known and d != config.get("domain"):
|
||||
if auto:
|
||||
print(" "+consoleForm("Federation "), "Auto-adding new domain:", d)
|
||||
Add(d, silent=True)
|
||||
else:
|
||||
print(" "+consoleForm("Federation "), "Suggested new domain:", d)
|
||||
Suggest(d, silent=True)
|
||||
|
||||
# Adding comments
|
||||
|
||||
for comment in data.get("comments", {}):
|
||||
|
||||
comment = data["comments"][comment]
|
||||
is_reply_to = comment.get("is_reply_to", "")
|
||||
article = is_reply_to.replace("https://", "").replace(config.get("domain", ""), "")
|
||||
|
||||
article = Articles.get(article, {})
|
||||
|
||||
if article:
|
||||
|
||||
# Checking if this comment is already recorded
|
||||
url = comment.get("url","")
|
||||
found = False
|
||||
for c in article.get("comments", {}).get("comments", []):
|
||||
if c.get("url", "") == url:
|
||||
found = True
|
||||
|
||||
if not found:
|
||||
print(" "+consoleForm("Federation "), "New comment from:", domain, "on:", article.get("url", ""))
|
||||
|
||||
description = comment.get("description", "")
|
||||
if not description:
|
||||
description = "A reply from "+domain
|
||||
|
||||
description = "*...from "+domain+"*\n\n**"+comment.get("title", "Reply")+"**\n\n"+description
|
||||
|
||||
|
||||
cdata = {"username":comment.get("author",domain),
|
||||
"text":Safe(description),
|
||||
"url":Safe(url)}
|
||||
|
||||
if "comments" not in article:
|
||||
article["comments"] = {}
|
||||
if "comments" not in article["comments"]:
|
||||
article["comments"]["comments"] = []
|
||||
|
||||
article["comments"]["comments"].append(cdata)
|
||||
|
||||
metadata = Set.Folder()+"/tabs"+article.get("url","")+"/metadata.json"
|
||||
|
||||
try:
|
||||
with ThreadLock(metadata):
|
||||
with open(metadata, "w") as save:
|
||||
json.dump(article, save, indent=4)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Notification
|
||||
if article.get("author"):
|
||||
text = comment.get("author", {}).get("username", "")
|
||||
text = text + ' from '+domain+' made an article reply to '
|
||||
text = text + article.get("title", "")
|
||||
|
||||
Render.Notify(article.get("author"), Safe(comment.get("url", article.get("url", ""))), Safe(text))
|
||||
|
||||
|
||||
# Get plugins
|
||||
|
||||
try:
|
||||
data = API.Get("https://"+domain+"/json/plugins")
|
||||
except:
|
||||
continue
|
||||
|
||||
# Load
|
||||
|
||||
try:
|
||||
|
||||
with ThreadLock(filename):
|
||||
with open(filename) as o:
|
||||
Pdata = json.load(o)
|
||||
except:
|
||||
Pdata = {}
|
||||
|
||||
Pdata[domain] = data
|
||||
|
||||
# Save
|
||||
try:
|
||||
filename = Set.Folder()+"/plugins.json"
|
||||
with ThreadLock(filename):
|
||||
with open(filename, "w") as save:
|
||||
json.dump(Pdata, save, indent=4)
|
||||
|
||||
except Exception as e:
|
||||
print(clr["bold"]+clr["tdrd"]+"Error:"+clr["norm"]+" Cannot save plugins!", e)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user