Пример #1
0
def activate_poll(poll_id):
    if request.method == 'GET':
        with my_session_scope(
                my_database) as session:  # type: MyDatabaseSession
            poll = session.get_poll_by_id(poll_id)
            if poll is None or poll.state != PollState.prepared:
                return render_template('admin_message.html',
                                       msg="poll_not_prepared")
            return render_template('admin_activate_poll.html',
                                   label=poll.label,
                                   poll_id=poll.poll_id)
    elif request.method == 'POST':
        request_tokens = json.loads(request.form["tokens"])
        tokens = request_tokens['tokens']
        attendees = request_tokens['users']
        with my_session_scope(
                my_database) as session:  # type: MyDatabaseSession
            if session.activate_poll(poll_id, tokens, attendees):
                return render_template('admin_message.html',
                                       msg="poll_activated",
                                       poll_id=poll_id)
            else:
                return render_template('admin_message.html',
                                       msg="poll_activate_error",
                                       poll_id=poll_id)
Пример #2
0
 def answer_subscribe_channel(self, update: Update,
                              context: CallbackContext):
     self.remove_all_inline_keyboards(update, context)
     chat_id = update.effective_chat.id
     with my_session_scope(
             self.my_database) as session:  # type: MyDatabaseSession
         user = session.get_user_by_chat_id(chat_id)
         channel = self.get_channel_from_update(session, update, context)
         if user is None:
             context.bot.send_message(
                 chat_id=chat_id, text=self.get_message_user_not_known())
             return ConversationHandler.END
         elif channel is not None:
             if channel.name in user.channels:
                 answer = "Du hast diesen Kanal bereits abonniert."
                 context.bot.send_message(chat_id=chat_id, text=answer)
                 return ConversationHandler.END
             else:
                 session.add_channel(chat_id, channel)
                 userLogger.info("User {0} subscribed channel {1}.".format(
                     chat_id, channel.name))
                 answer = "Kanal <b>" + channel.name + "</b> wurde abonniert."
                 context.bot.send_message(chat_id=chat_id,
                                          text=answer,
                                          parse_mode=ParseMode.HTML)
                 return ConversationHandler.END
         else:
             answer = "Kanal nicht vorhanden. Bitte anderen Kanal eingeben."
             unsubscribed_channels = session.get_unsubscribed_channels(
                 chat_id)
             reply_markup = TelegramShoutoutBot.create_channel_keyboard(
                 unsubscribed_channels, CB_SUBSCRIBE_CANCEL)
             context.bot.send_message_keyboard(chat_id=chat_id,
                                               text=answer,
                                               reply_markup=reply_markup)
Пример #3
0
 def cmd_send(self, update: Update, context: CallbackContext):
     self.remove_all_inline_keyboards(update, context)
     chat_id = update.effective_chat.id
     with my_session_scope(
             self.my_database) as session:  # type: MyDatabaseSession
         user = session.get_user_by_chat_id(chat_id)
         if user is None:
             context.bot.send_message(
                 chat_id=chat_id, text=self.get_message_user_not_known())
             return ConversationHandler.END
         elif user.ldap_account is not None and self.ldap_access.check_usergroup(
                 user.ldap_account):
             send_data: SendData = SendData()
             context.user_data["send"] = send_data
             accessible_channels: List[
                 Channel] = self.get_accessible_channels(session, user)
             answer = "<b>Nachricht senden</b>\n\n" \
                      "Bitte Kanal eingeben, an den die Nachricht gesendet werden soll.\n\n" \
                      "Verfügbare Kanäle:\n" + TelegramShoutoutBot.create_channel_list(accessible_channels)
             reply_markup = TelegramShoutoutBot.create_channel_keyboard(
                 accessible_channels, CB_SEND_CANCEL)
             send_data.botm_choose_channel = context.bot.send_message_keyboard(
                 chat_id=chat_id,
                 text=answer,
                 reply_markup=reply_markup,
                 parse_mode=ParseMode.HTML)
             return SEND_CHANNEL
         else:
             answer = "Du benötigst Admin-Rechte um Nachrichten zu verschicken."
             context.bot.send_message(chat_id=chat_id, text=answer)
             return ConversationHandler.END
