def get_icu_shortpost(self, icu: ICUData) -> List[BotResponse]:
        tweet_text = f"🏥 Die {self.divi_name} hat Daten über die #Intensivbetten in Deutschland für den " \
                     f"{icu.date.strftime('%d. %B %Y')} gemeldet.\n\n{format_float(icu.percent_occupied())}% " \
                     f"({format_int(icu.occupied_beds)}) der " \
                     f"Betten sind aktuell belegt. " \
                     f"In {format_noun(icu.occupied_covid, FormattableNoun.BEDS)} " \
                     f"({format_float(icu.percent_covid())}%) liegen Menschen" \
                     f" mit #COVID19, davon werden {format_int(icu.covid_ventilated)} beatmet. " \
                     f"Insgesamt gibt es {format_noun(icu.total_beds(), FormattableNoun.BEDS)} für Erwachsene."
        post = [BotResponse(tweet_text, [self.viz.icu_graph(0)])]

        icu_info = self.data.get_icu_global_facts()
        if icu_info:
            second_tweet = f"Insgesamt stehen in {icu_info.districts_total} Orten Intensivbetten zur Verfügung. "

            if icu_info.districts_full:
                second_tweet += f"Davon haben {icu_info.districts_full} Orte keine freien Intensivbetten mehr für Erwachsene. "

            if icu_info.districts_low:
                second_tweet += f"In weiteren {icu_info.districts_low} Orten sind mindestens 90% der Intensivbetten für Erwachsene belegt."

            if second_tweet:
                post.append(BotResponse(second_tweet))

        return post
    async def invite_event(self, room: MatrixRoom, event: InviteMemberEvent):
        if not event.membership == "invite" or event.state_key != self.matrix.user_id:
            return

        self.log.debug(f"Invite Event for {room.name}")

        resp = await self.matrix.join(room.room_id)
        if isinstance(resp, JoinError):
            self.log.error(
                f"Can't Join {room.room_id} ({room.encrypted}): {JoinError.message}"
            )
            return

        await self.matrix.sync()
        self.log.debug(f"Joined room {room.name}")

        await self.send_response(room.room_id,
                                 self.bot.handle_input('Start', room.room_id))

        if room.member_count > 2:
            await self.send_response(room.room_id, [
                BotResponse(
                    "Noch ein Hinweis: Da wir hier nicht zu zweit sind reagiere ich nur auf mentions!"
                )
            ])
