1 from JobManager
import Job
2 from error
import debug
3 from gobject
import GObject
, SIGNAL_RUN_FIRST
4 from model
import Feed
, Item
, Category
5 from storage
import DAO
, Storage
15 def import_opml(path
, category
):
17 fm
.import_opml(path
, category
)
21 fm
.init_storage(_storage_path
)
23 def setup(storage_path
= None):
25 _storage_path
= storage_path
27 def lookup_feed(id, ctg_id
):
29 return fm
.lookup_feed(id, ctg_id
)
31 def lookup_category(ctg_id
):
33 return fm
.lookup_category(ctg_id
)
35 def get_feed_items(id):
37 return fm
.get_feed_items(id)
39 def get_category_items(id):
41 return fm
.get_category_items(id)
47 def update_all_feeds(observers
, feeds
= None):
49 return fm
.update_all_feeds(observers
, feeds
)
51 def save_category(title
, pid
= None):
53 return fm
.save_category(title
, parent_id
= pid
)
57 result
= fm
.save_feed(feed
)
60 def save_all(save_list
):
62 fm
.save_all(save_list
)
68 def categories(root_id
= 1):
71 if not nodes
.has_key(root_id
):
76 for node
in nodes
[root_id
].children
:
78 for child
in categories(node
.id):
81 def move_node(node
, target_path
):
83 fm
.move_node(node
, target_path
)
85 class FeedManager(GObject
):
87 "item-added" : (gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_NONE
, (gobject
.TYPE_PYOBJECT
,)),
88 "feed-added" : (gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_NONE
, (gobject
.TYPE_PYOBJECT
,)),
89 "category-added" : (gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_NONE
, (gobject
.TYPE_PYOBJECT
,)),
93 GObject
.__init
__(self
)
97 def init_storage(self
, path
):
98 self
.storage
= Storage(path
)
99 self
.dao
= DAO(self
.storage
)
100 self
.nodes
= self
.dao
.get_nodes()
102 #self._process_model()
103 self
._prepare
_model
()
105 #print self.nodes[1].children
107 def import_opml(self
, path
, category
):
108 job
= Job("opml-parse")
109 job
.data
= (path
, category
)
110 job
.observers
= [ { "job-done": [ self
.import_opml_save
] } ]
112 JobManager
.start_job(job
)
114 def import_opml_save(self
, handler
, opml_data
):
115 save_list
, category
= opml_data
118 self
.save_all(save_list
)
121 def _model_add_node(self
, node
):
122 self
.nodes
[node
.parent_id
].add_child(node
)
124 def move_node(self
, node
, target_path
):
128 #print self.nodes[1].get_by_path(new_parent)
129 #print "move_node %d to %s [%s]" % (node.id, str(new_parent), new_parent[:-1])
130 new_parent
= self
.nodes
[1].get_by_path(target_path
[:-1])
133 new_parent
= self
.nodes
[1]
135 node
.move(new_parent
, target_path
[-1:][0])
137 def save_all(self
, save_list
):
138 for item
in save_list
:
139 item
.connect("parent-changed", self
.on_parent_changed
)
140 item
.connect("norder-changed", self
.on_norder_changed
)
142 if isinstance(item
, Feed
):
146 item
.parent_id
= item
.parent
.id
149 item
.parent
= self
.nodes
[1]
154 item
.parent_id
= item
.parent
.id
157 item
.parent
= self
.nodes
[1]
159 self
.save_category(item
)
161 def lookup_feed(self
, id):
162 return self
.nodes
[id]
164 def lookup_category(self
, id):
165 return self
.nodes
[id]
167 def save_feed(self
, feed
):
168 if not feed
.parent_id
:
171 category
= self
.lookup_category(feed
.parent_id
)
176 result
= self
.dao
.save(feed
)
178 self
.nodes
[feed
.id] = feed
179 self
._model
_add
_node
(feed
)
180 self
.emit("feed-added", feed
)
184 def update_all_feeds(self
, observers
, feeds
= None):
186 feeds
= [node
for node
in self
.nodes
.values() if node
.type == "F"]
188 FeedUpdater
.update_feeds(feeds
, [{
189 "job-done": [ self
.update_all_feeds_done
],
190 "task-start": [ self
._on
_update
_feed
_start
],
191 "task-done": [ self
._on
_update
_feed
_done
]
194 def update_all_feeds_done(self
, handler
, data
):
197 def _on_update_feed_start(self
, handler
, feed
):
198 feed
.props
.status
= straw
.FS_UPDATING
200 def _on_update_feed_done(self
, handler
, data
):
201 feed
= data
.task_info
.data
["feed"]
202 feed
.props
.status
= straw
.FS_IDLE
209 for item
in data
.result
.items
:
210 item
.feed_id
= feed
.id
212 if not self
.feed_item_exists(item
):
214 feed
.props
.unread_count
+= 1
215 self
.emit("item-added", item
)
221 def save_category(self
, category
):
222 self
.dao
.save(category
)
224 self
.nodes
[category
.id] = category
225 self
._model
_add
_node
(category
)
227 self
.emit("category-added", category
)
231 def get_feed_items(self
, id):
232 feed
= self
.lookup_feed(id)
233 feed
.items
= self
.dao
.get(Item
, " WHERE feed_id = %d" % feed
.id)
234 for item
in feed
.items
:
236 item
.connect("is-read-changed", feed
.on_is_read_changed
)
237 item
.connect("is-read-changed", self
.on_item_is_read_changed
)
240 def get_category_items(self
, id):
241 category
= self
.lookup_category(id)
246 def _get_children_feeds(category_id
):
247 feed_ids
= [str(node
.id) for node
in self
.lookup_category(category_id
).children
if node
.type == "F"]
248 children_categories
= [node
.id for node
in self
.lookup_category(category_id
).children
if node
.type == "C"]
250 for ctg_id
in children_categories
:
251 feed_ids
.extend(_get_children_feeds(ctg_id
))
255 in_str
= ", ".join(_get_children_feeds(id))
257 items
= self
.dao
.get(Item
, " WHERE feed_id IN(%s) ORDER BY id" % in_str
)
260 feed
= self
.lookup_feed(item
.feed_id
)
262 item
.connect("is-read-changed", feed
.on_is_read_changed
)
263 item
.connect("is-read-changed", self
.on_item_is_read_changed
)
267 def feed_item_exists(self
, item
):
268 result
= self
.dao
.get(Item
, " WHERE feed_id = ? AND title = ?", (item
.feed_id
, item
.title
,))
269 return len(result
) > 0
271 def _prepare_model(self
):
272 for node
in self
.nodes
.values():
273 node
.connect("parent-changed", self
.on_parent_changed
)
274 node
.connect("norder-changed", self
.on_norder_changed
)
276 if node
.parent_id
!= None:
277 node
.parent
= self
.nodes
[node
.parent_id
]
278 node
.parent
.append_child(node
)
282 def on_item_is_read_changed(self
, obj
, is_read
):
285 def on_parent_changed(self
, obj
, old_parent
):
286 debug("parent changed, saving %d" % (obj
.id))
289 def on_norder_changed(self
, obj
, old_norder
):
290 debug("norder changed, saving %d" % (obj
.id))
298 _instance
= FeedManager()