Beispiel #1
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        public = (data['public'] == 'true')
        assert (public or u_to)
        assert (data['diaspora_handle'] == c_from.diasp.username)
        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        p = Post(author=c_from, created_at=created)
        p.add_part(MimePart(
            type='text/x-markdown',
            body=data['raw_message'].encode('utf-8'),
        ),
                   order=0,
                   inline=True)
        p.tags = cls.find_tags(data['raw_message'])
        if public:
            p.share_with([c_from], show_on_wall=True)
        else:
            p.share_with([c_from, u_to.contact])
        p.thread_modified()

        p.diasp = DiasporaPost(guid=data['guid'],
                               type='public' if public else 'limited')
        db.session.commit()
Beispiel #2
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        node = xml.xpath('//message')[0]
        msg = dict((e.tag, e.text) for e in node)
        assert (data['diaspora_handle'] == c_from.diasp.username)
        assert (msg['diaspora_handle'] == c_from.diasp.username)
        assert (cls.valid_signature(c_from, msg['author_signature'], node))
        assert (cls.valid_signature(c_from, msg['parent_author_signature'],
                                    node))
        assert (data['guid'] == msg['parent_guid'])
        assert (data['guid'] == msg['conversation_guid'])

        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        p = Post(author=c_from, created_at=created)
        part_tags = [t for t in ('subject', 'text') if t in data or t in msg]
        for order, tag in enumerate(part_tags):
            p.add_part(MimePart(
                type='text/x-markdown' if tag == 'text' else 'text/plain',
                body=(data.get(tag, None) or msg[tag]).encode('utf-8'),
            ),
                       order=order,
                       inline=True)
        p.tags = cls.find_tags(msg['text'])
        p.share_with([c_from, u_to.contact])
        p.thread_modified()
        p.diasp = DiasporaPost(guid=data['guid'], type='private')
        db.session.add(p)
        db.session.commit()
Beispiel #3
0
 def _send_to_remotes(self, contacts):
     """
     Arrange to send this post to contacts on the remote node.
     """
     from pyaspora.diaspora.models import DiasporaPost
     contacts = [c for c in contacts if not c.user]
     if contacts:
         DiasporaPost.get_for_post(self).send_to(contacts)
Beispiel #4
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        author = DiasporaContact.get_by_username(data['diaspora_handle'], True,
                                                 False)
        assert (author)
        author = author.contact
        parent = DiasporaPost.get_by_guid(data['parent_guid'])

        # Which post is this in reply to?
        if parent:
            parent = parent.post
        else:
            raise TryLater()

        if u_to:
            assert (parent.shared_with(c_from))
        node = xml[0][0]
        if 'parent_author_signature' in data:
            assert (cls.valid_signature(parent.root().author,
                                        data['parent_author_signature'], node))
            if not current_app.config.get('ALLOW_INSECURE_COMPAT', False):
                assert (cls.valid_signature(author, data['author_signature'],
                                            node))
        else:
            assert (cls.valid_signature(author, data['author_signature'],
                                        node))

        p = Post(author=author, parent=parent)
        p.add_part(MimePart(
            type='text/x-markdown',
            body=data['text'].encode('utf-8'),
        ),
                   order=0,
                   inline=True)
        p.tags = cls.find_tags(data['text'])
        if u_to:
            p.share_with([p.author])
            if parent.shared_with(u_to.contact):
                p.share_with([u_to.contact])
        else:
            p.share_with([p.author], show_on_wall=True)
        if p.author.id != c_from.id:
            p.share_with([c_from])

        p.thread_modified()

        p.diasp = DiasporaPost(guid=data['guid'],
                               type='limited' if u_to else 'public')
        db.session.add(p)
        db.session.commit()

        if not (u_to) or (p.parent.author_id == u_to.contact.id):
            # If the parent has signed this then it must have already been
            # via the hub.
            if 'parent_author_signature' not in data:
                cls.forward(u_to, p, node)
Beispiel #5
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        author = DiasporaContact.get_by_username(
            data['diaspora_handle'], True, False
        )
        assert(author)
        author = author.contact
        parent = DiasporaPost.get_by_guid(data['parent_guid'])

        # Which post is this in reply to?
        if parent:
            parent = parent.post
        else:
            return

        if u_to:
            assert(parent.shared_with(c_from))
        node = xml[0][0]
        assert(cls.valid_signature(author, data['author_signature'], node))
        if 'parent_author_signature' in data:
            assert(
                cls.valid_signature(
                    parent.root().author, data['parent_author_signature'], node
                )
            )

        p = Post(author=author, parent=parent)
        p.add_part(MimePart(
            type='text/x-markdown',
            body=data['text'].encode('utf-8'),
        ), order=0, inline=True)
        p.tags = cls.find_tags(data['text'])
        if u_to:
            p.share_with([p.author])
            if parent.shared_with(u_to.contact):
                p.share_with([u_to.contact])
        else:
            p.share_with([p.author], show_on_wall=True)
        if p.author.id != c_from.id:
            p.share_with([c_from])

        p.thread_modified()

        p.diasp = DiasporaPost(
            guid=data['guid'],
            type='limited' if u_to else 'public'
        )
        db.session.add(p)
        db.session.commit()

        if not(u_to) or (p.parent.author_id == u_to.contact.id):
            # If the parent has signed this then it must have already been
            # via the hub.
            if 'parent_author_signature' not in data:
                cls.forward(u_to, p, node)
