diff options
| author | Étienne Loks <etienne.loks@peacefrogs.net> | 2012-10-18 17:49:57 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@peacefrogs.net> | 2012-10-18 17:51:30 +0200 | 
| commit | 7d2aa560ba859ebb593d34b062bf1faf09c8724c (patch) | |
| tree | 4136673563f802d6de992512e3c4adde86ef2a4e /ishtar/ishtar_base/views.py | |
| parent | 615457617e65019e0ce39b585f4eeb41b17ba61a (diff) | |
| download | Ishtar-7d2aa560ba859ebb593d34b062bf1faf09c8724c.tar.bz2 Ishtar-7d2aa560ba859ebb593d34b062bf1faf09c8724c.zip | |
Djangoization - Major refactoring (step 1)
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)) | 
