Esempio n. 1
0
    def post(self, author_slug):

        blog = self.blog
        author = None
        if author_slug:
            author = model.BlogAuthor.get_by_id(author_slug, parent=blog.key)
            if not author:
                return self.renderError(404)

        form_data, errors, valid_data = self.validate()

        if errors:
            return self.redisplay(
                form_data, errors,
                self.blog_url + '/admin/author/' + author_slug)

        name = valid_data["name"]
        slug = model.makeSlug(name, blog, model.BlogAuthor, author)
        if author:
            # if the name is different, remake the entity since the key name needs to change
            if name != author.name:
                # get lists of other entities to update (must be outside of transaction since they're a non-ancestor query)
                posts = list(author.posts)
                comments = list(author.comments)

                # update all the posts and comments referencing the author at the same time that a new author object is created
                def author_transaction(author, slug, blog, ref_lists):
                    # re-create the author object
                    author = model.makeNew(
                        author,
                        id=slug,
                        parent=blog.key,
                        use_transaction=False)  # no nested transactions
                    # update the others to reference the new object
                    for ref_list in ref_lists:
                        new_objects = []
                        for ref_object in ref_list:
                            ref_object.author = author
                            new_objects.append(ref_object)
                        model.db.put(new_objects)
                    return author

                author = model.db.run_in_transaction(author_transaction,
                                                     author, slug, blog,
                                                     [posts, comments])
            author.populate(**valid_data)
        else:
            author = model.BlogAuthor(id=slug, parent=blog.key, **valid_data)

        author.put()

        memcache.delete_multi(getCacheKeys(blog))

        if blog.authors.count() > 1:
            self.redirect(self.blog_url + '/admin/authors')

        else:
            self.redirect(self.blog_url + '/admin')
Esempio n. 2
0
    def post(self, author_slug):

        blog = self.blog
        author = None
        if author_slug:
            author = model.BlogAuthor.get_by_id(author_slug, parent=blog.key)
            if not author:
                return self.renderError(404)

        form_data, errors, valid_data = self.validate()

        if errors:
            return self.redisplay(form_data, errors, self.blog_url + '/admin/author/' + author_slug)

        name = valid_data["name"]
        slug = model.makeSlug(name, blog, model.BlogAuthor, author)
        if author:
            # if the name is different, remake the entity since the key name needs to change
            if name != author.name:
                # get lists of other entities to update (must be outside of transaction since they're a non-ancestor query)
                posts = list(author.posts)
                comments = list(author.comments)
                # update all the posts and comments referencing the author at the same time that a new author object is created
                def author_transaction(author, slug, blog, ref_lists):
                    # re-create the author object
                    author = model.makeNew(author, id=slug, parent=blog.key, use_transaction=False) # no nested transactions
                    # update the others to reference the new object
                    for ref_list in ref_lists:
                        new_objects = []
                        for ref_object in ref_list:
                            ref_object.author = author
                            new_objects.append(ref_object)
                        model.db.put(new_objects)
                    return author
                author = model.db.run_in_transaction(author_transaction, author, slug, blog, [posts, comments])
            author.populate(**valid_data)
        else:
            author = model.BlogAuthor(id=slug, parent=blog.key, **valid_data)

        author.put()
        
        memcache.delete_multi(getCacheKeys(blog))

        if blog.authors.count() > 1:
            self.redirect(self.blog_url + '/admin/authors')

        else:
            self.redirect(self.blog_url + '/admin')
Esempio n. 3
0
    def post(self, post_slug):

        blog = self.blog
        post = None
        if post_slug:
            post = model.BlogPost.get_by_id(post_slug, parent=blog.key)
            if not post:
                return self.renderError(404)

        form_data, errors, valid_data = self.validate()

        if "slug_choice" not in errors and "slug" not in errors:
            slug_choice = valid_data["slug_choice"]
            if slug_choice == "custom":
                slug = valid_data["slug"]
                if slug and "/" not in slug:
                    # check to make sure that there isn't already another post with this slug
                    existing = model.BlogPost.get_by_id(slug, parent=blog.key)
                    if existing and (not post or existing.key != post.key):
                        errors["slug_exists"] = True
                else:
                    errors["slug"] = True

        if "author" not in errors:
            author = model.BlogAuthor.get_by_id(valid_data["author"],
                                                parent=blog.key)
            if author:
                valid_data["author"] = author.key
            else:
                errors["author"] = True

        now = datetime.utcnow()
        if "timestamp_choice" not in errors:
            if valid_data["timestamp_choice"] == "now":
                valid_data["timestamp"] = now
            elif not valid_data.get("timestamp"):
                errors["timestamp"] = True

        if errors:
            return self.redisplay(form_data, errors,
                                  self.blog_url + '/admin/post/' + post_slug)

        if slug_choice == "auto":
            slug = model.makeSlug(valid_data["title"], blog, model.BlogPost,
                                  post)

        # turn tag strings into keys
        tag_keys = []
        if valid_data["tags"]:
            new_tags = []
            for tag_string in valid_data["tags"].split(","):
                tag_string = tag_string.strip()
                if tag_string:
                    tag_slug = model.slugify(tag_string)
                    tag = model.BlogTag.get_by_id(tag_slug, parent=blog.key)
                    if tag:
                        tag_keys.append(tag.key)
                    else:
                        tag_slug = model.makeSlug(tag_string, blog,
                                                  model.BlogTag)
                        tag = model.BlogTag(id=tag_slug,
                                            name=tag_string,
                                            parent=blog.key)
                        new_tags.append(tag)
            if new_tags:
                ndb.put_multi(new_tags)
                tag_keys.extend([tag.key for tag in new_tags])
        valid_data["tag_keys"] = tag_keys

        # don't want to attach these temporary choices to the model
        del valid_data["slug"]
        del valid_data["slug_choice"]
        del valid_data["tags"]
        del valid_data["timestamp_choice"]

        was_published = False
        if post:
            was_published = post.published

            # if the slug is different, remake the entities since the key name needs to change
            if slug != post.slug:
                post = model.makeNew(post, id=slug, parent=blog.key)
            post.populate(**valid_data)
        else:
            post = model.BlogPost(id=slug, parent=blog.key, **valid_data)

        post.put()

        # send them back to the admin list of posts if it's not published or to the actual post if it is
        if post.published:
            cache_keys = getCacheKeys(blog)
            memcache.delete_multi(cache_keys)
            datastore_keys = getDatastoreKeys(blog)
            if post.timestamp > now:
                # post is in the future, so set the expires on these to just after it's available
                html_caches = ndb.get_multi(datastore_keys, use_memcache=False)
                new_html_caches = []
                diff = int((post.timestamp - now).total_seconds())
                for html_cache in html_caches:
                    if html_cache:
                        html_cache.expires = diff
                        new_html_caches.append(html_cache)
                if new_html_caches:
                    ndb.put_multi(new_html_caches)
            else:
                # post is published in the past so just delete everything
                ndb.delete_multi(datastore_keys)
            self.redirect(self.blog_url + '/post/' + post.slug)
        else:
            if was_published:
                clearCache(blog)

            if self.request.get("preview"):
                self.redirect(self.blog_url + '/admin/preview/' + post.slug)
            else:
                self.redirect(self.blog_url + '/admin/posts')