Beispiel #6
0
    def generate(cls, u_from, c_to, post, reshare):
        req = etree.Element('reshare')
        diasp = DiasporaPost.get_for_post(post)
        r_diasp = DiasporaPost.get_for_post(reshare)

        cls.struct_to_xml(req, [
            {'root_diaspora_id': reshare.author.diasp.username},
            {'root_guid': r_diasp.guid},
            {'guid': diasp.guid},
            {'diaspora_handle': post.author.diasp.username},
            {'public': 'true'},
            {'created_at': cls.format_dt(reshare.created_at)}
        ])
        return req
Beispiel #7
0
 def _send_to_remotes(self, contacts, reshare_of):
     """
     Arrange to send this post to contacts on the remote node.
     """
     from pyaspora.diaspora.models import DiasporaPost
     db.session.commit()  # write out shares
     contacts = [c for c in contacts if not c.user]
     if contacts:
         # Only public posts can be reshared by Diaspora
         if reshare_of and self.author_made_public() and \
                 reshare_of.author_made_public():
             DiasporaPost.get_for_post(self).reshare(contacts, reshare_of)
         else:
             DiasporaPost.get_for_post(self).send_to(contacts)
Beispiel #8
0
 def _send_to_remotes(self, contacts, reshare_of):
     """
     Arrange to send this post to contacts on the remote node.
     """
     from pyaspora.diaspora.models import DiasporaPost
     db.session.commit()  # write out shares
     contacts = [c for c in contacts if not c.user]
     if contacts:
         # Only public posts can be reshared by Diaspora
         if reshare_of and self.author_made_public() and \
                 reshare_of.author_made_public():
             DiasporaPost.get_for_post(self).reshare(contacts, reshare_of)
         else:
             DiasporaPost.get_for_post(self).send_to(contacts)
Beispiel #9
0
def json_feed(guid):
    """
    Look up the User identified by GUID and return the User's public feed
    as Diaspora-style JSON.
    """
    contact = DiasporaContact.get_by_guid(guid)
    if not(contact and contact.contact.user):
        abort(404, 'No such contact', force_status=True)

    feed_query = Post.Queries.public_wall_for_contact(contact.contact)
    feed = db.session.query(Post).join(Share).filter(feed_query). \
        order_by(desc(Post.thread_modified_at)). \
        group_by(Post.id).limit(99)

    ret = []
    for post in feed:
        text = DiasporaPost.get_for_post(post, commit=False).as_text()
        rep = {
            "author": {
                "diaspora_id": contact.username,
                "name": contact.contact.realname,
                "guid": contact.guid,
            },
            "created_at": post.created_at.isoformat(),
            "text": text,
            "public": True,
            "post_type": "StatusMessage",
            "guid": post.diasp.guid,
            "interacted_at": post.root().thread_modified_at.isoformat(),
            "provider_display_name": None,
        }
        ret.append(rep)

    return jsonify(response)
Beispiel #10
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        assert(data['diaspora_handle'] == c_from.diasp.username)
        target_guid = data.get('status_message_guid', data['guid'])
        parent = DiasporaPost.get_by_guid(target_guid)

        if parent:
            parent = parent.post
        else:
            return

        assert(parent)
        assert(parent.shared_with(c_from))
        photo_url = urljoin(
            data['remote_photo_path'], data['remote_photo_name']
        )
        resp = urlopen(photo_url)
        mime = resp.info().get('Content-Type')
        parent.add_part(MimePart(
            type=resp.info().get('Content-Type'),
            body=resp.read(),
            text_preview='(picture)'
        ), order=0, inline=bool(mime.startswith('image/')))
        parent.thread_modified()
        db.session.add(parent)
        db.session.commit()
Beispiel #11
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        public = (data['public'] == 'true')
        assert(public or u_to)
        assert(data['diaspora_handle'] == c_from.diasp.username)
        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        p = Post(author=c_from, created_at=created)
        p.add_part(MimePart(
            type='text/x-markdown',
            body=data['raw_message'].encode('utf-8'),
        ), order=0, inline=True)
        p.tags = cls.find_tags(data['raw_message'])
        if public:
            p.share_with([c_from], show_on_wall=True)
        else:
            p.share_with([c_from, u_to.contact])
        p.thread_modified()

        p.diasp = DiasporaPost(
            guid=data['guid'],
            type='public' if public else 'limited'
        )
        db.session.commit()
Beispiel #12
0
    def receive(cls, xml, c_from, u_to):
        # Not sure what these do, but they don't seem to be necessary, so do
        # nothing - like Shares?
        data = cls.as_dict(xml)
        post = DiasporaPost.get_by_guid(data['parent_guid'])
        if not post:
            raise TryLater()
        post = post.post  # Underlying Post object
        if post.is_public():
            return

        participant = DiasporaContact.get_by_username(data['diaspora_handle'],
                                                      True, False)
        assert (participant)
        node = xml[0][0]
        if 'parent_author_signature' in data:
            assert (cls.valid_signature(post.author,
                                        data['parent_author_signature'], node))
            if not current_app.config.get('ALLOW_INSECURE_COMPAT', False):
                assert (cls.valid_signature(participant,
                                            data['author_signature'], node))
        else:
            assert (cls.valid_signature(participant, data['author_signature'],
                                        node))

        if not post.shared_with(participant.contact):
            post.share_with([participant.contact], remote=False)