Exemple #3
0
 async def send_bot_response(self, user: str, response: BotResponse):
     if response.message:
         images = response.images
         disable_unicode = not self.bot.get_user_setting(
             user, BotUserSettings.FORMATTING)
         max_chars = 2000
         if response.choices:
             max_chars = 640
         messages = split_message(adapt_text(str(response),
                                             just_strip=disable_unicode),
                                  max_chars=max_chars)
         for i in range(0, len(messages)):
             buttons = None
             if response.choices and i == len(messages) - 1:
                 buttons = []
                 if len(response.choices) > 3:
                     response.choices = response.choices[:3]
                 for choice in response.choices:
                     buttons.append(
                         PostbackButton(choice.label, choice.callback_data))
             await self.fb_messenger.send_message(user,
                                                  messages[i],
                                                  images=images,
                                                  buttons=buttons)
             images = None
             SENT_MESSAGE_COUNT.inc()
 def get_hospitalization_shortpost(
         self, hospitalization: Hospitalization) -> List[BotResponse]:
     responses = [
         BotResponse(
             f"🤒 Das {self.rki_name} hat die Hospitalisierungsdaten für den {hospitalization.date.strftime('%d. %B %Y')} veröffentlicht:\n\n"
             f"Die 7-Tage-Hospitalisierungsinzidenz liegt bei {format_float(hospitalization.incidence)} und in den "
             f"letzten 7 Tagen wurden {format_noun(hospitalization.cases, FormattableNoun.PERSONS)} ins Krankenhaus "
             f"aufgenommen. #COVID19")
     ]
     # Remove graphic, as it is misleading
     return responses
 def get_vaccination_shortpost(self,
                               vacc: VaccinationData) -> List[BotResponse]:
     responses = [
         BotResponse(
             f"💉 Das {self.rki_name} hat die Impfdaten für den {vacc.date.strftime('%d. %B %Y')} veröffentlicht.\n\n"
             f"{format_float(vacc.partial_rate * 100)}% der Bevölkerung haben mindestens eine #Impfung erhalten, "
             f"{format_float(vacc.full_rate * 100)}% sind vollständig erstimmunisiert. "
             f"{format_float(vacc.booster_rate * 100)}% haben eine Auffrischungsimpfung erhalten. #COVID19",
             [self.viz.vaccination_graph(0)]),
         BotResponse(
             f"Insgesamt wurden "
             f"{format_int(vacc.vaccinated_partial)} Erstimpfungen, {format_int(vacc.vaccinated_full)} Zweitimpfungen "
             f"und {format_int(vacc.vaccinated_booster)} Auffrischungsimpfungen durchgeführt. #COVID19"
         ),
         BotResponse(
             f"Es wurden {format_int(vacc.doses_diff)} Impfdosen verimpft. In den letzten 7 Tagen wurden "
             f"durchschnittlich täglich {format_int(vacc.avg_speed)} "
             f"Dosen verabreicht.", [self.viz.vaccination_speed_graph(0)])
     ]
     return responses
    def generate_icu_report(self, user: BotUser) -> List[BotResponse]:
        # Start creating report
        graphs = []
        subscriptions = []
        for district_id in user.subscriptions:
            district = self.covid_data.get_district_data(district_id)
            if district.icu_data:
                subscriptions.append(district)
        subscriptions = self.sort_districts(subscriptions)

        # Send How-To use if no subscriptions
        if not subscriptions:
            return self.get_how_to()

        message = "<b>Intensivbetten-Bericht vom {date}</b>\n\n"\
            .format(date=subscriptions[0].icu_data.date.strftime("%d.%m.%Y"))

        # Short introduction overview for first country subscribed to
        countries = list(filter(lambda d: d.type == "Staat", subscriptions))
        for c in countries:
            if self.user_manager.get_user_setting(
                    user.id, BotUserSettings.REPORT_GRAPHICS):
                graphs.append(self.visualization.icu_graph(c.id))

        country = None
        if countries:
            country = countries[0]
            subscriptions = list(
                filter(lambda x: x.id != country.id, subscriptions))
            message += self.get_icu_text(country)

        # Short summary for each subscribed district
        if subscriptions and len(subscriptions) > 0:
            for district in subscriptions:
                message += self.get_district_icu_summary(district)
                message += "\n\n"

        # Add a user message, if some exist
        user_hint = self.user_hints.get_hint_of_today()
        if user_hint:
            message += f"{user_hint}\n\n"

        # Sources
        message += '<i>Intensivbettendaten vom <a href="https://intensivregister.de">DIVI-Intensivregister</a>.</i>' \
                   '\n\n' \
                   '<i>Sende {info_command} um eine Erl├цuterung ' \
                   'der Daten zu erhalten. Ein Service von <a href="https://d-64.org">D64 - Zentrum f├╝r Digitalen ' \
                   'Fortschritt</a>.</i>'.format(info_command=self.command_formatter("Info"))

        message += '\n\n­ЪДњ­ЪЈй­ЪЉд­ЪЈ╗ Sharing is caring ­ЪЉЕ­ЪЈЙ­ЪДЉ­ЪЈ╝ <a href="https://covidbot.d-64.org">www.covidbot.d-64.org</a>'
        reports = [BotResponse(message, graphs)]
        return reports
 def get_how_to(self) -> List[BotResponse]:
     # Send How-To use if no subscriptions
     return [
         BotResponse(
             "Du hast keine abonnierten Orte. Sende uns einen Ort, um diesen zu abonnieren. Dieser "
             "taucht dann in deinem Bericht auf.",
             choices=[
                 UserChoice(
                     "Hilfe anzeigen", "/hilfe",
                     f"Sende {self.command_formatter('Hilfe')}, um einen ├юberblick ├╝ber "
                     f"die Funktionsweise zu bekommen.")
             ])
     ]
    async def send_message_to_users(self,
                                    message: str,
                                    users: List[Union[str, int]],
                                    append_report=False):
        if users:
            self.log.error("Can't send a message to specific users!")
            return

        if len(message) > 240:
            self.log.error("Message can't be longer than 240 characters!")
            return

        self.write_message([BotResponse(message)])
    def get_infection_shortpost(self, district_id: int) -> List[BotResponse]:
        graphs = [
            self.viz.incidence_graph(district_id),
            self.viz.infections_graph(district_id)
        ]
        district = self.data.get_district_data(district_id)
        date_str = "Am " + district.date.strftime('%d. %B %Y')
        if district.date == datetime.date.today() - datetime.timedelta(days=1):
            date_str = "Heute sind leider noch keine Daten verfügbar. Gestern"
        tweet_text = f"🦠 {date_str} wurden " \
                     f"{format_noun(district.new_cases, FormattableNoun.NEW_INFECTIONS, hashtag='#')} " \
                     f"{format_data_trend(district.cases_trend)} und " \
                     f"{format_noun(district.new_deaths, FormattableNoun.DEATHS)} " \
                     f"{format_data_trend(district.deaths_trend)} in {district.name} gemeldet. Die #Inzidenz liegt " \
                     f"bei {format_float(district.incidence)} {format_data_trend(district.incidence_trend)}. #COVID19"
        # Maximum of 4 graphs allowed
        #if district.vaccinations:
        #    graphs.append(self.viz.vaccination_graph(district_id))

        if district.icu_data:
            graphs.append(self.viz.icu_graph(district_id))

        return [BotResponse(tweet_text, graphs)]
 async def send_message_to_users(self, message: str,
                                 users: List[Union[str, int]]):
     for user in users:
         await self.send_response(user, [BotResponse(message)])
