Commit a9f418ed authored by Remi Rampin's avatar Remi Rampin

Merge branch 'export-xml' into 'master'

Add REFI-QDA Codebook (.qdc) export format

See merge request !43
parents 80fe1ad5 c8afa850
Pipeline #66383134 passed with stage
in 2 minutes and 4 seconds
......@@ -47,6 +47,7 @@
{% trans %}Export codebook{% endtrans %}
</button>
<div class="dropdown-menu" aria-labelledby="dropdown-codebook">
<a href="{{ reverse_url('export_codebook_qdc', project.id) }}" class="dropdown-item">QDC (XML)</a>
<a href="{{ reverse_url('export_codebook_csv', project.id) }}" class="dropdown-item">CSV</a>
<a href="{{ reverse_url('export_codebook_doc', project.id, 'html') }}" class="dropdown-item">HTML</a>
<a href="{{ reverse_url('export_codebook_doc', project.id, 'docx') }}" class="dropdown-item">DOCX</a>
......
......@@ -76,6 +76,8 @@ def make_app(config, debug=False, xsrf_cookies=True):
name='project_tag'),
# Export options
URLSpec('/project/([0-9]+)/export/codebook.qdc',
export.ExportCodebookXml, name='export_codebook_qdc'),
URLSpec('/project/([0-9]+)/export/codebook.csv',
export.ExportCodebookCsv, name='export_codebook_csv'),
URLSpec('/project/([0-9]+)/export/codebook.([a-z0-3]{2,4})',
......
......@@ -2,12 +2,16 @@ import bisect
import csv
import io
import logging
import uuid
from xml.sax.saxutils import XMLGenerator
from xml.sax.xmlreader import AttributesNSImpl
from markupsafe import Markup
import prometheus_client
from sqlalchemy.orm import aliased, joinedload
from tornado.web import authenticated
from .. import convert
from .. import convert, __version__
from .. import database
from .. import extract
from .base import BaseHandler
......@@ -16,6 +20,17 @@ from .base import BaseHandler
logger = logging.getLogger(__name__)
TAGUETTE_NAMESPACE = uuid.UUID('51B2B2B7-27EB-4ECB-9D56-E75B0A0496C2')
class WriteAdapter(object):
def __init__(self, write_func):
self.write = write_func
def flush(self):
pass
PROM_EXPORT = prometheus_client.Counter(
'export_total',
"Export",
......@@ -136,6 +151,57 @@ class ExportDocument(BaseHandler):
return name, html
class ExportCodebookXml(BaseHandler):
PROM_EXPORT.labels('codebook', 'qdc').inc(0)
@authenticated
def get(self, project_id):
PROM_EXPORT.labels('codebook', 'qdc').inc()
project, _ = self.get_project(project_id)
tags = list(project.tags)
self.set_header('Content-Type', 'text/xml; charset=utf-8')
self.set_header('Content-Disposition',
'attachment; filename="codebook.qdc"')
# http://schema.qdasoftware.org/versions/Codebook/v1.0/Codebook.xsd
output = XMLGenerator(WriteAdapter(self.write), encoding='utf-8',
short_empty_elements=True)
output.startDocument()
output.startPrefixMapping(None, 'urn:QDA-XML:codebook:1.0')
output.startElementNS(
(None, 'CodeBook'), 'CodeBook',
AttributesNSImpl({(None, 'origin'): 'Taguette %s' % __version__},
{(None, 'origin'): 'origin'}),
)
output.startElementNS(
(None, 'Codes'), 'Codes',
AttributesNSImpl({}, {}),
)
for tag in tags:
guid = uuid.uuid5(TAGUETTE_NAMESPACE, tag.path)
guid = str(guid).upper()
output.startElementNS(
(None, 'Code'), 'Code',
AttributesNSImpl({(None, 'guid'): guid,
(None, 'name'): tag.path,
(None, 'isCodable'): 'true'},
{(None, 'guid'): 'guid',
(None, 'name'): 'name',
(None, 'isCodable'): 'isCodable'}),
)
output.endElementNS((None, 'Code'), 'Code')
output.endElementNS((None, 'Codes'), 'Codes')
output.startElementNS(
(None, 'Sets'), 'Sets',
AttributesNSImpl({}, {}),
)
output.endElementNS((None, 'Sets'), 'Sets')
output.endElementNS((None, 'CodeBook'), 'CodeBook')
output.endPrefixMapping(None)
output.endDocument()
return self.finish()
class ExportCodebookCsv(BaseHandler):
PROM_EXPORT.labels('codebook', 'csv').inc(0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment