Skip to content

Commit

Permalink
Refactor export
Browse files Browse the repository at this point in the history
  • Loading branch information
jochenklar committed May 12, 2023
1 parent d444862 commit e1ba817
Show file tree
Hide file tree
Showing 41 changed files with 627 additions and 393 deletions.
33 changes: 22 additions & 11 deletions rdmo/conditions/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from rdmo.core.exports import XMLResponse
from rdmo.core.permissions import HasModelPermission
from rdmo.core.utils import render_to_format
from rdmo.core.views import ChoicesViewSet
from rdmo.core.viewsets import CopyModelMixin

Expand Down Expand Up @@ -40,17 +41,27 @@ def index(self, request):
serializer = ConditionIndexSerializer(queryset, many=True)
return Response(serializer.data)

@action(detail=False, permission_classes=[HasModelPermission])
def export(self, request):
serializer = ConditionExportSerializer(self.get_queryset(), many=True)
xml = ConditionRenderer().render(serializer.data)
return XMLResponse(xml, name='conditions')

@action(detail=True, url_path='export', permission_classes=[HasModelPermission])
def detail_export(self, request, pk=None):
serializer = ConditionExportSerializer(self.get_object())
xml = ConditionRenderer().render([serializer.data])
return XMLResponse(xml, name=self.get_object().key)
@action(detail=False, url_path='export(/(?P<export_format>[a-z]+))?', permission_classes=[HasModelPermission])
def export(self, request, export_format='xml'):
if export_format == 'xml':
serializer = ConditionExportSerializer(self.get_queryset(), many=True)
xml = ConditionRenderer().render(serializer.data)
return XMLResponse(xml, name='conditions')
else:
return render_to_format(self.request, export_format, 'tasks', 'conditions/export/conditions.html', {
'conditions': self.get_queryset()
})

@action(detail=True, url_path='export(/(?P<export_format>[a-z]+))?', permission_classes=[HasModelPermission])
def detail_export(self, request, pk=None, export_format='xml'):
if export_format == 'xml':
serializer = ConditionExportSerializer(self.get_object())
xml = ConditionRenderer().render([serializer.data])
return XMLResponse(xml, name=self.get_object().key)
else:
return render_to_format(self.request, export_format, self.get_object().key, 'conditions/export/conditions.html', {
'conditions': [self.get_object()]
})


class RelationViewSet(ChoicesViewSet):
Expand Down
2 changes: 1 addition & 1 deletion rdmo/core/exports.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class XMLResponse(HttpResponse):
def __init__(self, xml, name=None):
super().__init__(prettify_xml(xml), content_type='application/xml')
if name:
self['Content-Disposition'] = 'filename="{}.xml"'.format(name.replace('/', '_'))
self['Content-Disposition'] = 'attachment; filename="{}.xml"'.format(name.replace('/', '_'))


def prettify_xml(xmlstring):
Expand Down
3 changes: 2 additions & 1 deletion rdmo/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@
'DEFAULT_URI_PREFIX',
'LANGUAGES',
'MULTISITE',
'GROUPS'
'GROUPS',
'EXPORT_FORMATS',
]

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
Expand Down
44 changes: 32 additions & 12 deletions rdmo/domain/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from rdmo.core.exports import XMLResponse
from rdmo.core.permissions import HasModelPermission
from rdmo.core.utils import render_to_csv, render_to_format
from rdmo.core.viewsets import CopyModelMixin

from .models import Attribute
Expand Down Expand Up @@ -44,15 +45,34 @@ def nested(self, request, pk):
serializer = AttributeNestedSerializer(self.get_object(), context={'request': request})
return Response(serializer.data)

@action(detail=False, permission_classes=[HasModelPermission])
def export(self, request):
serializer = AttributeExportSerializer(self.get_queryset(), many=True)
xml = AttributeRenderer().render(serializer.data)
return XMLResponse(xml, name='attributes')

