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')
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')
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')