This repository has been archived on 2021-12-15. You can view files and clone it, but cannot push or open issues or pull requests.
pubspace/pubspace.py

82 lines
2.2 KiB
Python

import logging
from os import environ
from os.path import basename
import owncloud
from fastapi import FastAPI, Request
from mastodon import Mastodon, StreamListener
MASTODON_ACCESS_TOKEN = environ.get("MASTODON_ACCESS_TOKEN")
MASTODON_API_BASE_URL = environ.get("MASTODON_API_BASE_URL")
NEXTCLOUD_API_BASE_URL = environ.get("NEXTCLOUD_API_BASE_URL")
NEXTCLOUD_USER = environ.get("NEXTCLOUD_USER")
NEXTCLOUD_APP_PASSWORD = environ.get("NEXTCLOUD_APP_PASSWORD")
APP_LOG_LEVEL = environ.get("APP_LOG_LEVEL")
if APP_LOG_LEVEL == "info":
APP_LOG_LEVEL = logging.INFO
elif APP_LOG_LEVEL == "debug":
APP_LOG_LEVEL = logging.DEBUG
else:
APP_LOG_LEVEL = logging.INFO
mastodon = Mastodon(
access_token=MASTODON_ACCESS_TOKEN,
api_base_url=f"https://{MASTODON_API_BASE_URL}",
)
nextcloud = owncloud.Client(f"https://{NEXTCLOUD_API_BASE_URL}")
log = logging.getLogger("uvicorn")
log.setLevel(APP_LOG_LEVEL)
app = FastAPI()
app.state.log = log
class PubspaceListener(StreamListener):
def on_update(self, status):
log.info(status)
mastodon.stream_hashtag("pubspace", PubspaceListener(), run_async=True)
nextcloud.login(NEXTCLOUD_USER, NEXTCLOUD_APP_PASSWORD)
def create_share(fpath):
fname = basname(fpath)
fpaths = nextcloud.list("/", depth="infinity")
matching = [f.path for f in fpaths if fname in f.path][0]
if not nextcloud.is_shared(matching):
info = nextcloud.share_file_with_link(matching)
return info.get_link()
return None
@app.get("/")
async def home(request: Request):
try:
payload = await request.json()
except Exception:
request.app.state.log.info("Unable to parse request, bailing out")
return {"detail": "unknown request"}
request.app.state.log.info(f"Received: {payload}")
try:
file = payload["rel_path"]
link = create_share(file)
except Exception:
request.app.state.log.info(f"Failed to share {file}")
return {"detail": "failed to create share"}
if link:
request.app.state.log.info(f"Shared {file} on {link}")
else:
request.app.state.log.info(f"{file} already shared or failure!")
@app.get("/healthz")
async def healthz(request: Request):
return {"detail": "ALL ENGINES FIRING"}