Ejemplo n.º 1
0
def process_article_submission(handler, article_type):
    property_hash = restful.get_sent_properties(handler.request.get, [
        'title', ('body', get_sanitizer_func(handler, trusted_source=True)),
        'legacy_id', ('format', get_format), ('published', get_datetime),
        ('updated', get_datetime), ('tags', get_tags),
        ('html', get_html, 'body', 'format'),
        ('permalink', permalink_funcs[article_type], 'title', 'published')
    ])

    if property_hash:
        if 'tags' in property_hash:
            property_hash['tag_keys'] = [
                get_tag_key(name) for name in property_hash['tags']
            ]
        property_hash['format'] = 'html'  # For now, convert all to HTML
        property_hash['article_type'] = article_type
        article = models.blog.Article(**property_hash)
        article.set_associated_data({
            'relevant_links':
            handler.request.get('relevant_links'),
            'amazon_items':
            handler.request.get('amazon_items')
        })
        process_embedded_code(article)
        article.put()
        # Ensure there is a year entity for this entry's year
        models.blog.Year.get_or_insert('Y%d' % (article.published.year, ))
        # Update tags
        for key in article.tag_keys:
            db.get(key).counter.increment()
        do_sitemap_ping()
        restful.send_successful_response(handler, '/' + article.permalink)
        view.invalidate_cache()
    else:
        handler.error(400)
Ejemplo n.º 2
0
def process_article_edit(handler, permalink):
    # For http PUT, the parameters are passed in URIencoded string in body
    body = handler.request.body
    params = cgi.parse_qs(body)
    for key, value in params.iteritems():
        params[key] = value[0]
    property_hash = restful.get_sent_properties(params.get, [
        'title', ('body', get_sanitizer_func(handler, trusted_source=True)),
        ('format', get_format), ('updated', get_datetime), ('tags', get_tags),
        ('html', get_html, 'body', 'format')
    ])

    if property_hash:
        if 'tags' in property_hash:
            property_hash['tag_keys'] = [
                get_tag_key(name) for name in property_hash['tags']
            ]
        article = db.Query(models.blog.Article).filter('permalink =',
                                                       permalink).get()
        before_tags = set(article.tag_keys)
        for key, value in property_hash.iteritems():
            setattr(article, key, value)
        after_tags = set(article.tag_keys)
        for removed_tag in before_tags - after_tags:
            db.get(removed_tag).counter.decrement()
        for added_tag in after_tags - before_tags:
            db.get(added_tag).counter.increment()
        process_embedded_code(article)
        article.put()
        restful.send_successful_response(handler, '/' + article.permalink)
        view.invalidate_cache()
    else:
        handler.error(400)
Ejemplo n.º 3
0
Archivo: blog.py Proyecto: m4dc4p/bloog
def process_article_submission(handler, article_type):
    property_hash = restful.get_hash_from_request(handler.request, 
        ['title',
         'body',
         'format',
         'legacy_id',
         ('published', get_datetime),
         ('updated', get_datetime),
         ('tags', get_tags),
         ('html', get_html, 'body', 'format'),
         ('permalink', permalink_funcs[article_type], 'title', 'published')])
    
    article = model.Article(
        permalink = property_hash['permalink'],
        article_type = article_type,
        title = property_hash['title'],
        body = property_hash['body'],
        html = property_hash['html'],
        published = property_hash['published'],
        updated = property_hash['updated'],
        format = 'html')    # We are converting everything to HTML from Drupal 
                            # since it can mix formats within articles
    fill_optional_properties(article, property_hash)
    article.set_associated_data(
        {'relevant_links': handler.request.get('relevant_links'),       
         'amazon_items': handler.request.get('amazon_items')})
    article.put()
    restful.send_successful_response(handler, '/' + article.permalink)
    view.invalidate_cache()
Ejemplo n.º 4
0
Archivo: blog.py Proyecto: mloar/bloog
def process_article_edit(handler, permalink):
    # For http PUT, the parameters are passed in URIencoded string in body
    body = handler.request.body
    params = cgi.parse_qs(body)
    for key,value in params.iteritems():
        params[key] = value[0]
    property_hash = restful.get_sent_properties(params.get,
        ['title',
         ('body', get_sanitizer_func(handler, trusted_source=True)),
         ('format', get_format),
         ('updated', get_datetime),
         ('tags', get_tags),
         ('html', get_html, 'body', 'format')])

    if property_hash:
        if 'tags' in property_hash:
            property_hash['tag_keys'] = [get_tag_key(name) 
                                         for name in property_hash['tags']]
        article = db.Query(models.blog.Article).filter('permalink =', permalink).get()
        before_tags = set(article.tag_keys)
        for key,value in property_hash.iteritems():
            setattr(article, key, value)
        after_tags = set(article.tag_keys)
        for removed_tag in before_tags - after_tags:
            db.get(removed_tag).counter.decrement()
        for added_tag in after_tags - before_tags:
            db.get(added_tag).counter.increment()
        process_embedded_code(article)
        article.put()
        restful.send_successful_response(handler, '/' + article.permalink)
        view.invalidate_cache()
    else:
        handler.error(400)