Esempio n. 4
0
    def post(self, post_slug):

        blog = self.blog
        post = None
        if post_slug:
            post = model.BlogPost.get_by_id(post_slug, parent=blog.key)
            if not post:
                return self.renderError(404)

        form_data, errors, valid_data = self.validate()

        if "slug_choice" not in errors and "slug" not in errors:
            slug_choice = valid_data["slug_choice"]
            if slug_choice == "custom":
                slug = valid_data["slug"]
                if slug and "/" not in slug:
                    # check to make sure that there isn't already another post with this slug
                    existing = model.BlogPost.get_by_id(slug, parent=blog.key)
                    if existing and (not post or existing.key != post.key):
                        errors["slug_exists"] = True
                else:
                    errors["slug"] = True

        if "author" not in errors:
            author = model.BlogAuthor.get_by_id(valid_data["author"], parent=blog.key)
            if author:
                valid_data["author"] = author.key
            else:
                errors["author"] = True

        now = datetime.utcnow()
        if "timestamp_choice" not in errors:
            if valid_data["timestamp_choice"] == "now":
                valid_data["timestamp"] = now
            elif not valid_data.get("timestamp"):
                errors["timestamp"] = True

        if errors:
            return self.redisplay(form_data, errors, self.blog_url + '/admin/post/' + post_slug)

        if slug_choice == "auto":
            slug = model.makeSlug(valid_data["title"], blog, model.BlogPost, post)

        # turn tag strings into keys
        tag_keys = []
        if valid_data["tags"]:
            new_tags = []
            for tag_string in valid_data["tags"].split(","):
                tag_string = tag_string.strip()
                if tag_string:
                    tag_slug = model.slugify(tag_string)
                    tag = model.BlogTag.get_by_id(tag_slug, parent=blog.key)
                    if tag:
                        tag_keys.append(tag.key)
                    else:
                        tag_slug = model.makeSlug(tag_string, blog, model.BlogTag)
                        tag = model.BlogTag(id=tag_slug, name=tag_string, parent=blog.key)
                        new_tags.append(tag)
            if new_tags:
                ndb.put_multi(new_tags)
                tag_keys.extend([tag.key for tag in new_tags])
        valid_data["tag_keys"] = tag_keys

        # don't want to attach these temporary choices to the model
        del valid_data["slug"]
        del valid_data["slug_choice"]
        del valid_data["tags"]
        del valid_data["timestamp_choice"]

        was_published = False
        if post:
            was_published = post.published

            # if the slug is different, remake the entities since the key name needs to change
            if slug != post.slug:
                post = model.makeNew(post, id=slug, parent=blog.key)
            post.populate(**valid_data)
        else:
            post = model.BlogPost(id=slug, parent=blog.key, **valid_data)

        post.put()

        # send them back to the admin list of posts if it's not published or to the actual post if it is
        if post.published:
            cache_keys = getCacheKeys(blog)
            memcache.delete_multi(cache_keys)
            datastore_keys = getDatastoreKeys(blog)
            if post.timestamp > now:
                # post is in the future, so set the expires on these to just after it's available
                html_caches = ndb.get_multi(datastore_keys, use_memcache=False)
                new_html_caches = []
                diff = int((post.timestamp - now).total_seconds())
                for html_cache in html_caches:
                    if html_cache:
                        html_cache.expires = diff
                        new_html_caches.append(html_cache)
                if new_html_caches:
                    ndb.put_multi(new_html_caches)
            else:
                # post is published in the past so just delete everything
                ndb.delete_multi(datastore_keys)
            self.redirect(self.blog_url + '/post/' + post.slug)
        else:
            if was_published:
                clearCache(blog)

            if self.request.get("preview"):
                self.redirect(self.blog_url + '/admin/preview/' + post.slug)
            else:
                self.redirect(self.blog_url + '/admin/posts')