Пример #4
0
def submit_vote(poll_id):
    token = request.form['token']
    answers = [int(x) for x in request.form.getlist('answer')]
    with my_session_scope(my_database) as session:  # type: MyDatabaseSession
        poll: Poll = session.get_poll_by_id(poll_id)
        vote: Vote = session.get_vote(poll_id, token)
        if not vote:
            return render_template('message.html',
                                   poll_label=poll.label,
                                   state="token_invalid")
        if poll.state != PollState.active:
            return render_template('message.html',
                                   poll_label=poll.label,
                                   state="not_active")
        # Validation of vote
        if len(answers) > poll.numVotes:
            return render_template('message.html',
                                   poll_label=poll.label,
                                   state="too_many_votes")
        if len(answers) > 1 and session.contains_exclusive_answer(answers):
            return render_template('message.html',
                                   poll_label=poll.label,
                                   state="invalid_combination")
        vote.answerOptions.clear()
        vote.association_ids.extend(answers)
        return render_template('message.html',
                               poll_label=poll.label,
                               state="successful")
Пример #5
0
 def cmd_admin(self, update: Update, context: CallbackContext):
     self.remove_all_inline_keyboards(update, context)
     chat_id = update.effective_chat.id
     with my_session_scope(
             self.my_database) as session:  # type: MyDatabaseSession
         user = session.get_user_by_chat_id(chat_id)
         if user is None:
             answer = self.get_message_user_not_known()
         elif user.ldap_account is None:
             answer = "Du hast <i>keinen</i> DPSG-Account mit deinem Telegram-Zugang verbunden."
         elif self.ldap_access.check_usergroup(user.ldap_account):
             accessible_channels: List[
                 Channel] = self.get_accessible_channels(session, user)
             answer = "Du hast einen DPSG-Account mit deinem Telegram-Zugang verbunden " \
                      "und hast Admin-Rechte in Telegram.\n\n" \
                      "Du kannst derzeit die folgenden Kanäle beschreiben: \n"
             answer += TelegramShoutoutBot.create_channel_list(
                 accessible_channels)
             answer += "\nFalls du Zugang zu weiteren Kanälen brauchst, wende dich ans Webteam."
         else:
             answer = "Du hast einen DPSG-Account mit deinem Telegram-Zugang verbunden, " \
                      "hast aber noch keine Admin-Rechte in Telegram.\n" \
                      "Wende dich mit deiner Chat-ID {0} ans Webteam um Admin-Rechte zu erhalten.".format(chat_id)
         context.bot.send_message(chat_id=chat_id,
                                  text=answer,
                                  parse_mode=ParseMode.HTML)
Пример #6
0
 def answer_unsubscribe_channel(self, update: Update,
                                context: CallbackContext):
     self.remove_all_inline_keyboards(update, context)
     chat_id = update.effective_chat.id
     with my_session_scope(
             self.my_database) as session:  # type: MyDatabaseSession
         user = session.get_user_by_chat_id(chat_id)
         channel = self.get_channel_from_update(session, update, context)
         if user is None:
             context.bot.send_message(
                 chat_id=chat_id, text=self.get_message_user_not_known())
             return ConversationHandler.END
         elif channel is None:
             answer = "Kanal nicht vorhanden. " \
                      "Bitte anderen Kanal eingeben oder Abbrechen mit /cancel."
             context.bot.send_message(chat_id=chat_id, text=answer)
             # no return statement (stay in same state)
         elif channel not in user.channels.values():
             answer = "Kanal nicht abonniert. " \
                      "Bitte anderen Kanal eingeben oder Abbrechen mit /cancel."
             context.bot.send_message(chat_id=chat_id, text=answer)
             # no return statement (stay in same state)
         elif channel.mandatory:
             answer = "Dieser Kanal ist immer abonniert und kann nicht abbestellt werden."
             context.bot.send_message(chat_id=chat_id, text=answer)
             # no return statement (stay in same state)
         else:
             session.remove_channel(chat_id, channel)
             userLogger.info("User {0} desubscribed channel {1}.".format(
                 chat_id, channel.name))
             answer = "Kanal <b>" + channel.name + "</b> wurde deabonniert."
             context.bot.send_message(chat_id=chat_id,
                                      text=answer,
                                      parse_mode=ParseMode.HTML)
             return ConversationHandler.END
