Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDCP-408] [Server] Scheduled exports of event and planning filters #1513

Merged
merged 11 commits into from
Jan 19, 2021
251 changes: 251 additions & 0 deletions server/features/combined_export.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
Feature: Export combined Planning and Event items with default template
Background: Initial Setup
Given "content_templates"
"""
[{
"template_name": "Planning export",
"template_type": "planning_export",
"data": {"slugline": "Foo"}
}]
"""
Given "desks"
"""
[{
"name": "sports",
"default_content_template": "#content_templates._id#"
}]
"""
Given "vocabularies"
"""
[{
"_id": "g2_content_type",
"items": [
{"is_active": true, "name": "Text", "qcode": "text"},
{"is_active": true, "name": "Photo", "qcode": "photo"}
]
}]
"""
Given "planning_export_templates"
"""
[{
"name": "conf_template",
"label": "Default Combined Template",
"type": "combined",
"data": {
"body_html_template": "test_combined_export_template.html"
}
}]
"""
Given "events"
"""
[{
"_id": "event1",
"guid": "event1",
"name": "test",
"dates": {
"start": "2021-01-11T14:00:00.000Z",
"end": "2021-01-11T16:00:00.000Z",
"tz": "Europe/Prague"
},
"location": []
}]
"""
Given "planning"
"""
[{
"_id": "plan1",
"guid": "plan1",
"headline": "Planning 1",
"slugline": "planning-1",
"description_text": "desc",
"event_item": "#events._id#",
"ednote": "Ed. note 1",
"coverages": [{
"coverage_id": "123",
"planning": {
"g2_content_type": "text"
}
},
{
"coverage_id": "456",
"planning": {
"g2_content_type": "photo"
}
}],
"planning_date": "2021-01-11T16:00:00.000Z"
}, {
"_id": "plan2",
"guid": "plan2",
"headline": "Planning 2",
"slugline": "planning-2",
"description_text": "desc 2",
"ednote": "Ed. note 2",
"coverages": [{
"coverage_id": "789",
"planning": {
"g2_content_type": "text"
}
},
{
"coverage_id": "012",
"planning": {
"g2_content_type": "photo"
}
}],
"planning_date": "2021-01-11T16:00:00.000Z"
}]
"""

@auth
Scenario: Export combined items as an article
When we post to "planning_article_export"
"""
{
"items": ["event1", "plan1", "plan2"],
"desk": "#desks._id#",
"type": "combined"
}
"""
Then we get new resource
"""
{
"type": "text",
"slugline": "Foo",
"task": {
"desk": "#desks._id#",
"stage": "#desks.working_stage#"
}
}
"""
And we get text in "body_html"
"""
<h2>Events</h2>
<p><b>test</b>, 1500</p>
<p><b>Planned coverage:</b> Text, Photo</p>
<p>---</p>
"""
And we get text in "body_html"
"""
<h2>Planning</h2>
<p><b>Planning 2</b></p>
<p>desc 2</p>
<p></p>
<p>Editorial note: Ed. note 2</p>
<p>Planned coverage: Text, Photo
<p>---</p>
"""
When we get "archive"
Then we get list with 1 items
"""
{"_items": [{
"slugline": "Foo"
}]}
"""

@auth
Scenario: Supports configured template
When we post to "planning_article_export"
"""
{
"items": ["event1", "plan1", "plan2"],
"desk": "#desks._id#",
"template": "#planning_export_templates.name#",
"type": "combined"
}
"""
Then we get new resource
"""
{
"type": "text",
"slugline": "Foo",
"task": {
"desk": "#desks._id#",
"stage": "#desks.working_stage#"
}
}
"""
And we get text in "body_html"
"""
<h1>Planned Coverages</h1>
<p></p>
<p><b>Event:</b> test</p>
<p><b>Coverages:</b> Text, Photo</p>
<p>---</p>
<p><b>Planning:</b> Planning 2</p>
<p><b>Coverages:</b> Text, Photo</p>
<p>---</p>
"""

@auth
Scenario: Supports article templates
When we post to "planning_article_export"
"""
{
"items": ["event1", "plan1", "plan2"],
"desk": "#desks._id#",
"template": "#planning_export_templates.name#",
"article_template": "#content_templates._id#",
"type": "combined"
}
"""
Then we get new resource
"""
{
"type": "text",
"slugline": "Foo",
"task": {
"desk": "#desks._id#",
"stage": "#desks.working_stage#"
}
}
"""
And we get text in "body_html"
"""
<h1>Planned Coverages</h1>
<p></p>
<p><b>Event:</b> test</p>
<p><b>Coverages:</b> Text, Photo</p>
<p>---</p>
<p><b>Planning:</b> Planning 2</p>
<p><b>Coverages:</b> Text, Photo</p>
<p>---</p>
"""
When we get "archive"
Then we get list with 1 items
"""
{"_items": [{"slugline": "Foo"}]}
"""