Exemple #11
0
def format_response(bot_response: BotResponse, just_strip: bool):
    bot_response.message = adapt_text(str(bot_response), just_strip=just_strip)
    return bot_response
    def generate_infection_report(self, user: BotUser) -> List[BotResponse]:
        # Send How-To use if no subscriptions
        if not user.subscriptions:
            return self.get_how_to()

        # Start creating report
        graphs = []
        subscriptions = []
        for district_id in user.subscriptions:
            base_data = self.covid_data.get_district_data(district_id)
            if base_data is not None:
                subscriptions.append(base_data)
            else:
                self.log.warn(f"No base data for {district_id}")
        subscriptions = self.sort_districts(subscriptions)

        message = "<b>Corona-Bericht vom {date}</b>\n\n".format(
            date=subscriptions[0].date.strftime("%d.%m.%Y"))

        # Short introduction overview for first country subscribed to
        countries = list(filter(lambda d: d.type == "Staat", subscriptions))
        for c in countries:
            if self.user_manager.get_user_setting(
                    user.id, BotUserSettings.REPORT_GRAPHICS):
                graphs.append(self.visualization.infections_graph(c.id))
                # Remove graphic, as it is misleading
                #graphs.append(self.visualization.hospitalization_graph(c.id))

        country = None
        if countries:
            country = countries[0]
            subscriptions = list(
                filter(lambda x: x.id != country.id, subscriptions))
            message += self.get_infection_text(country)

        # Short summary for each subscribed district
        if subscriptions and len(subscriptions) > 0:
            every_graph = self.user_manager.get_user_setting(
                user.id, BotUserSettings.REPORT_ALL_INFECTION_GRAPHS)

            for district in subscriptions:
                message += self.get_district_summary(
                    district,
                    self.user_manager.get_user_setting(
                        user.id, BotUserSettings.REPORT_INCLUDE_ICU),
                    self.user_manager.get_user_setting(
                        user.id, BotUserSettings.REPORT_INCLUDE_VACCINATION))
                if every_graph:
                    graphs.append(
                        self.visualization.infections_graph(district.id))
                message += "\n\n"

        # Generate multi-incidence graph for up to 8 districts
        if self.user_manager.get_user_setting(user.id,
                                              BotUserSettings.REPORT_GRAPHICS):
            districts = user.subscriptions[-8:]
            if 0 in user.subscriptions and 0 not in districts:
                districts[0] = 0
            graphs.append(self.visualization.multi_incidence_graph(districts))

        # Add some information regarding vaccinations, if available
        if country and country.vaccinations and \
                self.user_manager.get_user_setting(user.id, BotUserSettings.REPORT_INCLUDE_VACCINATION):
            message += self.get_vacc_text(country)
            if self.user_manager.get_user_setting(
                    user.id, BotUserSettings.REPORT_GRAPHICS):
                graphs.append(self.visualization.vaccination_graph(country.id))
            if self.user_manager.get_user_setting(
                    user.id, BotUserSettings.REPORT_EXTENSIVE_GRAPHICS):
                graphs.append(
                    self.visualization.vaccination_speed_graph(country.id))

        # Add some information regarding ICU, if available
        if country and country.icu_data and self.user_manager.get_user_setting(
                user.id, BotUserSettings.REPORT_INCLUDE_ICU):
            message += self.get_icu_text(country)
            if self.user_manager.get_user_setting(
                    user.id, BotUserSettings.REPORT_EXTENSIVE_GRAPHICS):
                graphs.append(self.visualization.icu_graph(country.id))

        # Add a user message, if some exist
        user_hint = self.user_hints.get_hint_of_today()
        if user_hint:
            message += f"{user_hint}\n\n"

        # Sources
        message += '<i>Daten vom Robert Koch-Institut (RKI), Lizenz: dl-de/by-2-0, weitere Informationen findest Du' \
                   ' im <a href="https://corona.rki.de/">Dashboard des RKI</a> und dem ' \
                   '<a href="https://impfdashboard.de/">Impfdashboard</a>. ' \
                   'Intensivbettendaten vom <a href="https://intensivregister.de">DIVI-Intensivregister</a>.</i>' \
                   '\n\n' \
                   '<i>Sende {info_command} um eine Erl├цuterung ' \
                   'der Daten zu erhalten. Ein Service von <a href="https://d-64.org">D64 - Zentrum f├╝r Digitalen ' \
                   'Fortschritt</a>.</i>'.format(info_command=self.command_formatter("Info"))

        message += '\n\n­ЪДњ­ЪЈй­ЪЉд­ЪЈ╗ Sharing is caring ­ЪЉЕ­ЪЈЙ­ЪДЉ­ЪЈ╝ <a href="https://covidbot.d-64.org">www.covidbot.d-64.org</a>'

        reports = [BotResponse(message, graphs)]
        return reports
    def generate_vaccination_report(self, user: BotUser) -> List[BotResponse]:
        # Start creating report
        graphs = []
        subscriptions = []
        for district_id in user.subscriptions:
            district = self.covid_data.get_district_data(district_id)

            # Add parent, if no vaccination data available
            if not district.vaccinations:
                if district.parent in [d.id for d in subscriptions]:
                    continue
                district = self.covid_data.get_district_data(district.parent)

            if district.vaccinations:
                subscriptions.append(district)

        # Send How-To use if no subscriptions
        if not user.subscriptions:
            return self.get_how_to()

        subscriptions = self.sort_districts(subscriptions)
        message = "<b>Impfbericht zum {date}</b>\n\n".format(
            date=subscriptions[0].vaccinations.date.strftime("%d.%m.%Y"))

        # Short introduction overview for first country subscribed to
        countries = list(filter(lambda d: d.type == "Staat", subscriptions))
        for c in countries:
            if self.user_manager.get_user_setting(
                    user.id, BotUserSettings.REPORT_GRAPHICS):
                graphs.append(self.visualization.vaccination_graph(c.id))
                graphs.append(self.visualization.vaccination_speed_graph(c.id))

        country = None
        if countries:
            country = countries[0]
            subscriptions = list(
                filter(lambda x: x.id != country.id, subscriptions))
            message += self.get_vacc_text(country)

        # Short summary for each subscribed district
        if subscriptions and len(subscriptions) > 0:
            for district in subscriptions:
                message += self.get_district_vacc_summary(district)
                message += "\n\n"

        # Add a user message, if some exist
        user_hint = self.user_hints.get_hint_of_today()
        if user_hint:
            message += f"{user_hint}\n\n"

        # Sources
        message += '<i>Daten vom Robert Koch-Institut (RKI) und BMG, Lizenz: dl-de/by-2-0, weitere Informationen findest Du' \
                   ' im <a href="https://impfdashboard.de/">Impfdashboard</a>.</i>' \
                   '\n\n' \
                   '<i>Sende {info_command} um eine Erl├цuterung ' \
                   'der Daten zu erhalten. Ein Service von <a href="https://d-64.org">D64 - Zentrum f├╝r Digitalen ' \
                   'Fortschritt</a>.</i>'.format(info_command=self.command_formatter("Info"))

        message += '\n\n­ЪДњ­ЪЈй­ЪЉд­ЪЈ╗ Sharing is caring ­ЪЉЕ­ЪЈЙ­ЪДЉ­ЪЈ╝ <a href="https://covidbot.d-64.org">www.covidbot.d-64.org</a>'

        reports = [BotResponse(message, graphs)]
        return reports
 def message_developer(self, message: str):
     if self.send_message(self.dev_chat_id, [BotResponse(message)]):
         return True
     return False
    async def send_unconfirmed_reports(self) -> None:
        germany = self.data.get_country_data()
        if not germany:
            raise ValueError("Could not find data for Germany")

        # Do not tweet at night, so we show up more recently in the morning
        if datetime.datetime.now().hour < 6:
            return

        if self.user_manager.get_user(
                self.user_id).created.date() == datetime.date.today():
            return

        # Infections
        last_update = self.user_manager.get_last_updates(
            self.user_id, MessageType.CASES_GERMANY)
        if not last_update or last_update.date() < germany.date:
            tweet_text = f"🦠 Das {self.rki_name} hat für den {germany.date.strftime('%d. %B %Y')} neue Infektionszahlen veröffentlicht.\n\n" \
                         f"Es wurden {format_noun(germany.new_cases, FormattableNoun.NEW_INFECTIONS, hashtag='#')} " \
                         f"{format_data_trend(germany.cases_trend)} und " \
                         f"{format_noun(germany.new_deaths, FormattableNoun.DEATHS)} " \
                         f"{format_data_trend(germany.deaths_trend)} in Deutschland gemeldet. Die bundesweite #Inzidenz liegt " \
                         f"bei {format_float(germany.incidence)} {format_data_trend(germany.incidence_trend)}, der " \
                         f"aktuelle R-Wert beträgt {format_float(germany.r_value.r_value_7day)}. #COVID19"
            if self.no_write:
                print(f"Sent message: {tweet_text}")
                self.user_manager.add_sent_report(self.user_id,
                                                  MessageType.CASES_GERMANY)
            elif self.write_message([
                    BotResponse(tweet_text, [
                        self.viz.infections_graph(0),
                        self.viz.incidence_graph(0)
                    ])
            ]):
                self.log.info("Tweet was successfully sent")
                self.user_manager.add_sent_report(self.user_id,
                                                  MessageType.CASES_GERMANY)

        # Vaccinations
        last_update = self.user_manager.get_last_updates(
            self.user_id, MessageType.VACCINATION_GERMANY)
        if not last_update or (germany.vaccinations and
                               last_update < germany.vaccinations.last_update):
            posts = self.get_vaccination_shortpost(germany.vaccinations)

            if self.no_write:
                print(f"Sent message: {posts[0].message}")
                self.user_manager.add_sent_report(
                    self.user_id, MessageType.VACCINATION_GERMANY)
            elif self.write_message(posts):
                self.user_manager.add_sent_report(
                    self.user_id, MessageType.VACCINATION_GERMANY)
                self.log.info("Tweet was successfully sent")

        # ICU
        last_update = self.user_manager.get_last_updates(
            self.user_id, MessageType.ICU_GERMANY)
        if not last_update or last_update < germany.icu_data.last_update:
            posts = self.get_icu_shortpost(germany.icu_data)

            if self.no_write:
                print(f"Sent message: {posts[1].message}")
                self.user_manager.add_sent_report(self.user_id,
                                                  MessageType.ICU_GERMANY)
            elif self.write_message(posts):
                self.log.info("Tweet was successfully sent")
                self.user_manager.add_sent_report(self.user_id,
                                                  MessageType.ICU_GERMANY)

        # Hospitalization
        last_update = self.user_manager.get_last_updates(
            self.user_id, MessageType.HOSPITALIZATION_GERMANY)
        if not last_update or last_update.date(
        ) < germany.hospitalisation.date:
            posts = self.get_hospitalization_shortpost(germany.hospitalisation)

            if self.no_write:
                print(f"Sent message: {posts[0].message}")
                self.user_manager.add_sent_report(
                    self.user_id, MessageType.HOSPITALIZATION_GERMANY)
            elif self.write_message(posts):
                self.log.info("Tweet was successfully sent")
                self.user_manager.add_sent_report(
                    self.user_id, MessageType.HOSPITALIZATION_GERMANY)