Beispiel #13
0
    def generate(cls, u_from, c_to, post, text):
        req = etree.Element("conversation")
        diasp = DiasporaPost.get_for_post(post)
        cls.struct_to_xml(req, [
            {'guid': diasp.guid},
            {'subject': '(no subject)'},
            {'created_at': cls.format_dt(post.created_at)}
        ])
        msg = etree.SubElement(req, "message")
        cls.struct_to_xml(msg, [
            {'guid': diasp.guid + '-1'},
            {'parent_guid': diasp.guid},
            {'text': text},
            {'created_at': cls.format_dt(post.created_at)},
            {'diaspora_handle': u_from.contact.diasp.username},
            {'conversation_guid': diasp.guid}
        ])
        etree.SubElement(msg, "parent_author_signature").text = \
            cls.generate_signature(u_from, msg)
        etree.SubElement(msg, "author_signature").text = \
            cls.generate_signature(u_from, msg)
        cls.struct_to_xml(req, [
            {'diaspora_handle': u_from.contact.diasp.username},
            {'participant_handles': ';'.join(
                s.contact.diasp.username for s in post.shares
                if s.contact.diasp
            )}
        ])

        return req
Beispiel #14
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        node = xml.xpath('//message')[0]
        msg = dict((e.tag, e.text) for e in node)
        assert(data['diaspora_handle'] == c_from.diasp.username)
        assert(msg['diaspora_handle'] == c_from.diasp.username)
        assert(cls.valid_signature(c_from, msg['author_signature'], node))
        assert(cls.valid_signature(
            c_from, msg['parent_author_signature'], node
        ))
        assert(data['guid'] == msg['parent_guid'])
        assert(data['guid'] == msg['conversation_guid'])

        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        p = Post(author=c_from, created_at=created)
        part_tags = [t for t in ('subject', 'text') if t in data or t in msg]
        for order, tag in enumerate(part_tags):
            p.add_part(MimePart(
                type='text/x-markdown' if tag == 'text' else 'text/plain',
                body=(data.get(tag, None) or msg[tag]).encode('utf-8'),
            ), order=order, inline=True)
        p.tags = cls.find_tags(msg['text'])
        p.share_with([c_from, u_to.contact])
        p.thread_modified()
        p.diasp = DiasporaPost(guid=data['guid'], type='private')
        db.session.add(p)
        db.session.commit()
Beispiel #15
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        assert (data['diaspora_handle'] == c_from.diasp.username)
        target_guid = data.get('status_message_guid', data['guid'])
        parent = DiasporaPost.get_by_guid(target_guid)

        if parent:
            parent = parent.post
        else:
            raise TryLater()

        assert (parent.shared_with(c_from))

        # Check if already received here
        for part in parent.parts:
            dp = part.mime_part.diasp
            if dp and dp.guid == data['guid']:
                return

        photo_url = urljoin(data['remote_photo_path'],
                            data['remote_photo_name'])
        resp = urlopen(photo_url, timeout=10)
        mime = resp.info().get('Content-Type')
        part = MimePart(type=mime, body=resp.read(), text_preview='(picture)')
        parent.add_part(part, order=0, inline=bool(mime.startswith('image/')))
        parent.thread_modified()
        db.session.add(parent)
        db.session.add(DiasporaPart(part=part, guid=data['guid']))
        db.session.commit()
Beispiel #16
0
def json_feed(guid):
    """
    Look up the User identified by GUID and return the User's public feed
    as Diaspora-style JSON.
    """
    contact = DiasporaContact.get_by_guid(guid)
    if not (contact and contact.contact.user):
        abort(404, 'No such contact', force_status=True)

    feed_query = Post.Queries.public_wall_for_contact(contact.contact)
    feed = db.session.query(Post).join(Share).filter(feed_query). \
        order_by(desc(Post.thread_modified_at)). \
        group_by(Post.id).limit(99)

    ret = []
    for post in feed:
        text = DiasporaPost.get_for_post(post, commit=False).as_text()
        rep = {
            "author": {
                "diaspora_id": contact.username,
                "name": contact.contact.realname,
                "guid": contact.guid,
            },
            "created_at": post.created_at.isoformat(),
            "text": text,
            "public": True,
            "post_type": "StatusMessage",
            "guid": post.diasp.guid,
            "interacted_at": post.root().thread_modified_at.isoformat(),
            "provider_display_name": None,
        }
        ret.append(rep)

    return jsonify(response)
