Mercurial > pidgin
comparison finch/libgnt/pygnt/example/rss/gntrss.py @ 18681:ef15236a0866
A proof-of-conecpt RSS reader using pygnt.
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Sat, 28 Jul 2007 11:30:54 +0000 |
parents | |
children | 254823d66aa5 |
comparison
equal
deleted
inserted
replaced
18680:fd01bac27b79 | 18681:ef15236a0866 |
---|---|
1 #!/usr/bin/env python | |
2 | |
3 # A very simple and stupid RSS reader | |
4 # | |
5 # Uses the Universal Feed Parser | |
6 # | |
7 | |
8 import threading | |
9 import feedparser | |
10 import gobject | |
11 import sys | |
12 import time | |
13 | |
14 ## | |
15 # The FeedItem class. It will update emit 'delete' signal when it's | |
16 # destroyed. | |
17 ## | |
18 class FeedItem(gobject.GObject): | |
19 __gproperties__ = { | |
20 'unread' : (gobject.TYPE_BOOLEAN, 'read', | |
21 'The unread state of the item.', | |
22 False, gobject.PARAM_READWRITE) | |
23 } | |
24 __gsignals__ = { | |
25 'delete' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,)) | |
26 } | |
27 def __init__(self, item, parent): | |
28 self.__gobject_init__() | |
29 self.date = item['date'] | |
30 self.date_parsed = item['date_parsed'] | |
31 self.title = item['title'] | |
32 self.summary = item['summary'] | |
33 self.link = item['link'] | |
34 self.parent = parent | |
35 self.unread = True | |
36 | |
37 def remove(self): | |
38 self.emit('delete', self.parent) | |
39 | |
40 def do_set_property(self, property, value): | |
41 if property.name == 'unread': | |
42 self.unread = value | |
43 | |
44 gobject.type_register(FeedItem) | |
45 | |
46 def item_hash(item): | |
47 return str(item['date'] + item['title']) | |
48 | |
49 ## | |
50 # The Feed class. It will update the 'link', 'title', 'desc' and 'items' | |
51 # attributes if/when they are updated (triggering 'notify::<attr>' signal) | |
52 ## | |
53 class Feed(gobject.GObject): | |
54 __gproperties__ = { | |
55 'link' : (gobject.TYPE_STRING, 'link', | |
56 'The web page this feed is associated with.', | |
57 '...', gobject.PARAM_READWRITE), | |
58 'title' : (gobject.TYPE_STRING, 'title', | |
59 'The title of the feed.', | |
60 '...', gobject.PARAM_READWRITE), | |
61 'desc' : (gobject.TYPE_STRING, 'description', | |
62 'The description for the feed.', | |
63 '...', gobject.PARAM_READWRITE), | |
64 'items' : (gobject.TYPE_POINTER, 'items', | |
65 'The items in the feed.', gobject.PARAM_READWRITE), | |
66 'unread' : (gobject.TYPE_INT, 'unread', | |
67 'Number of unread items in the feed.', 0, 10000, 0, gobject.PARAM_READWRITE) | |
68 } | |
69 __gsignals__ = { | |
70 'added' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,)) | |
71 } | |
72 | |
73 def __init__(self, url): | |
74 self.__gobject_init__() | |
75 self.url = url # The url of the feed itself | |
76 self.link = url # The web page associated with the feed | |
77 self.desc = url | |
78 self.title = url | |
79 self.unread = 0 | |
80 self.timer = 0 | |
81 self.items = [] | |
82 self.hash = {} | |
83 | |
84 def do_set_property(self, property, value): | |
85 if property.name == 'link': | |
86 self.link = value | |
87 elif property.name == 'desc': | |
88 self.desc = value | |
89 elif property.name == 'title': | |
90 self.title = value | |
91 elif property.name == 'unread': | |
92 self.unread = value | |
93 pass | |
94 | |
95 def check_thread_for_death(self): | |
96 #if self.thread.running: | |
97 # sys.stderr.write(time.ctime() + "continue") | |
98 # return True | |
99 # The thread has ended!! | |
100 #result = self.thread.result | |
101 #self.thread = None | |
102 result = feedparser.parse(self.url) | |
103 channel = result['channel'] | |
104 self.set_property('link', channel['link']) | |
105 self.set_property('desc', channel['description']) | |
106 self.set_property('title', channel['title']) | |
107 self.set_property('unread', len(result['items'])) | |
108 self.timer = 0 | |
109 items = result['items'] | |
110 tmp = {} | |
111 for item in self.items: | |
112 tmp[hash(item)] = item | |
113 | |
114 for item in items: | |
115 try: | |
116 exist = self.hash[item_hash(item)] | |
117 del tmp[hash(exist)] | |
118 except: | |
119 itm = FeedItem(item, self) | |
120 self.items.append(itm) | |
121 self.emit('added', itm) | |
122 self.hash[item_hash(item)] = itm | |
123 for hv in tmp: | |
124 tmp[hv].remove() | |
125 | |
126 return False | |
127 | |
128 def refresh(self): | |
129 #if self.thread == 0: | |
130 # self.thread = FeedReader(self) | |
131 # self.thread.start() | |
132 if self.timer == 0: | |
133 self.timer = gobject.timeout_add(1000, self.check_thread_for_death) | |
134 | |
135 gobject.type_register(Feed) | |
136 | |
137 ## | |
138 # A FeedReader class, which is threaded to make sure it doesn't freeze the ui | |
139 # (this thing doesn't quite work ... yet) | |
140 ## | |
141 class FeedReader(threading.Thread): | |
142 def __init__(self, feed): | |
143 self.feed = feed | |
144 self.running = True | |
145 threading.Thread.__init__(self) | |
146 | |
147 def run(self): | |
148 sys.stderr.write(str(time.ctime()) + " STARTED!!!\n\n\n") | |
149 self.running = True | |
150 self.result = feedparser.parse(self.feed.url) | |
151 self.running = False | |
152 sys.stderr.write(str(time.ctime()) + " DONE!!!\n\n\n") | |
153 | |
154 feeds = [] | |
155 urls = ("http://rss.slashdot.org/Slashdot/slashdot", | |
156 "http://www.python.org/channews.rdf", | |
157 "http://pidgin.im/rss.php", | |
158 "./rss.php" | |
159 ) | |
160 | |
161 for url in urls: | |
162 feed = Feed(url) | |
163 feeds.append(feed) | |
164 |