~woutc/specto/specto-dbus-client

« back to all changes in this revision

Viewing changes to spectlib/watch.py

  • Committer: Jean-François Fortin Tam
  • Author(s): Wout Clymans
  • Date: 2008-07-22 23:22:49 UTC
  • Revision ID: jeff@kiki-20080722232249-l64srclhp6u6qyrw
WARNING: this commit contains all the significant changes that happened in a specto-woutc branch over the past year. Large change log follows. Some commit log lines were intentionally left out.

- A dialog with debug information is shown when specto has a system/programming error.
- Disable renaming watches in the listview, make it a Jump To action instead
- All mandatory fields have to be filled in now (add and edit watch)
- The error log now shows the lines in color according to the severity
- Better file size cache name
- Added more error-handling
- The filesize is now saved in a different cache file (not in watches.list), may fix issue 37?
- Icons are now shown in the combobox when you add a new watch (buggy, patches welcome)
- Improved the pop3, imap and gmail watches
- The gmail watch now saves what unread mails there already were last time
- Convert HTML entities for the web diff
- Moved some code so the file dialog will show faster
- A watch will be marked updated when you didn't clear it on quit.
- Removed double call to refresh the watch info
- Made a general gtkutil file where you can define widgets used in the edit and add watch windows
- Removed the class name from the logger
- Clear the watch when you open it using the balloon
- Make some watch names clearer
- Error log tab in notifier window
- Added "clear" button in the edit menu
- Show simple diff from webpage difference
- Console mode (specto --console or specto --console --help)
- Watch menu when you right-click a watch entry in the notifier window
- Ability to run a command when a watch is updated
- Ability to run a command when a watch is cleared
- Fields in the add and edit windows are now dynamic; when creating a new watch plugin, you don't have to write all the gui code anymore
- More space for the extra information in the info panel
- code cleanup
- use plugin-system

- Fix issue 150: Gmail.com - that address is disabled in Germany - hence you can't go to messages directly
- Fix issue 93: Gmail library can support no more than 19 new mails
- Fix issue 131: bombs on special characters
- Fix issue 134: harmonized colors
- Fix issue 119: don't let the log file get huge
- Fix issue 143: Site adress in "About" box is not clickable
- Fix issue 146: Per-watch option to prevent URL redirects; To use this option add "redirect = True" to the watch that is allowed to redirect
- Fix issue 145: abnormal behavior with ampersands in a web watch
- Fix issue 51: Specto stores passwords in plaintext (started keyring support)
- Fix issue 135: Proxy support (already proxy support for web watch)
- Fix issue 128: allow specifying a port for mail watches (add 'port = 323' to your watch config)
- Fix issue 132: removing a watch should remove its cache files
- Fix issue 136: Support specific folder monitor over IMAP (add 'folder = work' to your imap watch config)
- Fix issue 63: Google Reader Watch does not support more than 20 items
- Fix issue 39: POP3 & IMAP watches not on par with gmail watch's message counting logic
- Fix issue 100: gmail with google apps should point to the right domain when clicking Jump to
- Fix issue 95: statusbar should show something else when updates are done
- Fix issue 112: hide error log tabs when debug mode is deactivated
- Fix issue 101: show the import dialog after the file chooser
- Fix issue 114: removing a watch should show a confirmation dialog
- Fix issue 73: brackets in watch name lead to startup crash (brackets can now be used in the name!)
- Fix issue 69: startup fails due to wrong glade file path  
- Fix issue 12: provide more information
- Fix issue 13: watch list importing and exporting
- Fix issue 20: Organise specto source into modules
- Fix issue 33: ability to run a command instead of notifying
- Fix issue 54: freedesktop-compliant user directories
- Fix issue 72: "show in window list" preference is not saved
- Fix issue 77: don't mess up if ekiga's sound files are not present
- Fix issue 118: add http:// automatically for web watches (also @gmail.com added for gmail accounts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
26
26
import gobject
27
 
import gnome
28
27
import thread
29
28
import gtk
30
29
 
31
30
#specto imports
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
37
36
 
38
37
from time import sleep
39
38
from datetime import datetime
 
