2 |
|
|
3 |
import cPickle, os, traceback |
import cPickle, os, traceback |
4 |
from urlparse import urlparse |
from urlparse import urlparse |
5 |
from error import log, logtb |
from error import log, logtb, logparam |
6 |
|
|
7 |
import straw |
import straw |
8 |
import gconf |
import gconf |
10 |
|
|
11 |
GCONF_STRAW_ROOT = "/apps/straw" |
GCONF_STRAW_ROOT = "/apps/straw" |
12 |
GCONF_STRAW_POLL_FREQ = GCONF_STRAW_ROOT + "/general/poll_frequency" |
GCONF_STRAW_POLL_FREQ = GCONF_STRAW_ROOT + "/general/poll_frequency" |
13 |
GCONF_STRAW_ITEMS_STORED = GCONF_STRAW_ROOT + "/general/number_of_items_stored" |
|
14 |
GCONF_STRAW_ITEM_ORDER = GCONF_STRAW_ROOT + "/general/item_order_newest" |
OPTION_LAST_POLL = "/general/last_poll" |
15 |
GCONF_STRAW_OFFLINE = GCONF_STRAW_ROOT + "/general/offline" |
OPTION_ITEMS_STORED = "/general/number_of_items_stored" |
16 |
GCONF_STRAW_LAST_POLL = GCONF_STRAW_ROOT + "/general/last_poll" |
OPTION_ITEM_ORDER = "/general/item_order_newest" |
17 |
GCONF_STRAW_WINDOW_H = GCONF_STRAW_ROOT + "/ui/window_height" |
OPTION_WINDOW_SIZE_W = "/ui/window_width" |
18 |
GCONF_STRAW_WINDOW_W = GCONF_STRAW_ROOT + "/ui/window_width" |
OPTION_WINDOW_SIZE_H = "/ui/window_height" |
19 |
GCONF_STRAW_MAIN_PANE_POSITION = GCONF_STRAW_ROOT + "/ui/main_pane_position" |
OPTION_MAIN_PANE_POS = "/ui/main_pane_position" |
20 |
GCONF_STRAW_SUB_PANE_POSITION = GCONF_STRAW_ROOT + "/ui/sub_pane_position" |
OPTION_SUB_PANE_POS = "/ui/sub_pane_position" |
21 |
|
OPTION_OFFLINE = "/general/offline" |
22 |
|
OPTION_POLL_FREQUENCY = "/general/poll_frequency" |
23 |
|
OPTION_FEED_ID_SEQ = "feed_id_seq" |
24 |
|
OPTION_FEEDS = "feeds" |
25 |
|
|
26 |
def ensure_directory(strawdir): |
def ensure_directory(strawdir): |
27 |
if os.path.exists(strawdir): |
if os.path.exists(strawdir): |
31 |
os.mkdir(strawdir) |
os.mkdir(strawdir) |
32 |
return 1 |
return 1 |
33 |
|
|
34 |
def config_to_gconf(cf): |
############# |
35 |
straw.config.poll_frequency = cf.get('poll_frequency') |
# Config persistence classes |
36 |
straw.config.number_of_items_stored = cf.get('number_of_items_stored') |
class ConfigPicklePersistence: |
37 |
straw.config.item_order = cf.get('item_order') |
def __init__(self, filename): |
38 |
straw.config.main_window_size = cf.get('main_window_size') |
self._config_file = filename |
39 |
straw.config.main_pane_position = cf.get('main_pane_position') |
self._dict = None |
40 |
straw.config.sub_pane_position = cf.get('sub_pane_position') |
|
41 |
straw.config.offline = cf.get('offline') |
def save_option(self, option, value): |
42 |
|
if self._dict is None: |
43 |
del cf['poll_frequency'] |
self._initialize_dict() |
44 |
del cf['number_of_items_stored'] |
pickle_file = open(self._config_file, "w") |
45 |
del cf['item_order'] |
self._dict[option] = value |
46 |
del cf['main_window_size'] |
cPickle.dump(self._dict, pickle_file, True) |
47 |
del cf['main_pane_position'] |
pickle_file.close() |
|
del cf['sub_pane_position'] |
|
|
del cf['offline'] |
|
|
|
|
|
|
|
|
class ConfigSaver: |
|
|
def __init__(self): |
|
|
self._config_file = os.path.join(straw.config._straw_dir, "config") |
|
|
# change to FeedsChangedSignal |
|
|
self.load_config() |
|
|
straw.config.signal_connect(straw.LocalConfigOptionSignal,self.notify_change) |
|
|
|
|
|
def notify_change(self, signal): |
|
|
self.save_config() |
|
|
return |
|
|
|
|
|
def load_config(self): |
|
|
if os.path.exists(self._config_file): |
|
|
fl = straw.FeedList() |
|
|
f = open(self._config_file) |
|
|
cf = cPickle.load(f) |
|
|
straw.config.feed_id_seq = cf.get('feed_id_seq',0) |
|
|
for feed in cf['feeds']: |
|
|
nf = straw.create_empty_feed() |
|
|
nf.undump(feed) |
|
|
fl.append(nf) |
|
|
straw.config.feeds = fl |
|
|
# migrate old config to gconf |
|
|
if cf.has_key('poll_frequency'): |
|
|
config_to_gconf(cf) |
|
|
|
|
|
f.close() |
|
48 |
return |
return |
49 |
|
|
50 |
def save_config(self): |
def load_option(self, option): |
51 |
cf = {} |
if self._dict is None: |
52 |
l = [] |
self._initialize_dict() |
53 |
for f in straw.config.feeds: |
return self._dict.get(option, None) |
54 |
l.append(f.dump()) |
|
55 |
cf['feeds'] = l |
def _initialize_dict(self): |
56 |
cf['feed_id_seq'] = straw.config.feed_id_seq |
pickle_file = open(self._config_file, "r") |
57 |
pickle_file = open(self._config_file, 'w') |
self._dict = cPickle.load(pickle_file) |
|
cPickle.dump(cf, pickle_file, 1) |
|
58 |
pickle_file.close() |
pickle_file.close() |
|
return |
|
59 |
|
|
60 |
|
class ConfigGConfPersistence: |
61 |
|
SAVERS = {OPTION_LAST_POLL: 'int', |
62 |
|
OPTION_ITEMS_STORED: 'int', |
63 |
|
OPTION_ITEM_ORDER: 'bool', |
64 |
|
OPTION_WINDOW_SIZE_W: 'int', |
65 |
|
OPTION_WINDOW_SIZE_H: 'int', |
66 |
|
OPTION_MAIN_PANE_POS: 'int', |
67 |
|
OPTION_SUB_PANE_POS: 'int', |
68 |
|
OPTION_OFFLINE: 'bool', |
69 |
|
OPTION_POLL_FREQUENCY: 'int'} |
70 |
|
|
71 |
|
def __init__(self, client): |
72 |
|
self.client = client |
73 |
|
|
74 |
|
def save_option(self, option, value): |
75 |
|
getattr(self.client, 'set_' + self.SAVERS[option])( |
76 |
|
GCONF_STRAW_ROOT + option, value) |
77 |
|
|
78 |
|
def load_option(self, option): |
79 |
|
return getattr(self.client, 'get_' + self.SAVERS[option])( |
80 |
|
GCONF_STRAW_ROOT + option) |
81 |
|
|
82 |
|
class ConfigPersistence: |
83 |
|
def __init__(self, *backends): |
84 |
|
self.backends = backends |
85 |
|
|
86 |
|
def save_option(self, option, value): |
87 |
|
for b in self.backends: |
88 |
|
if option in b[1]: |
89 |
|
b[0].save_option(option, value) |
90 |
|
|
91 |
|
def load_option(self, option): |
92 |
|
for b in self.backends: |
93 |
|
if option in b[1]: |
94 |
|
return b[0].load_option(option) |
95 |
|
|
96 |
|
################ |
97 |
|
# Proxy config |
98 |
class BaseProxyConfig(object): |
class BaseProxyConfig(object): |
99 |
def get_config_working(self): |
def get_config_working(self): |
100 |
return self._config_working |
return self._config_working |
253 |
self.password = None |
self.password = None |
254 |
self.use_authentication = None |
self.use_authentication = None |
255 |
|
|
256 |
|
################### |
257 |
|
# The main man |
258 |
class Config(object, straw.SignalEmitter): |
class Config(object, straw.SignalEmitter): |
259 |
def __init__(self): |
_straw_dir = os.path.join(os.getenv("HOME"), ".straw") |
260 |
self.client = gconf.client_get_default() |
|
261 |
self.client.add_dir(GCONF_STRAW_ROOT, gconf.CLIENT_PRELOAD_ONELEVEL) |
def __init__(self, persistence): |
262 |
|
self.persistence = persistence |
263 |
|
|
264 |
straw.SignalEmitter.__init__(self) |
straw.SignalEmitter.__init__(self) |
265 |
self.initialize_slots(straw.FeedsChangedSignal, |
self.initialize_slots(straw.FeedsChangedSignal, |
266 |
straw.ItemOrderChangedSignal, |
straw.ItemOrderChangedSignal, |
267 |
straw.OfflineModeChangedSignal, |
straw.OfflineModeChangedSignal, |
268 |
straw.LastPollChangedSignal) |
straw.LastPollChangedSignal) |
|
self._feed_id_seq = 0 |
|
|
self._straw_dir = os.path.join(os.getenv("HOME"), ".straw") |
|
|
self._feeds = straw.FeedList() |
|
|
self._feeds.signal_connect(straw.FeedsChangedSignal, |
|
|
self.feeds_changed) |
|
269 |
pcchoices = (GconfProxyConfig, EnvironmentProxyConfig, NullProxyConfig) |
pcchoices = (GconfProxyConfig, EnvironmentProxyConfig, NullProxyConfig) |
270 |
for p in pcchoices: |
for p in pcchoices: |
271 |
self._proxy_config = p() |
self._proxy_config = p() |
272 |
if self._proxy_config.config_working: |
if self._proxy_config.config_working: |
273 |
break |
break |
274 |
self.first_time = ensure_directory(self._straw_dir) |
self.first_time = ensure_directory(self._straw_dir) |
275 |
|
self._last_poll = self.persistence.load_option(OPTION_LAST_POLL) |
|
self._last_poll = self.client.get_int(GCONF_STRAW_LAST_POLL) |
|
276 |
|
|
277 |
if self._last_poll is None or self._last_poll == 0: |
if self._last_poll is None or self._last_poll == 0: |
278 |
self._load_defaults() |
self._load_defaults() |
279 |
return |
return |
280 |
|
|
281 |
self._items_stored = self.client.get_int(GCONF_STRAW_ITEMS_STORED) |
self._items_stored = self.persistence.load_option(OPTION_ITEMS_STORED) |
282 |
self._item_order = self.client.get_bool(GCONF_STRAW_ITEM_ORDER) |
self._item_order = self.persistence.load_option(OPTION_ITEM_ORDER) |
283 |
self._main_window_size = (self.client.get_int(GCONF_STRAW_WINDOW_W), self.client.get_int(GCONF_STRAW_WINDOW_H)) |
self._main_window_size = ( |
284 |
self._main_pane_position = self.client.get_int(GCONF_STRAW_MAIN_PANE_POSITION) |
self.persistence.load_option(OPTION_WINDOW_SIZE_W), |
285 |
self._sub_pane_position = self.client.get_int(GCONF_STRAW_SUB_PANE_POSITION) |
self.persistence.load_option(OPTION_WINDOW_SIZE_H)) |
286 |
self._offline = self.client.get_bool(GCONF_STRAW_OFFLINE) |
self._main_pane_position = self.persistence.load_option( |
287 |
self._poll_freq = self.client.get_int(GCONF_STRAW_POLL_FREQ) |
OPTION_MAIN_PANE_POS) |
288 |
|
self._sub_pane_position = self.persistence.load_option( |
289 |
|
OPTION_SUB_PANE_POS) |
290 |
|
self._offline = self.persistence.load_option(OPTION_OFFLINE) |
291 |
|
self._poll_freq = self.persistence.load_option(OPTION_POLL_FREQUENCY) |
292 |
|
|
293 |
def _load_defaults(self): |
def _load_defaults(self): |
294 |
self._poll_freq = 3600 |
self._poll_freq = 3600 |
300 |
self._offline = bool(1) |
self._offline = bool(1) |
301 |
self._last_poll = 0 |
self._last_poll = 0 |
302 |
|
|
303 |
|
def _restore_feeds(self): |
304 |
|
self._feed_id_seq = self.persistence.load_option(OPTION_FEED_ID_SEQ) |
305 |
|
feeddicts = self.persistence.load_option(OPTION_FEEDS) |
306 |
|
feeds = [] |
307 |
|
for fd in feeddicts: |
308 |
|
f = straw.create_empty_feed() |
309 |
|
f.undump(fd) |
310 |
|
feeds.append(f) |
311 |
|
self._feeds = straw.FeedList(feeds) |
312 |
|
self._feeds.signal_connect(straw.FeedsChangedSignal, |
313 |
|
self.feeds_changed) |
314 |
|
self.emit_signal(straw.FeedsChangedSignal(self)) |
315 |
|
|
316 |
|
def get_straw_dir(self): |
317 |
|
return self._straw_dir |
318 |
|
|
319 |
|
straw_dir = property(get_straw_dir, None, None, "") |
320 |
|
|
321 |
def get_proxy_config(self): |
def get_proxy_config(self): |
322 |
return self._proxy_config |
return self._proxy_config |
323 |
|
|
325 |
|
|
326 |
# and the rest of the stuff |
# and the rest of the stuff |
327 |
def feeds_changed(self, signal): |
def feeds_changed(self, signal): |
328 |
|
self.persistence.save_option( |
329 |
|
OPTION_FEEDS, [f.dump() for f in self.feeds]) |
330 |
self.emit_signal(straw.FeedsChangedSignal(self)) |
self.emit_signal(straw.FeedsChangedSignal(self)) |
331 |
|
|
332 |
def set_feeds(self, feeds): |
def set_feeds(self, feeds): |
333 |
self._feeds = straw.FeedList(feeds) |
self._feeds = straw.FeedList(feeds) |
334 |
self._feeds.signal_connect(straw.FeedsChangedSignal, |
self._feeds.signal_connect(straw.FeedsChangedSignal, |
335 |
self.feeds_changed) |
self.feeds_changed) |
336 |
|
self.persistence.save_option( |
337 |
|
OPTION_FEEDS, [f.dump() for f in self.feeds]) |
338 |
self.emit_signal(straw.FeedsChangedSignal(self)) |
self.emit_signal(straw.FeedsChangedSignal(self)) |
339 |
return |
return |
340 |
|
|
346 |
def set_poll_frequency(self, poll_frequency=60): |
def set_poll_frequency(self, poll_frequency=60): |
347 |
if self._poll_freq != poll_frequency: |
if self._poll_freq != poll_frequency: |
348 |
self._poll_freq = poll_frequency |
self._poll_freq = poll_frequency |
349 |
self.client.set_int(GCONF_STRAW_POLL_FREQ, poll_frequency) |
self.persistence.save_option(OPTION_POLL_FREQUENCY, poll_frequency) |
350 |
return |
return |
351 |
|
|
352 |
def get_poll_frequency(self): |
def get_poll_frequency(self): |
358 |
def set_last_poll(self, last_poll): |
def set_last_poll(self, last_poll): |
359 |
if self._last_poll != last_poll: |
if self._last_poll != last_poll: |
360 |
self._last_poll = last_poll |
self._last_poll = last_poll |
361 |
self.client.set_int(GCONF_STRAW_LAST_POLL, last_poll) |
self.persistence.save_option(OPTION_LAST_POLL, last_poll) |
362 |
self.emit_signal(straw.LastPollChangedSignal(self)) |
self.emit_signal(straw.LastPollChangedSignal(self)) |
363 |
return |
return |
364 |
|
|
373 |
def set_number_of_items_stored(self, num=30): |
def set_number_of_items_stored(self, num=30): |
374 |
if self._items_stored != num: |
if self._items_stored != num: |
375 |
self._items_stored = num |
self._items_stored = num |
376 |
self.client.set_int(GCONF_STRAW_ITEMS_STORED, num) |
self.persistence.save_option(OPTION_ITEMS_STORED, num) |
377 |
self.emit_signal(straw.NumberOfItemsStoredChangedSignal(self)) |
self.emit_signal(straw.NumberOfItemsStoredChangedSignal(self)) |
378 |
return |
return |
379 |
|
|
384 |
def set_item_order(self, order): |
def set_item_order(self, order): |
385 |
if self._item_order != order: |
if self._item_order != order: |
386 |
self._item_order = order |
self._item_order = order |
387 |
self.client.set_bool(GCONF_STRAW_ITEM_ORDER, order) |
self.persistence.save_option(OPTION_ITEM_ORDER, order) |
388 |
self.emit_signal(straw.ItemOrderChangedSignal(self)) |
self.emit_signal(straw.ItemOrderChangedSignal(self)) |
389 |
return |
return |
390 |
|
|
398 |
|
|
399 |
def set_feed_id_seq(self, id): |
def set_feed_id_seq(self, id): |
400 |
self._feed_id_seq = id |
self._feed_id_seq = id |
401 |
|
self.persistence.save_option(OPTION_FEED_ID_SEQ, id) |
402 |
return |
return |
403 |
|
|
404 |
def next_feed_id_seq(self): |
def next_feed_id_seq(self): |
405 |
self._feed_id_seq += 1 |
self.feed_id_seq += 1 |
406 |
return self._feed_id_seq |
return self._feed_id_seq |
407 |
|
|
408 |
feed_id_seq = property(get_feed_id_seq, set_feed_id_seq, None, "") |
feed_id_seq = property(get_feed_id_seq, set_feed_id_seq, None, "") |
410 |
def set_main_window_size(self, size): |
def set_main_window_size(self, size): |
411 |
if self._main_window_size != size: |
if self._main_window_size != size: |
412 |
self._main_window_size = size |
self._main_window_size = size |
413 |
self.client.set_int(GCONF_STRAW_WINDOW_W,size[0]) |
self.persistence.save_option(OPTION_WINDOW_SIZE_W, size[0]) |
414 |
self.client.set_int(GCONF_STRAW_WINDOW_H,size[1]) |
self.persistence.save_option(OPTION_WINDOW_SIZE_H, size[1]) |
415 |
self.emit_signal(straw.MainWindowSizeChangedSignal(self)) |
self.emit_signal(straw.MainWindowSizeChangedSignal(self)) |
416 |
return |
return |
417 |
|
|
423 |
def set_offline(self, mode): |
def set_offline(self, mode): |
424 |
if self._offline != mode: |
if self._offline != mode: |
425 |
self._offline = mode |
self._offline = mode |
426 |
self.client.set_bool(GCONF_STRAW_OFFLINE, mode) |
self.persistence.save_option(OPTION_OFFLINE, mode) |
427 |
self.emit_signal(straw.OfflineModeChangedSignal(self)) |
self.emit_signal(straw.OfflineModeChangedSignal(self)) |
428 |
return |
return |
429 |
|
|
435 |
def set_main_pane_position(self, position): |
def set_main_pane_position(self, position): |
436 |
if self._main_pane_position != position: |
if self._main_pane_position != position: |
437 |
self._main_pane_position = position |
self._main_pane_position = position |
438 |
self.client.set_int(GCONF_STRAW_MAIN_PANE_POSITION, position) |
self.persistence.save_option(OPTION_MAIN_PANE_POS, position) |
439 |
self.emit_signal(straw.MainPanePositionChangedSignal(self)) |
self.emit_signal(straw.MainPanePositionChangedSignal(self)) |
440 |
|
|
441 |
def get_main_pane_position(self): |
def get_main_pane_position(self): |
446 |
def set_sub_pane_position(self, position): |
def set_sub_pane_position(self, position): |
447 |
if self._sub_pane_position != position: |
if self._sub_pane_position != position: |
448 |
self._sub_pane_position = position |
self._sub_pane_position = position |
449 |
self.client.set_int(GCONF_STRAW_SUB_PANE_POSITION, position) |
self.peristence.save_option(OPTION_SUB_PANE_POS, position) |
450 |
self.emit_signal(straw.SubPanePositionChangedSignal(self)) |
self.emit_signal(straw.SubPanePositionChangedSignal(self)) |
451 |
|
|
452 |
def get_sub_pane_position(self): |
def get_sub_pane_position(self): |
454 |
|
|
455 |
sub_pane_position = property(get_sub_pane_position, set_sub_pane_position, None, "") |
sub_pane_position = property(get_sub_pane_position, set_sub_pane_position, None, "") |
456 |
|
|
457 |
|
config_instance = None |
458 |
|
|
459 |
|
def convert_if_necessary(config): |
460 |
|
f = open(os.path.join(config.straw_dir, "config"), "rw") |
461 |
|
cf = cPickle.load(f) |
462 |
|
if cf.has_key('poll_frequency'): |
463 |
|
config.poll_frequency = cf.get('poll_frequency') |
464 |
|
config.number_of_items_stored = cf.get('number_of_items_stored') |
465 |
|
config.item_order = cf.get('item_order') |
466 |
|
config.main_window_size = cf.get('main_window_size') |
467 |
|
config.main_pane_position = cf.get('main_pane_position') |
468 |
|
config.sub_pane_position = cf.get('sub_pane_position') |
469 |
|
config.offline = cf.get('offline') |
470 |
|
|
471 |
|
del cf['poll_frequency'] |
472 |
|
del cf['number_of_items_stored'] |
473 |
|
del cf['item_order'] |
474 |
|
del cf['main_window_size'] |
475 |
|
del cf['main_pane_position'] |
476 |
|
del cf['sub_pane_position'] |
477 |
|
del cf['offline'] |
478 |
|
|
479 |
|
f.seek(0) |
480 |
|
f.truncate() |
481 |
|
cPickle.dump(cf, f, True) |
482 |
|
f.close() |
483 |
|
return |
484 |
|
|
485 |
|
def create_gconf_persistence(): |
486 |
|
client = gconf.client_get_default() |
487 |
|
client.add_dir(GCONF_STRAW_ROOT, gconf.CLIENT_PRELOAD_ONELEVEL) |
488 |
|
return ConfigGConfPersistence(client) |
489 |
|
|
490 |
|
def create_pickle_persistence(): |
491 |
|
return ConfigPicklePersistence(os.path.join(Config._straw_dir, "config")) |
492 |
|
|
493 |
|
def create_instance(): |
494 |
|
gp = create_gconf_persistence() |
495 |
|
pp = create_pickle_persistence() |
496 |
|
cp = ConfigPersistence( |
497 |
|
(create_gconf_persistence(), |
498 |
|
(OPTION_LAST_POLL, OPTION_ITEMS_STORED, OPTION_ITEM_ORDER, |
499 |
|
OPTION_WINDOW_SIZE_W, OPTION_WINDOW_SIZE_H, |
500 |
|
OPTION_MAIN_PANE_POS, OPTION_SUB_PANE_POS, OPTION_OFFLINE, |
501 |
|
OPTION_POLL_FREQUENCY)), |
502 |
|
(create_pickle_persistence(), |
503 |
|
(OPTION_FEED_ID_SEQ, OPTION_FEEDS))) |
504 |
|
config = Config(cp) |
505 |
|
convert_if_necessary(config) |
506 |
|
return config |
507 |
|
|
508 |
|
def get_instance(): |
509 |
|
global config_instance |
510 |
|
if config_instance is None: |
511 |
|
config_instance = create_instance() |
512 |
|
config_instance._restore_feeds() |
513 |
|
return config_instance |