def do_index(request): """Do cognacy index to help select subsets""" form = DoCognateForm(request.POST or None, clades=get_clades()) if request.POST and form.is_valid(): url = reverse('cognacy:do', kwargs={ 'word': form.cleaned_data['word'].slug, 'clade': form.cleaned_data['clade'] }) return redirect(url) return render(request, 'cognacy/do_index.html', {'form': form})
def do_index(request): """Do cognacy index to help select subsets""" form = DoCognateForm(request.POST or None) if request.POST and form.is_valid(): url = reverse('cognacy:do', kwargs={ 'word': form.cleaned_data['word'].slug, 'clade': form.cleaned_data['clade'] }) return redirect(url) return render_to_response('cognacy/do_index.html', {'form': form}, context_instance=RequestContext(request) )
def save(request, word, clade=None): form = DoCognateForm(request.POST or None, clades=get_clades()) commentform = CognateNoteForm(request.POST or None, prefix='comment', queryset=CognateSet.objects.all()) if request.POST and commentform.is_valid(): CognateNote.objects.create( word=commentform.cleaned_data['word'], cognateset=commentform.cleaned_data['cogset'], note=commentform.cleaned_data['comment'], editor=request.user, ) if request.POST and form.is_valid(): word = form.cleaned_data['word'] clade = form.cleaned_data['clade'] # collect lexicon ids and actions # 1. get anything (lex_id, value) that is a cognacy field and isn't empty changes = [(k[2:], v) for (k, v) in request.POST.items() if k.startswith('c-') and v != u''] # check that we've got valid lexical ids # Any exceptions here should only be due to tampering -- cause a 500 error. try: changes = [(int(k), v) for (k, v) in changes] except ValueError: raise ValueError("Form tampering!") # pull out subsets of actions commands = [(k, v) for (k, v) in changes if v.startswith("!")] additions = [ (k, v) for (k, v) in changes if v.startswith('-') == False and v.startswith("!") == False ] deletions = [(k, v[1:]) for (k, v) in changes if v.startswith('-') and v.startswith("!") == False] # 1. Special commands for lex_id, command in commands: L = Lexicon.objects.get(pk=lex_id) if command == '!DELETE': messages.add_message(request, messages.WARNING, 'Warning: DELETED lexicon %r' % L, extra_tags='warning') with reversion.create_revision(): L.delete() reversion.set_user(request.user) reversion.set_comment("Deleted item") # 2. Cognate Additions for lex_id, cogset in additions: L = Lexicon.objects.get(pk=lex_id) try: cog = CognateSet.objects.get(pk=int(cogset)) except ValueError: # non numeric input. Can't be a PK messages.add_message( request, messages.ERROR, 'ERROR %r for lexicon %d is not a number' % (cogset, lex_id), extra_tags='error') continue except CognateSet.DoesNotExist: # doesn't exist -- create with reversion.create_revision(): cog = CognateSet.objects.create(pk=int(cogset), protoform="", gloss="", editor=request.user) cog.save() messages.add_message(request, messages.INFO, 'Creating Cognate Set %r' % cog, extra_tags='success') # avoid duplicates if L not in cog.lexicon.all(): with reversion.create_revision(): Cognate.objects.create(lexicon=L, cognateset=cog, editor=request.user).save() messages.add_message(request, messages.INFO, 'Adding %r to cognate set %d' % (L, cog.id), extra_tags='success') else: messages.add_message(request, messages.WARNING, 'Warning: %r already in cognate set %d' % (L, cog.id), extra_tags='warning') # 3. Cognate Deletions for lex_id, cogset in deletions: L = Lexicon.objects.get(pk=lex_id) cog = None try: cog = CognateSet.objects.get(pk=int(cogset)) except ValueError: # non numeric input. Can't be a PK messages.add_message( request, messages.ERROR, 'ERROR %r for lexicon %d is not a number' % (cogset, lex_id), extra_tags='error') continue except CognateSet.DoesNotExist: # doesn't exist -- create messages.add_message(request, messages.ERROR, 'ERROR CognateSet %r does not exist' % cogset, extra_tags='error') continue members = [ _ for _ in L.cognate_set.all() if _.cognateset_id == cog.id ] for m in members: messages.add_message(request, messages.INFO, 'Removing %r to cognate set %d' % (L, cog.id), extra_tags='warning') with reversion.create_revision(): m.delete() # remove cognateset if it's empty if cog.cognate_set.count() == 0: messages.add_message(request, messages.INFO, 'Removing empty cognate set %r' % cog, extra_tags='warning') with reversion.create_revision(): cog.delete() url = reverse('cognacy:do', kwargs={ 'word': form.cleaned_data['word'].slug, 'clade': form.cleaned_data['clade'] }) return redirect(url) return redirect( reverse('cognacy:do_index')) # go somewhere safe on form tamper.
def do(request, word, clade=None): """Do cognacy""" w = get_object_or_404(Word, slug=word) lex_ids, entries = [], [] lexica = w.lexicon_set.all() if clade: lexica = lexica.filter(language__classification__startswith=clade) for e in lexica.select_related('source', 'word', 'language'): lex_ids.append(e.id) entries.append(e) # save us from one query for each cognateset -- select_related doesn't help us here so # we do a rather ungainly merge. # 1. get a list of (lexicon.id, cognateset.id) queryset = Cognate.objects.filter(lexicon_id__in=lex_ids).select_related( 'lexicon', 'cognateset', 'cognateset__source') cogs = [(c.lexicon_id, c.cognateset_id, c.cognateset) for c in queryset] # 2. get notes notes = CognateNote.objects.filter( Q(word=w) | Q(cognateset__in=[c[2] for c in cogs])) # 3. go through entries and attach a list of cognateset ids if needed, else empty list entries_and_cogs = [] inplay = {} for e in entries: e.cognacy = [c[1] for c in cogs if c[0] == e.id] e.edit = True # dummy value so django-tables2 passes to render_edit() e.classification = e.language.classification entries_and_cogs.append(e) cogobjs = [_[2] for _ in cogs if _[1] in e.cognacy] for o in cogobjs: inplay[o] = inplay.get(o, set()) inplay[o].add(e.entry) inplay = dict([(k, ", ".join(sorted(v)[0:20])) for (k, v) in inplay.items()]) inplay = sorted([(k.id, k, v) for (k, v) in inplay.items()]) inplay = [(_[1], _[2]) for _ in inplay] form = DoCognateForm(initial={ 'word': w.id, 'clade': clade }, is_hidden=True, clades=get_clades()) CSQ = CognateSet.cache_all_method.filter( id__in=[c[1] for c in cogs]).order_by('id') mergeform = MergeCognateForm(request.POST or None, prefix='merge', queryset=CSQ) commentform = CognateNoteForm(request.POST or None, prefix='comment', queryset=CSQ, initial={ 'word': w, }) table = CognacyTable(entries_and_cogs) RequestConfig(request, paginate=False).configure(table) return render( request, 'cognacy/do_detail.html', { 'word': w, 'clade': clade, 'lexicon': table, 'inplay': inplay, 'form': form, 'mergeform': mergeform, 'next_cognates': get_missing_cogids(limit=10), 'notes': notes, 'commentform': commentform, })
def save(request, word, clade=None): form = DoCognateForm(request.POST or None) commentform = CognateNoteForm(request.POST or None, prefix='comment', queryset=CognateSet.objects.all() ) if request.POST and commentform.is_valid(): CognateNote.objects.create( word=commentform.cleaned_data['word'], cognateset=commentform.cleaned_data['cogset'], note=commentform.cleaned_data['comment'], editor=request.user, ) if request.POST and form.is_valid(): word = form.cleaned_data['word'] clade = form.cleaned_data['clade'] # collect lexicon ids and actions # 1. get anything (lex_id, value) that is a cognacy field and isn't empty changes = [ (k[2:], v) for (k, v) in request.POST.items() if k.startswith('c-') and v != u'' ] # check that we've got valid lexical ids # Any exceptions here should only be due to tampering -- cause a 500 error. try: changes = [(int(k), v) for (k, v) in changes] except ValueError: raise ValueError("Form tampering!") # pull out subsets of actions commands = [ (k, v) for (k, v) in changes if v.startswith("!") ] additions = [ (k, v) for (k, v) in changes if v.startswith('-') == False and v.startswith("!") == False ] deletions = [ (k, v[1:]) for (k, v) in changes if v.startswith('-') and v.startswith("!") == False ] # 1. Special commands for lex_id, command in commands: L = Lexicon.objects.get(pk=lex_id) if command == '!DELETE': messages.add_message(request, messages.WARNING, 'Warning: DELETED lexicon %r' % L, extra_tags='warning' ) with reversion.create_revision(): L.delete() reversion.set_user(request.user) reversion.set_comment("Deleted item") # 2. Cognate Additions for lex_id, cogset in additions: L = Lexicon.objects.get(pk=lex_id) try: cog = CognateSet.objects.get(pk=int(cogset)) except ValueError: # non numeric input. Can't be a PK messages.add_message(request, messages.ERROR, 'ERROR %r for lexicon %d is not a number' % (cogset, lex_id), extra_tags='error' ) continue except CognateSet.DoesNotExist: # doesn't exist -- create with reversion.create_revision(): cog = CognateSet.objects.create( pk=int(cogset), protoform = "", gloss = "", editor=request.user ) cog.save() messages.add_message(request, messages.INFO, 'Creating Cognate Set %r' % cog, extra_tags='success' ) # avoid duplicates if L not in cog.lexicon.all(): with reversion.create_revision(): Cognate.objects.create(lexicon=L, cognateset=cog, editor=request.user).save() messages.add_message(request, messages.INFO, 'Adding %r to cognate set %d' % (L, cog.id), extra_tags='success' ) else: messages.add_message(request, messages.WARNING, 'Warning: %r already in cognate set %d' % (L, cog.id), extra_tags='warning' ) # 3. Cognate Deletions for lex_id, cogset in deletions: L = Lexicon.objects.get(pk=lex_id) cog = None try: cog = CognateSet.objects.get(pk=int(cogset)) except ValueError: # non numeric input. Can't be a PK messages.add_message(request, messages.ERROR, 'ERROR %r for lexicon %d is not a number' % (cogset, lex_id), extra_tags='error' ) continue except CognateSet.DoesNotExist: # doesn't exist -- create messages.add_message(request, messages.ERROR, 'ERROR CognateSet %r does not exist' % cogset, extra_tags='error' ) continue members = [_ for _ in L.cognate_set.all() if _.cognateset_id == cog.id] for m in members: messages.add_message(request, messages.INFO, 'Removing %r to cognate set %d' % (L, cog.id), extra_tags='warning' ) with reversion.create_revision(): m.delete() # remove cognateset if it's empty if cog.cognate_set.count() == 0: messages.add_message(request, messages.INFO, 'Removing empty cognate set %r' % cog, extra_tags='warning' ) with reversion.create_revision(): cog.delete() url = reverse('cognacy:do', kwargs={ 'word': form.cleaned_data['word'].slug, 'clade': form.cleaned_data['clade'] }) return redirect(url) return redirect(reverse('cognacy:do_index')) # go somewhere safe on form tamper.
def test_validate_clades(self): clades = [('', 'all'), ('clade1', 'subclade')] form_data = {'word': self.word.id, 'clade': 'clade1'} d = DoCognateForm(form_data, clades=clades) assert d.is_valid()
def test_validate_empty_clades(self): form_data = {'word': self.word.id, 'clade': ''} d = DoCognateForm(form_data) assert d.is_valid()
def test_clades(self): clades = [('', 'all'), ('clade1', 'subclade')] form_data = {'word': self.word.id, 'clade': 'clade1'} d = DoCognateForm(form_data, clades=clades) assert d.fields['clade'].choices == clades
def test_empty_clades(self): form_data = {'word': self.word.id, 'clade': ''} d = DoCognateForm(form_data) assert d.fields['clade'].choices == []