1d7bab572ba90b17bcb6d079ff52648be4350263
[redakcja.git] / apps / catalogue / management / commands / make_master.py
1 # -*- coding: utf-8 -*-
2
3 from django.core.management.base import BaseCommand
4 from django.core.management.color import color_style
5 from catalogue.management.prompt import confirm
6 from catalogue.models import Book
7 from optparse import make_option
8 from datetime import date
9 import re
10 from slughifi import slughifi
11 from lxml import etree
12
13
14 dc_fixed = {
15     'description': u'Publikacja zrealizowana w ramach projektu Cyfrowa Przyszłość (http://edukacjamedialna.edu.pl).',
16     'rights': u'Creative Commons Uznanie autorstwa - Na tych samych warunkach 3.0',
17     'rights_license': u'http://creativecommons.org/licenses/by-sa/3.0/',
18     }
19
20 dc_namespaces = { "dc": "http://purl.org/dc/elements/1.1/" }
21
22 class Command(BaseCommand):
23     option_list = BaseCommand.option_list + (
24         make_option('-s', '--slug', dest='slug', help="Slug for master module"),
25         make_option('-F', '--file', dest='slugs_file', help="file with child module slugs per line"),
26         make_option('-t', '--title', dest='title', default='', help="title of master module"),
27         make_option('-l', '--level', dest='audience', default='', help='Audience level'),
28     )
29     help = 'Create a master module skeleton'
30
31     def looks_like_synthetic(self, title):
32         if re.match(r"^(gim|lic)_\d[.]? ", title):
33             return True
34         return False
35
36     def fix_part(self, child, master, typ_, audience_, commit_args):
37         print "checking child %s" % child.slug
38         fc = child[0]
39         txt = fc.materialize()
40         changed = False
41         try:
42             t = etree.fromstring(txt)
43         except etree.XMLSyntaxError, e:
44             print "cannot read xml in part: %s" % child.slug
45             print unicode(e)
46             return
47         typ = t.xpath("//dc:type", namespaces=dc_namespaces)
48         if not typ:
49             print "no type in DC, inserting under format" 
50             fmt = t.xpath("//dc:format", namespaces=dc_namespaces)
51             container = fmt.getparent()
52             typ = etree.SubElement(container, etree.QName('dc', 'type'))
53             container.insert(typ, container.index(fmt)+1)
54             changed = True
55         else:
56             typ = typ[0]
57         if typ.text != typ_:
58             print "type is '%s', setting to '%s'" % (typ.text, typ_)
59             changed = True
60             typ.text = typ_
61         audience = t.xpath("//dc:audience", namespaces=dc_namespaces)[0]
62         if audience.text != audience_:
63             print "audience is '%s', setting to '%s'" % (audience.text, audience_)
64             changed = True
65             audience.text = audience_
66         if changed:
67             print "will commit."
68             fc.commit(etree.tostring(t, encoding=unicode), **commit_args)
69
70
71     def gen_xml(self, options, synthetic_modules=[], course_modules=[], project_modules=[]):
72         holder = {}
73         holder['xml'] = u""
74
75         def p(t):
76             holder['xml'] += u"%s\n" % t
77
78         def dc(k, v):
79             p(u'<dc:%s xml:lang="pl" xmlns:dc="http://purl.org/dc/elements/1.1/">%s</dc:%s>' % (k, v, k))
80
81         def t(tag, ct):
82             p(u'<%s>%s</%s>' % (tag, ct, tag))
83
84         def slug_url(slug):
85             return u"http://edukacjamedialna/%s/" % slug
86
87         p("<utwor>")
88         p(u'<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">')
89         p(u'<rdf:Description rdf:about="http://redakcja.edukacjamedialna.edu.pl/documents/">')
90
91         dc(u'title', options['title'])
92         for slug in synthetic_modules:
93             dc(u'relation.hasPart', slug_url(slug))
94         for slug in course_modules:
95             dc(u'relation.hasPart', slug_url(slug))
96         for slug in project_modules:
97             dc(u'relation.hasPart', slug_url(slug))
98         dc(u'publisher', u'Fundacja Nowoczesna Polska')
99         #        dc(u'subject.competence', meta.get(u'Wybrana kompetencja z Katalogu', u''))
100         #        dc(u'subject.curriculum', meta.get(u'Odniesienie do podstawy programowej', u''))
101         ## for keyword in meta.get(u'Słowa kluczowe', u'').split(u','):
102         ##     keyword = keyword.strip()
103         ##     dc(u'subject', keyword)
104         dc(u'description', dc_fixed['description'])
105         dc(u'identifier.url', u'http://edukacjamedialna.edu.pl/%s' % options['slug'])
106         dc(u'rights', dc_fixed['rights'])
107         dc(u'rights.license', dc_fixed['rights_license'])
108         dc(u'format', u'xml')
109         dc(u'type', u'text')
110         dc(u'date', date.strftime(date.today(), "%Y-%m-%d"))
111         dc(u'audience', options['audience'])
112         dc(u'language', u'pol')
113         p(u'</rdf:Description>')
114         p(u'</rdf:RDF>')
115         p(u'</utwor>')
116
117         return holder['xml']
118
119     def handle(self, *args, **options):
120         commit_args = {
121             "author_name": 'Platforma',
122             "description": 'Automatycznie zaimportowane z EtherPad',
123             "publishable": False,
124         }
125
126         slug = options['slug']
127         if not slug:
128             slug = slughifi(options['title'])
129         existing = Book.objects.filter(slug=slug)
130
131         master = None
132         if existing:
133             overwrite = confirm("%s exists. Overwrite?" % slug, True)
134             if not overwrite:
135                 return
136             master = existing[0]
137         else:
138             master = Book()
139         master.slug = slug
140         master.title = options['title']
141         master.save()
142
143         if len(master) == 0:
144             master.add(slug, options['title'])
145
146         synthetic_modules = []
147         course_modules = []
148         if 'slugs_file' in options:
149             f = open(options['slugs_file'], 'r')
150             try:
151                 titles = [l.strip() for l in f.readlines()]
152
153                 for t in titles:
154                     if not t: continue
155                     try:
156                         b = Book.objects.get(title=t)
157                     except Book.DoesNotExist:
158                         print "Book for title %s does not exist" % t
159                         continue
160                     if self.looks_like_synthetic(t):
161                         synthetic_modules.append(b.slug)
162                         self.fix_part(b, master, 'synthetic', options['audience'], commit_args)
163                     else:
164                         course_modules.append(b.slug)
165                         self.fix_part(b, master, 'course', options['audience'], commit_args)
166             except Exception, e:
167                 print "Error getting slug list (file %s): %s" % (options['slugs_file'], e)
168
169         print "synthetic: %s" % synthetic_modules
170         print "course: %s" % course_modules
171
172         xml = self.gen_xml(options, synthetic_modules, course_modules)
173         c = master[0]
174         print xml
175         if confirm("Commit?", True):
176             c.commit(xml, **commit_args)
177