1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """
24 Atom (rfc 4287) feed parser, used to read data from atom-over-pubsub transports
25 and services. Very simple. Actually implements only atom:entry. Implement more features
26 if you need
27 """
28
29
30
31
32 import xmpp
33 import time
34
36 """
37 Not used for now, as we don't need authors/contributors in pubsub.com feeds.
38 They rarely exist there
39 """
40
42 ''' Create person construct from node. '''
43 xmpp.Node.__init__(self, node=node)
44
47
48 name = property(get_name, None, None,
49 '''Conveys a human-readable name for the person. Should not be None,
50 although some badly generated atom feeds don't put anything here
51 (this is non-standard behavior, still pubsub.com sometimes does that.)''')
52
55
56 uri = property(get_uri, None, None,
57 '''Conveys an IRI associated with the person. Might be None when not set.''')
58
61
62 email = property(get_email, None, None,
63 '''Conveys an e-mail address associated with the person. Might be None when
64 not set.''')
65
66 -class Entry(xmpp.Node, object):
67 - def __init__(self, node=None):
68 xmpp.Node.__init__(self, 'entry', node=node)
69
71 return '<Atom:Entry object of id="%r">' % self.getAttr('id')
72
73 -class OldEntry(xmpp.Node, object):
74 """
75 Parser for feeds from pubsub.com. They use old Atom 0.3 format with their
76 extensions
77 """
78
79 - def __init__(self, node=None):
80 ''' Create new Atom 0.3 entry object. '''
81 xmpp.Node.__init__(self, 'entry', node=node)
82
84 return '<Atom0.3:Entry object of id="%r">' % self.getAttr('id')
85
86 - def get_feed_title(self):
87 """
88 Return title of feed, where the entry was created. The result is the feed
89 name concatenated with source-feed title
90 """
91 if self.parent is not None:
92 main_feed = self.parent.getTagData('title')
93 else:
94 main_feed = None
95
96 if self.getTag('feed') is not None:
97 source_feed = self.getTag('feed').getTagData('title')
98 else:
99 source_feed = None
100
101
102 if main_feed is not None and source_feed is not None:
103 return u'%s: %s' % (main_feed, source_feed)
104 elif main_feed is not None:
105 return main_feed
106 elif source_feed is not None:
107 return source_feed
108 else:
109 return u''
110
111 feed_title = property(get_feed_title, None, None,
112 ''' Title of feed. It is built from entry''s original feed title and title of feed
113 which delivered this entry. ''')
114
115 - def get_feed_link(self):
116 """
117 Get source link
118 """
119 try:
120 return self.getTag('feed').getTags('link', {'rel':'alternate'})[1].getData()
121 except Exception:
122 return None
123
124 feed_link = property(get_feed_link, None, None,
125 ''' Link to main webpage of the feed. ''')
126
127 - def get_title(self):
128 """
129 Get an entry's title
130 """
131 return self.getTagData('title')
132
133 title = property(get_title, None, None,
134 ''' Entry's title. ''')
135
137 """
138 Get the uri the entry points to (entry's first link element with
139 rel='alternate' or without rel attribute)
140 """
141 for element in self.getTags('link'):
142 if 'rel' in element.attrs and element.attrs['rel']!='alternate': continue
143 try:
144 return element.attrs['href']
145 except AttributeError:
146 pass
147 return None
148
149 uri = property(get_uri, None, None,
150 ''' URI that is pointed by the entry. ''')
151
152 - def get_updated(self):
153 """
154 Get the time the entry was updated last time
155
156 This should be standarized, but pubsub.com sends it in human-readable
157 format. We won't try to parse it. (Atom 0.3 uses the word «modified» for
158 that).
159
160 If there's no time given in the entry, we try with <published>
161 and <issued> elements.
162 """
163 for name in ('updated', 'modified', 'published', 'issued'):
164 date = self.getTagData(name)
165 if date is not None: break
166
167 if date is None:
168
169 return time.asctime()
170
171 return date
172
173 updated = property(get_updated, None, None,
174 ''' Last significant modification time. ''')
175
176 feed_tagline = u''
177