39
import base64 #encode/decode passwords
 
40
 
 
41
try:
 
42
    from spectlib.tools.keyringmanager import Keyring
 
43
    keyring = True
 
44
except:
 
45
    keyring = False
40
46
 
41
47
def gettext_noop(s):
42
48
   return s
43
49
 
44
50
class Watch:
45
 
    def __init__(self, specto, id, name, interval, type):
46
 
        self.name = name
47
 
        self.interval = interval
48
 
        self.type = type
49
 
        self.error = False
50
 
        self.timer_id = -1
 
51
    def __init__(self, specto, id, values, watch_values):
 
52
        self.specto = specto
 
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))
 
61
                            ])
 
62
 
51
63
        self.id = id
52
 
        self.updated = False
53
 
        self.specto = specto
54
 
        self.active = True #active/not active
55
 
        self.last_updated = "No updates yet"
 
64
        self.use_network = False
 
65
        self.error = False
56
66
        self.actually_updated = False
57
 
        gnome.sound_init('localhost')
58
 
        self.use_network = False
 
67
        self.timer_id = -1
 
68
        self.deleted = False
 
69
 
 
70
        self.watch_values = watch_values
 
71
        self.set_values(values)
 
72
                
 
73
        self.watch_io = Watch_io(self.specto.FILE)
 
74
        
59
75
        global _
60
 
        
 
76
                    
61
77
    def start(self):
62
78
        """ Start the watch. """
63
 
        self.active = True
64
 
        if self.use_network == True:
65
 
            self.check_connection()
66
 
        else:
 
79
        try:            
 
80
            self.active = True
 
81
            self.watch_io.write_option(self.name, 'active', self.active)
67
82
            self.start_update()
 
83
        except:
 
84
            self.error = True
 
85
            self.specto.logger.log(_("There was an error starting the watch"), "error", self.name)
68
86
            
69
87
    def stop(self):
70
88
        """ Stop the watch. """
71
 
        self.active = False
72
 
        gobject.source_remove(self.timer_id)
 
89
        try:
 
90
            self.active = False
 
91
            self.watch_io.write_option(self.name, 'active', self.active)
 
92
            gobject.source_remove(self.timer_id)
 
93
        except:
 
94
            self.error = True
 
95
            self.specto.logger.log(_("There was an error stopping the watch"), "error", self.name)           
73
96
 
74
97
    def clear(self):
75
98
        """ clear the watch """
76
 
        self.updated = False
 
99
        try:
 
100
            self.updated = False
 
101
            self.watch_io.write_option(self.name, 'updated', self.updated)
 
102
            if not self.error:
 
103
                self.specto.mark_watch_status("idle-clear", self.id)
 
104
        except:
 
105
            self.error = True
 
106
            self.specto.logger.log(_("There was an error clearing the watch"), "error", self.name)
77
107
 
78
108
    def restart(self):
79
109
        """ restart the watch """
82
112
        self.start()        
83
113
        
84
114
    def start_update(self):
85
 
        self.specto.mark_watch_status("updating", self.id)
86
 
        self.error = False
87
 
        #self.update()
88
 
        #return
89
 
        self.lock = thread.allocate_lock()
90
 
        self.lock.acquire()
91
 
        thread.start_new_thread(self.update,())
92
 
        while self.lock.locked():
93
 
            while gtk.events_pending():
94
 
                gtk.main_iteration()
95
 
            time.sleep(0.05)
96
 
        while gtk.events_pending():
97
 
            gtk.main_iteration()
 
115
        try:
 
116
            if self.updated == True:
 
117
                self.specto.mark_watch_status("mark-updated", self.id)
 
118
            if self.use_network:
 
119
                if not self.check_connection():
 
120
                    return 
 
121
            self.specto.logger.log("Started update.", "debug", self.name)   
 
122
            self.specto.mark_watch_status("updating", self.id)
 
123
            self.error = False
 
124
            self.actually_updated = False
 
125
            #self.update()
 
126
            #return
 
127
            self.lock = thread.allocate_lock()
 
128
            self.lock.acquire()
 
129
            thread.start_new_thread(self.update,())
 