Beispiel #17
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        public = (data['public'] == 'true')
        assert (public or u_to)
        assert (data['diaspora_handle'] == c_from.diasp.username)
        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        p = Post(author=c_from, created_at=created)
        msg = data.get('raw_message', None)
        if msg is None:
            msg = data.get('photo', None)
        if msg is None:
            msg = ''
        p.add_part(MimePart(
            type='text/x-markdown',
            body=msg.encode('utf-8'),
        ),
                   order=0,
                   inline=True)
        p.tags = cls.find_tags(msg)

        if 'poll' in data:
            pd = xml.xpath('//poll')[0]
            part = MimePart(
                type='application/x-diaspora-poll-question',
                body=pd.xpath('./question')[0].text.encode('utf-8'))
            part.diasp = DiasporaPart(guid=pd.xpath('./guid')[0].text)
            p.add_part(part, order=1, inline=True)
            for pos, answer in enumerate(pd.xpath('./poll_answer')):
                part = MimePart(
                    type='application/x-diaspora-poll-answer',
                    body=answer.xpath('./answer')[0].text.encode('utf-8'))
                part.diasp = DiasporaPart(guid=answer.xpath('./guid')[0].text)
                p.add_part(part, order=2 + pos, inline=True)

        if public:
            p.share_with([c_from], show_on_wall=True)
        else:
            p.share_with([c_from])
            if u_to.contact.subscribed_to(c_from):
                p.share_with([u_to.contact])
        p.thread_modified()

        p.diasp = DiasporaPost(guid=data['guid'],
                               type='public' if public else 'limited')
        db.session.commit()
Beispiel #18
0
    def generate(cls, u_from, c_to, post, text):
        req = etree.Element('comment')
        diasp = DiasporaPost.get_for_post(post)
        p_diasp = DiasporaPost.get_for_post(post.root())

        cls.struct_to_xml(req, [
            {'guid': diasp.guid},
            {'parent_guid': p_diasp.guid},
            {'text': text},
            {'diaspora_handle': post.author.diasp.username}
        ])
        etree.SubElement(req, "author_signature").text = \
            cls.generate_signature(u_from, req)
        if p_diasp.post.author.id == u_from.id:
            etree.SubElement(req, "parent_author_signature").text = \
                cls.generate_signature(u_from, req)
        return req
Beispiel #19
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        author = DiasporaContact.get_by_username(data['diaspora_handle'], True,
                                                 False)
        assert (author)
        author = author.contact
        parent = DiasporaPost.get_by_guid(data['parent_guid']).post
        if not parent:
            raise TryLater()
        assert (parent.shared_with(c_from))
        assert (parent.shared_with(u_to))
        node = xml[0][0]
        if 'parent_author_signature' in data:
            assert (cls.valid_signature(parent.author,
                                        data['parent_author_signature'], node))
            if not current_app.config.get('ALLOW_INSECURE_COMPAT', False):
                assert (cls.valid_signature(author, data['author_signature'],
                                            node))
        else:
            assert (cls.valid_signature(author, data['author_signature'],
                                        node))

        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        p = Post(author=author, created_at=created, parent=parent)
        p.add_part(MimePart(
            type='text/x-markdown',
            body=data['text'].encode('utf-8'),
        ),
                   order=0,
                   inline=True)
        p.tags = cls.find_tags(data['text'])
        p.share_with([s.contact for s in p.root().shares])
        p.thread_modified()
        p.diasp = DiasporaPost(guid=data['guid'], type='private')
        db.session.add(p)
        db.session.commit()

        if not (u_to) or (p.parent.author_id == u_to.contact.id):
            # If the parent has signed this then it must have already been
            # via the hub.
            if 'parent_author_signature' not in data:
                cls.forward(u_to, p, node)
Beispiel #20
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        author = DiasporaContact.get_by_username(
            data['diaspora_handle'], True, False
        )
        assert(author)
        author = author.contact
        parent = DiasporaPost.get_by_guid(data['parent_guid']).post
        if not parent:
            raise TryLater()
        assert(parent.shared_with(c_from))
        assert(parent.shared_with(u_to))
        node = xml[0][0]
        if 'parent_author_signature' in data:
            assert(cls.valid_signature(
                parent.author, data['parent_author_signature'], node
            ))
            if not current_app.config.get('ALLOW_INSECURE_COMPAT', False):
                assert(
                    cls.valid_signature(author, data['author_signature'], node)
                )
        else:
            assert(cls.valid_signature(author, data['author_signature'], node))

        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        p = Post(author=author, created_at=created, parent=parent)
        p.add_part(MimePart(
            type='text/x-markdown',
            body=data['text'].encode('utf-8'),
        ), order=0, inline=True)
        p.tags = cls.find_tags(data['text'])
        p.share_with([s.contact for s in p.root().shares])
        p.thread_modified()
        p.diasp = DiasporaPost(guid=data['guid'], type='private')
        db.session.add(p)
        db.session.commit()

        if not(u_to) or (p.parent.author_id == u_to.contact.id):
            # If the parent has signed this then it must have already been
            # via the hub.
            if 'parent_author_signature' not in data:
                cls.forward(u_to, p, node)
Beispiel #21
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        author = DiasporaContact.get_by_username(data['diaspora_handle'], True,
                                                 False)
        assert (author)
        author = author.contact
        parent = DiasporaPost.get_by_guid(data['parent_guid']).post
        assert (parent)
        if u_to:
            assert (parent.shared_with(c_from))
            assert (parent.shared_with(u_to))
        node = xml[0][0]
        assert (cls.valid_signature(author, data['author_signature'], node))
        if 'parent_author_signature' in data:
            assert (cls.valid_signature(parent.root().author,
                                        data['parent_author_signature'], node))

        p = Post(author=author)
        p.parent = parent
        p.add_part(MimePart(
            type='text/x-markdown',
            body=data['text'].encode('utf-8'),
        ),
                   order=0,
                   inline=True)
        p.tags = cls.find_tags(data['text'])
        if u_to:
            p.share_with([p.author, u_to.contact])
        else:
            p.share_with([p.author], show_on_wall=True)
        if p.author.id != c_from.id:
            p.share_with([c_from])

        p.thread_modified()

        p.diasp = DiasporaPost(guid=data['guid'],
                               type='limited' if u_to else 'public')
        db.session.add(p)
        db.session.commit()

        if not (u_to) or (p.parent.author_id == u_to.contact.id):
            cls.forward(u_to, p, node)
