summaryrefslogtreecommitdiffstats
path: root/feedgen/ext/dc.py
blob: 466c66db110e774a884a1f97e20d0d4ebecafaa8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
# -*- coding: utf-8 -*-
'''
    feedgen.ext.dc
    ~~~~~~~~~~~~~~~~~~~

    Extends the FeedGenerator to add Dubline Core Elements to the feeds.

    Descriptions partly taken from
    http://dublincore.org/documents/dcmi-terms/#elements-coverage

    :copyright: 2013-2017, Lars Kiesow <lkiesow@uos.de>

    :license: FreeBSD and LGPL, see license.* for more details.
'''

from feedgen.ext.base import BaseExtension
from feedgen.util import xml_elem


class DcBaseExtension(BaseExtension):
    '''Dublin Core Elements extension for podcasts.
    '''

    def __init__(self):
        # http://dublincore.org/documents/usageguide/elements.shtml
        # http://dublincore.org/documents/dces/
        # http://dublincore.org/documents/dcmi-terms/
        self._dcelem_contributor = None
        self._dcelem_coverage = None
        self._dcelem_creator = None
        self._dcelem_date = None
        self._dcelem_description = None
        self._dcelem_format = None
        self._dcelem_identifier = None
        self._dcelem_language = None
        self._dcelem_publisher = None
        self._dcelem_relation = None
        self._dcelem_rights = None
        self._dcelem_source = None
        self._dcelem_subject = None
        self._dcelem_title = None
        self._dcelem_type = None

    def extend_ns(self):
        return {'dc': 'http://purl.org/dc/elements/1.1/'}

    def _extend_xml(self, xml_element):
        '''Extend xml_element with set DC fields.

        :param xml_element: etree element
        '''
        DCELEMENTS_NS = 'http://purl.org/dc/elements/1.1/'

        for elem in ['contributor', 'coverage', 'creator', 'date',
                     'description', 'language', 'publisher', 'relation',
                     'rights', 'source', 'subject', 'title', 'type', 'format',
                     'identifier']:
            if hasattr(self, '_dcelem_%s' % elem):
                for val in getattr(self, '_dcelem_%s' % elem) or []:
                    node = xml_elem('{%s}%s' % (DCELEMENTS_NS, elem),
                                    xml_element)
                    node.text = val

    def extend_atom(self, atom_feed):
        '''Extend an Atom feed with the set DC fields.

        :param atom_feed: The feed root element
        :returns: The feed root element
        '''

        self._extend_xml(atom_feed)

        return atom_feed

    def extend_rss(self, rss_feed):
        '''Extend a RSS feed with the set DC fields.

        :param rss_feed: The feed root element
        :returns: The feed root element.
        '''
        channel = rss_feed[0]
        self._extend_xml(channel)

        return rss_feed

    def dc_contributor(self, contributor=None, replace=False):
        '''Get or set the dc:contributor which is an entity responsible for
        making contributions to the resource.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-contributor

        :param contributor: Contributor or list of contributors.
        :param replace: Replace already set contributors (default: False).
        :returns: List of contributors.
        '''
        if contributor is not None:
            if not isinstance(contributor, list):
                contributor = [contributor]
            if replace or not self._dcelem_contributor:
                self._dcelem_contributor = []
            self._dcelem_contributor += contributor
        return self._dcelem_contributor

    def dc_coverage(self, coverage=None, replace=True):
        '''Get or set the dc:coverage which indicated the spatial or temporal
        topic of the resource, the spatial applicability of the resource, or
        the jurisdiction under which the resource is relevant.

        Spatial topic and spatial applicability may be a named place or a
        location specified by its geographic coordinates. Temporal topic may be
        a named period, date, or date range. A jurisdiction may be a named
        administrative entity or a geographic place to which the resource
        applies. Recommended best practice is to use a controlled vocabulary
        such as the Thesaurus of Geographic Names [TGN]. Where appropriate,
        named places or time periods can be used in preference to numeric
        identifiers such as sets of coordinates or date ranges.

        References:
        [TGN] http://www.getty.edu/research/tools/vocabulary/tgn/index.html

        :param coverage: Coverage of the feed.
        :param replace: Replace already set coverage (default: True).
        :returns: Coverage of the feed.
        '''
        if coverage is not None:
            if not isinstance(coverage, list):
                coverage = [coverage]
            if replace or not self._dcelem_coverage:
                self._dcelem_coverage = []
            self._dcelem_coverage = coverage
        return self._dcelem_coverage

    def dc_creator(self, creator=None, replace=False):
        '''Get or set the dc:creator which is an entity primarily responsible
        for making the resource.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-creator

        :param creator: Creator or list of creators.
        :param replace: Replace already set creators (default: False).
        :returns: List of creators.
        '''
        if creator is not None:
            if not isinstance(creator, list):
                creator = [creator]
            if replace or not self._dcelem_creator:
                self._dcelem_creator = []
            self._dcelem_creator += creator
        return self._dcelem_creator

    def dc_date(self, date=None, replace=True):
        '''Get or set the dc:date which describes a point or period of time
        associated with an event in the lifecycle of the resource.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-date

        :param date: Date or list of dates.
        :param replace: Replace already set dates (default: True).
        :returns: List of dates.
        '''
        if date is not None:
            if not isinstance(date, list):
                date = [date]
            if replace or not self._dcelem_date:
                self._dcelem_date = []
            self._dcelem_date += date
        return self._dcelem_date

    def dc_description(self, description=None, replace=True):
        '''Get or set the dc:description which is an account of the resource.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-description

        :param description: Description or list of descriptions.
        :param replace: Replace already set descriptions (default: True).
        :returns: List of descriptions.
        '''
        if description is not None:
            if not isinstance(description, list):
                description = [description]
            if replace or not self._dcelem_description:
                self._dcelem_description = []
            self._dcelem_description += description
        return self._dcelem_description

    def dc_format(self, format=None, replace=True):
        '''Get or set the dc:format which describes the file format, physical
        medium, or dimensions of the resource.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-format

        :param format: Format of the resource or list of formats.
        :param replace: Replace already set format (default: True).
        :returns: Format of the resource.
        '''
        if format is not None:
            if not isinstance(format, list):
                format = [format]
            if replace or not self._dcelem_format:
                self._dcelem_format = []
            self._dcelem_format += format
        return self._dcelem_format

    def dc_identifier(self, identifier=None, replace=True):
        '''Get or set the dc:identifier which should be an unambiguous
        reference to the resource within a given context.

        For more inidentifierion see:
        http://dublincore.org/documents/dcmi-terms/#elements-identifier

        :param identifier: Identifier of the resource or list of identifiers.
        :param replace: Replace already set identifier (default: True).
        :returns: Identifiers of the resource.
        '''
        if identifier is not None:
            if not isinstance(identifier, list):
                identifier = [identifier]
            if replace or not self._dcelem_identifier:
                self._dcelem_identifier = []
            self._dcelem_identifier += identifier
        return self._dcelem_identifier

    def dc_language(self, language=None, replace=True):
        '''Get or set the dc:language which describes a language of the
        resource.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-language

        :param language: Language or list of languages.
        :param replace: Replace already set languages (default: True).
        :returns: List of languages.
        '''
        if language is not None:
            if not isinstance(language, list):
                language = [language]
            if replace or not self._dcelem_language:
                self._dcelem_language = []
            self._dcelem_language += language
        return self._dcelem_language

    def dc_publisher(self, publisher=None, replace=False):
        '''Get or set the dc:publisher which is an entity responsible for
        making the resource available.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-publisher

        :param publisher: Publisher or list of publishers.
        :param replace: Replace already set publishers (default: False).
        :returns: List of publishers.
        '''
        if publisher is not None:
            if not isinstance(publisher, list):
                publisher = [publisher]
            if replace or not self._dcelem_publisher:
                self._dcelem_publisher = []
            self._dcelem_publisher += publisher
        return self._dcelem_publisher

    def dc_relation(self, relation=None, replace=False):
        '''Get or set the dc:relation which describes a related resource.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-relation

        :param relation: Relation or list of relations.
        :param replace: Replace already set relations (default: False).
        :returns: List of relations.
        '''
        if relation is not None:
            if not isinstance(relation, list):
                relation = [relation]
            if replace or not self._dcelem_relation:
                self._dcelem_relation = []
            self._dcelem_relation += relation
        return self._dcelem_relation

    def dc_rights(self, rights=None, replace=False):
        '''Get or set the dc:rights which may contain information about rights
        held in and over the resource.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-rights

        :param rights: Rights information or list of rights information.
        :param replace: Replace already set rights (default: False).
        :returns: List of rights information.
        '''
        if rights is not None:
            if not isinstance(rights, list):
                rights = [rights]
            if replace or not self._dcelem_rights:
                self._dcelem_rights = []
            self._dcelem_rights += rights
        return self._dcelem_rights

    def dc_source(self, source=None, replace=False):
        '''Get or set the dc:source which is a related resource from which the
        described resource is derived.

        The described resource may be derived from the related resource in
        whole or in part. Recommended best practice is to identify the related
        resource by means of a string conforming to a formal identification
        system.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-source

        :param source: Source or list of sources.
        :param replace: Replace already set sources (default: False).
        :returns: List of sources.
        '''
        if source is not None:
            if not isinstance(source, list):
                source = [source]
            if replace or not self._dcelem_source:
                self._dcelem_source = []
            self._dcelem_source += source
        return self._dcelem_source

    def dc_subject(self, subject=None, replace=False):
        '''Get or set the dc:subject which describes the topic of the resource.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-subject

        :param subject: Subject or list of subjects.
        :param replace: Replace already set subjects (default: False).
        :returns: List of subjects.
        '''
        if subject is not None:
            if not isinstance(subject, list):
                subject = [subject]
            if replace or not self._dcelem_subject:
                self._dcelem_subject = []
            self._dcelem_subject += subject
        return self._dcelem_subject

    def dc_title(self, title=None, replace=True):
        '''Get or set the dc:title which is a name given to the resource.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-title

        :param title: Title or list of titles.
        :param replace: Replace already set titles (default: False).
        :returns: List of titles.
        '''
        if title is not None:
            if not isinstance(title, list):
                title = [title]
            if replace or not self._dcelem_title:
                self._dcelem_title = []
            self._dcelem_title += title
        return self._dcelem_title

    def dc_type(self, type=None, replace=False):
        '''Get or set the dc:type which describes the nature or genre of the
        resource.

        For more information see:
        http://dublincore.org/documents/dcmi-terms/#elements-type

        :param type: Type or list of types.
        :param replace: Replace already set types (default: False).
        :returns: List of types.
        '''
        if type is not None:
            if not isinstance(type, list):
                type = [type]
            if replace or not self._dcelem_type:
                self._dcelem_type = []
            self._dcelem_type += type
        return self._dcelem_type


class DcExtension(DcBaseExtension):
    '''Dublin Core Elements extension for podcasts.
    '''


class DcEntryExtension(DcBaseExtension):
    '''Dublin Core Elements extension for podcasts.
    '''
    def extend_atom(self, entry):
        '''Add dc elements to an atom item. Alters the item itself.

        :param entry: An atom entry element.
        :returns: The entry element.
        '''
        self._extend_xml(entry)
        return entry

    def extend_rss(self, item):
        '''Add dc elements to a RSS item. Alters the item itself.

        :param item: A RSS item element.
        :returns: The item element.
        '''
        self._extend_xml(item)
        return item