Ejemplo n.º 1
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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
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)
Ejemplo n.º 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)
Ejemplo n.º 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)
Ejemplo n.º 6
0
 def _build(cls, u_from, c_to, **kwargs):
     """
     Generate an XML message to send to a remote node.
     """
     diasp = DiasporaContact.get_for_contact(u_from.contact)
     fn = kwargs.pop('fn', cls.generate)
     xml = fn(u_from, c_to, **kwargs)
     m = DiasporaMessageBuilder(xml, diasp.username, u_from._unlocked_key)
     return m
Ejemplo n.º 7
0
 def _build(cls, u_from, c_to, **kwargs):
     """
     Generate an XML message to send to a remote node.
     """
     diasp = DiasporaContact.get_for_contact(u_from.contact)
     fn = kwargs.pop('fn', cls.generate)
     xml = fn(u_from, c_to, **kwargs)
     m = DiasporaMessageBuilder(xml, diasp.username, u_from._unlocked_key)
     return m
Ejemplo n.º 8
0
def webfinger(contact_addr):
    """
    Returns the Webfinger profile for a contact called <contact> (in
    "user@host" form).
    """
    contact_id, _ = contact_addr.split('@')
    c = Contact.get(int(contact_id))
    if not c or not c.user or not c.user.activated:
        abort(404, 'No such contact')
    diasp = DiasporaContact.get_for_contact(c)

    ns = 'http://docs.oasis-open.org/ns/xri/xrd-1.0'
    doc = etree.Element("{%s}XRD" % ns, nsmap={None: ns})
    etree.SubElement(doc, "Subject").text = "acct:%s" % diasp.username
    etree.SubElement(doc, "Alias").text = \
        '"{0}"'.format(url_for('index', _external=True))
    etree.SubElement(
        doc, "Link",
        rel='http://microformats.org/profile/hcard',
        type='text/html',
        href=url_for('.hcard', guid=diasp.guid, _external=True)
    )
    etree.SubElement(
        doc, "Link",
        rel='http://joindiaspora.com/seed_location',
        type='text/html',
        href=url_for('index', _external=True)
    )
    etree.SubElement(
        doc, "Link",
        rel='http://joindiaspora.com/guid',
        type='text/html',
        href=diasp.guid
    )
    etree.SubElement(
        doc, "Link",
        rel='http://webfinger.net/rel/profile-page',
        type='text/html',
        href=url_for('contacts.profile', contact_id=c.id, _external=True)
    )
    etree.SubElement(
        doc, "Link",
        rel='http://schemas.google.com/g/2010#updates-from',
        type='application/atom+xml',
        href=url_for('contacts.feed', contact_id=c.id, _external=True)
    )
    etree.SubElement(
        doc, "Link",
        rel='diaspora-public-key',
        type='RSA',
        href=b64encode(c.public_key.encode('ascii'))
    )

    return send_xml(doc)
Ejemplo n.º 9
0
def search(_user):
    from pyaspora.diaspora.models import DiasporaContact
    term = request.args.get('searchterm', None) or \
        abort(400, 'No search term provided')
    if re_match('[A-Za-z0-9._]+@[A-Za-z0-9.]+$', term):
        try:
            DiasporaContact.get_by_username(term)
        except:
            current_app.logger.debug(format_exc())

    matches = db.session.query(Contact).outerjoin(DiasporaContact).filter(
        or_(DiasporaContact.username.contains(term),
            Contact.realname.contains(term))).order_by(
                Contact.realname).limit(99)

    data = {'contacts': [json_contact(c, _user) for c in matches]}

    add_logged_in_user_to_data(data, _user)

    return render_response('contacts_search_results.tpl', data)
Ejemplo n.º 10
0
def webfinger(contact_addr):
    """
    Returns the Webfinger profile for a contact called <contact> (in
    "user@host" form).
    """
    contact_id, _ = contact_addr.split('@')
    c = Contact.get(int(contact_id))
    if not c or not c.user or not c.user.activated:
        abort(404, 'No such contact')
    diasp = DiasporaContact.get_for_contact(c)

    ns = 'http://docs.oasis-open.org/ns/xri/xrd-1.0'
    doc = etree.Element("{%s}XRD" % ns, nsmap={None: ns})
    etree.SubElement(doc, "Subject").text = "acct:%s" % diasp.username
    etree.SubElement(doc, "Alias").text = \
        '"{0}"'.format(url_for('index', _external=True))
    etree.SubElement(
        doc, "Link",
        rel='http://microformats.org/profile/hcard',
        type='text/html',
        href=url_for('.hcard', guid=diasp.guid, _external=True)
    )
    etree.SubElement(
        doc, "Link",
        rel='http://joindiaspora.com/seed_location',
        type='text/html',
        href=url_for('index', _external=True)
    )
    etree.SubElement(
        doc, "Link",
        rel='http://joindiaspora.com/guid',
        type='text/html',
        href=diasp.guid
    )
    etree.SubElement(
        doc, "Link",
        rel='http://webfinger.net/rel/profile-page',
        type='text/html',
        href=url_for('contacts.profile', contact_id=c.id, _external=True)
    )
    etree.SubElement(
        doc, "Link",
        rel='http://schemas.google.com/g/2010#updates-from',
        type='application/atom+xml',
        href=url_for('contacts.feed', contact_id=c.id, _external=True)
    )
    etree.SubElement(
        doc, "Link",
        rel='diaspora-public-key',
        type='RSA',
        href=b64encode(c.public_key.encode('ascii'))
    )

    return send_xml(doc)