Ejemplo n.º 5
0
Archivo: blog.py Proyecto: mloar/bloog
def process_article_submission(handler, article_type):
    property_hash = restful.get_sent_properties(handler.request.get, 
        ['title',
         ('body', get_sanitizer_func(handler, trusted_source=True)),
         'legacy_id',
         ('format', get_format),
         ('published', get_datetime),
         ('updated', get_datetime),
         ('tags', get_tags),
         ('html', get_html, 'body', 'format'),
         ('permalink', permalink_funcs[article_type], 'title', 'published')])

    if property_hash:
        if 'tags' in property_hash:
            property_hash['tag_keys'] = [get_tag_key(name) 
                                         for name in property_hash['tags']]
        property_hash['format'] = 'html'   # For now, convert all to HTML
        property_hash['article_type'] = article_type
        article = models.blog.Article(**property_hash)
        article.set_associated_data(
            {'relevant_links': handler.request.get('relevant_links'),
             'amazon_items': handler.request.get('amazon_items')})
        process_embedded_code(article)
        article.put()
        for key in article.tag_keys:
            db.get(key).counter.increment()
        do_sitemap_ping()
        restful.send_successful_response(handler, '/' + article.permalink)
        view.invalidate_cache()
    else:
        handler.error(400)
Ejemplo n.º 6
0
Archivo: blog.py Proyecto: m4dc4p/bloog
 def delete(self, year, month, perm_stem):
     permalink = year + '/' + month + '/' + perm_stem
     logging.debug("Deleting blog entry %s", permalink)
     article = db.Query(model.Article). \
                  filter('permalink =', permalink).get()
     article.delete()
     view.invalidate_cache()
     restful.send_successful_response(self, "/")
Ejemplo n.º 7
0
 def delete(self, comment_id):
   logging.info("Deleting comment %s", comment_id)
   comment = models.blog.Comment.get(db.Key(comment_id))
   article = comment.article
   article.num_comments -= 1
   article.put()
   comment.delete()
   view.invalidate_cache(article.permalink)
   restful.send_successful_response(self, "/")
Ejemplo n.º 8
0
Archivo: blog.py Proyecto: m4dc4p/bloog
 def delete_entity(query):
     targets = query.fetch(limit=1)
     if len(targets) > 0:
         permalink = targets[0].permalink
         logging.debug('Deleting %s %s', model_class, permalink)
         targets[0].delete()
         self.response.out.write('Deleted ' + permalink)
         view.invalidate_cache()
     else:
         self.error(404)
Ejemplo n.º 9
0
 def delete(self, category, year, month, perm_stem):
     permalink = '/'.join((category, year, month, perm_stem))
     logging.debug("Deleting %s entry %s" % (category, permalink))
     article = db.Query(models.blog.Article). \
             filter('permalink =', permalink).get()
     for key in article.tag_keys:
         db.get(key).counter.decrement()
     article.delete()
     view.invalidate_cache()
     restful.send_successful_response(self, "/")
Ejemplo n.º 10
0
Archivo: blog.py Proyecto: mloar/bloog
 def delete(self, year, month, perm_stem):
     permalink = 'blog/' + year + '/' + month + '/' + day + '/' + perm_stem
     logging.debug("Deleting blog entry %s", permalink)
     article = db.Query(models.blog.Article). \
                  filter('permalink =', permalink).get()
     for key in article.tag_keys:
         db.get(key).counter.decrement()
     article.delete()
     view.invalidate_cache()
     restful.send_successful_response(self, "/")
Ejemplo n.º 11
0
 def delete(self, year, month, perm_stem):
     permalink = year + '/' + month + '/' + perm_stem
     logging.debug("Deleting blog entry %s", permalink)
     article = db.Query(models.blog.Article). \
                  filter('permalink =', permalink).get()
     for key in article.tag_keys:
         db.get(key).counter.decrement()
     article.delete()
     view.invalidate_cache()
     restful.send_successful_response(self, "/")
Ejemplo n.º 12
0
Archivo: blog.py Proyecto: JamieS/bloog
    def delete(self, path):
        logging.debug("Deleting article %s", path)
        if path=='article': # hack to pick out the 'top' article for bulk delete
          return delete_entity(self, models.blog.Article.all())

        article = db.Query(models.blog.Article).filter('permalink =', path).get()
        if not article: return self.error(404)

        for key in article.tag_keys: db.get(key).counter.decrement()
        article.delete()
        view.invalidate_cache()
        restful.send_successful_response(self, "/")
Ejemplo n.º 13
0
Archivo: blog.py Proyecto: JamieS/bloog
def delete_entity(handler, query):
    target = query.get()
    if not target:
        return handler.response.set_status(204, 'No more entities')

    if hasattr(target, 'title'): title = target.title
    elif hasattr(target, 'name'): title = target.name
    else: title = ''
    logging.debug('Deleting %s', title)
    target.delete()
    handler.response.out.write('Deleted %s' % title)
    view.invalidate_cache()
    restful.send_successful_response(handler, "/")
Ejemplo n.º 14
0
def delete_entity(handler, query):
    target = query.get()
    if not target:
        return handler.response.set_status(204, 'No more entities')

    if hasattr(target, 'title'): title = target.title
    elif hasattr(target, 'name'): title = target.name
    else: title = ''
    logging.debug('Deleting %s', title)
    target.delete()
    handler.response.out.write('Deleted %s' % title)
    view.invalidate_cache()
    restful.send_successful_response(handler, "/")
Ejemplo n.º 15
0
  def delete(self, path):
    """
    By using DELETE on /Article, /Comment, /Tag, you can delete the first
     entity of the desired kind.
    This is useful for writing utilities like clear_datastore.py.
    """
    # TODO: Add DELETE for articles off root like blog entry DELETE.
    model_class = path.lower()
    aio.debug("blog.ArticleHandler#delete on %s", path)

    def delete_entity(query):
      targets = query.fetch(limit = 1)
      if len(targets) > 0:
        if hasattr(targets[0], 'title'):
          title = targets[0].title
        elif hasattr(targets[0], 'name'):
          title = targets[0].name
        else:
          title = ''
        aio.debug('Deleting %s %s', model_class, title)
        targets[0].delete()
        self.response.out.write('Deleted ' + model_class + ' ' + title)
        view.invalidate_cache(path)
      else:
        self.response.set_status(204, 'No more ' + model_class + ' entities')

    if model_class == 'article':
      query = models.blog.Article.all()
      delete_entity(query)
    elif model_class == 'comment':
      query = models.blog.Comment.all()
      delete_entity(query)
    elif model_class == 'tag':
      query = models.blog.Tag.all()
      delete_entity(query)
    else:
      article = db.Query(models.blog.Article). \
             filter('permalink =', path).get()
      for key in article.tag_keys:
        tag = db.get(key)
        logging.debug("Decrementing tag %s with initial value %d", tag.name, tag.counter.count)
        tag.counter.decrement()
        if tag.counter.count == 0:
          logging.debug("Tag %s has count 0, removing tag", tag.name)
          tag.delete_counter()
          tag.delete()
      for comment in article.comments:
        comment.delete()
      article.delete()
      view.invalidate_cache(path)
      restful.send_successful_response(self, "/")
Ejemplo n.º 16
0
  def put(self, comment_id):
    logging.debug("CommentHandler#put for comment %s", comment_id)
    # For HTTP PUT, the parameters are passed in URIencoded string in body
    sanitize_comment = get_sanitizer_func(self,
      allow_attributes = ['href', 'src'],
      blacklist_tags = ['img', 'script'])
    body = self.request.body
    params = cgi.parse_qs(body)
    for key, value in params.iteritems():
      params[key] = value[0]
      if not isinstance(params[key], unicode):
        params[key] = params[key].decode(config.APP['charset'])

    tmp_hash = restful.get_sent_properties(self.request.get,
      [('commentEmail', cgi.escape),
      ('commentHomepage', cgi.escape),
      ('commentTitle', cgi.escape),
      ('commentName', cgi.escape),
      ('commentBody', sanitize_comment)])
    property_hash = {}
    props = (("commentEmail", "email"), ("commentHomepage", "homepage"),
        ("commentTitle", "title"), ("commentBody", "body"),
        ('commentName', 'name'))
    for pair in props:
      if pair[0] in tmp_hash:
        logging.debug("Copying '%s' from received properties to '%s' in property hash (value: %s)", pair[0], pair[1], str(tmp_hash[pair[0]]))
        property_hash[pair[1]] = tmp_hash[pair[0]]
    if property_hash:
      comment = models.blog.Comment.get(db.Key(comment_id))
      for key, value in property_hash.iteritems():
        setattr(comment, key, value)
      comment.put()

      # Render just this comment and send it to client
      view_path = view.find_file(view.templates, "gablog/blog/comment.html")
      allow_comments = comment.article.allow_comments
      if allow_comments is None:
        age = (datetime.datetime.now() - comment.article.published).days
        allow_comments = (age <= config.BLOG['comment_window'])

      # response = template.render(os.path.join(config.APP['template_dir'], view_path),
      response = render_to_string(os.path.join(config.APP['template_dir'], view_path),
        { 'comment': comment, "use_gravatars": config.BLOG["use_gravatars"],
          "allow_comments": allow_comments, "user_is_admin":
          users.is_current_user_admin()},
        debug = config.DEBUG)
      self.response.out.write(response)
      view.invalidate_cache(comment.article.permalink)
    else:
      self.error(400)
Ejemplo n.º 17
0
    def delete(self, path):
        logging.debug("Deleting article %s", path)
        if path == 'article':  # hack to pick out the 'top' article for bulk delete
            return delete_entity(self, models.blog.Article.all())

        article = db.Query(models.blog.Article).filter('permalink =',
                                                       path).get()
        if not article: return self.error(404)

        for key in article.tag_keys:
            db.get(key).counter.decrement()
        article.delete()
        view.invalidate_cache()
        restful.send_successful_response(self, "/")
