diff options
| author | Tulir Asokan <tulir@maunium.net> | 2020-09-13 03:56:28 +0300 |
|---|---|---|
| committer | Tulir Asokan <tulir@maunium.net> | 2020-09-13 03:56:28 +0300 |
| commit | 80bcf6d0acdf35f082a6765db989ef80100f20fb (patch) | |
| tree | 89a02e12c0a4094863a80e2ff00591cb3551cb94 /sticker/lib | |
| parent | de79aea53568cf00f07610ceb233cf4f69837e81 (diff) | |
Reorganize Python stuff and add command to create packs
Fixes #11
Diffstat (limited to 'sticker/lib')
| -rw-r--r-- | sticker/lib/__init__.py | 0 | ||||
| -rw-r--r-- | sticker/lib/matrix.py | 77 | ||||
| -rw-r--r-- | sticker/lib/util.py | 67 |
3 files changed, 144 insertions, 0 deletions
diff --git a/sticker/lib/__init__.py b/sticker/lib/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sticker/lib/__init__.py diff --git a/sticker/lib/matrix.py b/sticker/lib/matrix.py new file mode 100644 index 0000000..426bdd0 --- /dev/null +++ b/sticker/lib/matrix.py @@ -0,0 +1,77 @@ +# Copyright (c) 2020 Tulir Asokan +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +from typing import Optional, TYPE_CHECKING +import json + +from aiohttp import ClientSession +from yarl import URL + +access_token: Optional[str] = None +homeserver_url: Optional[str] = None + +upload_url: Optional[URL] = None + +if TYPE_CHECKING: + from typing import TypedDict + + + class MediaInfo(TypedDict): + w: int + h: int + size: int + mimetype: str + thumbnail_url: Optional[str] + thumbnail_info: Optional['MediaInfo'] + + + class StickerInfo(TypedDict, total=False): + body: str + url: str + info: MediaInfo + id: str +else: + MediaInfo = None + StickerInfo = None + + +async def load_config(path: str) -> None: + global access_token, homeserver_url, upload_url + try: + with open(path) as config_file: + config = json.load(config_file) + homeserver_url = config["homeserver"] + access_token = config["access_token"] + except FileNotFoundError: + print("Matrix config file not found. Please enter your homeserver and access token.") + homeserver_url = input("Homeserver URL: ") + access_token = input("Access token: ") + whoami_url = URL(homeserver_url) / "_matrix" / "client" / "r0" / "account" / "whoami" + user_id = await whoami(whoami_url, access_token) + with open(path, "w") as config_file: + json.dump({ + "homeserver": homeserver_url, + "user_id": user_id, + "access_token": access_token + }, config_file) + print(f"Wrote config to {path}") + + upload_url = URL(homeserver_url) / "_matrix" / "media" / "r0" / "upload" + + +async def whoami(url: URL, access_token: str) -> str: + headers = {"Authorization": f"Bearer {access_token}"} + async with ClientSession() as sess, sess.get(url, headers=headers) as resp: + resp.raise_for_status() + user_id = (await resp.json())["user_id"] + print(f"Access token validated (user ID: {user_id})") + return user_id + + +async def upload(data: bytes, mimetype: str, filename: str) -> str: + url = upload_url.with_query({"filename": filename}) + headers = {"Content-Type": mimetype, "Authorization": f"Bearer {access_token}"} + async with ClientSession() as sess, sess.post(url, data=data, headers=headers) as resp: + return (await resp.json())["content_uri"] diff --git a/sticker/lib/util.py b/sticker/lib/util.py new file mode 100644 index 0000000..feefea2 --- /dev/null +++ b/sticker/lib/util.py @@ -0,0 +1,67 @@ +# Copyright (c) 2020 Tulir Asokan +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +from io import BytesIO +import os.path +import json + +from PIL import Image + +from . import matrix + + +def convert_image(data: bytes) -> (bytes, int, int): + image: Image.Image = Image.open(BytesIO(data)).convert("RGBA") + new_file = BytesIO() + image.save(new_file, "png") + w, h = image.size + if w > 256 or h > 256: + # Set the width and height to lower values so clients wouldn't show them as huge images + if w > h: + h = int(h / (w / 256)) + w = 256 + else: + w = int(w / (h / 256)) + h = 256 + return new_file.getvalue(), w, h + + +def add_to_index(name: str, output_dir: str) -> None: + index_path = os.path.join(output_dir, "index.json") + try: + with open(index_path) as index_file: + index_data = json.load(index_file) + except (FileNotFoundError, json.JSONDecodeError): + index_data = {"packs": []} + if "homeserver_url" not in index_data and matrix.homeserver_url: + index_data["homeserver_url"] = matrix.homeserver_url + if name not in index_data["packs"]: + index_data["packs"].append(name) + with open(index_path, "w") as index_file: + json.dump(index_data, index_file, indent=" ") + print(f"Added {name} to {index_path}") + + +def make_sticker(mxc: str, width: int, height: int, size: int, + body: str = "") -> matrix.StickerInfo: + return { + "body": body, + "url": mxc, + "info": { + "w": width, + "h": height, + "size": size, + "mimetype": "image/png", + + # Element iOS compatibility hack + "thumbnail_url": mxc, + "thumbnail_info": { + "w": width, + "h": height, + "size": size, + "mimetype": "image/png", + }, + }, + } |