Пример #7
0
 def cmd_unsubscribe(self, update: Update, context: CallbackContext):
     self.remove_all_inline_keyboards(update, context)
     chat_id = update.effective_chat.id
     with my_session_scope(
             self.my_database) as session:  # type: MyDatabaseSession
         user = session.get_user_by_chat_id(chat_id)
         if user is None:
             context.bot.send_message(
                 chat_id=chat_id, text=self.get_message_user_not_known())
             return ConversationHandler.END
         else:
             # Filter out mandatory channels from list to select from
             subscribed_channels = list(
                 filter(lambda channel: not channel.mandatory,
                        user.channels.values()))
             answer = "<b>Kanal deabonnieren</b>\n\n"\
                      "Kanal eingeben, der deabonniert werden soll oder Abbrechen mit /cancel.\n\n" \
                      "<b>Bereits abonnierte Kanäle:</b>\n" + \
                      TelegramShoutoutBot.create_channel_list(subscribed_channels)
             reply_markup = TelegramShoutoutBot.create_channel_keyboard(
                 subscribed_channels, CB_UNSUBSCRIBE_CANCEL)
             context.bot.send_message_keyboard(chat_id=chat_id,
                                               text=answer,
                                               reply_markup=reply_markup,
                                               parse_mode=ParseMode.HTML)
             return UNSUBSCRIBE_CHANNEL
Пример #8
0
 def cmd_stop(self, update: Update, context: CallbackContext):
     self.remove_all_inline_keyboards(update, context)
     chat_id = update.effective_chat.id
     with my_session_scope(self.my_database) as session:
         session.delete_user(chat_id)
         answer = "Alle Daten gelöscht. Der Bot wird keine weiteren Nachrichten schicken.\n" \
                  "Falls du wieder Nachrichten erhalten möchtest, schreibe /start."
         context.bot.send_message(chat_id=chat_id, text=answer)
Пример #9
0
def admin_overview():
    with my_session_scope(my_database) as session:  # type: MyDatabaseSession
        prepared_polls = session.get_polls(PollState.prepared)
        active_polls = session.get_polls(PollState.active)
        closed_polls = session.get_polls(PollState.closed)
        return render_template('admin_overview.html',
                               prepared_polls=prepared_polls,
                               active_polls=active_polls,
                               closed_polls=closed_polls)
Пример #10
0
    def answer_confirm(self, update: Update, context: CallbackContext):
        self.remove_all_inline_keyboards(update, context)
        chat = update.effective_chat
        send_data = context.user_data["send"]  # type: SendData
        updated_text = "Nachrichten werden versendet"
        send_data.botm_confirmation.result(10).edit_text(
            text=updated_text, parse_mode=ParseMode.HTML)
        channel_name = send_data.channel
        log_messages_strings = list(
            map(lambda msg: msg.__dict__, send_data.messages))
        log_message_format = "Sent message by user {0} ({1}, {2} {3}) to channel {4}: {5}"
        adminLogger.info(
            log_message_format.format(chat.id, chat.username, chat.first_name,
                                      chat.last_name, channel_name,
                                      log_messages_strings))
        with my_session_scope(
                self.my_database) as session:  # type: MyDatabaseSession
            # Verify permissions again to be safe (the conversation could be running for longer)
            user = session.get_user_by_chat_id(chat.id)
            channel = session.get_channel_by_name(channel_name)
            if user is None or user.ldap_account is None or not self.ldap_access.check_usergroup(user.ldap_account) or \
                    not self.ldap_access.check_filter(user.ldap_account, channel.ldap_filter):
                adminLogger.warning(
                    "Stopped message sending because of insufficient permissions."
                )
                answer = "Du hast keine Berechtigung zum Nachrichtenversand."
                context.bot.send_message(chat_id=chat.id, text=answer)
                return ConversationHandler.END
            # Send message out to users
            subscriber_count = 0
            last_message = None
            for user in session.get_users():
                if channel_name in user.channels:
                    subscriber_count += 1
                    for message in send_data.messages:
                        last_message = TelegramShoutoutBot.resend_message(
                            user.chat_id, message, context)

            if last_message is not None:
                promise_result = last_message.result(60)
                message_counter = len(send_data.messages) * subscriber_count
                if promise_result is not None:
                    answer = "Nachrichten erfolgreich zugestellt. " \
                             "Es wurden insgesamt <b>{0}</b> Nachrichten an <b>{1}</b> Abonnenten versendet."
                else:
                    answer = "Nicht alle Nachrichten konnten innerhalb von 60 Sekunden zugestellt werden. " \
                             "Es sollten insgesamt <b>{0}</b> an <b>{1}</b> Abonnenten Nachrichten versendet werden."
                context.bot.send_message(chat_id=chat.id,
                                         text=answer.format(
                                             message_counter,
                                             subscriber_count),
                                         parse_mode=ParseMode.HTML)
                adminLogger.info(answer)

            return ConversationHandler.END
