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