@auth
Scenario: Use COMBINED_EXPORT_BODY_TEMPLATE config to override default template
Given config update
"""
{"COMBINED_EXPORT_BODY_TEMPLATE": "{% for item in items %}<p>{{ item.name or item.headline }}</p>{% endfor %}"}
"""
When we post to "planning_article_export"
"""
{
"items": ["event1", "plan1", "plan2"],
"desk": "#desks._id#",
"type": "combined"
}
"""
Then we get new resource
"""
{
"type": "text",
"slugline": "Foo",
"task": {
"desk": "#desks._id#",
"stage": "#desks.working_stage#"
}
}
"""
When we get "archive"
Then we get list with 1 items
"""
{"_items": [{
"slugline": "Foo",
"body_html": "<p>test</p><p>Planning 2</p>"
}]}
"""
12 changes: 8 additions & 4 deletions server/features/planning_export.feature
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ Feature: Export planning items with default template
"""
{
"items": ["#planning._id#"],
"desk": "#desks._id#"
"desk": "#desks._id#",
"type": "planning"
}
"""
Then we get new resource
Expand Down Expand Up @@ -107,7 +108,8 @@ Feature: Export planning items with default template
{
"items": ["#planning._id#"],
"desk": "#desks._id#",
"template": "#planning_export_templates.name#"
"template": "#planning_export_templates.name#",
"type": "planning"
}
"""
Then we get new resource
Expand Down Expand Up @@ -167,7 +169,8 @@ Feature: Export planning items with default template
"items": ["#planning._id#"],
"desk": "#desks._id#",
"template": "#planning_export_templates.name#",
"article_template": "#content_templates._id#"
"article_template": "#content_templates._id#",
"type": "planning"
}
"""
Then we get new resource
Expand Down Expand Up @@ -200,7 +203,8 @@ Feature: Export planning items with default template
"""
{
"items": ["#planning._id#"],
"desk": "#desks._id#"
"desk": "#desks._id#",
"type": "planning"
}
"""
Then we get new resource
Expand Down
13 changes: 12 additions & 1 deletion server/features/steps/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,18 @@ def step_imp_when_action_resource(context, action, resource, item_id):
@then('we get text in "{field}"')
def then_we_get_text_in_response_field(context, field):
response = get_json_data(context.response)[field]
assert context.text in response, response

# Remove blank lines to make testing easier
response_text = '\n'.join([
line
for line in response.split('\n')
if len(line)
])

assert context.text.strip() in response_text, '"{}" not in "{}"'.format(
context.text.strip(),
response_text
)


@then('we store assignment id in "{tag}" from coverage {index}')
Expand Down
25 changes: 24 additions & 1 deletion server/planning/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from superdesk import register_jinja_filter
from .common import get_formatted_address

from .commands import FlagExpiredItems, DeleteSpikedItems, DeleteMarkedAssignments
from .commands import FlagExpiredItems, DeleteSpikedItems, DeleteMarkedAssignments, ExportScheduledFilters
import planning.commands # noqa
import planning.feeding_services # noqa
import planning.feed_parsers # noqa
Expand Down Expand Up @@ -237,6 +237,8 @@ def init_app(app):
'schedule': timedelta(seconds=60) # Runs once every minute
}

init_scheduled_exports_task(app)

# Create 'type' required for planning module if not already preset
with app.app_context():
vocabulary_service = superdesk.get_resource_service('vocabularies')
Expand Down Expand Up @@ -268,6 +270,22 @@ def init_app(app):
register_jinja_filter('formatted_address', get_formatted_address)


def init_scheduled_exports_task(app):
# If the celery task is not configured, then set the default now
if not app.config['CELERY_BEAT_SCHEDULE'].get('planning.export_scheduled_filters'):
app.config['CELERY_TASK_ROUTES']['planning.export_scheduled_filters'] = {
'queue': celery_queue('default'),
'routing_key': 'planning.exports'
}

# If the celery schedule is not configured, then set the default now
if not app.config['CELERY_BEAT_SCHEDULE'].get('planning:export_scheduled_filters'):
app.config['CELERY_BEAT_SCHEDULE']['planning:export_scheduled_filters'] = {
'task': 'planning.export_scheduled_filters',
'schedule': crontab(minute=0)
}


@celery.task(soft_time_limit=600)
def flag_expired():
FlagExpiredItems().run()
Expand All @@ -281,3 +299,8 @@ def delete_spiked():
@celery.task(soft_time_limit=600)
def delete_assignments():
DeleteMarkedAssignments().run()


@celery.task(soft_time_limit=600)
def export_scheduled_filters():
ExportScheduledFilters().run()
Loading