Снова всех приветствую. В моей прошлой статье «Как превратить статус Telegram в статус Steam» вдохновленной статьей «Как превратить свою аватарку в Telegram в часы» я описал интересную концепцию. Почитав комментарии с обеих статей, я пришел к еще одной идее. А именно — аватар с термометром. Это будет последняя статья, которая будет описывать скрипты для стилизации вашего аккаунта в ТГ.
Да, может я и высасываю идею из пальца, но мне показалось это весьма интересным. Ведь статус не очень заметен, а смена аватара часов очень любит вызывать flood-бан.
Перейдем к коду
Здесь более массивный список библиотек, чем в прошлой статье
pip install requests pip install Telethon pip install pillow pip install beautifulsoup4
И давайте сразу импортируем все модули
import requests from bs4 import BeautifulSoup as bs from PIL import Image, ImageDraw, ImageFont from datetime import datetime from telethon import TelegramClient from telethon.tl.functions.photos import UploadProfilePhotoRequest, DeletePhotosRequest from telethon.tl.types import InputPhoto import time
Также инициализируем все классы и зададим переменные
URL_TEMPLATE = "https://pogoda.mail.ru/prognoz/krasnodar/24hours/" FONT_LARGE = ImageFont.truetype("shr1.ttf", 80) FONT_SMALL = ImageFont.truetype("shr2.ttf", 30) client = TelegramClient("anon", api_id, "api_hash") client.start() city = "Krasnodar"
URL_TEMPLATE — Ссылка на сайт для парсинга. Просто заходите сюда
FONT_LARGE и FONT_SMALL — шрифты. Можете скачать любой и указать их тут. Я, к сожалению, уже не смогу сказать, какие использовал я, ибо шрифты были переименованны.
client — Инициализация клиента telethon. Вы можете взять api_id и api_hash здесь.
city — Надпись под под температурой
Парсинг погоды
Здесь мы будем использовать requests для подключения и bs4 для чтения страницы. Парсить мы будем с сайта pogoda.mail.ru
def weather_parse(): r = requests.get(URL_TEMPLATE) soup = bs(r.text, "html.parser") temperature = soup.find_all('span', class_='p-forecast__temperature-value')[0] # <span class="p-forecast__temperature-value">+24°</span> return temperature.text
Очень простой код, который парсит погоду. Просто заходите сюда, ищите свой город и вставляете ссылку в переменную URL_TEMPLATE.
Создание изображения с температурой
def img_weather(hour, show=False): temperature = weather_parse() print(temperature) if hour < 6: color = "#0000CD" elif hour < 12: color = "#FFD700" elif hour < 18: color = "#FFFACD" else: color = "#FF8C00" image = Image.new('RGB', (256, 256), color='black') draw = ImageDraw.Draw(image) text_width = draw.textlength(temperature, font=FONT_LARGE) draw.text(((256 - text_width) // 2, 80), temperature, font=FONT_LARGE, fill="white") subtext = city subtext_width = draw.textlength(subtext, font=FONT_SMALL) draw.text(((256 - subtext_width) // 2, 150), subtext, font=FONT_SMALL, fill=color) if show: image.show() return image
Здесь интересней. Как видите, мы передаем в аргументы переменную hour. Это час времени, который сейчас на дворе. Потом идет сравнение, сколько сейчас времени. От этого параметра зависит цвет надписи под температурой. Возможно, вам стоит поменять эти цвета, ибо я дальтоник 😀
Задаем черный фон, указываем все по середине и на нужной дистанции, а формат изображения 256*256 (квадрат, который требует Telegram).
По итогу получаем вот такое вот изображение. Мне лично нравится, оставлю так. Может можно туда засунуть что-то еще.
Обновление аватара
async def update_profile_photo(hour): try: try: # Удаляем старую фотографию (с await) photos = await client.get_profile_photos('me') if photos: await client(DeletePhotosRequest( id=[InputPhoto( id=photos[0].id, access_hash=photos[0].access_hash, file_reference=photos[0].file_reference )] )) except Exception as e: print("Нет аватарок или ошибка удаления:", e) image = img_weather(hour) image.save("vrem.png") with open("vrem.png", 'rb') as file: file1 = await client.upload_file(file) await client(UploadProfilePhotoRequest(file=file1)) return "True" except Exception as e: return str(e)
Здесь все просто. Удаляем старую аватарку, сохраняем новую и публикуем ее как аватар. Если выводит ошибку, значит аватарок нету.
Main()
async def main(): await client.start() last_time = "" while True: current_time = datetime.now().hour if current_time != last_time: last_time = current_time result = await update_profile_photo(current_time) if result != "True": print(f"Ошибка: {result}") else: print(f"{current_time}hour - Удачная смена") await asyncio.sleep(20) if __name__ == "__main__": with client: client.loop.run_until_complete(main())
Здесь мы просто сравниваем каждые 20 секунд час, если час изменится, то вызывается функция для смены аватара. Зачем мониторить именно смену каждого часа? Это за тем, чтобы менять градус точь-в-точь с прогнозом. В прочем не сложно.
Тест

Вот так вот выглядит наш профиль
Полный код
import asyncio import requests from bs4 import BeautifulSoup as bs from PIL import Image, ImageDraw, ImageFont from datetime import datetime from telethon import TelegramClient from telethon.tl.functions.photos import UploadProfilePhotoRequest, DeletePhotosRequest from telethon.tl.types import InputPhoto url_yandex = "https://yandex.ru/pogoda/ru/krasnodar" url_mail = "https://pogoda.mail.ru/prognoz/krasnodar/24hours/" FONT_LARGE = ImageFont.truetype("porn2.ttf", 80) FONT_SMALL = ImageFont.truetype("porn3.ttf", 30) client = TelegramClient("vology", 21079830, "fa59df8ecab7c0ffabff817922f1df56") city = "Krasnodar" def weather_parse(): try: # парсинг яндекс погоды (более точная) r = requests.get(url_yandex) soup = bs(r.text, "html.parser") temperature = soup.find_all('span', class_='AppFactTemperature_value__2qhsG')[0] if temperature.text.strip() == "0": return "0" znak = soup.find_all('span', class_='AppFactTemperature_sign__1MeN4')[0] return f"{znak.text}{temperature.text}°" except: # парсинг маил ру на случай поломки яндекса r = requests.get(url_mail) soup = bs(r.text, "html.parser") temperature = soup.find_all('span', class_='p-forecast__temperature-value')[0] return temperature.text def img_weather(hour, show=False): temperature = weather_parse() print(temperature) if hour < 6: color = "#0000CD" elif hour < 12: color = "#FFD700" elif hour < 18: color = "#FFFACD" else: color = "#FF8C00" image = Image.new('RGB', (256, 256), color='black') draw = ImageDraw.Draw(image) text_width = draw.textlength(temperature, font=FONT_LARGE) draw.text(((256 - text_width) // 2, 80), temperature, font=FONT_LARGE, fill="white") subtext = city subtext_width = draw.textlength(subtext, font=FONT_SMALL) draw.text(((256 - subtext_width) // 2, 150), subtext, font=FONT_SMALL, fill=color) if show: image.show() return image async def update_profile_photo(hour): try: try: # Удаляем старую фотографию (с await) photos = await client.get_profile_photos('me') if photos: await client(DeletePhotosRequest( id=[InputPhoto( id=photos[0].id, access_hash=photos[0].access_hash, file_reference=photos[0].file_reference )] )) except Exception as e: print("Нет аватарок или ошибка удаления:", e) image = img_weather(hour) image.save("vrem.png") with open("vrem.png", 'rb') as file: file1 = await client.upload_file(file) await client(UploadProfilePhotoRequest(file=file1)) return "True" except Exception as e: return str(e) async def main(): await client.start() last_time = "" while True: current_time = datetime.now().hour if current_time != last_time: last_time = current_time result = await update_profile_photo(current_time) if result != "True": print(f"Ошибка: {result}") else: print(f"{current_time}hour - Удачная смена") await asyncio.sleep(20) if __name__ == "__main__": with client: client.loop.run_until_complete(main())
Итог
Получилось довольно занимательно. Это еще один из способов выделиться из толпы, который вы можете использовать. Креативничайте, добавляйте свои идеи и модернизируйте вашу аватарку. Всем спасибо
ссылка на оригинал статьи https://habr.com/ru/articles/928358/
Добавить комментарий