def index(): def validate(date_text): try: datetime.strptime(date_text, '%d-%m-%Y') return True except (ValueError, TypeError): return False published_posts = (p for p in posts if 'date' in p.meta and validate(p.meta['date'])) latest = sorted(published_posts, reverse=True, key=lambda p: p.meta['date']) for post in latest: setattr(post, 'readtime', str(readtime.of_markdown(post.body))) setattr(post, 'num_comments', 0) ppp = app.config['POSTS_PER_PAGE'] max_pages = len(latest) // ppp page = max(0, min(max_pages, request.args.get('page', 0, type=int))) print(f'page={page}') prev_url = url_for('main.index', page=page - 1) if page > 0 else None next_url = \ url_for('main.index', page=page+1) if page+1 <= max_pages else None return render_template('index.html', posts=latest[page * ppp:(page + 1) * ppp], prev_url=prev_url, next_url=next_url)
def edit_post(postname): post = Post.query.filter_by(url=postname).first_or_404() form = PostForm(title=post.title, content=post.content) if form.validate_on_submit(): title = form.title.data url = generate_url(title) tags = {_.group(1) for _ in TAG_EXTRACTOR.finditer(form.content.data)} content = form.content.data post.edited = datetime.utcnow() post.url = url post.title = title post.content = content post.content_time = readtime.of_markdown(content).minutes post.post_tags.clear() post.post_tags.extend(PostTag(_) for _ in tags) try: db.session.commit() return redirect(url_for('post.post', username=g.user.username, postname=url)) except IntegrityError: flash('This title already exists. Please, enter another title.', 'warning') db.session.rollback() return render_template('edit/post.html', form=form, created=post.created, edited=post.edited, content_time=post.content_time)
def on_model_change(self, form, model, is_created): with suppress(AttributeError): if form.content.data: tags = { _.group(1) for _ in TAG_EXTRACTOR.finditer(form.content.data) } model.content_time = readtime.of_markdown( form.content.data).minutes model.post_tags.clear() model.post_tags.extend((PostTag(_) for _ in tags))
def on_model_change(self, form, model, is_created): with suppress(AttributeError): if form.new_password.data: model.password = app_bcrypt.generate_password_hash( form.new_password.data) if form.logotype.data.stream: form.logotype.data.stream.seek(0) model.logotype = resize_logotype(form.logotype.data.stream) if form.about.data: model.about_time = readtime.of_markdown( form.about.data).minutes
def md_readtime(md, reading_rate=READING_RATE, rounding_override=False, rounded_minutes=False, **kwargs): """Get reading time in seconds.""" rt = readtime.of_markdown(md, wpm=reading_rate).delta.total_seconds() #Round up on the conversion of estimated reading time in seconds, to minutes... #f'Reading time in seconds: {rt}; in minutes: {math.ceil(rt/60)}.' if not rounding_override and rounded_minutes: return math.ceil(rt / 60) return rt
def test_can_add(self): inp = open('tests/samples/plain_text.txt').read() result1 = readtime.of_text(inp) self.assertEquals(result1.seconds, 154) inp = open('tests/samples/markdown.md').read() result2 = readtime.of_markdown(inp) self.assertEquals(result2.seconds, 236) result = (result1 + result2) self.assertEquals(result.seconds, 154 + 236) self.assertEquals(type(result.seconds), int) self.assertEquals(result.text, u('7 min')) self.assertEquals(u(result), u('7 min read'))
def profile(): form = ProfileForm(first_name=g.user.first_name, last_name=g.user.last_name, about=g.user.about) if form.validate_on_submit(): g.user.edited = datetime.utcnow() g.user.first_name = form.first_name.data g.user.last_name = form.last_name.data g.user.about = form.about.data g.user.about_time = readtime.of_markdown(form.about.data).minutes if form.logotype.data: try: g.user.logotype = resize_logotype(form.logotype.data.stream) except ValueError: flash('Avatar should be JPG or PNG file format', 'warning') db.session.commit() return render_template('edit/profile.html', form=form)
def new_post(): form = PostForm() if form.validate_on_submit(): title = form.title.data url = generate_url(title) tags = {_.group(1) for _ in TAG_EXTRACTOR.finditer(form.content.data)} content = form.content.data post = Post(url, title, content, readtime.of_markdown(content).minutes) post.post_tags.extend(PostTag(_) for _ in tags) g.user.posts.append(post) try: db.session.commit() post_url = url_for('post.post', username=g.user.username, postname=url, _external=True) celery.send_task('words.tasks.repost.all', (post.post_id, post_url)) return redirect(post_url) except IntegrityError: flash('This title already exists. Please, enter another title.', 'warning') db.session.rollback() return render_template('edit/post.html', form=form, created=datetime.utcnow(), edited=datetime.utcnow(), content_time=0)
file_path.suffix, "").replace("/index", "") article['file_url'] = str(file_path.relative_to(doc_directory).as_posix()) article['http_url'] = http_url.lower() # Strip SVG and convert to html logging.debug("Stripping tags") contents = file_path.read_text(encoding="utf8") htmltags = re.compile('<.*>') cleantext = re.sub(htmltags, '', contents) words = cleantext.lower().split() logging.debug("Getting word count") article['word_count'] = len(words) logging.debug("Get reading time") article['read_time'] = str(readtime.of_markdown(cleantext)) logging.debug("Parsing Metadata") headers = re.findall(r"---\n(.*)\n---", contents, re.MULTILINE | re.DOTALL) if headers: try: logging.debug("Loadding YAML") article_meta = yaml.load("\n".join(headers), Loader=yaml.SafeLoader) except: print("Broken headers for: " + str_path) print("\n".join(headers)) if article_meta.get('redirect_url'): logging.info("Found redirect for: " + str_path) continue
def readtime(self): return readtime.of_markdown(self.body)
def get_read_time(post_markdown): """ Get a string representing the time to read the given markdown (expecting a post) """ return readtime.of_markdown(post_markdown)
def get_read_time(self, post): return readtime.of_markdown(post.text).text
def test_markdown(self): inp = open('tests/samples/markdown.md').read() result = readtime.of_markdown(inp) self.assertEquals(result.seconds, 236) self.assertEquals(result.text, u('4 min')) self.assertEquals(u(result), u('4 min read'))
def reading_time(value): return readtime.of_markdown(value)
import readtime as rt import re import sys filename = str(sys.argv[1]) with open(filename, 'r') as file: data = file.read() tmp = str(rt.of_markdown(data)) with open(filename, 'r') as file: lines = file.readlines() count = 0 for line in lines: if re.search("post-meta", line): break count += 1 newline = lines[count][-1] lines[count] = lines[count][:-1] if re.search("min read", lines[count]): lines[count] = lines[count][:-13] lines[count] += " - " + tmp + newline with open(filename, 'w') as file: file.writelines(lines)
def save(self, *args, **kwargs): self.lock_key = self.lock_key if self.lock_key else uuid4().hex self.readtime = readtime.of_markdown(self.markdown, wpm=250).minutes self.has_code = "```" in self.markdown super(Post, self).save(*args, **kwargs)