Created
February 3, 2023 13:35
-
-
Save a-sakharov/b6bb36b791c698daffca5099c6d565d5 to your computer and use it in GitHub Desktop.
Revisions
-
aleaksah created this gist
Feb 3, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,180 @@ # -*- coding: utf-8 -*- import asyncio import datetime import sys from pyrogram import Client import random from num2words import * # Тут надо выставить параметры соответствующие своим (https://my.telegram.org/apps). Я свои на всякий случай заменю заглушками API_ID = 0 API_HASH = "000000000000000000000000000000000" class PillsSchedule: name = "" # Название препарата. Гроприносин, например per_time_amount = 0 # Сколько пьется за раз. Например, 2 per_day_times = 0 # Сколько раз в день пьется. Например, 1 total_count = 0 # Сколько единиц всего надо принять. Не сколько раз, а сколько единиц already_consumed = 0 # Сколько уже принято в единицах. Опять же, в единицах, а не в разах per_day_first_offset = 0 # Задержка в минутах от полуночи до первой дозы per_day_subsequent_offset = 0 # Задержка в минутах перед последующими приемами относительно предыдущего приема days_period = 0 # сколько дней пропускается между приемами days_offset = 0 # Задержка в днях перед первых приемом course_started = None # datetime первого приема? def __init__(self, name, per_time_amount=1, per_day_times=1, total_count=1, already_consumed=0, per_day_first_offset=60*8, per_day_subsequent_offset=60*4, days_period=1, days_offset=0): self.name = name self.per_time_amount = per_time_amount self.per_day_times = per_day_times self.total_count = total_count self.already_consumed = already_consumed self.per_day_first_offset = per_day_first_offset self.per_day_subsequent_offset = per_day_subsequent_offset self.days_period = days_period self.days_offset = days_offset class OneTimePills: name = "" count = 0 total_consumed = 0 total_count = 0 def __init__(self, name, count, total_consumed, total_count): self.name = name self.count = count self.total_consumed = total_consumed self.total_count = total_count def get_right_noun(count): if count == 1: return "штука" elif count >=2 and count <=4: return "штуки" else: return "штук" def datetime_to_day_start(date): return datetime.datetime.combine(date.date(), datetime.time(0)) def pills_array_to_time_text(pills_array, start_of_admission=datetime.datetime.today()+datetime.timedelta(days=1)): # default start_of_admission is tomorrow # 1. строим массив со всеми приемами (название, количество и время) # 2. объединяем те приемы, что имеют одно время, и генерируем текст if start_of_admission.second != 0 or start_of_admission.microsecond != 0: start_of_admission -= datetime.timedelta(seconds=start_of_admission.second, microseconds=start_of_admission.microsecond) times = dict() for pill in pills_array: if pill.days_offset: time_offset = datetime_to_day_start(start_of_admission) + datetime.timedelta(days=pill.days_offset) else: time_offset = start_of_admission while pill.already_consumed < pill.total_count: for in_day_index in range(pill.per_day_times): consumption_time_in_day_offset = pill.per_day_first_offset + in_day_index * pill.per_day_subsequent_offset consumption_datetime = datetime_to_day_start(time_offset) + datetime.timedelta(minutes=consumption_time_in_day_offset) if time_offset <= consumption_datetime and pill.already_consumed < pill.total_count: pill.already_consumed += pill.per_time_amount if consumption_datetime not in times: times[consumption_datetime] = list() times[consumption_datetime].append(OneTimePills(pill.name, pill.per_time_amount, pill.already_consumed, pill.total_count)) # print("💊 Consumed {0} pills of {1} at {2} ({3}/{4})".format(pill.per_time_amount, pill.name, consumption_datetime, pill.already_consumed, pill.total_count)) if pill.days_period: time_offset = datetime_to_day_start(time_offset) + datetime.timedelta(days=pill.days_period) else: time_offset = datetime_to_day_start(time_offset) + datetime.timedelta(days=1) result = dict() lang_ru_n2w = lang_RU.Num2Word_RU() for time in times: if time.hour < 12: text = "Доброе утро!\n" elif time.hour > 19: text = "" else: text = "Привет\n" text += "Сейчас тебе нужно принять следующее:\n" for pill in times[time]: text += ("💊 {0}: {1} {2}. Это будет {3} из {4}, или {5:.1f}%\n".format(pill.name, lang_ru_n2w._int2word(pill.count, True), get_right_noun(pill.count), pill.total_consumed, pill.total_count, pill.total_consumed/pill.total_count*100.)) # Возможные поздравления. # Первый элемент - вес, выше - больше вероятность что выпадет # Второй элемент - само поздравление # Можно менять и удалять как нравится trailing_text_setup = [ [3, ""], [3, "Выздоравливай!"], [3, "Ты справишься!"], [3, "Скоро будешь здоровой!"], [2, "Хмели сумели и ты сможешь!"], [2, "Выпей таблетку, чтобы показать какая ты особенная"], [2, "Ради Барсика!"], [3, "За Маму"], [3, "За Папу"], [1, "За Юлю"], [1, "За Настю"], ] trailing_text_final = [] for item in trailing_text_setup: trailing_text_final = [*trailing_text_final, *(item[0] * [item[1]])] random.shuffle(trailing_text_final) training_text = trailing_text_final[random.randint(0, len(trailing_text_final)-1)] text += training_text if time.hour > 19: if text[-1] != '\n': text += '\n' text += "Спокойной ночи!" result[time] = text return result async def create_notifications(to, messages): async with Client("my_account", API_ID, API_HASH) as app: for date in messages: if date >= datetime.datetime.now(): pass await app.send_message(chat_id=to, text=messages[date], schedule_date=date) def print_messages(messages): for date in messages: print(date) print(messages[date]) print() print() # Тут настраиваются таблетосы pills = [ PillsSchedule("Гроприносин", per_time_amount=2, per_day_times=3, total_count=168, already_consumed=0, per_day_first_offset=60*8, per_day_subsequent_offset=60*6, days_period=0, days_offset=0), PillsSchedule("Юнидокс", per_time_amount=1, per_day_times=2, total_count=20, already_consumed=0, per_day_first_offset=60*8, per_day_subsequent_offset=60*12, days_period=0, days_offset=0), PillsSchedule("Флуконазол 150мг", per_time_amount=1, per_day_times=1, total_count=2, already_consumed=0, per_day_first_offset=60*8, per_day_subsequent_offset=0, days_period=5, days_offset=5), PillsSchedule("Метрамикон форте", per_time_amount=1, per_day_times=1, total_count=7, already_consumed=0, per_day_first_offset=60*20, per_day_subsequent_offset=0, days_period=0, days_offset=0), PillsSchedule("Джес Плюс", per_time_amount=1, per_day_times=1, total_count=56, already_consumed=0, per_day_first_offset=60*8, per_day_subsequent_offset=0, days_period=0, days_offset=14), ] time_text = pills_array_to_time_text(pills, start_of_admission=datetime.datetime(2023, 1, 20, 18, 0, 0)) print_messages(time_text) # Отправка. Для теста отправляем сами себе, иначе надо изменить 'me' на имя пользователя asyncio.run(create_notifications(to="me", messages=time_text)) print("Done!")