diff --git a/hikka/langpacks/de.yml b/hikka/langpacks/de.yml
index b514b31..aab2993 100644
--- a/hikka/langpacks/de.yml
+++ b/hikka/langpacks/de.yml
@@ -321,15 +321,6 @@ test:
logs_cleared: "🗑 Logs wurden gelöscht "
_cmd_doc_clearlogs: "Löscht die Logs"
-update_notifier:
- update_required: "🆕 Ein Heroku-Update ist verfügbar! \n\nEine neue Version von Heroku wurde veröffentlicht.\n🔮 Heroku {} -> {} \n\n{}"
- more: "\n🎥 Und noch {}... "
- _cfg_doc_disable_notifications: "Update-Benachrichtigungen deaktivieren"
- latest_disabled: "Benachrichtigungen über das neueste Update wurden deaktiviert"
- update: "🔄 Aktualisieren"
- ignore: "🚫 Ignorieren"
- changelog: '📰 Änderungsprotokoll des letzten großen Updates:
{}
'
-
updater:
source: "📖 Den Quellcode kannst du hier einsehen "
restarting_caption: "🕗 Dein {} wird neu gestartet... "
@@ -354,7 +345,15 @@ updater:
_cmd_doc_restart: "Startet den Userbot neu"
_cmd_doc_source: "Zeigt den Link zum Quellcode des Projekts"
_cmd_doc_update: "Lädt Updates für den Userbot herunter"
-
+ _cmd_doc_rollback: "Macht Userbot-Updates rückgängig"
+ update_required: "🆕 Ein Heroku-Update ist verfügbar! \n\nEine neue Version von Heroku wurde veröffentlicht.\n🔮 Heroku {} -> {} \n\n{}"
+ more: "\n🎥 Und noch {}... "
+ _cfg_doc_disable_notifications: "Update-Benachrichtigungen deaktivieren"
+ latest_disabled: "Benachrichtigungen über das neueste Update wurden deaktiviert"
+ update: "🔄 Aktualisieren"
+ ignore: "🚫 Ignorieren"
+ changelog: '📰 Änderungsprotokoll des letzten großen Updates: {}
'
+
api_protection:
warning: "⚠️ ACHTUNG! \n\nDas Konto hat die in der Konfiguration angegebenen Anfrageratenlimits überschritten. Um Telegram API-Fluten zu vermeiden, wurde der Userbot vollständig eingefroren für {} Sekunden. Weitere Informationen befinden sich in der beigefügten Datei unten. \n\nEs wird empfohlen, die Hilfe der {prefix}support
Gruppe in Anspruch zu nehmen!\n\nWenn du davon ausgehst, dass dies ein geplantes Verhalten des Userbots ist, warte einfach, bis der Timer abläuft, und beim nächsten Mal, wenn du eine ressourcenintensive Aufgabe planst, benutze {prefix}suspend_api_protect
Zeit in Sekunden"
args_invalid: "🚫 Ungültige Argumente "
diff --git a/hikka/langpacks/en.yml b/hikka/langpacks/en.yml
index b0fd102..e56f780 100644
--- a/hikka/langpacks/en.yml
+++ b/hikka/langpacks/en.yml
@@ -341,17 +341,6 @@ test:
_cmd_doc_suspend: " - Suspends the bot for N seconds"
_cls_doc: "Perform operations based on userbot self-testing"
-update_notifier:
- name: "UpdateNotifier"
- update_required: "🆕 Heroku Update available! \n\nNew Heroku version released.\n🔮 Heroku {} -> {} \n\n{}"
- more: "\n🎥 And {} more... "
- _cfg_doc_disable_notifications: "Disable update notifications"
- latest_disabled: "Notifications about the latest update have been suppressed"
- update: "🔄 Update"
- ignore: "🚫 Ignore"
- changelog: '📰 Changelog of the last major update: {}
'
- _cls_doc: "Tracks latest Heroku releases, and notifies you, if update is required"
-
updater:
name: "Updater"
source: "📖 Read the source code from here "
@@ -376,7 +365,16 @@ updater:
_cmd_doc_restart: "Restarts the userbot"
_cmd_doc_source: "Links the source code of this project"
_cmd_doc_update: "Downloads userbot updates"
- _cls_doc: "Updates itself"
+ _cmd_doc_rollback: "Rollbacks userbot updates"
+ _cls_doc: "Updates itself, tracks latest Heroku releases, and notifies you, if update is required"
+ update_required: "🆕 Heroku Update available! \n\nNew Heroku version released.\n🔮 Heroku {} -> {} \n\n{}"
+ more: "\n🎥 And {} more... "
+ _cfg_doc_disable_notifications: "Disable update notifications"
+ latest_disabled: "Notifications about the latest update have been suppressed"
+ update: "🔄 Update"
+ ignore: "🚫 Ignore"
+ changelog: '📰 Changelog of the last major update: {}
'
+
api_protection:
name: "APILimiter"
diff --git a/hikka/langpacks/ru.yml b/hikka/langpacks/ru.yml
index c76dd40..6d17cd7 100644
--- a/hikka/langpacks/ru.yml
+++ b/hikka/langpacks/ru.yml
@@ -345,6 +345,7 @@ updater:
_cmd_doc_restart: "Перезагружает юзербот"
_cmd_doc_source: "Показать ссылку на исходный код проекта"
_cmd_doc_update: "Скачивает обновления юзербота"
+ _cmd_doc_rollback: "Откатывает обновления юзербота"
api_protection:
warning: "⚠️ ВНИМАНИЕ! \n\nАккаунт вышел за лимиты запросов, указанные в конфиге. С целью предотвращения флуда Telegram API, юзербот был полностью заморожен на {} секунд. Дополнительная информация прикреплена в файле ниже. \n\nРекомендуется обратиться за помощью в {prefix}support
группу!\n\nЕсли ты считаешь, что это запланированное поведение юзербота, просто подожди, пока закончится таймер и в следующий раз, когда запланируешь выполнять такую ресурсозатратную операцию, используй {prefix}suspend_api_protect
<время в секундах>"
diff --git a/hikka/langpacks/ua.yml b/hikka/langpacks/ua.yml
index ac36d68..97c0b3d 100644
--- a/hikka/langpacks/ua.yml
+++ b/hikka/langpacks/ua.yml
@@ -321,15 +321,6 @@ test:
logs_cleared: "🗑 Логи очищено "
_cmd_doc_clearlogs: "Очистити логи"
-update_notifier:
- update_required: "🆕 Доступне оновлення Heroku! \n\nОпубліковано нову версію Heroku.\n🔮 Heroku {} -> {} \n\n{}"
- more: "\n🎥 І ще {}... "
- _cfg_doc_disable_notifications: "Вимкнути сповіщення про оновлення"
- latest_disabled: "Повідомлення про останнє оновлення було вимкнено"
- update: "🔄 Оновити"
- ignore: "🚫 Ігнорувати"
- changelog: '📰 Список змін останнього великого оновлення: {}
'
-
updater:
source: "📖 Вихідний код можна прочитати тут "
restarting_caption: "🕗 Твоя {} перезавантажується... "
@@ -354,6 +345,15 @@ updater:
_cmd_doc_restart: "Перезавантажує юзербот"
_cmd_doc_source: "Показати посилання на вихідний код проекту"
_cmd_doc_update: "Завантажує оновлення юзербота"
+ _cmd_doc_rollback: "Откатывает обновления юзербота"
+ update_required: "🆕 Доступне оновлення Heroku! \n\nОпубліковано нову версію Heroku.\n🔮 Heroku {} -> {} \n\n{}"
+ more: "\n🎥 І ще {}... "
+ _cfg_doc_disable_notifications: "Вимкнути сповіщення про оновлення"
+ latest_disabled: "Повідомлення про останнє оновлення було вимкнено"
+ update: "🔄 Оновити"
+ ignore: "🚫 Ігнорувати"
+ changelog: '📰 Список змін останнього великого оновлення: {}
'
+
api_protection:
warning: "⚠️ УВАГА! \n\nАкаунт вийшов за ліміти запитів, зазначені в конфігурації. З метою запобігання флуду Telegram API, юзербот був повністю заморожений на {} секунд. Додаткова інформація прикріплена у файлі нижче. \n\nРекомендується звернутися по допомогу до {prefix}support
групу!\n\nЯкщо ти вважаєш, що це запланована поведінка юзербота, просто почекай, доки закінчиться таймер, і наступного разу, коли заплануєш виконувати таку ресурсовитратну операцію, використовуй {prefix}suspend_api_protect
<час у секундах>"
diff --git a/hikka/modules/update_notifier.py b/hikka/modules/update_notifier.py
deleted file mode 100644
index da03e44..0000000
--- a/hikka/modules/update_notifier.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# пасхалка
-# ©️ Dan Gazizullin, 2021-2023
-# This file is a part of Hikka Userbot
-# 🌐 https://github.com/hikariatama/Hikka
-# You can redistribute it and/or modify it under the terms of the GNU AGPLv3
-# 🔑 https://www.gnu.org/licenses/agpl-3.0.html
-
-import asyncio
-import contextlib
-
-import git
-
-from .. import loader, utils, version
-from ..inline.types import InlineCall
-from ..types import Message
-
-
-@loader.tds
-class UpdateNotifier(loader.Module):
- """Tracks latest Hikka releases, and notifies you, if update is required"""
-
- strings = {"name": "UpdateNotifier"}
-
- def __init__(self):
- self._notified = None
- self.config = loader.ModuleConfig(
- loader.ConfigValue(
- "disable_notifications",
- doc=lambda: self.strings("_cfg_doc_disable_notifications"),
- validator=loader.validators.Boolean(),
- )
- )
-
- def get_changelog(self) -> str:
- try:
- repo = git.Repo()
-
- for remote in repo.remotes:
- remote.fetch()
-
- if not (
- diff := repo.git.log([f"HEAD..origin/{version.branch}", "--oneline"])
- ):
- return False
- except Exception:
- return False
-
- res = "\n".join(
- f"{commit.split()[0]} :"
- f" {utils.escape_html(' '.join(commit.split()[1:]))} "
- for commit in diff.splitlines()[:10]
- )
-
- if diff.count("\n") >= 10:
- res += self.strings("more").format(len(diff.splitlines()) - 10)
-
- return res
-
- def get_latest(self) -> str:
- try:
- return next(
- git.Repo().iter_commits(f"origin/{version.branch}", max_count=1)
- ).hexsha
- except Exception:
- return ""
-
- async def client_ready(self):
- try:
- git.Repo()
- except Exception as e:
- raise loader.LoadError("Can't load due to repo init error") from e
-
- self._markup = lambda: self.inline.generate_markup(
- [
- {"text": self.strings("update"), "data": "heroku/update"},
- {"text": self.strings("ignore"), "data": "heroku/ignore_upd"},
- ]
- )
-
- @loader.loop(interval=60, autostart=True)
- async def poller(self):
- if self.config["disable_notifications"] or not self.get_changelog():
- return
-
- self._pending = self.get_latest()
-
- if (
- self.get("ignore_permanent", False)
- and self.get("ignore_permanent") == self._pending
- ):
- await asyncio.sleep(60)
- return
-
- if self._pending not in {utils.get_git_hash(), self._notified}:
- m = await self.inline.bot.send_animation(
- self.tg_id,
- "https://t.me/hikari_assets/71",
- caption=self.strings("update_required").format(
- utils.get_git_hash()[:6],
- '{} '.format(
- utils.get_git_hash()[:12],
- self.get_latest()[:12],
- self.get_latest()[:6],
- ),
- self.get_changelog(),
- ),
- reply_markup=self._markup(),
- )
-
- self._notified = self._pending
- self.set("ignore_permanent", False)
-
- await self._delete_all_upd_messages()
-
- self.set("upd_msg", m.message_id)
-
- async def _delete_all_upd_messages(self):
- for client in self.allclients:
- with contextlib.suppress(Exception):
- await client.loader.inline.bot.delete_message(
- client.tg_id,
- client.loader.db.get("UpdateNotifier", "upd_msg"),
- )
-
- @loader.callback_handler()
- async def update(self, call: InlineCall):
- """Process update buttons clicks"""
- if call.data not in {"heroku/update", "heroku/ignore_upd"}:
- return
-
- if call.data == "heroku/ignore_upd":
- self.set("ignore_permanent", self.get_latest())
- await call.answer(self.strings("latest_disabled"))
- return
-
- await self._delete_all_upd_messages()
-
- with contextlib.suppress(Exception):
- await call.delete()
-
- await self.invoke("update", "-f", peer=self.inline.bot_username)
-
- @loader.command()
- async def changelog(self, message: Message):
- """Shows the changelog of the last major update"""
- with open('CHANGELOG.md', mode='r', encoding='utf-8') as f:
- changelog = f.read().split('##')[1].strip()
- if (await self._client.get_me()).premium:
- changelog.replace('🌑 Heroku', '🌘 🌘 🌘 ')
-
- await utils.answer(message, self.strings('changelog').format(changelog))
diff --git a/hikka/modules/updater.py b/hikka/modules/updater.py
index 8295b5a..b44b0fb 100644
--- a/hikka/modules/updater.py
+++ b/hikka/modules/updater.py
@@ -31,20 +31,132 @@ logger = logging.getLogger(__name__)
@loader.tds
class UpdaterMod(loader.Module):
- """Updates itself"""
+ """Updates itself, tracks latest Heroku releases, and notifies you, if update is required"""
strings = {"name": "Updater"}
def __init__(self):
+ self._notified = None
self.config = loader.ModuleConfig(
loader.ConfigValue(
"GIT_ORIGIN_URL",
"https://github.com/coddrago/Heroku",
lambda: self.strings("origin_cfg_doc"),
validator=loader.validators.Link(),
+ ),
+ loader.ConfigValue(
+ "disable_notifications",
+ doc=lambda: self.strings("_cfg_doc_disable_notifications"),
+ validator=loader.validators.Boolean(),
)
)
+ def get_changelog(self) -> str:
+ try:
+ repo = git.Repo()
+
+ for remote in repo.remotes:
+ remote.fetch()
+
+ if not (
+ diff := repo.git.log([f"HEAD..origin/{version.branch}", "--oneline"])
+ ):
+ return False
+ except Exception:
+ return False
+
+ res = "\n".join(
+ f"{commit.split()[0]} :"
+ f" {utils.escape_html(' '.join(commit.split()[1:]))} "
+ for commit in diff.splitlines()[:10]
+ )
+
+ if diff.count("\n") >= 10:
+ res += self.strings("more").format(len(diff.splitlines()) - 10)
+
+ return res
+
+ def get_latest(self) -> str:
+ try:
+ return next(
+ git.Repo().iter_commits(f"origin/{version.branch}", max_count=1)
+ ).hexsha
+ except Exception:
+ return ""
+
+ @loader.loop(interval=60, autostart=True)
+ async def poller(self):
+ if self.config["disable_notifications"] or not self.get_changelog():
+ return
+
+ self._pending = self.get_latest()
+
+ if (
+ self.get("ignore_permanent", False)
+ and self.get("ignore_permanent") == self._pending
+ ):
+ await asyncio.sleep(60)
+ return
+
+ if self._pending not in {utils.get_git_hash(), self._notified}:
+ m = await self.inline.bot.send_animation(
+ self.tg_id,
+ "https://t.me/hikari_assets/71",
+ caption=self.strings("update_required").format(
+ utils.get_git_hash()[:6],
+ '{} '.format(
+ utils.get_git_hash()[:12],
+ self.get_latest()[:12],
+ self.get_latest()[:6],
+ ),
+ self.get_changelog(),
+ ),
+ reply_markup=self._markup(),
+ )
+
+ self._notified = self._pending
+ self.set("ignore_permanent", False)
+
+ await self._delete_all_upd_messages()
+
+ self.set("upd_msg", m.message_id)
+
+ async def _delete_all_upd_messages(self):
+ for client in self.allclients:
+ with contextlib.suppress(Exception):
+ await client.loader.inline.bot.delete_message(
+ client.tg_id,
+ client.loader.db.get("Updater", "upd_msg"),
+ )
+
+ @loader.callback_handler()
+ async def update(self, call: InlineCall):
+ """Process update buttons clicks"""
+ if call.data not in {"heroku/update", "heroku/ignore_upd"}:
+ return
+
+ if call.data == "heroku/ignore_upd":
+ self.set("ignore_permanent", self.get_latest())
+ await call.answer(self.strings("latest_disabled"))
+ return
+
+ await self._delete_all_upd_messages()
+
+ with contextlib.suppress(Exception):
+ await call.delete()
+
+ await self.invoke("update", "-f", peer=self.inline.bot_username)
+
+ @loader.command()
+ async def changelog(self, message: Message):
+ """Shows the changelog of the last major update"""
+ with open('CHANGELOG.md', mode='r', encoding='utf-8') as f:
+ changelog = f.read().split('##')[1].strip()
+ if (await self._client.get_me()).premium:
+ changelog.replace('🌑 Heroku', '🌘 🌘 🌘 ')
+
+ await utils.answer(message, self.strings('changelog').format(changelog))
+
@loader.command()
async def restart(self, message: Message):
args = utils.get_args_raw(message)
@@ -272,6 +384,18 @@ class UpdaterMod(loader.Module):
)
async def client_ready(self):
+ try:
+ git.Repo()
+ except Exception as e:
+ raise loader.LoadError("Can't load due to repo init error") from e
+
+ self._markup = lambda: self.inline.generate_markup(
+ [
+ {"text": self.strings("update"), "data": "heroku/update"},
+ {"text": self.strings("ignore"), "data": "heroku/ignore_upd"},
+ ]
+ )
+
if self.get("selfupdatemsg") is not None:
try:
await self.update_complete()