@action(detail=True, url_path='export', permission_classes=[HasModelPermission])
def detail_export(self, request, pk=None):
queryset = self.get_object().get_descendants(include_self=True)
serializer = AttributeExportSerializer(queryset, many=True)
xml = AttributeRenderer().render(serializer.data)
return XMLResponse(xml, name=self.get_object().key)
@action(detail=False, url_path='export(/(?P<export_format>[a-z]+))?', permission_classes=[HasModelPermission])
def export(self, request, export_format='xml'):
attributes = self.get_queryset()
if export_format == 'xml':
serializer = AttributeExportSerializer(attributes, many=True)
xml = AttributeRenderer().render(serializer.data)
return XMLResponse(xml, name='attributes')
elif export_format[:3] == 'csv':
rows = [(attribute.key, attribute.comment, attribute.uri) for attribute in attributes]
delimiter = ',' if export_format == 'csvcomma' else ';'
return render_to_csv('domain', rows, delimiter)
else:
return render_to_format(self.request, export_format, 'domain', 'domain/export/attributes.html', {
'attributes': attributes
})

@action(detail=True, url_path='export(/(?P<export_format>[a-z]+))?', permission_classes=[HasModelPermission])
def detail_export(self, request, pk=None, export_format='xml'):
attributes = self.get_object().get_descendants(include_self=True)
if export_format == 'xml':
serializer = AttributeExportSerializer(attributes, many=True)
xml = AttributeRenderer().render(serializer.data)
return XMLResponse(xml, name=self.get_object().key)
elif export_format[:3] == 'csv':
rows = [(attribute.key, attribute.comment, attribute.uri) for attribute in attributes]
delimiter = ',' if export_format == 'csvcomma' else ';'
return render_to_csv('domain', rows, delimiter)
else:
return render_to_format(self.request, export_format, self.get_object().key, 'domain/export/attributes.html', {
'attributes': attributes
})
26 changes: 20 additions & 6 deletions rdmo/management/assets/js/components/common/Links.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import isUndefined from 'lodash/isUndefined'

import Link from 'rdmo/core/assets/js/components/Link'

import { elementModules } from '../../constants/elements'

