Added and updated repositories 2026-01-10 01:09:56

This commit is contained in:
github-actions[bot]
2026-01-10 01:09:56 +00:00
parent 1c99e02dd0
commit 572fb61011
67 changed files with 5294 additions and 1704 deletions

View File

@@ -1,6 +1,6 @@
# Proprietary License Agreement
# Copyright (c) 2024-29 CodWiz
# Copyright (c) 2026-2029 Archquise
# Permission is hereby granted to any person obtaining a copy of this software and associated documentation files (the "Software"), to use the Software for personal and non-commercial purposes, subject to the following conditions:
@@ -14,39 +14,50 @@
# 5. By using the Software, you agree to be bound by the terms and conditions of this license.
# For any inquiries or requests for permissions, please contact codwiz@yandex.ru.
# For any inquiries or requests for permissions, please contact archquise@gmail.com
# ---------------------------------------------------------------------------------
# Name: Shortener
# Description: shortening the link
# Description: Module for using bit.ly API
# Author: @hikka_mods
# ---------------------------------------------------------------------------------
# meta developer: @hikka_mods
# scope: Shortener
# scope: Shortener 0.0.1
# requires: pyshorteners
# ---------------------------------------------------------------------------------
import pyshorteners
import logging
import re
import aiohttp
from .. import loader, utils
logger = logging.getLogger(__name__)
@loader.tds
class Shortener(loader.Module):
"""Module for working with the api bit.ly"""
"""Module for using bit.ly API"""
strings = {
"name": "Shortener",
"no_api": "<emoji document_id=5854929766146118183>❌</emoji> You have not specified an API token from the site <a href='https://app.bitly.com/settings/api/'>bit.ly</a>",
"statclcmd": "<emoji document_id=5787384838411522455>📊</emoji> <b>Statistics on clicks for this link:</b> {c}",
"shortencmd": "<emoji document_id=5854762571659218443>✅</emoji> <b>Your shortened link is ready:</b> <code>{c}</code>",
"no_args": "<emoji document_id=5854929766146118183>❌</emoji> Please provide a URL to shorten.",
"invalid_url": "<emoji document_id=5854929766146118183>❌</emoji> Invalid URL format.",
"api_error": "<emoji document_id=5854929766146118183>❌</emoji> API error: {error}",
"_cls_doc": "Module for using bit.ly API",
}
strings_ru = {
"no_api": "<emoji document_id=5854929766146118183>❌</emoji> Вы не указали api токен с сайта <a href='https://app.bitly.com/settings/api/'>bit.ly</a>",
"statclcmd": "<emoji document_id=5787384838411522455>📊</emoji> <b>Статистика о переходе по этой ссылке:</b> {c}",
"shortencmd": "<emoji document_id=5854762571659218443>✅</emoji> <b>Ваша сокращённая ссылка готова:</b> <code>{c}</code>",
"no_args": "<emoji document_id=5854929766146118183>❌</emoji> Пожалуйста, укажите URL для сокращения.",
"invalid_url": "<emoji document_id=5854929766146118183>❌</emoji> Неверный формат URL.",
"api_error": "<emoji document_id=5854929766146118183>❌</emoji> Ошибка API: {error}",
"_cls_doc": "Модуль для использования API bit.ly",
}
def __init__(self):
@@ -59,32 +70,93 @@ class Shortener(loader.Module):
)
)
def _validate_url(self, url: str) -> bool:
"""Validate URL format"""
if not url:
return False
url_pattern = re.compile(
r"^https?://"
r"(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|"
r"localhost|"
r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"
r"(?::\d+)?"
r"(?:/?|[/?]\S+)$",
re.IGNORECASE,
)
return url_pattern.match(url) is not None
async def shorten_url(self, url: str, token: str) -> str:
async with aiohttp.ClientSession() as session:
async with session.post("https://api-ssl.bitly.com/v4/shorten", json={'long_url': url}, headers={"Authorization": f"Bearer {token}"}) as resp:
if resp.status == 201:
json_response = await resp.json()
return json_response['link']
else:
logger.error(f"Error occurred! Status code: {resp.status}")
return
async def get_bitlink_stats(self, bitlink: str, token: str) -> str:
async with aiohttp.ClientSession() as session:
async with session.get(f"https://api-ssl.bitly.com/v4/bitlinks/{bitlink}/clicks/summary", headers={"Authorization": f"Bearer {token}"}) as resp:
if resp.status == 200:
json_response = await resp.json()
return json_response['total_clicks']
else:
logger.error(f"Error occurred! Status code: {resp.status}")
return
@loader.command(
ru_doc="Сократить ссылку через bit.ly",
en_doc="Shorten the link via bit.ly",
ru_doc="Сократить ссылку через bit.ly (ссылка с https://)",
en_doc="Shorten the link via bit.ly (url with https://)",
)
async def shortencmd(self, message):
"""Shorten URL using bit.ly API"""
if self.config["token"] is None:
await utils.answer(message, self.strings("no_api"))
return
s = pyshorteners.Shortener(api_key=self.config["token"])
args = utils.get_args_raw(message)
await utils.answer(
message, self.strings("shortencmd").format(c=s.bitly.short(args))
)
if not args:
await utils.answer(message, self.strings("no_args"))
return
if not self._validate_url(args):
await utils.answer(message, self.strings("invalid_url"))
return
try:
short_url = await self.shorten_url(url=args, token=self.config['token'])
await utils.answer(message, self.strings("shortencmd").format(c=short_url))
except Exception as e:
logger.error(f"Error shortening URL: {e}")
await utils.answer(message, self.strings("api_error").format(error=str(e)))
@loader.command(
ru_doc="Посмотреть статистику ссылки через bit.ly",
en_doc="View link statistics via bit.ly",
ru_doc="Посмотреть статистику ссылки через bit.ly (ссылка без https:// | Доступно только на платных аккаунтах)",
en_doc="View link statistics via bit.ly (link without https:// | Works only on paid accounts)",
)
async def statclcmd(self, message):
"""Get click statistics for shortened URL"""
if self.config["token"] is None:
await utils.answer(message, self.strings("no_api"))
return
s = pyshorteners.Shortener(api_key=self.config["token"])
args = utils.get_args_raw(message)
await utils.answer(
message, self.strings("statclcmd").format(c=s.bitly.total_clicks(args))
)
if not args:
await utils.answer(message, self.strings("no_args"))
return
try:
if not args.startswith("bit.ly/"):
await utils.answer(message, self.strings("invalid_url"))
return
else:
clicks = await self.get_bitlink_stats(bitlink=args, token=self.config['token'])
await utils.answer(message, self.strings("statclcmd").format(c=clicks))
except Exception as e:
logger.error(f"Error getting statistics: {e}")
await utils.answer(message, self.strings("api_error").format(error=str(e)))