Make treeview refresh properly when adding nodes.
[straw/fork.git] / straw / FeedManager.py
blobbc77ef5f6b2375fe2cce69f2595b3e9d93fd2bd2
1 from gobject import GObject, SIGNAL_RUN_FIRST
2 from straw.JobManager import Job, TaskThread, TaskInfo, ThreadPoolJobHandler
3 from straw.model import Feed, Item, Category
4 from straw.storage import FeedDAO, DAO, Storage
5 import gobject
6 import straw.FeedUpdater as FeedUpdater
7 import straw.JobManager as JobManager
8 import straw.opml
10 _storage_path = None
12 model_data = None
14 def import_opml(path):
15 fm = _get_instance()
16 fm.import_opml(path)
18 def init():
19 fm = _get_instance()
20 fm.init_storage(_storage_path)
22 def setup(storage_path = None):
23 global _storage_path
24 _storage_path = storage_path
26 def lookup_feed(id, ctg_id):
27 fm = _get_instance()
28 return fm.lookup_feed(id, ctg_id)
30 def lookup_category(ctg_id):
31 fm = _get_instance()
32 return fm.lookup_category(ctg_id)
34 def get_feed_items(id):
35 fm = _get_instance()
36 return fm.get_feed_items(id)
38 def get_feeds():
39 fm = _get_instance()
40 return fm.get_feeds()
42 def update_all_feeds(observers):
43 fm = _get_instance()
44 return fm.update_all_feeds(observers)
46 def save_category(title, pid = None):
47 fm = _get_instance()
48 return fm.save_category(title, parent_id = pid)
50 def save_feed(feed):
51 fm = _get_instance()
52 result = fm.save_feed(feed)
53 return result
55 def get_model():
56 fm = _get_instance()
57 return fm.categories, fm.feeds
59 class FeedManager(GObject):
60 __gsignals__ = {
61 "item-added" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
62 "feed-added" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
63 "category-added" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
66 def __init__(self):
67 GObject.__init__(self)
69 self.storage = None
70 self.categories = []
71 self.feeds = {}
73 def init_storage(self, path):
74 self.storage = Storage(path)
75 self.dao = DAO(self.storage)
76 self.feed_dao = FeedDAO(self.storage)
78 self.categories = self.get_categories()
79 self.feeds = self.get_feeds_grouped()
81 self._populate_tree(1, None, [])
83 def import_opml(self, path):
84 job = Job("opml-parse")
85 job.data = path
86 job.observers = { "job-done": [ self.import_opml_save ] }
87 JobManager.start_job(job)
89 def import_opml_save(self, handler, opml_data):
90 categories = opml_data
91 #print opml_data
92 self._save_tree(opml_data)
93 #for item in opml_data:
94 # if isinstance(item, Feed):
95 # self.save_feed(item)
96 # else:
97 # self.save_category(item)
99 def _save_tree(self, level, parent_id = 1):
100 for item in level:
101 if isinstance(item, Feed):
102 category_id = 1
103 if item.category:
104 category_id = item.category.id
105 item.category_id = category_id
106 self.save_feed(item)
107 else:
108 parent_id = 1
109 if item.parent:
110 parent_id = item.parent.id
111 item.parent_id = parent_id
112 self.save_category(item)
114 def lookup_feed_by_id(self, id):
115 feed = [f for ctg_id in self.feeds.keys() for f in self.feeds[ctg_id] if f.id == id]
116 return feed[0]
118 def lookup_feed(self, id, ctg_id):
119 feed = [f for f in self.feeds[ctg_id] if f.id == id]
120 return feed[0]
122 def lookup_category(self, ctg_id):
123 return self.categories[ctg_id]
125 def get_feed(self, id):
126 return self.dao.get_one(Feed, id)
128 def get_feeds(self):
129 feeds = self.dao.get(Feed)
130 #print "after dao"
132 i = 0
133 for feed in feeds:
134 feed.items = self.dao.get(Item, " WHERE feed_id = %s" % feed.id)
135 i += len(feed.items)
137 #print i
138 return feeds
140 def save_feed(self, feed):
141 if not feed.category_id:
142 feed.category_id = 1
144 category = self.dao.get_one(Category, feed.category_id)
146 if not category:
147 return None
149 result = self.dao.save(feed)
151 if not self.feeds.has_key(feed.category_id):
152 self.feeds[feed.category_id] = []
154 feed.connect("unread-count-changed", self.categories[category.id].on_unread_count_changed)
156 self.feeds[feed.category_id].append(feed)
157 self.emit("feed-added", feed)
159 return result
161 def update_all_feeds(self, observers):
162 print "getting feeds..."
163 feeds = [feed for key in self.feeds.keys() for feed in self.feeds[key]]#self.get_feeds()
164 print "got %d feed(s)!" % len(feeds)
166 FeedUpdater.update_feeds(feeds, {
167 "job-done": [ self.update_all_feeds_done ],
168 "task-done": [ self.update_all_feed_done ]
171 def update_all_feeds_done(self, handler, data):
172 for result in data:
173 for feed_item in result.result.items:
174 item = Item()
175 item.title = feed_item.title
176 item.feed_id = result.task_info.data["feed"].id
177 #self.dao.save(item)
179 def update_all_feed_done(self, handler, data):
180 feed = data.task_info.data["feed"]
182 for item in data.result.items:
183 #item = Item()
184 #item.title = feed_item.title
185 item.feed_id = feed.id
187 self.dao.save(item)
188 #self._lookup_feed(feed_id,).unread_count += 1
189 feed.props.unread_count += 1
191 self.emit("item-added", item)
193 ### CATEGORIES
195 def save_category(self, category):
196 self.dao.save(category)
197 category.connect("unread-count-changed",
198 self.categories[category.parent_id].on_unread_count_changed)
199 self.categories[category.id] = category
200 self.emit("category-added", category)
202 def get_categories(self):
203 return self.dao.get_indexed(Category, "id")
205 def get_feeds_grouped(self):
206 return self.feed_dao.get_feeds_grouped()
208 # ITEMS
210 def get_feed_items(self, id):
211 #feed = self.dao.get_one(Feed, id)
212 feed = self.lookup_feed_by_id(id)
213 feed.items = self.dao.get(Item, " WHERE feed_id = %s" % feed.id)
214 for item in feed.items:
215 item.feed = feed
216 item.connect("is-read-changed", feed.on_is_read_changed)
217 item.connect("is-read-changed", self.on_item_is_read_changed)
218 return feed
220 def on_item_is_read_changed(self, obj, is_read):
221 self.dao.save(obj)
223 def _populate_tree(self, parent_id, parent_iter, done):
224 #if not self.categories.has_key(parent_id):
225 # return
227 for category_id in self.categories.keys():
228 category = self.categories[category_id]
230 if category.parent_id != None:
231 category.connect("unread-count-changed",
232 self.categories[category.parent_id].on_unread_count_changed)
233 #self.categories[category.parent_id].connect(category.connect
235 if self.feeds.has_key(category_id):
236 for feed in self.feeds[category_id]:
237 feed.connect("unread-count-changed", category.on_unread_count_changed)
238 #if node.type == "F":
239 # node.obj = self._get_feed(node, parent_id)
240 # node.treeiter = self._create_row(node, parent_iter)
241 # node.store = self.store
242 # self.categories[node.obj.category_id].props.unread_count += node.obj.unread_count
243 #print self.categories[node.obj.category_id].unread_count
244 #print node.obj.unread_count
245 #elif node.type == "C":
246 #node.obj = self.categories[node.obj_id]
247 #current_parent = self._create_row(node, parent_iter)
248 #node.treeiter = current_parent
249 #node.store = self.store
251 #if self.nodes.has_key(node.obj_id):
252 # self._populate_tree(node.obj_id, current_parent, done)
254 #self.categories[node.obj.parent_id].props.unread_count += node.obj.unread_count
256 _instance = None
258 def _get_instance():
259 global _instance
260 if not _instance:
261 _instance = FeedManager()
262 return _instance