def fetch_type(noticeboard, page): """ Handle http request for specific type """ notices = get_type(noticeboard, page) notices = JSONEncoder().encode(notices) return jsonify(json.loads(notices))
def attempt_single_item(self, item): """Attempts to preview or publish a single mf2 item. Args: item: mf2 item dict from mf2py Returns: CreationResult """ self.maybe_inject_silo_content(item) obj = microformats2.json_to_object(item) ignore_formatting = self.ignore_formatting(item) if ignore_formatting: prop = microformats2.first_props(item.get('properties', {})) content = microformats2.get_text(prop.get('content')) if content: obj['content'] = content.strip() # which original post URL to include? in order of preference: # 1. rel-shortlink (background: https://github.com/snarfed/bridgy/issues/173) # 2. original user-provided URL if it redirected # 3. u-url if available # 4. actual final fetched URL if self.shortlink: obj['url'] = self.shortlink elif self.source_url() != self.fetched.url: obj['url'] = self.source_url() elif 'url' not in obj: obj['url'] = self.fetched.url logging.debug('Converted to ActivityStreams object: %s', json.dumps(obj, indent=2)) # posts and comments need content obj_type = obj.get('objectType') if obj_type in ('note', 'article', 'comment'): if (not obj.get('content') and not obj.get('summary') and not obj.get('displayName')): return gr_source.creation_result( abort=False, error_plain='Could not find content in %s' % self.fetched.url, error_html= 'Could not find <a href="http://microformats.org/">content</a> in %s' % self.fetched.url) self.preprocess(obj) include_link = self.include_link(item) if not self.authorize(): return gr_source.creation_result(abort=True) # RIP Facebook comments/likes. https://github.com/snarfed/bridgy/issues/350 if (isinstance(self.source, FacebookPage) and (obj_type == 'comment' or obj.get('verb') == 'like')): return gr_source.creation_result( abort=True, error_plain= 'Facebook comments and likes are no longer supported. :(', error_html= '<a href="https://github.com/snarfed/bridgy/issues/350">' 'Facebook comments and likes are no longer supported.</a> :(') if self.PREVIEW: result = self.source.gr_source.preview_create( obj, include_link=include_link, ignore_formatting=ignore_formatting) self.entity.published = result.content or result.description if not self.entity.published: return result # there was an error state = { 'source_key': self.source.key.urlsafe(), 'source_url': self.source_url(), 'target_url': self.target_url(), 'include_link': include_link, } vars = { 'source': self.preprocess_source(self.source), 'preview': result.content, 'description': result.description, 'webmention_endpoint': self.request.host_url + '/publish/webmention', 'state': self.encode_state_parameter(state), } vars.update(state) logging.info('Rendering preview with template vars %s', pprint.pformat(vars)) return gr_source.creation_result( template.render('templates/preview.html', vars)) else: result = self.source.gr_source.create( obj, include_link=include_link, ignore_formatting=ignore_formatting) self.entity.published = result.content if not result.content: return result # there was an error if 'url' not in self.entity.published: self.entity.published['url'] = obj.get('url') self.entity.type = self.entity.published.get( 'type') or models.get_type(obj) self.entity.type_label = self.source.TYPE_LABELS.get( self.entity.type) self.response.headers['Content-Type'] = 'application/json' logging.info('Returning %s', json.dumps(self.entity.published, indent=2)) self.response.headers['Location'] = self.entity.published[ 'url'].encode('utf-8') self.response.status = 201 return gr_source.creation_result( json.dumps(self.entity.published, indent=2))
def attempt_single_item(self, item): """Attempts to preview or publish a single mf2 item. Args: item: mf2 item dict from mf2py Returns: CreationResult """ self.maybe_inject_silo_content(item) obj = microformats2.json_to_object(item) ignore_formatting = self.ignore_formatting(item) if ignore_formatting: prop = microformats2.first_props(item.get('properties', {})) content = microformats2.get_text(prop.get('content')) if content: obj['content'] = content.strip() # which original post URL to include? in order of preference: # 1. rel-shortlink (background: https://github.com/snarfed/bridgy/issues/173) # 2. original user-provided URL if it redirected # 3. u-url if available # 4. actual final fetched URL if self.shortlink: obj['url'] = self.shortlink elif self.source_url() != self.fetched.url: obj['url'] = self.source_url() elif 'url' not in obj: obj['url'] = self.fetched.url logging.debug('Converted to ActivityStreams object: %s', json_dumps(obj, indent=2)) # posts and comments need content obj_type = obj.get('objectType') if obj_type in ('note', 'article', 'comment'): if (not obj.get('content') and not obj.get('summary') and not obj.get('displayName')): return gr_source.creation_result( abort=False, error_plain='Could not find content in %s' % self.fetched.url, error_html='Could not find <a href="http://microformats.org/">content</a> in %s' % self.fetched.url) self.preprocess(obj) include_link = self.include_link(item) if not self.authorize(): return gr_source.creation_result(abort=True) if self.PREVIEW: result = self.source.gr_source.preview_create( obj, include_link=include_link, ignore_formatting=ignore_formatting) previewed = result.content or result.description if self.entity.type == 'preview': self.entity.published = previewed if not previewed: return result # there was an error return self._render_preview(result, include_link=include_link) else: result = self.source.gr_source.create( obj, include_link=include_link, ignore_formatting=ignore_formatting) self.entity.published = result.content if not result.content: return result # there was an error if 'url' not in self.entity.published: self.entity.published['url'] = obj.get('url') self.entity.type = self.entity.published.get('type') or models.get_type(obj) self.response.headers['Content-Type'] = 'application/json' logging.info('Returning %s', json_dumps(self.entity.published, indent=2)) self.response.headers['Location'] = self.entity.published['url'] self.response.status = 201 return gr_source.creation_result( json_dumps(self.entity.published, indent=2))
def attempt_single_item(self, item): """Attempts to preview or publish a single mf2 item. Args: item: mf2 item dict from mf2py Returns: CreationResult """ self.maybe_inject_silo_content(item) obj = microformats2.json_to_object(item) ignore_formatting = self.ignore_formatting(item) if ignore_formatting: prop = microformats2.first_props(item.get('properties', {})) content = microformats2.get_text(prop.get('content')) if content: obj['content'] = content.strip() # which original post URL to include? in order of preference: # 1. rel-shortlink (background: https://github.com/snarfed/bridgy/issues/173) # 2. original user-provided URL if it redirected # 3. u-url if available # 4. actual final fetched URL if self.shortlink: obj['url'] = self.shortlink elif self.source_url() != self.fetched.url: obj['url'] = self.source_url() elif 'url' not in obj: obj['url'] = self.fetched.url logging.debug('Converted to ActivityStreams object: %s', json.dumps(obj, indent=2)) # posts and comments need content obj_type = obj.get('objectType') if obj_type in ('note', 'article', 'comment'): if (not obj.get('content') and not obj.get('summary') and not obj.get('displayName')): return gr_source.creation_result( abort=False, error_plain='Could not find content in %s' % self.fetched.url, error_html='Could not find <a href="http://microformats.org/">content</a> in %s' % self.fetched.url) self.preprocess(obj) omit_link = self.omit_link(item) if not self.authorize(): return gr_source.creation_result(abort=True) # RIP Facebook comments/likes. https://github.com/snarfed/bridgy/issues/350 if (isinstance(self.source, FacebookPage) and (obj_type == 'comment' or obj.get('verb') == 'like')): return gr_source.creation_result( abort=True, error_plain='Facebook comments and likes are no longer supported. :(', error_html='<a href="https://github.com/snarfed/bridgy/issues/350">' 'Facebook comments and likes are no longer supported.</a> :(') if self.PREVIEW: result = self.source.gr_source.preview_create( obj, include_link=not omit_link, ignore_formatting=ignore_formatting) self.entity.published = result.content or result.description if not self.entity.published: return result # there was an error state = { 'source_key': self.source.key.urlsafe(), 'source_url': self.source_url(), 'target_url': self.target_url(), 'bridgy_omit_link': omit_link, } vars = {'source': self.preprocess_source(self.source), 'preview': result.content, 'description': result.description, 'webmention_endpoint': self.request.host_url + '/publish/webmention', 'state': self.encode_state_parameter(state), } vars.update(state) logging.info('Rendering preview with template vars %s', pprint.pformat(vars)) return gr_source.creation_result( template.render('templates/preview.html', vars)) else: result = self.source.gr_source.create(obj, include_link=not omit_link, ignore_formatting=ignore_formatting) self.entity.published = result.content if not result.content: return result # there was an error if 'url' not in self.entity.published: self.entity.published['url'] = obj.get('url') self.entity.type = self.entity.published.get('type') or models.get_type(obj) self.entity.type_label = self.source.TYPE_LABELS.get(self.entity.type) self.response.headers['Content-Type'] = 'application/json' logging.info('Returning %s', json.dumps(self.entity.published, indent=2)) self.response.headers['Location'] = self.entity.published['url'].encode('utf-8') self.response.status = 201 return gr_source.creation_result( json.dumps(self.entity.published, indent=2))
def afficher_film_local(self, film): """ Affiche les données d'un film en base :param film: le film à afficher """ # affiche if film['affiche'] is not None: image = ImageTk.PhotoImage( resizeimage.resize_thumbnail( Image.open(io.BytesIO(film['affiche'])), [400, 200])) else: image = ImageTk.PhotoImage( resizeimage.resize_thumbnail(Image.open("afficheDefaut.jpg"), [400, 200])) self.label_affiche = ttk.Label(self, image=image) self.label_affiche.img = image # titre self.label_titre = ttk.Label(self, text=film['titre'], font='bold 16') # annee if film['annee'] is not None: self.label_annee = ttk.Label(self, text=str(film['annee'])) # duree if film['duree'] is not None: self.label_duree = ttk.Label( self, text=('Durée : ' + str(film['duree']) + ' minutes')) # saison if film['saison'] is not None and film['saison'] > 0: self.label_saison = ttk.Label(self, text=('Saisons : ' + str(film['saison']))) # note générale if film['note_gen'] is not None: self.label_note = ttk.Label(self, text=str(film['note_gen']) + '/10') # le type de film self.label_type = ttk.Label(self, text=get_type(film['type'])) # est à acheter ou non self.label_a_acheter = ttk.Label( self, text=('A acheter : ' + ('Oui' if film['a_acheter'] is True else 'Non'))) # est à voir self.label_a_voir = ttk.Label( self, text=('A voir : ' + ('Oui' if film['a_voir'] is True else 'Non'))) # collection if film['collection'] is not None: self.label_collection = ttk.Label( self, text=('De la collection : ' + film['collection']['titre'])) # boutons self.frame_boutons = ttk.Frame(self) self.button_supprimer = ttk.Button( self.frame_boutons, text="Supprimer", command=lambda: self.supprimer_film(film['id'])) self.button_supprimer.pack(side=tk.LEFT) self.button_vu = ttk.Button( self.frame_boutons, text="Vu !" if film['a_voir'] is True else 'A voir !', command=lambda: self.film_vu(film['id'])) self.button_vu.pack(side=tk.LEFT) if film['a_acheter'] is True: self.button_achete = ttk.Button( self.frame_boutons, text="Acheté !", command=lambda: self.film_achete(film['id'])) self.button_achete.pack(side=tk.LEFT) # histoire self.label_synopsis = ttk.Label(self, text=film['synopsis'], wraplength=500) # genres self.frame_genres = ttk.Frame(self) titre_lab_genre = ttk.Label(self.frame_genres, text='Genres : ', font='bold') titre_lab_genre.pack(side=tk.LEFT) if len(film['genres']) > 0: for genre in film['genres']: lab_genre = ttk.Label(self.frame_genres, text=genre['titre']) lab_genre.pack(side=tk.LEFT) # producteurs if len(film['producteurs']) > 0: r = 0 c = 1 self.frame_producteurs = ttk.Frame(self) titre_lab_producteurs = ttk.Label(self.frame_producteurs, text='Producteurs : ', font='bold') titre_lab_producteurs.grid(row=0, column=0) for producteur in film['producteurs']: lab_producteur = ttk.Label(self.frame_producteurs, text=producteur['nom']) lab_producteur.grid(row=r, column=c) c += 1 if c is 4: c = 0 r += 1 # realisateurs if len(film['realisateurs']) > 0: r = 0 c = 1 self.frame_realisateurs = ttk.Frame(self) titre_lab_realisateurs = ttk.Label(self.frame_realisateurs, text='Réalisateurs : ', font='bold') titre_lab_realisateurs.grid(row=0, column=0) for realisateur in film['realisateurs']: lab_realisateur = ttk.Label(self.frame_realisateurs, text=realisateur['nom']) lab_realisateur.grid(row=r, column=c) c += 1 if c is 4: c = 0 r += 1 # casting if len(film['acteurs']) > 0: r = 0 c = 1 self.frame_acteurs = ttk.Frame(self) titre_lab_acteurs = ttk.Label(self.frame_acteurs, text='Acteurs : ', font='bold') titre_lab_acteurs.grid(row=0, column=0) for acteur in film['acteurs']: lab_acteur = ttk.Label(self.frame_acteurs, text=(acteur['nom'] + '(' + acteur['role'] + ')')) lab_acteur.grid(row=r, column=c) c += 1 if c is 4: c = 0 r += 1 # affichage des éléments self.label_affiche.grid(row=0, column=0, rowspan=12) self.label_titre.grid(row=0, column=1) if film['annee'] is not None: self.label_annee.grid(row=1, column=1) if film['duree'] is not None: self.label_duree.grid(row=2, column=1) if film['saison'] is not None and film['saison'] > 0: self.label_saison.grid(row=3, column=1) if film['note_gen'] is not None: self.label_note.grid(row=4, column=1) self.label_type.grid(row=5, column=1) self.label_a_acheter.grid(row=6, column=1) self.label_a_voir.grid(row=7, column=1) if film['collection'] is not None: self.label_collection.grid(row=8, column=1) if len(film['genres']) > 0: self.frame_genres.grid(row=9, column=1) if len(film['producteurs']) > 0: self.frame_producteurs.grid(row=10, column=1) if len(film['realisateurs']) > 0: self.frame_realisateurs.grid(row=11, column=1) self.frame_boutons.grid(row=12, column=0) if len(film['acteurs']) > 0: self.frame_acteurs.grid(row=13, column=0, columnspan=2) self.label_synopsis.grid(row=14, column=0, columnspan=2)
def attempt_single_item(self, item): """Attempts to preview or publish a single mf2 item. Args: item: mf2 item dict from mf2py Returns: a CreationResult object, where content is the string HTTP response or None if the source cannot publish this item type. """ obj = microformats2.json_to_object(item) # which original post URL to include? if the source URL redirected, use the # (pre-redirect) source URL, since it might be a short URL. otherwise, use # u-url if it's set. finally, fall back to the actual fetched URL if self.source_url != self.fetched.url: obj['url'] = self.source_url elif 'url' not in obj: obj['url'] = self.fetched.url logging.debug('Converted to ActivityStreams object: %s', pprint.pformat(obj)) # posts and comments need content props = item.get('properties', {}) obj_type = obj.get('objectType') if obj_type in ('note', 'article', 'comment'): if (not obj.get('content') and not obj.get('summary') and not obj.get('displayName')): return as_source.creation_result( abort=False, error_plain='Could not find content in %s' % self.fetched.url, error_html='Could not find <a href="http://microformats.org/">content</a> in %s' % self.fetched.url) self.preprocess_activity(obj) # whether to include link to original post. bridgy_omit_link query param # (any value) takes precedence, then u-bridgy-omit-link mf2 class. if self.PREVIEW or 'bridgy_omit_link' in self.request.params: omit_link = self.request.get('bridgy_omit_link').lower() in ('', 'true') else: omit_link = 'bridgy-omit-link' in props if self.PREVIEW: result = self.source.as_source.preview_create( obj, include_link=not omit_link) self.entity.published = result.content or result.description if not self.entity.published: return result # there was an error vars = {'source': self.preprocess_source(self.source), 'preview': result.content, 'description': result.description, 'source_url': self.source_url, 'target_url': self.target_url, 'bridgy_omit_link': omit_link, 'webmention_endpoint': self.request.host_url + '/publish/webmention', } logging.info('Rendering preview with template vars %s', pprint.pformat(vars)) return as_source.creation_result( template.render('templates/preview.html', vars)) else: result = self.source.as_source.create(obj, include_link=not omit_link) self.entity.published = result.content if not result.content: return result # there was an error if 'url' not in self.entity.published: self.entity.published['url'] = obj.get('url') self.entity.type = self.entity.published.get('type') or models.get_type(obj) self.entity.type_label = self.source.TYPE_LABELS.get(self.entity.type) self.response.headers['Content-Type'] = 'application/json' logging.info('Returning %s', pprint.pformat(self.entity.published)) return as_source.creation_result( json.dumps(self.entity.published, indent=2))
def attempt_single_item(self, item): """Attempts to preview or publish a single mf2 item. Args: item: mf2 item dict from mf2py Returns: a CreationResult object, where content is the string HTTP response or None if the source cannot publish this item type. """ props = item.get('properties', {}) ignore_formatting = self.ignore_formatting() if ignore_formatting is None: ignore_formatting = 'bridgy-ignore-formatting' in props obj = microformats2.json_to_object(item) if ignore_formatting: prop = microformats2.first_props(props) obj['content'] = prop.get('content', {}).get('value').strip() # which original post URL to include? if the source URL redirected, use the # (pre-redirect) source URL, since it might be a short URL. otherwise, use # u-url if it's set. finally, fall back to the actual fetched URL if self.source_url() != self.fetched.url: obj['url'] = self.source_url() elif 'url' not in obj: obj['url'] = self.fetched.url logging.debug('Converted to ActivityStreams object: %s', json.dumps(obj, indent=2)) # posts and comments need content obj_type = obj.get('objectType') if obj_type in ('note', 'article', 'comment'): if (not obj.get('content') and not obj.get('summary') and not obj.get('displayName')): return gr_source.creation_result( abort=False, error_plain='Could not find content in %s' % self.fetched.url, error_html='Could not find <a href="http://microformats.org/">content</a> in %s' % self.fetched.url) self.preprocess_activity(obj, ignore_formatting=ignore_formatting) omit_link = self.omit_link() if omit_link is None: omit_link = 'bridgy-omit-link' in props if not self.authorize(): return gr_source.creation_result(abort=True) # RIP Facebook comments/likes. https://github.com/snarfed/bridgy/issues/350 if (isinstance(self.source, FacebookPage) and (obj_type == 'comment' or obj.get('verb') == 'like')): return gr_source.creation_result( abort=True, error_plain='Facebook comments and likes are no longer supported. :(', error_html='<a href="https://github.com/snarfed/bridgy/issues/350">' 'Facebook comments and likes are no longer supported.</a> :(') if self.PREVIEW: result = self.source.gr_source.preview_create( obj, include_link=not omit_link) self.entity.published = result.content or result.description if not self.entity.published: return result # there was an error state = { 'source_key': self.source.key.urlsafe(), 'source_url': self.source_url(), 'target_url': self.target_url(), 'bridgy_omit_link': omit_link, } vars = {'source': self.preprocess_source(self.source), 'preview': result.content, 'description': result.description, 'webmention_endpoint': self.request.host_url + '/publish/webmention', 'state': self.encode_state_parameter(state), } vars.update(state) logging.info('Rendering preview with template vars %s', pprint.pformat(vars)) return gr_source.creation_result( template.render('templates/preview.html', vars)) else: result = self.source.gr_source.create(obj, include_link=not omit_link) self.entity.published = result.content if not result.content: return result # there was an error if 'url' not in self.entity.published: self.entity.published['url'] = obj.get('url') self.entity.type = self.entity.published.get('type') or models.get_type(obj) self.entity.type_label = self.source.TYPE_LABELS.get(self.entity.type) self.response.headers['Content-Type'] = 'application/json' logging.info('Returning %s', json.dumps(self.entity.published, indent=2)) return gr_source.creation_result( json.dumps(self.entity.published, indent=2))
def attempt_single_item(self, item): """Attempts to preview or publish a single mf2 item. Args: item: mf2 item dict from mf2py Returns: CreationResult """ self.maybe_inject_silo_content(item) obj = microformats2.json_to_object(item) ignore_formatting = self.ignore_formatting(item) if ignore_formatting: prop = microformats2.first_props(item.get('properties', {})) content = microformats2.get_text(prop.get('content')) if content: obj['content'] = content.strip() # which original post URL to include? in order of preference: # 1. rel-shortlink (background: https://github.com/snarfed/bridgy/issues/173) # 2. original user-provided URL if it redirected # 3. u-url if available # 4. actual final fetched URL if self.shortlink: obj['url'] = self.shortlink elif self.source_url() != self.fetched.url: obj['url'] = self.source_url() elif 'url' not in obj: obj['url'] = self.fetched.url logging.debug('Converted to ActivityStreams object: %s', json.dumps(obj, indent=2)) # posts and comments need content obj_type = obj.get('objectType') if obj_type in ('note', 'article', 'comment'): if (not obj.get('content') and not obj.get('summary') and not obj.get('displayName')): return gr_source.creation_result( abort=False, error_plain='Could not find content in %s' % self.fetched.url, error_html='Could not find <a href="http://microformats.org/">content</a> in %s' % self.fetched.url) self.preprocess(obj) include_link = self.include_link(item) if not self.authorize(): return gr_source.creation_result(abort=True) # RIP Facebook. # https://github.com/snarfed/bridgy/issues/817 # https://github.com/snarfed/bridgy/issues/350 verb = obj.get('verb') if isinstance(self.source, FacebookPage): return gr_source.creation_result( abort=True, error_plain='Facebook is no longer supported. So long, and thanks for all the fish!', error_html='<a href="https://brid.gy/about#rip-facebook">Facebook is no longer supported. So long, and thanks for all the fish!</a>') if self.PREVIEW: result = self.source.gr_source.preview_create( obj, include_link=include_link, ignore_formatting=ignore_formatting) self.entity.published = result.content or result.description if not self.entity.published: return result # there was an error return self._render_preview(result, include_link=include_link) else: result = self.source.gr_source.create( obj, include_link=include_link, ignore_formatting=ignore_formatting) self.entity.published = result.content if not result.content: return result # there was an error if 'url' not in self.entity.published: self.entity.published['url'] = obj.get('url') self.entity.type = self.entity.published.get('type') or models.get_type(obj) self.response.headers['Content-Type'] = 'application/json' logging.info('Returning %s', json.dumps(self.entity.published, indent=2)) self.response.headers['Location'] = self.entity.published['url'].encode('utf-8') self.response.status = 201 return gr_source.creation_result( json.dumps(self.entity.published, indent=2))
def attempt_single_item(self, item): """Attempts to preview or publish a single mf2 item. Args: item: mf2 item dict from mf2py Returns: string HTTP response on success, otherwise None Raises: NotImplementedError if the source doesn't support this item type """ obj = microformats2.json_to_object(item) # which original post URL to include? if the source URL redirected, use the # (pre-redirect) source URL, since it might be a short URL. otherwise, use # u-url if it's set. finally, fall back to the actual fetched URL if self.source_url != self.fetched.url: obj['url'] = self.source_url elif 'url' not in obj: obj['url'] = self.fetched.url logging.debug('Converted to ActivityStreams object: %s', obj) # posts and comments need content props = item.get('properties', {}) obj_type = obj.get('objectType') if obj_type in ('note', 'article', 'comment'): if (not obj.get('content') and not obj.get('summary') and not obj.get('displayName')): raise NotImplementedError('Could not find <a href="http://microformats.org/">content</a> in %s' % self.fetched.url) # expand inReplyTo or object urls by fetching the original and # searching for rel=syndication self.expand_target_urls(obj) # special case for me: don't allow posts in live app, just comments, likes, # and reposts verb = obj.get('verb', '') if (not appengine_config.DEBUG and 'snarfed.org' in self.source.domains and not self.PREVIEW and obj_type in ('note', 'article') and verb not in ('like', 'share') and not verb.startswith('rsvp-')): return self.error('Not posting for snarfed.org') # RSVPs need in-reply-to _, url = self.source.as_source.base_object(obj) if (verb.startswith('rsvp-') or verb == 'invite') and not url: return self.error( "This looks like an RSVP, but it's missing an in-reply-to link to the " "%s event." % self.source.AS_CLASS.NAME, html="This looks like an <a href='http://indiewebcamp.com/rsvp'>RSVP</a>, " "but it's missing an <a href='http://indiewebcamp.com/comment'>in-reply-to</a> " "link to the %s event." % self.source.AS_CLASS.NAME, data=item) # whether to include link to original post. bridgy_omit_link query param # (any value) takes precedence, then u-bridgy-omit-link mf2 class. if 'bridgy_omit_link' in self.request.params: omit_link = self.request.get('bridgy_omit_link').lower() in ('', 'true') else: omit_link = 'bridgy-omit-link' in props if self.PREVIEW: self.entity.published = self.source.as_source.preview_create( obj, include_link=not omit_link) return template.render('templates/preview.html', { 'source': self.preprocess_source(self.source), 'preview': self.entity.published, 'source_url': self.fetched.url, 'target_url': self.target_url, 'bridgy_omit_link': omit_link, 'webmention_endpoint': self.request.host_url + '/publish/webmention', }) else: self.entity.published = self.source.as_source.create( obj, include_link=not omit_link) if 'url' not in self.entity.published: self.entity.published['url'] = obj.get('url') self.entity.type = self.entity.published.get('type') or models.get_type(obj) self.entity.type_label = self.source.TYPE_LABELS.get(self.entity.type) self.response.headers['Content-Type'] = 'application/json' return json.dumps(self.entity.published, indent=2)