130
            while self.lock.locked():
 
131
                while gtk.events_pending():
 
132
                    gtk.main_iteration()
 
133
                time.sleep(0.05)
 
134
        except:
 
135
            self.error = True
 
136
            self.specto.logger.log(_("There was an error starting to update the watch"), "error", self.name)
 
137
 
 
138
                
 
139
                        
 
140
    def watch_updated(self):
 
141
        try:
 
142
            self.specto.logger.log("Watch is updated!", "info", self.name)   
 
143
            self.actually_updated = False
 
144
            self.updated = True            
 
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 + " &")
 
151
        except:
 
152
            self.error = True
 
153
            self.specto.logger.log(_("There was an error marking the watch as updated"), "error", self.name)
 
154
                
98
155
        
99
156
    def timer_update(self):
100
157
        """ update the timer """
101
 
        if self.actually_updated == True:
102
 
            self.actually_updated = False
103
 
            self.updated = True
104
 
            self.last_updated = datetime.today().strftime("%A %d %b %Y %H:%M")
105
 
            self.specto.mark_watch_status("updated", self.id)
106
 
        else:
107
 
            self.specto.mark_watch_status("idle", self.id)
108
158
        try:
109
 
            self.lock.release()
110
 
            self.timer_id = gobject.timeout_add(self.interval, self.thread_update)
 
159
            if self.actually_updated == True:
 
160
                self.watch_updated()
 
161
            elif self.error == True:
 
162
                self.specto.mark_watch_status("error", self.id)
 
163
            elif self.active == False:
 
164
                self.stop()
 
165
            else:
 
166
                self.specto.mark_watch_status("idle", self.id)
 
167
            try:
 
168
                self.lock.release()
 
169
                self.timer_id = gobject.timeout_add(self.refresh, self.start_update)
 
170
            except:
 
171
                self.timer_id = gobject.timeout_add(self.refresh, self.update)
111
172
        except:
112
 
            self.timer_id = gobject.timeout_add(self.interval, self.update)
 
173
            self.error = True
 
174
            self.specto.logger.log(_("There was an error updating the watch"), "error", self.name)
113
175
 
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)
 
181
            return False
120
182
        else :
121
 
            self.start_update()
122
 
 
123
 
    def set_name(self, name):
124
 
        """ Set the name. """
125
 
        self.name = name
126
 
 
127
 
    def get_name(self):
128
 
        """ Return the name. """
129
 
        return self.name
130
 
 
131
 
    def set_interval(self, interval):
132
 
        self.interval = interval
133
 
        
134
 
    def get_interval(self):
135
 
        return self.interval
136
 
    
137
 
    def set_error(self, error):
138
 
        self.error = error
139
 
        
140
 
    def get_error(self):
141
 
        return self.error
142
 
    
 
183
            self.specto.mark_watch_status("network", self.id)
 
184
            #proxy support
 
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("")            
 
192
            return True
 
193
        
 
194
    def get_values(self):
 
195
        return self.values
 
196
        
 
197
    def set_values(self, values, validate=False):
 
198
        error_fields = ""
 
199
        for key, type in self.watch_values:
 
200
            try:
 
201
                value = values[key]
 
202
            except KeyError:
 
203
                if type.mandatory == False:
 
204
                    values[key] = type.getStandardValue()
 
205
                    value = values[key]
 
206
                    if not validate:
 
207
                        setattr(self, key, value)
 
208
                else:
 
209
                    error_fields += ", " + key
 
210
            else:    
 
211
                value = type.checkRestrictions(values[key])
 
212
                if value[0] == True:
 
213
                    if type.mandatory == True and value[1] == type.getStandardValue():
 
214
                        error_fields += ", " + key
 
215
                    else:
 
216
                        values[key] = value[1]
 
217
                        if not validate:
 
218
                            setattr(self, key, value[1])
 
219
                else:
 
220
                    error_fields += ", " + key
 
221
        
 
222
        if values['open_command'] == "":
 
223
            try:
 
224
                self.open_command = self.standard_open_command
 
225
            except:
 
226
                self.open_command = ""
 
227
            
 
228
        if self.last_updated == "":
 
229
            self.last_updated = "No updates yet"
 
230
                
 
231
        if len(error_fields) <> 0:
 
232
            error_fields = error_fields.lstrip(",")
 
233
            raise AttributeError, error_fields
 
234
        else:
 
235
            if not validate:
 
236
                self.values = values
 
237
        
 
238
    def get_balloon_text(self):        
 
239
        return "No message specified yet!"
 
240
    
 
241
    def get_extra_information(self):
 
242
        return "No extra information available."
 
243
    
 
244
    def remove_cache_files(self):
 
245
        return ""
 
246
        
143
247
class Watch_collection:
144
 
    def __init__(self):
 
248
    def __init__(self, specto):
145
249
        self.watch_db = []
146
250
        self.id = 0
147
251
        self.plugin_dict = {}
 
252
        self.disabl_plugin_dict = {}
 
253
        self.specto = specto
148
254
        self.load_plugins()
149
255
                
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):
153
 
            if f[-3:] == ".py":
 
259
            if f[-3:] == ".py" and f != "__init__.py":
 
260
                if not os.path.exists('data'):
 
261
                    dir = "spectlib.plugins."
 
262
                else:
 
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        
 
267
 
 
268
                self.plugin_dict[obj.type] = mod
 
269
 
158
270
                
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 """      
 
273
        _id = []
161
274
        for i in values:
 
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"                    
 
280
 
162
281
            type = values[i]['type']
163
 
            
 
282
                        
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])
 
284
            mod = ""
 
285
            try:
 
286
                mod = self.plugin_dict[type]
 
287
            except:
 
288
                print "Please enable plugin \""+ type + "\", if you want to use the watch: "+ values[i]["name"] + "."
167
289
            
168
 
            self.watch_db.append(watch_)
169
 
            self.id+=1
 
290
            if mod:  
 
291
                obj = getattr(mod, type)
 
292
                try:
 
293
                    watch_ = obj(self.specto, self.id, values[i])
 
294
                except AttributeError, error_fields:
 
295
                    if len(values) > 1:
 
296
                        pass
 
297
                    else:
 
298
                        raise AttributeError, error_fields
 
299
                else:
 
300
                    self.watch_db.append(watch_)
 
301
                    _id.append(self.id)
 
302
                    self.id+=1
 
303
                        
 
304
        return _id
170
305
        
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]
176
 
        
 
309
        self.watch_db[id].updated = False   
 
310
        self.watch_db[id].deleted = True
 
311
        try:
 
312
            self.watch_db[id].remove_cache_files()
 
313
        except:
 
314
            pass
 
315
        self.specto.logger.remove_watch_log(self.watch_db[id].name)    
 
316
                
177
317
    def get(self, id):
178
318
        """ get a watch object """
179
319
        return self.watch_db[id]
196
336
    def restart_all_watches(self):
197
337
        """ restart all watches in the collection """
198
338
        for watch in self.watch_db:
199
 
            if watch.activate == True:
 
339
            if watch.active == True:
200
340
                watch.restart()
201
341
        
202
342
    def length(self):
207
347
        """ Count the number of updated watches for the tooltip. """
208
348
        count_updates = {}
209
349
        for watch in self.watch_db:
210
 
            print watch.updated
211
350
            try:
212
 
                count_updates[watch.type]
 
351
                count_updates[watch.type_desc]
213
352
            except KeyError:
214
 
                count_updates[watch.type] = 0
 
353
                count_updates[watch.type_desc] = 0
215
354
            
216
355
            if watch.updated == True:
217
 
                count_updates[watch.type] += 1
218
 
                
 
356
                updates = count_updates[watch.type_desc]
 
357
                count_updates[watch.type_desc] = updates + 1
 
358
        
219
359
        return count_updates
220
360
    
221
361
    def find_watch(self, name):
223
363
        Returns the key of a watch or None if it doesn't exists.
224
364
        """
225
365
        k = -1
226
 
        for key in self.watch_db.iterkeys():
227
 
            if self.watch_db[key].name == name: 
228
 
                k = key
 
366
        for watch in self.watch_db:
 
