def notify_subscribe(self, contact): """ Notify contact <contact> that they have a new follower (<self>), usually by placing an item in their feed. This is so the contact can see them and decide if they wish to follow them in return. The notice is also placed on <self>'s feed so they can know that they sent it. """ from pyaspora.post.models import Post assert(self.user or contact.user) p = Post(author=self) db.session.add(p) p.add_part( order=0, inline=True, mime_part=MimePart( body=dumps({ 'from': self.id, 'to': contact.id, 'to_name': contact.realname }).encode('utf-8'), type='application/x-pyaspora-subscribe', text_preview=u'subscribed to {0}'.format(contact.realname) ) ) if self.user: p.share_with([self]) if contact.user: p.share_with([contact]) p.thread_modified()
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()
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()
def import_public_posts(self): """ Load the JSON of public posts for this user and create local posts from them. """ url = self.server + 'people/{0}'.format(self.guid) req = Request(url) req.add_header('User-Agent', USER_AGENT) req.add_header('Accept', 'application/json') entries = json_load(urlopen(req, timeout=10)) if isinstance(entries, dict): return # Faulty node? for entry in entries: user_guid = entry['author']['guid'] username = entry['author']['diaspora_id'] user = self if self.username == username \ else DiasporaContact.get_by_username(username, commit=False) if not user or user.guid != user_guid: continue post_guid = entry['guid'] existing_post = DiasporaPost.get_by_guid(post_guid) if existing_post or not entry['public']: continue # Already imported if entry.get('root'): root_guid = entry['root']['guid'] root_post = DiasporaPost.get_by_guid(root_guid) if root_post: parent = root_post.post else: continue # Cannot find parent else: parent = None post = Post(author=user.contact, parent=parent) db.session.add(post) post.created_at = datetime.strptime( entry['created_at'], '%Y-%m-%dT%H:%M:%SZ' ) post.thread_modified(when=datetime.strptime( entry['interacted_at'], '%Y-%m-%dT%H:%M:%SZ' )) post.add_part( MimePart( type='text/x-markdown', body=entry['text'].encode('utf-8'), text_preview=entry['text'] ), inline=True, order=0 ) post.share_with([user.contact], show_on_wall=True) post.diasp = DiasporaPost(guid=post_guid, type='public')
def import_public_posts(self): """ Load the JSON of public posts for this user and create local posts from them. """ url = self.server + 'people/{0}'.format(self.guid) req = Request(url) req.add_header('User-Agent', USER_AGENT) req.add_header('Accept', 'application/json') entries = json_load(urlopen(req, timeout=10)) if isinstance(entries, dict): return # Faulty node? for entry in entries: user_guid = entry['author']['guid'] username = entry['author']['diaspora_id'] user = self if self.username == username \ else DiasporaContact.get_by_username(username, commit=False) if not user or user.guid != user_guid: continue post_guid = entry['guid'] existing_post = DiasporaPost.get_by_guid(post_guid) if existing_post or not entry['public']: continue # Already imported if entry.get('root'): root_guid = entry['root']['guid'] root_post = DiasporaPost.get_by_guid(root_guid) if root_post: parent = root_post.post else: continue # Cannot find parent else: parent = None post = Post(author=user.contact, parent=parent) db.session.add(post) post.created_at = datetime.strptime(entry['created_at'], '%Y-%m-%dT%H:%M:%SZ') post.thread_modified(when=datetime.strptime( entry['interacted_at'], '%Y-%m-%dT%H:%M:%SZ')) post.add_part(MimePart(type='text/x-markdown', body=entry['text'].encode('utf-8'), text_preview=entry['text']), inline=True, order=0) post.share_with([user.contact], show_on_wall=True) post.diasp = DiasporaPost(guid=post_guid, type='public')
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)
def hide(post_id, _user): """ Hide an existing Post from the user's wall and profile. """ post = Post.get(post_id) if not post: abort(404, 'No such post', force_status=True) post.hide(_user) db.session.commit() return redirect(url_for('feed.view', _external=True))
def comment(post_id, _user): """ Comment on (reply to) an existing Post. """ post = Post.get(post_id) if not post: abort(404, 'No such post', force_status=True) if not post.has_permission_to_view(_user.contact): abort(403, 'Forbidden') data = _base_create_form(_user, post) data.update({ 'relationship': { 'type': 'comment', 'object': json_post(post, children=False), 'description': 'Comment on this item' } }) return render_response('posts_create_form.tpl', data)
def share(post_id, _user): """ Form to share an existing Post with more Contacts. """ post = Post.get(post_id) if not post: abort(404, 'No such post', force_status=True) if not post.has_permission_to_view(_user.contact): abort(403, 'Forbidden') data = _base_create_form(_user) data.update({ 'relationship': { 'type': 'share', 'object': json_post(post, children=False), 'description': 'Share this item' }, 'default_target': { 'type': 'all_friends', 'id': None } }) return render_response('posts_create_form.tpl', data)
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()
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)
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)
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()
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()
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)
def edit(_user): """ Apply the changes from the user edit form. This updates such varied things as the profile photo and bio, the email address, name, password and interests. """ from pyaspora.post.models import Post p = Post(author=_user.contact) changed = [] order = 0 notif_freq = post_param( 'notification_frequency_hours', template='users_edit.tpl', optional=True ) _user.notification_hours = int(notif_freq) if notif_freq else None email = post_param('email', optional=True) if email and email != _user.email: _user.email = email old_pw = post_param('current_password', optional=True) new_pw1 = post_param('new_password', optional=True) new_pw2 = post_param('new_password2', optional=True) if old_pw and new_pw1 and new_pw2: if new_pw1 != new_pw2: abort(400, 'New passwords do not match') try: _user.change_password(old_pw, new_pw1) except ValueError: abort(400, 'Old password is incorrect') db.session.add(_user) attachment = request.files.get('avatar', None) if attachment and attachment.filename: changed.append('avatar') order += 1 check_attachment_is_safe(attachment) if not renderer_exists(attachment.mimetype) or \ not attachment.mimetype.startswith('image/'): abort(400, 'Avatar format unsupported') attachment_part = MimePart( type=attachment.mimetype, body=attachment.stream.read(), text_preview=attachment.filename ) p.add_part(attachment_part, order=order, inline=True) _user.contact.avatar = attachment_part name = post_param('name', template='users_edit.tpl', optional=True) if name and name != _user.contact.realname: _user.contact.realname = name changed.append('name') bio = post_param('bio', template='users_edit.tpl', optional=True) if bio: bio = bio.encode('utf-8') else: bio = b'' if bio and (not _user.contact.bio or _user.contact.bio.body != bio): changed.append('bio') order += 1 bio_part = MimePart(body=bio, type='text/plain', text_preview=None) p.add_part( order=order, inline=True, mime_part=bio_part ) _user.contact.bio = bio_part tags = post_param('tags', optional=True) if tags is not None: tag_objects = Tag.parse_line(tags, create=True) old_tags = set([t.id for t in _user.contact.interests]) new_tags = set([t.id for t in tag_objects]) if old_tags != new_tags: changed.append('tags') _user.contact.interests = tag_objects p.add_part( order=0, inline=True, mime_part=MimePart( body=json_dumps({ 'fields_changed': changed }).encode('utf-8'), type='application/x-pyaspora-profile-update', text_preview='updated their profile' ) ) if changed: db.session.add(p) db.session.add(_user.contact) p.share_with([_user.contact]) p.thread_modified() db.session.commit() return redirect(url_for('contacts.profile', contact_id=_user.contact.id))
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()
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()
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)
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()
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)
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)
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)
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)
def create(_user): """ Create a new Post and Share it with the selected Contacts. """ body = post_param('body') relationship = { 'type': post_param('relationship_type', optional=True), 'id': post_param('relationship_id', optional=True), } target = { 'type': post_param('target_type'), 'id': post_param('target_id', optional=True), } assert (target['type'] in targets_by_name) # Loathe inflexible HTML forms if target['id'] is None: target['id'] = post_param('target_%s_id' % target['type'], optional=True) if relationship['type']: post = Post.get(relationship['id']) if not post: abort(404, 'No such post', force_status=True) if not post.has_permission_to_view(_user.contact): abort(403, 'Forbidden') relationship['post'] = post shared = None post = Post(author=_user.contact) body_part = MimePart(type='text/x-markdown', body=body.encode('utf-8'), text_preview=None) topics = post_param('tags', optional=True) if topics: post.tags = Tag.parse_line(topics, create=True) if relationship['type'] == 'comment': post.parent = relationship['post'] post.add_part(body_part, order=0, inline=True) elif relationship['type'] == 'share': shared = relationship['post'] 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) post.add_part(body_part, order=1, inline=True) order = 1 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 else: # Naked post post.add_part(body_part, order=0, inline=True) attachment = request.files.get('attachment', None) if attachment and attachment.filename: check_attachment_is_safe(attachment) attachment_part = MimePart(type=attachment.mimetype, body=attachment.stream.read(), text_preview=attachment.filename) post.add_part(attachment_part, order=1, inline=bool(renderer_exists(attachment.mimetype))) post.thread_modified() # Sigh, need an ID for the post for making shares db.session.add(post) db.session.commit() targets_by_name[target['type']].make_shares(post, target['id'], reshare_of=shared) db.session.commit() data = json_post(post) return redirect(url_for('feed.view', _external=True), data_structure=data)
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()
def create(_user): """ Create a new Post and Share it with the selected Contacts. """ body = post_param('body') relationship = { 'type': post_param('relationship_type', optional=True), 'id': post_param('relationship_id', optional=True), } target = { 'type': post_param('target_type'), 'id': post_param('target_id', optional=True), } assert(target['type'] in targets_by_name) # Loathe inflexible HTML forms if target['id'] is None: target['id'] = post_param( 'target_%s_id' % target['type'], optional=True) if relationship['type']: post = Post.get(relationship['id']) if not post: abort(404, 'No such post', force_status=True) if not post.has_permission_to_view(_user.contact): abort(403, 'Forbidden') relationship['post'] = post post = Post(author=_user.contact) body_part = MimePart(type='text/x-markdown', body=body.encode('utf-8'), text_preview=None) topics = post_param('tags', optional=True) if topics: post.tags = Tag.parse_line(topics, create=True) if relationship['type'] == 'comment': post.parent = relationship['post'] post.add_part(body_part, order=0, inline=True) elif relationship['type'] == 'share': shared = relationship['post'] 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) post.add_part(body_part, order=1, inline=True) order = 1 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 else: # Naked post post.add_part(body_part, order=0, inline=True) attachment = request.files.get('attachment', None) if attachment and attachment.filename: check_attachment_is_safe(attachment) attachment_part = MimePart( type=attachment.mimetype, body=attachment.stream.read(), text_preview=attachment.filename ) post.add_part(attachment_part, order=1, inline=bool(renderer_exists(attachment.mimetype))) post.thread_modified() # Sigh, need an ID for the post for making shares db.session.add(post) db.session.commit() targets_by_name[target['type']].make_shares(post, target['id']) db.session.commit() data = json_post(post) return redirect(url_for('feed.view', _external=True), data_structure=data)
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()
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)