def switch_entry_in_collection(request): try: entry_id = int(request.POST['entry_id']) entry = get_object_or_404(Entry, pk=entry_id) collection_id = int(request.POST['collection_id']) collection = get_object_or_404(UsersEntryCollection, pk=collection_id) action = request.POST['action'] assert(action in ('add', 'remove')) except KeyError: raise AjaxException('Missing required POST parameter (entry_id, collection_id and action are required).') except (TypeError, ValueError): raise AjaxException('The id parameter must contain an integer.') except AssertionError: raise AjaxException('Invalid action.') if collection.user != request.user and not request.user.is_superuser: raise AjaxException('You are not allowed to do this!') if action == 'add': collection.entries.add(entry) else: collection.entries.remove(entry) return {'success': True, 'size': collection.entries.count(), 'name': collection.name if len(collection.name) < 30 else collection.name[:27] + '...', 'public': collection.public}
def save_entries_order(request): try: event_id = request.POST.get('eventId', None) ordering = json.loads(request.POST.get('ordering')) assert isinstance(ordering, dict) ordering = {int(key): int(value) for key, value in ordering.items()} except KeyError: raise AjaxException("This view requires two parameters: " "eventId and ordering.") except json.JSONDecodeError: raise AjaxException("Invalid JSON in ordering.") except AssertionError: raise AjaxException("JSON in ordering has to represent a dict.") except TypeError: raise AjaxException("Only integers are allowed in ordering dict.") event = get_object_or_404(Event, pk=event_id) entries_dict = Entry.objects.filter(event=event).in_bulk(ordering.keys()) Entry.objects.filter(event=event).update(order=max(ordering.values())+1) for entry_id, order in ordering.items(): entries_dict[entry_id].order = int(order) entries_dict[entry_id].save() logging.getLogger('palanaeum.staff').info("%s reordered entries in event %s", request.user, event_id) return {'url': reverse('view_event_no_title', kwargs={'event_id': event_id})}
def update_snippets(request): """ Update or create a new snippet. Return the edited snippet's id. """ try: source_id = request.POST['source_id'] source = get_object_or_404(AudioSource, pk=int(source_id)) except KeyError: raise AjaxException('Missing source_id parameter.') try: updated_snippets, updated_urls = _process_snippets(source, request) except ValueError as err: raise AjaxException('Invalid value: {}.'.format(err)) # Save changes snip_ids = [] for s in updated_snippets: s.save() snip_ids.append(s.id) for snippet_id in snip_ids: tasks.create_snippet.delay(snippet_id) return {'saved_count': len(updated_snippets), 'edit_urls': updated_urls}
def ajax_add_collection(request): try: name = request.POST['name'][:UsersEntryCollection.MAX_NAME_LENGTH] entry_id = int(request.POST['entry_id']) entry = get_object_or_404(Entry, pk=entry_id) except KeyError: raise AjaxException('Missing required POST parameter (name and entry_id required).') except (TypeError, ValueError): raise AjaxException('The id parameter must contain an integer.') collection = UsersEntryCollection.objects.create( user=request.user, name=name, public=False ) collection.entries.add(entry) return {'success': True, 'name': name, 'id': collection.id}
def hide_show_resource(request): try: resource_class = request.POST['class'] assert (resource_class in ('entry', 'audio_source', 'url_source', 'snippet', 'image_source')) resource_id = int(request.POST['id']) mode = request.POST['mode'] except KeyError: raise AjaxException( 'Missing required POST parameter (class, mode and id are required).' ) except TypeError: raise AjaxException('The id parameter must contain an integer.') except AssertionError: raise AjaxException('Invalid class.') if mode not in ('show', 'hide'): raise AjaxException('Invalid mode.') if resource_class == 'entry': obj = get_object_or_404(Entry, pk=resource_id) elif resource_class == 'url_source': obj = get_object_or_404(URLSource, pk=resource_id) elif resource_class == 'audio_source': obj = get_object_or_404(AudioSource, pk=resource_id) elif resource_class == 'snippet': obj = get_object_or_404(Snippet, pk=resource_id) elif resource_class == 'image_source': obj = get_object_or_404(ImageSource, pk=resource_id) else: raise AjaxException("Unknown resource class.") if mode == 'show': obj.show() logging.getLogger('palanaeum.staff').info("%s showed %s %s.", request.user, resource_class, obj.id) else: obj.hide() logging.getLogger('palanaeum.staff').info("%s hid %s %s.", request.user, resource_class, obj.id) obj.save() return
def rename_audio_source(request): """ Rename an audio source, return JSON response. """ source_id = request.POST.get('source_id') try: source = get_object_or_404(AudioSource, pk=int(source_id)) except ValueError: raise AjaxException("Source_id has to be integer.") try: old_title = source.file_title source.file_title = request.POST['title'] except KeyError: raise AjaxException("Title missing.") logging.getLogger('palanaeum.staff').info("%s renamed audio source %s from %s to %s.", request.user, source.id, old_title, source.file_title) source.save() return {}
def _process_snippets(source: AudioSource, request: HttpRequest): beginning_re = r'^snippet-(\d+)-beginning$' length_re = r'^snippet-(\d+)-length$' comment_re = r'^snippet-(\d+)-comment$' optional_re = r'^snippet-(\d+)-optional' snippets_by_id = {s.id: s for s in Snippet.objects.filter(source=source)} updated_snippets = set() updated_urls = {} for key in request.POST.keys(): b_match = re.match(beginning_re, key) l_match = re.match(length_re, key) c_match = re.match(comment_re, key) t_match = re.match(optional_re, key) match = b_match or l_match or c_match or t_match if not match: continue snippet_id = int(match.group(1)) try: snippet = snippets_by_id[snippet_id] except KeyError: if Snippet.objects.filter(pk=snippet_id).exists(): raise AjaxException( _('"Snippet {} already exists and cannot be edited here.'). format(snippet_id)) snippet = Snippet() snippet.id = snippet_id snippet.created_by = request.user snippet.source = source snippets_by_id[snippet_id] = snippet if b_match and not snippet.muted: new_beginning = int(request.POST[key]) snippet.beginning = new_beginning elif l_match and not snippet.muted: new_length = max(1, int(request.POST[key])) snippet.length = new_length elif c_match: snippet.comment = request.POST[key] elif t_match: snippet.optional = request.POST[key] == 'true' updated_snippets.add(snippet) logging.getLogger('palanaeum.staff').info( "Audio snippet %s edited by %s.", snippet.id, request.user) updated_urls[snippet_id] = reverse('edit_snippet_entry', kwargs={'snippet_id': snippet_id}) return updated_snippets, updated_urls
def get_new_snippet_id(request): """ Get a new snippet's id and return it. Don't leave the new snippet in the database. """ try: source_id = request.POST['source_id'] except KeyError: raise AjaxException('Missing source_id parameter.') snippet = Snippet() snippet.created_by = request.user snippet.source_id = source_id snippet.save() snippet_id = snippet.id snippet.delete() return {'snippet_id': snippet_id}
def set_user_state(request): try: user_id = request.POST['user_id'] user = User.objects.get(pk=user_id) is_active = request.POST.get('is_active', False) == 'true' is_staff = request.POST.get('is_staff', False) == 'true' is_superuser = request.POST.get('is_superuser', False) == 'true' except KeyError: raise AjaxException('Missing user_id parameter.') except User.DoesNotExist: raise Http404 user.is_active = is_active user.is_staff = is_staff and is_active user.is_superuser = is_superuser and is_staff and is_active user.save() return {'is_staff': user.is_staff, 'is_active': user.is_active, 'is_superuser': user.is_superuser, 'user_id': user_id}
def save_entry(request): """ Save received entry data. """ if not is_contributor(request): raise AjaxException(_('Only contributors can perform this action.')) if 'entry_id' not in request.POST or not request.POST['entry_id']: entry = Entry() event = get_object_or_404(Event, pk=request.POST['event_id']) entry.event = event entry.date = event.date entry.created_by = request.user entry.is_approved = False entry.set_order_last() entry.save() entry_version = EntryVersion() entry_version.entry = entry entry_version.user = request.user else: entry_id = request.POST['entry_id'] entry = get_object_or_404(Entry, pk=entry_id) event = entry.event entry_version = entry.versions.last() if entry_version is None: entry_version = EntryVersion() entry_version.entry = entry entry_version.user = request.user date_str = request.POST.get('date', event.date.strftime("%Y-%m-%d")) if date_str: try: entry.date = datetime.strptime(date_str, "%Y-%m-%d") except ValueError: raise AjaxException(_("Unsupported date format. Expected date format is: YYYY-MM-DD.")) else: entry.date = event.date entry.paraphrased = bool(request.POST.get('paraphrased', False)) entry.save() entry_version.archive_version() entry_version.note = request.POST.get('note', '') entry_version.user = request.user entry_version.is_approved = False entry_version.approved_by = None entry_version.approved_date = None entry_version.save() lines_id_mapping, deleted_lines_ids = _save_entry_lines(request, entry_version) # There is a bunch of stuff that only staff can do... if request.user.is_staff: _save_entry_url_sources(request, entry) tags_str = ", ".join(request.POST.getlist('tags[]')) entry.update_tags(tags_str) entry_version.approve(request.user) logging.getLogger('palanaeum.staff').info("Entry %s updated by %s", entry.id, request.user) return {'lines_id_mapping': lines_id_mapping, 'deleted_lines': deleted_lines_ids, 'entry_id': entry.id, 'add_entry_url': reverse('event_add_entry', kwargs={'event_id': event.id})}
def update_snippets(request): """ Update or create a new snippet. Return the edited snippet's id. """ try: source_id = request.POST['source_id'] source = get_object_or_404(AudioSource, pk=int(source_id)) except KeyError: raise AjaxException('Missing source_id parameter.') snippets_by_id = {s.id: s for s in Snippet.objects.filter(source=source)} # Update the snippets beginnings beginning_re = r'^snippet-(\d+)-beginning$' length_re = r'^snippet-(\d+)-length$' comment_re = r'^snippet-(\d+)-comment$' key = None updated_snippets = set() updated_urls = {} try: for key in request.POST: b_match = re.match(beginning_re, key) l_match = re.match(length_re, key) c_match = re.match(comment_re, key) match = b_match or l_match or c_match if match: snippet_id = int(match.group(1)) else: continue if snippet_id in snippets_by_id: snippet = snippets_by_id[snippet_id] else: if Snippet.objects.filter(pk=snippet_id).exists(): raise AjaxException(_('"Snippet {} already exists and cannot be edited here.').format(snippet_id)) snippet = Snippet() snippet.id = snippet_id snippet.created_by = request.user snippet.source = source snippets_by_id[snippet_id] = snippet if b_match and not snippet.muted: new_beginning = int(request.POST[key]) snippet.beginning = new_beginning if l_match and not snippet.muted: new_length = max(1, int(request.POST[key])) snippet.length = new_length elif c_match: snippet.comment = request.POST[key] updated_snippets.add(snippet) logging.getLogger('palanaeum.staff').info("Audio snippet %s edited by %s.", snippet.id, request.user) updated_urls[snippet_id] = reverse('edit_snippet_entry', kwargs={'snippet_id': snippet_id}) except ValueError: raise AjaxException('Invalid value for key {}.'.format(key)) # Save changes snip_ids = [] for s in updated_snippets: s.save() snip_ids.append(s.id) for snippet_id in snip_ids: tasks.create_snippet.delay(snippet_id) return {'saved_count': len(updated_snippets), 'edit_urls': updated_urls}