def add_task(self, task: TODOTask) -> TODOTask:
        task.id = str(uuid.uuid4())

        with db_session().begin():
            db_session.add(task)

        return task
예제 #2
0
async def route_delete_confirm(cb: CallbackQuery, callback_data: dict):
    """Delete route from DB and send message."""
    with db_session() as db:
        route = db.get(Route, callback_data['route_id'])  # type: ignore
        db.delete(route)

    await cb.answer(f'Маршрут "{route.name}" успешно удален', show_alert=True)
    await route_list(cb)
예제 #3
0
 def setUp(self):
     self.app = get_decorated_app()
     self.app_context = self.app.app_context()
     self.app_context.push()
     self.db = db_session()
     #init_db()
     #load_all(self.backup_db)
     self.client = self.app.test_client(use_cookies=True)
예제 #4
0
async def schedule_delete(cb: types.CallbackQuery, callback_data: dict):
    """Delete schedule."""
    with db_session() as db:
        schedule = db.get(Schedule, callback_data['schedule_id'])
        db.delete(schedule)

    await cb.answer('Расписание уведомления удалено', show_alert=True)
    await schedule_list(cb, callback_data)
예제 #5
0
async def settings_tz(cb: CallbackQuery):
    with db_session() as db:
        user = db.query(User).filter(User.uid.__eq__(cb.from_user.id)).first()

    await cb.message.edit_text(
        f'Ваш часовой пояс <b>{user.timezone}</b>.',
        reply_markup=settings.kb_settings_tz(),
    )
    await cb.answer()
예제 #6
0
async def cmd_about(message: types.Message):
    """Show information about bot."""
    stat = dict()
    with db_session() as db:
        stat['users'] = db.query(func.count(User.id)).scalar()
        stat['routes'] = db.query(func.count(Route.id)).scalar()
        stat['schedules'] = db.query(func.count(Schedule.id)).scalar()

    await message.answer(ABOUT_TEXT % stat)
예제 #7
0
async def settings_tz_set(message: types.Message, state: FSMContext):
    tz = message.text.split(' ')[0].upper()
    with db_session() as db:
        db.query(User).filter(User.uid.__eq__(message.from_user.id)).update(
            {User.timezone: tz})
    await state.finish()
    await message.answer(
        f'Вы успешно изменили часовой пояс {uchar.OK_HAND}',
        reply_markup=settings.kb_settings_back(),
    )
예제 #8
0
async def route_delete(cb: types.CallbackQuery, callback_data: dict):
    """Delete route and cascade schedules."""
    with db_session() as db:
        route = db.get(Route, callback_data['route_id'])  # type: ignore

    await cb.message.edit_text(
        f'Вы уверены, что хотите удалить маршрут <b>{route.name}</b>?',
        reply_markup=inline_route.kb_route_delete_confirm_buttons(
            callback_data['route_id']),
    )
    await cb.answer()
예제 #9
0
async def send_single_route(route_id: int):
    # REFACTOR ME PLS!!!
    from app.main import bot  # pylint: disable=import-outside-toplevel

    with db_session() as db:
        route = db.get(Route, route_id)
        uid = route.user.uid
    message = route.message()
    message = f'Уведомление по расписанию:\n{message}'

    await bot.send_message(chat_id=uid, text=message)
예제 #10
0
async def schedule_select(cb: types.CallbackQuery, callback_data: dict):
    """Show single schedule."""
    with db_session() as db:
        schedule = db.get(Schedule, callback_data['schedule_id'])
        route = schedule.route

    await cb.message.edit_text(
        f'Редактирование уведомления для маршрута <b>{route.name}</b>',
        reply_markup=inline_schedule.kb_schedule_show(schedule.id, route.id,
                                                      schedule.is_active),
    )
예제 #11
0
async def schedule_toggle(cb: types.CallbackQuery, callback_data: dict):
    """Toggle is_active schedule property."""
    with db_session() as db:
        schedule = db.get(Schedule, callback_data['schedule_id'])
        route = schedule.route
        state = schedule.toggle()
        alert_text = ('Уведомления включены'
                      if bool(state) else 'Уведомления отключены')

    await cb.answer(alert_text)
    await cb.message.edit_reply_markup(
        inline_schedule.kb_schedule_show(schedule.id, route.id, state))
예제 #12
0
async def schedule_list(cb: types.CallbackQuery, callback_data: dict):
    """List all schedules for specific route."""
    with db_session() as db:
        route = db.get(Route, callback_data['route_id'])
        schedules = (db.query(Schedule).where(
            Schedule.route_id.__eq__(callback_data['route_id'])).all())

    await cb.message.edit_text(
        f'Настройка уведомлений для маршрута <b>{route.name}</b>.',
        reply_markup=inline_schedule.kb_schedule_list(schedules, route.id),
    )
    await cb.answer()
예제 #13
0
async def cmd_start(message: types.Message):
    """Show welcome message and register user.

    :param obj message: Message object.
    """
    with db_session() as db:
        user = (db.query(User).filter(User.uid.__eq__(
            message.from_user.id)).first())
        if not user:
            new_user = User(uid=message.from_user.id,
                            username=message.from_user.username)
            db.add(new_user)
    await message.answer(WELCOME_TEXT)
예제 #14
0
async def route_show(cb: types.CallbackQuery, callback_data: dict):
    """Show single route information."""
    # get user route from database
    with db_session() as db:
        route = db.get(Route, callback_data['route_id'])  # type: ignore

    message_text = route.message()
    if not message_text:
        await cb.answer('Что-то пошло не так!', show_alert=True)
    else:
        await cb.message.edit_text(
            message_text,
            reply_markup=inline_route.kb_route_single(route.id),
        )