367
            if watch.name == name: 
 
368
                k = watch.id
229
369
                break
230
370
        return k
231
371
    
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:
235
 
            return False
 
372
    def set_interval(self, refresh, refresh_unit):
 
373
        """
 
374
        Set the interval between the update checks.
 
375
        refresh = number
 
376
        refresh_unit = days, hours, minutes,... in values of 0, 1, 2, 3.
 
377
        """
 
378
        new_refresh = 0
 
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
 
387
        
 
388
        return new_refresh
 
389
        
 
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
 
394
            type = 3
 
395
        elif (value / 60) / 60 / 1000 > 0:
 
396
            refresh_value = (value / 60) / 60 / 1000
 
397
            type = 2
 
398
        elif value / 60 / 1000 > 0:
 
399
            refresh_value = value / 60 / 1000
 
400
            type = 1
236
401
        else:
237
 
            return True
238
 
    
 
402
            refresh_value = value / 1000
 
403
            type = 0
 
404
            
 
405
        return refresh_value, type
 
406
 
 
407
        
239
408
    def __getitem__(self, i):
240
409
        return self.watch_db[i]
241
410
 
288
457
            self.cfg = ini_namespace(file(self.file_name))
289
458
        except:
290
459
            self.specto.logger.log(_("There was an error initializing config file %s") % self.file_name, "critical", self.__class__)
291
 
            
 
460
        
 
461
        name = self.hide_brackets(name)    
292
462
        options = self.cfg._sections[name]._options.keys()
293
463
        
294
464
        for option_ in options:
295
 
            watch_options_ = { option_: self.read_watch_option(name, option_) }
296
 
            watch_options.update(watch_options_) 
 
465
            if option_ == "password" and not self.check_old_version(self.cfg[name]['type']): #don't use decoding for old watches.list
 
466
                option = self.read_option(name, option_)
 
467
                option = self.decode_password(name, option)
 
468
            else:
 
469
                option = self.read_option(name, option_)
 
470
                
 
471
            watch_options_ = { option_: option }
 
472
            watch_options.update(watch_options_)
 
473
        name = self.show_brackets(name)
297
474
        watch_options.update({'name':name})
298
475
                
299
476
        return watch_options
300
477
    
301
 
    def read_watch_option(self, name, option):
 
478
    def read_option(self, name, option):
302
479
        """ Read one option from a watch """
303
480
        try:
304
481
            return self.cfg[name][option]
312
489
        If the name is not found, a new watch will be added, else the excisting watch will be changed.
313
490
        """
314
491
        try:
315
 
            self.cfg = ini_namespace(file(self.file_name))
316
 
        except:
317
 
            return 0
318
 
        
319
 
        if self.cfg:
320
 
            try:
321
 
                name = values['name']
322
 
 
323
 
                if not self.cfg._sections.has_key(name):
324
 
                    self.cfg.new_namespace(name) #add a new watch
325
 
    
326
 
                del values['name']
327
 
                for option, value  in values.iteritems():
328
 
                    self.cfg[name][option] = value
329
 
            except:
330
 
                self.specto.logger.log(_("There was an reading the watches from %s") % self.file_name, "critical", self.__class__)
331
 
 
332
 
            try:
333
 
                f = open(self.file_name, "w")
334
 
                f.write(str(self.cfg).strip()) #write the new configuration file
335
 
            except IOError:
336
 
                self.specto.logger.log(_("There was an error writing to %s") % self.file_name, "critical", self.__class__)
337
 
            finally:
338
 
                f.close()
 
492
            cfg = ini_namespace(file(self.file_name))
 
493
        except:
 
494
            return 0
 
495
        
 
496
        if cfg:
 
497
            name = self.hide_brackets(values['name'])
 
498
            if not cfg._sections.has_key(name):
 
499
                cfg.new_namespace(name) #add a new watch
 
500
                try:
 
501
                    f = open(self.file_name, "w")
 
502
                    f.write(str(cfg).strip()) #write the new configuration file
 
503
                except IOError:
 
504
                    self.specto.logger.log(_("There was an error writing to %s") % self.file_name, "critical", self.__class__)
 
505
                finally:
 
506
                    f.close()
 
507
 
 
508
            del values['name']
 
509
            for option, value  in values.iteritems():
 
510
                self.write_option(name, option, value)
 
511
                
 
512
            #except:
 
513
            #    self.specto.logger.log(_("There was an reading the watches from %s") % self.file_name, "critical", self.__class__)
 
514
                
 
515
    def write_option(self, name, option, value):
 
516
        try:
 
517
            cfg = ini_namespace(file(self.file_name))
 
518
        except:
 
519
            return 0
 
520
        
 
521
        if cfg:
 
522
            name = self.hide_brackets(name)
 
523
            if not cfg._sections.has_key(name):
 
524
                return 0
 
525
            else:
 
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
 
529
                try:
 
530
                    f = open(self.file_name, "w")
 
531
                    f.write(str(cfg).strip()) #write the new configuration file
 
532
                except IOError:
 
533
                    self.specto.logger.log(_("There was an error writing to %s") % self.file_name, "critical", self.__class__)
 
534
                finally:
 
535
                    f.close()
 
536
        
339
537
        
340
538
 
341
539
    def remove_watch(self, name):
343
541
        try:
344
542
            cfgpr = ConfigParser()
345
543
            cfgpr.read(self.file_name)
346
 
            cfgpr.remove_section(name)
 
544
            cfgpr.remove_section(self.hide_brackets(name))
347
545
            f = open(self.file_name, "w")
348
546
            cfgpr.write(open(self.file_name, "w"))
349
547
        except IOError:
357
555
        """
