Skip to content

Commit

Permalink
Add import functionality from .qsp, Quelea archive
Browse files Browse the repository at this point in the history
  • Loading branch information
mdujava committed Dec 30, 2021
1 parent 83b6068 commit 3b0a9bf
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 7 deletions.
6 changes: 5 additions & 1 deletion backend/forms.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Forms for backend app"""
from django.forms import ModelForm, ModelMultipleChoiceField, CheckboxSelectMultiple
from django.forms import ModelForm, ModelMultipleChoiceField, CheckboxSelectMultiple, Form, FileField

from backend.models import Song
from category.models import Category
Expand All @@ -13,3 +13,7 @@ class Meta:
model = Song
# pylint: disable=modelform-uses-exclude
exclude = ["prerendered_web", "prerendered_pdf"]

class UploadFileForm(Form):
categories = ModelMultipleChoiceField(widget=CheckboxSelectMultiple, queryset=Category.objects.all())
file = FileField(required=True, allow_empty_file=False)
2 changes: 2 additions & 0 deletions backend/menus.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
reverse("category:list")),
MenuItem(_("Add a song"),
reverse("backend:add")),
MenuItem(_("Import Quelue archive"),
reverse("backend:import")),
MenuItem(_("Add Songbook"),
reverse("category:add")),
MenuItem(_("Analytics"),
Expand Down
5 changes: 5 additions & 0 deletions backend/templates/songs/import.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% extends "base/form.html" %}
{% load i18n %}

{% block title %} {% trans "Song Editor" %} {% endblock %}
{% block header %} {% trans "Song Editor" %} {% endblock %}
3 changes: 2 additions & 1 deletion backend/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
from django.urls import path

from backend.views import SongCreateView, SongUpdateView, SongDeleteView, SongsDatatableView, \
IndexSongListView
IndexSongListView, UploadView

urlpatterns = [
path('', IndexSongListView.as_view(), name="index"),
path('add', SongCreateView.as_view(), name="add"),
path('edit/<int:pk>', SongUpdateView.as_view(), name="edit"),
path('delete/<int:pk>', SongDeleteView.as_view(), name="delete"),
path('api/songs', SongsDatatableView.as_view(), name="songs"),
path('import', UploadView.as_view(), name="import"),
]
68 changes: 66 additions & 2 deletions backend/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Views for backend app"""
import json
from typing import Dict
import zipfile
import xml.etree.ElementTree as ET

from django.conf import settings
from django.contrib import messages
Expand All @@ -11,11 +13,12 @@
from django.urls import reverse_lazy, reverse
from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _, gettext_noop
from django.views.generic import ListView, CreateView, UpdateView, DeleteView
from django.views.generic import ListView, CreateView, UpdateView, DeleteView, FormView
from django_datatables_view.base_datatable_view import BaseDatatableView
from django.http import HttpResponseRedirect

from analytics.views import AnalyticsMixin
from backend.forms import SongForm
from backend.forms import SongForm, UploadFileForm
from backend.models import Song
from backend.utils import regenerate_pdf, regenerate_prerender
from category.models import Category
Expand Down Expand Up @@ -120,3 +123,64 @@ class SongsDatatableView(BaseDatatableView):
model = Song
max_display_length = 500
columns = ["name", "author", "capo"]

def SongsQueleaImport(uploaded_file, cleaned_data):

def read_quelea_file(filename):
with zipfile.ZipFile(filename) as f:
return {name: f.read(name) for name in f.namelist()}


def get_lyrics(mapp):
ret = []
for name in mapp.keys():
song = ET.fromstring(mapp[name])
lyrics_lines = []
for child in song.findall('.//lyrics'):
if child.text is not None:
lyrics_lines.append(child.text)

ret.append((name, '\n\n'.join(lyrics_lines)))
return ret


songs = read_quelea_file(cleaned_data['file'])
lyric = get_lyrics(songs)

songs = 0
for (name, l) in lyric:
clean_name = name.rstrip('.xml')

song_obj = Song(name=clean_name, text=l)
song_obj.save()

list_ids = [f.pk for f in cleaned_data['categories']]

song_obj.categories.set(list_ids)
songs += 1

return songs


@method_decorator(login_required, name='dispatch')
class UploadView(FormView):
form_class = UploadFileForm
template_name = 'songs/import.html'

success_url = reverse_lazy('backend:index')

def get_success_url(self):
#regenerate_pdf(self.object)
#regenerate_prerender(self.object)
return super().get_success_url()

def post(self, request, *args, **kwargs):
"""A POST request. Validate the form and then handle the upload
based ont the POSTed data. Does not handle extra parameters yet.
"""
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
SongsQueleaImport(request.FILES['file'], form.cleaned_data)
else:
print(form.errors)
return HttpResponseRedirect(self.get_success_url())
2 changes: 1 addition & 1 deletion chords/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'sass_processor.finders.CssFinder'
'sass_processor.finders.CssFinder',
]

COMPRESS_ENABLED = True
Expand Down
8 changes: 6 additions & 2 deletions frontend/templates/base/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
{% load bootstrap4 %}

{% block framed_body %}
<form method="post">
{% if form.is_multipart %}
<form enctype="multipart/form-data" method="post">
{% else %}
<form method="post">
{% endif %}
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">{% trans "Submit" %}</button>
{% endbuttons %}
</form>
{{ form.media }}
{% endblock %}
{% endblock %}

0 comments on commit 3b0a9bf

Please sign in to comment.