Beispiel #22
0
    def generate(cls, u_from, c_to, post, text):
        req = etree.Element('comment')
        diasp = DiasporaPost.get_for_post(post)
        p_diasp = DiasporaPost.get_for_post(post.root())

        cls.struct_to_xml(req, [{
            'guid': diasp.guid
        }, {
            'parent_guid': p_diasp.guid
        }, {
            'text': text
        }, {
            'diaspora_handle': post.author.diasp.username
        }])
        etree.SubElement(req, "author_signature").text = \
            cls.generate_signature(u_from, req)
        if p_diasp.post.author.id == u_from.id:
            etree.SubElement(req, "parent_author_signature").text = \
                cls.generate_signature(u_from, req)
        return req
Beispiel #23
0
 def generate(cls, u_from, c_to, post, text):
     diasp = DiasporaPost.get_for_post(post)
     req = etree.Element("status_message")
     cls.struct_to_xml(req, [
         {'raw_message': text},
         {'guid': diasp.guid},
         {'diaspora_handle': u_from.contact.diasp.username},
         {'public': 'false' if c_to else 'true'},
         {'created_at': cls.format_dt(post.created_at)}
     ])
     return req
Beispiel #24
0
    def generate(cls, u_from, c_to, post, reshare):
        req = etree.Element('reshare')
        diasp = DiasporaPost.get_for_post(post)
        r_diasp = DiasporaPost.get_for_post(reshare)

        cls.struct_to_xml(req,
                          [{
                              'root_diaspora_id': reshare.author.diasp.username
                          }, {
                              'root_guid': r_diasp.guid
                          }, {
                              'guid': diasp.guid
                          }, {
                              'diaspora_handle': post.author.diasp.username
                          }, {
                              'public': 'true'
                          }, {
                              'created_at': cls.format_dt(reshare.created_at)
                          }])
        return req
Beispiel #25
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        shared = DiasporaPost.get_by_guid(data['root_guid'])
        assert (shared)
        shared = shared.post
        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        post = Post(author=c_from, created_at=created)
        share_part = MimePart(type='application/x-pyaspora-share',
                              body=dumps({
                                  'post': {
                                      'id': shared.id
                                  },
                                  'author': {
                                      'id': shared.author_id,
                                      'name': shared.author.realname,
                                  }
                              }).encode('utf-8'),
                              text_preview="shared {0}'s post".format(
                                  shared.author.realname))
        post.add_part(share_part, order=0, inline=True)
        order = 0
        for part in shared.parts:
            if part.mime_part.type != 'application/x-pyaspora-share':
                order += 1
                post.add_part(part.mime_part, inline=part.inline, order=order)
        if not post.tags:
            post.tags = shared.tags
        if u_to:
            post.share_with([c_from, u_to.contact])
        else:
            post.share_with([c_from], show_on_wall=True)
        post.thread_modified()

        post.diasp = DiasporaPost(guid=data['guid'],
                                  type='limited' if u_to else 'public')
        db.session.add(post)
        db.session.commit()
Beispiel #26
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        public = (data['public'] == 'true')
        assert(public or u_to)
        assert(data['diaspora_handle'] == c_from.diasp.username)
        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        p = Post(author=c_from, created_at=created)
        msg = data.get('raw_message', None)
        if msg is None:
            msg = data.get('photo', None)
        if msg is None:
            msg = ''
        p.add_part(MimePart(
            type='text/x-markdown',
            body=msg.encode('utf-8'),
        ), order=0, inline=True)
        p.tags = cls.find_tags(msg)

        if 'poll' in data:
            pd = xml.xpath('//poll')[0]
            part = MimePart(
                type='application/x-diaspora-poll-question',
                body=pd.xpath('./question')[0].text.encode('utf-8')
            )
            part.diasp = DiasporaPart(guid=pd.xpath('./guid')[0].text)
            p.add_part(part, order=1, inline=True)
            for pos, answer in enumerate(pd.xpath('./poll_answer')):
                part = MimePart(
                    type='application/x-diaspora-poll-answer',
                    body=answer.xpath('./answer')[0].text.encode('utf-8')
                )
                part.diasp = DiasporaPart(guid=answer.xpath('./guid')[0].text)
                p.add_part(part, order=2+pos, inline=True)

        if public:
            p.share_with([c_from], show_on_wall=True)
        else:
            p.share_with([c_from])
            if u_to.contact.subscribed_to(c_from):
                p.share_with([u_to.contact])
        p.thread_modified()

        p.diasp = DiasporaPost(
            guid=data['guid'],
            type='public' if public else 'limited'
        )
        db.session.commit()
