def on_message(self, update: Update, context: CallbackContext): dialog_state = DB.get_user_dialog_state(update.message.from_user.id) if dialog_state is not None: if dialog_state['dialog_state'].startswith('ACTIVITY_NAME'): if len(update.message.text) <= 50: activity = DB.create_activity(dialog_state['user_id'], update.message.text) # update.message.reply_text("☑� *Ты �оздал зан�тие* _%s_.\n\n" # "*�а�троить его можешь в меню* /activities" % update.message.text, # parse_mode="Markdown") DB.set_user_dialog_state(dialog_state['user_id'], "NONE") self.activities[1].open_menu("0", { "u_id": str(activity['owner']), "a": str(activity['id']) }, update, context, send=True) else: update.message.reply_text( "�азвание зан�ти� не должно быть длиннее 50-ти �имволов." )
def ranks(self, update: Update, context: CallbackContext): ranks = DB.get_all_ranks() users = DB.get_chat_users(update.effective_chat.id) string = "🧩 *Звания участников чата*\n\n" i = 0 emoji = ["🔸", "🔹"] for user in users: hours = DB._get_user_useful_time(user['user_id'], 'all')['time'] rank = ranks[0]['name'] for obj in ranks: if obj['min_hours'] <= hours: rank = obj['name'] else: break username = user['username'].replace("_", "\_") username = username.replace(".", "\.") if hours < 0: hours = 0 string += "%s `%s` \- *%s* \(%d часов с пользой\)\n" % ( emoji[i % 2], username, rank, floor(hours)) update.message.reply_text(text=string, parse_mode="MarkdownV2")
def create(self, update: Update, state): if update.callback_query is not None and update.callback_query.from_user.id != int( state['u_id']): update.callback_query.answer( text= "Меню было вызвано другим пользователем.", show_alert=True) return False chat = DB.get_chat_by_id(update.effective_chat.id) now = datetime.datetime.now() expiration = datetime.datetime.strptime(chat['premium_expiration'], '%Y-%m-%d %H:%M:%S') if False and expiration < now: update.callback_query.message.edit_text( text= "🌟 *Дл� до�тупа к �той функции подключите Premium*\n\n" "➡� Подключить - /chat", parse_mode="Markdown") return False update.callback_query.message.edit_text( text="� *�апиши название зан�ти�*", parse_mode="Markdown") DB.set_user_dialog_state(state['u_id'], "ACTIVITY_NAME") return False
def on_message(self, update: Update, context: CallbackContext): dialog_state = DB.get_user_dialog_state(update.message.from_user.id) if dialog_state is not None: if dialog_state['dialog_state'].startswith('PROJECT_NAME'): state = dialog_state['dialog_state'].split() if len(update.message.text) <= 50: project = DB.create_project(dialog_state['user_id'], state[1], update.message.text) # update.message.reply_text("☑️ *Ты создал проект* _%s_.\n\n" # "*Запустить его можешь в меню* /projects" % update.message.text, # parse_mode="Markdown") DB.set_user_dialog_state(dialog_state['user_id'], "NONE") self.projects[0].open_menu("0", { "u_id": str(project['user_id']), "a": str(project['activity_id']), "p_id": str(project['id']) }, update, context, send=True) else: update.message.reply_text( "Название проектов не должно быть длиннее 50-ти символов." )
def stop_project(self, update: Update, state): if not self.is_owner(update, state): return False DB.stop_project(state['p_id']) return True
def activate_project(self, update: Update, state): if not self.is_owner(update, state): return False DB.activate_project(state['p_id'], state['u_id'], state['a']) return True
def stop_project(self, update: Update, state): if update.callback_query is not None and update.callback_query.from_user.id != int(state['u_id']): update.callback_query.answer(text="Меню было вызвано другим пользователем.", show_alert=True) return False DB.stop_project(state['p_id']) return True
def restore(self, update: Update, state): if update.callback_query is not None and update.callback_query.from_user.id != int(state['u_id']): update.callback_query.answer(text="Меню было вызвано другим пользователем.", show_alert=True) return False DB.restore_user_activities(update.effective_user.id) update.callback_query.answer(text="Все твои занятия были успешно восстановлены.", show_alert=True) return False
def initial_state(self, update: Update): active_days = DB.get_chat_active_days(update.effective_chat.id) members_count = len(DB.get_chat_users(update.effective_chat.id)) return { "members": members_count if members_count < 7 else 7, "days": active_days, "md": active_days, "mm": members_count }
def is_next_hidden(self, state, update: Update): if state['q'] == "": length = len(DB.get_user_projects(state['u_id'])) else: length = len( DB.get_user_project_by_query(state['u_id'], state['q'])) page_count = ceil(length / self.IN_PAGE) if page_count <= int(state['page']): return True return False
def save_state(self, db_name): """ This function save state by storing data from the application's data structure into a database """ person_list = self.staff_list + self.fellow_list if self.all_rooms or person_list: db_name = "" if not db_name else db_name new_db = DB() log = new_db.save_state(db_name, self.all_rooms, person_list) cprint(log, "yellow") else: cprint("There is no data to be saved in the database", "yellow")
def remove(self, update: Update, state): if not self.is_owner(update, state): return False DB.remove_activity(state['a']) self.activities[0].open_menu('0', { "u_id": state["u_id"], "a": "0", "page": "1" }, update) return False
def create(self, update: Update, state): if update.callback_query is not None and update.callback_query.from_user.id != int( state['u_id']): update.callback_query.answer( text="Меню было вызвано другим пользователем.", show_alert=True) return False update.callback_query.message.edit_text( text="🖍 *Напиши название проекта*", parse_mode="Markdown") DB.set_user_dialog_state(state['u_id'], "PROJECT_NAME %s" % state['a']) return False
def toggle_tag(self, update: Update, context: CallbackContext): user = DB.get_user_by_id(update.message.from_user.id) if user['tag']: DB.disable_tag(update.message.from_user.id) update.message.reply_text( "☑️ *Ты выключил теги\. Вернуть можешь командой:*\n" "/toggle\_tag", parse_mode="MarkdownV2") else: DB.enable_tag(update.message.from_user.id) update.message.reply_text( "☑️ *Ты включил теги\. Выключить можешь командой:*\n" "/toggle\_tag", parse_mode="MarkdownV2")
def remove(self, update: Update, state): if update.callback_query is not None and update.callback_query.from_user.id != int(state['u_id']): update.callback_query.answer(text="Меню было вызвано другим пользователем.", show_alert=True) return False DB.remove_project(state['p_id']) self.projects[1].open_menu('0', { "u_id": state["u_id"], "a": state["a"], "p_id": "0", "page": "1" }, update) return False
def get_url(self, state, update: Update): purchase = DB.get_purchase_by_reference(state['order']) if purchase is None: date = int(time()) url = 'https://secure.wayforpay.com/pay?behavior=offline' myobj = { 'merchantAccount': '34_89_218_42', 'merchantDomainName': 'https://t.me/timeplayer_bot', 'merchantTransactionSecureType': 'AUTO', 'orderReference': state['order'], 'orderDate': date, 'amount': 40, 'currency': 'UAH', 'productName': ['TimePlayer Premium'], 'productCount': [1], 'productPrice': [40], 'serviceUrl': 'http://34.89.218.42:7000/', 'language': 'RU', 'regularMode': 'monthly', 'regularOn': 1, 'regularCount': 12, 'alternativeCurrency': 'RUB' } signature_string = ';'.join([ myobj['merchantAccount'], myobj['merchantDomainName'], myobj['orderReference'], str(date), str(myobj['amount']), myobj['currency'], myobj['productName'][0], str(myobj['productCount'][0]), str(myobj['productPrice'][0]) ]) myobj['merchantSignature'] = hmac.new( b'23a1179dc7491d991e8d840b11555a70eaa7c53a', msg=signature_string.encode(), digestmod='MD5').hexdigest() x = requests.post(url, data=myobj) vkh = json.loads(x.text)['url'].split('=')[1] DB.add_purchase(state['order'], update.effective_chat.id, vkh) return "https://secure.wayforpay.com/page?vkh=" + vkh else: return "https://secure.wayforpay.com/page?vkh=" + purchase['vkh']
def get_activity_buttons(self, state, update: Update): def get_keyboard_by_names(names): keyboard = list() i = 0 for name in names: button = { "name": name, "action": "select_activity", "callback": True } if i % 2 == 0: keyboard.append([button]) else: keyboard[i // 2].append(button) i += 1 return keyboard if state['q'] == "": activity_names = DB.get_user_accessible_activities( state['u_id'], update.effective_chat.id) names = [] counted = DB.count_user_activities(state['u_id']) for obj in counted: if obj['name'] in [x['name'] for x in activity_names]: names.append(obj['name']) for activity in activity_names: if activity['name'] not in names and activity['id'] != 0: names.append(activity['name']) else: names = [ obj['name'] for obj in DB.get_user_activity_by_query( update.effective_user.id, update.effective_chat.id, state['q']) ] if 'Ничего' in names: names.remove('Ничего') i = self.IN_PAGE * (int(state['page']) - 1) return get_keyboard_by_names(names[i:i + 4])
def get_activity_buttons(self, state, update: Update): def get_keyboard_by_names(names): keyboard = list() i = 0 for name in names: button = { "name": name, "action": "select_activity", "callback": True } if i % 2 == 0: keyboard.append([button]) else: keyboard[i // 2].append(button) i += 1 return keyboard activity_names = DB.get_user_personal_activities(state['u_id']) names = [] for activity in activity_names: if activity['name'] not in names and activity['id'] != 0: names.append(activity['name']) i = self.IN_PAGE * (int(state['page']) - 1) return get_keyboard_by_names(names[i:i + 4])
def plot_all_time(self, user_id, con): activities = pd.read_sql_query( "SELECT * from activities a JOIN activity_names an ON a.activity_id=an.id WHERE a.user_id=" + str(user_id), con) activities['date'] = activities.start_time.apply( lambda x: pd.Timestamp(x).strftime("%m-%d-%y")) grouped = activities[~activities.activity_id.isin([0, 9])].groupby( by=["date", "name"]).duration.sum() range_ = pd.date_range( end=pd.to_datetime("today").strftime("%m/%d/%y"), periods=14) indicies = pd.Series(range_).apply( lambda x: pd.Timestamp(x).strftime("%m-%d-%y")) sns.set() ax = grouped.loc[indicies, :].unstack().plot(kind='bar', figsize=(10, 10), stacked=True) ax.set_xlabel('Дата') ax.set_ylabel('Время (часов)') ax.set_title('Все занятия пользователя %s' % (DB.get_user_by_id(user_id)['username']))
def get_activities(user_id: int): activities = DB.get_all_user_activities(user_id) results = [] for activity in activities: if activity['activity_id'] is None: continue if activity['activity_id'] != 0: start_dt = datetime.strptime(activity['start_time'], '%Y-%m-%d %H:%M:%S') end_dt = start_dt + timedelta(hours=activity['duration']) project = "" if activity['project_name'] is not None: project = f" ({activity['project_name']})" results.append({ "start": start_dt.strftime('%Y-%m-%dT%H:%M:%S'), "end": end_dt.strftime('%Y-%m-%dT%H:%M:%S'), "title": f"{activity['activity_name']}{project}", "color": colors[activity['activity_id'] % len(colors)] }) print(results) return render_template("index.html", data=results)
def plot_time_with_benefit(self, user_id, con): activities = pd.read_sql_query( "SELECT * from activities a JOIN activity_names an ON a.activity_id=an.id WHERE an.challenge=1 AND a.user_id=" + str(user_id), con) # activities = activities.merge(self.activity_names[['id', 'challenge', 'name']], left_on="activity_id", right_on="id", # how="inner") activities['date'] = activities.start_time.apply( lambda x: pd.Timestamp(x).strftime("%m-%d-%y")) grouped = activities[~activities.activity_id.isin([0, 9])].groupby( by=["date", "name"]).duration.sum() range_ = pd.date_range( end=pd.to_datetime("today").strftime("%m/%d/%y"), periods=14) indicies = pd.Series(range_).apply( lambda x: pd.Timestamp(x).strftime("%m-%d-%y")) sns.set() ax = grouped.loc[indicies, :].unstack().plot(kind='bar', figsize=(10, 10), stacked=True) ax.set_xlabel('Дата') ax.set_ylabel('Время с пользой (часов)') ax.set_title('Время с пользой по дням пользователя %s' % (DB.get_user_by_id(user_id)['username']))
def initial_state(self, update: Update): if update.message.reply_to_message is None: text = update.message.text.split() if len(text) > 1 and text[1][0] == '@': user = DB.get_by_username(text[1][1:]) else: user = DB.get_user_by_id(update.message.from_user.id) else: print(update.message.reply_to_message.from_user.username) user = DB.get_user_by_id( update.message.reply_to_message.from_user.id) if user is None: return {} else: return {"user_id": user['user_id']}
def get_user_keyboard(self, user_id): activity_names = DB.get_all_activity_names() names = [] counted = DB.count_user_activities(user_id) for obj in counted: names.append(obj['name']) for activity in activity_names: if activity['name'] not in names and activity['id'] != 0: names.append(activity['name']) keyboard = self.get_keyboard_list_by_names(names) return ReplyKeyboardMarkup(keyboard, selective=True)
def is_next_hidden(self, state, update: Update): length = len(DB.get_user_personal_activities(state['u_id'])) page_count = ceil(length / self.IN_PAGE) if page_count <= int(state['page']): return True return False
def start(self, update: Update, context: CallbackContext): temp = update.message.text.split(" ") if len(temp) > 1 and not temp[1].isdigit(): activities = DB.get_user_activity_by_query( update.effective_user.id, update.effective_chat.id, temp[1]) if len(activities) == 1: activity_name = activities[0]['name'] self.start_activity(update.effective_user.id, activity_name, update, edit=False) return chat = DB.get_chat_by_id(update.effective_chat.id) if chat is None: keyboard = [[ KeyboardButton(text="/help"), KeyboardButton(text="/start") ]] markup = ReplyKeyboardMarkup(keyboard=keyboard, one_time_keyboard=True, resize_keyboard=True) update.message.reply_text( text="👋 *Привет!*\n\n" "Я помогу тебе контролировать все твои занятия в течении дня и " "существенно улучшить твою продуктивность.\n\n" "📄 *Как пользоваться ботом* - /help\n" "▶️ *Выбрать и начать занятие* - /start", parse_mode="Markdown") # update.message.reply_text( # text="🌟 Поздравляю! Для этого чата было начислено *30 дней* бесплатного *Premium*.\n\n" # "_Узнать возможности Premium и продлить его можно в меню_ /chat", # parse_mode="Markdown" # ) else: self.send(update, context) DB.update_user_and_chat(update.message.from_user, update.effective_chat)
def is_next_hidden(self, state, update: Update): length = len(DB.get_user_accessible_activities(state['u_id'], update.effective_chat.id)) - 1 page_count = ceil(length / self.IN_PAGE) if page_count <= int(state['p']): return True return False
def open(self, update: Update, context: CallbackContext): if DB.has_user_activities(update.message.from_user.id): self.send(update, context) else: update.message.reply_text( text= "Чтобы получить личную статистику, необходимо запустить хотя бы одно занятие командой /start." )
def main_menu_format(self, message_text, update: Update, state): project = DB.get_project_by_id(state['p_id']) time = self.get_string_by_duration(float(DB.get_project_time(state['p_id'])['duration'])) is_active = bool(project['active']) name = project['name'].replace("_","\_") # name = name.replace("(", "\(") # name = name.replace(")", "\)") # name = name.replace(".", "\.") # name = name.replace("-", "\-") return message_text.format( project_name=name, activity_name=DB.get_activity_by_id(state['a'])['name'], time=time, status="🟢 *Проект активен*" if is_active else "🔴 *Проект не активен*" )
def load_state(self, db_name): """ This function retrieves data from the database and assign them to the appropraite variables to store them """ if os.path.isfile("data/{}.sqlite".format(db_name)): self.reset() new_db = DB() app_data = new_db.load_state(db_name) self.all_rooms = app_data["all_rooms"] self.staff_list = app_data["staff_list"] self.fellow_list = app_data["fellow_list"] allocations = self.get_allocations() self.allocated = allocations["allocated"] self.unallocated = allocations["unallocated"] cprint(state_loaded_info.format(db_name), "green") else: cprint("File not found", "yellow")
def action_custom_callback(self, update: Update, state, project_id): if update.callback_query is not None and update.callback_query.from_user.id != int( state['u_id']): update.callback_query.answer( text="Меню было вызвано другим пользователем.", show_alert=True) return False activity = DB.get_activity_by_project_id(project_id) project = DB.get_project_by_id(project_id) self.start_activity.start_activity(state['u_id'], activity['name'], update, delay=int(state['dur']), project=project) return False