Example #1
0
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})
Example #2
0
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)
    )
Example #3
0
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.
Example #4
0
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,
        })
Example #5
0
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.
Example #6
0
 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()
Example #7
0
 def test_validate_empty_clades(self):
     form_data = {'word': self.word.id, 'clade': ''}
     d = DoCognateForm(form_data)
     assert d.is_valid()
Example #8
0
 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
Example #9
0
 def test_empty_clades(self):
     form_data = {'word': self.word.id, 'clade': ''}
     d = DoCognateForm(form_data)
     assert d.fields['clade'].choices == []