Ejemplo n.º 11
0
def search(_user):
    from pyaspora.diaspora.models import DiasporaContact
    term = request.args.get('searchterm', None) or \
        abort(400, 'No search term provided')
    if re_match('[A-Za-z0-9._]+@[A-Za-z0-9.]+$', term):
        try:
            DiasporaContact.get_by_username(term)
        except:
            current_app.logger.debug(format_exc())

    matches = db.session.query(Contact).outerjoin(DiasporaContact).filter(or_(
        DiasporaContact.username.contains(term),
        Contact.realname.contains(term)
    )).order_by(Contact.realname).limit(99)

    data = {
        'contacts': [json_contact(c, _user) for c in matches]
    }

    add_logged_in_user_to_data(data, _user)

    return render_response('contacts_search_results.tpl', data)
Ejemplo n.º 12
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)

        participant = DiasporaContact.get_by_username(data['diaspora_handle'],
                                                      False)
        if not participant:
            return

        participant.contact.bio = MimePart(
            text_preview="This account has been deleted.",
            body="This account has been deleted.",
            type="text/plain")
        db.session.add(participant)
        db.session.query(Subscription).filter(
            Subscription.to_contact == participant.contact).delete()
        db.session.commit()
Ejemplo n.º 13
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)
Ejemplo n.º 14
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)
Ejemplo n.º 15
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)
Ejemplo n.º 16
0
    def receive(cls, xml, c_from, u_to):
        data = cls.as_dict(xml)

        participant = DiasporaContact.get_by_username(
            data['diaspora_handle'], False
        )
        if not participant:
            return

        participant.contact.bio = MimePart(
            text_preview="This account has been deleted.",
            body="This account has been deleted.",
            type="text/plain"
        )
        db.session.add(participant)
        db.session.query(Subscription).filter(
            Subscription.to_contact == participant.contact
        ).delete()
        db.session.commit()
Ejemplo n.º 17
0
def receive(guid):
    """
    Receive a Salmon Slap and save it for when the user logs in.
    """
    diasp = DiasporaContact.get_by_guid(guid)
    if diasp is None or not diasp.contact.user:
        abort(404, 'No such contact')

    queue_item = MessageQueue()
    queue_item.local_user = diasp.contact.user
    queue_item.remote = None
    queue_item.format = MessageQueue.INCOMING
    queue_item.body = request.form['xml'].encode('ascii')
    db.session.add(queue_item)
    db.session.commit()

    diasp.contact.user.notify_event()

    return 'OK'
Ejemplo n.º 18
0
def receive(guid):
    """
    Receive a Salmon Slap and save it for when the user logs in.
    """
    diasp = DiasporaContact.get_by_guid(guid)
    if diasp is None or not diasp.contact.user:
        abort(404, 'No such contact')

    queue_item = MessageQueue()
    queue_item.local_user = diasp.contact.user
    queue_item.remote = None
    queue_item.format = MessageQueue.INCOMING
    queue_item.body = request.form['xml'].encode('ascii')
    db.session.add(queue_item)
    db.session.commit()

    diasp.contact.user.notify_event()

    return 'OK'
Ejemplo n.º 19
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)
Ejemplo n.º 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
        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)
Ejemplo n.º 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)
        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)
