diff options
Diffstat (limited to 'ishtar/ishtar_base/views.py')
| -rw-r--r-- | ishtar/ishtar_base/views.py | 1333 |
1 files changed, 0 insertions, 1333 deletions
diff --git a/ishtar/ishtar_base/views.py b/ishtar/ishtar_base/views.py deleted file mode 100644 index 4a7f276fb..000000000 --- a/ishtar/ishtar_base/views.py +++ /dev/null @@ -1,1333 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (C) 2010-2011 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. - -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -# See the file COPYING for details. - -try: - import tidy -except: - from tidylib import tidy_document as tidy - -import re -import csv -import json -import datetime -import optparse -import cStringIO as StringIO -from tempfile import NamedTemporaryFile -import ho.pisa as pisa - -from django.contrib.formtools.wizard.views import NamedUrlWizardView -from django.core import serializers -from django.core.exceptions import ObjectDoesNotExist -from django.core.urlresolvers import reverse, NoReverseMatch -from django.db.models import Q -from django.http import HttpResponse, Http404 -from django.shortcuts import render_to_response, redirect -from django.template import RequestContext, loader -from django.template.defaultfilters import slugify -from django.utils.translation import ugettext, ugettext_lazy as _ - -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_main as ishtar_forms - -from ishtar.ishtar_base.forms import FinalForm -from ishtar.ishtar_base.forms_common import PersonForm -import models - -CSV_OPTIONS = {'delimiter':';', 'quotechar':'"', 'quoting':csv.QUOTE_ALL} -ENCODING = settings.ENCODING or 'utf-8' - -def index(request): - """ - Main page - """ - dct = {} - return render_to_response('index.html', dct, - context_instance=RequestContext(request)) - -class Wizard(NamedUrlWizardView): - model = None - modification = None # True when the wizard modify an item - storage_name = 'django.contrib.formtools.wizard.storage.session.SessionStorage' - - @staticmethod - def _check_right(step, condition=True): - '''Return a method to check the right for a specific step''' - """ - def check_right(self, request, storage): - cond = condition - if callable(condition): - cond = condition(self, request, storage) - if not cond: - return False - person_type = request.user.ishtaruser.person.person_type - if person_type.txt_idx == 'administrator': - return True - if person_type.rights.filter(url_name=step).count(): - return True""" - def check_right(self): - cond = condition - if callable(condition): - cond = condition(self) - if not cond: - return False - person_type = self.request.user.ishtaruser.person.person_type - if person_type.txt_idx == 'administrator': - return True - if person_type.rights.filter(url_name=step).count(): - return True - return check_right - - def __init__(self, *args, **kwargs): - """Check right for each step of the wizard""" - super(Wizard, self).__init__(*args, **kwargs) - for form_key in self.form_list.keys()[:-1]: - condition = True - if form_key in self.condition_dict: - condition = self.condition_dict.get(form_key, True) - cond = self._check_right(form_key, condition) - self.condition_dict[form_key] = cond - """ - for form_key in self.form_list.keys()[:-1]: - condition = True - if form_key in self.condition_list: - condition = self.condition_list.get(form_key, True) - cond = self._check_right(form_key, condition) - self.condition_list[form_key] = cond""" - - def get_wizard_name(self): - """As the class name can interfere when reused, use the url_name""" - return self.url_name - - def get_template_names(self): - templates = ['ishtar/wizard/default_wizard.html'] - current_step = self.steps.current - if current_step == self.steps.last: - templates = ['ishtar/wizard/confirm_wizard.html'] + templates - return templates - - def get_context_data(self, form, **kwargs): - """Add previous, next and current steps to manage the wizard path""" - context = super(Wizard, self).get_context_data(form) - step = self.steps.first - current_step = self.steps.current - context.update({'current_step':self.form_list[current_step]}) - if step == current_step: - return context - previous_steps, next_steps, previous_step_counter = [], [], 0 - while step: - if step == current_step: - break - previous_steps.append(self.form_list[step]) - step = self.steps.next - previous_step_counter += 1 - context.update({'previous_steps':previous_steps, - 'previous_step_counter':previous_step_counter}) - # if modification: show the next steps - if self.modification: - next_step = step - while next_step: - # check if the form is initialized otherwise initialize it - if not storage.get_step_data(next_step): - values = self.get_form_initial(request, storage, next_step) - prefixed_values = {} - if not isinstance(values, list): - for key in values: - form_key = next_step + '-' + key - prefixed_values[form_key] = values[key] - else: - for formset_idx, v in enumerate(values): - prefix = u"-%d-" % formset_idx - for key in v: - form_key = next_step + prefix + key - prefixed_values[form_key] = v[key] - storage.set_step_data(next_step, prefixed_values) - if step != next_step: # if not current step - next_steps.append(self.form_list[next_step]) - next_step = self.get_next_step(request, storage, next_step) - context.update({'next_steps':next_steps}) - # not last step: validation - if current_step != self.steps.last: - return context - final_form_list = [] - for form_key in self.get_form_list().keys(): - form_obj = self.get_form(step=form_key, - data=self.storage.get_step_data(form_key), - files=self.storage.get_step_files(form_key)) - form_obj.is_valid() - final_form_list.append(form_obj) - last_form = final_form_list[-1] - context.update({'datas':self.get_formated_datas(final_form_list)}) - if hasattr(last_form, 'confirm_msg'): - context.update({'confirm_msg':last_form.confirm_msg}) - if hasattr(last_form, 'confirm_end_msg'): - context.update({'confirm_end_msg':last_form.confirm_end_msg}) - return context - - def get_formated_datas(self, forms): - """Get the data to present in the last page""" - datas = [] - for form in forms: - form_datas = [] - base_form = hasattr(form, 'forms') and form.forms[0] or form - associated_models = hasattr(base_form, 'associated_models') and \ - base_form.associated_models or {} - if not hasattr(form, 'cleaned_data') and hasattr(form, 'forms'): - cleaned_datas = [frm.cleaned_data for frm in form.forms - if frm.is_valid()] - if not cleaned_datas: - continue - elif not hasattr(form, 'cleaned_data'): - continue - else: - cleaned_datas = type(form.cleaned_data) == list and \ - form.cleaned_data \ - or [form.cleaned_data] - for cleaned_data in cleaned_datas: - if not cleaned_data: - continue - if form_datas: - form_datas.append(("", "", "spacer")) - items = hasattr(base_form, 'fields') and \ - base_form.fields.keyOrder or cleaned_data.keys() - for key in items: - lbl = None - if key.startswith('hidden_'): - continue - if hasattr(base_form, 'fields') and key in base_form.fields: - lbl = base_form.fields[key].label - if hasattr(base_form, 'associated_labels') \ - and key in base_form.associated_labels: - lbl = base_form.associated_labels[key] - if not lbl: - continue - value = cleaned_data[key] - if not value and value != False: - continue - if type(value) == bool: - if value == True: - value = _(u"Yes") - elif value == False: - value = _(u"No") - elif key in associated_models: - values = [] - if "," in unicode(value): - values = unicode(value).split(",") - else: - values = [value] - rendered_values = [] - for val in values: - item = associated_models[key].objects.get(pk=val) - if hasattr(item, 'short_label'): - value = item.short_label() - else: - value = unicode(item) - rendered_values.append(value) - value = u" ; ".join(rendered_values) - form_datas.append((lbl, value, '')) - if form_datas: - datas.append((form.form_label, form_datas)) - return datas - - def get_extra_model(self, dct, form_list): - dct['history_modifier'] = self.request.user - return dct - - def done(self, form_list, return_object=False, **kwargs): - """Save to the model""" - dct, m2m, whole_associated_models = {}, [], [] - for form in form_list: - if not form.is_valid(): - return self.render(form) - base_form = hasattr(form, 'forms') and form.forms[0] or form - associated_models = hasattr(base_form, 'associated_models') and \ - base_form.associated_models or {} - if hasattr(form, 'forms'): - multi = False - if form.forms: - frm = form.forms[0] - if hasattr(frm, 'base_model') and frm.base_model: - whole_associated_models.append(frm.base_model) - else: - whole_associated_models += associated_models.keys() - fields = frm.fields.copy() - if 'DELETE' in fields: - fields.pop('DELETE') - multi = len(fields) > 1 - if multi: - assert hasattr(frm, 'base_model'), \ - u"Must define a base_model for " + unicode(frm.__class__) - for frm in form.forms: - if not frm.is_valid(): - continue - vals = {} - if "DELETE" in frm.cleaned_data: - if frm.cleaned_data["DELETE"]: - continue - frm.cleaned_data.pop('DELETE') - for key in frm.cleaned_data: - value = frm.cleaned_data[key] - if not value and value != False: - continue - if key in associated_models: - value = associated_models[key].objects.get(pk=value) - if multi: - vals[key] = value - else: - m2m.append((key, value)) - if multi and vals: - m2m.append((frm.base_model, vals)) - elif type(form.cleaned_data) == dict: - for key in form.cleaned_data: - if key.startswith('hidden_'): - continue - value = form.cleaned_data[key] - if key in associated_models: - if value: - model = associated_models[key] - if isinstance(value, unicode) \ - or isinstance(value, str) and "," in value: - value = value.split(",") - if isinstance(value, list) \ - or isinstance(value, tuple): - value = [model.objects.get(pk=val) - for val in value if val] - if len(value) == 1: - value = value[0] - else: - value = model.objects.get(pk=value) - else: - value = None - dct[key] = value - return self.save_model(dct, m2m, whole_associated_models, form_list, - return_object) - - def get_saved_model(self): - """Permit a distinguo when saved model is not the base selected model""" - return self.model - - def get_current_saved_object(self): - """Permit a distinguo when saved model is not the base selected model""" - return self.get_current_object() - - def save_model(self, dct, m2m, whole_associated_models, form_list, - return_object): - dct = self.get_extra_model(dct, form_list) - obj = self.get_current_saved_object() - # manage dependant items - other_objs = {} - for k in dct.keys(): - if '__' not in k: - continue - vals = k.split('__') - assert len(vals) == 2, "Only one level of dependant item is managed" - dependant_item, key = vals - if dependant_item not in other_objs: - other_objs[dependant_item] = {} - other_objs[dependant_item][key] = dct.pop(k) - if obj: - for k in dct: - if k.startswith('pk'): - continue - setattr(obj, k, dct[k]) - try: - obj.full_clean() - except forms.ValidationError, msg: - return self.render(form_list[-1]) - for dependant_item in other_objs: - c_item = getattr(obj, dependant_item) - # manage ManyToMany if only one associated - if hasattr(c_item, "all"): - c_items = c_item.all() - if len(c_items) != 1: - continue - c_item = c_items[0] - if c_item: - # to check # - for k in other_objs[dependant_item]: - setattr(c_item, k, other_objs[dependant_item][k]) - c_item.save() - else: - m = getattr(self.model, dependant_item) - if hasattr(m, 'related'): - c_item = m.related.model(**other_objs[dependant_item]) - setattr(obj, dependant_item, c_item) - obj.save() - obj.save() - else: - adds = {} - for dependant_item in other_objs: - m = getattr(self.model, dependant_item) - model = m.field.rel.to - c_dct = other_objs[dependant_item].copy() - if issubclass(model, models.BaseHistorizedItem): - c_dct['history_modifier'] = self.request.user - c_item = model(**c_dct) - c_item.save() - if hasattr(m, 'through'): - adds[dependant_item] = c_item - elif hasattr(m, 'field'): - dct[dependant_item] = c_item - if 'pk' in dct: - dct.pop('pk') - obj = self.get_saved_model()(**dct) - try: - obj.full_clean() - except forms.ValidationError, msg: - return self.render(form_list[-1]) - obj.save() - for k in adds: - getattr(obj, k).add(adds[k]) - # necessary to manage interaction between models like - # material_index management for baseitems - obj.save() - m2m_items = {} - for model in whole_associated_models: - getattr(obj, model+'s').clear() - for key, value in m2m: - if key not in m2m_items: - if type(key) == dict: - vals = [] - for item in getattr(obj, key+'s').all(): - v = {} - for k in value.keys(): - v[k] = getattr(item, k) - vals.append(v) - m2m_items[key] = vals - else: - m2m_items[key] = getattr(obj, key+'s').all() - if value not in m2m_items[key]: - if type(value) == dict: - model = getattr(obj, key+'s').model - if issubclass(model, models.BaseHistorizedItem): - value['history_modifier'] = self.request.user - value = model.objects.create(**value) - value.save() - getattr(obj, key+'s').add(value) - # necessary to manage interaction between models like - # material_index management for baseitems - obj.save() - res = render_to_response('wizard_done.html', {}, - context_instance=RequestContext(self.request)) - return return_object and (obj, res) or res - - def get_deleted(self, keys): - """Get the deleted and non-deleted items in formsets""" - not_to_delete, to_delete = set(), set() - for key in keys: - items = key.split('-') - if len(items) < 2 or items[-2] in to_delete: - continue - idx = items[-2] - try: - int(idx) - except: - continue - if items[-1] == u'DELETE': - to_delete.add(idx) - if idx in not_to_delete: - not_to_delete.remove(idx) - elif idx not in not_to_delete: - not_to_delete.add(idx) - return (to_delete, not_to_delete) - - def get_form(self, step=None, data=None, files=None): - """Manage formset""" - request = self.request - storage = self.storage - if data: - data = data.copy() - if not step: - step = self.steps.current - form = self.get_form_list()[step] - if hasattr(form, 'management_form'): - # manage deletion - to_delete, not_to_delete = self.get_deleted(data.keys()) - # raz deleted fields - for key in data.keys(): - items = key.split('-') - if len(items) < 2 or items[-2] not in to_delete: - continue - data.pop(key) - if to_delete: - # reorganize - for idx, number in enumerate(sorted(not_to_delete)): - idx = unicode(idx) - if idx == number: - continue - for key in data.keys(): - items = key.split('-') - if len(items) > 2 and number == items[-2]: - items[-2] = unicode(idx) - k = u'-'.join(items) - data[k] = data.pop(key)[0] - # get a form key - base_key = form.form.base_fields.keys()[0] - init = self.get_form_initial(request, storage, step) - total_field = len([key for key in data.keys() - if base_key in key.split('-') - and data[key]]) - if init and not to_delete: - total_field = max((total_field, len(init))) - data[step + u'-INITIAL_FORMS'] = unicode(total_field) - data[step + u'-TOTAL_FORMS'] = unicode(total_field + 1) - data = data or None - form = super(Wizard, self).get_form(step, data, files) - return form - - def render_next_step(self, form, **kwargs): - """ - Manage: - - modify or delete button in formset: next step = current step - - validate and end: nextstep = last step - """ - request = self.request - if request.POST.has_key('formset_modify') \ - and request.POST['formset_modify'] \ - or [key for key in request.POST.keys() - if key.endswith('DELETE') and request.POST[key]]: - return self.render(form) - elif request.POST.has_key('validate_and_end') \ - and request.POST['validate_and_end']: - last_step = self.steps.last - new_form = self.get_form(last_step, - data=self.storage.get_step_data(last_step), - files=self.storage.get_step_files(last_step)) - self.storage.current_step = last_step - return self.render(new_form) - return super(Wizard, self).render_next_step(form, **kwargs) - - def post(self, *args, **kwargs): - """Convert numerical step number to step name""" - request = self.request - post_data = request.POST.copy() - if request.POST.has_key('form_prev_step'): - try: - step_number = int(request.POST['form_prev_step']) - post_data['wizard_goto_step'] = self.get_form_list().keys( - )[step_number] - except ValueError: - pass - request.POST = post_data - return super(Wizard, self).post(*args, **kwargs) - - @classmethod - def session_has_key(cls, request, storage, form_key, key=None, multi=None): - """Check if the session has value of a specific form and (if provided) - of a key - """ - test = storage.prefix in request.session \ - and 'step_data' in request.session[storage.prefix] \ - and form_key in request.session[storage.prefix]['step_data'] - if not key or not test: - return test - key = key.startswith(form_key) and key or \ - not multi and form_key + '-' + key or \ - form_key + '-0-' + key #only check if the first field is available - return key in request.session[storage.prefix]['step_data'][form_key] - - @classmethod - def session_get_value(cls, request, storage, form_key, key, multi=False): - """Get the value of a specific form""" - if not cls.session_has_key(request, storage, form_key, key, multi): - return - if not multi: - key = key.startswith(form_key) and key or form_key + '-' + key - return request.session[storage.prefix]['step_data'][form_key][key] - vals = [] - for k in request.session[storage.prefix]['step_data'][form_key]: - if k.startswith(form_key) and k.endswith(key) and \ - request.session[storage.prefix]['step_data'][form_key][k]: - vals.append(request.session[storage.prefix]['step_data']\ - [form_key][k]) - return vals - - def get_current_object(self): - """Get the current object for an instancied wizard""" - current_obj = None - main_form_key = 'selec-' + self.url_name - try: - idx = int(self.session_get_value(self.request, self.storage, - main_form_key, 'pk')) - current_obj = self.model.objects.get(pk=idx) - except(TypeError, ValueError, ObjectDoesNotExist): - pass - return current_obj - - def get_form_initial(self, step): - current_obj = self.get_current_object() - current_step = self.steps.current - if step.startswith('selec-') and step in self.form_list \ - and 'pk' in self.form_list[step].associated_models: - model_name = self.form_list[step].associated_models['pk' - ].__name__.lower() - if step == current_step: - self.reset_wizard(request, storage) - val = model_name in request.session and request.session[model_name] - if val: - return {'pk':val} - elif current_obj: - return self.get_instanced_init(current_obj, step) - current_form = self.form_list[current_step] - if hasattr(current_form, 'currents'): - initial = {} - for key in current_form.currents: - model_name = current_form.currents[key].__name__.lower() - val = model_name in request.session and \ - request.session[model_name] - if val: - initial[key] = val - if initial: - return initial - return super(Wizard, self).get_form_initial(step) - - def get_instanced_init(self, obj, step=None): - """Get initial data from an init""" - current_step = step or self.steps.current - c_form = self.form_list[current_step] - # make the current object the default item for the session - obj_name = obj.__class__.__name__.lower() - # prefer a specialized name if available - prefixes = self.storage.prefix.split('_') - if len(prefixes) > 1 and prefixes[-2].startswith(obj_name): - obj_name = prefixes[-2] - self.request.session[obj_name] = unicode(obj.pk) - initial = {} - if self.request.POST or \ - (step in self.request.session[self.storage.prefix] and\ - self.request.session[self.storage.prefix]['step_data'][step]): - return {} - if hasattr(c_form, 'base_fields'): - for base_field in c_form.base_fields.keys(): - fields = base_field.split('__') - value = obj - for field in fields: - if not hasattr(value, field) or \ - getattr(value, field) == None: - value = obj - break - value = getattr(value, field) - if value == obj: - continue - if hasattr(value, 'pk'): - value = value.pk - if value in (True, False): - initial[base_field] = value - elif value != None: - initial[base_field] = unicode(value) - elif hasattr(c_form, 'management_form'): - initial = [] - if hasattr(c_form.form, 'base_model'): - key = c_form.form.base_model + 's' - else: - key = current_step.split('-')[0] - if not hasattr(obj, key): - return initial - keys = c_form.form.base_fields.keys() - for child_obj in getattr(obj, key).order_by('pk').all(): - if not keys: - break - vals = {} - if len(keys) == 1: - # only one field: must be the id of the object - vals[keys[0]] = unicode(child_obj.pk) - else: - for field in keys: - if hasattr(child_obj, field): - value = getattr(child_obj, field) - if hasattr(value, 'pk'): - value = value.pk - if value != None: - vals[field] = unicode(value) - if vals: - initial.append(vals) - return initial - -class PersonWizard(Wizard): - model = models.Person - -person_creation_wizard = PersonWizard.as_view([ - ('identity-person_creation', PersonForm), - ('final-person_creation', FinalForm)], - url_name='person_creation_step',) - - -def update_current_item(request): - if not request.is_ajax() and not request.method == 'POST': - raise Http404 - if 'value' in request.POST and 'item' in request.POST: - request.session[request.POST['item']] = request.POST['value'] - return HttpResponse('ok') - -def check_permission(request, action_slug, obj_id=None): - if action_slug not in menu.items: - #! TODO - return True - if obj_id: - return menu.items[action_slug].is_available(request.user, obj_id) - return menu.items[action_slug].can_be_available(request.user) - -def autocomplete_person(request, person_type=None): - person_types = request.user.ishtaruser.person.person_type - if (not request.user.has_perm('ishtar_base.view_person', models.Person) and - not request.user.has_perm('ishtar_base.view_own_person', models.Person) - and not person_types.rights.filter(wizard__url_name='person_search' - ).count()): - return HttpResponse(mimetype='text/plain') - if not request.GET.get('term'): - return HttpResponse(mimetype='text/plain') - q = request.GET.get('term') - limit = request.GET.get('limit', 20) - try: - limit = int(limit) - except ValueError: - return HttpResponseBadRequest() - query = Q() - for q in q.split(' '): - query = query & (Q(name__icontains=q) | Q(surname__icontains=q) | \ - Q(email__icontains=q)) - if person_type: - try: - typs = [int(tp) for tp in person_type.split('_') if tp] - typ = models.PersonType.objects.filter(pk__in=typs).all() - query = query & Q(person_type__in=typ) - except (ValueError, ObjectDoesNotExist): - pass - limit = 20 - persons = models.Person.objects.filter(query)[:limit] - data = json.dumps([{'id':person.pk, 'value':unicode(person)} - for person in persons if person]) - return HttpResponse(data, mimetype='text/plain') - -def autocomplete_town(request): - if not request.GET.get('term'): - return HttpResponse(mimetype='text/plain') - q = request.GET.get('term') - query = Q() - for q in q.split(' '): - extra = Q(name__icontains=q) - if settings.COUNTRY == 'fr': - extra = (extra | Q(numero_insee__istartswith=q) | \ - Q(departement__label__istartswith=q)) - query = query & extra - limit = 20 - towns = models.Town.objects.filter(query)[:limit] - data = json.dumps([{'id':town.pk, 'value':unicode(town)} - for town in towns]) - return HttpResponse(data, mimetype='text/plain') - -def autocomplete_file(request): - person_types = request.user.ishtaruser.person.person_type - if (not request.user.has_perm('ishtar_base.view_file', models.File) and \ - not request.user.has_perm('ishtar_base.view_own_file', models.File) - and not person_types.rights.filter(wizard__url_name='file_search' - ).count()): - return HttpResponse(mimetype='text/plain') - if not request.GET.get('term'): - return HttpResponse(mimetype='text/plain') - q = request.GET.get('term') - query = Q() - for q in q.split(' '): - extra = Q(internal_reference__icontains=q) | \ - Q(towns__name__icontains=q) - try: - value = int(q) - extra = extra | Q(year=q) | Q(numeric_reference=q) - except ValueError: - pass - query = query & extra - limit = 20 - files = models.File.objects.filter(query)[:limit] - data = json.dumps([{'id':file.pk, 'value':unicode(file)} - for file in files]) - return HttpResponse(data, mimetype='text/plain') - -from types import NoneType - -def format_val(val): - if type(val) == NoneType: - return u"" - if type(val) == bool: - if val: - return unicode(_(u"True")) - else: - return unicode(_(u"False")) - return unicode(val) - -HIERARCHIC_LEVELS = 5 -HIERARCHIC_FIELDS = ['period', 'unit', 'material_type'] -PRIVATE_FIELDS = ('id', 'history_modifier', 'order') -def get_item(model, func_name, default_name, extra_request_keys=[], - base_request={}, bool_fields=[]): - """ - Generic treatment of tables - """ - def func(request, data_type='json', full=False, **dct): - if 'type' in dct: - data_type = dct.pop('type') - if not data_type: - data_type = 'json' - fields = [model._meta.get_field_by_name(k)[0] - for k in model._meta.get_all_field_names()] - request_keys = dict([(field.name, - field.name + (hasattr(field, 'rel') and field.rel and '__pk' or '')) - for field in fields]) - request_keys.update(extra_request_keys) - request_items = request.method == 'POST' and request.POST or request.GET - dct = base_request.copy() - try: - old = 'old' in request_items and int(request_items['old']) - except ValueError: - return HttpResponse(None, mimetype='text/plain') - for k in request_keys: - q = request_items.get(k) - if not q: - continue - dct[request_keys[k]] = q - if not dct and 'submited' not in request_items: - if default_name in request.session and \ - request.session[default_name]: - dct = {"pk":request.session[default_name]} - if (not dct or data_type == 'csv') and func_name in request.session: - dct = request.session[func_name] - else: - request.session[func_name] = dct - for k in bool_fields: - if k in dct: - if dct[k] == u"1": - dct.pop(k) - else: - dct[k] = dct[k] == u"2" and True or False - - # manage hierarchic conditions - or_reqs = [] - for req in dct.copy(): - for k_hr in HIERARCHIC_FIELDS: - if req.endswith(k_hr + '__pk'): - val = dct.pop(req) - reqs = Q(**{req:val}) - req = req[:-2] + '__' - for idx in xrange(HIERARCHIC_LEVELS): - req = req[:-2] + 'parent__pk' - q = Q(**{req:val}) - reqs = reqs | q - or_reqs.append(reqs) - break - query = Q(**dct) - for or_req in or_reqs: - query = query & or_req - items = model.objects.filter(query) - q = request_items.get('sidx') - - # manage sort tables - if q and q in request_keys: - ks = request_keys[q] - if type(ks) not in (list, tuple): - ks = [ks] - orders = [] - for k in ks: - if k.endswith("__pk"): - k = k[:-len("__pk")] + "__label" - q = request_items.get('sord') - sign = q and q == u'desc' and "-" or '' - if '__' in k: - k = k.split('__')[0] - orders.append(sign+k) - items = items.order_by(*orders) - - # pager management - start, end = 0, None - page_nb = 1 - try: - row_nb = int(request_items.get('rows')) - except (ValueError, TypeError): - row_nb = None - if row_nb: - try: - page_nb = int(request_items.get('page')) - assert page_nb >= 1 - except (ValueError, AssertionError): - pass - start = (page_nb-1)*row_nb - end = page_nb*row_nb - items_nb = items.count() - items = items[start:end] - - datas = [] - if old: - items = [item.get_previous(old) for item in items] - table_cols = full and [field.name for field in model._meta.fields - if field.name not in PRIVATE_FIELDS] \ - or model.TABLE_COLS - for item in items: - data = [item.pk] - for k in table_cols: - vals = [item] - for ky in k.split('.'): - new_vals = [] - for val in vals: - if hasattr(val, 'all'): # manage related objects - val = list(val.all()) - for v in val: - new_vals.append(getattr(v, ky)) - elif val: - new_vals.append(getattr(val, ky)) - vals = new_vals - if vals and hasattr(vals[0], 'all'): # manage last related objects - new_vals = [] - for val in vals: - new_vals += list(val.all()) - vals = new_vals - data.append(", ".join([format_val(v) for v in vals]) or u"") - datas.append(data) - link_template = "<a href='#' onclick='load_window(\"%%s\")'>%s</a>" % \ - (unicode(_("Details"))) - if data_type == "json": - rows = [] - for data in datas: - try: - lnk = link_template % reverse('show-'+default_name, - args=[data[0], '']) - except NoReverseMatch: - lnk = '' - res = {'id':data[0], 'link':lnk} - for idx, value in enumerate(data[1:]): - if value: - res[table_cols[idx].split('.')[-1]] = value - rows.append(res) - data = json.dumps({ - "records":items_nb, - "rows":rows, - "page":page_nb, - "total":items_nb/row_nb + 1, - }) - return HttpResponse(data, mimetype='text/plain') - elif data_type == "csv": - response = HttpResponse(mimetype='text/csv') - n = datetime.datetime.now() - filename = u'%s_%s.csv' % (default_name, - n.strftime('%Y%m%d-%H%M%S')) - response['Content-Disposition'] = 'attachment; filename=%s'%filename - writer = csv.writer(response, **CSV_OPTIONS) - col_names = [] - for field_name in table_cols: - try: - field = model._meta.get_field(field_name) - except: - col_names.append(u"".encode(ENCODING)) - continue - col_names.append(unicode(field.verbose_name).encode(ENCODING)) - writer.writerow(col_names) - for data in datas: - writer.writerow([val.encode(ENCODING) for val in data[1:]]) - return response - return HttpResponse(None, mimetype='text/plain') - - return func - -def show_item(model, name): - def func(request, pk, **dct): - try: - item = model.objects.get(pk=pk) - except ObjectDoesNotExist: - return HttpResponse(None) - doc_type = 'type' in dct and dct.pop('type') - date = 'date' in dct and dct.pop('date') - dct['window_id'] = "%s-%d-%s" % (name, item.pk, - datetime.datetime.now().strftime('%M%s')) - if date: - try: - date = datetime.datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.%f') - item = item.get_previous(date=date) - assert item != None - except (ValueError, AssertionError): - return HttpResponse(None, mimetype='text/plain') - dct['previous'] = item._previous - dct['next'] = item._next - else: - historized = item.history.all() - if historized: - item.history_date = historized[0].history_date - if len(historized) > 1: - dct['previous'] = historized[1].history_date - dct['item'], dct['item_name'] = item, name - context_instance = RequestContext(request) - context_instance.update(dct) - n = datetime.datetime.now() - filename = u'%s_%s_%s' % (name, slugify(unicode(item)), - n.strftime('%Y%m%d-%H%M%S')) - 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: - tidy_options = dict(output_xhtml=1, add_xml_decl=1, indent=1, - tidy_mark=0, output_encoding='utf8', doctype='auto', - wrap=0, char_encoding='utf8') - html = str(tidy.parseString(content.encode('utf-8'), - **tidy_options)) - html = html.replace(" ", " ") - html = re.sub('<pre([^>]*)>\n', '<pre\\1>', html) - - odt = NamedTemporaryFile() - options = optparse.Values() - options.with_network = True - for k, v in (('input', ''), - ('output', odt.name), - ('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) - odtfile = xhtml2odt.ODTFile(options) - odtfile.open() - odtfile.import_xhtml(html) - odtfile = odtfile.save() - except xhtml2odt.ODTExportError, ex: - return HttpResponse(content, content_type="application/xhtml") - response = HttpResponse( - mimetype='application/vnd.oasis.opendocument.text') - response['Content-Disposition'] = 'attachment; filename=%s.odt' % \ - filename - response.write(odtfile) - return response - elif doc_type == 'pdf': - tpl = loader.get_template('sheet_%s_pdf.html' % name) - content = tpl.render(context_instance) - result = StringIO.StringIO() - html = content.encode('utf-8') - html = html.replace("<table", "<pdf:nextpage/><table repeat='1'") - pdf = pisa.pisaDocument(StringIO.StringIO(html), result) - response = HttpResponse(result.getvalue(), - mimetype='application/pdf') - response['Content-Disposition'] = 'attachment; filename=%s.pdf' % \ - filename - if not pdf.err: - return response - return HttpResponse(content, content_type="application/xhtml") - else: - tpl = loader.get_template('sheet_%s_window.html' % name) - content = tpl.render(context_instance) - return HttpResponse(content, content_type="application/xhtml") - return func - -def revert_item(model): - def func(request, pk, date, **dct): - try: - item = model.objects.get(pk=pk) - date = datetime.datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.%f') - item.rollback(date) - except (ObjectDoesNotExist, ValueError, HistoryError): - return HttpResponse(None, mimetype='text/plain') - return HttpResponse("True", mimetype='text/plain') - return func - - -get_file = get_item(models.File, 'get_file', 'file') -show_file = show_item(models.File, 'file') -revert_file = revert_item(models.File) - -def autocomplete_operation(request, non_closed=True): - person_types = request.user.ishtaruser.person.person_type - if (not request.user.has_perm('ishtar_base.view_operation', models.Operation)\ - and not request.user.has_perm('ishtar_base.view_own_operation', - models.Operation) - and not person_types.rights.filter(wizard__url_name='operation_search' - ).count()): - return HttpResponse(mimetype='text/plain') - if not request.GET.get('term'): - return HttpResponse(mimetype='text/plain') - q = request.GET.get('term') - query = Q() - for q in q.split(' '): - extra = Q(towns__name__icontains=q) - try: - value = int(q) - extra = extra | Q(year=q) | Q(operation_code=q) - except ValueError: - pass - query = query & extra - if non_closed: - query = query & Q(end_date__isnull=True) - limit = 15 - operations = models.Operation.objects.filter(query)[:limit] - data = json.dumps([{'id':operation.pk, 'value':unicode(operation)} - for operation in operations]) - return HttpResponse(data, mimetype='text/plain') - -def get_available_operation_code(request, year=None): - if not request.user.has_perm('ishtar_base.view_operation', models.Operation)\ - and not request.user.has_perm('ishtar_base.view_own_operation', - models.Operation): - return HttpResponse(mimetype='text/plain') - data = json.dumps({'id':models.Operation.get_available_operation_code(year)}) - return HttpResponse(data, mimetype='text/plain') - -get_operation = get_item(models.Operation, 'get_operation', 'operation', - bool_fields = ['end_date__isnull'], - extra_request_keys={'common_name':'common_name__icontains', - 'end_date':'end_date__isnull', - 'year_index':('year', 'operation_code')}) -show_operation = show_item(models.Operation, 'operation') -revert_operation = revert_item(models.Operation) - -get_operationsource = get_item(models.OperationSource, - 'get_operationsource', 'operationsource', - extra_request_keys={'operation__towns':'operation__towns__pk', - 'operation__operation_type':'operation__operation_type__pk', - 'operation__year':'operation__year'}) - -get_administrativeactfile = get_item(models.AdministrativeAct, - 'get_administrativeactfile', 'administrativeactfile', - extra_request_keys={'associated_file__towns':'associated_file__towns__pk', - 'operation__towns':'operation__towns__pk', - 'act_type__intented_to':'act_type__intented_to'}) -get_administrativeactop = get_item(models.AdministrativeAct, - 'get_administrativeactop', 'administrativeactop', - extra_request_keys={'associated_file__towns':'associated_file__towns__pk', - 'operation__towns':'operation__towns__pk', - 'act_type__intented_to':'act_type__intented_to'}) - -def autocomplete_organization(request, orga_type=None): - person_types = request.user.ishtaruser.person.person_type - if (not request.user.has_perm('ishtar_base.view_organization', - models.Organization) and \ - not request.user.has_perm('ishtar_base.view_own_organization', - models.Organization) - and not person_types.rights.filter(wizard__url_name='person_search' - ).count()): - return HttpResponse(mimetype='text/plain') - if not request.GET.get('term'): - return HttpResponse(mimetype='text/plain') - q = request.GET.get('term') - query = Q() - for q in q.split(' '): - extra = Q(name__icontains=q) - query = query & extra - if orga_type: - try: - typs = [int(tp) for tp in orga_type.split('_') if tp] - typ = models.OrganizationType.objects.filter(pk__in=typs).all() - query = query & Q(organization_type__in=typ) - except (ValueError, ObjectDoesNotExist): - pass - limit = 15 - organizations = models.Organization.objects.filter(query)[:limit] - data = json.dumps([{'id':org.pk, 'value':unicode(org)} - for org in organizations]) - return HttpResponse(data, mimetype='text/plain') - -show_contextrecord = show_item(models.ContextRecord, 'contextrecord') -get_contextrecord = get_item(models.ContextRecord, - 'get_contextrecord', 'contextrecord', - extra_request_keys={'parcel__town':'parcel__town__pk', - 'operation__year':'operation__year__contains', - 'datings__period':'datings__period__pk'},) -get_contextrecordsource = get_item(models.ContextRecordSource, - 'get_contextrecordsource', 'contextrecordsource', - extra_request_keys={ - 'context_record__parcel__town':'context_record__parcel__town__pk', - 'context_record__operation__year':'context_record__operation__year', - 'context_record__datings__period':'context_record__datings__period__pk', - 'context_record__unit':'context_record__unit__pk', - }) -get_archaeologicalitem = get_item(models.Item, - 'get_archaeologicalitem', 'item', - bool_fields = ['base_items__is_isolated'], - base_request={'downstream_treatment__isnull':True}, - extra_request_keys={ -'base_items__context_record__parcel__town': - 'base_items__context_record__parcel__town', -'base_items__context_record__operation__year': - 'base_items__context_record__operation__year__contains', -'base_items__context_record__operation__code_patriarche': - 'base_items__context_record__operation__code_patriarche', -'dating__period':'dating__period__pk', -'base_items__item__description':'base_items__item__description__icontains', -'base_items__is_isolated':'base_items__is_isolated'}) -get_itemsource = get_item(models.ItemSource, - 'get_itemsource', 'itemsource', - extra_request_keys={ -'item__context_record__operation__year':'item__context_record__operation__year', -'item__dating__period':'item__dating__period__pk', -'item__description':'item__description__icontains', - }) -get_container = get_item(models.Container, - 'get_container', 'container', - extra_request_keys={ -'location':'location__pk', -'container_type':'container_type__pk', -'reference':'reference__icontains', - }) - -def autocomplete_warehouse(request): - if not request.user.has_perm('ishtar_base.view_warehouse', models.Warehouse)\ - and not request.user.has_perm('ishtar_base.view_own_warehouse', - models.Warehouse) : - return HttpResponse(mimetype='text/plain') - if not request.GET.get('term'): - return HttpResponse(mimetype='text/plain') - q = request.GET.get('term') - query = Q() - for q in q.split(' '): - extra = Q(name__icontains=q) | \ - Q(warehouse_type__label__icontains=q) - query = query & extra - limit = 15 - warehouses = models.Warehouse.objects.filter(query)[:limit] - data = json.dumps([{'id':warehouse.pk, 'value':unicode(warehouse)} - for warehouse in warehouses]) - return HttpResponse(data, mimetype='text/plain') - -def autocomplete_author(request): - if not request.user.has_perm('ishtar_base.view_author', models.Author)\ - and not request.user.has_perm('ishtar_base.view_own_author', - models.Warehouse) : - return HttpResponse(mimetype='text/plain') - if not request.GET.get('term'): - return HttpResponse(mimetype='text/plain') - q = request.GET.get('term') - query = Q() - for q in q.split(' '): - extra = Q(person__name__icontains=q) | \ - Q(person__surname__icontains=q) | \ - Q(person__email__icontains=q) | \ - Q(author_type__label__icontains=q) - query = query & extra - limit = 15 - authors = models.Author.objects.filter(query)[:limit] - data = json.dumps([{'id':author.pk, 'value':unicode(author)} - for author in authors]) - return HttpResponse(data, mimetype='text/plain') - -def autocomplete_container(request): - if not request.user.has_perm('ishtar_base.view_warehouse', - models.Warehouse)\ - and not request.user.has_perm('ishtar_base.view_own_warehouse', - models.Warehouse): - return HttpResponse(mimetype='text/plain') - if not request.GET.get('term'): - return HttpResponse(mimetype='text/plain') - q = request.GET.get('term') - query = Q() - for q in q.split(' '): - extra = Q(container_type__label__icontains=q) | \ - Q(container_type__reference__icontains=q) | \ - Q(reference__icontains=q) | \ - Q(location__name=q) | \ - Q(location__town=q) - query = query & extra - limit = 15 - containers = models.Container.objects.filter(query)[:limit] - data = json.dumps([{'id':container.pk, 'value':unicode(container)} - for container in containers]) - return HttpResponse(data, mimetype='text/plain') - -def new_item(model): - def func(request, parent_name): - model_name = model._meta.object_name - if not check_permission(request, 'add_'+model_name.lower()): - not_permitted_msg = ugettext(u"Operation not permitted.") - return HttpResponse(not_permitted_msg) - frm = getattr(ishtar_forms, model_name + 'Form') - dct = {'title':unicode(_(u'New %s' % model_name.lower()))} - if request.method == 'POST': - dct['form'] = frm(request.POST) - if dct['form'].is_valid(): - new_item = dct['form'].save(request.user) - dct['new_item_label'] = unicode(new_item) - dct['new_item_pk'] = new_item.pk - dct['parent_name'] = parent_name - dct['parent_pk'] = parent_name - if dct['parent_pk'] and '_select_' in dct['parent_pk']: - parents = dct['parent_pk'].split('_') - dct['parent_pk'] = "_".join([parents[0]] + parents[2:]) - return render_to_response('window.html', dct, - context_instance=RequestContext(request)) - else: - dct['form'] = frm() - return render_to_response('window.html', dct, - context_instance=RequestContext(request)) - return func - -new_warehouse = new_item(models.Warehouse) -new_person = new_item(models.Person) -new_organization = new_item(models.Organization) -new_author = new_item(models.Author) -new_container = new_item(models.Container) - -def action(request, action_slug, obj_id=None, *args, **kwargs): - """ - Action management - """ - if not check_permission(request, action_slug, obj_id): - not_permitted_msg = ugettext(u"Operation not permitted.") - return HttpResponse(not_permitted_msg) - request.session['CURRENT_ACTION'] = action_slug - associated_wizard = action_slug + '_wizard' - dct = {} - globals_dct = globals() - if action_slug in globals_dct: - return globals_dct[action_slug](request, dct, obj_id, *args, **kwargs) - elif hasattr(ishtar_forms, action_slug + "_wizard"): - return getattr(ishtar_forms, action_slug+"_wizard")(request, *args, - **kwargs) - return render_to_response('index.html', dct, - context_instance=RequestContext(request)) - -def dashboard_main(request, dct, obj_id=None, *args, **kwargs): - """ - Main dashboard - """ - dct = {'items':[ - (_(u"Archaeological files"), models.Dashboard(models.File)), - (_(u"Operations"), models.Dashboard(models.Operation)), - (_(u"Context records"), models.Dashboard(models.ContextRecord)), - (_(u"Archaeological items"), models.Dashboard(models.Item)), - ], - 'ishtar_users':models.UserDashboard()} - return render_to_response('dashboard_main.html', dct, - context_instance=RequestContext(request)) - -def dashboard_file(request, dct, obj_id=None, *args, **kwargs): - """ - Main dashboard - """ - dct = {'dashboard': models.FileDashboard()} - return render_to_response('dashboard_file.html', dct, - context_instance=RequestContext(request)) - -def dashboard_operation(request, dct, obj_id=None, *args, **kwargs): - """ - Operation dashboard - """ - dct = {'dashboard': models.OperationDashboard()} - return render_to_response('dashboard_operation.html', dct, - context_instance=RequestContext(request)) |