Beispiel #27
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        author = DiasporaContact.get_by_username(
            data['diaspora_handle'], True, False
        )
        assert(author)
        author = author.contact
        parent = DiasporaPost.get_by_guid(data['parent_guid']).post
        assert(parent)
        assert(parent.shared_with(c_from))
        assert(parent.shared_with(u_to))
        node = xml[0][0]
        assert(cls.valid_signature(author, data['author_signature'], node))
        if 'parent_author_signature' in data:
            assert(cls.valid_signature(
                parent.author, data['parent_author_signature'], node
            ))

        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        p = Post(author=author, created_at=created)
        p.parent = parent
        p.add_part(MimePart(
            type='text/x-markdown',
            body=data['text'].encode('utf-8'),
        ), order=0, inline=True)
        p.tags = cls.find_tags(data['text'])
        p.share_with([s.contact for s in p.root().shares])
        p.thread_modified()
        p.diasp = DiasporaPost(guid=data['guid'], type='private')
        db.session.add(p)
        db.session.commit()

        if not(u_to) or (p.parent.author_id == u_to.contact.id):
            cls.forward(u_to, p, node)
Beispiel #28
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        author = DiasporaContact.get_by_username(data['diaspora_handle'], True,
                                                 False)
        assert (author)
        author = author.contact
        parent = DiasporaPost.get_by_guid(data['parent_guid']).post
        assert (parent)
        assert (parent.shared_with(c_from))
        assert (parent.shared_with(u_to))
        node = xml[0][0]
        assert (cls.valid_signature(author, data['author_signature'], node))
        if 'parent_author_signature' in data:
            assert (cls.valid_signature(parent.author,
                                        data['parent_author_signature'], node))

        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        p = Post(author=author, created_at=created)
        p.parent = parent
        p.add_part(MimePart(
            type='text/x-markdown',
            body=data['text'].encode('utf-8'),
        ),
                   order=0,
                   inline=True)
        p.tags = cls.find_tags(data['text'])
        p.share_with([s.contact for s in p.root().shares])
        p.thread_modified()
        p.diasp = DiasporaPost(guid=data['guid'], type='private')
        db.session.add(p)
        db.session.commit()

        if not (u_to) or (p.parent.author_id == u_to.contact.id):
            cls.forward(u_to, p, node)
Beispiel #29
0
 def generate(cls, u_from, c_to, post, text):
     diasp = DiasporaPost.get_for_post(post)
     req = etree.Element("status_message")
     cls.struct_to_xml(req,
                       [{
                           'raw_message': text
                       }, {
                           'guid': diasp.guid
                       }, {
                           'diaspora_handle': u_from.contact.diasp.username
                       }, {
                           'public': 'false' if c_to else 'true'
                       }, {
                           'created_at': cls.format_dt(post.created_at)
                       }])
     return req
Beispiel #30
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        shared = DiasporaPost.get_by_guid(data['root_guid'])
        if not shared:
            current_app.logger.warning(
                'Could not find post being reshared (with GUID {0})'.format(
                    data['root_guid']
                )
            )
            return
        shared = shared.post
        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        post = Post(author=c_from, created_at=created)
        share_part = MimePart(
            type='application/x-pyaspora-share',
            body=dumps({
                'post': {'id': shared.id},
                'author': {
                    'id': shared.author_id,
                    'name': shared.author.realname,
                }
            }).encode('utf-8'),
            text_preview=u"shared {0}'s post".format(shared.author.realname)
        )
        post.add_part(share_part, order=0, inline=True)
        order = 0
        for part in shared.parts:
            if part.mime_part.type != 'application/x-pyaspora-share':
                order += 1
                post.add_part(part.mime_part, inline=part.inline, order=order)
        if not post.tags:
            post.tags = shared.tags
        if u_to:
            post.share_with([c_from])
            if u_to.contact.subscribed_to(c_from):
                p.share_with([u_to.contact])
        else:
            post.share_with([c_from], show_on_wall=True)
        post.thread_modified()

        post.diasp = DiasporaPost(
            guid=data['guid'],
            type='limited' if u_to else 'public'
        )
        db.session.add(post)
        db.session.commit()
Beispiel #31
0
 def receive(cls, xml, c_from, u_to):
     data = cls.as_dict(xml)
     assert (data['diaspora_handle'] == c_from.diasp.username)
     parent = DiasporaPost.get_by_guid(data['guid']).post
     assert (parent)
     assert (parent.shared_with(c_from))
     assert (parent.shared_with(u_to))
     photo_url = urljoin(data['remote_photo_path'],
                         data['remote_photo_name'])
     resp = urlopen(photo_url)
     mime = resp.info().get('Content-Type')
     parent.add_part(MimePart(type=resp.info().get('Content-Type'),
                              body=resp.read(),
                              text_preview='(picture)'),
                     order=0,
                     inline=bool(mime.startswith('image/')))
     parent.thread_modified()
     db.session.add(parent)
     db.session.commit()
Beispiel #32
0
    def generate(cls, u_from, c_to, post, text):
        req = etree.Element("conversation")
        diasp = DiasporaPost.get_for_post(post)
        cls.struct_to_xml(req, [{
            'guid': diasp.guid
        }, {
            'subject': '(no subject)'
        }, {
            'created_at': cls.format_dt(post.created_at)
        }])
        msg = etree.SubElement(req, "message")
        cls.struct_to_xml(msg,
                          [{
                              'guid': diasp.guid + '-1'
                          }, {
                              'parent_guid': diasp.guid
                          }, {
                              'text': text
                          }, {
                              'created_at': cls.format_dt(post.created_at)
                          }, {
                              'diaspora_handle': u_from.contact.diasp.username
                          }, {
                              'conversation_guid': diasp.guid
                          }])
        etree.SubElement(msg, "parent_author_signature").text = \
            cls.generate_signature(u_from, msg)
        etree.SubElement(msg, "author_signature").text = \
            cls.generate_signature(u_from, msg)
        cls.struct_to_xml(req,
                          [{
                              'diaspora_handle': u_from.contact.diasp.username
                          }, {
                              'participant_handles':
                              ';'.join(s.contact.diasp.username
                                       for s in post.shares if s.contact.diasp)
                          }])

        return req
