From 8301e4705fccdf557d5d9e57eb32f9ba66c663b8 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 25 Feb 2011 15:58:32 +0100 Subject: Work on file sheet and odt export (refs #227) --- .gitignore | 1 + docs/src/INSTALL.t2t | 3 +- ishtar/__init__.py | 5 +- ishtar/furnitures/models.py | 9 +- ishtar/furnitures/urls.py | 5 +- ishtar/furnitures/views.py | 62 ++++++++++++- ishtar/settings.py.example | 2 + ishtar/templates/sheet.html | 16 ++++ ishtar/templates/sheet_file.html | 151 ++++++++++++++++---------------- ishtar/templates/sheet_file_window.html | 3 + static/media/style.css | 15 +++- static/template.odt | Bin 0 -> 7013 bytes 12 files changed, 185 insertions(+), 87 deletions(-) create mode 100644 ishtar/templates/sheet_file_window.html create mode 100644 static/template.odt diff --git a/.gitignore b/.gitignore index d79b2cf6f..e282b5668 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ *.mo django-simple-history/* django-formwizard/* +xhtml2odt ishtar-docs ishtar-logo diff --git a/docs/src/INSTALL.t2t b/docs/src/INSTALL.t2t index 8f28ac8fd..c485f0d96 100644 --- a/docs/src/INSTALL.t2t +++ b/docs/src/INSTALL.t2t @@ -29,7 +29,8 @@ cd django-simple-history python setup.py install ``` - +git clone git://gitorious.org/xhtml2odt/xhtml2odt.git +INSTALL_PATH = "/home/etienne/work/ishtar/xhtml2odt" Import towns: curl --location --globoff "http://openstreetmap.us/xapi/api/0.6/node[place=village|town|city][bbox=-5.53711,41.90228,8.96484,51.50874]" -o data.osm diff --git a/ishtar/__init__.py b/ishtar/__init__.py index 128bebf23..d9bcb5701 100644 --- a/ishtar/__init__.py +++ b/ishtar/__init__.py @@ -2,4 +2,7 @@ from django.utils.translation import ugettext as _ _("username") _("email address") - +if settings.XHTML2ODT_PATH: + import sys + sys.path.append(settings.XHTML2ODT_PATH) + from xhtml2odt import xhtml2odt diff --git a/ishtar/furnitures/models.py b/ishtar/furnitures/models.py index 3b73baba0..ce94e4042 100644 --- a/ishtar/furnitures/models.py +++ b/ishtar/furnitures/models.py @@ -237,7 +237,7 @@ class Person(Address, OwnPerms) : return lbl def full_label(self): - return " ".join([getattr(self, attr) + return u" ".join([unicode(getattr(self, attr)) for attr in ('title', 'surname', 'name', 'attached_to') if getattr(self, attr)]) @@ -360,6 +360,11 @@ class File(BaseHistorizedItem, OwnPerms): if self.total_developed_surface: return self.total_developed_surface/10000.0 + def operation_acts(self): + return [act for act in + [ope.administrative_act.all() for ope in self.operations.all()] + ] + def is_preventive(self): return FileType.is_preventive(self.file_type.pk) @@ -391,7 +396,7 @@ class Operation(BaseHistorizedItem, OwnPerms): blank=True, verbose_name=_(u"In charge")) year = models.IntegerField(_(u"Year")) operation_code = models.IntegerField(_(u"Operation code")) - associated_file = models.ForeignKey(File, related_name='+', + associated_file = models.ForeignKey(File, related_name='operations', verbose_name=_(u"File"), blank=True, null=True) operation_type = models.ForeignKey(OperationType, related_name='+', verbose_name=_(u"Operation type")) diff --git a/ishtar/furnitures/urls.py b/ishtar/furnitures/urls.py index 5123609fc..c93f14c78 100644 --- a/ishtar/furnitures/urls.py +++ b/ishtar/furnitures/urls.py @@ -87,13 +87,14 @@ urlpatterns += patterns('ishtar.furnitures.views', name='autocomplete-file'), url(BASE_URL + r'get-file/(?P.+)?$', 'get_file', name='get-file'), - url(BASE_URL + r'show-file/(?P.+)?$', 'show_file', + url(BASE_URL + r'show-file/(?P.+)?/(?P.+)?$', 'show_file', name='show-file'), url(BASE_URL + r'autocomplete-operation/$', 'autocomplete_operation', name='autocomplete-operation'), url(BASE_URL + r'get-operation/(?P.+)?$', 'get_operation', name='get-operation'), - url(BASE_URL + r'show-operation/(?P.+)?$', 'show_operation', + url(BASE_URL + r'show-operation/(?P.+)?/(?P.+)?$', + 'show_operation', name='show-operation'), url(BASE_URL + r'update-current-item/$', 'update_current_item', name='update-current-item'), diff --git a/ishtar/furnitures/views.py b/ishtar/furnitures/views.py index 8511022a4..34d5c4655 100644 --- a/ishtar/furnitures/views.py +++ b/ishtar/furnitures/views.py @@ -24,9 +24,12 @@ Furnitures views import csv import json import datetime +import optparse +from tempfile import NamedTemporaryFile from django.http import HttpResponse, Http404 -from django.template import RequestContext +from django.template import RequestContext, loader +from django.template.defaultfilters import slugify from django.shortcuts import render_to_response, redirect from django.utils.translation import ugettext, ugettext_lazy as _ from django.core.exceptions import ObjectDoesNotExist @@ -35,6 +38,11 @@ from django.db.models import Q from django.core import serializers from ishtar import settings +if settings.XHTML2ODT_PATH: + import sys + sys.path.append(settings.XHTML2ODT_PATH) + from xhtml2odt import xhtml2odt + from menus import menu import forms as ishtar_forms import models @@ -190,7 +198,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[]): for data in datas: res = {'id':data[0], 'link':link_template % reverse('show-'+default_name, - args=[data[0]])} + args=[data[0], ''])} for idx, value in enumerate(data[1:]): if value: res[model.TABLE_COLS[idx].split('.')[-1]] = value @@ -229,9 +237,55 @@ def show_item(model, name): item = model.objects.get(pk=pk) except ObjectDoesNotExist: return HttpResponse(None) + doc_type = 'type' in dct and dct.pop('type') dct['item'] = item - return render_to_response('sheet_%s.html' % name, dct, - context_instance=RequestContext(request)) + context_instance = RequestContext(request) + context_instance.update(dct) + if doc_type == "odt" and settings.XHTML2ODT_PATH and \ + settings.ODT_TEMPLATE: + tpl = loader.get_template('sheet_%s.html' % name) + content = tpl.render(context_instance) + try: + ht, odt = NamedTemporaryFile(), NamedTemporaryFile() + ht.write(content.encode('utf-8')) + options = optparse.Values() + options.input = ht.name + options.output = odt.name + options.template = settings.ODT_TEMPLATE + options.with_network = True + for k, v in (('input', ht.name), + ('output', None), + ('template', settings.ODT_TEMPLATE), + ('with_network', True), + ('top_header_level', 1), + ('img_width', '8cm'), + ('img_height', '6cm'), + ('verbose', False), + ('replace_keyword', 'ODT-INSERT'), + ('cut_start', 'ODT-CUT-START'), + ('htmlid', None), + ('url', "#")): + setattr(options, k, v) + htmlfile = xhtml2odt.HTMLFile(options) + htmlfile.read() + odtfile = xhtml2odt.ODTFile(options) + odtfile.open() + odtfile.import_xhtml(htmlfile.html) + hop = odtfile.save() + except xhtml2odt.ODTExportError, ex: + return HttpResponse(content, content_type="application/xhtml") + response = HttpResponse( + mimetype='application/vnd.oasis.opendocument.text') + n = datetime.datetime.now() + filename = u'%s_%s_%s.odt' % (name, slugify(unicode(item)), + n.strftime('%Y%m%d-%H%M%S')) + response['Content-Disposition'] = 'attachment; filename=%s'%filename + response.write(hop) + return response + else: + tpl = loader.get_template('sheet_%s_window.html' % name) + content = tpl.render(context_instance) + return HttpResponse(content, content_type="application/xhtml") return func get_file = get_item(models.File, 'get_file', 'file') diff --git a/ishtar/settings.py.example b/ishtar/settings.py.example index 99017d049..4b3388389 100644 --- a/ishtar/settings.py.example +++ b/ishtar/settings.py.example @@ -11,6 +11,8 @@ ROOT_PATH = "/var/local/webapp/ishtar/ishtar/" URL_PATH = "" JQUERY_URL = "/javascript/jquery/jquery.js" JQUERY_UI_URL = "/javascript/jquery-ui/" +XHTML2ODT_PATH = ROOT_PATH + "../xhtml2odt" +ODT_TEMPLATE = ROOT_PATH + "../static/template.odt" LOGIN_REDIRECT_URL = "/" + URL_PATH DEBUG = True diff --git a/ishtar/templates/sheet.html b/ishtar/templates/sheet.html index 9d1305c1d..a93b193e0 100644 --- a/ishtar/templates/sheet.html +++ b/ishtar/templates/sheet.html @@ -1,7 +1,23 @@ {% load i18n %} +{% block main_head %} + + + + + {% block title %}Ishtar{% if APP_NAME %} - {{APP_NAME}}{%endif%}{% endblock %} + + + + +{% endblock %}
{% block content %}{% endblock %}
+{%block main_foot%} + + +{%endblock%} diff --git a/ishtar/templates/sheet_file.html b/ishtar/templates/sheet_file.html index 57f1c00fc..ea0fc20bd 100644 --- a/ishtar/templates/sheet_file.html +++ b/ishtar/templates/sheet_file.html @@ -2,58 +2,53 @@ {% load i18n %} {% block content %}

{% trans "General"%}

-

{{ item.year }}

-

{{ item.numeric_reference }}

+

{{ item.year }}

+

{{ item.numeric_reference }}

-

{{ item.internal_reference }}

+

{{ item.internal_reference }}

-

{{ item.history.all.0.history_date }}

-{% if item.reception_date %}

{{ item.reception_date }}

{% endif %} -

{{ item.creation_date }}

+

{{ item.history.all.0.history_date }}

+{% if item.reception_date %}

{{ item.reception_date }}

{% endif %} +

{{ item.creation_date }}

{% comment %} {% if item.deadline_date and not item.acts %} -

{%trans "Deadline"%} : {% item.deadline_date %}

+

{% item.deadline_date %}

{% endif %} {% endcomment %} -

{{ item.in_charge.full_label }}

-

-{% if item.is_active %}{%trans "Active file"%}

-{% else %}{%trans "Closed file"%}

-

{{ item.closing.date }} {%trans "by" %} {{ item.closing.user }}

+

{{ item.in_charge.full_label }}

+

{% if item.is_active %}{%trans "Active file"%}

+{% else %}{%trans "Closed file"%}

+

{{ item.closing.date }} {%trans "by" %} {{ item.closing.user }}

{% endif %} -

{{ item.file_type }}

+

{{ item.file_type }}

-{% if item.related_file %}

{%trans "Related file:"%} {{ item.related_file }}

{% endif %} -

{{ item.comment }}

+{% if item.related_file %}

{{ item.related_file }}

{% endif %} +{% if item.comment %}

{{ item.comment }}

{%endif%}

{% trans "Localisation"%}

-

{{ item.towns.all|join:", " }}

+

{{ item.towns.all|join:", " }}

-

{{ item.address }}

-

{{ item.complem_adress }}

-

{{ item.postal_code }}

+

{{ item.address }}

+{% if item.address_complement %}

{{ item.address_complement }}

{%endif%} +{% if item.postal_code %}

{{ item.postal_code }}

{%endif%} -

{{ item.total_surface }} m2 ({{ item.total_surface_ha }} ha)

+

{{ item.total_surface }} m2 ({{ item.total_surface_ha }} ha)

{% if item.is_preventive %}

{% trans "Preventive archaelogical file"%}

-

{{ item.total_developed_surface }} m2 ({{ item.total_developed_surface_ha }} ha)

-

{{ item.saisine_type }}

-{% if item.town_planning_service %}

{{ item.town_planning_service }}

{% endif %} -{% if item.permit_type %}

{{ item.permit_type }}

{% endif %} -{% if item.permit_reference %}

{{ item.permit_reference }}

{% endif %} -{% if item.general_contractor.attached_to %}

{{ item.general_contractor.attached_to }}

{% endif %} -{% if item.general_contractor %}

{{ item.general_contractor.full_label }}

{% endif %} -{% comment %} -

{%trans "Numerical reference"%} : {% item.index %}

-{% endcomment %} +

{{ item.total_developed_surface }} m2 ({{ item.total_developed_surface_ha }} ha)

+

{{ item.saisine_type }}

+{% if item.town_planning_service %}

{{ item.town_planning_service }}

{% endif %} +{% if item.permit_type %}

{{ item.permit_type }}

{% endif %} +{% if item.permit_reference %}

{{ item.permit_reference }}

{% endif %} +{% if item.general_contractor.attached_to %}

{{ item.general_contractor.attached_to }}

{% endif %} +{% if item.general_contractor %}

{{ item.general_contractor.full_label }}

{% endif %} {% endif %} -{% if item.administrative_act.all %} @@ -66,53 +61,59 @@ - + + {% empty %} + {% endfor %}
{%trans "Admninistrative acts"%}
{{act.signature_date.year}} {{act.ref_sra}}{{act.act_type}}{{act.act_type}} {{act.signature_date}}
{% trans "No administrative act associated to this archaelogical file" %}
-{%endif%} -{% comment %} - - - - - - {% for label, in item.data_ope %} - - {% endfor %} - - {% for data, in item.data_ope %} - - - - - - - - - - - {% endfor %} -
{%trans "Associated operations"%}
{{label}}
{{year}}{{reference}}{{patriarche}}{{type}}{{head_scientist}}{{date_debut}}{{date_fin}}{{link_to_ope_sheet}}
- - - - - - {% for label, in item.ope.data_acts %} - - {% endfor %} - - {% for data, in item.ope.data_acts %} - - - - - - - {% endfor %} -
{%trans "Admninistrative acts linked to associated operations"%}
{{label}}
{{year}}{{reference}}{{type}}{{date}}
-{% endcomment %} + + + + + + + + + + + + + {% for operation in item.operations.all %} + + + + + + + + + + + {% empty %} + + {% endfor %} +
{%trans "Associated operations"%}
{% trans "Year" %}{% trans "Reference" %}Code Patriarche{% trans "Type" %}{% trans "In charge" %}{% trans "Start date" %}{% trans "End date" %}
{{operation.year}}{{operation.operation_code}}{{operation.code_patriarche|default:""}}{{operation.operation_type}}{{operation.in_charge|default:""}}{{operation.start_date|default:""}}{{operation.end_date|default:""}}{% trans "Details" %}
{% trans "No operation associated to this archaelogical file" %}
+ + + + + + + + + + {% for act in item.operation_acts %} + + + + + + + {% empty %} + + {% endfor %} +
{%trans "Admninistrative acts linked to associated operations"%}
{% trans "Year" %}{% trans "Reference" %}{% trans "Type" %}{% trans "Date" %}
{{act.signature_date.year}}{{act.ref_sra}}{{act.act_type}}{{act.signature_date}}
{% trans "No administrative act linked to operations" %}
{% endblock %} diff --git a/ishtar/templates/sheet_file_window.html b/ishtar/templates/sheet_file_window.html new file mode 100644 index 000000000..e9debdd0d --- /dev/null +++ b/ishtar/templates/sheet_file_window.html @@ -0,0 +1,3 @@ +{% extends "sheet_file.html" %} +{% block main_head %}{%endblock%} +{% block main_foot %}{%endblock%} diff --git a/static/media/style.css b/static/media/style.css index 5e5613cfc..f4dd8ddc9 100644 --- a/static/media/style.css +++ b/static/media/style.css @@ -20,7 +20,7 @@ caption, h3 { h3{ text-align:center; - margin:1em 0; + margin:1em 0 0.5em 0; } label{display:block} @@ -264,6 +264,7 @@ table.confirm tr.spacer td:last-child{ } #window table{ + font-size:0.9em; margin:10px 0; width:100%; border-collapse:collapse; @@ -279,12 +280,17 @@ table.confirm tr.spacer td:last-child{ border:1px solid #EEE; color:#FFF; } + #window table td{ text-align:right; padding:0 1em; border:1px solid #EEE; } +#window table td.string{ + text-align:left; +} + #window .sheet{ } @@ -311,7 +317,12 @@ table.confirm tr.spacer td:last-child{ #window label{ display:inline-table; font-weight:bold; - width:160px; + width:240px; +} + +#window span.value{ + display:inline-table; + width:470px; } #window p{ diff --git a/static/template.odt b/static/template.odt new file mode 100644 index 000000000..d1d0515bf Binary files /dev/null and b/static/template.odt differ -- cgit v1.2.3