Ejemplo n.º 18
0
Archivo: blog.py Proyecto: mloar/bloog
 def delete_entity(query):
     targets = query.fetch(limit=1)
     if len(targets) > 0:
         if hasattr(targets[0], 'title'):
             title = targets[0].title
         elif hasattr(targets[0], 'name'):
             title = targets[0].name
         else:
             title = ''
         logging.debug('Deleting %s %s', model_class, title)
         targets[0].delete()
         self.response.out.write('Deleted ' + model_class + ' ' + title)
         view.invalidate_cache()
     else:
         self.response.set_status(204, 'No more ' + model_class + ' entities')
Ejemplo n.º 19
0
    def delete(self, comment_id):
        if not comment_id:
            return delete_entity(self, models.blog.Comment.all())
        logging.debug("Deleting comment %s", comment_id)
        comment = models.blog.Comment.get(db.Key(comment_id))

        if not comment: return self.error(404)

        article = comment.article
        comment.delete()
        # TODO replace with counter?
        article.num_comments -= 1  # decrement comment count
        article.put()
        view.invalidate_cache(comment.article.permalink)
        restful.send_successful_response(self, "/")
Ejemplo n.º 20
0
Archivo: blog.py Proyecto: JamieS/bloog
 def delete(self,comment_id):
     if not comment_id:
         return delete_entity( self, models.blog.Comment.all() )
     logging.debug("Deleting comment %s", comment_id)
     comment = models.blog.Comment.get(db.Key(comment_id))
     
     if not comment: return self.error(404)
     
     article = comment.article
     comment.delete()
     # TODO replace with counter?
     article.num_comments -=1 # decrement comment count
     article.put()
     view.invalidate_cache(comment.article.permalink)
     restful.send_successful_response(self, "/")
Ejemplo n.º 21
0
 def delete_entity(query):
     targets = query.fetch(limit=1)
     if len(targets) > 0:
         if hasattr(targets[0], 'title'):
             title = targets[0].title
         elif hasattr(targets[0], 'name'):
             title = targets[0].name
         else:
             title = ''
         logging.debug('Deleting %s %s', model_class, title)
         targets[0].delete()
         self.response.out.write('Deleted ' + model_class + ' ' + title)
         view.invalidate_cache()
     else:
         self.response.set_status(
             204, 'No more ' + model_class + ' entities')
Ejemplo n.º 22
0
Archivo: blog.py Proyecto: m4dc4p/bloog
def process_article_edit(handler, permalink):
    # For http PUT, the parameters are passed in URIencoded string in body
    body = handler.request.body
    params = cgi.parse_qs(body)
    logging.debug(params)

    article = db.Query(model.Article).filter('permalink =', permalink).get()
    if 'title' in params:
        article.title = params['title'][0]
    if 'tags' in params:
        article.tags = get_tags(params['tags'][0])
    article.body = params['body'][0]
    article.html = params['body'][0]
    article.updated = get_datetime()
    article.put()
    restful.send_successful_response(handler, '/' + article.permalink)
    view.invalidate_cache()
Ejemplo n.º 23
0
    def delete(self, path):
        """
        By using DELETE on /Article, /Comment, /Tag, you can delete the first 
         entity of the desired kind.
        This is useful for writing utilities like clear_datastore.py.  
        """
        # TODO: Add DELETE for articles off root like blog entry DELETE.
        model_class = path.lower()
        logging.debug("ArticleHandler#delete on %s", path)

        def delete_entity(query):
            targets = query.fetch(limit=1)
            if len(targets) > 0:
                if hasattr(targets[0], 'title'):
                    title = targets[0].title
                elif hasattr(targets[0], 'name'):
                    title = targets[0].name
                else:
                    title = ''
                logging.debug('Deleting %s %s', model_class, title)
                targets[0].delete()
                self.response.out.write('Deleted ' + model_class + ' ' + title)
                view.invalidate_cache()
            else:
                self.response.set_status(
                    204, 'No more ' + model_class + ' entities')

        if model_class == 'article':
            query = models.blog.Article.all()
            delete_entity(query)
        elif model_class == 'comment':
            query = models.blog.Comment.all()
            delete_entity(query)
        elif model_class == 'tag':
            query = models.blog.Tag.all()
            delete_entity(query)
        else:
            article = db.Query(models.blog.Article). \
                         filter('permalink =', path).get()
            for key in article.tag_keys:
                db.get(key).counter.decrement()
            article.delete()
            view.invalidate_cache()
            restful.send_successful_response(self, "/")
Ejemplo n.º 24
0
  def delete(self, year, month, permalink):

    perm_stem = [t for t in permalink.split("/") if len(t)][-1]
    permalink = year + '/' + month + '/' + perm_stem
    aio.debug("BlogEntryHandler. delete Deleting blog entry %s", permalink)

    article = db.Query(models.blog.Article).filter('permalink =', permalink).get()
    for key in article.tag_keys:
      tag = db.get(key)
      aio.debug("BlogEntryHandler.delete: Decrementing tag '%s' with current count %d", tag.name, tag.counter.count)
      tag.counter.decrement()
      if tag.counter.count == 0:
        aio.debug("Tag '%s' has count 0, removing tag", tag.name)
        tag.delete_counter()
        tag.delete()

    article.delete()
    view.invalidate_cache(perm_stem)
    
    restful.send_successful_response(self, "/")
