3
3
feedgen.entry
4
4
~~~~~~~~~~~~~
5
5
6
- :copyright: 2013, Lars Kiesow <[email protected] >
6
+ :copyright: 2013-2020 , Lars Kiesow <[email protected] >
7
7
8
8
:license: FreeBSD and LGPL, see license.* for more details.
9
9
'''
13
13
import dateutil .parser
14
14
import dateutil .tz
15
15
import warnings
16
- from lxml import etree
16
+
17
+ from lxml .etree import CDATA # nosec - adding CDATA entry is safe
17
18
18
19
from feedgen .compat import string_types
19
- from feedgen .util import ensure_format , formatRFC2822
20
+ from feedgen .util import ensure_format , formatRFC2822 , xml_fromstring , xml_elem
20
21
21
22
22
23
def _add_text_elm (entry , data , name ):
23
24
"""Add a text subelement to an entry"""
24
25
if not data :
25
26
return
26
27
27
- elm = etree . SubElement ( entry , name )
28
+ elm = xml_elem ( name , entry )
28
29
type_ = data .get ('type' )
29
30
if data .get ('src' ):
30
31
if name != 'content' :
@@ -34,16 +35,14 @@ def _add_text_elm(entry, data, name):
34
35
elif data .get (name ):
35
36
# Surround xhtml with a div tag, parse it and embed it
36
37
if type_ == 'xhtml' :
37
- elm . append ( etree . fromstring (
38
- '<div xmlns="http://www.w3.org/1999/xhtml">' +
39
- data . get ( name ) + '</div>' ))
38
+ xhtml = '<div xmlns="http://www.w3.org/1999/xhtml">' \
39
+ + data . get ( name ) + '</div>'
40
+ elm . append ( xml_fromstring ( xhtml ))
40
41
elif type_ == 'CDATA' :
41
- elm .text = etree .CDATA (
42
- data .get (name ))
42
+ elm .text = CDATA (data .get (name ))
43
43
# Parse XML and embed it
44
44
elif type_ and (type_ .endswith ('/xml' ) or type_ .endswith ('+xml' )):
45
- elm .append (etree .fromstring (
46
- data [name ]))
45
+ elm .append (xml_fromstring (data [name ]))
47
46
# Embed the text in escaped form
48
47
elif not type_ or type_ .startswith ('text' ) or type_ == 'html' :
49
48
elm .text = data .get (name )
@@ -102,14 +101,14 @@ def __init__(self):
102
101
103
102
def atom_entry (self , extensions = True ):
104
103
'''Create an ATOM entry and return it.'''
105
- entry = etree . Element ('entry' )
104
+ entry = xml_elem ('entry' )
106
105
if not (self .__atom_id and self .__atom_title and self .__atom_updated ):
107
106
raise ValueError ('Required fields not set' )
108
- id = etree . SubElement ( entry , 'id' )
107
+ id = xml_elem ( 'id' , entry )
109
108
id .text = self .__atom_id
110
- title = etree . SubElement ( entry , 'title' )
109
+ title = xml_elem ( 'title' , entry )
111
110
title .text = self .__atom_title
112
- updated = etree . SubElement ( entry , 'updated' )
111
+ updated = xml_elem ( 'updated' , entry )
113
112
updated .text = self .__atom_updated .isoformat ()
114
113
115
114
# An entry must contain an alternate link if there is no content
@@ -125,20 +124,20 @@ def atom_entry(self, extensions=True):
125
124
# Atom requires a name. Skip elements without.
126
125
if not a .get ('name' ):
127
126
continue
128
- author = etree . SubElement ( entry , 'author' )
129
- name = etree . SubElement ( author , 'name' )
127
+ author = xml_elem ( 'author' , entry )
128
+ name = xml_elem ( 'name' , author )
130
129
name .text = a .get ('name' )
131
130
if a .get ('email' ):
132
- email = etree . SubElement ( author , 'email' )
131
+ email = xml_elem ( 'email' , author )
133
132
email .text = a .get ('email' )
134
133
if a .get ('uri' ):
135
- uri = etree . SubElement ( author , 'uri' )
134
+ uri = xml_elem ( 'uri' , author )
136
135
uri .text = a .get ('uri' )
137
136
138
137
_add_text_elm (entry , self .__atom_content , 'content' )
139
138
140
139
for l in self .__atom_link or []:
141
- link = etree . SubElement ( entry , 'link' , href = l ['href' ])
140
+ link = xml_elem ( 'link' , entry , href = l ['href' ])
142
141
if l .get ('rel' ):
143
142
link .attrib ['rel' ] = l ['rel' ]
144
143
if l .get ('type' ):
@@ -153,7 +152,7 @@ def atom_entry(self, extensions=True):
153
152
_add_text_elm (entry , self .__atom_summary , 'summary' )
154
153
155
154
for c in self .__atom_category or []:
156
- cat = etree . SubElement ( entry , 'category' , term = c ['term' ])
155
+ cat = xml_elem ( 'category' , entry , term = c ['term' ])
157
156
if c .get ('scheme' ):
158
157
cat .attrib ['scheme' ] = c ['scheme' ]
159
158
if c .get ('label' ):
@@ -164,32 +163,31 @@ def atom_entry(self, extensions=True):
164
163
# Atom requires a name. Skip elements without.
165
164
if not c .get ('name' ):
166
165
continue
167
- contrib = etree . SubElement ( entry , 'contributor' )
168
- name = etree . SubElement ( contrib , 'name' )
166
+ contrib = xml_elem ( 'contributor' , entry )
167
+ name = xml_elem ( 'name' , contrib )
169
168
name .text = c .get ('name' )
170
169
if c .get ('email' ):
171
- email = etree . SubElement ( contrib , 'email' )
170
+ email = xml_elem ( 'email' , contrib )
172
171
email .text = c .get ('email' )
173
172
if c .get ('uri' ):
174
- uri = etree . SubElement ( contrib , 'uri' )
173
+ uri = xml_elem ( 'uri' , contrib )
175
174
uri .text = c .get ('uri' )
176
175
177
176
if self .__atom_published :
178
- published = etree . SubElement ( entry , 'published' )
177
+ published = xml_elem ( 'published' , entry )
179
178
published .text = self .__atom_published .isoformat ()
180
179
181
180
if self .__atom_rights :
182
- rights = etree . SubElement ( entry , 'rights' )
181
+ rights = xml_elem ( 'rights' , entry )
183
182
rights .text = self .__atom_rights
184
183
185
184
if self .__atom_source :
186
- source = etree . SubElement ( entry , 'source' )
185
+ source = xml_elem ( 'source' , entry )
187
186
if self .__atom_source .get ('title' ):
188
- source_title = etree . SubElement ( source , 'title' )
187
+ source_title = xml_elem ( 'title' , source )
189
188
source_title .text = self .__atom_source ['title' ]
190
189
if self .__atom_source .get ('link' ):
191
- etree .SubElement (source , 'link' ,
192
- href = self .__atom_source ['link' ])
190
+ xml_elem ('link' , source , href = self .__atom_source ['link' ])
193
191
194
192
if extensions :
195
193
for ext in self .__extensions .values () or []:
@@ -200,60 +198,59 @@ def atom_entry(self, extensions=True):
200
198
201
199
def rss_entry (self , extensions = True ):
202
200
'''Create a RSS item and return it.'''
203
- entry = etree . Element ('item' )
201
+ entry = xml_elem ('item' )
204
202
if not (self .__rss_title or
205
203
self .__rss_description or
206
204
self .__rss_content ):
207
205
raise ValueError ('Required fields not set' )
208
206
if self .__rss_title :
209
- title = etree . SubElement ( entry , 'title' )
207
+ title = xml_elem ( 'title' , entry )
210
208
title .text = self .__rss_title
211
209
if self .__rss_link :
212
- link = etree . SubElement ( entry , 'link' )
210
+ link = xml_elem ( 'link' , entry )
213
211
link .text = self .__rss_link
214
212
if self .__rss_description and self .__rss_content :
215
- description = etree . SubElement ( entry , 'description' )
213
+ description = xml_elem ( 'description' , entry )
216
214
description .text = self .__rss_description
217
215
XMLNS_CONTENT = 'http://purl.org/rss/1.0/modules/content/'
218
- content = etree . SubElement ( entry , '{%s}encoded' % XMLNS_CONTENT )
219
- content .text = etree . CDATA (self .__rss_content ['content' ]) \
216
+ content = xml_elem ( '{%s}encoded' % XMLNS_CONTENT , entry )
217
+ content .text = CDATA (self .__rss_content ['content' ]) \
220
218
if self .__rss_content .get ('type' , '' ) == 'CDATA' \
221
219
else self .__rss_content ['content' ]
222
220
elif self .__rss_description :
223
- description = etree . SubElement ( entry , 'description' )
221
+ description = xml_elem ( 'description' , entry )
224
222
description .text = self .__rss_description
225
223
elif self .__rss_content :
226
- description = etree . SubElement ( entry , 'description' )
227
- description .text = etree . CDATA (self .__rss_content ['content' ]) \
224
+ description = xml_elem ( 'description' , entry )
225
+ description .text = CDATA (self .__rss_content ['content' ]) \
228
226
if self .__rss_content .get ('type' , '' ) == 'CDATA' \
229
227
else self .__rss_content ['content' ]
230
228
for a in self .__rss_author or []:
231
- author = etree . SubElement ( entry , 'author' )
229
+ author = xml_elem ( 'author' , entry )
232
230
author .text = a
233
231
if self .__rss_guid .get ('guid' ):
234
- guid = etree . SubElement ( entry , 'guid' )
232
+ guid = xml_elem ( 'guid' , entry )
235
233
guid .text = self .__rss_guid ['guid' ]
236
234
permaLink = str (self .__rss_guid .get ('permalink' , False )).lower ()
237
235
guid .attrib ['isPermaLink' ] = permaLink
238
236
for cat in self .__rss_category or []:
239
- category = etree . SubElement ( entry , 'category' )
237
+ category = xml_elem ( 'category' , entry )
240
238
category .text = cat ['value' ]
241
239
if cat .get ('domain' ):
242
240
category .attrib ['domain' ] = cat ['domain' ]
243
241
if self .__rss_comments :
244
- comments = etree . SubElement ( entry , 'comments' )
242
+ comments = xml_elem ( 'comments' , entry )
245
243
comments .text = self .__rss_comments
246
244
if self .__rss_enclosure :
247
- enclosure = etree . SubElement ( entry , 'enclosure' )
245
+ enclosure = xml_elem ( 'enclosure' , entry )
248
246
enclosure .attrib ['url' ] = self .__rss_enclosure ['url' ]
249
247
enclosure .attrib ['length' ] = self .__rss_enclosure ['length' ]
250
248
enclosure .attrib ['type' ] = self .__rss_enclosure ['type' ]
251
249
if self .__rss_pubDate :
252
- pubDate = etree . SubElement ( entry , 'pubDate' )
250
+ pubDate = xml_elem ( 'pubDate' , entry )
253
251
pubDate .text = formatRFC2822 (self .__rss_pubDate )
254
252
if self .__rss_source :
255
- source = etree .SubElement (entry , 'source' ,
256
- url = self .__rss_source ['url' ])
253
+ source = xml_elem ('source' , entry , url = self .__rss_source ['url' ])
257
254
source .text = self .__rss_source ['title' ]
258
255
259
256
if extensions :
0 commit comments