Пример #11
0
 def cmd_start(self, update: Update, context: CallbackContext):
     self.remove_all_inline_keyboards(update, context)
     chat = update.effective_chat
     with my_session_scope(
             self.my_database) as session:  # type: MyDatabaseSession
         session.add_user(chat.id, chat.username, chat.first_name,
                          chat.last_name)
         context.bot.send_message(
             chat_id=chat.id,
             parse_mode=ParseMode.HTML,
             text='<b>Herzlich willkommen!</b>\n\n'
             'Mittels /subscribe kannst du jetzt zusätzliche Kanäle abbonieren.\n'
             'Mit /help werden dir alle Befehle angezeigt.')
Пример #12
0
def vote_form(poll_id):
    with my_session_scope(my_database) as session:  # type: MyDatabaseSession
        poll: Poll = session.get_poll_by_id(poll_id)
        if poll.state == PollState.prepared:
            return render_template('message.html',
                                   state="not_active",
                                   poll_label=poll.label,
                                   poll_id=poll_id)
        elif poll.state == PollState.active:
            return render_template('index.html', poll=poll)
        else:
            poll_results = session.get_results(poll_id)
            return render_template('poll_results.html',
                                   poll=poll,
                                   poll_results=poll_results)
Пример #13
0
 def cmd_unregister(self, update: Update, context: CallbackContext):
     self.remove_all_inline_keyboards(update, context)
     chat_id = update.effective_chat.id
     with my_session_scope(
             self.my_database) as session:  # type: MyDatabaseSession
         user = session.get_user_by_chat_id(chat_id)
         if user is None:
             answer = self.get_message_user_not_known()
         elif user.ldap_account is None:
             answer = "Du hast keinen DPSG-Account mit deinem Telegram-Zugang verbunden. " \
                      "Verwende /register um einen Account zu verbinden."
         else:
             ldap_account_name = user.ldap_account
             session.remove_ldap(chat_id)
             userLogger.info(
                 "User {0} removed his account connection to {1}.".format(
                     chat_id, ldap_account_name))
             answer = "Account-Zuordnung entfernt"
         context.bot.send_message(chat_id=chat_id, text=answer)
Пример #14
0
 def cmd_register(self, update: Update, context: CallbackContext):
     self.remove_all_inline_keyboards(update, context)
     chat_id = update.effective_chat.id
     with my_session_scope(
             self.my_database) as session:  # type: MyDatabaseSession
         user = session.get_user_by_chat_id(chat_id)
         if user is None:
             answer = self.get_message_user_not_known()
         elif user.ldap_account is not None:
             answer = "Du hast bereits einen DPSG-Account mit deinem Telegram-Zugang verbunden. " \
                      "Verwende /unregister um diese Verbindung zu lösen."
         else:
             letters_and_digits = string.ascii_letters + string.digits
             token = ''.join(
                 random.choice(letters_and_digits) for _ in range(20))
             user.ldap_register_token = token
             session.commit()
             answer = "Bitte klicke auf den folgenden Link:\n" \
                      "{0}{1}register/{2}?token={3}".format(Conf.url_host, Conf.url_path, chat_id, token)
     context.bot.send_message(chat_id=chat_id, text=answer)