Ejemplo n.º 25
0
Archivo: blog.py Proyecto: m4dc4p/bloog
def process_comment_submission(handler, article):
    if not article:
        handler.error(404)
        return

    # Get and store some pieces of information from parent article.
    # TODO: See if this overhead can be avoided
    if not article.num_comments:
        article.num_comments = 1
    else:
        article.num_comments += 1
    article_key = article.put()

    property_hash = restful.get_hash_from_request(handler.request, 
        ['name',
         'email',
         'title',
         'body',
         'thread',
         ('published', get_datetime)])

    # Compute a comment key by hashing name, email, and body.  
    # If these aren't different, don't bother adding comment.
    comment_key = str(
        hash((property_hash['name'], 
              property_hash['email'], 
              property_hash['body'])))

    comment = model.Comment(
        permalink = comment_key,
        body = property_hash['body'],
        article = article_key,
        thread = property_hash['thread'])
    fill_optional_properties(comment, property_hash)
    comment.put()
    restful.send_successful_response(handler, '/' + comment.permalink)
    view.invalidate_cache()
Ejemplo n.º 26
0
Archivo: blog.py Proyecto: mloar/bloog
def process_comment_submission(handler, article):
    sanitize_comment = get_sanitizer_func(handler,
                                          allow_attributes=['href', 'src'],
                                          blacklist_tags=['img'])
    property_hash = restful.get_sent_properties(handler.request.get, 
        ['name',
         'email',
         'homepage',
         'title',
         ('body', sanitize_comment),
         'key',
         'thread',    # If it's given, use it.  Else generate it.
         'captcha',
         ('published', get_datetime)])

    # If we aren't administrator, abort if bad captcha
    if not users.is_current_user_admin():
        if property_hash.get('captcha', None) != get_captcha(article.key()):
            logging.info("Received captcha (%s) != %s", 
                          property_hash.get('captcha', None),
                          get_captcha(article.key()))
            handler.error(401)      # Unauthorized
            return
    if 'key' not in property_hash and 'thread' not in property_hash:
        handler.error(401)
        return

    # Generate a thread string.
    if 'thread' not in property_hash:
        matchobj = re.match(r'[^#]+#comment-(?P<key>\w+)', 
                            property_hash['key'])
        if matchobj:
            logging.debug("Comment has parent: %s", matchobj.group('key'))
            comment_key = matchobj.group('key')
            # TODO -- Think about GQL injection security issue since 
            # it can be submitted by public
            parent = models.blog.Comment.get(db.Key(comment_key))
            thread_string = parent.next_child_thread_string()
        else:
            logging.debug("Comment is off main article")
            comment_key = None
            thread_string = article.next_comment_thread_string()
        if not thread_string:
            handler.error(400)
            return
        property_hash['thread'] = thread_string
        del property_hash['key']

    # Get and store some pieces of information from parent article.
    # TODO: See if this overhead can be avoided
    if not article.num_comments:
        article.num_comments = 1
    else:
        article.num_comments += 1
    property_hash['article'] = article.put()

    try:
        comment = models.blog.Comment(**property_hash)
        comment.put()
    except:
        logging.debug("Bad comment: %s", property_hash)
        handler.error(400)
        return
        
    # Notify the author of a new comment (from matteocrippa.it)
    if config.BLOG['send_comment_notification']:
        recipient = "%s <%s>" % (config.BLOG['author'], config.BLOG['email'],)
        body = ("A new comment has just been posted on %s/%s by %s."
                % (config.BLOG['root_url'], article.permalink, comment.name))
        mail.send_mail(sender=config.BLOG['email'],
                       to=recipient,
                       subject="New comment by %s" % (comment.name,),
                       body=body)

    # Render just this comment and send it to client
    view_path = view.find_file(view.templates, "bloog/blog/comment.html")
    response = template.render(
        os.path.join("views", view_path),
        { 'comment': comment, "use_gravatars": config.BLOG["use_gravatars"] },
        debug=config.DEBUG)
    handler.response.out.write(response)
    view.invalidate_cache()