예제 #15
0
async def route_add_url(message: types.Message, state: FSMContext):
    """Set route url and create route from state."""
    await state.update_data(url=message.text)
    state_data = await state.get_data()
    url = extract_url(state_data['url'])
    with db_session() as db:
        user = (db.query(User).filter(User.uid.__eq__(
            message.from_user.id)).first())

        route = Route(url=url, name=state_data['name'], user=user)
        db.add(route)
    await state.finish()
    await message.answer(
        f'Маршрут "<b>{route.name}</b>" добавлен.'
        '\nПосмотрите список всех маршрутов и настройте уведомления '
        'командой /routes. \nДобавьте еще один маршрут командой /routeadd.',
        reply_markup=types.ReplyKeyboardRemove(),
    )
예제 #16
0
    def get_active(cls: Type[T],
                   route: Optional[Union['Route', int]] = None) -> List[T]:
        """Get list of active schedules. Parent route needs to be active too.

        Args:
            route (Route, int): A Route instance or route id. Defaults to None.

        Returns:
            List of Schedule instances or empty list
            if no active schedules found.
        """
        active_routes = select(Route).where(Route.is_active.__eq__(True))
        if route is not None:
            route_id = int(route)
            active_routes = active_routes.where(Route.id.__eq__(route_id))
        stmt = (select(cls).where(cls.is_active.__eq__(True)).join(
            active_routes.cte()))
        with db_session() as db:
            return db.execute(stmt).scalars().all()
예제 #17
0
async def route_select(cb: types.CallbackQuery, callback_data: dict):
    """Display single route actions."""
    route_id = callback_data['route_id']
    with db_session() as db:
        route = db.get(Route, route_id)  # type: ignore
        state = route.is_active

        if callback_data['action'] == 'toggle':
            state = route.toggle()
            text = ('Уведомления включены'
                    if bool(state) else 'Уведомления отключены')
            await cb.answer(text)

    await cb.message.edit_text(
        f'Вы выбрали <b>{route.name}</b>.'
        '\nЧто вы хотите сделать с этим маршрутом?',
        reply_markup=inline_route.kb_route_buttons(route_id, state),
    )
    await cb.answer()
예제 #18
0
async def route_list(entity: Union[types.Message, types.CallbackQuery]):
    """Display all user routes by command or callback query."""
    message = ('У Вас пока нет ни одного маршрута. '
               'Вы можете создать новый маршрут при помощи команды /routeadd.')
    keyboard = None

    with db_session() as db:
        data = (db.query(Route).join(User).where(
            User.uid.__eq__(entity.from_user.id)).all())
    if len(data):
        message = 'Выберите маршрут из списка ниже:'
        keyboard = inline_route.kb_route_list(data)

    if isinstance(entity, types.CallbackQuery):
        await entity.message.edit_text(message, reply_markup=keyboard)
        await entity.answer()
        return

    await entity.answer(
        message,
        reply_markup=keyboard,
    )
예제 #19
0
    def setUpClass(cls):
        # start the driver
        try:
            import subprocess
            driver_directories = ['/usr/local/bin']
            os.environ.update({'PATH': ':'.join(driver_directories + [os.environ.get('PATH')])})
            cls.client = webdriver.Firefox()

        except Exception as exc:
            print("your path is:\n {}".format(sys.path))
            print("sys path is:\n {}".format(os.environ.get('PATH')))
            print("could not load selenium webdriver", str(exc), sep='\n')

        if cls.client:
            os.environ['APP_SETTINGS'] == 'testing' or os.environ.update(APP_SETTINGS='testing')
            cls.config_obj = get_env_config()
            cls.app = get_decorated_app()
            cls.app_context = cls.app.test_request_context()
            cls.app_context.push()

            # suppress logging
            import logging
            logger = logging.getLogger('werkzeug')
            logger.setLevel("ERROR")

            # instead of rebuilding each time, take a snapshot of db and reload that
            cls.db = db_session()
            cls.meta_db = get_db_metadata()

            # need to find a way to make this work
            # serialize_all(DB_PICKLE_NAME, cls.meta_db)

            # the server url
            cls.host = 'localhost'
            cls.port = 5001
            cls.server_url = 'http://{}:{}'.format(cls.host, cls.port)

            threading.Thread(target=lambda: cls.app.run(port=cls.port)).start()
예제 #20
0
async def schedule_add_days(cb: types.CallbackQuery, callback_data: dict,
                            state: FSMContext):
    """Save schedule data to database."""
    state_data = await state.get_data()
    time = state_data['time'].split(':')
    day_of_week = callback_data['days']
    cron = {
        'hour': time[0],
        'minute': time[1],
        'day_of_week': day_of_week,
    }

    with db_session() as db:
        route = db.get(Route, CreateSchedule.route_id)
        schedule = Schedule(route=route,
                            cron=json.dumps(cron).encode('utf-8'),
                            is_active=True)
        db.add(schedule)
        callback_data['route_id'] = route.id

    await state.finish()
    await cb.answer('Расписание уведомления добавлено')
    await schedule_list(cb, callback_data=callback_data)
예제 #21
0
def before_request():
    g.db = db_session()
    if session.get('current_user_id', None) and not request.endpoint == 'testing.server_shutdown':
        g.user = g.db.query(User).filter_by(id=int(session.get('current_user_id'))).first()
    else:
        g.user = None
예제 #22
0
 def setUp(self):
     os.environ['APP_SETTINGS'] == 'testing' or os.environ.update(APP_SETTINGS='testing')
     self.config_obj = get_env_config()
     self.db = db_session()
     init_db()
     self.meta_db = get_db_metadata()