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 %}
{%trans "Admninistrative acts"%}
@@ -66,53 +61,59 @@
{{act.signature_date.year}} |
{{act.ref_sra}} |
- {{act.act_type}} |
+ {{act.act_type}} |
{{act.signature_date}} |
+ {% empty %}
+ {% trans "No administrative act associated to this archaelogical file" %} |
{% endfor %}
-{%endif%}
-{% comment %}
-
-
-
- {%trans "Associated operations"%}
-
- {% for label, in item.data_ope %}
- {{label}} |
- {% endfor %}
-
- {% for data, in item.data_ope %}
-
- {{year}} |
- {{reference}} |
- {{patriarche}} |
- {{type}} |
- {{head_scientist}} |
- {{date_debut}} |
- {{date_fin}} |
- {{link_to_ope_sheet}} |
-
- {% endfor %}
-
-
-
-
- {%trans "Admninistrative acts linked to associated operations"%}
-
- {% for label, in item.ope.data_acts %}
- {{label}} |
- {% endfor %}
-
- {% for data, in item.ope.data_acts %}
-
- {{year}} |
- {{reference}} |
- {{type}} |
- {{date}} |
-
- {% endfor %}
-
-{% endcomment %}
+
+ {%trans "Associated operations"%}
+
+ {% trans "Year" %} |
+ {% trans "Reference" %} |
+ Code Patriarche |
+ {% trans "Type" %} |
+ {% trans "In charge" %} |
+ {% trans "Start date" %} |
+ {% trans "End date" %} |
+ |
+
+ {% for operation in item.operations.all %}
+
+ {{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" %} |
+
+ {% empty %}
+ {% trans "No operation associated to this archaelogical file" %} |
+ {% endfor %}
+
+
+
+ {%trans "Admninistrative acts linked to associated operations"%}
+
+ {% trans "Year" %} |
+ {% trans "Reference" %} |
+ {% trans "Type" %} |
+ {% trans "Date" %} |
+
+ {% for act in item.operation_acts %}
+
+ {{act.signature_date.year}} |
+ {{act.ref_sra}} |
+ {{act.act_type}} |
+ {{act.signature_date}} |
+
+ {% empty %}
+ {% trans "No administrative act linked to operations" %} |
+ {% endfor %}
+
{% 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