Ejemplo n.º 27
0
def process_comment_submission(handler, parent=None):
    sanitize_comment = get_sanitizer_func(handler,
                                          allow_attributes=['href', 'src'],
                                          blacklist_tags=['img', 'script'])
    property_hash = restful.get_sent_properties(
        handler.request.get,
        [('name', cgi.escape), ('email', cgi.escape), ('homepage', cgi.escape),
         ('title', cgi.escape), ('body', sanitize_comment),
         ('article_id', cgi.escape), 'recaptcha_challenge_field',
         'recaptcha_response_field', ('published', get_datetime)])

    # If we aren't administrator, abort if bad captcha
    if not users.is_current_user_admin():
        cap_challenge = property_hash.get('recaptcha_challenge_field')
        cap_response = property_hash.get('recaptcha_response_field')

        cap_validation = captcha.RecaptchaResponse(False)
        if cap_challenge and cap_response:
            cap_validation = captcha.submit(cap_challenge, cap_response,
                                            config.BLOG['recap_private_key'],
                                            handler.request.remote_addr)

        if not cap_validation.is_valid:
            logging.info("Invalid captcha: %s", cap_validation.error_code)
            handler.response.set_status(401, 'Invalid Captcha')  # Unauthorized
            return

    if 'article_id' not in property_hash:
        return handler.error(400)

    article = db.Query(models.blog.Article).filter(
        'permalink =', property_hash['article_id']).get()

    # Generate a thread string.
    if parent:
        logging.debug("Comment has parent: %s", parent.key())
        thread_string = parent.next_child_thread_string()
    else:
        logging.debug("Comment is off main article")
        thread_string = article.next_comment_thread_string()

    property_hash['thread'] = thread_string

    # Get and store some pieces of information from parent article.
    # TODO: See if this overhead can be avoided
    if not article.num_comments: article.num_comments = 1
    else: article.num_comments += 1
    property_hash['article'] = article.put()

    try:
        comment = models.blog.Comment(**property_hash)
        comment.put()
    except:
        logging.debug("Bad comment: %s", property_hash)
        return handler.error(400)

    # Notify the author of a new comment (from matteocrippa.it)
    if config.BLOG[
            'send_comment_notification'] and not users.is_current_user_admin():
        recipient = "%s <%s>" % (config.BLOG['author'], config.BLOG['email'])
        article_link = config.BLOG['root_url'] + "/" + article.permalink
        comment_link = '%s#comment-%s' % (article_link, comment.key())
        body = ('''A new comment has just been posted on %s by %s:\n\n"%s"
                \n\nReply to the comment here: %s''' %
                (article_link, comment.name, comment.body, comment_link))
        mail.send_mail(sender=config.BLOG['email'],
                       to=recipient,
                       subject="New comment by %s" % (comment.name),
                       body=body)

    # Render just this comment and send it to client
    view_path = view.find_file(view.templates, "bloog/blog/comment.html")
    response = template.render(os.path.join("views", view_path), {
        'comment': comment,
        "use_gravatars": config.BLOG["use_gravatars"]
    },
                               debug=config.DEBUG)
    handler.response.out.write(response)
    view.invalidate_cache(comment.article.permalink)
Ejemplo n.º 28
0
Archivo: blog.py Proyecto: JamieS/bloog
def process_comment_submission(handler, parent=None):
    sanitize_comment = get_sanitizer_func(handler,
                                          allow_attributes=['href', 'src'],
                                          blacklist_tags=['img', 'script'])
    property_hash = restful.get_sent_properties(handler.request.get, 
        [('name', cgi.escape),
         ('email', cgi.escape),
         ('homepage', cgi.escape),
         ('title', cgi.escape),
         ('body', sanitize_comment),
         ('article_id', cgi.escape),
         'recaptcha_challenge_field',
         'recaptcha_response_field',
         ('published', get_datetime)])

    # If we aren't administrator, abort if bad captcha
    if not users.is_current_user_admin():
        cap_challenge = property_hash.get('recaptcha_challenge_field')
        cap_response = property_hash.get('recaptcha_response_field')
        
        cap_validation = captcha.RecaptchaResponse(False)
        if cap_challenge and cap_response:
          cap_validation = captcha.submit( cap_challenge, cap_response, 
            config.BLOG['recap_private_key'], handler.request.remote_addr )
        
        if not cap_validation.is_valid: 
          logging.info( "Invalid captcha: %s", cap_validation.error_code )
          handler.response.set_status(401, 'Invalid Captcha') # Unauthorized
          return
          
    if 'article_id' not in property_hash:
        return handler.error(400)
        
    article = db.Query(models.blog.Article).filter(
        'permalink =', property_hash['article_id'] ).get()

    # Generate a thread string.
    if parent:
        logging.debug("Comment has parent: %s", parent.key())
        thread_string = parent.next_child_thread_string()
    else:
        logging.debug("Comment is off main article")
        thread_string = article.next_comment_thread_string()
        
    property_hash['thread'] = thread_string

    # Get and store some pieces of information from parent article.
    # TODO: See if this overhead can be avoided
    if not article.num_comments: article.num_comments = 1
    else: article.num_comments += 1
    property_hash['article'] = article.put()

    try:
        comment = models.blog.Comment(**property_hash)
        comment.put()
    except:
        logging.debug("Bad comment: %s", property_hash)
        return handler.error(400)
        
    # Notify the author of a new comment (from matteocrippa.it)
    if config.BLOG['send_comment_notification'] and not users.is_current_user_admin():
        recipient = "%s <%s>" % (config.BLOG['author'], config.BLOG['email'])
        article_link = config.BLOG['root_url'] + "/" + article.permalink
        comment_link = '%s#comment-%s' % (article_link, comment.key())
        body = ('''A new comment has just been posted on %s by %s:\n\n"%s"
                \n\nReply to the comment here: %s'''
                % (article_link, comment.name, comment.body, comment_link))
        mail.send_mail(sender=config.BLOG['email'],
                       to=recipient,
                       subject="New comment by %s" % (comment.name),
                       body=body)

    # Render just this comment and send it to client
    view_path = view.find_file(view.templates, "bloog/blog/comment.html")
    response = template.render(
        os.path.join("views", view_path),
        { 'comment': comment, "use_gravatars": config.BLOG["use_gravatars"] },
        debug=config.DEBUG)
    handler.response.out.write(response)
    view.invalidate_cache(comment.article.permalink)
