def save(self, *args, **kwargs): # Needs to be imported here to avoid circular imports. from biostar.utils import markdown self.lastedit_user = self.lastedit_user or self.author self.creation_date = self.creation_date or util.now() self.lastedit_date = self.lastedit_date or self.creation_date self.last_contributor = self.lastedit_user # Sanitize the post body. self.html = markdown.parse(self.content, post=self) # Set the rank self.rank = self.lastedit_date.timestamp() # Must add tags with instance method. This is just for safety. self.tag_val = util.strip_tags(self.tag_val) self.creation_date = self.creation_date or util.now() self.lastedit_date = self.lastedit_date or self.creation_date if self.type == Post.ANSWER: Post.objects.filter(uid=self.parent.uid).update( lastedit_date=self.lastedit_date, lastedit_user=self.lastedit_user) # This will trigger the signals super(Post, self).save(*args, **kwargs)
def save(self, *args, **kwargs): # Needs to be imported here to avoid circular imports. from biostar.utils import markdown self.lastedit_user = self.lastedit_user or self.author self.creation_date = self.creation_date or util.now() self.lastedit_date = util.now() self.last_contributor = self.lastedit_user # Sanitize the post body. self.content = bleach.clean(self.content, attributes=markdown.ALLOWED_ATTRIBUTES) self.html = markdown.parse(self.content, post=self) self.tag_val = self.tag_val.replace(' ', '') # Default tags self.tag_val = self.tag_val or "tag1,tag2" # Set the top level state of the post. self.is_toplevel = self.type in Post.TOP_LEVEL if self.type == Post.ANSWER: Post.objects.filter(uid=self.parent.uid).update( lastedit_date=self.lastedit_date, lastedit_user=self.lastedit_user) # This will trigger the signals super(Post, self).save(*args, **kwargs)
def render(self, context): text = self.nodelist.render(context) text = markdown.parse(text) text = bleach.linkify(text, callbacks=self.CALLBACKS, skip_tags=['pre']) return text
def gen_posts(): logger.info("Transferring posts") posts = PostsPost.objects.order_by("id") elapsed, progress = timer_func() stream = zip(count(1), posts) stream = islice(stream, limit) for index, post in stream: progress(index, msg="posts") author = users_set.get(str(post.author_id)) lastedit_user = users_set.get(str(post.lastedit_user_id)) # Incomplete author information loaded or existing posts. if not (author and lastedit_user): continue is_toplevel = post.type in Post.TOP_LEVEL rank = post.lastedit_date.timestamp() # Convert the content to markdown if its html force_text = post.content.strip().startswith("<") if force_text: try: content = html2text.html2text(post.content, bodywidth=0) except Exception as exc: content = post.content logger.error(f"Failed parsing post={post.id}.") html = markdown.parse(content) else: content = post.content html = post.html new_post = Post(uid=post.id, html=decode(html), type=post.type, is_toplevel=is_toplevel, lastedit_user=lastedit_user, thread_votecount=post.thread_score, author=author, status=post.status, rank=rank, accept_count=int(post.has_accepted), lastedit_date=post.lastedit_date, book_count=post.book_count, content=decode(content), title=decode(post.title), vote_count=post.vote_count, creation_date=post.creation_date, tag_val=decode(post.tag_val), view_count=post.view_count) # Store parent and root for every post. relations[str( new_post.uid)] = [str(post.root_id), str(post.parent_id)] yield new_post
def markdown_file(pattern): """ Returns the content of a file matched by the pattern. Returns an error message if the pattern cannot be found. """ #path = find_file(pattern=pattern) path = pattern path = os.path.abspath(path) if os.path.isfile(path): text = open(path).read() else: text = f" file '{pattern}': '{path}' not found" try: html = markdown.parse(text) html = bleach.linkify(html, callbacks=[top_level_only], skip_tags=['pre']) html = mark_safe(html) except Exception as e: html = f"Markdown rendering exception" logger.error(e) return html