diff options
Diffstat (limited to 'ishtar_common/views.py')
-rw-r--r-- | ishtar_common/views.py | 219 |
1 files changed, 118 insertions, 101 deletions
diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 234dcd826..997acd7df 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -19,11 +19,15 @@ from tidylib import tidy_document as tidy -from copy import copy +from copy import copy, deepcopy import csv import cStringIO as StringIO import datetime + +import reportlab +reportlab.Version = "2.2" # stupid hack for an old library... import ho.pisa as pisa + import json import logging from markdown import markdown @@ -44,8 +48,8 @@ from django.db.models.fields import FieldDoesNotExist from django.forms.models import modelformset_factory from django.http import HttpResponse, Http404, HttpResponseRedirect, \ HttpResponseBadRequest -from django.shortcuts import render_to_response, redirect -from django.template import RequestContext, loader +from django.shortcuts import redirect, render +from django.template import loader from django.utils.decorators import method_decorator from django.utils.translation import ugettext, ugettext_lazy as _ from django.views.generic import ListView, UpdateView, TemplateView @@ -68,7 +72,8 @@ from archaeological_finds.forms import DashboardTreatmentForm, \ from ishtar_common.forms import FinalForm, FinalDeleteForm from ishtar_common.widgets import JQueryAutoComplete -from ishtar_common.utils import get_random_item_image_link, shortify +from ishtar_common.utils import get_random_item_image_link, shortify, \ + get_all_field_names from ishtar_common import forms_common as forms from ishtar_common import wizards from ishtar_common.models import HistoryError, PRIVATE_FIELDS, \ @@ -109,13 +114,11 @@ def index(request): else: dct['random_image'] = image try: - return render_to_response('index.html', dct, - context_instance=RequestContext(request)) + return render(request, 'index.html', dct) except NoReverseMatch: # probably rights exception (rights revoked) logout(request) - return render_to_response('index.html', dct, - context_instance=RequestContext(request)) + return render(request, 'index.html', dct) person_search_wizard = wizards.SearchWizard.as_view( [('general-person_search', forms.PersonFormSelection)], @@ -186,10 +189,13 @@ organization_deletion_wizard = wizards.OrganizationDeletionWizard.as_view( label=_(u"Organization deletion"), url_name='organization_deletion',) +account_wizard_steps = [ + ('selec-account_management', forms.PersonUserFormSelection), + ('account-account_management', forms.AccountForm), + ('final-account_management', forms.FinalAccountForm)] + account_management_wizard = wizards.AccountWizard.as_view( - [('selec-account_management', forms.PersonUserFormSelection), - ('account-account_management', forms.AccountForm), - ('final-account_management', forms.FinalAccountForm)], + account_wizard_steps, label=_(u"Account management"), url_name='account_management',) @@ -214,44 +220,44 @@ def get_autocomplete_generic(model, extra={'available': True}): else unicode(x) data = json.dumps([{'id': obj.pk, 'value': get_label(obj)} for obj in objects]) - return HttpResponse(data, mimetype='text/plain') + return HttpResponse(data, content_type='text/plain') return func def hide_shortcut_menu(request): request.session['SHORTCUT_SHOW'] = 'off' - return HttpResponse('OK', mimetype='text/plain') + return HttpResponse('OK', content_type='text/plain') def show_shortcut_menu(request): request.session['SHORTCUT_SHOW'] = 'on' - return HttpResponse('OK', mimetype='text/plain') + return HttpResponse('OK', content_type='text/plain') def activate_all_search(request): request.session['SHORTCUT_SEARCH'] = 'all' - return HttpResponse('OK', mimetype='text/plain') + return HttpResponse('OK', content_type='text/plain') def activate_own_search(request): request.session['SHORTCUT_SEARCH'] = 'own' - return HttpResponse('OK', mimetype='text/plain') + return HttpResponse('OK', content_type='text/plain') def activate_advanced_shortcut_menu(request): if not hasattr(request.user, 'ishtaruser'): - return HttpResponse('KO', mimetype='text/plain') + return HttpResponse('KO', content_type='text/plain') request.user.ishtaruser.advanced_shortcut_menu = True request.user.ishtaruser.save() - return HttpResponse('OK', mimetype='text/plain') + return HttpResponse('OK', content_type='text/plain') def activate_simple_shortcut_menu(request): if not hasattr(request.user, 'ishtaruser'): - return HttpResponse('KO', mimetype='text/plain') + return HttpResponse('KO', content_type='text/plain') request.user.ishtaruser.advanced_shortcut_menu = False request.user.ishtaruser.save() - return HttpResponse('OK', mimetype='text/plain') + return HttpResponse('OK', content_type='text/plain') def shortcut_menu(request): @@ -288,9 +294,9 @@ def shortcut_menu(request): model).render( model.SLUG + '-shortcut', value=current, attrs={'id': 'current_' + model.SLUG}))) - return render_to_response( - 'ishtar/blocks/advanced_shortcut_menu.html', - dct, context_instance=RequestContext(request)) + return render( + request, 'ishtar/blocks/advanced_shortcut_menu.html', dct + ) dct = { 'current_menu': [], 'SHORTCUT_SHOW': request.session['SHORTCUT_SHOW'] @@ -333,8 +339,7 @@ def shortcut_menu(request): dct['current_menu'].append((lbl, model_name, cls, items)) if new_selected_item: current_selected_item[model_name] = new_selected_item - return render_to_response('ishtar/blocks/shortcut_menu.html', dct, - context_instance=RequestContext(request)) + return render(request, 'ishtar/blocks/shortcut_menu.html', dct) CURRENT_ITEM_KEYS = (('file', File), ('operation', Operation), @@ -352,7 +357,7 @@ def get_current_items(request): if key in request.session and request.session[key]: try: currents[key] = model.objects.get(pk=int(request.session[key])) - except (ValueError, File.DoesNotExist): + except (ValueError, model.DoesNotExist): continue return currents @@ -462,7 +467,7 @@ def autocomplete_person(request, person_types=None, attached_to=None, own_items = request.user.has_perm('ishtar_common.view_own_person', models.Person) if not all_items and not own_items or not request.GET.get('term'): - return HttpResponse('[]', mimetype='text/plain') + return HttpResponse('[]', content_type='text/plain') q = request.GET.get('term') limit = request.GET.get('limit', 20) try: @@ -493,12 +498,12 @@ def autocomplete_person(request, person_types=None, attached_to=None, 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') + return HttpResponse(data, content_type='text/plain') def autocomplete_department(request): if not request.GET.get('term'): - return HttpResponse('[]', mimetype='text/plain') + return HttpResponse('[]', content_type='text/plain') q = request.GET.get('term') q = unicodedata.normalize("NFKD", q).encode('ascii', 'ignore') query = Q() @@ -509,12 +514,12 @@ def autocomplete_department(request): departments = models.Department.objects.filter(query)[:limit] data = json.dumps([{'id': department.pk, 'value': unicode(department)} for department in departments]) - return HttpResponse(data, mimetype='text/plain') + return HttpResponse(data, content_type='text/plain') def autocomplete_town(request): if not request.GET.get('term'): - return HttpResponse(mimetype='text/plain') + return HttpResponse(content_type='text/plain') q = request.GET.get('term') q = unicodedata.normalize("NFKD", q).encode('ascii', 'ignore') query = Q() @@ -527,12 +532,12 @@ def autocomplete_town(request): 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') + return HttpResponse(data, content_type='text/plain') def autocomplete_advanced_town(request, department_id=None, state_id=None): if not request.GET.get('term'): - return HttpResponse(mimetype='text/plain') + return HttpResponse(content_type='text/plain') q = request.GET.get('term') q = unicodedata.normalize("NFKD", q).encode('ascii', 'ignore') query = Q() @@ -556,7 +561,7 @@ def autocomplete_advanced_town(request, department_id=None, state_id=None): val += " (%s)" % town.numero_insee result.append({'id': town.pk, 'value': val}) data = json.dumps(result) - return HttpResponse(data, mimetype='text/plain') + return HttpResponse(data, content_type='text/plain') def department_by_state(request, state_id=''): @@ -567,7 +572,7 @@ def department_by_state(request, state_id=''): data = json.dumps([{'id': department.pk, 'number': department.number, 'value': unicode(department)} for department in departments]) - return HttpResponse(data, mimetype='text/plain') + return HttpResponse(data, content_type='text/plain') def format_val(val): @@ -582,7 +587,24 @@ def format_val(val): HIERARCHIC_LEVELS = 5 HIERARCHIC_FIELDS = ['periods', 'period', 'unit', 'material_types', - 'material_type', 'conservatory_state'] + 'material_type', 'conservatory_state', 'object_types'] + + +def _get_values(request, val): + if hasattr(val, 'all'): # manage related objects + vals = list(val.all()) + else: + vals = [val] + new_vals = [] + for v in vals: + if callable(v): + v = v() + if hasattr(v, 'url'): + v = request.is_secure() and \ + 'https' or 'http' + '://' + \ + request.get_host() + v.url + new_vals.append(v) + return new_vals def get_item(model, func_name, default_name, extra_request_keys=[], @@ -607,7 +629,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[], allowed, own = models.check_model_access_control(request, model, available_perms) if not allowed: - return HttpResponse(EMPTY, mimetype='text/plain') + return HttpResponse(EMPTY, content_type='text/plain') if force_own: own = True @@ -653,8 +675,9 @@ def get_item(model, func_name, default_name, extra_request_keys=[], else: my_relation_types_prefix = copy(relation_types_prefix) - fields = [model._meta.get_field_by_name(k)[0] - for k in model._meta.get_all_field_names()] + fields = [model._meta.get_field(k) + for k in get_all_field_names(model)] + request_keys = dict([ (field.name, field.name + (hasattr(field, 'rel') and field.rel and '__pk' @@ -666,8 +689,8 @@ def get_item(model, func_name, default_name, extra_request_keys=[], continue associated_model = globals()[associated_model] associated_fields = [ - associated_model._meta.get_field_by_name(k)[0] - for k in associated_model._meta.get_all_field_names()] + associated_model._meta.get_field(k) + for k in get_all_field_names(associated_model)] request_keys.update( dict([(key + "__" + field.name, key + "__" + field.name + @@ -683,7 +706,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[], try: old = 'old' in request_items and int(request_items['old']) except ValueError: - return HttpResponse('[]', mimetype='text/plain') + return HttpResponse('[]', content_type='text/plain') # manage relations types if 'relation_types' not in my_relation_types_prefix: @@ -711,6 +734,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[], q = Q(**{req_key: val}) reqs |= q and_reqs.append(reqs) + pinned_search = "" if 'submited' not in request_items and full != 'shortcut': # default search @@ -730,7 +754,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[], try: dct = {"pk": request.session[default_name]} pinned_search = unicode(model._meta.verbose_name)\ - + u" - " + unicode( + + u" - " + unicode( model.objects.get(pk=dct["pk"])) except model.DoesNotExist: pass @@ -856,7 +880,11 @@ def get_item(model, func_name, default_name, extra_request_keys=[], query |= Q(**altor_dct) if own: - query = query & model.get_query_owns(request.user) + q = models.IshtarUser.objects.filter(user_ptr=request.user) + if q.count(): + query = query & model.get_query_owns(q.all()[0]) + else: + return HttpResponse(EMPTY, content_type='text/plain') for and_req in and_reqs: query = query & and_req @@ -1007,23 +1035,11 @@ def get_item(model, func_name, default_name, extra_request_keys=[], val = list(val.all()) for v in val: v = getattr(v, ky) - if callable(v): - v = v() - if hasattr(v, 'url'): - v = request.is_secure() and \ - 'https' or 'http' + '://' + \ - request.get_host() + v.url - new_vals.append(v) + new_vals += _get_values(request, v) elif val: try: val = getattr(val, ky) - if callable(val): - val = val() - if hasattr(val, 'url'): - val = request.is_secure() and \ - 'https' or 'http' + '://' + \ - request.get_host() + val.url - new_vals.append(val) + new_vals += _get_values(request, val) except AttributeError: # must be a query key such as "contains" pass @@ -1111,9 +1127,9 @@ def get_item(model, func_name, default_name, extra_request_keys=[], "page": page_nb, "total": (items_nb / row_nb + 1) if row_nb else items_nb, }) - return HttpResponse(data, mimetype='text/plain') + return HttpResponse(data, content_type='text/plain') elif data_type == "csv": - response = HttpResponse(mimetype='text/csv') + response = HttpResponse(content_type='text/csv') n = datetime.datetime.now() filename = u'%s_%s.csv' % (default_name, n.strftime('%Y%m%d-%H%M%S')) @@ -1154,14 +1170,15 @@ def get_item(model, func_name, default_name, extra_request_keys=[], val = data[1:][idx + delta].encode( ENCODING, errors='replace') if col_name and "|" in col_name[0]: - for delta_idx in range(len(col_name[0].split('|')) - 1): + for delta_idx in range( + len(col_name[0].split('|')) - 1): delta += 1 val += data[1:][idx + delta].encode( ENCODING, errors='replace') row.append(val) writer.writerow(row) return response - return HttpResponse('{}', mimetype='text/plain') + return HttpResponse('{}', content_type='text/plain') return func @@ -1173,7 +1190,7 @@ def get_by_importer(request, slug, data_type='json', full=False, res = '' if data_type == "json": res = '{}' - return HttpResponse(res, mimetype='text/plain') + return HttpResponse(res, content_type='text/plain') imp = q.all()[0].get_importer_class() cols, col_names = [], [] for formater in imp.LINE_FORMAT: @@ -1193,8 +1210,7 @@ def display_item(model, extra_dct=None, show_url=None): dct['show_url'] = "/{}{}/".format(show_url, pk) else: dct['show_url'] = "/show-{}/{}/".format(model.SLUG, pk) - return render_to_response('ishtar/display_item.html', dct, - context_instance=RequestContext(request)) + return render(request, 'ishtar/display_item.html', dct) return func @@ -1231,7 +1247,7 @@ def show_item(model, name, extra_dct=None): item = item.get_previous(date=date) assert item is not None except (ValueError, AssertionError): - return HttpResponse(None, mimetype='text/plain') + return HttpResponse(None, content_type='text/plain') dct['previous'] = item._previous dct['next'] = item._next else: @@ -1244,8 +1260,7 @@ def show_item(model, name, extra_dct=None): # add context if extra_dct: dct.update(extra_dct(request, item)) - context_instance = RequestContext(request) - context_instance.update(dct) + context_instance = deepcopy(dct) context_instance['output'] = 'html' if hasattr(item, 'history_object'): filename = item.history_object.associated_filename @@ -1254,7 +1269,7 @@ def show_item(model, name, extra_dct=None): if doc_type == "odt" and settings.ODT_TEMPLATE: tpl = loader.get_template('ishtar/sheet_%s.html' % name) context_instance['output'] = 'ODT' - content = tpl.render(context_instance) + content = tpl.render(context_instance, request) try: tidy_options = {'output-xhtml': 1, 'indent': 1, 'tidy-mark': 0, 'doctype': 'auto', @@ -1286,7 +1301,7 @@ def show_item(model, name, extra_dct=None): except xhtml2odt.ODTExportError: return HttpResponse(content, content_type="application/xhtml") response = HttpResponse( - mimetype='application/vnd.oasis.opendocument.text') + content_type='application/vnd.oasis.opendocument.text') response['Content-Disposition'] = 'attachment; filename=%s.odt' % \ filename response.write(odtfile) @@ -1294,14 +1309,14 @@ def show_item(model, name, extra_dct=None): elif doc_type == 'pdf': tpl = loader.get_template('ishtar/sheet_%s_pdf.html' % name) context_instance['output'] = 'PDF' - content = tpl.render(context_instance) + content = tpl.render(context_instance, request) result = StringIO.StringIO() html = content.encode('utf-8') html = html.replace("<table", "<pdf:nextpage/><table repeat='1'") pdf = pisa.pisaDocument(StringIO.StringIO(html), result, encoding='utf-8') response = HttpResponse(result.getvalue(), - mimetype='application/pdf') + content_type='application/pdf') response['Content-Disposition'] = 'attachment; filename=%s.pdf' % \ filename if not pdf.err: @@ -1309,7 +1324,7 @@ def show_item(model, name, extra_dct=None): return HttpResponse(content, content_type="application/xhtml") else: tpl = loader.get_template('ishtar/sheet_%s_window.html' % name) - content = tpl.render(context_instance) + content = tpl.render(context_instance, request) return HttpResponse(content, content_type="application/xhtml") return func @@ -1321,8 +1336,8 @@ def revert_item(model): 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 HttpResponse(None, content_type='text/plain') + return HttpResponse("True", content_type='text/plain') return func @@ -1333,9 +1348,9 @@ def autocomplete_organization(request, orga_type=None): models.Organization) and not request.user.ishtaruser.has_right( 'person_search', session=request.session)): - return HttpResponse('[]', mimetype='text/plain') + return HttpResponse('[]', content_type='text/plain') if not request.GET.get('term'): - return HttpResponse('[]', mimetype='text/plain') + return HttpResponse('[]', content_type='text/plain') q = request.GET.get('term') query = Q() for q in q.split(' '): @@ -1352,16 +1367,16 @@ def autocomplete_organization(request, orga_type=None): 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') + return HttpResponse(data, content_type='text/plain') def autocomplete_author(request): if not request.user.has_perm('ishtar_common.view_author', models.Author)\ and not request.user.has_perm('ishtar_common.view_own_author', models.Author): - return HttpResponse('[]', mimetype='text/plain') + return HttpResponse('[]', content_type='text/plain') if not request.GET.get('term'): - return HttpResponse('[]', mimetype='text/plain') + return HttpResponse('[]', content_type='text/plain') q = request.GET.get('term') query = Q() for q in q.split(' '): @@ -1374,7 +1389,7 @@ def autocomplete_author(request): 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') + return HttpResponse(data, content_type='text/plain') def new_item(model, frm, many=False): @@ -1396,13 +1411,10 @@ def new_item(model, frm, many=False): 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)) + return render(request, 'window.html', dct) else: dct['form'] = frm(limits=limits) - return render_to_response('window.html', dct, - context_instance=RequestContext(request)) + return render(request, 'window.html', dct) return func new_person = new_item(models.Person, forms.PersonForm) @@ -1431,8 +1443,7 @@ def action(request, action_slug, obj_id=None, *args, **kwargs): globals_dct = globals() if action_slug in globals_dct: return globals_dct[action_slug](request, dct, obj_id, *args, **kwargs) - return render_to_response('index.html', dct, - context_instance=RequestContext(request)) + return render(request, 'index.html', dct) def dashboard_main(request, dct, obj_id=None, *args, **kwargs): @@ -1452,8 +1463,7 @@ def dashboard_main(request, dct, obj_id=None, *args, **kwargs): app_list.append((_(u"Treatment requests"), 'treatmentfiles')) app_list.append((_(u"Treatments"), 'treatments')) dct = {'app_list': app_list} - return render_to_response('ishtar/dashboards/dashboard_main.html', dct, - context_instance=RequestContext(request)) + return render(request, 'ishtar/dashboards/dashboard_main.html', dct) DASHBOARD_FORMS = { 'files': DashboardFormFile, 'operations': DashboardFormOpe, @@ -1468,9 +1478,8 @@ def dashboard_main_detail(request, item_name): """ if item_name == 'users': dct = {'ishtar_users': models.UserDashboard()} - return render_to_response( - 'ishtar/dashboards/dashboard_main_detail_users.html', - dct, context_instance=RequestContext(request)) + return render( + request, 'ishtar/dashboards/dashboard_main_detail_users.html', dct) form = None slicing, date_source, fltr, show_detail = 'year', None, {}, False profile = models.get_current_profile() @@ -1534,8 +1543,7 @@ def dashboard_main_detail(request, item_name): n = datetime.datetime.now() dct['unique_id'] = dct['item_name'] + "_" + \ '%d_%d_%d' % (n.minute, n.second, n.microsecond) - return render_to_response('ishtar/dashboards/dashboard_main_detail.html', - dct, context_instance=RequestContext(request)) + return render(request, 'ishtar/dashboards/dashboard_main_detail.html', dct) def reset_wizards(request): @@ -1587,9 +1595,7 @@ def merge_action(model, form, key): return redirect(reverse(current_url, kwargs={'page': page})) else: context['formset'] = FormSet(queryset=queryset) - return render_to_response( - 'ishtar/merge_' + key + '.html', context, - context_instance=RequestContext(request)) + return render(request, 'ishtar/merge_' + key + '.html', context) return merge @@ -1659,6 +1665,11 @@ class NewImportView(IshtarMixin, LoginRequiredMixin, CreateView): def get_success_url(self): return reverse('current_imports') + def get_form_kwargs(self): + kwargs = super(NewImportView, self).get_form_kwargs() + kwargs['user'] = self.request.user + return kwargs + def form_valid(self, form): user = models.IshtarUser.objects.get(pk=self.request.user.pk) self.object = form.save(user=user) @@ -1698,7 +1709,7 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView): return HttpResponseRedirect(reverse('import_delete', kwargs={'pk': imprt.pk})) elif action == 'A': - imprt.initialize() + imprt.initialize(user=self.request.user.ishtaruser) elif action == 'I': imprt.importation() elif action == 'AC': @@ -1719,18 +1730,24 @@ class ImportOldListView(ImportListView): class ImportLinkView(IshtarMixin, LoginRequiredMixin, ModelFormSetView): - template_name = 'ishtar/formset.html' + template_name = 'ishtar/formset_import_match.html' model = models.TargetKey page_name = _(u"Link unmatched items") extra = 0 form_class = forms.TargetKeyForm + formset_class = forms.TargetKeyFormset + + def get_formset_kwargs(self): + kwargs = super(ImportLinkView, self).get_formset_kwargs() + kwargs['user'] = self.request.user + return kwargs def get_queryset(self): return self.model.objects.filter( is_set=False, associated_import=self.kwargs['pk']) def get_success_url(self): - return reverse('current_imports') + return reverse('import_link_unmatched', args=[self.kwargs['pk']]) class ImportDeleteView(IshtarMixin, LoginRequiredMixin, DeleteView): |