Ejemplo n.º 29
0
def process_comment_submission(handler, article):
    sanitize_comment = get_sanitizer_func(handler,
                                          allow_attributes=['href', 'src'],
                                          blacklist_tags=['img', 'script'])
    property_hash = restful.get_sent_properties(
        handler.request.get,
        [
            ('name', cgi.escape),
            ('email', cgi.escape),
            ('homepage', cgi.escape),
            ('title', cgi.escape),
            ('body', sanitize_comment),
            ('key', cgi.escape),
            'thread',  # If it's given, use it.  Else generate it.
            'captcha',
            ('published', get_datetime)
        ])

    # If we aren't administrator, abort if bad captcha
    if not users.is_current_user_admin():
        if property_hash.get('captcha', None) != get_captcha(article.key()):
            logging.info("Received captcha (%s) != %s",
                         property_hash.get('captcha', None),
                         get_captcha(article.key()))
            handler.error(401)  # Unauthorized
            return
    if 'key' not in property_hash and 'thread' not in property_hash:
        handler.error(401)
        return

    # Generate a thread string.
    if 'thread' not in property_hash:
        matchobj = re.match(r'[^#]+#comment-(?P<key>\w+)',
                            property_hash['key'])
        if matchobj:
            logging.debug("Comment has parent: %s", matchobj.group('key'))
            comment_key = matchobj.group('key')
            # TODO -- Think about GQL injection security issue since
            # it can be submitted by public
            parent = models.blog.Comment.get(db.Key(comment_key))
            thread_string = parent.next_child_thread_string()
        else:
            logging.debug("Comment is off main article")
            comment_key = None
            thread_string = article.next_comment_thread_string()
        if not thread_string:
            handler.error(400)
            return
        property_hash['thread'] = thread_string
        del property_hash['key']

    # Get and store some pieces of information from parent article.
    # TODO: See if this overhead can be avoided
    if not article.num_comments:
        article.num_comments = 1
    else:
        article.num_comments += 1
    property_hash['article'] = article.put()

    try:
        comment = models.blog.Comment(**property_hash)
        comment.put()
    except:
        logging.debug("Bad comment: %s", property_hash)
        handler.error(400)
        return

    # Notify the author of a new comment (from matteocrippa.it)
    if config.BLOG['send_comment_notification']:
        recipient = "%s <%s>" % (
            config.BLOG['author'],
            config.BLOG['email'],
        )
        body = ("A new comment has just been posted on %s/%s by %s." %
                (config.BLOG['root_url'], article.permalink, comment.name))
        mail.send_mail(sender=config.BLOG['email'],
                       to=recipient,
                       subject="New comment by %s" % (comment.name, ),
                       body=body)

    # Render just this comment and send it to client
    view_path = view.find_file(view.templates, "bloog/blog/comment.html")
    response = template.render(os.path.join("views", view_path), {
        'comment': comment,
        "use_gravatars": config.BLOG["use_gravatars"]
    },
                               debug=config.DEBUG)
    handler.response.out.write(response)
    view.invalidate_cache()
Ejemplo n.º 30
0
def process_article_submission(handler, article_type):
  """
  takes care of permalink
  """

  aio.debug("blog.process_article_submission article_type: %s", article_type)

  tmp_hash = restful.get_sent_properties(handler.request.get, [
    ('postTitle',     get_sanitizer_func(handler, trusted_source = True)),
    ('postBody',      get_sanitizer_func(handler, trusted_source = True)),
    ('postFormat',    get_format),
    ('postType',      get_type),
    ('postUpdated',   get_datetime),
    ('postTags',      get_tags),
    ('html',          get_html, 'postBody', 'postFormat'),
    ('permalink',     permalink_funcs[article_type], 'postTitle', 'postPublished'),
    'postExcerpt',
    'postThumb'
  ])

  property_hash = {}
  props = (
    ("key",           "key"), 
    ("postTitle",     "title"), 
    ("postBody",      "body"),
    ("postExcerpt",   "excerpt"),
    ("postThumb",     "thumb"),
    ("postFormat",    "format"),
    ("postType",      "article_type"), 
    ("postPublished", "published"), 
    ("postUpdated",   "updated"), 
    ("article_id",    "article_id"),
    ("permalink",     "permalink"), 
    ("html",          "html"), 
    ("postTags",      "tags"),
  )

  for pair in props:
    if pair[0] in tmp_hash:
      property_hash[pair[1]] = tmp_hash[pair[0]]

  if property_hash:

    if 'tags' in property_hash:
      property_hash['tag_keys'] = [get_tag_key(name) for name in property_hash['tags']]

    # property_hash['format']       = 'html'   # For now, convert all to HTML
    # property_hash['article_type'] = article_type

    article = models.blog.Article(**property_hash)
    article.set_associated_data({'relevant_links': handler.request.get('relevant_links'), })
    process_embedded_code(article)

    article.put()
    time.sleep(1)

    # Ensure there is a year entity for this entry's year
    if article.published :
      models.blog.Year.get_or_insert('Y%d' % (article.published.year, ))

    # Update tags
    for key in article.tag_keys:
      db.get(key).counter.increment()

    aio.debug("blog.process_article_submission perm: %s, key: %s", article.permalink, article.key())

    # restful.send_successful_response(handler, '/' + article.permalink)

    restful.send_successful_response(handler, '/post/edit/' + str(article.key()))

    view.invalidate_cache(article.permalink)

  else:
    aio.debug("blog.process_article_submission no property_hash")
    handler.error(400)
