mirror of
				https://github.com/maunium/stickerpicker.git
				synced 2025-10-31 08:58:09 +01:00 
			
		
		
		
	
							
								
								
									
										0
									
								
								sticker/lib/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								sticker/lib/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										77
									
								
								sticker/lib/matrix.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								sticker/lib/matrix.py
									
									
									
									
									
										Normal file
									
								
							| @@ -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"] | ||||
							
								
								
									
										67
									
								
								sticker/lib/util.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								sticker/lib/util.py
									
									
									
									
									
										Normal file
									
								
							| @@ -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", | ||||
|             }, | ||||
|         }, | ||||
|     } | ||||
		Reference in New Issue
	
	Block a user