-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add task to save rendered content to db; call tasks on delay
- Loading branch information
Showing
5 changed files
with
177 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,83 @@ | ||
import os | ||
|
||
import subprocess | ||
import structlog | ||
|
||
from celery import shared_task | ||
|
||
from .asciidoc import adoc_to_html | ||
from .boostrenderer import get_body_from_html, get_content_from_s3 | ||
from dateutil.parser import parse | ||
|
||
from django.core.cache import caches | ||
|
||
from .asciidoc import convert_adoc_to_html, process_adoc_to_html_content | ||
from .boostrenderer import get_content_from_s3 | ||
from .models import RenderedContent | ||
|
||
logger = structlog.get_logger() | ||
|
||
|
||
@shared_task | ||
def adoc_to_html(file_path, delete_file=True): | ||
return adoc_to_html(file_path, delete_file=delete_file) | ||
return convert_adoc_to_html(file_path, delete_file=delete_file) | ||
|
||
|
||
@shared_task | ||
def clear_rendered_content_cache_by_cache_key(cache_key): | ||
"""Deletes a RenderedContent object by its cache key from redis and | ||
database.""" | ||
cache = caches["static_content"] | ||
cache.delete(cache_key) | ||
RenderedContent.objects.delete_by_cache_key(cache_key) | ||
|
||
|
||
@shared_task | ||
def refresh_rendered_content_from_s3(content_path, cache_key): | ||
""" Take a cache """ | ||
result = get_content_from_s3(key=content_path) | ||
if result and result.get("content"): | ||
content = result.get("content") | ||
content_type = result.get("content_type") | ||
last_updated_at_raw = result.get("last_updated_at") | ||
def clear_rendered_content_cache_by_content_type(content_type): | ||
"""Deletes all RenderedContent objects for a given content type from redis | ||
and database.""" | ||
RenderedContent.objects.clear_cache_by_content_type(content_type) | ||
RenderedContent.objects.delete_by_content_type(content_type) | ||
|
||
|
||
@shared_task | ||
def refresh_content_from_s3(s3_key, cache_key): | ||
"""Calls S3 with the s3_key, then saves the result to the | ||
RenderedContent object with the given cache_key.""" | ||
content_dict = get_content_from_s3(key=s3_key) | ||
content = content_dict.get("content") | ||
if content_dict and content: | ||
content_type = content_dict.get("content_type") | ||
if content_type == "text/asciidoc": | ||
content = self.convert_adoc_to_html(content, cache_key) | ||
last_updated_at = ( | ||
parse(last_updated_at_raw) if last_updated_at_raw else None | ||
) | ||
content = process_adoc_to_html_content(content) | ||
last_updated_at_raw = content_dict.get("last_updated_at") | ||
last_updated_at = parse(last_updated_at_raw) if last_updated_at_raw else None | ||
# Clear the cache because we're going to update it. | ||
clear_rendered_content_cache_by_cache_key(cache_key) | ||
|
||
# Update the rendered content. | ||
save_rendered_content( | ||
cache_key, content_type, content, last_updated_at=last_updated_at | ||
) | ||
# Cache the refreshed rendered content | ||
cache = caches["static_content"] | ||
cache.set(cache_key, {"content": content, "content_type": content_type}) | ||
|
||
# Get the output from the command | ||
converted_html = result.stdout | ||
|
||
# Delete the temporary file | ||
if delete_file: | ||
os.remove(file_path) | ||
@shared_task | ||
def save_rendered_content(cache_key, content_type, content_html, last_updated_at=None): | ||
"""Saves a RenderedContent object to database.""" | ||
defaults = { | ||
"content_type": content_type, | ||
"content_html": content_html, | ||
} | ||
|
||
if last_updated_at: | ||
defaults["last_updated_at"] = last_updated_at | ||
|
||
return converted_html | ||
obj, created = RenderedContent.objects.update_or_create( | ||
cache_key=cache_key[:255], defaults=defaults | ||
) | ||
logger.info( | ||
"content_saved_to_rendered_content", | ||
cache_key=cache_key, | ||
content_type=content_type, | ||
status_code=200, | ||
obj_id=obj.id, | ||
obj_created=created, | ||
) | ||
return obj |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import pytest | ||
import tempfile | ||
from unittest.mock import patch | ||
|
||
from django.core.cache import caches | ||
from django.test import override_settings | ||
|
||
from core.asciidoc import convert_adoc_to_html, process_adoc_to_html_content | ||
|
||
|
||
@override_settings( | ||
CACHES={ | ||
"static_content": { | ||
"BACKEND": "django.core.cache.backends.locmem.LocMemCache", | ||
"LOCATION": "third-unique-snowflake", | ||
"TIMEOUT": "60", # Cache timeout in seconds: 1 minute | ||
}, | ||
} | ||
) | ||
def test_adoc_to_html(): | ||
# Get the static content cache | ||
caches["static_content"] | ||
|
||
# The content of the sample adoc file | ||
sample_adoc_content = "= Document Title\n\nThis is a sample document.\n" | ||
|
||
# Write the content to a temporary file | ||
with tempfile.NamedTemporaryFile(delete=False) as temp_file: | ||
temp_file.write(sample_adoc_content.encode()) | ||
temp_file_path = temp_file.name | ||
|
||
# Execute the task | ||
with patch("core.asciidoc.subprocess.run") as mock_run: | ||
mock_run.return_value.stdout = "html_content".encode() | ||
convert_adoc_to_html(temp_file_path, delete_file=True) | ||
|
||
# Verify that the temporary file has been deleted | ||
with pytest.raises(FileNotFoundError): | ||
with open(temp_file_path, "r"): | ||
pass | ||
|
||
|
||
def test_process_adoc_to_html_content(): | ||
"""Test the process_adoc_to_html_content function.""" | ||
content = "sample" | ||
expected_html = '<div id="header">\n</div><div id="content">\n<div class="paragraph">\n<p>sample</p>\n</div>\n</div>' # noqa: E501 | ||
|
||
result = process_adoc_to_html_content(content) | ||
assert result == expected_html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters