Example #1
0
def annotate_sequence(request, id):
    """
    Like edit_sequence, but only allows you to change the annotations,
    not the chord sequence. Supplies an automatic annotation that you 
    can choose to apply selectively to the sequence.
    """
    sequence = get_object_or_404(ChordSequence, id=id)
    raise NotImplementedError, "Don't use this for now: the JP has changed and this needs to be updated"
    #### Do the automatic tagging
    chords = list(sequence.iterator())
    # Get the default grammar
    grammar = Grammar(jpsettings.DEFAULT_GRAMMAR)
    tagger = TrigramAnnotatorChordTagger('alpha', grammar, chords)
    tagger_output = tagger.tag_input()
    
    if request.method == "POST":
        if 'cancel' in request.POST:
            return HttpResponseRedirect(reverse(index))
        else:
            # Save the data
            form = ChordSequenceForm(instance=sequence, data=request.POST)
            chord_forms = [ChordAnnotationForm(chord, tag, prefix="chord%s"%chord.id, data=request.POST) for chord,tag in zip(chords,tagger_output)]
            
            # Check every chord form validates
            chords_valid = reduce(lambda so_far, chord: so_far and chord.is_valid(), chord_forms, True)
            if form.is_valid() and chords_valid:
                form.save()
                # This view can only change the annotations on a sequence
                for cf in chord_forms:
                    cf.save()
                
                if 'save_and_exit' in request.POST:
                    return HttpResponseRedirect(reverse(index))
                else:
                    return HttpResponseRedirect(reverse(annotate_sequence, kwargs={ 'id' : sequence.id }))
    else:
        form = ChordSequenceForm(instance=sequence)
        # Prepare a form for each chord
        chord_forms = [ChordAnnotationForm(chord, tag, prefix="chord%s"%chord.id) for chord,tag in zip(chords,tagger_output)]
        
    # Calculate the width the sequence needs to be
    annotator_width = sum([cf.layout_width+7 for cf in chord_forms])
    
    if len(chord_forms):
        first_field = chord_forms[0].prefix
    else:
        first_field = None
    
    context = {
        'sequence' : sequence,
        'form' : form,
        'chord_forms' : chord_forms,
        'categories' : category_pairs,
        'annotator_width' : annotator_width,
        'first_field' : first_field,
    }
    return render_to_response('sequences/annotate_sequence.html', context, RequestContext(request))
Example #2
0
def edit_sequence(request, id):
    if id is None:
        sequence = ChordSequence()
        song = Song()
        sequence.song = song
    else:
        sequence = get_object_or_404(ChordSequence, id=id)
        song = sequence.song
    
    if request.method == "POST":
        if 'cancel' in request.POST:
            return HttpResponseRedirect(reverse(index))
        else:
            # Save the data
            form = ChordSequenceForm(instance=sequence, data=request.POST)
            song_form = SongForm(instance=song, prefix="song", data=request.POST)
            if form.is_valid():
                # See whether a song was selected
                if form.cleaned_data['song'] is not None and \
                        (sequence.song is None or
                         form.cleaned_data['song'].id != sequence.song.id):
                    # A song has been selected for a new sequence or 
                    #  the song has been changed
                    # Use the selected song
                    form.save()
                else:
                    if form.cleaned_data['song'] is None:
                        # The song was set to empty, so these details 
                        #  should be saved as a new song
                        song_form = SongForm(prefix="song", data=request.POST)
                    # We need to validate the song details
                    if song_form.is_valid():
                        saved_song = song_form.save()
                        saved_seq = form.save()
                        saved_seq.song = saved_song
                        saved_seq.save()
                # First, keep a list of all the chords that were in the sequence before
                old_chords = get_chord_list_from_sequence(sequence)
                # Handle the chord sequence data
                chord_dataset = json.loads(request.POST['chords'])
                chords = []
                for chord_data in chord_dataset:
                    chords.append(_save_chord_from_data(chord_data, sequence))
                # Now they're saved, chain the sequence together
                for i,chord in enumerate(chords):
                    if i < len(chords)-1:
                        chord.next = chords[i+1]
                    else:
                        chord.next = None
                    chord.save()
                if len(chords):
                    sequence.first_chord = chords[0]
                else:
                    sequence.first_chord = None
                sequence.save()
                # Clean up any chords that have been deleted
                new_chords = get_chord_list_from_sequence(sequence)
                for old_chord in old_chords:
                    if old_chord not in new_chords:
                        # Chord has been removed from the sequence - delete it
                        to_delete = Chord.objects.get(id=old_chord)
                        to_delete.delete()
                if 'save_and_exit' in request.POST:
                    return HttpResponseRedirect(reverse(index))
                else:
                    return HttpResponseRedirect(reverse(edit_sequence, kwargs={ 'id' : sequence.id }))
    else:
        form = ChordSequenceForm(instance=sequence)
        song_form = SongForm(prefix="song", instance=song)
        
    chord_form = ChordForm()
        
    chord_editor_options = json.dumps({
        'bars_across' : 4,
        'width' : 1000,
        'bar_length' : sequence.bar_length,
    })
    chord_data = sequence.to_json()
    
    chord_types = [( type.id, type.symbol ) for type in ChordType.objects.all()]
    
    context = {
        'sequence' : sequence,
        'form' : form,
        'song_form' : song_form,
        'chord_form' : chord_form,
        'chord_data' : chord_data,
        'chord_editor_options' : chord_editor_options,
        'chord_roots' : _root_choices,
        'chord_types' : chord_types,
        'categories' : category_pairs,
        'pos_tags' : pos_tags,
    }
    return render_to_response('sequences/edit_sequence.html', context, RequestContext(request))
Example #3
0
def annotate_sequence(request, id):
    """
    Like edit_sequence, but only allows you to change the annotations,
    not the chord sequence. Supplies an automatic annotation that you 
    can choose to apply selectively to the sequence.
    """
    sequence = get_object_or_404(ChordSequence, id=id)
    raise NotImplementedError, "Don't use this for now: the JP has changed and this needs to be updated"
    #### Do the automatic tagging
    chords = list(sequence.iterator())
    # Get the default grammar
    grammar = Grammar(jpsettings.DEFAULT_GRAMMAR)
    tagger = TrigramAnnotatorChordTagger('alpha', grammar, chords)
    tagger_output = tagger.tag_input()

    if request.method == "POST":
        if 'cancel' in request.POST:
            return HttpResponseRedirect(reverse(index))
        else:
            # Save the data
            form = ChordSequenceForm(instance=sequence, data=request.POST)
            chord_forms = [
                ChordAnnotationForm(chord,
                                    tag,
                                    prefix="chord%s" % chord.id,
                                    data=request.POST)
                for chord, tag in zip(chords, tagger_output)
            ]

            # Check every chord form validates
            chords_valid = reduce(
                lambda so_far, chord: so_far and chord.is_valid(), chord_forms,
                True)
            if form.is_valid() and chords_valid:
                form.save()
                # This view can only change the annotations on a sequence
                for cf in chord_forms:
                    cf.save()

                if 'save_and_exit' in request.POST:
                    return HttpResponseRedirect(reverse(index))
                else:
                    return HttpResponseRedirect(
                        reverse(annotate_sequence, kwargs={'id': sequence.id}))
    else:
        form = ChordSequenceForm(instance=sequence)
        # Prepare a form for each chord
        chord_forms = [
            ChordAnnotationForm(chord, tag, prefix="chord%s" % chord.id)
            for chord, tag in zip(chords, tagger_output)
        ]

    # Calculate the width the sequence needs to be
    annotator_width = sum([cf.layout_width + 7 for cf in chord_forms])

    if len(chord_forms):
        first_field = chord_forms[0].prefix
    else:
        first_field = None

    context = {
        'sequence': sequence,
        'form': form,
        'chord_forms': chord_forms,
        'categories': category_pairs,
        'annotator_width': annotator_width,
        'first_field': first_field,
    }
    return render_to_response('sequences/annotate_sequence.html', context,
                              RequestContext(request))
Example #4
0
def reannotate_sequence(request, id, new=False):
    """
    Takes the chords from an old sequence and allows a new version of it to 
    be created with alternative annotations.
    
    """
    sequence = get_object_or_404(ChordSequence, id=id)
    song = sequence.song

    if request.method == "POST":
        if 'cancel' in request.POST:
            return HttpResponseRedirect(reverse(index))
        else:
            # Check there's the same number of chords
            # We will ignore any changes to the chords themselves
            chord_dataset = json.loads(request.POST['chords'])
            if len(sequence) != len(chord_dataset):
                raise ValidationError, "You can't edit the chord sequence "\
                    "through this page"
            # Update the annotations from the form data
            chords = []
            for chord_data, chord in zip(chord_dataset, sequence.iterator()):
                chord.category = chord_data['category']
                chord.save()
                # And the treeinfo fields
                tree = chord.treeinfo
                if 'coord_resolved' in chord_data and chord_data[
                        'coord_resolved']:
                    tree.coord_resolved = True
                    tree.save()
                elif tree.coord_resolved:
                    tree.coord_resolved = False
                    tree.save()
                if 'coord_unresolved' in chord_data and chord_data[
                        'coord_unresolved']:
                    tree.coord_unresolved = True
                    tree.save()
                elif tree.coord_unresolved:
                    tree.coord_unresolved = False
                    tree.save()
                chords.append(chord)

            if 'save_and_exit' in request.POST:
                return HttpResponseRedirect(reverse(index))
            else:
                return HttpResponseRedirect(
                    reverse('reannotate', args=(sequence.id, )))
    else:
        form = ChordSequenceForm(instance=sequence)

    if new:
        chords = list(sequence.iterator())
        # Create a copy of this sequence
        sequence.id = None
        # Clear notes and omissions, so we don't give any clues to bias
        sequence.notes = ''
        sequence.omissions = ''
        sequence.save()

        # Copy each chord
        # Clear annotations to start afresh
        for chord in chords:
            chord.id = None
            chord.sequence = sequence
            chord.category = ''
            chord.save()

        # Chain together these chords
        previous_chord = chords[0]
        for chord in chords[1:]:
            previous_chord.next = chord
            previous_chord.save()
            previous_chord = chord
        chords[-1].next = None
        chords[-1].save()

        sequence.first_chord = chords[0]
        # Mark this as an alternative annotation
        sequence.alternative = True
        sequence.save()
        # Go to the editor page for this new sequence
        return HttpResponseRedirect(reverse('reannotate',
                                            args=(sequence.id, )))

    chord_form = ChordForm(readonly=True)

    chord_editor_options = json.dumps({
        'bars_across': 4,
        'width': 1000,
        'bar_length': sequence.bar_length,
        'vertical_offset': 280,
    })

    chord_data = sequence.to_json()

    chord_types = [(type.id, type.symbol) for type in ChordType.objects.all()]

    context = {
        'sequence': sequence,
        'form': form,
        'song_form': None,
        'chord_form': chord_form,
        'chord_data': chord_data,
        'chord_editor_options': chord_editor_options,
        'chord_roots': _root_choices,
        'chord_types': chord_types,
        'categories': category_pairs,
        'pos_tags': pos_tags,
        'hidenotes': True,
    }
    return render_to_response('sequences/reannotate_sequence.html', context,
                              RequestContext(request))
Example #5
0
def edit_sequence(request, id):
    if id is None:
        sequence = ChordSequence()
        song = Song()
        sequence.song = song
    else:
        sequence = get_object_or_404(ChordSequence, id=id)
        song = sequence.song

    if request.method == "POST":
        if 'cancel' in request.POST:
            return HttpResponseRedirect(reverse(index))
        else:
            # Save the data
            form = ChordSequenceForm(instance=sequence, data=request.POST)
            song_form = SongForm(instance=song,
                                 prefix="song",
                                 data=request.POST)
            if form.is_valid():
                # See whether a song was selected
                if form.cleaned_data['song'] is not None and \
                        (sequence.song is None or
                         form.cleaned_data['song'].id != sequence.song.id):
                    # A song has been selected for a new sequence or
                    #  the song has been changed
                    # Use the selected song
                    form.save()
                else:
                    if form.cleaned_data['song'] is None:
                        # The song was set to empty, so these details
                        #  should be saved as a new song
                        song_form = SongForm(prefix="song", data=request.POST)
                    # We need to validate the song details
                    if song_form.is_valid():
                        saved_song = song_form.save()
                        saved_seq = form.save()
                        saved_seq.song = saved_song
                        saved_seq.save()
                # First, keep a list of all the chords that were in the sequence before
                old_chords = get_chord_list_from_sequence(sequence)
                # Handle the chord sequence data
                chord_dataset = json.loads(request.POST['chords'])
                chords = []
                for chord_data in chord_dataset:
                    chords.append(_save_chord_from_data(chord_data, sequence))
                # Now they're saved, chain the sequence together
                for i, chord in enumerate(chords):
                    if i < len(chords) - 1:
                        chord.next = chords[i + 1]
                    else:
                        chord.next = None
                    chord.save()
                if len(chords):
                    sequence.first_chord = chords[0]
                else:
                    sequence.first_chord = None
                sequence.save()
                # Clean up any chords that have been deleted
                new_chords = get_chord_list_from_sequence(sequence)
                for old_chord in old_chords:
                    if old_chord not in new_chords:
                        # Chord has been removed from the sequence - delete it
                        to_delete = Chord.objects.get(id=old_chord)
                        to_delete.delete()
                if 'save_and_exit' in request.POST:
                    return HttpResponseRedirect(reverse(index))
                else:
                    return HttpResponseRedirect(
                        reverse(edit_sequence, kwargs={'id': sequence.id}))
    else:
        form = ChordSequenceForm(instance=sequence)
        song_form = SongForm(prefix="song", instance=song)

    chord_form = ChordForm()

    chord_editor_options = json.dumps({
        'bars_across': 4,
        'width': 1000,
        'bar_length': sequence.bar_length,
    })
    chord_data = sequence.to_json()

    chord_types = [(type.id, type.symbol) for type in ChordType.objects.all()]

    context = {
        'sequence': sequence,
        'form': form,
        'song_form': song_form,
        'chord_form': chord_form,
        'chord_data': chord_data,
        'chord_editor_options': chord_editor_options,
        'chord_roots': _root_choices,
        'chord_types': chord_types,
        'categories': category_pairs,
        'pos_tags': pos_tags,
    }
    return render_to_response('sequences/edit_sequence.html', context,
                              RequestContext(request))