Skip to content
This repository has been archived by the owner on Jul 18, 2023. It is now read-only.

Commit

Permalink
Develop (#9)
Browse files Browse the repository at this point in the history
* feat: Added video download counter by months

Signed-off-by: rin-gil <[email protected]>

* feat: Added video download counter by months

Added statistics for admins - the number of video downloads in the bot

Signed-off-by: rin-gil <[email protected]>

* revert:

Signed-off-by: rin-gil <[email protected]>

---------

Signed-off-by: rin-gil <[email protected]>
  • Loading branch information
rin-gil authored Apr 6, 2023
1 parent bff6383 commit 46fb053
Show file tree
Hide file tree
Showing 19 changed files with 522 additions and 44 deletions.
6 changes: 5 additions & 1 deletion .env.dist
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# Paste the bot token here and rename the file to .env
# Paste the bot token here
BOT_TOKEN=123456:Your-TokEn_ExaMple
# Insert the id of administrators here, separated by commas.
# You can find out your id by writing a message to the bot https://t.me/getmyid_bot
ADMINS=First-AdminID_ExaMple,Second-AdminID_ExaMple
# Rename the file to .env
12 changes: 12 additions & 0 deletions bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,30 @@
from aiogram.contrib.fsm_storage.memory import MemoryStorage

from tgbot.config import load_config, Config
from tgbot.filters.admin import AdminFilter
from tgbot.handlers.admin import register_admin_handlers
from tgbot.handlers.commands import register_commands_handlers
from tgbot.handlers.error import register_errors_handlers
from tgbot.handlers.messages import register_messages_handlers
from tgbot.middlewares.localization import i18n
from tgbot.misc.commands import set_default_commands
from tgbot.misc.logger import logger
from tgbot.services.database import database_init


def register_all_middlewares(dp: Dispatcher) -> None:
"""Registers middlewares"""
dp.middleware.setup(i18n)


def register_all_filters(dp: Dispatcher) -> None:
"""Registers filters"""
dp.filters_factory.bind(AdminFilter)


def register_all_handlers(dp: Dispatcher) -> None:
"""Registers handlers"""
register_admin_handlers(dp)
register_commands_handlers(dp)
register_messages_handlers(dp)
register_errors_handlers(dp)
Expand All @@ -31,9 +40,12 @@ async def main() -> None:
config: Config = load_config(path=".env")
bot: Bot = Bot(token=config.tg_bot.token, parse_mode="HTML")
dp: Dispatcher = Dispatcher(bot, storage=MemoryStorage())
bot["config"] = config
register_all_middlewares(dp)
register_all_filters(dp)
register_all_handlers(dp)
try: # On starting bot
await database_init()
await set_default_commands(dp)
await dp.skip_updates()
await dp.start_polling()
Expand Down
4 changes: 2 additions & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
mypy==1.1.1
pylint==2.17.1
mypy==1.2.0
pylint==2.17.2
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
aiogram==2.25.1
aiosqlite==0.18.0
environs==9.5.0
pytube==12.1.2
matplotlib==3.7.1
pytube==12.1.3
8 changes: 5 additions & 3 deletions tgbot/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

from os.path import join, normpath
from pathlib import Path
from typing import NamedTuple, Optional
from typing import NamedTuple

from environs import Env


_BASE_DIR: Path = Path(__file__).resolve().parent.parent
LOG_FILE: str = join(_BASE_DIR, "log.log")
BOT_LOGO: str = normpath(join(_BASE_DIR, "tgbot/assets/img/bot_logo.png"))
DB_FILE: str = normpath(join(_BASE_DIR, "tgbot/db.sqlite3"))
TEMP_DIR: str = normpath(join(_BASE_DIR, "tgbot/temp"))
LOCALES_DIR: str = normpath(join(_BASE_DIR, "tgbot/locales"))

Expand All @@ -18,6 +19,7 @@ class TgBot(NamedTuple):
"""Bot data"""

token: str
admin_ids: tuple[int, ...]


class Config(NamedTuple):
Expand All @@ -26,8 +28,8 @@ class Config(NamedTuple):
tg_bot: TgBot


def load_config(path: Optional[str] = None) -> Config:
def load_config(path: str | None) -> Config:
"""Loads settings from environment variables"""
env = Env()
env.read_env(path)
return Config(tg_bot=TgBot(token=env.str("BOT_TOKEN")))
return Config(tg_bot=TgBot(token=env.str("BOT_TOKEN"), admin_ids=tuple(map(int, env.list("ADMINS")))))
Empty file added tgbot/filters/__init__.py
Empty file.
22 changes: 22 additions & 0 deletions tgbot/filters/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
""" Allows to perform actions if the user is an administrator """

from aiogram.dispatcher.filters import BoundFilter
from aiogram.types import CallbackQuery, Message

from tgbot.config import Config


class AdminFilter(BoundFilter):
"""Allows to define administrators"""

key = "is_admin"

def __init__(self, is_admin: bool | None = None):
self.is_admin = is_admin

async def check(self, obj: Message | CallbackQuery) -> bool:
"""Checks if the user is an administrator"""
if self.is_admin is None:
return False
config: Config = obj.bot.get("config")
return (obj.from_user.id in config.tg_bot.admin_ids) == self.is_admin
36 changes: 36 additions & 0 deletions tgbot/handlers/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Message handlers for administrators"""

from os import remove as os_remove

from aiogram import Dispatcher
from aiogram.types import InputFile, Message

from tgbot.config import BOT_LOGO
from tgbot.middlewares.localization import i18n
from tgbot.services.database import get_downloads_data
from tgbot.services.statistics import get_path_to_statistics_graph

_ = i18n.gettext # Alias for gettext method


async def if_admin_sent_command_stats(message: Message) -> None:
"""Shows statistics for administrators"""
lang_code: str = message.from_user.language_code
path_to_statistics_graph: str | None = await get_path_to_statistics_graph(
downloads_data=await get_downloads_data(), locale=lang_code
)
if path_to_statistics_graph:
await message.reply_photo(
photo=InputFile(path_to_statistics_graph),
caption="📊 " + _("Statistics of bot video downloads by months", locale=lang_code),
)
os_remove(path_to_statistics_graph)
else:
await message.reply_photo(
photo=InputFile(BOT_LOGO), caption="❌ " + _("Error in plotting the graph", locale=lang_code)
)


def register_admin_handlers(dp: Dispatcher) -> None:
"""Registers admin handlers"""
dp.register_message_handler(if_admin_sent_command_stats, commands="stats", state="*", is_admin=True)
2 changes: 2 additions & 0 deletions tgbot/handlers/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from tgbot.middlewares.localization import i18n
from tgbot.misc.states import UserInput
from tgbot.services.database import increase_downloads_counter
from tgbot.services.youtube import get_path_to_video_file

_ = i18n.gettext # Alias for gettext method
Expand All @@ -24,6 +25,7 @@ async def if_user_sent_link(message: Message) -> None:
await message.reply_video(InputFile(path_to_mp4_file))
await message.bot.delete_message(chat_id=chat_id, message_id=bot_reply.message_id)
os_remove(path_to_mp4_file)
await increase_downloads_counter()
else:
await message.bot.edit_message_text(
text="❌ " + _("Unable to download this video", locale=lang_code),
Expand Down
Binary file modified tgbot/locales/en/LC_MESSAGES/tgbot.mo
Binary file not shown.
79 changes: 71 additions & 8 deletions tgbot/locales/en/LC_MESSAGES/tgbot.po
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
# Copyright (C) 2022 Ringil
# This file is distributed under the same license as the
# YouTubeShortsDownloader project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
# Ringil <[email protected]>, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: YouTubeShortsDownloader v1.0.0\n"
"Project-Id-Version: YouTubeShortsDownloader v1.1.0\n"
"Report-Msgid-Bugs-To: [email protected]\n"
"POT-Creation-Date: 2022-11-30 23:59+0200\n"
"PO-Revision-Date: 2022-11-30 23:59+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2023-04-06 20:15+0300\n"
"PO-Revision-Date: 2023-04-06 20:18+0300\n"
"Last-Translator: Ringil <[email protected]>\n"
"Language: en\n"
"Language-Team: en <[email protected]>\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
Expand All @@ -19,6 +19,14 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"

#: tgbot/handlers/admin.py:25
msgid "Statistics of bot video downloads by months"
msgstr "Statistics of bot video downloads by months"

#: tgbot/handlers/admin.py:30
msgid "Error in plotting the graph"
msgstr "Error in plotting the graph"

#: tgbot/handlers/commands.py:15
msgid "Send a link to YouTube Shorts"
msgstr "Send a link to YouTube Shorts"
Expand All @@ -31,15 +39,15 @@ msgstr "I can download videos from YouTube Shorts"
msgid "Error downloading the video"
msgstr "Error downloading the video"

#: tgbot/handlers/messages.py:20
#: tgbot/handlers/messages.py:21
msgid "Wait, downloading..."
msgstr "Wait, downloading..."

#: tgbot/handlers/messages.py:29
#: tgbot/handlers/messages.py:31
msgid "Unable to download this video"
msgstr "Unable to download this video"

#: tgbot/handlers/messages.py:38
#: tgbot/handlers/messages.py:40
msgid "This is not a link to YouTube Shorts"
msgstr "This is not a link to YouTube Shorts"

Expand All @@ -51,3 +59,58 @@ msgstr "Start"
msgid "Bot info"
msgstr "Bot info"

#: tgbot/services/statistics.py:29
msgid "Jan"
msgstr "Jan"

#: tgbot/services/statistics.py:30
msgid "Feb"
msgstr "Feb"

#: tgbot/services/statistics.py:31
msgid "Mar"
msgstr "Mar"

#: tgbot/services/statistics.py:32
msgid "Apr"
msgstr "Apr"

#: tgbot/services/statistics.py:33
msgid "May"
msgstr "May"

#: tgbot/services/statistics.py:34
msgid "Jun"
msgstr "Jun"

#: tgbot/services/statistics.py:35
msgid "Jul"
msgstr "Jul"

#: tgbot/services/statistics.py:36
msgid "Aug"
msgstr "Aug"

#: tgbot/services/statistics.py:37
msgid "Sep"
msgstr "Sep"

#: tgbot/services/statistics.py:38
msgid "Oct"
msgstr "Oct"

#: tgbot/services/statistics.py:39
msgid "Nov"
msgstr "Nov"

#: tgbot/services/statistics.py:40
msgid "Dec"
msgstr "Dec"

#: tgbot/services/statistics.py:62
msgid "Downloads chart by dates"
msgstr "Downloads chart by dates"

#: tgbot/services/statistics.py:63
msgid "Number of downloads"
msgstr "Number of downloads"
Binary file modified tgbot/locales/ru/LC_MESSAGES/tgbot.mo
Binary file not shown.
Loading

0 comments on commit 46fb053

Please sign in to comment.