24
24
# The Watcher : this file should give a class intended for subclassing. It should give all the basic methods.
25
25
import os, sys, time
32
from spectlib.iniparser import ini_namespace
31
import spectlib.config
32
from spectlib.tools.iniparser import ini_namespace
33
33
from ConfigParser import ConfigParser
34
34
from spectlib import i18n
35
35
from spectlib.i18n import _
36
from spectlib.balloons import NotificationToast
38
37
from time import sleep
39
38
from datetime import datetime
39
import base64 #encode/decode passwords
42
from spectlib.tools.keyringmanager import Keyring
41
47
def gettext_noop(s):
45
def __init__(self, specto, id, name, interval, type):
47
self.interval = interval
51
def __init__(self, specto, id, values, watch_values):
53
watch_values.extend([('name', spectlib.config.String(True)),
54
('refresh', spectlib.config.Integer(True)),
55
('type', spectlib.config.String(True)),
56
('updated', spectlib.config.Boolean(False)),
57
('command', spectlib.config.String(False)),
58
('active', spectlib.config.Boolean(False)),
59
('last_updated', spectlib.config.String(False)),
60
('open_command', spectlib.config.String(False))
54
self.active = True #active/not active
55
self.last_updated = "No updates yet"
64
self.use_network = False
56
66
self.actually_updated = False
57
gnome.sound_init('localhost')
58
self.use_network = False
70
self.watch_values = watch_values
71
self.set_values(values)
73
self.watch_io = Watch_io(self.specto.FILE)
62
78
""" Start the watch. """
64
if self.use_network == True:
65
self.check_connection()
81
self.watch_io.write_option(self.name, 'active', self.active)
67
82
self.start_update()
85
self.specto.logger.log(_("There was an error starting the watch"), "error", self.name)
70
88
""" Stop the watch. """
72
gobject.source_remove(self.timer_id)
91
self.watch_io.write_option(self.name, 'active', self.active)
92
gobject.source_remove(self.timer_id)
95
self.specto.logger.log(_("There was an error stopping the watch"), "error", self.name)
75
98
""" clear the watch """
101
self.watch_io.write_option(self.name, 'updated', self.updated)
103
self.specto.mark_watch_status("idle-clear", self.id)
106
self.specto.logger.log(_("There was an error clearing the watch"), "error", self.name)
78
108
def restart(self):
79
109
""" restart the watch """
84
114
def start_update(self):
85
self.specto.mark_watch_status("updating", self.id)
89
self.lock = thread.allocate_lock()
91
thread.start_new_thread(self.update,())
92
while self.lock.locked():
93
while gtk.events_pending():
96
while gtk.events_pending():
116
if self.updated == True:
117
self.specto.mark_watch_status("mark-updated", self.id)
119
if not self.check_connection():
121
self.specto.logger.log("Started update.", "debug", self.name)
122
self.specto.mark_watch_status("updating", self.id)
124
self.actually_updated = False
127
self.lock = thread.allocate_lock()
129
thread.start_new_thread(self.update,())
130
while self.lock.locked():
131
while gtk.events_pending():
136
self.specto.logger.log(_("There was an error starting to update the watch"), "error", self.name)
140
def watch_updated(self):
142
self.specto.logger.log("Watch is updated!", "info", self.name)
143
self.actually_updated = False
145
self.last_updated = datetime.today().strftime("%A %d %b %Y %H:%M")
146
self.watch_io.write_option(self.name, 'updated', self.updated)
147
self.watch_io.write_option(self.name, 'last_updated', self.last_updated)
148
self.specto.mark_watch_status("updated", self.id)
149
if self.command != "": #run watch specific updated commando
150
os.system(self.command + " &")
153
self.specto.logger.log(_("There was an error marking the watch as updated"), "error", self.name)
99
156
def timer_update(self):
100
157
""" update the timer """
101
if self.actually_updated == True:
102
self.actually_updated = False
104
self.last_updated = datetime.today().strftime("%A %d %b %Y %H:%M")
105
self.specto.mark_watch_status("updated", self.id)
107
self.specto.mark_watch_status("idle", self.id)
110
self.timer_id = gobject.timeout_add(self.interval, self.thread_update)
159
if self.actually_updated == True:
161
elif self.error == True:
162
self.specto.mark_watch_status("error", self.id)
163
elif self.active == False:
166
self.specto.mark_watch_status("idle", self.id)
169
self.timer_id = gobject.timeout_add(self.refresh, self.start_update)
171
self.timer_id = gobject.timeout_add(self.refresh, self.update)
112
self.timer_id = gobject.timeout_add(self.interval, self.update)
174
self.specto.logger.log(_("There was an error updating the watch"), "error", self.name)
114
176
def check_connection(self):
115
if not self.specto.connection_manager.connected():
116
self.specto.logger.log(_("No network connection detected"),
117
"info", self.__class__)
177
if not self.specto.connection_manager.connected():
178
self.specto.logger.log(_("No network connection detected"), "warning", self.name)
118
179
self.specto.connection_manager.add_callback(self.start_update)
119
self.specto.mark_watch_status("idle", self.id)
180
self.specto.mark_watch_status("no-network", self.id)
123
def set_name(self, name):
124
""" Set the name. """
128
""" Return the name. """
131
def set_interval(self, interval):
132
self.interval = interval
134
def get_interval(self):
137
def set_error(self, error):
183
self.specto.mark_watch_status("network", self.id)
185
self.specto.specto_gconf.set_directory("/system/http_proxy")
186
http_proxy = "http://%s:%s" % (self.specto.specto_gconf.get_entry("host"),
187
self.specto.specto_gconf.get_entry("port"))
188
https_proxy = "https://%s:%s" % (self.specto.specto_gconf.get_entry("secure_host"),
189
self.specto.specto_gconf.get_entry("secure_port"))
190
proxies = {"http": http_proxy, "https": https_proxy}
191
self.specto.specto_gconf.set_directory("")
194
def get_values(self):
197
def set_values(self, values, validate=False):
199
for key, type in self.watch_values:
203
if type.mandatory == False:
204
values[key] = type.getStandardValue()
207
setattr(self, key, value)
209
error_fields += ", " + key
211
value = type.checkRestrictions(values[key])
213
if type.mandatory == True and value[1] == type.getStandardValue():
214
error_fields += ", " + key
216
values[key] = value[1]
218
setattr(self, key, value[1])
220
error_fields += ", " + key
222
if values['open_command'] == "":
224
self.open_command = self.standard_open_command
226
self.open_command = ""
228
if self.last_updated == "":
229
self.last_updated = "No updates yet"
231
if len(error_fields) <> 0:
232
error_fields = error_fields.lstrip(",")
233
raise AttributeError, error_fields
238
def get_balloon_text(self):
239
return "No message specified yet!"
241
def get_extra_information(self):
242
return "No extra information available."
244
def remove_cache_files(self):
143
247
class Watch_collection:
248
def __init__(self, specto):
145
249
self.watch_db = []
147
251
self.plugin_dict = {}
252
self.disabl_plugin_dict = {}
148
254
self.load_plugins()
150
256
def load_plugins(self):
151
dir = "spectlib/plugins/"
257
dir = self.specto.SRC_PATH + "/plugins/"
152
258
for f in os.listdir(dir):
259
if f[-3:] == ".py" and f != "__init__.py":
260
if not os.path.exists('data'):
261
dir = "spectlib.plugins."
263
dir = "spectlib/plugins/"
154
264
_file = dir + f[:-3]
155
mod = __import__(_file)
265
mod = __import__(_file, globals(), locals(), [''])
156
266
obj = sys.modules[_file]
157
self.plugin_dict[obj.type] = mod
268
self.plugin_dict[obj.type] = mod
159
def add(self,specto, values):
160
""" read the content from the dictionary and create the watch """
271
def create(self, values):
272
""" read the content from the dictionary and create the watch """
275
if values[i]['type'] == "0":
276
values[i]['type'] = "Web_watch"
277
if values[i]['type'] == "1":
278
if values[i]['prot'] == "2":
279
values[i]['type'] = "Mail_watch_gmail"
162
281
type = values[i]['type']
164
283
#get the right object and create the watch object
165
obj = getattr(self.plugin_dict[type], type)
166
watch_ = obj(specto, self.id, values[i])
286
mod = self.plugin_dict[type]
288
print "Please enable plugin \""+ type + "\", if you want to use the watch: "+ values[i]["name"] + "."
168
self.watch_db.append(watch_)
291
obj = getattr(mod, type)
293
watch_ = obj(self.specto, self.id, values[i])
294
except AttributeError, error_fields:
298
raise AttributeError, error_fields
300
self.watch_db.append(watch_)
171
306
def remove(self, id):
172
307
""" remove the watch from the collection """
173
308
self.watch_db[id].stop()
174
self.watch_db[id].updated = False
175
del self.watch_db[id]
309
self.watch_db[id].updated = False
310
self.watch_db[id].deleted = True
312
self.watch_db[id].remove_cache_files()
315
self.specto.logger.remove_watch_log(self.watch_db[id].name)
177
317
def get(self, id):
178
318
""" get a watch object """
179
319
return self.watch_db[id]
223
363
Returns the key of a watch or None if it doesn't exists.
226
for key in self.watch_db.iterkeys():
227
if self.watch_db[key].name == name:
366
for watch in self.watch_db:
367
if watch.name == name:
232
def check_unique_watch(self, name):
233
""" Check if the watch name is unique. """
234
if self.watch_io.search_watch(name) and GTK:
372
def set_interval(self, refresh, refresh_unit):
374
Set the interval between the update checks.
376
refresh_unit = days, hours, minutes,... in values of 0, 1, 2, 3.
379
if refresh_unit == 0:#seconds
380
new_refresh = refresh * 1000
381
elif refresh_unit == 1:#minutes
382
new_refresh = refresh * 60 * 1000
383
elif refresh_unit == 2:#hours
384
new_refresh = (refresh * 60) * 60 * 1000
385
elif refresh_unit == 3:#days
386
new_refresh = ((refresh * 60) * 60) * 24 *1000
390
def get_interval(self, value):
391
""" Get the interval between 2 updates. """
392
if ((value / 60) / 60) / 24 / 1000 > 0:
393
refresh_value = ((value / 60) / 60) / 24 / 1000
395
elif (value / 60) / 60 / 1000 > 0:
396
refresh_value = (value / 60) / 60 / 1000
398
elif value / 60 / 1000 > 0:
399
refresh_value = value / 60 / 1000
402
refresh_value = value / 1000
405
return refresh_value, type
239
408
def __getitem__(self, i):
240
409
return self.watch_db[i]
312
489
If the name is not found, a new watch will be added, else the excisting watch will be changed.
315
self.cfg = ini_namespace(file(self.file_name))
321
name = values['name']
323
if not self.cfg._sections.has_key(name):
324
self.cfg.new_namespace(name) #add a new watch
327
for option, value in values.iteritems():
328
self.cfg[name][option] = value
330
self.specto.logger.log(_("There was an reading the watches from %s") % self.file_name, "critical", self.__class__)
333
f = open(self.file_name, "w")
334
f.write(str(self.cfg).strip()) #write the new configuration file
336
self.specto.logger.log(_("There was an error writing to %s") % self.file_name, "critical", self.__class__)
492
cfg = ini_namespace(file(self.file_name))
497
name = self.hide_brackets(values['name'])
498
if not cfg._sections.has_key(name):
499
cfg.new_namespace(name) #add a new watch
501
f = open(self.file_name, "w")
502
f.write(str(cfg).strip()) #write the new configuration file
504
self.specto.logger.log(_("There was an error writing to %s") % self.file_name, "critical", self.__class__)
509
for option, value in values.iteritems():
510
self.write_option(name, option, value)
513
# self.specto.logger.log(_("There was an reading the watches from %s") % self.file_name, "critical", self.__class__)
515
def write_option(self, name, option, value):
517
cfg = ini_namespace(file(self.file_name))
522
name = self.hide_brackets(name)
523
if not cfg._sections.has_key(name):
526
if option == "password": # and self.check_old_version(self.cfg[name]['type']): #don't use encoding for old watches.list
527
value = self.encode_password(name, value)
528
cfg[name][option] = value
530
f = open(self.file_name, "w")
531
f.write(str(cfg).strip()) #write the new configuration file
533
self.specto.logger.log(_("There was an error writing to %s") % self.file_name, "critical", self.__class__)
341
539
def remove_watch(self, name):
386
586
self.specto.logger.log(_("There was an error writing to %s") % self.file_name, "critical", self.__class__)
590
def hide_brackets(self,name):
591
name = name.replace("[", "&brStart;")
592
name = name.replace("]", "&brEnd;")
595
def show_brackets(self,name):
596
name = name.replace("&brStart;", "[")
597
name = name.replace("&brEnd;", "]")
600
def encode_password(self, name, password):
602
k = Keyring(name, "Specto " + name, "network")
603
k.set_credentials((name, password))
604
password = "**keyring**"
606
password = base64.b64encode(password)
609
def decode_password(self, name, password):
612
k = Keyring(name, "Specto " + name, "network")
613
password = k.get_credentials()[1]
616
password = base64.b64decode(password)
617
except TypeError:#password was not yet encoded
621
password = base64.b64decode(password)
622
except TypeError:#password was not yet encoded
626
def check_old_version(self, type):
629
int(type) #type is int: old version
632
old = False #type is not int: new version