def options(request): option_defaults = dict(basket_thumbnails='square', ) class UserInterfaceForm(forms.Form): basket_thumbnails = forms.ChoiceField(choices=[ ('square', 'Square'), ('normal', 'Normal'), ]) if request.method == "POST": ui_form = UserInterfaceForm(request.POST) if ui_form.is_valid(): for key in option_defaults.keys(): store_settings(request.user, 'options_%s' % key, ui_form.cleaned_data[key]) request.user.message_set.create( message="Updated settings have been saved.") return HttpResponseRedirect(request.get_full_path()) else: initial = option_defaults.copy() initial.update( dict((key[8:], val[0]) for (key, val) in load_settings( request.user, filter='options_').iteritems())) ui_form = UserInterfaceForm(initial) return render_to_response('ui_options.html', { 'ui_form': ui_form, }, context_instance=RequestContext(request))
def options(request): option_defaults = dict( basket_thumbnails='square', ) class UserInterfaceForm(forms.Form): basket_thumbnails = forms.ChoiceField(choices=[('square', 'Square'), ('normal', 'Normal'),], label='Basket and lighttable thumbnails') alternate_password = forms.CharField(required=False, help_text='<small>Alternate Password for e.g. Desktop MediaViewer login</small>') if request.method == "POST": ui_form = UserInterfaceForm(request.POST) if ui_form.is_valid(): for key in option_defaults.keys(): store_settings(request.user, 'options_%s' % key, ui_form.cleaned_data[key]) if ui_form.cleaned_data['alternate_password'] != '[unchanged]': set_alternate_password(request.user, ui_form.cleaned_data['alternate_password']) request.user.message_set.create(message="Updated settings have been saved.") return HttpResponseRedirect(request.get_full_path()) else: initial = option_defaults.copy() initial.update(dict((key[8:], val[0]) for (key, val) in load_settings(request.user, filter='options_').iteritems())) initial['alternate_password'] = '******' ui_form = UserInterfaceForm(initial) return render_to_response('ui_options.html', { 'ui_form': ui_form, }, context_instance=RequestContext(request))
def options(request): option_defaults = dict( basket_thumbnails='square', ) class UserInterfaceForm(forms.Form): basket_thumbnails = forms.ChoiceField(choices=[('square', 'Square'), ('normal', 'Normal'),]) if request.method == "POST": ui_form = UserInterfaceForm(request.POST) if ui_form.is_valid(): for key in option_defaults.keys(): store_settings(request.user, 'options_%s' % key, ui_form.cleaned_data[key]) request.user.message_set.create(message="Updated settings have been saved.") return HttpResponseRedirect(request.get_full_path()) else: initial = option_defaults.copy() initial.update(dict((key[8:], val[0]) for (key, val) in load_settings(request.user, filter='options_').iteritems())) ui_form = UserInterfaceForm(initial) return render_to_response('ui_options.html', { 'ui_form': ui_form, }, context_instance=RequestContext(request))
def options(request): option_defaults = dict( basket_thumbnails='square', ) class UserInterfaceForm(forms.Form): basket_thumbnails = forms.ChoiceField( choices=[('square', 'Square'), ('normal', 'Normal')], label='Basket and lighttable thumbnails' ) alternate_password = forms.CharField( required=False, help_text='<small>Alternate Password for e.g. Desktop ' 'MediaViewer login</small>' ) if request.method == "POST": ui_form = UserInterfaceForm(request.POST) if ui_form.is_valid(): for key in option_defaults.keys(): store_settings( request.user, 'options_%s' % key, ui_form.cleaned_data[key] ) if ui_form.cleaned_data['alternate_password'] != '[unchanged]': set_alternate_password( request.user, ui_form.cleaned_data['alternate_password']) messages.add_message( request, messages.INFO, message="Updated settings have been saved." ) return HttpResponseRedirect(request.get_full_path()) else: initial = option_defaults.copy() initial.update(dict( (key[8:], val[0]) for (key, val) in load_settings( request.user, filter='options_' ).iteritems() )) initial['alternate_password'] = '******' ui_form = UserInterfaceForm(initial) return render_to_response( 'ui_options.html', { 'ui_form': ui_form, }, context_instance=RequestContext(request) )
def handle(self, *args, **kwargs): username = kwargs.get('user') if not username: print >> sys.stderr, "--user is a required parameter" return user = User.objects.get(username=username) s = json.loads(' '.join(sys.stdin.readlines())) for k, v in s.iteritems(): print "Importing %s" % k store_settings(user, k, v[0])
def m_browse(request, manage=False): if manage and not request.user.is_authenticated(): raise Http404() if request.user.is_authenticated() and not request.GET.items(): #retrieve past settings qs = load_settings(request.user, filter='presentation_browse_querystring') if qs.has_key('presentation_browse_querystring'): return HttpResponseRedirect('%s?%s' % ( reverse('presentation-manage' if manage else 'presentation-browse'), qs['presentation_browse_querystring'][0], )) presenter = request.GET.get('presenter') tags = filter(None, request.GET.getlist('t')) untagged = 1 if request.GET.get('ut') else 0 if untagged: tags = [] remove_tag = request.GET.get('rt') if remove_tag and remove_tag in tags: tags.remove(remove_tag) keywords = request.GET.get('kw', '') get = request.GET.copy() get.setlist('t', tags) if get.has_key('rt'): del get['rt'] if untagged: get['ut'] = '1' elif get.has_key('ut'): del get['ut'] if request.user.is_authenticated(): existing_tags = Tag.objects.usage_for_model(OwnedWrapper, filters=dict(user=request.user, content_type=OwnedWrapper.t(Presentation))) else: existing_tags = () if untagged and request.user.is_authenticated(): qs = TaggedItem.objects.filter(content_type=OwnedWrapper.t(OwnedWrapper)).values('object_id').distinct() qs = OwnedWrapper.objects.filter(user=request.user, content_type=OwnedWrapper.t(Presentation), id__in=qs).values('object_id') q = ~Q(id__in=qs) elif tags: qs = OwnedWrapper.objects.filter(content_type=OwnedWrapper.t(Presentation)) # get list of matching IDs for each individual tag, since tags may be attached by different owners ids = [list(TaggedItem.objects.get_by_model(qs, '"%s"' % tag).values_list('object_id', flat=True)) for tag in tags] q = Q(*(Q(id__in=x) for x in ids)) else: q = Q() if presenter: presenter = User.objects.get(username=presenter) qp = Q(owner=presenter) else: qp = Q() if keywords: qk = Q(*(Q(title__icontains=kw) | Q(description__icontains=kw) | Q(owner__last_name__icontains=kw) | Q(owner__first_name__icontains=kw) | Q(owner__username__icontains=kw) for kw in keywords.split())) else: qk = Q() if manage: qv = Q() presentations = filter_by_access(request.user, Presentation, write=True, manage=True) else: qv = Presentation.published_Q() presentations = filter_by_access(request.user, Presentation ) presentations = presentations.select_related('owner').filter(q, qp, qk, qv).order_by('title') if request.method == "POST": if manage and (request.POST.get('hide') or request.POST.get('unhide')) and request.user.has_perm('presentation.publish_presentations'): hide = request.POST.get('hide') or False ids = map(int, request.POST.getlist('h')) for presentation in Presentation.objects.filter(owner=request.user, id__in=ids): presentation.hidden = hide presentation.save() if manage and request.POST.get('delete'): ids = map(int, request.POST.getlist('h')) Presentation.objects.filter(owner=request.user, id__in=ids).delete() get['kw'] = request.POST.get('kw') if get['kw'] != request.POST.get('okw') and get.has_key('page'): # user entered keywords, reset page counter del get['page'] if request.POST.get('update_tags'): ids = map(int, request.POST.getlist('h')) update_actionbar_tags(request, *presentations.filter(id__in=ids)) # check for clicks on "add selected items" buttons for button in filter(lambda k: k.startswith('add-selected-items-'), request.POST.keys()): id = int(button[len('add-selected-items-'):]) presentation = get_object_or_404( filter_by_access(request.user, Presentation, write=True, manage=True).filter(id=id)) add_selected_items(request, presentation) return HttpResponseRedirect(reverse('presentation-edit', args=(presentation.id, presentation.name))) return HttpResponseRedirect(request.path + '?' + get.urlencode()) active_tags = tags active_presenter = presenter def col(model, field): qn = backend.DatabaseOperations().quote_name return '%s.%s' % (qn(model._meta.db_table), qn(model._meta.get_field(field).column)) if presentations and not manage: q = OwnedWrapper.objects.extra( tables=(Presentation._meta.db_table,), where=('%s=%s' % (col(OwnedWrapper, 'object_id'), col(Presentation, 'id')), '%s=%s' % (col(OwnedWrapper, 'user'), col(Presentation, 'owner')))).filter( object_id__in=presentations.values('id'), content_type=OwnedWrapper.t(Presentation)) tags = Tag.objects.usage_for_queryset(q, counts=True) for p in presentations: p.verify_password(request) else: tags = () if presentations and request.user.is_authenticated(): usertags = Tag.objects.usage_for_queryset(OwnedWrapper.objects.filter( user=request.user, object_id__in=presentations.values('id'), content_type=OwnedWrapper.t(Presentation)), counts=True) else: usertags = () presenters = User.objects.filter(presentation__in=presentations) \ .annotate(presentations=Count('presentation')).order_by('last_name', 'first_name') if request.user.is_authenticated() and presentations: # save current settings querystring = request.GET.urlencode() store_settings(request.user, 'presentation_browse_querystring', querystring) return render_to_response('m_presentation_browse.html', {'manage': manage, 'tags': tags if len(tags) > 0 else None, 'untagged': untagged, 'usertags': usertags if len(usertags) > 0 else None, 'active_tags': active_tags, 'active_presenter': presenter, 'presentations': presentations, 'presenters': presenters if len(presenters) > 1 else None, 'keywords': keywords, }, context_instance=RequestContext(request))
def browse(request, manage=False): if manage and not request.user.is_authenticated(): raise Http404() if request.user.is_authenticated() and not list(request.GET.items()) and \ not getattr(settings, 'FORGET_PRESENTATION_BROWSE_FILTER', False): # retrieve past settings qs = load_settings( request.user, filter='presentation_browse_querystring') if 'presentation_browse_querystring' in qs: # Don't restore the "untagged only" setting, as it confuses # a lot of users args = qs['presentation_browse_querystring'][0] args = '&'.join( p for p in args.split('&') if not p.startswith('ut=') ) return HttpResponseRedirect( '%s?%s' % ( reverse('presentation-manage' if manage else 'presentation-browse'), args, ) ) presenter = request.GET.get('presenter') tags = [_f for _f in request.GET.getlist('t') if _f] sortby = request.GET.get('sortby') if sortby not in ('title', 'created', 'modified'): sortby = 'title' untagged = 1 if request.GET.get('ut') else 0 if untagged: tags = [] remove_tag = request.GET.get('rt') if remove_tag and remove_tag in tags: tags.remove(remove_tag) keywords = request.GET.get('kw', '') get = request.GET.copy() get.setlist('t', tags) if 'rt' in get: del get['rt'] if untagged: get['ut'] = '1' elif 'ut' in get: del get['ut'] if untagged and request.user.is_authenticated(): qs = TaggedItem.objects.filter( content_type=OwnedWrapper.t(OwnedWrapper) ).values('object_id').distinct() qs = OwnedWrapper.objects.filter( user=request.user, content_type=OwnedWrapper.t(Presentation), id__in=qs ).values('object_id') q = ~Q(id__in=qs) elif tags: qs = OwnedWrapper.objects.filter( content_type=OwnedWrapper.t(Presentation)) # get list of matching IDs for each individual tag, since tags # may be attached by different owners ids = [ list( TaggedItem.objects .get_by_model(qs, '"%s"' % tag) .values_list('object_id', flat=True) ) for tag in tags ] q = Q(*(Q(id__in=x) for x in ids)) else: q = Q() if presenter: presenter = User.objects.get(username=presenter) qp = Q(owner=presenter) else: qp = Q() if keywords: qk = Q(*(Q(title__icontains=kw) | Q(description__icontains=kw) | Q(owner__last_name__icontains=kw) | Q(owner__first_name__icontains=kw) | Q(owner__username__icontains=kw) for kw in keywords.split())) else: qk = Q() if manage: qv = Q() presentations = filter_by_access( request.user, Presentation, write=True, manage=True) else: qv = Presentation.published_q() presentations = filter_by_access(request.user, Presentation) presentations = presentations.select_related('owner').filter(q, qp, qk, qv) presentations = presentations.order_by( '-' + sortby if sortby != 'title' else sortby) if request.method == "POST": if manage and ( request.POST.get('hide') or request.POST.get('unhide') ) and request.user.has_perm('presentation.publish_presentations'): hide = request.POST.get('hide') or False ids = list(map(int, request.POST.getlist('h'))) for presentation in Presentation.objects.filter( owner=request.user, id__in=ids): presentation.hidden = hide presentation.save() if manage and request.POST.get('delete'): ids = list(map(int, request.POST.getlist('h'))) Presentation.objects.filter( owner=request.user, id__in=ids).delete() get['kw'] = request.POST.get('kw') if get['kw'] != request.POST.get('okw') and 'page' in get: # user entered keywords, reset page counter del get['page'] if request.POST.get('update_tags'): ids = list(map(int, request.POST.getlist('h'))) update_actionbar_tags(request, *presentations.filter(id__in=ids)) # check for clicks on "add selected items" buttons for button in [k for k in list(request.POST.keys()) if k.startswith('add-selected-items-')]: id = int(button[len('add-selected-items-'):]) presentation = get_object_or_404( filter_by_access( request.user, Presentation, write=True, manage=True) .filter(id=id) ) add_selected_items(request, presentation) return HttpResponseRedirect( reverse( 'presentation-edit', args=(presentation.id, presentation.name) ) ) return HttpResponseRedirect(request.path + '?' + get.urlencode()) active_tags = tags def col(model, field): qn = connection.ops.quote_name return '%s.%s' % ( qn(model._meta.db_table), qn(model._meta.get_field(field).column) ) if presentations: q = OwnedWrapper.objects.extra( tables=(Presentation._meta.db_table,), where=( '%s=%s' % ( col(OwnedWrapper, 'object_id'), col(Presentation, 'id') ), '%s=%s' % ( col(OwnedWrapper, 'user'), col(Presentation, 'owner') ) ) ).filter( object_id__in=presentations.values('id'), content_type=OwnedWrapper.t(Presentation) ) tags = Tag.objects.usage_for_queryset(q, counts=True) if not manage: for p in presentations: p.verify_password(request) else: tags = () if presentations and request.user.is_authenticated(): usertags = Tag.objects.usage_for_queryset( OwnedWrapper.objects.filter( user=request.user, object_id__in=presentations.values('id'), content_type=OwnedWrapper.t(Presentation) ), counts=True ) else: usertags = () presenters = User.objects.filter(presentation__in=presentations) \ .annotate(presentations=Count('presentation')) \ .order_by('last_name', 'first_name') if request.user.is_authenticated() and presentations: # save current settings querystring = request.GET.urlencode() store_settings( request.user, 'presentation_browse_querystring', querystring) if presentations: paginator = Paginator(presentations, 50) page = request.GET.get('page') try: presentations = paginator.page(page) except PageNotAnInteger: presentations = paginator.page(1) except EmptyPage: presentations = paginator.page(paginator.num_pages) return render( request, 'presentation_browse.html', { 'manage': manage, 'tags': tags if len(tags) > 0 else None, 'untagged': untagged, 'usertags': usertags if len(usertags) > 0 else None, 'active_tags': active_tags, 'active_presenter': presenter, 'presentations': presentations, 'presenters': presenters if len(presenters) > 1 else None, 'keywords': keywords, 'sortby': sortby, } )
def data_import_file(request, file): available_collections = filter_by_access(request.user, Collection) writable_collection_ids = list(filter_by_access(request.user, Collection, write=True).values_list('id', flat=True)) if not available_collections: raise Http404 available_fieldsets = FieldSet.for_user(request.user) def _get_fields(): return Field.objects.select_related('standard').all().order_by('standard', 'name') def _field_choices(): fsf = list(FieldSetField.objects.select_related('fieldset', 'field').exclude(fieldset__name__startswith='browse-collection-').exclude(fieldset__name='facet-fields').order_by('fieldset__name', 'order', 'field__label')) grouped = {} for f in fsf: grouped.setdefault((f.fieldset.title, f.fieldset.id), []).append(f.field) others = list(Field.objects.exclude(id__in=[f.field.id for f in fsf]).order_by('label').values_list('id', 'label')) choices = [('', '-' * 10)] + [(set[0], [(f.id, f.label) for f in fields]) for set, fields in sorted(grouped.iteritems(), key=lambda s: s[0][0])] if others: choices.append(('Others', others)) return choices #def _field_choices(): # grouped = {} # for f in _get_fields(): # grouped.setdefault(f.standard and f.standard.title or 'Other', []).append(f) # return [('0', '[do not import]'), ('-1', '[new field]')] + \ # [(g, [(f.id, f.label) for f in grouped[g]]) for g in grouped] class ImportOptionsForm(forms.Form): separator = forms.CharField(required=False) collections = forms.MultipleChoiceField(choices=((c.id, '%s%s' % ('*' if c.id in writable_collection_ids else '', c.title)) for c in sorted(available_collections, key=lambda c: c.title)), widget=forms.CheckboxSelectMultiple) fieldset = FieldSetChoiceField(user=request.user, default_label='any') #forms.ChoiceField(choices=[(0, 'any')] + [(f.id, f.title) for f in available_fieldsets], required=False) update = forms.BooleanField(label='Update existing records', initial=True, required=False) add = forms.BooleanField(label='Add new records', initial=True, required=False) test = forms.BooleanField(label='Test import only', initial=False, required=False) personal = forms.BooleanField(label='Personal records', initial=False, required=False) def clean(self): cleaned_data = self.cleaned_data if any(self.errors): return cleaned_data personal = cleaned_data['personal'] if not personal: for c in map(int, cleaned_data['collections']): if not c in writable_collection_ids: self._errors['collections'] = ErrorList(["Can only add personal records to selected collections"]) del cleaned_data['collections'] return cleaned_data return cleaned_data class MappingForm(forms.Form): fieldname = forms.CharField(widget=DisplayOnlyTextWidget, required=False) mapping = forms.ChoiceField(choices=_field_choices(), required=False) separate = forms.BooleanField(required=False) label = forms.CharField(required=False) hidden = forms.BooleanField(required=False) class BaseMappingFormSet(forms.formsets.BaseFormSet): def clean(self): if any(self.errors): return _dcidentifier = Field.objects.get(name='identifier', standard__prefix='dc') _identifier_ids = list(_dcidentifier.get_equivalent_fields().values_list('id', flat=True)) + [_dcidentifier.id] for i in range(self.total_form_count()): if self.forms[i].cleaned_data['mapping'] and \ (int(self.forms[i].cleaned_data['mapping']) in _identifier_ids): return raise forms.ValidationError, "At least one field must be mapped to an identifier field." MappingFormSet = formset_factory(MappingForm, extra=0, formset=BaseMappingFormSet, can_order=True) def analyze(collections=None, separator=None, separate_fields=None, fieldset=None): try: with open(os.path.join(_get_scratch_dir(), _get_filename(request, file)), 'rU') as csvfile: imp = SpreadsheetImport(csvfile, collections, separator=separator, separate_fields=separate_fields, preferred_fieldset=fieldset) return imp, imp.analyze() except IOError: raise Http404() if request.method == 'POST': form = ImportOptionsForm(request.POST) mapping_formset = MappingFormSet(request.POST, prefix='m') if form.is_valid() and mapping_formset.is_valid(): imp, preview_rows = analyze(available_collections.filter(id__in=form.cleaned_data['collections']), form.cleaned_data['separator'], dict((f.cleaned_data['fieldname'], f.cleaned_data['separate']) for f in mapping_formset.forms), available_fieldsets.get(id=form.cleaned_data['fieldset']) if int(form.cleaned_data.get('fieldset') or 0) else None) store_settings(request.user, 'data_import_file_%s' % imp.field_hash, simplejson.dumps(dict(options=form.cleaned_data, mapping=mapping_formset.cleaned_data))) if request.POST.get('import_button'): j = JobInfo.objects.create(owner=request.user, func='csvimport', arg=simplejson.dumps(dict( file=_get_filename(request, file), separator=form.cleaned_data['separator'], collections=map(int, form.cleaned_data['collections']), update=form.cleaned_data['update'], add=form.cleaned_data['add'], test=form.cleaned_data['test'], personal=form.cleaned_data['personal'], fieldset=form.cleaned_data['fieldset'], mapping=dict((f.cleaned_data['fieldname'], int(f.cleaned_data['mapping'])) for f in mapping_formset.forms if f.cleaned_data['mapping']), separate_fields=dict((f.cleaned_data['fieldname'], f.cleaned_data['separate']) for f in mapping_formset.forms), labels=dict((f.cleaned_data['fieldname'], f.cleaned_data['label']) for f in mapping_formset.forms), order=dict((f.cleaned_data['fieldname'], safe_int(f.cleaned_data['ORDER'], 0)) for f in mapping_formset.forms), hidden=dict((f.cleaned_data['fieldname'], f.cleaned_data['hidden']) for f in mapping_formset.forms), ) )) j.run() request.user.message_set.create(message='Import job has been submitted.') return HttpResponseRedirect("%s?highlight=%s" % (reverse('workers-jobs'), j.id)) else: imp, preview_rows = analyze() else: imp, preview_rows = analyze() # try to load previously stored settings key = 'data_import_file_%s' % imp.field_hash values = load_settings(request.user, key) if values.has_key(key): value = simplejson.loads(values[key][0]) mapping = value['mapping'] options = value['options'] else: mapping = [dict(fieldname=f, mapping=v.id if v else 0, separate=True) for f, v in imp.mapping.iteritems()] options = None mapping = sorted(mapping, key=lambda m: m['fieldname']) mapping_formset = MappingFormSet(initial=mapping, prefix='m') form = ImportOptionsForm(initial=options) return render_to_response('data_import_file.html', {'form': form, 'preview_rows': preview_rows, 'mapping_formset': mapping_formset, 'writable_collections': bool(writable_collection_ids), }, context_instance=RequestContext(request))
def store_current_presentation(user, presentation): store_settings(user, RECENT_PRESENTATION, presentation.id)
def data_import_file(request, file): available_collections = filter_by_access(request.user, Collection) writable_collection_ids = accessible_ids(request.user, Collection, write=True) if not available_collections: raise Http404 available_fieldsets = FieldSet.for_user(request.user) def _get_fields(): return Field.objects.select_related("standard").all().order_by("standard", "name") def _field_choices(): fsf = list( FieldSetField.objects.select_related("fieldset", "field") .all() .order_by("fieldset__name", "order", "field__label") ) grouped = {} for f in fsf: grouped.setdefault((f.fieldset.title, f.fieldset.id), []).append(f.field) others = list( Field.objects.exclude(id__in=[f.field.id for f in fsf]).order_by("label").values_list("id", "label") ) choices = [("", "-" * 10)] + [ (set[0], [(f.id, f.label) for f in fields]) for set, fields in sorted(grouped.iteritems(), key=lambda s: s[0][0]) ] if others: choices.append(("Others", others)) return choices # def _field_choices(): # grouped = {} # for f in _get_fields(): # grouped.setdefault(f.standard and f.standard.title or 'Other', []).append(f) # return [('0', '[do not import]'), ('-1', '[new field]')] + \ # [(g, [(f.id, f.label) for f in grouped[g]]) for g in grouped] class ImportOptionsForm(forms.Form): separator = forms.CharField(required=False) collections = forms.MultipleChoiceField( choices=( (c.id, "%s%s" % ("*" if c.id in writable_collection_ids else "", c.title)) for c in sorted(available_collections, key=lambda c: c.title) ), widget=forms.CheckboxSelectMultiple, ) fieldset = FieldSetChoiceField(user=request.user, default_label="any") # forms.ChoiceField(choices=[(0, 'any')] + [(f.id, f.title) for f in available_fieldsets], required=False) update = forms.BooleanField(label="Update existing records", initial=True, required=False) add = forms.BooleanField(label="Add new records", initial=True, required=False) test = forms.BooleanField(label="Test import only", initial=False, required=False) personal = forms.BooleanField(label="Personal records", initial=True, required=False) def clean(self): cleaned_data = self.cleaned_data if any(self.errors): return cleaned_data personal = cleaned_data["personal"] if not personal: for c in map(int, cleaned_data["collections"]): if not c in writable_collection_ids: self._errors["collections"] = ErrorList( ["Can only add personal records to selected collections"] ) del cleaned_data["collections"] return cleaned_data return cleaned_data class MappingForm(forms.Form): fieldname = forms.CharField(widget=DisplayOnlyTextWidget, required=False) mapping = forms.ChoiceField(choices=_field_choices(), required=False) separate = forms.BooleanField(required=False) label = forms.CharField(required=False) hidden = forms.BooleanField(required=False) class BaseMappingFormSet(forms.formsets.BaseFormSet): def clean(self): if any(self.errors): return _dcidentifier = Field.objects.get(name="identifier", standard__prefix="dc") _identifier_ids = list(_dcidentifier.get_equivalent_fields().values_list("id", flat=True)) + [ _dcidentifier.id ] for i in range(self.total_form_count()): if self.forms[i].cleaned_data["mapping"] and ( int(self.forms[i].cleaned_data["mapping"]) in _identifier_ids ): return raise forms.ValidationError, "At least one field must be mapped to an identifier field." MappingFormSet = formset_factory(MappingForm, extra=0, formset=BaseMappingFormSet, can_order=True) def analyze(collections=None, separator=None, separate_fields=None, fieldset=None): try: with open(os.path.join(_get_scratch_dir(), _get_filename(request, file)), "rU") as csvfile: imp = SpreadsheetImport( csvfile, collections, separator=separator, separate_fields=separate_fields, preferred_fieldset=fieldset, ) return imp, imp.analyze() except IOError: raise Http404() if request.method == "POST": form = ImportOptionsForm(request.POST) mapping_formset = MappingFormSet(request.POST, prefix="m") if form.is_valid() and mapping_formset.is_valid(): imp, preview_rows = analyze( available_collections.filter(id__in=form.cleaned_data["collections"]), form.cleaned_data["separator"], dict((f.cleaned_data["fieldname"], f.cleaned_data["separate"]) for f in mapping_formset.forms), available_fieldsets.get(id=form.cleaned_data["fieldset"]) if int(form.cleaned_data.get("fieldset") or 0) else None, ) store_settings( request.user, "data_import_file_%s" % imp.field_hash, simplejson.dumps(dict(options=form.cleaned_data, mapping=mapping_formset.cleaned_data)), ) if request.POST.get("import_button"): j = JobInfo.objects.create( owner=request.user, func="csvimport", arg=simplejson.dumps( dict( file=os.path.join(_get_scratch_dir(), _get_filename(request, file)), separator=form.cleaned_data["separator"], collections=map(int, form.cleaned_data["collections"]), update=form.cleaned_data["update"], add=form.cleaned_data["add"], test=form.cleaned_data["test"], personal=form.cleaned_data["personal"], fieldset=form.cleaned_data["fieldset"], mapping=dict( (f.cleaned_data["fieldname"], int(f.cleaned_data["mapping"])) for f in mapping_formset.forms if f.cleaned_data["mapping"] ), separate_fields=dict( (f.cleaned_data["fieldname"], f.cleaned_data["separate"]) for f in mapping_formset.forms ), labels=dict( (f.cleaned_data["fieldname"], f.cleaned_data["label"]) for f in mapping_formset.forms ), order=dict( (f.cleaned_data["fieldname"], int(f.cleaned_data["ORDER"])) for f in mapping_formset.forms ), hidden=dict( (f.cleaned_data["fieldname"], f.cleaned_data["hidden"]) for f in mapping_formset.forms ), ) ), ) j.run() request.user.message_set.create(message="Import job has been submitted.") return HttpResponseRedirect("%s?highlight=%s" % (reverse("workers-jobs"), j.id)) else: imp, preview_rows = analyze() else: imp, preview_rows = analyze() # try to load previously stored settings key = "data_import_file_%s" % imp.field_hash values = load_settings(request.user, key) if values.has_key(key): value = simplejson.loads(values[key][0]) mapping = value["mapping"] options = value["options"] else: mapping = [dict(fieldname=f, mapping=v.id if v else 0, separate=True) for f, v in imp.mapping.iteritems()] options = None mapping = sorted(mapping, key=lambda m: m["fieldname"]) mapping_formset = MappingFormSet(initial=mapping, prefix="m") form = ImportOptionsForm(initial=options) return render_to_response( "data_import_file.html", { "form": form, "preview_rows": preview_rows, "mapping_formset": mapping_formset, "writable_collections": bool(writable_collection_ids), }, context_instance=RequestContext(request), )
def browse(request, manage=False): if manage and not request.user.is_authenticated(): raise Http404() if request.user.is_authenticated() and not request.GET.items(): # retrieve past settings qs = load_settings(request.user, filter='presentation_browse_querystring') if qs.has_key('presentation_browse_querystring'): return HttpResponseRedirect('%s?%s' % ( reverse('presentation-manage' if manage else 'presentation-browse'), qs['presentation_browse_querystring'][0], )) presenter = request.GET.get('presenter') tags = filter(None, request.GET.getlist('t')) untagged = 1 if request.GET.get('ut') else 0 if untagged: tags = [] remove_tag = request.GET.get('rt') if remove_tag and remove_tag in tags: tags.remove(remove_tag) keywords = request.GET.get('kw', '') get = request.GET.copy() get.setlist('t', tags) if get.has_key('rt'): del get['rt'] if untagged: get['ut'] = '1' elif get.has_key('ut'): del get['ut'] print tags if request.user.is_authenticated(): existing_tags = Tag.objects.usage_for_model( OwnedWrapper, filters=dict(user=request.user, content_type=OwnedWrapper.t(Presentation))) else: existing_tags = () if untagged and request.user.is_authenticated(): qs = TaggedItem.objects.filter(content_type=OwnedWrapper.t( OwnedWrapper)).values('object_id').distinct() qs = OwnedWrapper.objects.filter( user=request.user, content_type=OwnedWrapper.t(Presentation), id__in=qs).values('object_id') q = ~Q(id__in=qs) elif tags: qs = OwnedWrapper.objects.filter( content_type=OwnedWrapper.t(Presentation)) # get list of matching IDs for each individual tag, since tags may be attached by different owners ids = [ list( TaggedItem.objects.get_by_model(qs, '"%s"' % tag).values_list( 'object_id', flat=True)) for tag in tags ] q = Q(*(Q(id__in=x) for x in ids)) else: q = Q() if presenter: presenter = User.objects.get(username=presenter) qp = Q(owner=presenter) else: qp = Q() if keywords: qk = Q(*(Q(title__icontains=kw) | Q(description__icontains=kw) | Q(owner__last_name__icontains=kw) | Q(owner__first_name__icontains=kw) | Q(owner__username__icontains=kw) for kw in keywords.split())) else: qk = Q() if manage: qv = Q() presentations = filter_by_access(request.user, Presentation, write=True, manage=True) else: qv = Presentation.published_Q() presentations = filter_by_access(request.user, Presentation) presentations = presentations.select_related('owner').filter( q, qp, qk, qv).order_by('title') if request.method == "POST": if manage and ( request.POST.get('hide') or request.POST.get('unhide') ) and request.user.has_perm('presentation.publish_presentations'): hide = request.POST.get('hide') or False ids = map(int, request.POST.getlist('h')) for presentation in Presentation.objects.filter(owner=request.user, id__in=ids): presentation.hidden = hide presentation.save() if manage and request.POST.get('delete'): ids = map(int, request.POST.getlist('h')) Presentation.objects.filter(owner=request.user, id__in=ids).delete() get['kw'] = request.POST.get('kw') if get['kw'] != request.POST.get('okw') and get.has_key('page'): # user entered keywords, reset page counter del get['page'] if request.POST.get('update_tags'): ids = map(int, request.POST.getlist('h')) update_actionbar_tags(request, *presentations.filter(id__in=ids)) # check for clicks on "add selected items" buttons for button in filter(lambda k: k.startswith('add-selected-items-'), request.POST.keys()): id = int(button[len('add-selected-items-'):]) presentation = get_object_or_404( filter_by_access(request.user, Presentation, write=True, manage=True).filter(id=id)) add_selected_items(request, presentation) return HttpResponseRedirect( reverse('presentation-edit', args=(presentation.id, presentation.name))) return HttpResponseRedirect(request.path + '?' + get.urlencode()) active_tags = tags active_presenter = presenter def col(model, field): qn = backend.DatabaseOperations().quote_name return '%s.%s' % (qn( model._meta.db_table), qn(model._meta.get_field(field).column)) if presentations and not manage: q = OwnedWrapper.objects.extra( tables=(Presentation._meta.db_table, ), where=('%s=%s' % (col(OwnedWrapper, 'object_id'), col(Presentation, 'id')), '%s=%s' % (col(OwnedWrapper, 'user'), col(Presentation, 'owner')))).filter( object_id__in=presentations.values('id'), content_type=OwnedWrapper.t(Presentation)) tags = Tag.objects.usage_for_queryset(q, counts=True) for p in presentations: p.verify_password(request) else: tags = () if presentations and request.user.is_authenticated(): usertags = Tag.objects.usage_for_queryset(OwnedWrapper.objects.filter( user=request.user, object_id__in=presentations.values('id'), content_type=OwnedWrapper.t(Presentation)), counts=True) else: usertags = () presenters = User.objects.filter(presentation__in=presentations) \ .annotate(presentations=Count('presentation')).order_by('last_name', 'first_name') if request.user.is_authenticated() and presentations: # save current settings querystring = request.GET.urlencode() store_settings(request.user, 'presentation_browse_querystring', querystring) return render_to_response( 'presentation_browse.html', { 'manage': manage, 'tags': tags if len(tags) > 0 else None, 'untagged': untagged, 'usertags': usertags if len(usertags) > 0 else None, 'active_tags': active_tags, 'active_presenter': presenter, 'presentations': presentations, 'presenters': presenters if len(presenters) > 1 else None, 'keywords': keywords, }, context_instance=RequestContext(request))
def set_collection_visibility_preferences(user, mode, ids): value = '%s:%s' % (mode, ','.join(ids)) return store_settings(user, COLLECTION_VISIBILITY_PREFERENCES, value)
def browse(request, manage=False): if manage and not request.user.is_authenticated(): raise Http404() if request.user.is_authenticated() and not request.GET.items(): # retrieve past settings qs = load_settings(request.user, filter="presentation_browse_querystring") if qs.has_key("presentation_browse_querystring"): return HttpResponseRedirect( "%s?%s" % ( reverse("presentation-manage" if manage else "presentation-browse"), qs["presentation_browse_querystring"][0], ) ) presenter = request.GET.get("presenter") tags = filter(None, request.GET.getlist("t")) sortby = request.GET.get("sortby") if not sortby in ("title", "created", "modified"): sortby = "title" untagged = 1 if request.GET.get("ut") else 0 if untagged: tags = [] remove_tag = request.GET.get("rt") if remove_tag and remove_tag in tags: tags.remove(remove_tag) keywords = request.GET.get("kw", "") get = request.GET.copy() get.setlist("t", tags) if get.has_key("rt"): del get["rt"] if untagged: get["ut"] = "1" elif get.has_key("ut"): del get["ut"] if request.user.is_authenticated(): existing_tags = Tag.objects.usage_for_model( OwnedWrapper, filters=dict(user=request.user, content_type=OwnedWrapper.t(Presentation)) ) else: existing_tags = () if untagged and request.user.is_authenticated(): qs = TaggedItem.objects.filter(content_type=OwnedWrapper.t(OwnedWrapper)).values("object_id").distinct() qs = OwnedWrapper.objects.filter( user=request.user, content_type=OwnedWrapper.t(Presentation), id__in=qs ).values("object_id") q = ~Q(id__in=qs) elif tags: qs = OwnedWrapper.objects.filter(content_type=OwnedWrapper.t(Presentation)) # get list of matching IDs for each individual tag, since tags may be attached by different owners ids = [ list(TaggedItem.objects.get_by_model(qs, '"%s"' % tag).values_list("object_id", flat=True)) for tag in tags ] q = Q(*(Q(id__in=x) for x in ids)) else: q = Q() if presenter: presenter = User.objects.get(username=presenter) qp = Q(owner=presenter) else: qp = Q() if keywords: qk = Q( *( Q(title__icontains=kw) | Q(description__icontains=kw) | Q(owner__last_name__icontains=kw) | Q(owner__first_name__icontains=kw) | Q(owner__username__icontains=kw) for kw in keywords.split() ) ) else: qk = Q() if manage: qv = Q() presentations = filter_by_access(request.user, Presentation, write=True, manage=True) else: qv = Presentation.published_Q() presentations = filter_by_access(request.user, Presentation) presentations = presentations.select_related("owner").filter(q, qp, qk, qv) presentations = presentations.order_by("-" + sortby if sortby != "title" else sortby) if request.method == "POST": if ( manage and (request.POST.get("hide") or request.POST.get("unhide")) and request.user.has_perm("presentation.publish_presentations") ): hide = request.POST.get("hide") or False ids = map(int, request.POST.getlist("h")) for presentation in Presentation.objects.filter(owner=request.user, id__in=ids): presentation.hidden = hide presentation.save() if manage and request.POST.get("delete"): ids = map(int, request.POST.getlist("h")) Presentation.objects.filter(owner=request.user, id__in=ids).delete() get["kw"] = request.POST.get("kw") if get["kw"] != request.POST.get("okw") and get.has_key("page"): # user entered keywords, reset page counter del get["page"] if request.POST.get("update_tags"): ids = map(int, request.POST.getlist("h")) update_actionbar_tags(request, *presentations.filter(id__in=ids)) # check for clicks on "add selected items" buttons for button in filter(lambda k: k.startswith("add-selected-items-"), request.POST.keys()): id = int(button[len("add-selected-items-") :]) presentation = get_object_or_404( filter_by_access(request.user, Presentation, write=True, manage=True).filter(id=id) ) add_selected_items(request, presentation) return HttpResponseRedirect(reverse("presentation-edit", args=(presentation.id, presentation.name))) return HttpResponseRedirect(request.path + "?" + get.urlencode()) active_tags = tags active_presenter = presenter def col(model, field): qn = backend.DatabaseOperations().quote_name return "%s.%s" % (qn(model._meta.db_table), qn(model._meta.get_field(field).column)) if presentations and not manage: q = OwnedWrapper.objects.extra( tables=(Presentation._meta.db_table,), where=( "%s=%s" % (col(OwnedWrapper, "object_id"), col(Presentation, "id")), "%s=%s" % (col(OwnedWrapper, "user"), col(Presentation, "owner")), ), ).filter(object_id__in=presentations.values("id"), content_type=OwnedWrapper.t(Presentation)) tags = Tag.objects.usage_for_queryset(q, counts=True) for p in presentations: p.verify_password(request) else: tags = () if presentations and request.user.is_authenticated(): usertags = Tag.objects.usage_for_queryset( OwnedWrapper.objects.filter( user=request.user, object_id__in=presentations.values("id"), content_type=OwnedWrapper.t(Presentation) ), counts=True, ) else: usertags = () presenters = ( User.objects.filter(presentation__in=presentations) .annotate(presentations=Count("presentation")) .order_by("last_name", "first_name") ) if request.user.is_authenticated() and presentations: # save current settings querystring = request.GET.urlencode() store_settings(request.user, "presentation_browse_querystring", querystring) return render_to_response( "presentation_browse.html", { "manage": manage, "tags": tags if len(tags) > 0 else None, "untagged": untagged, "usertags": usertags if len(usertags) > 0 else None, "active_tags": active_tags, "active_presenter": presenter, "presentations": presentations, "presenters": presenters if len(presenters) > 1 else None, "keywords": keywords, "sortby": sortby, }, context_instance=RequestContext(request), )
def data_import_file(request, file): available_collections = filter_by_access(request.user, Collection) writable_collection_ids = list( filter_by_access(request.user, Collection, write=True).values_list('id', flat=True)) if not available_collections: raise Http404 available_fieldsets = FieldSet.for_user(request.user) def _get_fields(): return Field.objects.select_related('standard').all().order_by( 'standard', 'name') def _field_choices(): fsf = list( FieldSetField.objects.select_related('fieldset', 'field').all().order_by( 'fieldset__name', 'order', 'field__label')) grouped = {} for f in fsf: grouped.setdefault((f.fieldset.title, f.fieldset.id), []).append(f.field) others = list( Field.objects.exclude( id__in=[f.field.id for f in fsf]).order_by('label').values_list( 'id', 'label')) choices = [('', '-' * 10) ] + [(set[0], [(f.id, f.label) for f in fields]) for set, fields in sorted(grouped.iteritems(), key=lambda s: s[0][0])] if others: choices.append(('Others', others)) return choices #def _field_choices(): # grouped = {} # for f in _get_fields(): # grouped.setdefault(f.standard and f.standard.title or 'Other', []).append(f) # return [('0', '[do not import]'), ('-1', '[new field]')] + \ # [(g, [(f.id, f.label) for f in grouped[g]]) for g in grouped] class ImportOptionsForm(forms.Form): separator = forms.CharField(required=False) collections = forms.MultipleChoiceField( choices=( (c.id, '%s%s' % ('*' if c.id in writable_collection_ids else '', c.title)) for c in sorted(available_collections, key=lambda c: c.title)), widget=forms.CheckboxSelectMultiple) fieldset = FieldSetChoiceField(user=request.user, default_label='any') #forms.ChoiceField(choices=[(0, 'any')] + [(f.id, f.title) for f in available_fieldsets], required=False) update = forms.BooleanField(label='Update existing records', initial=True, required=False) add = forms.BooleanField(label='Add new records', initial=True, required=False) test = forms.BooleanField(label='Test import only', initial=False, required=False) personal = forms.BooleanField(label='Personal records', initial=False, required=False) def clean(self): cleaned_data = self.cleaned_data if any(self.errors): return cleaned_data personal = cleaned_data['personal'] if not personal: for c in map(int, cleaned_data['collections']): if not c in writable_collection_ids: self._errors['collections'] = ErrorList([ "Can only add personal records to selected collections" ]) del cleaned_data['collections'] return cleaned_data return cleaned_data class MappingForm(forms.Form): fieldname = forms.CharField(widget=DisplayOnlyTextWidget, required=False) mapping = forms.ChoiceField(choices=_field_choices(), required=False) separate = forms.BooleanField(required=False) label = forms.CharField(required=False) hidden = forms.BooleanField(required=False) class BaseMappingFormSet(forms.formsets.BaseFormSet): def clean(self): if any(self.errors): return _dcidentifier = Field.objects.get(name='identifier', standard__prefix='dc') _identifier_ids = list( _dcidentifier.get_equivalent_fields().values_list( 'id', flat=True)) + [_dcidentifier.id] for i in range(self.total_form_count()): if self.forms[i].cleaned_data['mapping'] and \ (int(self.forms[i].cleaned_data['mapping']) in _identifier_ids): return raise forms.ValidationError, "At least one field must be mapped to an identifier field." MappingFormSet = formset_factory(MappingForm, extra=0, formset=BaseMappingFormSet, can_order=True) def analyze(collections=None, separator=None, separate_fields=None, fieldset=None): try: with open( os.path.join(_get_scratch_dir(), _get_filename(request, file)), 'rU') as csvfile: imp = SpreadsheetImport(csvfile, collections, separator=separator, separate_fields=separate_fields, preferred_fieldset=fieldset) return imp, imp.analyze() except IOError: raise Http404() if request.method == 'POST': form = ImportOptionsForm(request.POST) mapping_formset = MappingFormSet(request.POST, prefix='m') if form.is_valid() and mapping_formset.is_valid(): imp, preview_rows = analyze( available_collections.filter( id__in=form.cleaned_data['collections']), form.cleaned_data['separator'], dict((f.cleaned_data['fieldname'], f.cleaned_data['separate']) for f in mapping_formset.forms), available_fieldsets.get(id=form.cleaned_data['fieldset']) if int(form.cleaned_data.get('fieldset') or 0) else None) store_settings( request.user, 'data_import_file_%s' % imp.field_hash, simplejson.dumps( dict(options=form.cleaned_data, mapping=mapping_formset.cleaned_data))) if request.POST.get('import_button'): j = JobInfo.objects.create( owner=request.user, func='csvimport', arg=simplejson.dumps( dict( file=_get_filename(request, file), separator=form.cleaned_data['separator'], collections=map(int, form.cleaned_data['collections']), update=form.cleaned_data['update'], add=form.cleaned_data['add'], test=form.cleaned_data['test'], personal=form.cleaned_data['personal'], fieldset=form.cleaned_data['fieldset'], mapping=dict((f.cleaned_data['fieldname'], int(f.cleaned_data['mapping'])) for f in mapping_formset.forms if f.cleaned_data['mapping']), separate_fields=dict( (f.cleaned_data['fieldname'], f.cleaned_data['separate']) for f in mapping_formset.forms), labels=dict((f.cleaned_data['fieldname'], f.cleaned_data['label']) for f in mapping_formset.forms), order=dict((f.cleaned_data['fieldname'], int(f.cleaned_data['ORDER'])) for f in mapping_formset.forms), hidden=dict((f.cleaned_data['fieldname'], f.cleaned_data['hidden']) for f in mapping_formset.forms), ))) j.run() request.user.message_set.create( message='Import job has been submitted.') return HttpResponseRedirect("%s?highlight=%s" % (reverse('workers-jobs'), j.id)) else: imp, preview_rows = analyze() else: imp, preview_rows = analyze() # try to load previously stored settings key = 'data_import_file_%s' % imp.field_hash values = load_settings(request.user, key) if values.has_key(key): value = simplejson.loads(values[key][0]) mapping = value['mapping'] options = value['options'] else: mapping = [ dict(fieldname=f, mapping=v.id if v else 0, separate=True) for f, v in imp.mapping.iteritems() ] options = None mapping = sorted(mapping, key=lambda m: m['fieldname']) mapping_formset = MappingFormSet(initial=mapping, prefix='m') form = ImportOptionsForm(initial=options) return render_to_response( 'data_import_file.html', { 'form': form, 'preview_rows': preview_rows, 'mapping_formset': mapping_formset, 'writable_collections': bool(writable_collection_ids), }, context_instance=RequestContext(request))
def set_alternate_password(user, password): logger.debug('Setting alternate password for "%s"' % user.username) encoded_password = _get_encoded_password(password) if password else '!' logger.debug('Setting password to "%s"' % encoded_password[:5]) return store_settings(user, 'alternate_password', encoded_password)
def store_recent_presentation(user, presentation): store_settings(user, RECENT_PRESENTATION, presentation.id) return ''