def retrieve_pseudostream(request, recordid, record, mediaid, media): mediaobj = get_object_or_404(Media.objects.filter(id=mediaid, record__id=recordid, record__collection__id__in=accessible_ids(request.user, Collection), storage__id__in=accessible_ids(request.user, Storage)).distinct()) q = dict() start = request.GET.get('start', '') if start.isdigit(): q['start'] = start end = request.GET.get('end', '') if end.isdigit(): q['end'] = end client = request.GET.get('client') if client: q['client'] = client url = mediaobj.storage.urlbase url = url + ('/' if not url.endswith('/') else '') + mediaobj.url.replace('\\', '/') if q: url = url + '?' + urlencode(q) try: result = urlopen(url) response = HttpResponse(FileWrapper(result), content_type=result.info().get('Content-Type')) response['Content-Length'] = result.info().get('Content-Length') return response except HTTPError, e: return HttpResponse(status=e.errno)
def filter_by_access(user, *ids): records = Record.objects.distinct() ids = map(int, ids) if user: if user.is_superuser: return records.filter(id__in=ids) accessible_records = cache_get_many( ['record-access-%d-%d' % (user.id or 0, id) for id in ids], model_dependencies=[Record, Collection, AccessControl] ) accessible_record_ids = map(lambda (k, v): (int(k.rsplit('-', 1)[1]), v), accessible_records.iteritems()) allowed_ids = [k for k, v in accessible_record_ids if v == 't'] denied_ids = [k for k, v in accessible_record_ids if v == 'f'] to_check = [id for id in ids if not id in allowed_ids and not id in denied_ids] if not to_check: return records.filter(id__in=allowed_ids) else: allowed_ids = [] to_check = ids # check which records have individual ACLs set individual = _records_with_individual_acl_by_ids(to_check) if individual: allowed_ids.extend(accessible_ids(user, Record.objects.filter(id__in=individual))) to_check = [id for id in to_check if not id in individual] # check records without individual ACLs if to_check: cq = Q(collectionitem__collection__in=accessible_ids(user, Collection), collectionitem__hidden=False) mq = Q(collectionitem__collection__in=accessible_ids(user, Collection, write=True), owner=None) oq = Q(owner=user) if user and not user.is_anonymous() else Q() records = records.filter(cq | mq | oq) checked = records.filter(id__in=to_check).values_list('id', flat=True) allowed_ids.extend(checked) if user: cache_update = dict( ('record-access-%d-%d' % (user.id or 0, id), 't' if id in checked else 'f') for id in to_check ) cache_set_many(cache_update, model_dependencies=[Record, Collection, AccessControl]) return records.filter(id__in=allowed_ids)
def powerpoint(request): available_storage = get_list_or_404(filter_by_access(request.user, Storage, write=True).order_by('title').values_list('id', 'title')) available_collections = get_list_or_404(filter_by_access(request.user, Collection, write=True).order_by('title').values_list('id', 'title')) class UploadFileForm(forms.Form): title = forms.CharField(max_length=50) storage = forms.ChoiceField(choices=available_storage) collection = forms.ChoiceField(choices=available_collections) file = forms.FileField() def clean_file(self): file = self.cleaned_data['file'] if not file.content_type in ('application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'): raise forms.ValidationError("The selected file does not appear to be a PowerPoint file") return file if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): tempdir = tempfile.mkdtemp() infile = form.cleaned_data['file'] filename = os.path.join(tempdir, 'a.ppt' if infile.content_type == 'application/vnd.ms-powerpoint' else 'a.pptx') outfile = open(filename, "wb+") for chunk in infile.chunks(): outfile.write(chunk) outfile.close() presentation = convert_ppt(request.user, form.cleaned_data['title'], Collection.objects.get(id=form.cleaned_data['collection'], id__in=accessible_ids(request.user, Collection, write=True)), Storage.objects.get(id=form.cleaned_data['storage'], id__in=accessible_ids(request.user, Storage, write=True)), tempdir, filename) shutil.rmtree(tempdir) if not presentation: request.user.message_set.create(message="An error occurred while importing the presentation.") else: request.user.message_set.create(message="Presentation created successfully.") return HttpResponseRedirect(reverse('presentation-edit', kwargs=dict(id=presentation.id, name=presentation.name))) else: form = UploadFileForm() return render_to_response('powerpoint.html', {'form': form}, context_instance=RequestContext(request))
def password(request, id, name): presentation = get_object_or_404(Presentation.objects.filter(Presentation.published_Q(request.user), id=id, id__in=accessible_ids(request.user, Presentation))) class PasswordForm(forms.Form): password = forms.CharField(widget=forms.PasswordInput) def clean_password(self): p = self.cleaned_data.get('password') if p != presentation.password: raise forms.ValidationError("Password is not correct.") return p if request.method == 'POST': form = PasswordForm(request.POST) if form.is_valid(): request.session.setdefault('passwords', dict())[presentation.id] = form.cleaned_data.get('password') return HttpResponseRedirect(request.GET.get('next', reverse('presentation-browse'))) else: form = PasswordForm() return render_to_response('presentation_password.html', {'form': form, 'presentation': presentation, 'next': request.GET.get('next', reverse('presentation-browse')), }, context_instance=RequestContext(request))
def _generate_query(search_facets, user, collection, criteria, keywords, selected, *exclude): # add owned tag facet search_facets['ownedtag'] = OwnedTagSearchFacet() fields = {} for c in criteria: if (c in exclude) or (':' not in c): continue (f, o) = c.split(':', 1) if f.startswith('-'): f = 'NOT ' + f[1:] fname = f.rsplit(' ',1)[-1] # create exact match criteria on the fly if needed if fname.endswith('_s') and not search_facets.has_key(fname): search_facets[fname] = ExactValueSearchFacet(fname) if search_facets.has_key(fname): o = search_facets[fname].process_criteria(o, user) fields.setdefault(f, []).append('(' + o.replace('|', ' OR ') + ')') fields = map(lambda (name, crit): '%s:(%s)' % (name, (name.startswith('NOT ') and ' OR ' or ' AND ').join(crit)), fields.iteritems()) def build_keywords(q, k): k = k.lower() if k == 'and' or k == 'or': return q + ' ' + k.upper() elif q.endswith(' AND') or q.endswith(' OR'): return q + ' ' + k else: return q + ' AND ' + k if keywords: keywords = reduce(build_keywords, keywords.split()) query = '' if fields: query = ' AND '.join(fields) if keywords: query = query and '%s AND (%s)' % (query, keywords) or '(%s)' % keywords if not query: query = '*:*' if collection: query = 'collections:%s AND %s' % (collection.id, query) if hasattr(selected, '__len__'): query = 'id:(%s) AND %s' % (' '.join(map(str, selected or [-1])), query) if not user.is_superuser: collections = ' '.join(map(str, accessible_ids(user, Collection))) c = [] if collections: c.append('collections:(%s)' % collections) if user.id: c.append('owner:%s' % user.id) if c: query = '(%s) AND %s' % (' OR '.join(c), query) else: query = 'id:"-1"' return query
def run_search(user, collection=None, criteria=[], keywords='', sort='score desc', page=1, pagesize=25, orquery=None, selected=False, remove=None, produce_facets=False): available_storage = accessible_ids(user, Storage) exclude_facets = ['identifier'] fields = Field.objects.filter(standard__prefix='dc').exclude(name__in=exclude_facets) search_facets = [SearchFacet('tag', 'Tags')] + [SearchFacet(field.name + '_t', field.label) for field in fields] search_facets.append(StorageSearchFacet('resolution', 'Image size', available_storage)) search_facets.append(StorageSearchFacet('mimetype', 'Media type', available_storage)) search_facets.append(CollectionSearchFacet('allcollections', 'Collection')) search_facets.append(OwnerSearchFacet('owner', 'Owner')) # convert to dictionary search_facets = dict((f.name, f) for f in search_facets) query = _generate_query(search_facets, user, collection, criteria, keywords, selected, remove) s = SolrIndex() return_facets = search_facets.keys() if produce_facets else [] try: (hits, records, facets) = s.search(query, sort=sort, rows=pagesize, start=(page - 1) * pagesize, facets=return_facets, facet_mincount=1, facet_limit=100) except SolrError: hits = -1 records = None facets = dict() except socket.error: hits = 0 records = None facets = dict() if produce_facets: for f in search_facets: search_facets[f].set_result(facets.get(f)) if orquery: (f, v) = orquery.split(':', 1) orfacets = s.search(_generate_query(search_facets, user, collection, criteria, keywords, selected, remove, orquery), rows=0, facets=[f], facet_mincount=1, facet_limit=100)[2] orfacet = copy.copy(search_facets[f]) orfacet.label = '%s in %s or...' % (v.replace("|", " or "), orfacet.label) orfacet.set_result(orfacets[f]) else: orfacet = None return (hits, records, search_facets, orfacet, query, fields)
def _check_permission_for_user(self, user, **permissions): # checks if user is owner or has ACL access if check_access(user, self, **permissions): return True # if record does not have individual ACL... if len(_records_with_individual_acl_by_ids([self.id])) > 0: return False # ...check collection access return len(accessible_ids(user, self.collection_set, **permissions)) > 0
def published_Q(owner=None): publish_permission = Permission.objects.get(codename='publish_presentations') valid_publishers = User.objects.filter(Q(id__in=publish_permission.user_set.all()) | Q(groups__id__in=publish_permission.group_set.all()) | Q(is_superuser=True)) q = Q(owner__in=valid_publishers) & Q(hidden=False) if owner and not owner.is_anonymous(): return q | Q(id__in=accessible_ids(owner, Presentation, manage=True)) else: return q
def get_media_for_record(record, user=None, passwords={}): """ Returns all media accessible to the user either directly through collections or indirectly through presentations. A user always must have access to the storage where the media is stored. """ from rooibos.presentation.models import Presentation record_id = getattr(record, 'id', record) record = Record.filter_one_by_access(user, record_id) if not record: # Try to get to record through an accessible presentation - # own presentations don't count, since it's already established that owner # doesn't have access to the record. pw_q = Q( # Presentation must not have password Q(password=None) | Q(password='') | # or must know password Q(id__in=Presentation.check_passwords(passwords)) ) access_q = Q( # Must have access to presentation id__in=accessible_ids(user, Presentation), # and presentation must not be archived hidden=False ) accessible_presentations = Presentation.objects.filter( pw_q, access_q, items__record__id=record_id) # Now get all the presentation owners so we can check if any of them have access # to the record owners = User.objects.filter(id__in=accessible_presentations.values('owner')) if not any(Record.filter_one_by_access(owner, record_id) for owner in owners): return Media.objects.none() return Media.objects.filter( record__id=record_id, storage__id__in=accessible_ids(user, Storage), )
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 import_files(request): available_storage = get_list_or_404(filter_by_access(request.user, Storage, write=True).order_by('title')) available_collections = get_list_or_404(filter_by_access(request.user, Collection)) writable_collection_ids = accessible_ids(request.user, Collection, write=True) storage_choices = choices = [make_storage_select_choice(s, request.user) for s in available_storage] class UploadFileForm(forms.Form): collection = forms.ChoiceField(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))) storage = forms.ChoiceField(choices=storage_choices) file = forms.FileField() create_records = forms.BooleanField(required=False) replace_files = forms.BooleanField(required=False, label='Replace files of same type') personal_records = forms.BooleanField(required=False) def clean(self): cleaned_data = self.cleaned_data if any(self.errors): return cleaned_data personal = cleaned_data['personal_records'] if not personal: if not int(cleaned_data['collection']) in writable_collection_ids: self._errors['collection'] = ErrorList(["Can only add personal records to selected collection"]) del cleaned_data['collection'] return cleaned_data if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): create_records = form.cleaned_data['create_records'] replace_files = form.cleaned_data['replace_files'] personal_records = form.cleaned_data['personal_records'] collection = get_object_or_404(filter_by_access(request.user, Collection.objects.filter(id=form.cleaned_data['collection']), write=True if not personal_records else None)) storage = get_object_or_404(filter_by_access(request.user, Storage.objects.filter(id=form.cleaned_data['storage'].split(',')[0]), write=True)) file = request.FILES['file'] record = None limit = storage.get_upload_limit(request.user) if limit > 0 and file.size > limit * 1024: result = "The uploaded file is too large (%d>%d)." % (file.size, limit * 1024) else: mimetype = mimetypes.guess_type(file.name)[0] or file.content_type owner = request.user if personal_records else None id = os.path.splitext(file.name)[0] # find record by identifier titlefield = standardfield('title') idfield = standardfield('identifier') idfields = standardfield('identifier', equiv=True) # Match identifiers that are either full file name (with extension) or just base name match records = Record.by_fieldvalue(idfields, (id, file.name)).filter(collection=collection, owner=owner) result = "File skipped." if len(records) == 1: # Matching record found record = records[0] media = record.media_set.filter(storage=storage, mimetype=mimetype) if len(media) == 0: # No media yet media = Media.objects.create(record=record, name=id, storage=storage, mimetype=mimetype) media.save_file(file.name, file) result = "File added (Identifier '%s')." % id elif replace_files: # Replace existing media media = media[0] media.delete_file() media.save_file(file.name, file) result = "File replaced (Identifier '%s')." % id else: result = "File skipped, media files already attached." elif len(records) == 0: # No matching record found if create_records: # Create a record record = Record.objects.create(name=id, owner=owner) CollectionItem.objects.create(collection=collection, record=record) FieldValue.objects.create(record=record, field=idfield, value=id, order=0) FieldValue.objects.create(record=record, field=titlefield, value=id, order=1) media = Media.objects.create(record=record, name=id, storage=storage, mimetype=mimetype) media.save_file(file.name, file) result = "File added to new record (Identifier '%s')." % id else: result = "File skipped, no matching record found (Identifier '%s')." % id else: result = "File skipped, multiple matching records found (Identifier '%s')." % id # Multiple matching records found pass if request.POST.get('swfupload') == 'true': html = render_to_string('storage_import_file_response.html', {'result': result, 'record': record,}, context_instance=RequestContext(request) ) return HttpResponse(content=simplejson.dumps(dict(status='ok', html=html)), mimetype='application/json') request.user.message_set.create(message=result) next = request.GET.get('next', request.get_full_path()) return HttpResponseRedirect(next) else: # invalid form submission if request.POST.get('swfupload') == 'true': html = render_to_string('storage_import_file_response.html', {'result': form.errors}, context_instance=RequestContext(request) ) return HttpResponse(content=simplejson.dumps(dict(status='ok', html=html)), mimetype='application/json') else: form = UploadFileForm() return render_to_response('storage_import_files.html', {'upload_form': form, }, context_instance=RequestContext(request))
def record(request, id, name, contexttype=None, contextid=None, contextname=None, edit=False, customize=False, personal=False): writable_collections = list(accessible_ids(request.user, Collection, write=True)) readable_collections = list(accessible_ids(request.user, Collection)) can_edit = request.user.is_authenticated() if id and name: record = Record.get_or_404(id, request.user) can_edit = can_edit and record.editable_by(request.user) else: if request.user.is_authenticated() and (writable_collections or (personal and readable_collections)): record = Record() if personal: record.owner = request.user else: raise Http404() if record.owner: valid_collections = set(readable_collections) | set(writable_collections) else: valid_collections = writable_collections context = None if contexttype and contextid: app_label, model = contexttype.split('.') model_class = get_object_or_404(ContentType, app_label=app_label, model=model).model_class() context = get_object_or_404(filter_by_access(request.user, model_class), id=contextid) media = Media.objects.select_related().filter(record=record, storage__id__in=accessible_ids(request.user, Storage)) # Only list media that is downloadable or editable for m in media: # Calculate permissions and store with object for later use in template m.downloadable_in_template = m.is_downloadable_by(request.user) m.editable_in_template = m.editable_by(request.user) media = filter(lambda m: m.downloadable_in_template or m.editable_in_template, media) edit = edit and request.user.is_authenticated() class FieldSetForm(forms.Form): fieldset = FieldSetChoiceField(user=request.user, default_label='Default' if not edit else None) fieldsetform = FieldSetForm(request.GET) if fieldsetform.is_valid(): fieldset = FieldSet.for_user(request.user).get(id=fieldsetform.cleaned_data['fieldset']) if fieldsetform.cleaned_data['fieldset'] else None elif id and name: fieldset = None else: # Creating new record, use DC fieldset by default fieldset = FieldSet.objects.get(name='dc') collection_items = collectionformset = None if edit: if not can_edit and not customize and not context: return HttpResponseRedirect(reverse('data-record', kwargs=dict(id=id, name=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 class FieldValueForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(FieldValueForm, self).__init__(*args, **kwargs) def clean_field(self): return Field.objects.get(id=self.cleaned_data['field']) def clean_context_type(self): context = self.cleaned_data.get('context_type') if context: context = ContentType.objects.get(id=context) return context def clean(self): cleaned_data = self.cleaned_data return cleaned_data field = forms.ChoiceField(choices=_field_choices()) value = forms.CharField(widget=forms.Textarea, required=False) context_type = forms.IntegerField(widget=forms.HiddenInput, required=False) context_id = forms.IntegerField(widget=forms.HiddenInput, required=False) index_value = forms.CharField(widget=forms.HiddenInput, required=False) class Meta: model = FieldValue exclude = [] class CollectionForm(forms.Form): id = forms.IntegerField(widget=forms.HiddenInput) title = forms.CharField(widget=DisplayOnlyTextWidget) member = forms.BooleanField(required=False) shared = forms.BooleanField(required=False) fieldvalues_readonly = [] if customize or context: fieldvalues = record.get_fieldvalues(owner=request.user, context=context, hidden=True).filter(owner=request.user) else: fieldvalues = record.get_fieldvalues(hidden=True) FieldValueFormSet = modelformset_factory(FieldValue, form=FieldValueForm, exclude=FieldValueForm.Meta.exclude, can_delete=True, extra=3) CollectionFormSet = formset_factory(CollectionForm, extra=0) if request.method == 'POST': formset = FieldValueFormSet(request.POST, request.FILES, queryset=fieldvalues, prefix='fv') collectionformset = CollectionFormSet(request.POST, request.FILES, prefix='c') if not (customize or context) else None if formset.is_valid() and (customize or context or collectionformset.is_valid()):# or metadataform.is_valid()): record.save() if not (customize or context): collections = dict((c['id'],c) for c in collectionformset.cleaned_data if c['id'] in valid_collections) for item in record.collectionitem_set.filter(collection__in=valid_collections): if collections.has_key(item.collection_id): if not collections[item.collection_id]['member']: item.delete() elif collections[item.collection_id]['shared'] == item.hidden: item.hidden = not item.hidden item.save() del collections[item.collection_id] for coll in collections.values(): if coll['member']: CollectionItem.objects.create(record=record, collection_id=coll['id'], hidden=not coll['shared']) instances = formset.save(commit=False) o1 = fieldvalues and max(v.order for v in fieldvalues) or 0 o2 = instances and max(v.order for v in instances) or 0 order = max(o1, o2, 0) for instance in instances: if not instance.value: if instance.id: instance.delete() continue instance.record = record if instance.order == 0: order += 1 instance.order = order if customize or context: instance.owner = request.user if context: instance.context = context instance.save() request.user.message_set.create(message="Record saved successfully.") url = reverse('data-record-edit-customize' if customize else 'data-record-edit', kwargs=dict(id=record.id, name=record.name)) next = request.GET.get('next', reverse('data-record', kwargs=dict(id=record.id, name=record.name))) return HttpResponseRedirect(url if request.POST.has_key('save_and_continue') else next) else: if fieldset: needed = fieldset.fields.filter(~Q(id__in=[fv.field_id for fv in fieldvalues])).order_by('fieldsetfield__order').values_list('id', flat=True) initial = [{}] * len(fieldvalues) + [{'field': id} for id in needed] FieldValueFormSet.extra = len(needed) + 3 else: initial = [] formset = FieldValueFormSet(queryset=fieldvalues, prefix='fv', initial=initial) if not (customize or context): collections = dict( ((coll.id, dict(id=coll.id, title=coll.title)) for coll in Collection.objects.filter(id__in=valid_collections) ) ) for item in record.collectionitem_set.all(): collections.get(item.collection_id, {}).update(dict( member=True, shared=not item.hidden, )) collections = sorted(collections.values(), key=lambda c: c['title']) collectionformset = CollectionFormSet(prefix='c', initial=collections) else: fieldvalues_readonly = record.get_fieldvalues(owner=request.user, fieldset=fieldset) formset = None q = Q() if record.owner == request.user or request.user.is_superuser else Q(hidden=False) collection_items = record.collectionitem_set.filter(q, collection__in=readable_collections) if can_edit: from rooibos.storage.views import media_upload_form UploadFileForm = media_upload_form(request) upload_form = UploadFileForm() if UploadFileForm else None else: upload_form = None return render_to_response('data_record.html', {'record': record, 'media': media, 'fieldsetform': fieldsetform, 'fieldset': fieldset, 'fieldvalues': fieldvalues_readonly, 'context': context, 'customize': customize, 'fv_formset': formset, 'c_formset': collectionformset, 'can_edit': can_edit, 'next': request.GET.get('next'), 'collection_items': collection_items, 'upload_form': upload_form, 'upload_url': (reverse('storage-media-upload', args=(record.id, record.name)) + "?sidebar") if record.id else None, }, context_instance=RequestContext(request))
def manage_collection(request, id=None, name=None): if id and name: collection = get_object_or_404(Collection, id__in=accessible_ids(request.user, Collection, manage=True), id=id) else: collection = Collection(title='Untitled') if not request.user.is_superuser: collection.owner = request.user collection.hidden = True class CollectionForm(forms.ModelForm): class UserField(forms.CharField): widget=forms.TextInput(attrs={'class': 'autocomplete-user'}) def prepare_value(self, value): try: if not value or getattr(self, "_invalid_user", False): return value return User.objects.get(id=value).username except ValueError: return value except ObjectDoesNotExist: return None def to_python(self, value): try: return User.objects.get(username=value) if value else None except ObjectDoesNotExist: self._invalid_user = True raise ValidationError('User not found') children = forms.ModelMultipleChoiceField(queryset=filter_by_access(request.user, Collection).exclude(id=collection.id), widget=forms.CheckboxSelectMultiple, required=False) owner = UserField(widget=None if request.user.is_superuser else forms.HiddenInput, required=False) def clean_owner(self): if not request.user.is_superuser: # non-admins cannot change collection owner return collection.owner else: return self.cleaned_data['owner'] class Meta: model = Collection fields = ('title', 'hidden', 'owner', 'description', 'agreement', 'children') if request.method == "POST": if request.POST.get('delete-collection'): if not (request.user.is_superuser or request.user == collection.owner): raise HttpResponseForbidden() request.user.message_set.create(message="Collection '%s' has been deleted." % collection.title) collection.delete() return HttpResponseRedirect(reverse('data-collections-manage')) else: form = CollectionForm(request.POST, instance=collection) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('data-collection-manage', kwargs=dict( id=form.instance.id, name=form.instance.name))) else: form = CollectionForm(instance=collection) return render_to_response('data_collection_edit.html', {'form': form, 'collection': collection, 'can_delete': collection.id and (request.user.is_superuser or collection.owner == request.user), }, context_instance=RequestContext(request))
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=_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 edit(request, id, name): presentation = get_object_or_404(Presentation.objects.filter( id=id, id__in=accessible_ids(request.user, Presentation, write=True, manage=True))) existing_tags = [t.name for t in Tag.objects.usage_for_model( OwnedWrapper, filters=dict(user=request.user, content_type=OwnedWrapper.t(Presentation)))] tags = Tag.objects.get_for_object( OwnedWrapper.objects.get_for_object(user=request.user, object=presentation)) class PropertiesForm(forms.Form): title = forms.CharField(label='Title', max_length=Presentation._meta.get_field('title').max_length) # tags = SplitTaggingField(label='Tags', choices=[(t, t) for t in existing_tags], # required=False, add_label='Additional tags') hidden = forms.BooleanField(label='Hidden', required=False) description = forms.CharField(label='Description', widget=forms.Textarea(attrs={'rows': 5}), required=False) password = forms.CharField(label='Password', required=False, max_length=Presentation._meta.get_field('password').max_length) fieldset = FieldSetChoiceField(label='Field set', user=presentation.owner) hide_default_data = forms.BooleanField(label='Hide default data', required=False) class BaseOrderingForm(ModelForm): record = forms.CharField(widget=forms.HiddenInput) annotation = forms.CharField(widget=forms.Textarea, required=False) def __init__(self, initial=None, instance=None, *args, **kwargs): if instance: object_data = dict(annotation=instance.annotation) else: object_data = dict() if initial is not None: object_data.update(initial) super(BaseOrderingForm, self).__init__(initial=object_data, instance=instance, *args, **kwargs) def clean_record(self): return Record.objects.get(id=self.cleaned_data['record']) def save(self, commit=True): instance = super(BaseOrderingForm, self).save(commit) instance.annotation = self.cleaned_data['annotation'] return instance self_page = HttpResponseRedirect( reverse('presentation-edit', kwargs={'id': presentation.id, 'name': presentation.name})) OrderingFormSet = modelformset_factory(PresentationItem, extra=0, can_delete=True, exclude=('presentation'), form=BaseOrderingForm) queryset = presentation.items.select_related('record', 'presentation', 'presentation__owner').all() if request.method == 'POST' and request.POST.get('update-items'): formset = OrderingFormSet(request.POST, queryset=queryset) if formset.is_valid(): instances = formset.save(commit=False) for instance in instances: instance.presentation = presentation instance.save() request.user.message_set.create(message="Changes to presentation items saved successfully.") return self_page else: formset = OrderingFormSet(queryset=queryset) if request.method == 'POST' and request.POST.get('add-selected-items'): add_selected_items(request, presentation) return self_page if request.method == "POST" and request.POST.get('update-properties'): update_actionbar_tags(request, presentation) form = PropertiesForm(request.POST) if form.is_valid(): presentation.title = form.cleaned_data['title'] presentation.name = None if presentation.owner.has_perm('presentation.publish_presentations'): presentation.hidden = form.cleaned_data['hidden'] presentation.description = form.cleaned_data['description'] presentation.password = form.cleaned_data['password'] presentation.fieldset = FieldSet.for_user(presentation.owner).get(id=form.cleaned_data['fieldset']) if form.cleaned_data['fieldset'] else None presentation.hide_default_data = form.cleaned_data['hide_default_data'] presentation.save() request.user.message_set.create(message="Changes to presentation saved successfully.") return self_page else: form = PropertiesForm(initial={'title': presentation.title, 'hidden': presentation.hidden, 'description': presentation.description, 'hidden': presentation.hidden, 'fieldset': presentation.fieldset.id if presentation.fieldset else None, 'hide_default_data': presentation.hide_default_data, }) contenttype = ContentType.objects.get_for_model(Presentation) return render_to_response('presentation_properties.html', {'presentation': presentation, 'contenttype': "%s.%s" % (contenttype.app_label, contenttype.model), 'formset': formset, 'form': form, 'selected_tags': [tag.name for tag in tags], 'usertags': existing_tags if len(existing_tags) > 0 else None, }, context_instance=RequestContext(request))
def record( request, id, name, contexttype=None, contextid=None, contextname=None, edit=False, customize=False, personal=False, copy=False, copyid=None, copyname=None, ): writable_collections = list(accessible_ids(request.user, Collection, write=True)) readable_collections = list(accessible_ids(request.user, Collection)) can_edit = request.user.is_authenticated() can_manage = False if id and name: record = Record.get_or_404(id, request.user) # if the user passes the first test if record: # if the user can't see an image, and there is one, then # don't let them see the record passwords = request.session.get("passwords", dict()) media = get_media_for_record(record, request.user, passwords) unfiltered_media = Media.objects.filter(record__id=record.id) if not media and unfiltered_media: raise Http404() can_edit = can_edit and record.editable_by(request.user) can_manage = record.manageable_by(request.user) else: if request.user.is_authenticated() and (writable_collections or (personal and readable_collections)): record = Record() if personal: record.owner = request.user else: raise Http404() if record.owner: valid_collections = set(readable_collections) | set(writable_collections) else: valid_collections = writable_collections context = None if contexttype and contextid: app_label, model = contexttype.split(".") model_class = get_object_or_404(ContentType, app_label=app_label, model=model).model_class() context = get_object_or_404(filter_by_access(request.user, model_class), id=contextid) media = Media.objects.select_related().filter(record=record, storage__id__in=accessible_ids(request.user, Storage)) # Only list media that is downloadable or editable for m in media: # Calculate permissions and store with object for later use in template m.downloadable_in_template = m.is_downloadable_by(request.user) m.editable_in_template = m.editable_by(request.user) media = filter(lambda m: m.downloadable_in_template or m.editable_in_template, media) edit = edit and request.user.is_authenticated() copyrecord = Record.get_or_404(copyid, request.user) if copyid else None class FieldSetForm(forms.Form): fieldset = FieldSetChoiceField(user=request.user, default_label="Default" if not edit else None) fieldsetform = FieldSetForm(request.GET) if fieldsetform.is_valid(): fieldset = ( FieldSet.for_user(request.user).get(id=fieldsetform.cleaned_data["fieldset"]) if fieldsetform.cleaned_data["fieldset"] else None ) elif (edit or customize) and (id and name): # if we're editing, touch all the data (no default fieldset) fieldset = None else: # use default fieldset settings if settings.DEFAULT_FIELDSET and isinstance(settings.DEFAULT_FIELDSET, basestring): default_fieldset = settings.DEFAULT_FIELDSET else: # yes, it's a default default setting default_fieldset = "dc" fieldset = FieldSet.objects.get(name=default_fieldset) collection_items = collectionformset = None if edit: if not can_edit and not customize and not context: return HttpResponseRedirect(reverse("data-record", kwargs=dict(id=id, name=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 class FieldValueForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(FieldValueForm, self).__init__(*args, **kwargs) def clean_field(self): return Field.objects.get(id=self.cleaned_data["field"]) def clean_context_type(self): context = self.cleaned_data.get("context_type") if context: context = ContentType.objects.get(id=context) return context def clean(self): cleaned_data = self.cleaned_data return cleaned_data field = forms.ChoiceField(choices=_field_choices()) value = forms.CharField(widget=forms.Textarea, required=False) context_type = forms.IntegerField(widget=forms.HiddenInput, required=False) context_id = forms.IntegerField(widget=forms.HiddenInput, required=False) index_value = forms.CharField(widget=forms.HiddenInput, required=False) class Meta: model = FieldValue exclude = [] class CollectionForm(forms.Form): id = forms.IntegerField(widget=forms.HiddenInput) title = forms.CharField(widget=DisplayOnlyTextWidget) member = forms.BooleanField(required=False) shared = forms.BooleanField(required=False) fieldvalues_readonly = [] if customize or context: fieldvalues = record.get_fieldvalues(owner=request.user, context=context, hidden=True).filter( owner=request.user ) else: fieldvalues = record.get_fieldvalues(hidden=True) FieldValueFormSet = modelformset_factory( FieldValue, form=FieldValueForm, exclude=FieldValueForm.Meta.exclude, can_delete=True, extra=3 ) CollectionFormSet = formset_factory(CollectionForm, extra=0) if request.method == "POST": formset = FieldValueFormSet(request.POST, request.FILES, queryset=fieldvalues, prefix="fv") collectionformset = ( CollectionFormSet(request.POST, request.FILES, prefix="c") if not (customize or context) else None ) if formset.is_valid() and ( customize or context or collectionformset.is_valid() ): # or metadataform.is_valid()): record.save() if not (customize or context): collections = dict( (c["id"], c) for c in collectionformset.cleaned_data if c["id"] in valid_collections ) for item in record.collectionitem_set.filter(collection__in=valid_collections): if collections.has_key(item.collection_id): if not collections[item.collection_id]["member"]: item.delete() elif collections[item.collection_id]["shared"] == item.hidden: item.hidden = not item.hidden item.save() del collections[item.collection_id] for coll in collections.values(): if coll["member"]: CollectionItem.objects.create( record=record, collection_id=coll["id"], hidden=not coll["shared"] ) instances = formset.save(commit=False) o1 = fieldvalues and max(v.order for v in fieldvalues) or 0 o2 = instances and max(v.order for v in instances) or 0 order = max(o1, o2, 0) for instance in instances: if not instance.value: if instance.id: instance.delete() continue instance.record = record if instance.order == 0: order += 1 instance.order = order if customize or context: instance.owner = request.user if context: instance.context = context instance.save() request.user.message_set.create(message="Record saved successfully.") url = reverse( "data-record-edit-customize" if customize else "data-record-edit", kwargs=dict(id=record.id, name=record.name), ) next = request.GET.get("next", reverse("data-record", kwargs=dict(id=record.id, name=record.name))) return HttpResponseRedirect(url if request.POST.has_key("save_and_continue") else next) else: if copyrecord: initial = [] for fv in copyrecord.get_fieldvalues(hidden=True): initial.append( dict( label=fv.label, field=fv.field_id, refinement=fv.refinement, value=fv.value, date_start=fv.date_start, date_end=fv.date_end, numeric_value=fv.numeric_value, language=fv.language, order=fv.order, group=fv.group, hidden=fv.hidden, ) ) FieldValueFormSet.extra = len(initial) + 3 elif fieldset: needed = ( fieldset.fields.filter(~Q(id__in=[fv.field_id for fv in fieldvalues])) .order_by("fieldsetfield__order") .values_list("id", flat=True) ) initial = [{}] * len(fieldvalues) + [{"field": id} for id in needed] FieldValueFormSet.extra = len(needed) + 3 else: initial = [] formset = FieldValueFormSet(queryset=fieldvalues, prefix="fv", initial=initial) if not (customize or context): collections = dict( ( (coll.id, dict(id=coll.id, title=coll.title)) for coll in Collection.objects.filter(id__in=valid_collections) ) ) for item in (copyrecord or record).collectionitem_set.all(): collections.get(item.collection_id, {}).update(dict(member=True, shared=not item.hidden)) collections = sorted(collections.values(), key=lambda c: c["title"]) collectionformset = CollectionFormSet(prefix="c", initial=collections) else: fieldvalues_readonly = record.get_fieldvalues(owner=request.user, fieldset=fieldset) formset = None q = Q() if record.owner == request.user or request.user.is_superuser else Q(hidden=False) collection_items = record.collectionitem_set.filter(q, collection__in=readable_collections) if can_edit: from rooibos.storage.views import media_upload_form UploadFileForm = media_upload_form(request) upload_form = UploadFileForm() if UploadFileForm else None else: upload_form = None # handle uploading over secure URLs: in the view, offer link to insecure insecure_url = None if request.is_secure() and settings.INSECURE_UPLOAD: request_url = request.build_absolute_uri(request.get_full_path()) insecure_url = request_url.replace("https://", "http://") record_usage = record.presentationitem_set.values("presentation").distinct().count() if can_edit else 0 return render_to_response( "data_record.html", { "record": record, "media": media, "fieldsetform": fieldsetform, "fieldset": fieldset, "fieldvalues": fieldvalues_readonly, "context": context, "customize": customize, "fv_formset": formset, "c_formset": collectionformset, "can_edit": can_edit, "can_manage": can_manage, "next": request.GET.get("next"), "collection_items": collection_items, "upload_form": upload_form, "upload_url": ( "%s?sidebar&next=%s" % (reverse("storage-media-upload", args=(record.id, record.name)), request.get_full_path()) ) if record.id else None, "insecure_url": insecure_url, "record_usage": record_usage, }, context_instance=RequestContext(request), )
def browse(request, manage=False): if manage and not request.user.is_authenticated(): raise Http404() presenter = request.GET.get('presenter') tags = filter(None, request.GET.getlist('t')) 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 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 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() qid = Q(id__in=accessible_ids(request.user, Presentation, write=True, manage=True)) else: qv = Presentation.published_Q() qid = Q(id__in=accessible_ids(request.user, Presentation)) presentations = Presentation.objects.select_related('owner').filter(q, qp, qk, qv, qid).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') or keywords 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(Presentation.objects.filter( id=id, id__in=accessible_ids(request.user, Presentation, write=True, manage=True))) 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') return render_to_response('presentation_browse.html', {'manage': manage, 'tags': tags if len(tags) > 0 else None, '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 get_by_id_for_request(id, request): p = Presentation.objects.filter(Presentation.published_Q(request.user), id=id, id__in=accessible_ids(request.user, Presentation)) return p[0] if p and p[0].verify_password(request) else None
def editable_by(self, user): return ( # checks if user is owner: check_access(user, self, write=True) or # or if user has write access to collection: len(accessible_ids(user, self.collection_set, write=True)) > 0)
def duplicate(request, id, name): presentation = get_object_or_404(Presentation.objects.filter( id=id, id__in=accessible_ids(request.user, Presentation, write=True, manage=True))) dup = duplicate_presentation(presentation, request.user) return HttpResponseRedirect(reverse('presentation-edit', args=(dup.id, dup.name)))