feat: refactor rentry paste and implement cleanup job
This commit is contained in:
3
main.py
3
main.py
@@ -59,6 +59,7 @@ from utils import config
|
|||||||
from utils.db import db
|
from utils.db import db
|
||||||
from utils.misc import gitrepo, userbot_version
|
from utils.misc import gitrepo, userbot_version
|
||||||
from utils.scripts import restart, load_module
|
from utils.scripts import restart, load_module
|
||||||
|
from utils.rentry import rentry_cleanup_job
|
||||||
|
|
||||||
SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__))
|
SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__))
|
||||||
if SCRIPT_PATH != os.getcwd():
|
if SCRIPT_PATH != os.getcwd():
|
||||||
@@ -183,6 +184,8 @@ async def main():
|
|||||||
|
|
||||||
logging.info("Moon-Userbot started!")
|
logging.info("Moon-Userbot started!")
|
||||||
|
|
||||||
|
app.loop.create_task(rentry_cleanup_job())
|
||||||
|
|
||||||
await idle()
|
await idle()
|
||||||
|
|
||||||
await app.stop()
|
await app.stop()
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ from pyrogram.types import Message
|
|||||||
|
|
||||||
from utils.misc import modules_help, prefix
|
from utils.misc import modules_help, prefix
|
||||||
from utils.scripts import edit_or_reply, format_exc, progress
|
from utils.scripts import edit_or_reply, format_exc, progress
|
||||||
from utils.rentry import new
|
from utils.rentry import paste as rentry_paste
|
||||||
|
|
||||||
|
|
||||||
async def read_file(file_path):
|
async def read_file(file_path):
|
||||||
@@ -96,17 +96,20 @@ async def openfile(client: Client, message: Message):
|
|||||||
"<code>File Content is too long... Pasting to rentry...</code>"
|
"<code>File Content is too long... Pasting to rentry...</code>"
|
||||||
)
|
)
|
||||||
content_new = f"```{code_start[11:-2]}\n{content}```"
|
content_new = f"```{code_start[11:-2]}\n{content}```"
|
||||||
paste = new(url="", edit_code="", text=content_new)
|
try:
|
||||||
if paste["status"] != "200":
|
rentry_url, edit_code = await rentry_paste(
|
||||||
await ms.edit_text(f"<b>Error:</b> <code>{paste['content']}</code>")
|
text=content_new, return_edit=True
|
||||||
|
)
|
||||||
|
except RuntimeError:
|
||||||
|
await ms.edit_text("<b>Error:</b> <code>Failed to paste to rentry</code>")
|
||||||
return
|
return
|
||||||
await client.send_message(
|
await client.send_message(
|
||||||
"me",
|
"me",
|
||||||
f"Here's your edit code for Url: {paste['url']}\nEdit code: <code>{paste['edit_code']}</code>",
|
f"Here's your edit code for Url: {rentry_url}\nEdit code: <code>{edit_code}</code>",
|
||||||
disable_web_page_preview=True,
|
disable_web_page_preview=True,
|
||||||
)
|
)
|
||||||
await ms.edit_text(
|
await ms.edit_text(
|
||||||
f"<b>File Name:</b> <code>{file_name[0]}</code>\n<b>Size:</b> <code>{file_size} bytes</code>\n<b>Last Modified:</b> <code>{last_modified}</code>\n<b>Content:</b> {paste['url']}\n<b>Note:</b> <code>Edit Code has been sent to your saved messages</code>",
|
f"<b>File Name:</b> <code>{file_name[0]}</code>\n<b>Size:</b> <code>{file_size} bytes</code>\n<b>Last Modified:</b> <code>{last_modified}</code>\n<b>Content:</b> {rentry_url}\n<b>Note:</b> <code>Edit Code has been sent to your saved messages</code>",
|
||||||
disable_web_page_preview=True,
|
disable_web_page_preview=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
126
utils/rentry.py
126
utils/rentry.py
@@ -1,13 +1,18 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
# @source: https://github.com/radude/rentry/blob/master/rentry.py
|
# @source: https://github.com/radude/rentry/blob/master/rentry.py
|
||||||
|
import asyncio
|
||||||
import http.cookiejar
|
import http.cookiejar
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
|
||||||
|
from uuid import uuid4
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from http.cookies import SimpleCookie
|
from http.cookies import SimpleCookie
|
||||||
from json import loads as json_loads
|
from json import loads as json_loads
|
||||||
|
|
||||||
|
from utils.db import db
|
||||||
|
|
||||||
BASE_PROTOCOL = "https://"
|
BASE_PROTOCOL = "https://"
|
||||||
BASE_URL = "rentry.co"
|
BASE_URL = "rentry.co"
|
||||||
|
|
||||||
@@ -44,12 +49,12 @@ class UrllibClient:
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def raw(url):
|
def raw(url: str):
|
||||||
client = UrllibClient()
|
client = UrllibClient()
|
||||||
return json_loads(client.get(f"{BASE_PROTOCOL}{BASE_URL}/api/raw/{url}").data)
|
return json_loads(client.get(f"{BASE_PROTOCOL}{BASE_URL}/api/raw/{url}").data)
|
||||||
|
|
||||||
|
|
||||||
def new(url, edit_code, text):
|
def new(text: str, edit_code: str = "", url: str = ""):
|
||||||
client, cookie = UrllibClient(), SimpleCookie()
|
client, cookie = UrllibClient(), SimpleCookie()
|
||||||
|
|
||||||
cookie.load(vars(client.get(f"{BASE_PROTOCOL}{BASE_URL}"))["headers"]["Set-Cookie"])
|
cookie.load(vars(client.get(f"{BASE_PROTOCOL}{BASE_URL}"))["headers"]["Set-Cookie"])
|
||||||
@@ -69,7 +74,7 @@ def new(url, edit_code, text):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def edit(url, edit_code, text):
|
def edit(url_short: str, edit_code: str, text: str):
|
||||||
client, cookie = UrllibClient(), SimpleCookie()
|
client, cookie = UrllibClient(), SimpleCookie()
|
||||||
|
|
||||||
cookie.load(vars(client.get(f"{BASE_PROTOCOL}{BASE_URL}"))["headers"]["Set-Cookie"])
|
cookie.load(vars(client.get(f"{BASE_PROTOCOL}{BASE_URL}"))["headers"]["Set-Cookie"])
|
||||||
@@ -79,6 +84,117 @@ def edit(url, edit_code, text):
|
|||||||
|
|
||||||
return json_loads(
|
return json_loads(
|
||||||
client.post(
|
client.post(
|
||||||
f"{BASE_PROTOCOL}{BASE_URL}/api/edit/{url}", payload, headers=_headers
|
f"{BASE_PROTOCOL}{BASE_URL}/api/edit/{url_short}", payload, headers=_headers
|
||||||
).data
|
).data
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def delete(url_short: str, edit_code: str):
|
||||||
|
client, cookie = UrllibClient(), SimpleCookie()
|
||||||
|
cookie.load(vars(client.get(f"{BASE_PROTOCOL}{BASE_URL}"))["headers"]["Set-Cookie"])
|
||||||
|
csrftoken = cookie["csrftoken"].value
|
||||||
|
payload = {"csrfmiddlewaretoken": csrftoken, "edit_code": edit_code}
|
||||||
|
return json_loads(
|
||||||
|
client.post(
|
||||||
|
f"{BASE_PROTOCOL}{BASE_URL}/api/delete/{url_short}",
|
||||||
|
payload,
|
||||||
|
headers=_headers,
|
||||||
|
).data
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def paste(
|
||||||
|
text: str,
|
||||||
|
return_edit: bool = False,
|
||||||
|
edit_bin: bool = False,
|
||||||
|
edit_code: str = None,
|
||||||
|
url: str = None,
|
||||||
|
permanent: bool = False,
|
||||||
|
) -> str | tuple[str, str]:
|
||||||
|
"""Pastes some text to rentry bin.
|
||||||
|
args:
|
||||||
|
text: Input text to paste
|
||||||
|
return_edit: If it should return edit code also
|
||||||
|
edit_bin: If this request is to edit an already existing bin
|
||||||
|
edit_code: Only required if edit_bin is True. It is the edit code used to edit bin.
|
||||||
|
url: Only required if edit_bin is True. It is the url on which the bin is located.
|
||||||
|
permanent: If the pasted content should not be deleted automatically
|
||||||
|
|
||||||
|
returns:
|
||||||
|
The url of the paste or return a tuple containing url and edit code
|
||||||
|
"""
|
||||||
|
if not str(text):
|
||||||
|
return
|
||||||
|
|
||||||
|
if edit_bin:
|
||||||
|
if not (url and edit_code):
|
||||||
|
raise ValueError("Please provide both, url and edit code")
|
||||||
|
response = edit(url_short=url, edit_code=edit_code, text=text)
|
||||||
|
else:
|
||||||
|
response = new(text=text)
|
||||||
|
|
||||||
|
if response.get("status") != "200":
|
||||||
|
raise RuntimeError(
|
||||||
|
f"paste task terminated with status: {response.get('status')}\n"
|
||||||
|
f"Message: {response.get('content', 'No message provided')}"
|
||||||
|
)
|
||||||
|
|
||||||
|
url = response["url"]
|
||||||
|
edit_code = response["edit_code"]
|
||||||
|
|
||||||
|
if not permanent:
|
||||||
|
short_url = response["url_short"]
|
||||||
|
time_now = datetime.now()
|
||||||
|
ftime = time_now.strftime("%d %I:%M:%S %p %Y")
|
||||||
|
|
||||||
|
print(f"URL: {url} - Edit Code: {edit_code} - Time: {ftime}")
|
||||||
|
|
||||||
|
rallUrls = db.get("core.rentry", "urls", default={"allUrls": {}})
|
||||||
|
entry_id = str(uuid4())
|
||||||
|
rallUrls["allUrls"][entry_id] = {
|
||||||
|
"url": short_url,
|
||||||
|
"edit_code": edit_code,
|
||||||
|
"time": ftime,
|
||||||
|
}
|
||||||
|
db.set("core.rentry", "urls", rallUrls)
|
||||||
|
|
||||||
|
if return_edit:
|
||||||
|
return (url, edit_code)
|
||||||
|
return url
|
||||||
|
|
||||||
|
|
||||||
|
async def rentry_cleanup_job():
|
||||||
|
"""Periodically checks and deletes rentry pastes older than 24 hours"""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
rallUrls = db.get("core.rentry", "urls", default={"allUrls": {}})
|
||||||
|
now = datetime.now()
|
||||||
|
deleted_count = 0
|
||||||
|
error_count = 0
|
||||||
|
|
||||||
|
for entry_id, entry in list(rallUrls["allUrls"].items()):
|
||||||
|
url = entry["url"]
|
||||||
|
entry_time = datetime.strptime(entry["time"], "%d %I:%M:%S %p %Y")
|
||||||
|
|
||||||
|
if now - entry_time > timedelta(days=1):
|
||||||
|
try:
|
||||||
|
delete(url, entry["edit_code"])
|
||||||
|
del rallUrls["allUrls"][entry_id]
|
||||||
|
deleted_count += 1
|
||||||
|
print(f"[#] Deleted expired rentry paste: {url}")
|
||||||
|
except Exception as e:
|
||||||
|
error_count += 1
|
||||||
|
print(f"[!] Failed to delete rentry paste {url}: {str(e)}")
|
||||||
|
|
||||||
|
if deleted_count or error_count:
|
||||||
|
print(
|
||||||
|
f"[*] Cleanup summary: {deleted_count} deleted, {error_count} failed"
|
||||||
|
)
|
||||||
|
|
||||||
|
if deleted_count:
|
||||||
|
db.set("core.rentry", "urls", rallUrls)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[!] Error in rentry cleanup job: {str(e)}")
|
||||||
|
|
||||||
|
await asyncio.sleep(12 * 60 * 60)
|
||||||
|
|||||||
Reference in New Issue
Block a user