Exemple #1
0
        def sendMessage(userKey: ndb.Key):

            # gevent somehow messes with the ndb context even though it's the same thread
            with cls.ndbClient.context():
                # Create message payload
                payload = {
                    "chat_id": str(userKey.id()),
                    "text": text,
                    "parse_mode": "HTML",
                    "reply_markup": TelegramMarkup.TemperatureKeyboard,
                }

                user: User = userKey.get()

                try:
                    resp = telegramApi.sendMessage(payload)

                    # User statuses have to be updated right after sending or user may hit an invalid state
                    # when they report their temperature
                    if resp["ok"]:
                        user.temp = User.TEMP_NONE
                        user.status = UserState.TEMP_REPORT
                        user.put()

                        return SUCCESS

                    else:
                        if (resp["description"] ==
                                "Forbidden: bot was blocked by the user"):

                            user.reset()
                            user.blocked = True
                            user.put()

                            return BLOCKED
                        else:
                            return FAILED
                            logger.error(resp["description"])

                except Exception as e:
                    logger.error(e)
                    return FAILED
Exemple #2
0
    def _activitypub_targets(self):
        """
        Returns: list of (Response, string inbox URL)
        """
        # if there's in-reply-to, like-of, or repost-of, they're the targets.
        # otherwise, it's all followers' inboxes.
        targets = self._targets()

        if not targets:
            # interpret this as a Create or Update, deliver it to followers
            inboxes = []
            for follower in Follower.query().filter(
                    Follower.key > Key('Follower', self.source_domain + ' '),
                    Follower.key < Key(
                        'Follower', self.source_domain + chr(ord(' ') + 1))):
                if follower.status != 'inactive' and follower.last_follow:
                    actor = json_loads(follower.last_follow).get('actor')
                    if actor and isinstance(actor, dict):
                        inboxes.append(
                            actor.get('endpoints', {}).get('sharedInbox')
                            or actor.get('publicInbox') or actor.get('inbox'))
            return [(Response.get_or_create(source=self.source_url,
                                            target=inbox,
                                            direction='out',
                                            protocol='activitypub',
                                            source_mf2=json_dumps(
                                                self.source_mf2)), inbox)
                    for inbox in inboxes if inbox]

        resps_and_inbox_urls = []
        for target in targets:
            # fetch target page as AS2 object
            try:
                self.target_resp = common.get_as2(target)
            except (requests.HTTPError, exc.HTTPBadGateway) as e:
                self.target_resp = getattr(e, 'response', None)
                if self.target_resp and self.target_resp.status_code // 100 == 2:
                    content_type = common.content_type(self.target_resp) or ''
                    if content_type.startswith('text/html'):
                        # TODO: pass e.response to try_salmon()'s target_resp
                        continue  # give up
                raise
            target_url = self.target_resp.url or target

            resp = Response.get_or_create(source=self.source_url,
                                          target=target_url,
                                          direction='out',
                                          protocol='activitypub',
                                          source_mf2=json_dumps(
                                              self.source_mf2))

            # find target's inbox
            target_obj = self.target_resp.json()
            resp.target_as2 = json_dumps(target_obj)
            inbox_url = target_obj.get('inbox')

            if not inbox_url:
                # TODO: test actor/attributedTo and not, with/without inbox
                actor = (util.get_first(target_obj, 'actor')
                         or util.get_first(target_obj, 'attributedTo'))
                if isinstance(actor, dict):
                    inbox_url = actor.get('inbox')
                    actor = actor.get('url') or actor.get('id')
                if not inbox_url and not actor:
                    self.error(
                        'Target object has no actor or attributedTo with URL or id.'
                    )
                elif not isinstance(actor, str):
                    self.error(
                        'Target actor or attributedTo has unexpected url or id object: %r'
                        % actor)

            if not inbox_url:
                # fetch actor as AS object
                actor = common.get_as2(actor).json()
                inbox_url = actor.get('inbox')

            if not inbox_url:
                # TODO: probably need a way to save errors like this so that we can
                # return them if ostatus fails too.
                # self.error('Target actor has no inbox')
                continue

            inbox_url = urllib.parse.urljoin(target_url, inbox_url)
            resps_and_inbox_urls.append((resp, inbox_url))

        return resps_and_inbox_urls
def delete_book(book_id):
    key = Key(Book, book_id)
    if key.get() is None:
        raise BookNotFound()
    key.delete()
def delete_member(member_id):
    member = Key(Member, member_id)
    if member.get() is None:
        raise MemberNotFound()
    member.key.delete()