Example #1
0
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))
Example #2
0
    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))
Example #3
0
  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))
Example #4
0
  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))
Example #5
0
    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)
Example #6
0
  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))
Example #7
0
  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))
Example #8
0
  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))
Example #9
0
  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)