first commit

This commit is contained in:
Alex55 2025-06-25 14:08:37 +03:00
commit 22f175966a
12 changed files with 191 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
/.venv
/logs
# Игнорируем файлы логов
*.log
.env
/tests
session.session

1
.python-version Normal file
View File

@ -0,0 +1 @@
3.12

1
README.md Normal file
View File

@ -0,0 +1 @@
Пример как следить когда пользователи были в онлайн)

Binary file not shown.

2
envprimer Normal file
View File

@ -0,0 +1,2 @@
API_ID=
API_HASH=

53
main.py Normal file
View File

@ -0,0 +1,53 @@
import asyncio
from datetime import datetime, timezone, timedelta
from telethon import TelegramClient
from telethon.tl.types import UserStatusOnline, UserStatusOffline
import utils.config
from utils.logging_setup import configure_global_logging
logger = configure_global_logging()
config = utils.config
# Список пользователей, которых отслеживаем
async def check_status(client, username):
try:
entity = await client.get_entity(username)
user_id = entity.id
username = entity.username or ''
user = await client.get_entity(user_id)
status = user.status
# 1. Получаем тип статуса
status_type = type(status).__name__
logger.info(f"\nСледим за: {username} (ID: {user_id})")
if status_type == 'UserStatusOffline':
was_online_utc = status.was_online
kiev_time = was_online_utc.astimezone(timezone(timedelta(hours=3)))
year, month, day = kiev_time.year, kiev_time.month, kiev_time.day
hour, minute, second = kiev_time.hour, kiev_time.minute, kiev_time.second
logger.info(f"Статус: {status_type}")
logger.info(f"Последний онлайн (Киев): {year}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d}")
elif status_type == 'UserStatusOnline':
logger.info(f"Статус: {status_type} — Сейчас онлайн")
else:
logger.info(f"Статус: {status_type} — Время скрыто или неизвестно")
except Exception as e:
logger.info(f"⚠️ Ошибка при проверке {username}: {e}")
async def main():
async with TelegramClient('session', config.api_id, config.api_hash) as client:
tasks = [check_status(client, username) for username in config.target_usernames]
await asyncio.gather(*tasks)
if __name__ == '__main__':
asyncio.run(main())

10
pyproject.toml Normal file
View File

@ -0,0 +1,10 @@
[project]
name = "tgshka"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"python-dotenv>=1.1.1",
"telethon>=1.40.0",
]

Binary file not shown.

Binary file not shown.

10
utils/config.py Normal file
View File

@ -0,0 +1,10 @@
from dotenv import load_dotenv
import os
load_dotenv()
# db_host = os.getenv('DB_HOST')
api_id = os.getenv('API_ID') # замени на свой
api_hash = os.getenv('API_HASH')
target_usernames = ['vipertt', 'Prommm12']

40
utils/logging_setup.py Normal file
View File

@ -0,0 +1,40 @@
import logging
from logging.handlers import RotatingFileHandler
from pathlib import Path
class MyAppFilter(logging.Filter):
def filter(self, record):
return record.name == "my_app"
def configure_global_logging(
log_file="logs/app.log",
level=logging.INFO,
max_bytes=5_000_000,
backup_count=3
):
log_file_path = Path(log_file)
log_file_path.parent.mkdir(parents=True, exist_ok=True)
logger = logging.getLogger("my_app")
logger.setLevel(level)
if not logger.hasHandlers():
file_handler = RotatingFileHandler(
log_file, maxBytes=max_bytes, backupCount=backup_count
)
file_handler.setLevel(level)
file_handler.setFormatter(logging.Formatter("%(asctime)s [%(filename)s:%(lineno)d] - %(message)s"))
file_handler.addFilter(MyAppFilter())
console_handler = logging.StreamHandler()
console_handler.setLevel(level)
console_handler.setFormatter(logging.Formatter("%(asctime)s [%(filename)s:%(lineno)d] - %(message)s"))
console_handler.addFilter(MyAppFilter())
logger.addHandler(file_handler)
logger.addHandler(console_handler)
# Отключаем все другие логгеры
logging.getLogger().setLevel(logging.CRITICAL)
return logger

67
uv.lock Normal file
View File

@ -0,0 +1,67 @@
version = 1
revision = 2
requires-python = ">=3.12"
[[package]]
name = "pyaes"
version = "1.6.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/44/66/2c17bae31c906613795711fc78045c285048168919ace2220daa372c7d72/pyaes-1.6.1.tar.gz", hash = "sha256:02c1b1405c38d3c370b085fb952dd8bea3fadcee6411ad99f312cc129c536d8f", size = 28536, upload-time = "2017-09-20T21:17:54.23Z" }
[[package]]
name = "pyasn1"
version = "0.6.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" },
]
[[package]]
name = "python-dotenv"
version = "1.1.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f6/b0/4bc07ccd3572a2f9df7e6782f52b0c6c90dcbb803ac4a167702d7d0dfe1e/python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab", size = 41978, upload-time = "2025-06-24T04:21:07.341Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556, upload-time = "2025-06-24T04:21:06.073Z" },
]
[[package]]
name = "rsa"
version = "4.9.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyasn1" },
]
sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload-time = "2025-04-16T09:51:18.218Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload-time = "2025-04-16T09:51:17.142Z" },
]
[[package]]
name = "telethon"
version = "1.40.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyaes" },
{ name = "rsa" },
]
sdist = { url = "https://files.pythonhosted.org/packages/58/af/9b7111e3f63fffe8e55b7ceb8bda023173e2052f420b6debcb25fd2fbc15/telethon-1.40.0.tar.gz", hash = "sha256:40e83326877a2e68b754d4b6d0d1ca5ac924110045b039e02660f2d67add97db", size = 646723, upload-time = "2025-04-21T09:12:10.506Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2c/5a/c5370edb3215d19a6e858f4169b8eec725ba55f9d39df0f557508048c037/Telethon-1.40.0-py3-none-any.whl", hash = "sha256:146fd4cb2a7afa66bc67f9c2167756096a37b930f65711a3e7399ec9874dcfa7", size = 722013, upload-time = "2025-04-21T09:12:08.399Z" },
]
[[package]]
name = "tgshka"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "python-dotenv" },
{ name = "telethon" },
]
[package.metadata]
requires-dist = [
{ name = "python-dotenv", specifier = ">=1.1.1" },
{ name = "telethon", specifier = ">=1.40.0" },
]