Пример #15
0
 def answer_channel(self, update: Update, context: CallbackContext):
     self.remove_all_inline_keyboards(update, context)
     chat_id = update.effective_chat.id
     with my_session_scope(
             self.my_database) as session:  # type: MyDatabaseSession
         user = session.get_user_by_chat_id(chat_id)
         channel = self.get_channel_from_update(session, update, context)
         if user is None:
             context.bot.send_message(
                 chat_id=chat_id, text=self.get_message_user_not_known())
             return ConversationHandler.END
         elif channel is None:
             answer = "Kanal nicht vorhanden. Bitte anderen Kanal eingeben."
             context.bot.send_message(chat_id=chat_id, text=answer)
             # no return statement (stay in same state)
         else:
             if channel.ldap_filter is None or len(
                     channel.ldap_filter) == 0:
                 logger.warning(
                     "No LDAP filter configured for channel {0}. Denying access."
                     .format(channel.name))
             if self.ldap_access.check_filter(user.ldap_account,
                                              channel.ldap_filter):
                 send_data = context.user_data["send"]
                 send_data.channel = channel.name
                 updated_text = "<b>Nachricht senden</b>\n\n" \
                                "Ausgewählter Kanal: <b>" + channel.name + "</b>"
                 send_data.botm_choose_channel.result(10).edit_text(
                     text=updated_text, parse_mode=ParseMode.HTML)
                 answer = "Nachrichten eingeben, die gesendet werden soll."
                 context.bot.send_message(chat_id=chat_id, text=answer)
                 return SEND_MESSAGE
             else:
                 answer = "Du hast keine Berechtigung an diesen Kanal zu schreiben."
                 all_channels = session.get_channels()
                 reply_markup = TelegramShoutoutBot.create_channel_keyboard(
                     all_channels, CB_SEND_CANCEL)
                 context.bot.send_message_keyboard(
                     chat_id=chat_id,
                     text=answer,
                     reply_markup=reply_markup)
def register_login(chat_id):
    token = request.form['token']
    username = request.form['username']
    password = request.form['password']
    ldap_account = Conf.ldap_username_template.format(username)
    if not ldap_access.check_credentials(ldap_account, password):
        return render_template('register_login_fail.html', reason="ldap", chat_id=chat_id, token=token)
    with db.my_session_scope(my_database) as session:  # type: db.MyDatabaseSession
        user = session.get_user_by_chat_id(chat_id)
        if user is None:
            return render_template('register_login_fail.html', reason="chat_id",
                                   chat_id=chat_id, token=token)
        if user.ldap_register_token != token:
            return render_template('register_login_fail.html', reason="token",
                                   chat_id=chat_id, token=token)
        user.ldap_account = ldap_account
        user.ldap_register_token = None
        session.commit()
        log_message_format = "Registered chat_id {0} with token {1} for LDAP-User {2}"
        webLogger.info(log_message_format.format(chat_id, token, username))
    return render_template('register_login_success.html', chat_id=chat_id, token=token, username=username)
Пример #17
0
def new_poll():
    if request.method == 'GET':
        return render_template('admin_new_poll.html',
                               poll_types=PollType.__members__.items())
    elif request.method == 'POST':
        label = request.form["label"]
        poll_type = PollType[request.form["type"]]
        if poll_type == PollType.multiPersonVote:
            num_votes = request.form["numVotes"]
        else:
            num_votes = 1
        request_answers: List[str] = request.form.getlist("answer[]")
        answer_options = [x.strip() for x in request_answers if x.strip()]
        with my_session_scope(
                my_database) as session:  # type: MyDatabaseSession
            poll = session.add_poll(label, poll_type, num_votes,
                                    answer_options)
            if poll_type == PollType.multiPersonVote:
                answer_option_empty = AnswerOption(EMPTY_VOTE)
                answer_option_empty.exclusive = True
                poll.answer_options.append(answer_option_empty)
            return render_template('admin_message.html',
                                   msg="create_success",
                                   poll_id=poll.poll_id)
Пример #18
0
def close_poll(poll_id):
    with my_session_scope(my_database) as session:  # type: MyDatabaseSession
        session.close_poll(poll_id)
        return render_template('admin_message.html',
                               msg="poll_closed",
                               poll_id=poll_id)