foxhole/tasks.py
SouthFox 523cb1f467
All checks were successful
/ run-pytest (push) Successful in 38s
[feat] add accept follow again command
2024-03-10 02:16:14 +08:00

204 lines
5.5 KiB
Python

import os
import sys
import tomli_w
import asyncio
from pathlib import Path
from prompt_toolkit import prompt
from prompt_toolkit.key_binding import KeyBindings
from invoke import Context # type: ignore
from invoke import run # type: ignore
from invoke import task # type: ignore
_kb = KeyBindings()
@_kb.add("c-@")
def _(event):
"""Save multi-line buffer on CTRL + space"""
event.current_buffer.validate_and_handle()
@task
def config(ctx):
from Crypto.PublicKey import RSA
_ROOT_DIR = Path().parent.resolve()
_KEY_PATH = _ROOT_DIR / "data" / "key.pem"
if _KEY_PATH.exists():
print("is existing!")
sys.exit(2)
else:
k = RSA.generate(2048)
privkey_pem = k.exportKey("PEM").decode("utf-8")
_KEY_PATH.write_text(privkey_pem)
config_file = Path("data/config.toml")
if config_file.exists():
print("is existing!")
sys.exit(2)
config_dict: dict = {}
config_dict["domain"] = prompt("domain: ")
config_dict["username"] = prompt("username: ")
config_dict["name"] = prompt("name (e.g. John Doe): ",
default=config_dict["username"])
config_dict["summary"] = prompt("summary: ")
config_dict["https"] = True
proto = "https"
yn = ""
while yn not in ["y", "n"]:
yn = prompt("will the site be served via https? (y/n): ", default="y").lower()
if yn == "n":
config_dict["https"] = False
proto = "http"
config_dict["icon_url"] = prompt(
"icon URL: ", default=f'{proto}://{config_dict["domain"]}/static/nopic.png'
)
config_dict["secret"] = os.urandom(16).hex()
with config_file.open("w") as f:
f.write(tomli_w.dumps(config_dict))
print("Done")
sys.exit(0)
@task
def follow(ctx):
from app.database import async_session
from app.boxes import send_follow
acct = prompt("enter want to follow actor id:")
async def _dodo():
async with async_session() as db_session: #type: ignore
await send_follow(db_session,acct)
print("Done!")
asyncio.run(_dodo())
@task
def accept_follow_again(ctx):
from app.database import async_session
from sqlalchemy import select
from sqlalchemy.orm import joinedload
from app import models
from app.boxes import _send_accept
inbox_id = prompt("enter want to accept inbox id:")
async def _do():
async with async_session() as db_session: #type: ignore
try:
exist_inbox = (
await db_session.scalars(
select(models.InboxObject).where(
models.InboxObject.id == int(inbox_id)
).options(
joinedload(models.InboxObject.actor)
)
)
).one_or_none()
await _send_accept(
db_session,
exist_inbox.actor,
exist_inbox,
)
await db_session.commit()
except Exception as e:
print(f"ERROR: Failed to {e}")
return
print("Done!")
asyncio.run(_do())
@task
def accept_follow(ctx):
from app.database import async_session
from sqlalchemy import select
from sqlalchemy.orm import joinedload
from app import models
from app.boxes import _send_accept
ingress_id = prompt("enter want to accept ingress id:")
async def _do():
async with async_session() as db_session: #type: ignore
try:
exist_request = (
await db_session.scalars(
select(models.IncomingActivity).where(
models.IncomingActivity.id == int(ingress_id)
)
)
).one_or_none()
if not exist_request or exist_request.ap_object["type"] != "Follow":
raise ValueError("Non-valid id!")
exist_inbox = (
await db_session.scalars(
select(models.InboxObject).where(
models.InboxObject.ap_id == exist_request.ap_id
).options(
joinedload(models.InboxObject.actor)
)
)
).one_or_none()
await _send_accept(
db_session,
exist_inbox.actor,
exist_inbox,
)
await db_session.delete(exist_request)
await db_session.commit()
except Exception as e:
print(f"ERROR: Failed to {e}")
return
print("Done!")
asyncio.run(_do())
@task
def send_note(ctx):
from app.database import async_session
from app.activitypub import VisibilityEnum
from app.boxes import _send_create
from app.orgpython import to_html
content = prompt(
(
"note contents, in org mode, "
"use [CTRL] + [SPACE] to submit:\n"
),
key_bindings=_kb,
multiline=True,
)
content = to_html(content).replace("\n", "")
async def _dodo():
async with async_session() as db_session: #type: ignore
await _send_create(
db_session,
"Note",
content,
VisibilityEnum.PUBLIC
)
print("Done!")
asyncio.run(_dodo())