Beispiel #33
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        assert(data['diaspora_handle'] == c_from.diasp.username)
        target_guid = data.get('status_message_guid', data['guid'])
        parent = DiasporaPost.get_by_guid(target_guid)

        if parent:
            parent = parent.post
        else:
            raise TryLater()

        assert(parent.shared_with(c_from))

        # Check if already received here
        for part in parent.parts:
            dp = part.mime_part.diasp
            if dp and dp.guid == data['guid']:
                return

        photo_url = urljoin(
            data['remote_photo_path'], data['remote_photo_name']
        )
        resp = urlopen(photo_url, timeout=10)
        mime = resp.info().get('Content-Type')
        part = MimePart(
            type=mime,
            body=resp.read(),
            text_preview='(picture)'
        )
        parent.add_part(
            part,
            order=0,
            inline=bool(mime.startswith('image/'))
        )
        parent.thread_modified()
        db.session.add(parent)
        db.session.add(DiasporaPart(part=part, guid=data['guid']))
        db.session.commit()
Beispiel #34
0
    def receive(cls, xml, c_from, u_to):
        # Not sure what these do, but they don't seem to be necessary, so do
        # nothing - like Shares?
        data = cls.as_dict(xml)
        post = DiasporaPost.get_by_guid(data['parent_guid'])
        if not post:
            raise TryLater()
        post = post.post  # Underlying Post object
        if post.is_public():
            return

        participant = DiasporaContact.get_by_username(
            data['diaspora_handle'], True, False
        )
        assert(participant)
        node = xml[0][0]
        if 'parent_author_signature' in data:
            assert(
                cls.valid_signature(
                    post.author, data['parent_author_signature'], node
                )
            )
            if not current_app.config.get('ALLOW_INSECURE_COMPAT', False):
                assert(
                    cls.valid_signature(
                        participant, data['author_signature'], node
                    )
                )
        else:
            assert(
                cls.valid_signature(
                    participant, data['author_signature'], node
                )
            )

        if not post.shared_with(participant.contact):
            post.share_with([participant.contact], remote=False)
Beispiel #35
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        author = DiasporaContact.get_by_username(
            data['diaspora_handle'], True, False
        )
        assert(author)
        author = author.contact
        poll_part = DiasporaPart.get_by_guid(data['parent_guid'])
        if not poll_part:
            raise TryLater()
        posts = dict((p.post.id, p.post) for p in poll_part.part.posts)
        if not posts:
            raise TryLater()

        answer_part = DiasporaPart.get_by_guid(data['poll_answer_guid'])
        assert answer_part, 'Poll participation must have stored answer'

        new_part = MimePart(
            type='application/x-diaspora-poll-participation',
            body=dumps({
                'poll_guid': data['parent_guid'],
                'answer_guid': data['poll_answer_guid'],
                'answer_text': answer_part.part.body.decode('utf-8')
            })
        )

        node = xml[0][0]
        assert(cls.valid_signature(author, data['author_signature'], node))

        saved = []
        for parent in posts.values():
            # FIXME: we should validate parent_author_signature against, err
            # the right post.
            if u_to and not parent.shared_with(c_from):
                continue
            p = Post(author=author, parent=parent)
            saved.append(p)
            p.add_part(new_part, order=0, inline=True)

            if u_to:
                p.share_with([p.author])
                if parent.shared_with(u_to.contact):
                    p.share_with([u_to.contact])
            else:
                p.share_with([p.author], show_on_wall=True)
            if p.author.id != c_from.id:
                p.share_with([c_from])

            p.thread_modified()

            p.diasp = DiasporaPost(
                guid=data['guid'],
                type='limited' if u_to else 'public'
            )
            db.session.add(p)

        db.session.commit()

        for p in saved:
            if not(u_to) or (p.parent.author_id == u_to.contact.id):
                # If the parent has signed this then it must have already been
                # via the hub.
                if 'parent_author_signature' not in data:
                    cls.forward(u_to, p, node)
