예제 #1
0
    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-ти �имволов."
                    )
예제 #2
0
    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")
예제 #3
0
    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
예제 #4
0
    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
예제 #8
0
    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
예제 #9
0
    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
        }
예제 #10
0
    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
예제 #11
0
 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
예제 #13
0
    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
예제 #14
0
    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
예제 #16
0
    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']
예제 #17
0
    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])
예제 #18
0
    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])
예제 #19
0
    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']))
예제 #20
0
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)
예제 #21
0
    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']))
예제 #22
0
    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']}
예제 #23
0
    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)
예제 #24
0
    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
예제 #25
0
    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)
예제 #26
0
    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
예제 #27
0
 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 "🔴 *Проект не активен*"
        )
예제 #29
0
 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")
예제 #30
0
    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