Ejemplo n.º 22
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()
Ejemplo n.º 23
0
def hcard(guid):
    """
    Returns the hCard for the User with GUID <guid>. I would have
    preferred to use the primary key, but the protocol insists on
    fetch-by-GUID.
    """
    diasp = DiasporaContact.get_by_guid(guid)
    if diasp is None or not diasp.contact.user:
        abort(404, 'No such contact')
    c = diasp.contact

    ns = 'http://www.w3.org/1999/xhtml'
    doc = etree.Element("{%s}div" % ns, nsmap={None: ns}, id="content")
    etree.SubElement(doc, "h1").text = c.realname
    content_inner = etree.SubElement(
        doc,
        'div',
        **{'class': "content_inner"}
    )
    author = etree.SubElement(
        content_inner,
        'div',
        id="i",
        **{'class': "entity_profile vcard author"}
    )

    etree.SubElement(author, "h2").text = "User profile"

    dl = etree.SubElement(author, 'dl', **{'class': "entity_nickname"})
    etree.SubElement(dl, 'dt').text = 'Nickname'
    dd = etree.SubElement(dl, 'dd')
    etree.SubElement(
        dd,
        'a',
        rel='me',
        href=url_for('index'),
        **{'class': "nickname url uid"}
    ).text = c.realname

    dl = etree.SubElement(author, 'dl', **{'class': "entity_fn"})
    etree.SubElement(dl, 'dt').text = 'Full name'
    dd = etree.SubElement(dl, 'dd').text = c.realname

    dl = etree.SubElement(author, 'dl', **{'class': "entity_url"})
    etree.SubElement(dl, 'dt').text = 'URL'
    dd = etree.SubElement(dl, 'dd')
    etree.SubElement(
        dd,
        'a',
        id='pod_location',
        rel='me',
        href=url_for('index', _external=True),
        **{'class': "url"}
    ).text = url_for('index', _external=True)

    # FIXME - need to resize photos
    photos = {
        "entity_photo": "300px",
        "entity_photo_medium": "100px",
        "entity_photo_small": "50px"
    }
    for k, v in photos.items():
        src = diasp.photo_url()
        dl = etree.SubElement(author, "dl", **{'class': k})
        etree.SubElement(dl, "dt").text = "Photo"
        dd = etree.SubElement(dl, "dd")
        etree.SubElement(
            dd,
            'img',
            height=v,
            width=v,
            src=src,
            **{'class': "photo avatar"}
        )

    dl = etree.SubElement(author, 'dl', **{'class': "entity_searchable"})
    etree.SubElement(dl, 'dt').text = 'Searchable'
    dd = etree.SubElement(dl, 'dd')
    etree.SubElement(dd, 'a', **{'class': "searchable"}).text = 'true'

    return send_xml(doc, content_type='text/html')
Ejemplo n.º 24
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()
Ejemplo n.º 25
0
def hcard(guid):
    """
    Returns the hCard for the User with GUID <guid>. I would have
    preferred to use the primary key, but the protocol insists on
    fetch-by-GUID.
    """
    diasp = DiasporaContact.get_by_guid(guid)
    if diasp is None or not diasp.contact.user:
        abort(404, 'No such contact')
    c = diasp.contact

    ns = 'http://www.w3.org/1999/xhtml'
    doc = etree.Element("{%s}div" % ns, nsmap={None: ns}, id="content")
    etree.SubElement(doc, "h1").text = c.realname
    content_inner = etree.SubElement(doc, 'div', **{'class': "content_inner"})
    author = etree.SubElement(content_inner,
                              'div',
                              id="i",
                              **{'class': "entity_profile vcard author"})

    etree.SubElement(author, "h2").text = "User profile"

    dl = etree.SubElement(author, 'dl', **{'class': "entity_nickname"})
    etree.SubElement(dl, 'dt').text = 'Nickname'
    dd = etree.SubElement(dl, 'dd')
    etree.SubElement(dd,
                     'a',
                     rel='me',
                     href=url_for('index'),
                     **{
                         'class': "nickname url uid"
                     }).text = c.realname

    dl = etree.SubElement(author, 'dl', **{'class': "entity_fn"})
    etree.SubElement(dl, 'dt').text = 'Full name'
    dd = etree.SubElement(dl, 'dd').text = c.realname

    dl = etree.SubElement(author, 'dl', **{'class': "entity_url"})
    etree.SubElement(dl, 'dt').text = 'URL'
    dd = etree.SubElement(dl, 'dd')
    etree.SubElement(dd,
                     'a',
                     id='pod_location',
                     rel='me',
                     href=url_for('index', _external=True),
                     **{
                         'class': "url"
                     }).text = url_for('index', _external=True)

    # FIXME - need to resize photos
    photos = {
        "entity_photo": "300px",
        "entity_photo_medium": "100px",
        "entity_photo_small": "50px"
    }
    for k, v in photos.items():
        src = diasp.photo_url()
        dl = etree.SubElement(author, "dl", **{'class': k})
        etree.SubElement(dl, "dt").text = "Photo"
        dd = etree.SubElement(dl, "dd")
        etree.SubElement(dd,
                         'img',
                         height=v,
                         width=v,
                         src=src,
                         **{'class': "photo avatar"})

    dl = etree.SubElement(author, 'dl', **{'class': "entity_searchable"})
    etree.SubElement(dl, 'dt').text = 'Searchable'
    dd = etree.SubElement(dl, 'dd')
    etree.SubElement(dd, 'a', **{'class': "searchable"}).text = 'true'

    return send_xml(doc, content_type='text/html')
Ejemplo n.º 26
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)
Ejemplo n.º 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
        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)