Keep BookMedia filenames tied to media names (keep filename when updating the file, update on name change), which means overwriting the replaced files,
Split book files into dirs by type,
savemedia: update name on media replace, don't need to slugify though (BookMedia does it anyway)
from django.core.management.base import BaseCommand
from django.core.files import File
-from slughifi import slughifi
from catalogue.models import Book, BookMedia
from catalogue.utils import ExistingFile
try:
assert source_sha1
bm = book.media.get(type=ext, source_sha1=source_sha1)
- print "Replacing media: %s (%s)" % (bm.name, ext)
+ print "Replacing media: %s (%s)" % (bm.name.encode('utf-8'), ext)
except (AssertionError, BookMedia.DoesNotExist):
- bm = BookMedia(book=book, type=ext, name=name)
+ bm = BookMedia(book=book, type=ext)
print "Creating new media"
- bm.file.save(slughifi(name), ExistingFile(path))
+ bm.name = name
+ bm.file.save(None, ExistingFile(path))
bm.save()
transaction.commit()
transaction.leave_transaction_management()
from newtagging.models import TagBase, tags_updated
from newtagging import managers
from catalogue.fields import JSONField
+from catalogue.utils import ExistingFile
from librarian import dcparser, html, epub, NoDublinCore
import mutagen
name = slughifi(filename.split(".")[0])
else:
name = slughifi(media.name)
- return 'lektura/%s.%s' % (name[:maxlen-len('lektura/.%s' % ext)-4], ext)
+ return 'book/%s/%s.%s' % (ext, name[:maxlen-len('book/%s/.%s' % (ext, ext))-4], ext)
return get_dynamic_path
verbose_name_plural = _('book media')
def save(self, *args, **kwargs):
+ try:
+ b = BookMedia.objects.get(pk=self.pk)
+ except BookMedia.DoesNotExist, e:
+ pass
+ else:
+ # if file is replaced, delete the old one
+ if self.file.path != b.file.path:
+ b.file.delete(save=False)
+ # if name changed, change the file name, too
+ elif self.name != b.name:
+ self.file.save(None, ExistingFile(self.file.path))
+
super(BookMedia, self).save(*args, **kwargs)
extra_info = self.get_extra_info_value()
extra_info.update(self.read_meta())
Reads some metadata from the audiobook.
"""
- artist_name = director_name = ''
+ artist_name = director_name = project = funded_by = ''
if self.type == 'mp3':
try:
audio = id3.ID3(self.file.path)
artist_name = ', '.join(', '.join(tag.text) for tag in audio.getall('TPE1'))
director_name = ', '.join(', '.join(tag.text) for tag in audio.getall('TPE3'))
+ project = ", ".join([t.data for t in audio.getall('PRIV')
+ if t.owner=='wolnelektury.pl?project'])
+ funded_by = ", ".join([t.data for t in audio.getall('PRIV')
+ if t.owner=='wolnelektury.pl?funded_by'])
except:
pass
elif self.type == 'ogg':
audio = mutagen.File(self.file.path)
artist_name = ', '.join(audio.get('artist', []))
director_name = ', '.join(audio.get('conductor', []))
+ project = ", ".join(audio.get('project', []))
+ funded_by = ", ".join(audio.get('funded_by', []))
except:
pass
else:
return {}
- return {'artist_name': artist_name, 'director_name': director_name}
+ return {'artist_name': artist_name, 'director_name': director_name,
+ 'project': project, 'funded_by': funded_by}
@staticmethod
def read_source_sha1(filepath, filetype):
try:
audio = id3.ID3(filepath)
return [t.data for t in audio.getall('PRIV')
- if t.owner=='http://wolnelektury.pl?flac_sha1'][0]
+ if t.owner=='wolnelektury.pl?flac_sha1'][0]
except:
return None
elif filetype == 'ogg':
def counters(request):
+ form = forms.SearchForm()
+
books = models.Book.objects.count()
books_nonempty = models.Book.objects.exclude(html_file='').count()
books_empty = models.Book.objects.filter(html_file='').count()
annotate(count=Count('type')).\
order_by('type')
for mt in media_types:
- mt['size'] = sum(b.file.size for b in models.BookMedia.objects.filter(type=mt['type']))
+ size = 0
+ deprecated = missing_project = 0
+ for b in models.BookMedia.objects.filter(type=mt['type']):
+ size += b.file.size
+ if b.type in ('mp3', 'ogg'):
+ if not b.source_sha1:
+ deprecated += 1
+ if not 'project' in b.get_extra_info_value():
+ missing_project += 1
+ mt['size'] = size
+ mt['deprecated'] = deprecated
+ mt['missing_project'] = missing_project
return render_to_response('catalogue/counters.html',
locals(), context_instance=RequestContext(request))
extra_info = book.get_extra_info_value()
+ projects = set()
+ for m in book.media.filter(type='mp3'):
+ # ogg files are always from the same project
+ meta = m.get_extra_info_value()
+ project = meta.get('project')
+ if not project:
+ # temporary fallback
+ project = u'CzytamySłuchając'
+
+ projects.add((project, meta.get('funded_by')))
+ projects = sorted(projects)
+
form = forms.SearchForm()
return render_to_response('catalogue/book_detail.html', locals(),
context_instance=RequestContext(request))
</ul>
{% endif %}
</div> <!-- /audiobooks -->
- <p>{% blocktrans with '<a href="http://czytamysluchajac.pl">CzytamySłuchając</a>' as cs %}Audiobooks were prepared as a part of the {{ cs }} project.{% endblocktrans %}
- </p>
+ {% if projects|length > 1 %}
+ <p>{% trans "Audiobooks were prepared as a part of the projects:" %}</p>
+ <ul>
+ {% for cs, fb in projects %}
+ <li>
+ {% if fb %}
+ {% blocktrans %}{{ cs }}, funded by {{ fb }}{% endblocktrans %}
+ {% else %}
+ {{ cs }}
+ {% endif %}
+ </li>
+ {% endfor %}
+ </ul>
+ {% else %}
+ <p>
+ {% with cs=projects.0.0 fb=projects.0.1 %}
+ {% if fb %}
+ {% blocktrans %}Audiobooks were prepared as a part of the {{ cs }} project funded by {{ fb }}.{% endblocktrans %}
+ {% else %}
+ {% blocktrans %}Audiobooks were prepared as a part of the {{ cs }} project.{% endblocktrans %}
+ {% endif %}
+ {% endwith %}
+ </p>
+ {% endif %}
{% endif %}
</div>
</div>
{% block body %}
<h1>Liczniki</h1>
+ <form action="{% url search %}" method="get" accept-charset="utf-8" id="search-form">
+ <p>{{ form.q }} <input type="submit" value="{% trans "Search" %}" /> <strong>{% trans "or" %}</strong> <a href="{% url main_page %}">{% trans "return to main page" %}</a></p>
+ </form>
<table>
+ <tr><th>Utwory</th></tr>
<tr><td>Wszystkie utwory:</td><td>{{ books }}</td></tr>
<tr><td>Utwory z własną treścią:</td><td>{{ books_nonempty }}</td></tr>
<tr><td>Utwory bez własnej treści:</td><td>{{ books_empty }}</td></tr>
<tr><td>Niezależne książki:</td><td>{{ books_root }}</td></tr>
+
+ <tr><th>Media</th><th>Liczba</th><th>Rozmiar</th><th>Do wymiany</th></tr>
{% for mt in media_types %}
- <tr><td>Media – {{ mt.type }}:</td><td>{{ mt.count }}, {{ mt.size|filesizeformat }}</td></tr>
+ <tr><td>{{ mt.type }}:</td>
+ <td>{{ mt.count }}</td>
+ <td>{{ mt.size|filesizeformat }}</td>
+ <td>{{ mt.deprecated }}</td>
+ </tr>
{% endfor %}
</table>