Attachment 'RSSReader.py'
Download 1 # -*- coding: iso-8859-1 -*-
2 u"""
3 MoinMoin - RSSREader macro Version 2.1 Alpha
4 Output an RSS/ATOM Feed
5
6 @copyright: 2006 by Ian Wienand <ianw@ieee.org>
7 2010 by Marcel Häfner http://moinmo.in/MarcelH%C3%A4fner
8 @license: Public Doman / from 2.1 GNU GPL
9
10 Version:
11 * 1.0 default Version from Ian Wienand
12 * 2.1 first version from marcel Häfner
13
14 Examples:
15 * <<RSSReader("http://www.example.dot/feed.rss">>
16 * <<RSSReader("http://www.example.dot/feed.rss", allowHtml=False,includeStyle=True)>>
17
18 Description:
19 <<RSSReader(url, allowHtml, includeStyle>>
20 * url is the url of the RSS/ATOM feed to read
21 * allowHtml is an optional argument if you trust the feed to put the HTML
22 directly into the page. CAUTION: this could be an attack vector,
23 although feedparser should strip most "bad" HTML.
24 * includeStyle per default True, so a nice css is added before the maco,
25 normaly you may say false and but this into your common.css
26 """
27
28 #do not chache the macro, so you receive updates without refreshing the page
29 Dependencies = ["time"]
30
31
32 class RSStoWiki:
33 def __init__(self, macro, url, allowHtml, includeStyle):
34
35 #initial stuff for the whole class
36 import feedparser
37 self.f = feedparser.parse(url)
38 self.macro = macro
39 self.fmt = macro.formatter
40 self.allowHtml = allowHtml
41 self.includeStyle = includeStyle
42 self.request = macro.request
43 self._ = self.request.getText
44 self.result = []
45
46 #check if feed exist or display an error message
47 if self.f.feed == {}:
48 self.result.append(self.fmt.div(True, css_class="error rssError") + \
49 self.fmt.icon('info') + \
50 self.fmt.text(" ") + \
51 self.fmt.strong(True) + \
52 self.fmt.text(self._('Unable to retreive feed')) + \
53 self.fmt.strong(False) + \
54 self.fmt.text(' "%s"' % url) + \
55 self.fmt.div(False))
56 self.valid = False
57 else:
58 self.valid = True
59
60 #generate content for the main (header) feed
61 def get_title(self):
62 if 'title' not in self.f.feed:
63 return
64 self.result.append(self.fmt.heading(True, depth=1, css_class="rssTitle") + \
65 self.fmt.text(self.f.feed.title) + \
66 self.fmt.heading(False, depth=1))
67
68 def get_subtitle(self):
69 if 'subtitle' not in self.f.feed:
70 return
71 self.result.append(self.fmt.paragraph(True, css_class="rssSubTitle") + \
72 self.fmt.text(self.f.feed.subtitle) + \
73 self.fmt.paragraph(False))
74
75 def get_description(self):
76 if 'description' not in self.f.feed:
77 return
78 #only desiplay description if its different compare to subtitel, mostly not
79 if ('subtitle' in self.f.feed) and ('description' in self.f.feed):
80 if self.f.feed.subtitle == self.f.feed.description:
81 return
82 self.result.append(self.fmt.paragraph(True, css_class="rssDescription") + \
83 self.fmt.text(self.f.feed.description) + \
84 self.fmt.paragraph(False))
85
86 def get_feedlink(self):
87 if 'link' not in self.f.feed:
88 return
89 self.get_link(self.f.feed.link)
90
91 #generate content for a single feed item (entries)
92 def get_entries(self):
93 for entry in self.f.entries:
94 self.result.append(self.fmt.div(True, css_class="rssEntry"))
95 if 'title' in entry:
96 if 'link' in entry:
97 self.get_entry_header(entry.title, entry.link)
98 else:
99 self.get_entry_header(entry.title)
100 if 'updated' in entry:
101 self.result.append(self.fmt.paragraph(True, css_class="rssEntryUpdated") + \
102 self.fmt.text(entry.updated) + \
103 self.fmt.paragraph(False))
104 if 'description' in entry:
105 self.get_entry_body(entry.description)
106 if ('link' in entry) and 'title' not in entry:
107 self.get_link(entry.link)
108 self.result.append(self.fmt.div(False))
109
110 #helper functions
111 def get_paragraph(self, text):
112 self.result.append(self.fmt.paragraph(True) + \
113 self.fmt.text(text) + \
114 self.fmt.paragraph(False))
115
116 def get_link(self, link):
117 self.result.append(self.fmt.url(True, href=link) + \
118 self.fmt.text(" ") + \
119 self.fmt.icon('www') + \
120 self.fmt.text(" " + link) + \
121 self.fmt.url(False))
122
123 #helper function for the entry / item
124 def get_entry_header(self, title, link=None):
125 if link: # if link exist, make the entry title with a link
126 self.result.append(self.fmt.paragraph(True, css_class="rssEntryTitle") + \
127 self.fmt.url(True, href=link) + \
128 self.fmt.text(title) + \
129 self.fmt.url(False) + \
130 self.fmt.paragraph(False))
131 else:
132 self.result.append(self.fmt.paragraph(True, css_class="rssEntryTitle") + \
133 self.fmt.text(title) + \
134 self.fmt.heading(False))
135
136 def get_entry_body(self, body):
137 self.result.append(self.fmt.paragraph(True, css_class="rssEntryBody"))
138 if (self.allowHtml): # check if html is allow, for raw html output
139 self.result.append(self.fmt.rawHTML(body))
140 else:
141 self.result.append(self.fmt.text(body))
142 self.result.append(self.fmt.paragraph(False))
143
144 def get_css(self):
145 self.result.append(self.fmt.rawHTML("""
146 <style type="text/css" media="all">
147
148 /* macro RSSReader start*/
149 div.rssReader .rssHeader {
150 margin-top: 1em;
151 margin-bottom: 1em;
152 border-bottom: 1px dotted gray;
153 }
154 div .rssReader .rssSubTitle, div .rssReader .rssDescription {
155 font-size: bold;
156 }
157 div.rssReader .rssEntries {
158 margin-top: 1em;
159 margin-bottom: 1em;
160 border-bottom: 1px dotted gray;
161 }
162 div.rssReader .rssEntry {
163 margin-top: 1em;
164 margin-bottom: 1em;
165 }
166 div.rssReader .rssEntryTitle {
167 font-size: 1.25em;
168 font-weight: bold;
169 margin: 0em;
170 }
171 div.rssReader .rssEntryUpdated {
172 color: gray;
173 font-size: 0.75em;
174 margin: 0em;
175 }
176 div.rssReader .rssEntryBody {
177 margin: 0em;
178 padding-top: 1em;
179 }
180 /* macro RSSReader end*/
181 </style>
182 """))
183
184 #output content
185 def get_output(self):
186 if self.valid:
187 #start
188 self.get_css()
189 self.result.append(self.fmt.div(True, css_class="rssReader"))
190 #header
191 self.result.append(self.fmt.div(True, css_class="rssHeader"))
192 self.get_title()
193 self.get_subtitle()
194 self.get_description()
195 self.result.append(self.fmt.linebreak(False))
196 self.get_feedlink()
197 self.result.append(self.fmt.div(False))
198 #entries
199 self.result.append(self.fmt.div(True, css_class="rssEntries"))
200 self.get_entries()
201 self.result.append(self.fmt.div(False))
202 #end
203 self.result.append(self.fmt.div(False))
204 return ''.join(self.result)
205
206
207 def macro_RSSReader(macro, feed, allowHtml=False, includeStyle=True):
208 rss = RSStoWiki(macro, feed, allowHtml, includeStyle)
209 return rss.get_output()
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.