Better management of manually-set members.
[wolnelektury.git] / src / isbn / management / commands / export_onix.py
1 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
3 #
4 import json
5 from django.core.management.base import BaseCommand
6 from django.utils import timezone
7
8 from isbn.models import ONIXRecord
9
10 HEADER = """<?xml version="1.0" encoding="UTF-8"?>
11 <ONIXMessage release="3.0"
12     xmlns="http://ns.editeur.org/onix/3.0/reference"
13     xmlns:schemaLocation="https://e-isbn.pl/IsbnWeb/schemas/ONIX_BookProduct_3.0_reference.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
14     <Header>
15         <Sender>
16             <SenderName>Fundacja NOWOCZESNA POLSKA</SenderName>
17             <ContactName>Paulina Choromańska</ContactName>
18             <EmailAddress>paulinachoromanska@nowoczesnapolska.org.pl</EmailAddress>
19         </Sender>
20         <SentDateTime>%s</SentDateTime>
21         <MessageNote>Opis wygenerowany przez wydawcę</MessageNote>
22         <DefaultLanguageOfText>pol</DefaultLanguageOfText>
23     </Header>"""
24
25 PRODUCT = """
26     <Product datestamp="%(datestamp)s">
27         <RecordReference>%(record_reference)s</RecordReference>
28         <NotificationType>03</NotificationType>
29         <RecordSourceType>01</RecordSourceType>
30         <RecordSourceName>Fundacja NOWOCZESNA POLSKA</RecordSourceName>
31         <ProductIdentifier>
32             <ProductIDType>15</ProductIDType>
33             <IDValue>%(isbn)s</IDValue>
34         </ProductIdentifier>
35         <DescriptiveDetail>
36             <ProductComposition>00</ProductComposition>
37             <ProductForm>%(product_form)s</ProductForm>%(product_form_detail)s
38             <TitleDetail>
39                 <TitleType>01</TitleType>
40                 <TitleElement>
41                     <TitleElementLevel>01</TitleElementLevel>%(part_number)s
42                     <TitleText>%(title)s</TitleText>
43                 </TitleElement>
44             </TitleDetail>%(contributors)s
45             <EditionType>%(edition_type)s</EditionType>
46             <EditionNumber>%(edition_number)s</EditionNumber>
47             <Language>
48                 <LanguageRole>01</LanguageRole>
49                 <LanguageCode>%(language)s</LanguageCode>
50             </Language>
51         </DescriptiveDetail>
52         <PublishingDetail>
53             <Imprint>
54                 <ImprintName>%(imprint)s</ImprintName>
55             </Imprint>
56             <Publisher>
57                 <PublishingRole>01</PublishingRole>
58                 <PublisherName>Fundacja NOWOCZESNA POLSKA</PublisherName>
59             </Publisher>
60             <CityOfPublication>Warszawa</CityOfPublication>
61             <CountryOfPublication>PL</CountryOfPublication>
62             <PublishingDate>
63                 <PublishingDateRole>01</PublishingDateRole>
64                 <Date>%(publishing_date)s</Date>
65             </PublishingDate>
66             <PublishingDate>
67                 <PublishingDateRole>09</PublishingDateRole>
68                 <Date>%(publishing_date)s</Date>
69             </PublishingDate>
70         </PublishingDetail>
71     </Product>"""
72
73 PRODUCT_FORM_DETAIL = """
74             <ProductFormDetail>%s</ProductFormDetail>"""
75
76 PART_NUMBER = """
77                     <PartNumber>%s</PartNumber>"""
78
79 CONTRIBUTOR = """
80             <Contributor>
81                 <SequenceNumber>%(no)s</SequenceNumber>
82                 <ContributorRole>%(role)s</ContributorRole>%(identifier)s%(name)s%(corporate_name)s%(unnamed)s%(birth_date)s%(death_date)s
83             </Contributor>"""
84
85 NAME_IDENTFIER = """
86                 <NameIdentifier>
87                     <NameIDType>16</NameIDType>
88                     <IDValue>%(isni)s</IDValue>
89                 </NameIdentifier>"""
90
91 NAME = """
92                 <PersonNameInverted>%s</PersonNameInverted>"""
93
94 CORPORATE_NAME = """
95                 <CorporateName>%s</CorporateName>"""
96
97 UNNAMED = """
98                 <UnnamedPersons>%s</UnnamedPersons>"""
99
100 CONTRIBUTOR_DATE = """
101                 <ContributorDate>
102                     <ContributorDateRole>%(role)s</ContributorDateRole>
103                     <Date>%(date)s</Date>
104                 </ContributorDate>"""
105
106 FOOTER = """
107 </ONIXMessage>"""
108
109
110 class Command(BaseCommand):
111     help = "Export ONIX."
112
113     def handle(self, *args, **options):
114         xml = HEADER % timezone.now().strftime('%Y%m%dT%H%M%z')
115         for record in ONIXRecord.objects.all():
116             xml += self.render_product(record)
117         xml += FOOTER
118         print(xml)
119
120     def render_product(self, record):
121         if record.product_form_detail:
122             product_form_detail = PRODUCT_FORM_DETAIL % record.product_form_detail
123         else:
124             product_form_detail = ''
125         if record.part_number:
126             part_number = PART_NUMBER % record.part_number
127         else:
128             part_number = ''
129         contributors = ''
130         for no, contributor in enumerate(json.loads(record.contributors), start=1):
131             contributors += self.render_contributor(no, contributor)
132         return PRODUCT % {
133             'datestamp': record.datestamp.strftime('%Y%m%d'),
134             'record_reference': record.reference(),
135             'isbn': record.isbn(),
136             'product_form': record.product_form,
137             'product_form_detail': product_form_detail,
138             'part_number': part_number,
139             'title': record.title,
140             'contributors': contributors,
141             'edition_type': record.edition_type,
142             'edition_number': record.edition_number,
143             'language': record.language,
144             'imprint': record.imprint,
145             'publishing_date': record.publishing_date.strftime('%Y%m%d'),
146         }
147
148     @staticmethod
149     def render_contributor(no, contributor):
150         if 'isni' in contributor:
151             identifier = NAME_IDENTFIER % contributor
152         else:
153             identifier = ''
154         if 'name' in contributor:
155             name = NAME % contributor['name']
156         else:
157             name = ''
158         if 'corporate_name' in contributor:
159             corporate_name = CORPORATE_NAME % contributor['corporate_name']
160         else:
161             corporate_name = ''
162         if 'unnamed' in contributor:
163             unnamed = UNNAMED % contributor['unnamed']
164         else:
165             unnamed = ''
166         if 'birth_date' in contributor:
167             birth_date = CONTRIBUTOR_DATE % {'role': '50', 'date': contributor['birth_date']}
168         else:
169             birth_date = ''
170         if 'death_date' in contributor:
171             death_date = CONTRIBUTOR_DATE % {'role': '51', 'date': contributor['death_date']}
172         else:
173             death_date = ''
174         return CONTRIBUTOR % {
175             'no': no,
176             'role': contributor['role'],
177             'identifier': identifier,
178             'name': name,
179             'corporate_name': corporate_name,
180             'unnamed': unnamed,
181             'birth_date': birth_date,
182             'death_date': death_date,
183         }