Beispiel #36
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        shared = DiasporaPost.get_by_guid(data['root_guid'])
        if not shared:
            # Try to pull it from the Atom feed
            author = DiasporaContact.get_by_username(data['root_diaspora_id'],
                                                     True, True)
            if not author:
                raise TryLater()
            author.import_public_posts()
            shared = DiasporaPost.get_by_guid(data['root_guid'])

        if not shared:
            # Fall back to poking the origin server
            post_url = urljoin(author.server,
                               "/p/{0}.xml".format(data['root_guid']))
            resp = urlopen(post_url, timeout=10)
            current_app.logger.debug(
                'Injecting downloaded message into processing loop')
            process_incoming_message(resp.read(), author.contact, None)
            shared = DiasporaPost.get_by_guid(data['root_guid'])

        if not shared:
            # Failed
            current_app.logger.warning(
                'Could not find post being reshared (with GUID {0})'.format(
                    data['root_guid']))
            raise TryLater()
        shared = shared.post
        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        post = Post(author=c_from, created_at=created)
        share_part = MimePart(type='application/x-pyaspora-share',
                              body=dumps({
                                  'post': {
                                      'id': shared.id
                                  },
                                  'author': {
                                      'id': shared.author_id,
                                      'name': shared.author.realname,
                                  }
                              }).encode('utf-8'),
                              text_preview=u"shared {0}'s post".format(
                                  shared.author.realname))
        post.add_part(share_part, order=0, inline=True)
        order = 0
        for part in shared.parts:
            if part.mime_part.type != 'application/x-pyaspora-share':
                order += 1
                post.add_part(part.mime_part, inline=part.inline, order=order)
        if not post.tags:
            post.tags = shared.tags
        if u_to:
            post.share_with([c_from])
            if u_to.contact.subscribed_to(c_from):
                p.share_with([u_to.contact])
        else:
            post.share_with([c_from], show_on_wall=True)
        post.thread_modified()

        post.diasp = DiasporaPost(guid=data['guid'],
                                  type='limited' if u_to else 'public')
        db.session.add(post)
        db.session.commit()
Beispiel #37
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        shared = DiasporaPost.get_by_guid(data['root_guid'])
        if not shared:
            # Try to pull it from the Atom feed
            author = DiasporaContact.get_by_username(
                data['root_diaspora_id'], True, True
            )
            if not author:
                raise TryLater()
            author.import_public_posts()
            shared = DiasporaPost.get_by_guid(data['root_guid'])

        if not shared:
            # Fall back to poking the origin server
            post_url = urljoin(author.server, "/p/{0}.xml".format(
                data['root_guid']
            ))
            resp = urlopen(post_url, timeout=10)
            current_app.logger.debug(
                'Injecting downloaded message into processing loop'
            )
            process_incoming_message(resp.read(), author.contact, None)
            shared = DiasporaPost.get_by_guid(data['root_guid'])

        if not shared:
            # Failed
            current_app.logger.warning(
                'Could not find post being reshared (with GUID {0})'.format(
                    data['root_guid']
                )
            )
            raise TryLater()
        shared = shared.post
        created = datetime.strptime(data['created_at'], '%Y-%m-%d %H:%M:%S %Z')
        post = Post(author=c_from, created_at=created)
        share_part = MimePart(
            type='application/x-pyaspora-share',
            body=dumps({
                'post': {'id': shared.id},
                'author': {
                    'id': shared.author_id,
                    'name': shared.author.realname,
                }
            }).encode('utf-8'),
            text_preview=u"shared {0}'s post".format(shared.author.realname)
        )
        post.add_part(share_part, order=0, inline=True)
        order = 0
        for part in shared.parts:
            if part.mime_part.type != 'application/x-pyaspora-share':
                order += 1
                post.add_part(part.mime_part, inline=part.inline, order=order)
        if not post.tags:
            post.tags = shared.tags
        if u_to:
            post.share_with([c_from])
            if u_to.contact.subscribed_to(c_from):
                p.share_with([u_to.contact])
        else:
            post.share_with([c_from], show_on_wall=True)
        post.thread_modified()

        post.diasp = DiasporaPost(
            guid=data['guid'],
            type='limited' if u_to else 'public'
        )
        db.session.add(post)
        db.session.commit()
Beispiel #38
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)
        if DiasporaPost.get_by_guid(data['guid']):
            return
        author = DiasporaContact.get_by_username(data['diaspora_handle'], True,
                                                 False)
        assert (author)
        author = author.contact
        poll_part = DiasporaPart.get_by_guid(data['parent_guid'])
        if not poll_part:
            raise TryLater()
        posts = dict((p.post.id, p.post) for p in poll_part.part.posts)
        if not posts:
            raise TryLater()

        answer_part = DiasporaPart.get_by_guid(data['poll_answer_guid'])
        assert answer_part, 'Poll participation must have stored answer'

        new_part = MimePart(type='application/x-diaspora-poll-participation',
                            body=dumps({
                                'poll_guid':
                                data['parent_guid'],
                                'answer_guid':
                                data['poll_answer_guid'],
                                'answer_text':
                                answer_part.part.body.decode('utf-8')
                            }))

        node = xml[0][0]
        assert (cls.valid_signature(author, data['author_signature'], node))

        saved = []
        for parent in posts.values():
            # FIXME: we should validate parent_author_signature against, err
            # the right post.
            if u_to and not parent.shared_with(c_from):
                continue
            p = Post(author=author, parent=parent)
            saved.append(p)
            p.add_part(new_part, order=0, inline=True)

            if u_to:
                p.share_with([p.author])
                if parent.shared_with(u_to.contact):
                    p.share_with([u_to.contact])
            else:
                p.share_with([p.author], show_on_wall=True)
            if p.author.id != c_from.id:
                p.share_with([c_from])

            p.thread_modified()

            p.diasp = DiasporaPost(guid=data['guid'],
                                   type='limited' if u_to else 'public')
            db.session.add(p)

        db.session.commit()

        for p in saved:
            if not (u_to) or (p.parent.author_id == u_to.contact.id):
                # If the parent has signed this then it must have already been
                # via the hub.
                if 'parent_author_signature' not in data:
                    cls.forward(u_to, p, node)