Skip to content

Commit

Permalink
Add published if missing on build
Browse files Browse the repository at this point in the history
  • Loading branch information
Siecje committed Jan 15, 2024
1 parent 3e5d1d5 commit 77787bd
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 81 deletions.
58 changes: 55 additions & 3 deletions htmd/cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import datetime
import importlib
import os
import sys

import click
Expand Down Expand Up @@ -56,11 +58,12 @@ def verify():
importlib.reload(site)

correct = True
required_fields = ('author', 'title')
for post in site.posts:
for item in ['author', 'published', 'title']:
if item not in post.meta:
for field in required_fields:
if field not in post.meta:
correct = False
msg = f'Post "{post.path}" does not have field {item}.'
msg = f'Post "{post.path}" does not have field {field}.'
click.echo(click.style(msg, fg='red'))
if 'published' in post.meta:
try:
Expand Down Expand Up @@ -89,6 +92,53 @@ def verify():
sys.exit(1)


def set_post_time(app, post, property, date_time):
file_path = os.path.join(
app.config['FLATPAGES_ROOT'],
post.path + app.config['FLATPAGES_EXTENSION']
)
with open(file_path, 'r') as file:
lines = file.readlines()

found = False
with open(file_path, 'w') as file:
for line in lines:
if not found and property in line:
line = f'{property}: {date_time.isoformat()}\n'
found = True
elif not found and '...' in line:
file.write(f'{property}: {date_time.isoformat()}\n')
found = True
file.write(line)


def set_posts_datetime(app, posts):
# Ensure each post has a published date
# set time for correct date field
for post in posts:
if 'updated' not in post.meta:
published = post.meta.get('published')
if isinstance(published, datetime.datetime):
property = 'updated'
else:
property = 'published'
else:
property = 'updated'

post_datetime = post.meta.get(property)
now = datetime.datetime.now()
current_time = now.time()
if isinstance(post_datetime, datetime.date):
post_datetime = datetime.datetime.combine(
post_datetime, current_time
)
else:
post_datetime = now
post.meta[property] = post_datetime
set_post_time(app, post, property, post_datetime)