Ejemplo n.º 31
0
def process_article_edit(handler, postlink):
  # For HTTP PUT, the parameters are passed in URIencoded string in body

  body = handler.request.body
  params = cgi.parse_qs(body)

  for key, value in params.iteritems():
    params[key] = value[0]
    if not isinstance(params[key], unicode):
      params[key] = params[key].decode(config.APP['charset'])


  aio.debug("blog.process_article_edit: params.keys: %s", params.keys())

  # article_type = restful.get_sent_properties(params.get, [('postType', get_type)])['postType']
  article_type = params['postType']

  aio.debug("blog.process_article_edit article with postlink: %s, type: %s/%s", postlink, article_type, params['postFormat'])

  tmp_hash = restful.get_sent_properties(params.get, [
    ('postTitle',     cgi.escape),
    ('postBody',      get_sanitizer_func(handler, trusted_source = True)),
    ('postFormat',    get_format),     ## markdown, html, text
    ('postType',      get_type),       ## draft, post, article
    ('postTags',      get_tags),
    ('html',          get_html, 'postBody', 'postFormat'),

    ('postPublished',   get_datetime, 'postPublished'),

    ('permalink',     permalink_funcs[article_type], 'postTitle', 'postPublished'),
    'postThumb',
    # 'postPublished',
  ])

  # aio.debug("blog.process_article_edit tmp_hash: %s", tmp_hash)

  property_hash = {}
  props = (
    ("postTitle",     "title"), 
    ("postBody",      "body"),
    ("postFormat",    "format"),
    ("postPublished", "published"), 
    ("postThumb",     "thumb"),
    ("legacy_id",     "legacy_id"), 
    ("article_id",    "article_id"), 
    ("postType",      "article_type"), 
    ("postTags",      "tags"),
    ("html",          "html"), 
    ("postPerma",     "permalink")
  )
  for pair in props :
    # aio.debug("PAIR: %s", pair)
    if pair is not None:
      if pair[0] in tmp_hash :
        # logging.info("COPY  PAIR %s", pair)
        property_hash[pair[1]] = tmp_hash[pair[0]]
      else : 
        pass
        # aio.debug("IGNORE %s from sent properties to %s in property hash", pair[0], pair[1])
    else :
      aio.debug("ERROR '%s' with pair", pair)


  if property_hash:
    if 'tags' in property_hash:
      property_hash['tag_keys'] = [get_tag_key(name) for name in property_hash['tags'] if name != ""]

    aio.debug("blog.process_article_edit search article by postlink: %s", postlink)


    ## adjust dates
    property_hash['updated'] = datetime.datetime.utcnow()

    if property_hash['article_type'] == 'draft' : 
      property_hash['published'] = None
    else :
      # property_hash['published'] = get_datetime(property_hash['published'])
      property_hash['published'] = property_hash['published']

    aio.debug("blog.process_article_edit pub: %s: upd: %s", property_hash['published'], property_hash['updated'])


    article = db.Query(models.blog.Article).filter('permalink =', postlink).get()
    before_tags = set(article.tag_keys)

    for key, value in property_hash.iteritems():
      # aio.debug("blog.process_article_edit: SAVE: " + key + " > " + aio.asciify(value)[:10]) ## utf errors
      setattr(article, key, value)

    after_tags = set(article.tag_keys)

    for removed_tag in before_tags - after_tags:
      tag = db.get(removed_tag)
      logging.debug("Decrementing tag '%s' with initial value %d", tag.name, tag.counter.count)
      tag.counter.decrement()
      if tag.counter.count == 0:
        logging.debug("Tag %s has count 0, removing tag", tag.name)
        tag.delete_counter()
        tag.delete()

    for added_tag in after_tags - before_tags:
      db.get(added_tag).counter.increment()

    process_embedded_code(article)
    article.put()

    # restful.send_successful_response(handler, '/' + article.permalink)
    restful.send_successful_response(handler, '/post/edit/' + str(article.key()))
    view.invalidate_cache(article.permalink)

  else:
    handler.error(400)