const EditLink = ({ element, verboseName, onClick }) => {
const title = interpolate(gettext('Edit %s'), [verboseName])
return <Link className="element-link fa fa-pencil" title={title} onClick={onClick} />
Expand Down Expand Up @@ -102,18 +104,30 @@ LockedLink.propTypes = {
onClick: PropTypes.func.isRequired
}

const ExportLink = ({ element, verboseName }) => {
const title = interpolate(gettext('Export %s as XML'), [verboseName])
const ExportLink = ({ element, elementType, verboseName, exportFormats }) => {
const title = interpolate(gettext('Export %s'), [verboseName])
const url = `/api/v1/${elementModules[elementType]}/${elementType}`
return (
<a href={element.xml_url} className="element-link fa fa-download"
title={title} target="_blank">
</a>
<span className="dropdown">
<a href="" className="element-link fa fa-download" title={title} data-toggle="dropdown"></a>
<ul className="dropdown-menu">
<li><a href={`${url}/${element.id}/export/`}>{gettext('XML')}</a></li>
<li role="separator" className="divider"></li>
{
exportFormats.map(([key, label], index) => <li key={index}>
<a href={`${url}/${element.id}/export/${key}/`} target={['pdf', 'html'].includes(key) ? '_blank' : '_self'}>{label}</a>
</li>)
}
</ul>
</span>
)
}

ExportLink.propTypes = {
element: PropTypes.object.isRequired,
verboseName: PropTypes.string.isRequired
elementType: PropTypes.string.isRequired,
verboseName: PropTypes.string.isRequired,
exportFormats: PropTypes.array
}

const NestedLink = ({ element, verboseName, onClick }) => {
Expand Down
3 changes: 2 additions & 1 deletion rdmo/management/assets/js/components/element/Attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const Attribute = ({ config, attribute, elementActions, display='list', filter=n
<CopyLink element={attribute} verboseName={verboseName} onClick={fetchCopy} />
<LockedLink element={attribute} verboseName={verboseName} onClick={toggleLocked} />
<NestedLink element={attribute} verboseName={verboseName} onClick={fetchNested} />
<ExportLink element={attribute} verboseName={verboseName} />
<ExportLink element={attribute} elementType="attributes" verboseName={verboseName}
exportFormats={config.settings.export_formats} />
</div>
<div>
<p>
Expand Down
4 changes: 3 additions & 1 deletion rdmo/management/assets/js/components/element/Catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import isUndefined from 'lodash/isUndefined'

import { filterElement } from '../../utils/filter'
import { exportUrls } from '../../constants/elements'

import Section from './Section'
import { ElementErrors } from '../common/Errors'
Expand Down Expand Up @@ -31,7 +32,8 @@ const Catalog = ({ config, catalog, elementActions, display='list', filter=null
<AddLink element={catalog} verboseName={gettext('section')} onClick={createSection} />
<AvailableLink element={catalog} verboseName={verboseName} onClick={toggleAvailable} />
<LockedLink element={catalog} verboseName={verboseName} onClick={toggleLocked} />
<ExportLink element={catalog} verboseName={verboseName} />
<ExportLink element={catalog} elementType="catalogs" verboseName={verboseName}
exportFormats={config.settings.export_formats} />
</div>
<div>
<p>
Expand Down
3 changes: 2 additions & 1 deletion rdmo/management/assets/js/components/element/Condition.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ const Condition = ({ config, condition, elementActions, filter=null }) => {
<EditLink element={condition} verboseName={verboseName} onClick={fetchEdit} />
<CopyLink element={condition} verboseName={verboseName} onClick={fetchCopy} />
<LockedLink element={condition} verboseName={verboseName} onClick={toggleLocked} />
<ExportLink element={condition} verboseName={verboseName} />
<ExportLink element={condition} elementType="conditions" verboseName={verboseName}
exportFormats={config.settings.export_formats} />
</div>
<div>
<p>
Expand Down
3 changes: 2 additions & 1 deletion rdmo/management/assets/js/components/element/Option.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ const Option = ({ config, option, elementActions, display='list', indent=0, filt
<EditLink element={option} verboseName={verboseName} onClick={fetchEdit} />
<CopyLink element={option} verboseName={verboseName} onClick={fetchCopy} />
<LockedLink element={option} verboseName={verboseName} onClick={toggleLocked} />
<ExportLink element={option} verboseName={verboseName} />
<ExportLink element={option} elementType="options" verboseName={verboseName}
exportFormats={config.settings.export_formats} />
</div>
<div>
<p>
Expand Down
3 changes: 2 additions & 1 deletion rdmo/management/assets/js/components/element/OptionSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ const OptionSet = ({ config, optionset, elementActions, display='list', filter=n
<CopyLink element={optionset} verboseName={verboseName} onClick={fetchCopy} />
<AddLink element={optionset} verboseName={gettext('option')} onClick={createOption} />
<LockedLink element={optionset} verboseName={verboseName} onClick={toggleLocked} />
<ExportLink element={optionset} verboseName={verboseName} />
<ExportLink element={optionset} elementType="optionsets" verboseName={verboseName}
exportFormats={config.settings.export_formats} />
</div>
<div>
<p>
Expand Down
3 changes: 2 additions & 1 deletion rdmo/management/assets/js/components/element/Page.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ const Page = ({ config, page, elementActions, display='list', filter=null, inden
<AddLink element={page} verboseName={gettext('question')} verboseNameAlt={gettext('question set')}
onClick={createQuestion} onAltClick={createQuestionSet} />
<LockedLink element={page} verboseName={verboseName} onClick={toggleLocked} />
<ExportLink element={page} verboseName={verboseName} />
<ExportLink element={page} elementType="pages" verboseName={verboseName}
exportFormats={config.settings.export_formats} />
</div>
<div>
<p>
Expand Down
3 changes: 2 additions & 1 deletion rdmo/management/assets/js/components/element/Question.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ const Question = ({ config, question, elementActions, display='list', filter=nul
<EditLink element={question} verboseName={verboseName} onClick={fetchEdit} />
<CopyLink element={question} verboseName={verboseName} onClick={fetchCopy} />
<LockedLink element={question} verboseName={verboseName} onClick={toggleLocked} />
<ExportLink element={question} verboseName={verboseName} />
<ExportLink element={question} elementType="questions" verboseName={verboseName}
exportFormats={config.settings.export_formats} />
</div>
<div>
<p>
Expand Down
3 changes: 2 additions & 1 deletion rdmo/management/assets/js/components/element/QuestionSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ const QuestionSet = ({ config, questionset, elementActions, display='list', filt
<AddLink element={questionset} verboseName={gettext('question')} verboseNameAlt={gettext('question set')}
onClick={createQuestion} onAltClick={createQuestionSet} />
<LockedLink element={questionset} verboseName={verboseName} onClick={toggleLocked} />
<ExportLink element={questionset} verboseName={verboseName} />
<ExportLink element={questionset} elementType="questionsets" verboseName={verboseName}
exportFormats={config.settings.export_formats} />
</div>
<div>
<p>
Expand Down
3 changes: 2 additions & 1 deletion rdmo/management/assets/js/components/element/Section.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ const Section = ({ config, section, elementActions, display='list', filter=null,
<CopyLink element={section} verboseName={verboseName} onClick={fetchCopy} />
<AddLink element={section} verboseName={gettext('page')} onClick={createPage} />
<LockedLink element={section} verboseName={verboseName} onClick={toggleLocked} />
<ExportLink element={section} verboseName={verboseName} />
<ExportLink element={section} elementType="sections" verboseName={verboseName}
exportFormats={config.settings.export_formats} />
</div>
<div>
<p>
Expand Down
3 changes: 2 additions & 1 deletion rdmo/management/assets/js/components/element/Task.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const Task = ({ config, task, elementActions, filter=null }) => {
<CopyLink element={task} verboseName={verboseName} onClick={fetchCopy} />
<AvailableLink element={task} verboseName={verboseName} onClick={toggleAvailable} />
<LockedLink element={task} verboseName={verboseName} onClick={toggleLocked} />
<ExportLink element={task} verboseName={verboseName} />
<ExportLink element={task} elementType="tasks" verboseName={verboseName}
exportFormats={config.settings.export_formats} />
</div>
<div>
<p>
Expand Down
3 changes: 2 additions & 1 deletion rdmo/management/assets/js/components/element/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const View = ({ config, view, elementActions, filter=null }) => {
<CopyLink element={view} verboseName={verboseName} onClick={fetchCopy} />
<AvailableLink element={view} verboseName={verboseName} onClick={toggleAvailable} />
<LockedLink element={view} verboseName={verboseName} onClick={toggleLocked} />
<ExportLink element={view} verboseName={verboseName} />
<ExportLink element={view} elementType="views" verboseName={verboseName}
exportFormats={config.settings.export_formats} />
</div>
<div>
<p>
Expand Down
13 changes: 13 additions & 0 deletions rdmo/options/templates/options/export/option.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{% load i18n %}

<li>
<p>
<strong>{% trans 'URI' %}:</strong> {{ option.uri }}
</p>
<p>
<strong>{% trans 'Text' %}:</strong> {{ option.text }}
</p>
<p>
<strong>{% trans 'Additional input' %}:</strong> {{ option.additional_input }}
</p>
</li>
14 changes: 14 additions & 0 deletions rdmo/options/templates/options/export/options.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{% extends 'core/export.html' %}
{% load i18n %}

{% block body %}

<h1>{% trans 'Options' %}</h1>

<ul>
{% for option in options %}
{% include 'options/export/option.html' with option=option %}
{% endfor %}
</ul>

{% endblock %}
41 changes: 41 additions & 0 deletions rdmo/options/templates/options/export/optionset.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{% load i18n %}

<li>
<p>
<strong>{% trans 'URI' %}:</strong> {{ optionset.uri }}
</p>

<p>
<strong>{% trans 'Options' %}:</strong>
</p>

<ul>
{% for option in optionset.elements %}
{% include 'options/export/option.html' with option=option %}
{% endfor %}
</ul>

{% if optionset.provider_key %}

<p>
<strong>{% trans 'Provider' %}:</strong> {{ optionset.provider.label }}
</p>

{% endif %}

{% if optionset.conditions.all %}

<p>
<strong>{% trans 'Conditions' %}:</strong>
</p>

<ul>
{% for condition in optionset.conditions.all %}
<li>
{{ condition.source_label }} {{ condition.relation_label }} {{ condition.target_label }}
</li>
{% endfor %}
</ul>

{% endif %}
</li>
14 changes: 14 additions & 0 deletions rdmo/options/templates/options/export/optionsets.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{% extends 'core/export.html' %}
{% load i18n %}

{% block body %}

<h1>{% trans 'Option sets' %}</h1>

<ul>
{% for optionset in optionsets %}
{% include 'options/export/optionset.html' with optionset=optionset %}
{% endfor %}
</ul>

{% endblock %}

0 comments on commit e1ba817

Please sign in to comment.