1 # -*- coding: utf-8 -*-
3 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
4 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
9 from django.contrib.auth.models import User
10 from lxml import etree
11 from optparse import make_option
13 from collections import defaultdict
14 from django.core.management import BaseCommand
16 from catalogue.models import Book
17 from librarian import RDFNS, DCNS
20 'pdf': 'application/pdf',
21 'epub': 'application/epub+zip',
22 'mobi': 'application/x-mobipocket-ebook',
29 r'<dc:relation.hasFormat id="%(format)s" xmlns:dc="http://purl.org/dc/elements/1.1/">%(url)s'
30 r'</dc:relation.hasFormat>',
31 r'<meta refines="#%(format)s" id="%(format)s-id" property="dcterms:identifier">ISBN-%(isbn)s</meta>',
32 r'<meta refines="#%(format)s-id" property="identifier-type">ISBN</meta>',
33 r'<meta refines="#%(format)s" property="dcterms:format">%(content_type)s</meta>',
37 def url_for_format(slug, format):
39 return 'https://wolnelektury.pl/katalog/lektura/%s.html' % slug
41 return 'http://wolnelektury.pl/media/book/%(format)s/%(slug)s.%(format)s' % {'slug': slug, 'format': format}
44 class Command(BaseCommand):
45 option_list = BaseCommand.option_list + (
46 # make_option('-q', '--quiet', action='store_false', dest='verbose',
47 # default=True, help='Less output'),
48 # make_option('-d', '--dry-run', action='store_true', dest='dry_run',
49 # default=False, help="Don't actually touch anything"),
51 '-u', '--username', dest='username', metavar='USER',
52 help='Assign commits to this user (required, preferably yourself).'),
56 def handle(self, csv_file, **options):
57 username = options.get('username')
60 user = User.objects.get(username=username)
62 print 'Please provide a username.'
65 csvfile = open(csv_file, 'rb')
66 isbn_lists = defaultdict(list)
67 for slug, format, isbn in csv.reader(csvfile, delimiter=','):
68 isbn_lists[slug].append((format, isbn))
71 for slug, isbn_list in isbn_lists.iteritems():
72 print 'processing %s' % slug
73 book = Book.objects.get(dc_slug=slug)
74 chunk = book.chunk_set.first()
76 src = old_head.materialize()
77 tree = etree.fromstring(src)
78 isbn_node = tree.find('.//' + DCNS("relation.hasFormat"))
79 if isbn_node is not None:
80 print '%s already contains ISBN metadata, skipping' % slug
82 desc = tree.find(".//" + RDFNS("Description"))
83 for format, isbn in isbn_list:
84 for template in ISBN_TEMPLATES:
85 isbn_xml = template % {
88 'content_type': CONTENT_TYPES[format],
89 'url': url_for_format(slug, format),
91 element = etree.XML(isbn_xml)
94 new_head = chunk.commit(
95 etree.tostring(tree, encoding=unicode),
97 description='automatyczne dodanie isbn'
99 print 'committed %s' % slug
100 if old_head.publishable:
101 new_head.set_publishable(True)
103 print 'Warning: %s not publishable' % slug