Optimized for API

This commit is contained in:
Profitroll 2023-01-17 14:11:23 +01:00
parent 9f0ed202da
commit aebe804b58
7 changed files with 156 additions and 36 deletions

View File

@ -25,6 +25,7 @@
"location": "logs" "location": "logs"
}, },
"locations": { "locations": {
"tmp": "tmp",
"data": "data", "data": "data",
"cache": "cache", "cache": "cache",
"sent": "data/sent", "sent": "data/sent",
@ -67,10 +68,7 @@
"address": "http://localhost:8054", "address": "http://localhost:8054",
"username": "", "username": "",
"password": "", "password": "",
"albums": { "album": ""
"queue": "poster_queue",
"sent": "poster_sent"
}
} }
}, },
"caption": { "caption": {

View File

@ -19,6 +19,9 @@
"sub_by": "\n\nSubmitted by:", "sub_by": "\n\nSubmitted by:",
"sub_sent": "Media has been submitted.\nWe'll notify you whether it will be accepted or not soon.", "sub_sent": "Media has been submitted.\nWe'll notify you whether it will be accepted or not soon.",
"sub_cooldown": "You can only submit 1 media per {0} seconds", "sub_cooldown": "You can only submit 1 media per {0} seconds",
"sub_media_failed": "Could not upload submission to API. Please check logs for details.",
"sub_media_duplicates": "⚠️ Image duplicates found",
"sub_media_duplicates_list": "It seems like following image has duplicates in API's Db.\n\nNext files marked as similar:\n • {0}",
"document_too_large": "File you've sent is too large. Please submit files not bigger than {0} MB", "document_too_large": "File you've sent is too large. Please submit files not bigger than {0} MB",
"mime_not_allowed": "File type not allowed. Please, consider using one of these: {0}", "mime_not_allowed": "File type not allowed. Please, consider using one of these: {0}",
"post_exception": "Could not send content due to `{exp}`\n\nTraceback:\n```{0}```", "post_exception": "Could not send content due to `{exp}`\n\nTraceback:\n```{0}```",

View File

@ -19,6 +19,9 @@
"sub_by": "\n\nПредставлено:", "sub_by": "\n\nПредставлено:",
"sub_sent": "Медіа-файл надіслано.\nСкоро ми повідомимо вас, чи буде його прийнято.", "sub_sent": "Медіа-файл надіслано.\nСкоро ми повідомимо вас, чи буде його прийнято.",
"sub_cooldown": "Ви можете надсилати лише 1 медіафайл на {0} секунд", "sub_cooldown": "Ви можете надсилати лише 1 медіафайл на {0} секунд",
"sub_media_failed": "Не вдалося завантажити подання на сервер. Перевірте логи для деталей.",
"sub_media_duplicates": "⚠️ Знайдено зображення-дублікати",
"sub_media_duplicates_list": "Здається, подане зображення має дублікати в базі даних.\n\nНаступні файли було відмічено як дуже схожі з поданням:\n • {0}",
"document_too_large": "Надісланий файл завеликий. Будь ласка, надсилайте файли не більше {0} Мб", "document_too_large": "Надісланий файл завеликий. Будь ласка, надсилайте файли не більше {0} Мб",
"mime_not_allowed": "Тип файлу не дозволений. Розгляньте можливість використання одного з цих: {0}", "mime_not_allowed": "Тип файлу не дозволений. Розгляньте можливість використання одного з цих: {0}",
"post_exception": "Не вдалося надіслати контент через `{exp}`\n\nTraceback:\n```{0}```", "post_exception": "Не вдалося надіслати контент через `{exp}`\n\nTraceback:\n```{0}```",

60
modules/api_client.py Normal file
View File

@ -0,0 +1,60 @@
from os import makedirs, path, sep
from base64 import b64encode, b64decode
from random import choice
from typing import Tuple
from requests import get, post, put, patch
from modules.utils import configGet
def authorize() -> str:
makedirs(configGet("cache", "locations"), exist_ok=True)
if path.exists(configGet("cache", "locations")+sep+"api_access") is True:
with open(configGet("cache", "locations")+sep+"api_access", "rb") as file:
token = b64decode(file.read()).decode("utf-8")
if "user" in get(configGet("address", "posting", "api")+"/users/me/", headers={"Authorization": f"Bearer {token}"}).json():
return token
payload = {
"grant_type": "password",
"scope": "me albums.list albums.read albums.write photos.list photos.read photos.write videos.list videos.read videos.write",
"username": configGet("username", "posting", "api"),
"password": configGet("password", "posting", "api")
}
response = post(configGet("address", "posting", "api")+"/token", data=payload).json()
with open(configGet("cache", "locations")+sep+"api_access", "wb") as file:
file.write(b64encode(response["access_token"].encode("utf-8")))
return response["access_token"]
def random_pic() -> Tuple[str, str]:
"""Returns random image id and filename from the queue.
### Returns:
* `Tuple[str, str]`: First value is an ID and the filename in the filesystem to be indexed.
"""
token = authorize()
pic = choice(get(f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos?q=&page_size=100&caption=queue', headers={"Authorization": f"Bearer {token}"}).json()["results"])
return pic["id"], pic["filename"]
def upload_pic(filepath: str) -> bool:
token = authorize()
try:
pic_name = path.basename(filepath)
files = {'file': (pic_name, open(filepath, 'rb'), 'image/jpeg')}
response = post(f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos&caption=queue', headers={"Authorization": f"Bearer {token}"}, files=files).json()
print(response, flush=True)
duplicates = []
if "duplicates" in response:
for duplicate in response["duplicates"]:
duplicates.append(f'{configGet("address", "posting", "api")}/photos/{duplicate["id"]}')
return True, duplicates
except:
return False, []
def move_pic(id: str) -> bool:
token = authorize()
try:
patch(f'{configGet("address", "posting", "api")}/photos/{id}?caption=sent', headers={"Authorization": f"Bearer {token}"})
return True
except:
return False
if __name__ == "__main__":
print(authorize())

View File

@ -3,6 +3,7 @@ from pathlib import Path
from pyrogram import filters from pyrogram import filters
from pyrogram.client import Client from pyrogram.client import Client
from pyrogram.types import CallbackQuery from pyrogram.types import CallbackQuery
from modules.api_client import upload_pic
from modules.utils import jsonLoad, jsonSave, configGet, locale from modules.utils import jsonLoad, jsonSave, configGet, locale
from modules.submissions import subBlock, subUnblock from modules.submissions import subBlock, subUnblock
from modules.app import app from modules.app import app
@ -18,11 +19,25 @@ async def callback_query_yes(app: Client, clb: CallbackQuery):
await clb.answer(text=locale("sub_msg_unavail", "message", locale=user_locale), show_alert=True) await clb.answer(text=locale("sub_msg_unavail", "message", locale=user_locale), show_alert=True)
return return
try: try:
media = await app.download_media(submission, file_name=configGet("queue", "locations")+sep) if configGet("api_based", "mode") is True:
if clb.data.endswith("_caption"): media = await app.download_media(submission, file_name=configGet("tmp", "locations")+sep)
index = jsonLoad(configGet("index", "locations")) upload = upload_pic(media)
index["captions"][Path(media).name] = submission.caption if upload[0] is False:
jsonSave(index, configGet("index", "locations")) await clb.answer(text=locale("sub_media_failed", "message", locale=user_locale), show_alert=True)
elif len(upload[1]) > 0:
await clb.answer(text=locale("sub_media_duplicates", "message", locale=user_locale))
await clb.message.reply_text(locale("sub_media_duplicates_list", "message", locale=user_locale).format("\n".join(upload[1])))
else:
if clb.data.endswith("_caption"):
index = jsonLoad(configGet("index", "locations"))
index["captions"][Path(media).name] = submission.caption
jsonSave(index, configGet("index", "locations"))
else:
media = await app.download_media(submission, file_name=configGet("queue", "locations")+sep)
if clb.data.endswith("_caption"):
index = jsonLoad(configGet("index", "locations"))
index["captions"][Path(media).name] = submission.caption
jsonSave(index, configGet("index", "locations"))
except: except:
await clb.answer(text=locale("sub_media_unavail", "message", locale=user_locale), show_alert=True) await clb.answer(text=locale("sub_media_unavail", "message", locale=user_locale), show_alert=True)
return return

View File

@ -1,10 +1,12 @@
from os import listdir, sep from os import listdir, remove, sep
from random import choice from random import choice
from shutil import move from shutil import copyfileobj, move
from requests import get
from traceback import format_exc from traceback import format_exc
from pyrogram.client import Client from pyrogram.client import Client
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from modules.logger import logWrite from modules.logger import logWrite
from modules.api_client import authorize, move_pic, random_pic
from modules.utils import jsonLoad, jsonSave, configGet, locale from modules.utils import jsonLoad, jsonSave, configGet, locale
async def send_content(app: Client): async def send_content(app: Client):
@ -13,40 +15,66 @@ async def send_content(app: Client):
try: try:
index = jsonLoad(configGet("index", "locations")) index = jsonLoad(configGet("index", "locations"))
list_queue = listdir(configGet("queue", "locations"))
for file in list_queue: if configGet("api_based", "mode"):
if not file in index["sent"]: try:
pic = random_pic()
except:
logWrite(locale("post_empty", "console", locale=configGet("locale")))
if configGet("error", "reports"):
await app.send_message(configGet("admin"), locale("post_empty", "message", locale=configGet("locale")))
return
ext_match = False token = authorize()
for ext in configGet("photo", "posting", "extensions"): response = get(f'{configGet("address", "posting", "api")}/photos/{pic[0]}', headers={"Authorization": f"Bearer {token}"}, stream=True)
if file.endswith(ext):
ext_match = True
ext_type = "photo"
break
for ext in configGet("video", "posting", "extensions"): with open(configGet("tmp", "locations")+sep+pic[0]+".jpg", 'wb') as out_file:
if file.endswith(ext): copyfileobj(response.raw, out_file)
ext_match = True
ext_type = "video"
break
if not ext_match: del response
candidate = configGet("tmp", "locations")+sep+pic[0]+".jpg"
candidate_file = pic[1]
ext_type = "photo"
if not configGet("api_based", "mode"):
list_queue = listdir(configGet("queue", "locations"))
for file in list_queue:
if not file in index["sent"]:
ext_match = False
for ext in configGet("photo", "posting", "extensions"):
if file.endswith(ext):
ext_match = True
ext_type = "photo"
break
for ext in configGet("video", "posting", "extensions"):
if file.endswith(ext):
ext_match = True
ext_type = "video"
break
if not ext_match:
list_queue.remove(file)
else:
list_queue.remove(file) list_queue.remove(file)
if len(list_queue) > 0:
candidate_file = choice(list_queue)
candidate = configGet("queue", "locations")+sep+candidate_file
else: else:
list_queue.remove(file) logWrite(locale("post_empty", "console", locale=configGet("locale")))
if configGet("error", "reports"):
if len(list_queue) > 0: await app.send_message(configGet("admin"), locale("post_empty", "message", locale=configGet("locale")))
candidate_file = choice(list_queue) return
candidate = configGet("queue", "locations")+sep+candidate_file
else:
logWrite(locale("post_empty", "console", locale=configGet("locale")))
if configGet("error", "reports"):
await app.send_message(configGet("admin"), locale("post_empty", "message", locale=configGet("locale")))
return
if candidate_file in index["captions"]: if candidate_file in index["captions"]:
caption = index["captions"][candidate_file] caption = index["captions"][candidate_file]
@ -84,6 +112,10 @@ async def send_content(app: Client):
else: else:
return return
if configGet("api_based", "mode"):
remove(configGet("tmp", "locations")+sep+pic[0]+".jpg")
move_pic(pic[0])
index["sent"].append(candidate_file) index["sent"].append(candidate_file)
index["last_id"] = sent.id index["last_id"] = sent.id

View File

@ -70,6 +70,7 @@ if args.norun:
try: try:
from modules.app import app from modules.app import app
from pyrogram import idle from pyrogram import idle
from requests import get, post
except ModuleNotFoundError: except ModuleNotFoundError:
print(locale("deps_missing", "console", locale=configGet("locale")), flush=True) print(locale("deps_missing", "console", locale=configGet("locale")), flush=True)
exit() exit()
@ -122,6 +123,9 @@ if configGet("submit", "mode"):
from modules.callbacks.submission import * from modules.callbacks.submission import *
from modules.commands.mode_submit import * from modules.commands.mode_submit import *
from modules.handlers.submission import * from modules.handlers.submission import *
if configGet("api_based", "mode"):
from modules.api_client import authorize
#=========================================================================================================================================== #===========================================================================================================================================
# Work in progress # Work in progress
@ -147,6 +151,11 @@ if __name__ == "__main__":
if configGet("post", "mode"): if configGet("post", "mode"):
scheduler.start() scheduler.start()
if configGet("api_based", "mode"):
token = authorize()
if len(get(f'{configGet("address", "posting", "api")}/albums?q={configGet("queue", "posting", "api", "albums")}', headers={"Authorization": f"Bearer {token}"}).json()["results"]) == 0:
post(f'{configGet("address", "posting", "api")}/albums?name={configGet("queue", "posting", "api", "albums")}&title={configGet("queue", "posting", "api", "albums")}', headers={"Authorization": f"Bearer {token}"})
idle() idle()
app.send_message(configGet("admin"), locale("shutdown", "message", locale=configGet("locale")).format(str(pid))) app.send_message(configGet("admin"), locale("shutdown", "message", locale=configGet("locale")).format(str(pid)))