358
556
        try:
359
557
            self.cfg = ini_namespace(file(self.file_name))
360
 
            if not self.cfg._sections.has_key(name):
 
558
            if not self.cfg._sections.has_key(self.hide_brackets(name)):
361
559
                return False
362
560
            else:
363
561
                return True
374
572
            self.specto.logger.log(_("There was an error writing to %s") % self.file_name, "critical", self.__class__)
375
573
        except:
376
574
            f.close
377
 
            
 
575
        
 
576
        name = self.hide_brackets(name)
 
577
        new_name = self.hide_brackets(new_name)
378
578
        text = text.replace("[" + name + "]", "[" + new_name + "]")
379
 
        
 
579
 
380
580
        if text:
381
581
            #replace and write file
382
582
            try:
386
586
                self.specto.logger.log(_("There was an error writing to %s") % self.file_name, "critical", self.__class__)
387
587
            finally:
388
588
                f.close()
 
589
                
 
590
    def hide_brackets(self,name):
 
591
        name = name.replace("[", "&brStart;")
 
592
        name = name.replace("]", "&brEnd;")
 
593
        return name
 
594
        
 
595
    def show_brackets(self,name):
 
596
        name = name.replace("&brStart;", "[")
 
597
        name = name.replace("&brEnd;", "]")
 
598
        return name
 
599
    
 
600
    def encode_password(self, name, password):
 
601
        if keyring == True:
 
602
            k = Keyring(name, "Specto " + name, "network") 
 
603
            k.set_credentials((name, password))
 
604
            password = "**keyring**"
 
605
        else:
 
606
            password = base64.b64encode(password)
 
607
        return password
 
608
        
 
609
    def decode_password(self, name, password):
 
610
        if keyring == True:
 
611
            try:
 
612
                k = Keyring(name, "Specto " + name, "network")
 
613
                password = k.get_credentials()[1]
 
614
            except:
 
615
                try:
 
616
                    password = base64.b64decode(password)
 
617
                except TypeError:#password was not yet encoded
 
618
                    password = password
 
619
        else:
 
620
            try:
 
621
                password = base64.b64decode(password)
 
622
            except TypeError:#password was not yet encoded
 
623
                password = password
 
624
        return password
 
625
    
 
626
    def check_old_version(self, type):
 
627
        old = True
 
628
        try:
 
629
            int(type) #type is int: old version
 
630
            old = True
 
631
        except ValueError:
 
632
            old = False #type is not int: new version
 
633
        
 
634
        return old
 
635
            
 
636
 
 
637