@cli.command('build', short_help='Create static version of the site.')
@click.pass_context
@click.option(
Expand Down Expand Up @@ -119,6 +169,8 @@ def build(ctx, css_minify, js_minify):
# setting them here doesn't work
importlib.reload(site)

set_posts_datetime(site.app, site.posts)

freezer = site.freezer
try:
freezer.freeze()
Expand Down
43 changes: 3 additions & 40 deletions htmd/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def get_project_dir():

# Flask configs are flat, config.toml is not
# Define the configuration keys and their default values
# [section, key, default]
config_keys = {
'SITE_NAME': ['site', 'name', ''],
'SITE_URL': ['site', 'url', ''],
Expand All @@ -78,7 +79,6 @@ def get_project_dir():
# Update app.config using the configuration keys
for flask_key, (table, key, default) in config_keys.items():
app.config[flask_key] = htmd_config.get(table, {}).get(key, default)



# To avoid full paths in config.toml
Expand Down Expand Up @@ -174,26 +174,6 @@ def index():
return render_template('index.html', active='home', posts=latest[:4])


def set_post_time(post, property, date_time):
file_path = os.path.join(
app.config['FLATPAGES_ROOT'],
post.path + app.config['FLATPAGES_EXTENSION']
)
with open(file_path, 'r') as file:
lines = file.readlines()

found = False
with open(file_path, 'w') as file:
for line in lines:
if not found and property in line:
line = f'{property}: {date_time.isoformat()}\n'
found = True
elif not found and '...' in line:
file.write(f'{property}: {date_time.isoformat()}\n')
found = True
file.write(line)


@app.route('/feed.atom')
def feed():
name = app.config.get('SITE_NAME')
Expand All @@ -205,7 +185,6 @@ def feed():
title=name,
url=url
)
current_time = datetime.datetime.now().time()
for post in posts:
url = url_for(
'post',
Expand All @@ -215,28 +194,12 @@ def feed():
path=post.path
)

if 'updated' not in post.meta:
published = post.meta.get('published')
if isinstance(published, datetime.datetime):
property = 'updated'
else:
property = 'published'
else:
property = 'updated'

datetime_field = post.meta.get(property)
if isinstance(datetime_field, datetime.date):
datetime_field = datetime.datetime.combine(
datetime_field, current_time
)
else:
datetime_field = datetime.datetime.now()
set_post_time(post, property, datetime_field)
post_datetime = post.meta.get('updated') or post.meta.get('published')
atom.add(
post.meta.get('title'), post.html, content_type='html',
author=post.meta.get('author', app.config.get('DEFAULT_AUTHOR')),
url=url,
updated=datetime_field,
updated=post_datetime,
)
ret = atom.get_response()
return ret
Expand Down
7 changes: 0 additions & 7 deletions htmd/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,6 @@ def copy_file(source, destination):
def copy_missing_templates():
template_dir = files('htmd.example_site') / 'templates'
for template_file in sorted(template_dir.iterdir()):
skip_file = False
for skip_file_name in ('__pycache__',):
if skip_file_name in str(template_file):
skip_file = True
break
if skip_file:
continue
file_name = os.path.basename(template_file)
copy_file(
template_file,
Expand Down
42 changes: 25 additions & 17 deletions tests/test_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from click.testing import CliRunner
from htmd.cli import build, start

from test_verify import remove_field_from_example_post
from utils import remove_fields_from_example_post


SUCCESS_REGEX = (
Expand All @@ -31,7 +31,7 @@ def test_build_verify_fails():
runner = CliRunner()
with runner.isolated_filesystem():
result = runner.invoke(start)
remove_field_from_example_post('title')
remove_fields_from_example_post(('title',))
result = runner.invoke(build)
assert result.exit_code == 1
assert result.output == expected_output
Expand Down Expand Up @@ -498,12 +498,9 @@ def test_build_published_time_is_added():
runner = CliRunner()
with runner.isolated_filesystem():
runner.invoke(start)
remove_fields_from_example_post(('updated',))
with open(os.path.join('posts', 'example.md'), 'r') as post_file:
b_lines = post_file.readlines()
with open(os.path.join('posts', 'example.md'), 'w') as post_file:
for line in b_lines:
if 'updated' not in line:
post_file.write(line)
runner.invoke(build)
with open(os.path.join('posts', 'example.md'), 'r') as post_file:
a_lines = post_file.readlines()
Expand Down Expand Up @@ -532,9 +529,7 @@ def test_build_published_time_is_added():
assert time_difference.total_seconds() < threshold_seconds

# verify updated is not added
for a_line in a_lines:
if 'updated' in a_line:
assert False, 'updated found in example post'
assert 'updated' not in ''.join(a_lines)


def test_build_updated_is_added():
Expand All @@ -545,15 +540,10 @@ def test_build_updated_is_added():
with runner.isolated_filesystem():
runner.invoke(start)
# Remove updated from example post
with open(os.path.join('posts', 'example.md'), 'r') as post_file:
b_lines = post_file.readlines()
with open(os.path.join('posts', 'example.md'), 'w') as post_file:
for line in b_lines:
if 'updated' not in line:
post_file.write(line)
# First build adds published time
remove_fields_from_example_post(('updated',))
# First build adds time to published
runner.invoke(build)
# Second build adds updated
# Second build adds updated with time
runner.invoke(build)
with open(os.path.join('posts', 'example.md'), 'r') as post_file:
a_lines = post_file.readlines()
Expand Down Expand Up @@ -598,3 +588,21 @@ def test_build_updated_is_added_once():
count += 1

assert count == 1


def test_build_without_published():
runner = CliRunner()
with runner.isolated_filesystem():
runner.invoke(start)
remove_fields_from_example_post(('published', 'updated',))

# First build adds published time
runner.invoke(build)
with open(os.path.join('posts', 'example.md'), 'r') as post_file:
a_lines = post_file.readlines()
count = 0
for a_line in a_lines:
if 'published' in a_line:
count += 1

assert count == 1
23 changes: 9 additions & 14 deletions tests/test_verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from click.testing import CliRunner
from htmd.cli import start, verify

from utils import remove_fields_from_example_post


def test_verify():
runner = CliRunner()
Expand All @@ -14,22 +16,13 @@ def test_verify():
assert result.output == expected_output


def remove_field_from_example_post(field_name):
with open(os.path.join('posts', 'example.md'), 'r') as post:
lines = post.readlines()
with open(os.path.join('posts', 'example.md'), 'w') as post:
for line in lines:
if field_name not in line:
post.write(line)


def test_verify_author_missing():
runner = CliRunner()
with runner.isolated_filesystem():
runner.invoke(start)

# Remove author from example post
remove_field_from_example_post('author')
remove_fields_from_example_post(('author',))

result = runner.invoke(verify)
assert result.exit_code == 1
Expand All @@ -43,7 +36,7 @@ def test_verify_title_missing():
runner.invoke(start)

# Remove title from example post
remove_field_from_example_post('title')
remove_fields_from_example_post(('title',))

result = runner.invoke(verify)
assert result.exit_code == 1
Expand All @@ -57,12 +50,14 @@ def test_verify_published_missing():
runner.invoke(start)

# Remove published from example post
remove_field_from_example_post('published')
remove_fields_from_example_post(('published',))

result = runner.invoke(verify)
assert result.exit_code == 1
expected_output = 'Post "example" does not have field published.\n'
# verify doesn't check for published
# since it will be added on build.
expected_output = 'All posts are correctly formatted.\n'
assert result.output == expected_output
assert result.exit_code == 0


def test_verify_published_invalid_year():
Expand Down
13 changes: 13 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import os


def remove_fields_from_example_post(field_names):
with open(os.path.join('posts', 'example.md'), 'r') as post:
lines = post.readlines()
with open(os.path.join('posts', 'example.md'), 'w') as post:
for line in lines:
for field_name in field_names:
if field_name in line:
break
else:
post.write(line)

0 comments on commit 77787bd

Please sign in to comment.