gnome-schedule r1125 - in trunk: . po src
- From: gauteh svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-schedule r1125 - in trunk: . po src
- Date: Sat, 14 Feb 2009 21:20:56 +0000 (UTC)
Author: gauteh
Date: Sat Feb 14 21:20:56 2009
New Revision: 1125
URL: http://svn.gnome.org/viewvc/gnome-schedule?rev=1125&view=rev
Log:
* X support ready for testing
* xwrapper.py: checks for X connection in both crontab and at
* xwrapper.py: works for at
* Merged x-output-support onto trunk
Added:
trunk/src/xwrapper.py
- copied unchanged from r1124, /branches/x-output-support/src/xwrapper.py
Modified:
trunk/ (props changed)
trunk/ChangeLog
trunk/HACKING
trunk/NEWS
trunk/README
trunk/po/POTFILES.in
trunk/src/Makefile.am
trunk/src/addWindow.py
trunk/src/at.py
trunk/src/atEditor.py
trunk/src/config.py.in
trunk/src/crontab.py
trunk/src/crontabEditor.py
trunk/src/crontabEditorHelper.py
trunk/src/data.py
trunk/src/gnome-schedule.glade
trunk/src/gnome-schedule.py
trunk/src/lang.py
trunk/src/mainWindow.py
trunk/src/scheduleapplet.py
trunk/src/setuserWindow.py
trunk/src/template.py
trunk/src/template_chooser.py
trunk/src/template_manager.py
Modified: trunk/HACKING
==============================================================================
--- trunk/HACKING (original)
+++ trunk/HACKING Sat Feb 14 21:20:56 2009
@@ -12,3 +12,6 @@
Major changes should be submitted for approval to the maintainer(s).
+Coding style:
+ Use expanded tabs, 4 of them, on all *.py files.
+
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Sat Feb 14 21:20:56 2009
@@ -1,3 +1,6 @@
+2009-02-14:
+ X output support ready for testing, merged onto trunk/
+
2008-02-08:
Releasing 2.0.2 to with a new at parser.
Modified: trunk/README
==============================================================================
--- trunk/README (original)
+++ trunk/README Sat Feb 14 21:20:56 2009
@@ -87,6 +87,7 @@
This will use images and datafiles from the current directory. Remember this is only for debugging and might not always work as expected.
+
To make contributions you should first read
o. HACKING
Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in (original)
+++ trunk/po/POTFILES.in Sat Feb 14 21:20:56 2009
@@ -24,4 +24,4 @@
src/template.py
src/template_chooser.py
src/template_manager.py
-
+src/xwrapper.py.in
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Sat Feb 14 21:20:56 2009
@@ -17,7 +17,8 @@
scheduleapplet.py \
template.py \
template_chooser.py \
- template_manager.py
+ template_manager.py \
+ xwrapper.py
uidir = $(datadir)/gnome-schedule
@@ -31,7 +32,7 @@
config.py \
gnome-schedule.glade.bak \
gnome-schedule.gladep.bak \
- gnome-schedule.gladep
+ gnome-schedule.gladep
EXTRA_DIST = \
$(bin_SCRIPTS) \
Modified: trunk/src/addWindow.py
==============================================================================
--- trunk/src/addWindow.py (original)
+++ trunk/src/addWindow.py Sat Feb 14 21:20:56 2009
@@ -21,101 +21,101 @@
import gtk
class AddWindow:
- def __init__(self, parent):
- self.ParentClass = parent
- self.transient = self.ParentClass.widget
- self.xml = self.ParentClass.xml
- self.widget = self.xml.get_widget ("addWindow")
- self.widget.connect("delete-event", self.widget.hide_on_delete)
-
- self.mode = 0
-
- self.cancel_button = self.xml.get_widget ("select_cancel_button")
- self.ok_button = self.xml.get_widget ("select_ok_button")
-
- self.xml.signal_connect("on_select_cancel_button_clicked", self.on_cancel_button_clicked)
-
- self.xml.signal_connect("on_button_at_clicked", self.on_button_at_clicked)
- self.xml.signal_connect("on_button_crontab_clicked", self.on_button_crontab_clicked)
- self.xml.signal_connect("on_button_templates_clicked", self.on_button_template_clicked)
-
- self.button_at = self.xml.get_widget ("button_at")
- self.button_crontab = self.xml.get_widget ("button_crontab")
- self.button_template = self.xml.get_widget ("button_templates")
-
- self.chbox = gtk.HBox (False, 5)
- self.cicon = gtk.Image ()
- self.cicon.set_from_pixbuf (self.ParentClass.bigiconcrontab)
- self.cicon.set_alignment (0, 0.5)
- self.chbox.pack_start (self.cicon, False, False, 5)
- self.clabel = gtk.Label (_("A task that launches recurrently"))
- self.clabel.set_justify (gtk.JUSTIFY_LEFT)
- self.clabel.set_alignment (0, 0.5)
- self.chbox.pack_start (self.clabel, True, True, 5)
-
- self.button_crontab.add (self.chbox)
- self.button_crontab.show_all ()
-
- self.ahbox = gtk.HBox (False, 5)
- self.aicon = gtk.Image ()
- self.aicon.set_from_pixbuf (self.ParentClass.bigiconat)
- self.aicon.set_alignment (0, 0.5)
- self.ahbox.pack_start (self.aicon, False, False, 5)
- self.alabel = gtk.Label (_("A task that launches one time"))
- self.alabel.set_justify (gtk.JUSTIFY_LEFT)
- self.alabel.set_alignment (0, 0.5)
- self.ahbox.pack_start (self.alabel, True, True, 5)
-
- self.button_at.add (self.ahbox)
- self.button_at.show_all ()
-
- self.thbox = gtk.HBox (False, 5)
- self.ticon = gtk.Image ()
- self.ticon.set_from_pixbuf (self.ParentClass.bigicontemplate)
- self.ticon.set_alignment (0, 0.5)
- self.thbox.pack_start (self.ticon, False, False, 5)
- self.tlabel = gtk.Label (_("A task from a predefined template"))
- self.tlabel.set_justify (gtk.JUSTIFY_LEFT)
- self.tlabel.set_alignment (0, 0.5)
- self.thbox.pack_start (self.tlabel, True, True, 5)
-
- self.button_template.add (self.thbox)
- self.button_template.show_all ()
-
-
- # mode: 0 = normal add, 1 = new template
- def ShowAddWindow (self, transient, mode = 0):
- self.mode = mode
- self.transient = transient
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.widget.show_all()
- if (mode == 1):
- self.button_template.hide ()
- elif (mode == 0):
- self.button_template.show_all ()
-
-
- def on_cancel_button_clicked (self, *args):
- self.widget.hide()
-
- def on_button_template_clicked (self, *args):
- self.widget.hide ()
- self.ParentClass.template_chooser.show (self.transient)
-
- def on_button_crontab_clicked (self, *args):
- self.widget.hide ()
- self.ParentClass.editor = self.ParentClass.crontab_editor
- if (self.mode == 1):
- self.ParentClass.editor.shownew_template (self.transient)
- elif (self.mode == 0):
- self.ParentClass.editor.showadd (self.transient)
-
- def on_button_at_clicked (self, *args):
- self.widget.hide ()
- self.ParentClass.editor = self.ParentClass.at_editor
- if (self.mode == 1):
- self.ParentClass.editor.shownew_template (self.transient)
- elif (self.mode == 0):
- self.ParentClass.editor.showadd (self.transient)
-
+ def __init__(self, parent):
+ self.ParentClass = parent
+ self.transient = self.ParentClass.widget
+ self.xml = self.ParentClass.xml
+ self.widget = self.xml.get_widget ("addWindow")
+ self.widget.connect("delete-event", self.widget.hide_on_delete)
+
+ self.mode = 0
+
+ self.cancel_button = self.xml.get_widget ("select_cancel_button")
+ self.ok_button = self.xml.get_widget ("select_ok_button")
+
+ self.xml.signal_connect("on_select_cancel_button_clicked", self.on_cancel_button_clicked)
+
+ self.xml.signal_connect("on_button_at_clicked", self.on_button_at_clicked)
+ self.xml.signal_connect("on_button_crontab_clicked", self.on_button_crontab_clicked)
+ self.xml.signal_connect("on_button_templates_clicked", self.on_button_template_clicked)
+
+ self.button_at = self.xml.get_widget ("button_at")
+ self.button_crontab = self.xml.get_widget ("button_crontab")
+ self.button_template = self.xml.get_widget ("button_templates")
+
+ self.chbox = gtk.HBox (False, 5)
+ self.cicon = gtk.Image ()
+ self.cicon.set_from_pixbuf (self.ParentClass.bigiconcrontab)
+ self.cicon.set_alignment (0, 0.5)
+ self.chbox.pack_start (self.cicon, False, False, 5)
+ self.clabel = gtk.Label (_("A task that launches recurrently"))
+ self.clabel.set_justify (gtk.JUSTIFY_LEFT)
+ self.clabel.set_alignment (0, 0.5)
+ self.chbox.pack_start (self.clabel, True, True, 5)
+
+ self.button_crontab.add (self.chbox)
+ self.button_crontab.show_all ()
+
+ self.ahbox = gtk.HBox (False, 5)
+ self.aicon = gtk.Image ()
+ self.aicon.set_from_pixbuf (self.ParentClass.bigiconat)
+ self.aicon.set_alignment (0, 0.5)
+ self.ahbox.pack_start (self.aicon, False, False, 5)
+ self.alabel = gtk.Label (_("A task that launches one time"))
+ self.alabel.set_justify (gtk.JUSTIFY_LEFT)
+ self.alabel.set_alignment (0, 0.5)
+ self.ahbox.pack_start (self.alabel, True, True, 5)
+
+ self.button_at.add (self.ahbox)
+ self.button_at.show_all ()
+
+ self.thbox = gtk.HBox (False, 5)
+ self.ticon = gtk.Image ()
+ self.ticon.set_from_pixbuf (self.ParentClass.bigicontemplate)
+ self.ticon.set_alignment (0, 0.5)
+ self.thbox.pack_start (self.ticon, False, False, 5)
+ self.tlabel = gtk.Label (_("A task from a predefined template"))
+ self.tlabel.set_justify (gtk.JUSTIFY_LEFT)
+ self.tlabel.set_alignment (0, 0.5)
+ self.thbox.pack_start (self.tlabel, True, True, 5)
+
+ self.button_template.add (self.thbox)
+ self.button_template.show_all ()
+
+
+ # mode: 0 = normal add, 1 = new template
+ def ShowAddWindow (self, transient, mode = 0):
+ self.mode = mode
+ self.transient = transient
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.widget.show_all()
+ if (mode == 1):
+ self.button_template.hide ()
+ elif (mode == 0):
+ self.button_template.show_all ()
+
+
+ def on_cancel_button_clicked (self, *args):
+ self.widget.hide()
+
+ def on_button_template_clicked (self, *args):
+ self.widget.hide ()
+ self.ParentClass.template_chooser.show (self.transient)
+
+ def on_button_crontab_clicked (self, *args):
+ self.widget.hide ()
+ self.ParentClass.editor = self.ParentClass.crontab_editor
+ if (self.mode == 1):
+ self.ParentClass.editor.shownew_template (self.transient)
+ elif (self.mode == 0):
+ self.ParentClass.editor.showadd (self.transient)
+
+ def on_button_at_clicked (self, *args):
+ self.widget.hide ()
+ self.ParentClass.editor = self.ParentClass.at_editor
+ if (self.mode == 1):
+ self.ParentClass.editor.shownew_template (self.transient)
+ elif (self.mode == 0):
+ self.ParentClass.editor.showadd (self.transient)
+
Modified: trunk/src/at.py
==============================================================================
--- trunk/src/at.py (original)
+++ trunk/src/at.py Sat Feb 14 21:20:56 2009
@@ -30,575 +30,618 @@
class At:
- def __init__(self,root,user,uid,gid,user_home_dir,manual_poscorrect):
-
- #default preview length
- self.preview_len = 50
- self.root = root
- self.set_rights(user,uid,gid, user_home_dir)
- self.user_home_dir = user_home_dir
- self.manual_poscorrect = manual_poscorrect
-
-
- # 16 2006-01-08 13:01 a gaute
- # 7 Sun Jan 8 13:01:00 2006 a pvanhoof
- # 1 2006-04-26 08:54 a gaute
- # 14 2006-09-21 10:54 a gaute
- # 3 Tue May 8 01:01:00 2007 a gaute
-
- self.atRecordRegex = re.compile('^([\d]+)[\t]([\w]{3,3})[\s]([\w]{3,3})[\s]*([\d]+)[\s]([\d]{2,2}[:][\d]{2,2}[:][\d]{2,2})[\s]([\d]{4,4})[\s]([\w])[\s]([\w]+)')
-
-
- # after you add a job, this line is printed to stderr
- # job 10 at 2006-09-18 12:38
- self.atRecordRegexAdd = re.compile('^job\s([0-9]+)\sat')
-
- self.atRecordRegexAdded = re.compile('[^\s]+\s([0-9]+)\sat')
- self.nooutput = 0
- self.SCRIPT_DELIMITER = "###### ---- GNOME_SCHEDULE_SCRIPT_DELIMITER #####"
-
- # If normally this variable is unset the user would not expect it
- # to be set, which it will be because Gnome Schedule needs it.
- # Therefore we unset it in the script.
- self.POSIXLY_CORRECT_UNSET = "unset POSIXLY_CORRECT\n"
-
- self.atdatafileversion = 3
- self.atdata = self.user_home_dir + "/.gnome/gnome-schedule/at"
- if os.path.exists (self.user_home_dir + "/.gnome") != True:
- os.mkdir (self.user_home_dir + "/.gnome", 0700)
- os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
- if os.path.exists(self.atdata) != True:
- try:
- os.makedirs(self.atdata, 0700)
- if self.root == 1:
- os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
- os.chown (self.atdata, self.uid, self.gid)
- except:
- print _("Failed to create data dir! Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.")
-
- self.months = {
- 'Jan' : '1',
- 'Feb' : '2',
- 'Mar' : '3',
- 'Apr' : '4',
- 'May' : '5',
- 'Jun' : '6',
- 'Jul' : '7',
- 'Aug' : '8',
- 'Sep' : '9',
- 'Oct' : '10',
- 'Nov' : '11',
- 'Dec' : '12'
- }
-
- def set_rights(self,user,uid,gid, ud):
- self.user = user
- self.uid = uid
- self.gid = gid
- self.user_home_dir = ud
- self.atdata = self.user_home_dir + "/.gnome/gnome-schedule/at"
- if os.path.exists (self.user_home_dir + "/.gnome") != True:
- os.mkdir (self.user_home_dir + "/.gnome", 0700)
- os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
- if os.path.exists(self.atdata) != True:
- try:
- os.makedirs(self.atdata, 0700)
- if self.root == 1:
- os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
- os.chown (self.atdata, self.uid, self.gid)
- except:
- print (_("Failed to create data dir: %s. Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.") % (self.atdata))
-
-
- def get_type (self):
- return "at"
-
- def parse (self, line, output = True):
- if (output == True):
- if len (line) > 1 and line[0] != '#':
- m = self.atRecordRegex.match(line)
- if m != None:
- # Time
- time = m.groups ()[4][:-3]
-
- # Date
- day = m.groups ()[3]
- month = m.groups ()[2]
-
- for monthname in self.months:
- month = month.replace (monthname, self.months[monthname])
-
- if int (day) < 10:
- day = "0" + day
- if int (month) < 10:
- month = "0" + month
-
- date = day + "." + month + "." + m.groups ()[5]
-
- job_id = m.groups ()[0]
- class_id = m.groups ()[6]
- user = m.groups ()[7]
-
- title, desc, manual_poscorrect = self.get_job_data (int (job_id))
- # manual_poscorrect is only used during preparation of script
-
- execute = config.getAtbin() + " -c " + job_id
- # read lines and detect starter
- script = os.popen(execute).read()
- script, prelen, dangerous = self.__prepare_script__ (script, manual_poscorrect)
-
- #removing ending newlines, but keep one
- #if a date in the past is selected the record is removed by at, this creates an error, and generally if the script is of zero length
- # TODO: complain about it as well
-
- if len(script) < 2:
- done = 1
- else:
- done = 0
-
- while done == 0:
- if script[-1] == "\n":
- script = script[0:-1]
- else:
- done = 1
-
- return job_id, date, time, class_id, user, script, title, prelen, dangerous
-
- elif (output == False):
- if len (line) > 1 and line[0] != '#':
- m = self.atRecordRegexAdd.search(line)
- #print "Parsing line: " + line
- if m != None:
- #print "Parse successfull, groups: "
- #print m.groups()
- job_id = m.groups ()[0]
- return int(job_id)
- else:
- return False
-
- return False
- # TODO: throw exception
-
- def get_job_data (self, job_id):
- f = os.path.join (self.atdata, str (job_id))
- if os.access (f, os.R_OK):
- fh = open (f, 'r')
- d = fh.read ()
-
- ver_p = d.find ("ver=")
- if ver_p == -1:
- ver = 1
- else:
- ver_s = d[ver_p + 4:d.find ("\n")]
- d = d[d.find ("\n") + 1:]
- ver = int (ver_s)
-
- title = d[6:d.find ("\n")]
- d = d[d.find ("\n") + 1:]
-
- # icons out
- if ver < 2:
- icon = d[5:d.find ("\n")]
- d = d[d.find ("\n") + 1:]
-
- desc = d[5:d.find ("\n")]
- d = d[d.find ("\n") + 1:]
-
- manual_poscorrect_b = False
- if ver > 2:
- manual_poscorrect = d[18:d.find ("\n")]
- d = d[d.find ("\n") + 1:]
- if manual_poscorrect == "true":
- manual_poscorrect_b = True
- elif manual_poscorrect == "false":
- manual_poscorrect_b = False
- fh.close ()
-
- return title, desc, manual_poscorrect_b
-
- else:
- return "", "", False
-
- def write_job_data (self, job_id, title, desc):
- # Create and write data file
- f = os.path.join (self.atdata, str(job_id))
- #print f
- fh = open (f, 'w')
- fh.truncate (1)
- fh.seek (0)
- fh.write ("ver=" + str(self.atdatafileversion) + "\n")
- fh.write ("title=" + title + "\n")
- fh.write ("desc=" + desc + "\n")
-
- # This one doesn't need to be passed independently for each job since the job data is only updated together with a task being appended or updated (also new added), and the variable depends on each session. Not job.
- if self.manual_poscorrect == True:
- fh.write ("manual_poscorrect=true\n")
- else:
- fh.write ("manual_poscorrect=false\n")
- fh.close ()
- os.chown (f, self.uid, self.gid)
- os.chmod (f, 0600)
-
- def checkfield (self, runat):
- #TODO: fix bug $0:19 2004-12-8$ not valid by regexp
- # print "$" + runat + "$"
- #regexp1 = re.compile("([0-9][0-9]):([0-9][0-9])\ ([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
- #print "Testing: " + runat
- regexp1 = re.compile ("([0-9][0-9])([0-9][0-9])\ ([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
- regexp2 = re.compile("([0-9][0-9])([0-9][0-9])")
- regexp3 = re.compile("([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
-
- runat_g1 = regexp1.match(runat)
- runat_g2 = regexp2.match(runat)
- runat_g3 = regexp3.match(runat)
- ctime = time.localtime()
- cyear = ctime[0]
- cmonth = ctime[1]
- cday = ctime[2]
- chour = ctime[3]
- cminute = ctime[4]
-
- if runat_g1:
- (hour, minute, day, month, year) = runat_g1.groups()
- hour = int(hour)
- minute = int(minute)
- year = int(year)
- month = int(month)
- day = int(day)
-
- if hour > 24 or hour < 0:
- return False, "hour"
-
- if minute > 60 or minute < 0:
- return False, "minute"
-
- if month > 12 or month < 0:
- return False, "month"
-
- if day > 31 or day < 0:
- return False, "day"
-
- if year < 0:
- return False, "year"
-
- if year >= cyear:
- if year == cyear:
- syear = True
- if (month >= cmonth):
- if month == cmonth:
- smonth = True
- if day >= cday:
- if day == cday:
- sday = True
- if hour >= chour:
- if hour == chour:
- shour = True
- if minute <= cminute:
- return False, "minute"
- else:
- shour = False
- else:
- return False, "hour"
- else:
- sday = False
- else:
- return False, "day"
- else:
- smonth = False
- else:
- return False, "month"
- else:
- syear = False
- else:
- return False, "year"
-
- elif runat_g2:
-
- (hour, minute) = runat_g2.groups()
- hour = int(hour)
- minute = int(minute)
- if hour > 24 or hour < 0:
- return False, "hour"
-
- if minute > 60 or minute < 0:
- return False, "minute"
-
-
- elif runat_g3:
-
- (day, month, year) = runat_g3.groups()
- year = int(year)
- month = int(month)
- day = int(day)
- if year < cyear:
- return False, "year"
- if month < cmonth:
- return False, "month"
- if day < cday:
- return False, "day"
-
- else:
- #lowercase
- runat = runat.lower()
-
- #some timespecs:
- days = ['sun','mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sunday','monday','tuesday','wednesday','thursday','friday','saturday']
- relative_days = ['tomorrow','next week','today']
- relative_hour = ['noon','teatime','midnight','next hour']
- relative_minute = ['next minute']
- relative_month = ['next month']
-
- if runat in days:
- pass
- elif runat in relative_days:
- pass
- elif runat in relative_hour:
- pass
- elif runat in relative_minute:
- pass
- elif runat in relative_month:
- pass
- else:
- return False, "other"
-
- return True, "ok"
-
-
- def append (self, runat, command, title):
- tmpfile = tempfile.mkstemp ()
- fd, path = tmpfile
- tmp = os.fdopen(fd, 'w')
- tmp.write (self.SCRIPT_DELIMITER + "\n")
- if self.manual_poscorrect:
- tmp.write (self.POSIXLY_CORRECT_UNSET)
- tmp.write (command + "\n")
- tmp.close ()
-
- temp = None
-
- if self.root == 1:
- if self.user != "root":
- #changes the ownership
- os.chown(path, self.uid, self.gid)
- execute = config.getSubin() + " " + self.user + " -c \"" + config.getAtbin() + " -f " + path + " " + runat + " && exit\""
- child_stdin, child_stdout, child_stderr = os.popen3(execute)
- else:
- execute = config.getAtbin() + " -f " + path + " " + runat
- child_stdin, child_stdout, child_stderr = os.popen3(execute)
- else:
- execute = config.getAtbin() + " -f " + path + " " + runat
- child_stdin, child_stdout, child_stderr = os.popen3(execute)
-
-
- err = child_stderr.readlines ()
- job_id = 0
- for line in err:
- t = self.parse (line, False)
- if t != False:
- job_id = t
-
- #print job_id
-
- desc = ""
- self.write_job_data (job_id, title, desc)
-
- os.unlink (path)
-
-
- def update (self, job_id, runat, command, title):
- #print "update" + str (job_id) + runat + command + title
- #remove old
- f = os.path.join (self.atdata, str (job_id))
- if os.access (f, os.F_OK):
- os.unlink (f)
- execute = config.getAtrmbin()+ " " + str(job_id)
- commands.getoutput(execute)
-
- #add new
- tmpfile = tempfile.mkstemp ()
- fd, path = tmpfile
- tmp = os.fdopen(fd, 'w')
-
- tmp.write (self.SCRIPT_DELIMITER + "\n")
- if self.manual_poscorrect:
- tmp.write (self.POSIXLY_CORRECT_UNSET)
- tmp.write (command + "\n")
- tmp.close ()
-
- if self.root == 1:
- if self.user != "root":
- #changes the ownership
- os.chown(path, self.uid, self.gid)
- execute = config.getSubin() + " " + self.user + " -c \"" + config.getAtbin() + " -f " + path + " " + runat + " && exit\""
- child_stdin, child_stdout, child_stderr = os.popen3(execute)
- else:
- execute = config.getAtbin() + " -f " + path + " " + runat
- child_stdin, child_stdout, child_stderr = os.popen3(execute)
- else:
- execute = config.getAtbin() + " -f " + path + " " + runat
- child_stdin, child_stdout, child_stderr = os.popen3(execute)
-
- err = child_stderr.readlines ()
- job_id = 0
- for line in err:
- t = self.parse (line, False)
- if t != False:
- job_id = t
-
- #print job_id
-
- desc = ""
- self.write_job_data (job_id, title, desc)
-
- os.unlink (path)
-
-
- def delete (self, job_id, iter):
- if job_id:
- # delete file
- f = os.path.join (self.atdata, str(job_id))
- if os.access(f, os.F_OK):
- os.unlink (f)
- execute = config.getAtrmbin()+ " " + str(job_id)
- commands.getoutput(execute)
-
-
- def read (self):
- data = []
- #do 'atq'
- execute = config.getAtqbin ()
- self.lines = os.popen(execute).readlines()
- for line in self.lines:
-
- array_or_false = self.parse (line)
- #print array_or_false
- if array_or_false != False:
- (job_id, date, time, class_id, user, lines, title, prelen, dangerous) = array_or_false
-
-
- preview = self.__make_preview__ (lines, prelen)
- if dangerous == 1:
- preview = _("DANGEROUS PARSE: %(preview)s") % {'preview': preview}
- #chopping of script delimiter
- lines = lines[prelen:]
- lines.strip ()
-
- timestring = "%s %s" % (date, time)
- # TODO: localize time and date formats
- timestring_show = _("On %(date)s at %(time)s") % {'date': date, 'time': time}
-
- # TODO: looks like it could be one append
- if self.root == 1:
- if self.user == user:
- data.append([title, timestring_show, preview, lines, int(job_id), timestring, self, None, date, class_id, user, time, _("Once"), "at", self.nooutput, timestring])
- else:
- #print "Record omitted, not current user"
- pass
- else:
- data.append([title, timestring_show, preview, lines, int(job_id), timestring, self, None, date, class_id, user, time, _("Once"), "at", self.nooutput, timestring])
-
- #print _("added %(id)s") % { "id": job_id }
- else:
- print _("Warning: a line in atq's output didn't parse")
- return data
-
-
- def __prepare_script__ (self, script, manual_poscorrect):
-
- # It looks like at prepends a bunch of stuff to each script
- # Luckily it delimits that using two newlines
- # So assuming that at never prepends two newlines unless
- # it's done prepending, we will start recording the custom commands
- # once the first two lines have been found
-
- # Later: It now seems like this is incorrect, and may vary upon distribution. I therefore determine the prepended stuff by making a test job and then removing the length of it. in gentoo it adds to newlines at the end of the script
-
- # If the script is created by Gnome Schedule the script is seperated by a delimiter.
-
- dangerous = 0
- prelen = 0
- string = self.SCRIPT_DELIMITER
- scriptstart = script.find(string)
-
- if scriptstart != -1:
- script = script[scriptstart:]
- if manual_poscorrect == True:
- scriptstart = script.find (self.POSIXLY_CORRECT_UNSET)
- if scriptstart != -1:
- script = script[scriptstart:]
- prelen = len (self.POSIXLY_CORRECT_UNSET)
- else:
- prelen = len(self.SCRIPT_DELIMITER) + 1
-
- else:
- dangerous = 1
-
- string = " || {\n echo 'Execution directory inaccessible' >&2\n exit 1\n}\n"
- string_len = len(string)
- start = script.find(string)
- start = start + string_len
- script = script[start:]
- prelen = 0
- # If the string contains TITLE=
- titlestart = script.find ("TITLE=")
- if titlestart != -1:
- titleend = script.find("\n", titlestart)
- title = script[(titlestart + 6):titleend]
- #remeber the length to remove this from the preview
- prelen = len(title) + 7
- else:
- title = "Untitled"
- # If the string contains ICON=
- iconstart = script.find ("ICON=")
- if iconstart != -1:
- iconend = script.find ("\n", iconstart)
- icon = script[(iconstart + 5):iconend]
-
- prelen = prelen + len(icon) + 6
-
- else:
- icon = None
-
- return script, prelen, dangerous
-
-
- def __make_preview__ (self, lines, prelen, preview_len = 0):
- if preview_len == 0:
- preview_len = self.preview_len
- try:
- if prelen:
- result = lines[(0 + prelen):(preview_len + prelen)]
- else:
- result = lines[0:preview_len]
- except:
- #print "short preview"
- result = lines[prelen:(-1 - prelen)]
-
- result = result.replace("\n",";")
- result = result.replace ("&", "&")
- #remove ending newlines, not if result len = 0
- if len(result) < 2:
- done = 1
- else:
- done = 0
- while done == 0:
- if result[-1] == ";":
- result = result[0:-1]
- else:
- done = 1
- #remove beginning newlines
- if len(result) < 2:
- done = 1
- else:
- done = 0
- while done == 0:
- if result[0] == ";":
- result = result[1:]
- else:
- done = 1
+ def __init__(self,root,user,uid,gid,user_home_dir,manual_poscorrect):
+
+ #default preview length
+ self.preview_len = 50
+ self.root = root
+ self.set_rights(user,uid,gid, user_home_dir)
+ self.user_home_dir = user_home_dir
+ self.manual_poscorrect = manual_poscorrect
+
+
+ # 16 2006-01-08 13:01 a gaute
+ # 7 Sun Jan 8 13:01:00 2006 a pvanhoof
+ # 1 2006-04-26 08:54 a gaute
+ # 14 2006-09-21 10:54 a gaute
+ # 3 Tue May 8 01:01:00 2007 a gaute
+
+ self.atRecordRegex = re.compile('^([\d]+)[\t]([\w]{3,3})[\s]([\w]{3,3})[\s]*([\d]+)[\s]([\d]{2,2}[:][\d]{2,2}[:][\d]{2,2})[\s]([\d]{4,4})[\s]([\w])[\s]([\w]+)')
+
+
+ # after you add a job, this line is printed to stderr
+ # job 10 at 2006-09-18 12:38
+ self.atRecordRegexAdd = re.compile('^job\s([0-9]+)\sat')
+
+ self.atRecordRegexAdded = re.compile('[^\s]+\s([0-9]+)\sat')
+ self.SCRIPT_DELIMITER = "###### ---- GNOME_SCHEDULE_SCRIPT_DELIMITER #####"
+
+ self.DISPLAY = "DISPLAY=%s; export DISPLAY;\n"
+ self.DISPLAY = self.DISPLAY + config.xwrapper_exec + " a\n"
+ self.DISPLAY = self.DISPLAY + """
+xwrapper=$?;
+if [ $xwrapper -eq 0 ]; then
+ echo "all fine";
+else
+ echo "xwrapper failed.";
+ exit;
+fi
+"""
+
+ # If normally this variable is unset the user would not expect it
+ # to be set, which it will be because Gnome Schedule needs it.
+ # Therefore we unset it in the script.
+ self.POSIXLY_CORRECT_UNSET = "unset POSIXLY_CORRECT\n"
+
+ self.atdatafileversion = 5
+ self.atdata = self.user_home_dir + "/.gnome/gnome-schedule/at"
+ if os.path.exists (self.user_home_dir + "/.gnome") != True:
+ os.mkdir (self.user_home_dir + "/.gnome", 0700)
+ os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
+ if os.path.exists(self.atdata) != True:
+ try:
+ os.makedirs(self.atdata, 0700)
+ if self.root == 1:
+ os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
+ os.chown (self.atdata, self.uid, self.gid)
+ except:
+ print _("Failed to create data dir! Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.")
+
+ self.months = {
+ 'Jan' : '1',
+ 'Feb' : '2',
+ 'Mar' : '3',
+ 'Apr' : '4',
+ 'May' : '5',
+ 'Jun' : '6',
+ 'Jul' : '7',
+ 'Aug' : '8',
+ 'Sep' : '9',
+ 'Oct' : '10',
+ 'Nov' : '11',
+ 'Dec' : '12'
+ }
+
+ def set_rights(self,user,uid,gid, ud):
+ self.user = user
+ self.uid = uid
+ self.gid = gid
+ self.user_home_dir = ud
+ self.atdata = self.user_home_dir + "/.gnome/gnome-schedule/at"
+ if os.path.exists (self.user_home_dir + "/.gnome") != True:
+ os.mkdir (self.user_home_dir + "/.gnome", 0700)
+ os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
+ if os.path.exists(self.atdata) != True:
+ try:
+ os.makedirs(self.atdata, 0700)
+ if self.root == 1:
+ os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
+ os.chown (self.atdata, self.uid, self.gid)
+ except:
+ print (_("Failed to create data dir: %s. Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.") % (self.atdata))
+
+
+ def get_type (self):
+ return "at"
+
+ def parse (self, line, output = True):
+ if (output == True):
+ if len (line) > 1 and line[0] != '#':
+ m = self.atRecordRegex.match(line)
+ if m != None:
+ # Time
+ time = m.groups ()[4][:-3]
+
+ # Date
+ day = m.groups ()[3]
+ month = m.groups ()[2]
+
+ for monthname in self.months:
+ month = month.replace (monthname, self.months[monthname])
+
+ if int (day) < 10:
+ day = "0" + day
+ if int (month) < 10:
+ month = "0" + month
+
+ date = day + "." + month + "." + m.groups ()[5]
+
+ job_id = m.groups ()[0]
+ class_id = m.groups ()[6]
+ user = m.groups ()[7]
+
+ success, title, desc, manual_poscorrect, output, display = self.get_job_data (int (job_id))
+ # manual_poscorrect is only used during preparation of script
+
+ execute = config.getAtbin() + " -c " + job_id
+ # read lines and detect starter
+ script = os.popen(execute).read()
+ script, dangerous = self.__prepare_script__ (script, manual_poscorrect, output, display)
+
+ #removing ending newlines, but keep one
+ #if a date in the past is selected the record is removed by at, this creates an error, and generally if the script is of zero length
+ # TODO: complain about it as well
+
+ if len(script) < 2:
+ done = 1
+ else:
+ done = 0
+
+ while done == 0:
+ if script[-1] == "\n":
+ script = script[0:-1]
+ else:
+ done = 1
+
+ return job_id, date, time, class_id, user, script, title, dangerous, output
+
+ elif (output == False):
+ if len (line) > 1 and line[0] != '#':
+ m = self.atRecordRegexAdd.search(line)
+ #print "Parsing line: " + line
+ if m != None:
+ #print "Parse successfull, groups: "
+ #print m.groups()
+ job_id = m.groups ()[0]
+ return int(job_id)
+ else:
+ return False
+
+ return False
+ # TODO: throw exception
+
+ def get_job_data (self, job_id):
+ f = os.path.join (self.atdata, str (job_id))
+ if os.access (f, os.R_OK):
+ fh = open (f, 'r')
+ d = fh.read ()
+
+ ver_p = d.find ("ver=")
+ if ver_p == -1:
+ ver = 1
+ else:
+ ver_s = d[ver_p + 4:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+ ver = int (ver_s)
+
+ title = d[6:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+
+ # icons out
+ if ver < 2:
+ icon = d[5:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+
+ desc = d[5:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+
+ manual_poscorrect_b = False
+ if ver > 2:
+ manual_poscorrect = d[18:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+ if manual_poscorrect == "true":
+ manual_poscorrect_b = True
+ elif manual_poscorrect == "false":
+ manual_poscorrect_b = False
+
+ if ver >= 5:
+ output_str = d[7:d.find ("\n")]
+ output = int (output_str)
+ d = d[d.find("\n") + 1:]
+ else:
+ output = 0
+
+ if ver >= 5:
+ display = d[8:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+ if (len (display) < 1) or (output == 0):
+ display = ""
+ else:
+ display = ""
+
+ fh.close ()
+
+ return True, title, desc, manual_poscorrect_b, output, display
+
+ else:
+ return False, "", "", False, 0, ""
+
+ def write_job_data (self, job_id, title, desc, output, display):
+ # Create and write data file
+ f = os.path.join (self.atdata, str(job_id))
+ #print f
+ fh = open (f, 'w')
+ fh.truncate (1)
+ fh.seek (0)
+ fh.write ("ver=" + str(self.atdatafileversion) + "\n")
+ fh.write ("title=" + title + "\n")
+ fh.write ("desc=" + desc + "\n")
+
+ # This one doesn't need to be passed independently for each job since the job data is only updated together with a task being appended or updated (also new added), and the variable depends on each session. Not job.
+ if self.manual_poscorrect == True:
+ fh.write ("manual_poscorrect=true\n")
+ else:
+ fh.write ("manual_poscorrect=false\n")
+
+ fh.write ("output=" + str (output) + "\n")
+ fh.write ("display=" + display + "\n")
+
+ fh.close ()
+ os.chown (f, self.uid, self.gid)
+ os.chmod (f, 0600)
+
+ def checkfield (self, runat):
+ #TODO: fix bug $0:19 2004-12-8$ not valid by regexp
+ # print "$" + runat + "$"
+ #regexp1 = re.compile("([0-9][0-9]):([0-9][0-9])\ ([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
+ #print "Testing: " + runat
+ regexp1 = re.compile ("([0-9][0-9])([0-9][0-9])\ ([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
+ regexp2 = re.compile("([0-9][0-9])([0-9][0-9])")
+ regexp3 = re.compile("([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
+
+ runat_g1 = regexp1.match(runat)
+ runat_g2 = regexp2.match(runat)
+ runat_g3 = regexp3.match(runat)
+ ctime = time.localtime()
+ cyear = ctime[0]
+ cmonth = ctime[1]
+ cday = ctime[2]
+ chour = ctime[3]
+ cminute = ctime[4]
+
+ if runat_g1:
+ (hour, minute, day, month, year) = runat_g1.groups()
+ hour = int(hour)
+ minute = int(minute)
+ year = int(year)
+ month = int(month)
+ day = int(day)
+
+ if hour > 24 or hour < 0:
+ return False, "hour"
+
+ if minute > 60 or minute < 0:
+ return False, "minute"
+
+ if month > 12 or month < 0:
+ return False, "month"
+
+ if day > 31 or day < 0:
+ return False, "day"
+
+ if year < 0:
+ return False, "year"
+
+ if year >= cyear:
+ if year == cyear:
+ syear = True
+ if (month >= cmonth):
+ if month == cmonth:
+ smonth = True
+ if day >= cday:
+ if day == cday:
+ sday = True
+ if hour >= chour:
+ if hour == chour:
+ shour = True
+ if minute <= cminute:
+ return False, "minute"
+ else:
+ shour = False
+ else:
+ return False, "hour"
+ else:
+ sday = False
+ else:
+ return False, "day"
+ else:
+ smonth = False
+ else:
+ return False, "month"
+ else:
+ syear = False
+ else:
+ return False, "year"
+
+ elif runat_g2:
+
+ (hour, minute) = runat_g2.groups()
+ hour = int(hour)
+ minute = int(minute)
+ if hour > 24 or hour < 0:
+ return False, "hour"
+
+ if minute > 60 or minute < 0:
+ return False, "minute"
+
+
+ elif runat_g3:
+
+ (day, month, year) = runat_g3.groups()
+ year = int(year)
+ month = int(month)
+ day = int(day)
+ if year < cyear:
+ return False, "year"
+ if month < cmonth:
+ return False, "month"
+ if day < cday:
+ return False, "day"
+
+ else:
+ #lowercase
+ runat = runat.lower()
+
+ #some timespecs:
+ days = ['sun','mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sunday','monday','tuesday','wednesday','thursday','friday','saturday']
+ relative_days = ['tomorrow','next week','today']
+ relative_hour = ['noon','teatime','midnight','next hour']
+ relative_minute = ['next minute']
+ relative_month = ['next month']
+
+ if runat in days:
+ pass
+ elif runat in relative_days:
+ pass
+ elif runat in relative_hour:
+ pass
+ elif runat in relative_minute:
+ pass
+ elif runat in relative_month:
+ pass
+ else:
+ return False, "other"
+
+ return True, "ok"
+
+
+ def append (self, runat, command, title, output):
+ tmpfile = tempfile.mkstemp ()
+ fd, path = tmpfile
+ tmp = os.fdopen(fd, 'w')
+ tmp.write (self.SCRIPT_DELIMITER + "\n")
+ if self.manual_poscorrect:
+ tmp.write (self.POSIXLY_CORRECT_UNSET)
+
+ display = ""
+ if output > 0:
+ display = os.getenv ('DISPLAY')
+ tmp.write (self.DISPLAY % display )
+
+ tmp.write (command + "\n")
+ tmp.close ()
+
+ temp = None
+
+ if self.root == 1:
+ if self.user != "root":
+ #changes the ownership
+ os.chown(path, self.uid, self.gid)
+ execute = config.getSubin() + " " + self.user + " -c \"" + config.getAtbin() + " -f " + path + " " + runat + " && exit\""
+ child_stdin, child_stdout, child_stderr = os.popen3(execute)
+ else:
+ execute = config.getAtbin() + " -f " + path + " " + runat
+ child_stdin, child_stdout, child_stderr = os.popen3(execute)
+ else:
+ execute = config.getAtbin() + " -f " + path + " " + runat
+ child_stdin, child_stdout, child_stderr = os.popen3(execute)
+
+
+ err = child_stderr.readlines ()
+ job_id = 0
+ for line in err:
+ t = self.parse (line, False)
+ if t != False:
+ job_id = t
+
+ #print job_id
+
+ desc = ""
+ self.write_job_data (job_id, title, desc, output, display)
+
+ os.unlink (path)
+
+
+ def update (self, job_id, runat, command, title, output):
+ #print "update" + str (job_id) + runat + command + title
+ #remove old
+ f = os.path.join (self.atdata, str (job_id))
+ if os.access (f, os.F_OK):
+ os.unlink (f)
+ execute = config.getAtrmbin()+ " " + str(job_id)
+ commands.getoutput(execute)
+
+ #add new
+ tmpfile = tempfile.mkstemp ()
+ fd, path = tmpfile
+ tmp = os.fdopen(fd, 'w')
+
+ tmp.write (self.SCRIPT_DELIMITER + "\n")
+ if self.manual_poscorrect:
+ tmp.write (self.POSIXLY_CORRECT_UNSET)
+
+ display = ""
+ if output > 0:
+ display = os.getenv ('DISPLAY')
+ tmp.write (self.DISPLAY % display )
+
+ tmp.write (command + "\n")
+ tmp.close ()
+
+ if self.root == 1:
+ if self.user != "root":
+ #changes the ownership
+ os.chown(path, self.uid, self.gid)
+ execute = config.getSubin() + " " + self.user + " -c \"" + config.getAtbin() + " -f " + path + " " + runat + " && exit\""
+ child_stdin, child_stdout, child_stderr = os.popen3(execute)
+ else:
+ execute = config.getAtbin() + " -f " + path + " " + runat
+ child_stdin, child_stdout, child_stderr = os.popen3(execute)
+ else:
+ execute = config.getAtbin() + " -f " + path + " " + runat
+ child_stdin, child_stdout, child_stderr = os.popen3(execute)
+
+ err = child_stderr.readlines ()
+ job_id = 0
+ for line in err:
+ t = self.parse (line, False)
+ if t != False:
+ job_id = t
+
+ #print job_id
+
+ desc = ""
+ self.write_job_data (job_id, title, desc, output, display)
+
+ os.unlink (path)
+
+
+ def delete (self, job_id, iter):
+ if job_id:
+ # delete file
+ f = os.path.join (self.atdata, str(job_id))
+ if os.access(f, os.F_OK):
+ os.unlink (f)
+ execute = config.getAtrmbin()+ " " + str(job_id)
+ commands.getoutput(execute)
+
+
+ def read (self):
+ data = []
+ #do 'atq'
+ execute = config.getAtqbin ()
+ self.lines = os.popen(execute).readlines()
+ for line in self.lines:
+
+ array_or_false = self.parse (line)
+ #print array_or_false
+ if array_or_false != False:
+ (job_id, date, time, class_id, user, lines, title, dangerous, output) = array_or_false
+
+
+ preview = self.__make_preview__ (lines)
+ if dangerous == 1:
+ preview = _("DANGEROUS PARSE: %(preview)s") % {'preview': preview}
+ #chopping of script delimiter
+ lines.strip ()
+
+ timestring = "%s %s" % (date, time)
+ # TODO: localize time and date formats
+ timestring_show = _("On %(date)s at %(time)s") % {'date': date, 'time': time}
+
+ # TODO: looks like it could be one append
+ if self.root == 1:
+ if self.user == user:
+ data.append([title, timestring_show, preview, lines, int(job_id), timestring, self, None, date, class_id, user, time, _("Once"), "at", output, timestring])
+ else:
+ #print "Record omitted, not current user"
+ pass
+ else:
+ data.append([title, timestring_show, preview, lines, int(job_id), timestring, self, None, date, class_id, user, time, _("Once"), "at", output, timestring])
+
+ #print _("added %(id)s") % { "id": job_id }
+ else:
+ print _("Warning: a line in atq's output didn't parse")
+ return data
+
+
+ def __prepare_script__ (self, script, manual_poscorrect, output, display):
+
+ # It looks like at prepends a bunch of stuff to each script
+ # Luckily it delimits that using two newlines
+ # So assuming that at never prepends two newlines unless
+ # it's done prepending, we will start recording the custom commands
+ # once the first two lines have been found
+
+ # Later: It now seems like this is incorrect, and may vary upon distribution. I therefore determine the prepended stuff by making a test job and then removing the length of it. in gentoo it adds to newlines at the end of the script
+
+ # If the script is created by Gnome Schedule the script is seperated by a delimiter.
+
+ dangerous = 0
+ scriptstart = script.find(self.SCRIPT_DELIMITER)
+
+ if scriptstart != -1:
+ script = script[scriptstart:]
+ if manual_poscorrect == True:
+ scriptstart = script.find (self.POSIXLY_CORRECT_UNSET)
+ if scriptstart != -1:
+ script = script[scriptstart + len(self.POSIXLY_CORRECT_UNSET):]
+ else:
+ script = script[len(self.SCRIPT_DELIMITER) + 1:]
+
+ if output > 0:
+ scriptstart = script.find (self.DISPLAY % display)
+ if scriptstart != -1:
+ script = script [scriptstart + len (self.DISPLAY % display):]
+
+ else:
+ dangerous = 1
+
+ string = " || {\n echo 'Execution directory inaccessible' >&2\n exit 1\n}\n"
+ string_len = len(string)
+ start = script.find(string)
+ start = start + string_len
+ script = script[start:]
+ prelen = 0
+ # If the string contains TITLE=
+ titlestart = script.find ("TITLE=")
+ if titlestart != -1:
+ titleend = script.find("\n", titlestart)
+ title = script[(titlestart + 6):titleend]
+ #remeber the length to remove this from the preview
+ prelen = len(title) + 7
+ else:
+ title = "Untitled"
+ # If the string contains ICON=
+ iconstart = script.find ("ICON=")
+ if iconstart != -1:
+ iconend = script.find ("\n", iconstart)
+ icon = script[(iconstart + 5):iconend]
+
+ prelen = prelen + len(icon) + 6
+
+ else:
+ icon = None
+
+ script = script[prelen:]
+
+ return script, dangerous
+
+
+ def __make_preview__ (self, lines, preview_len = 0):
+ if preview_len == 0:
+ preview_len = self.preview_len
+
+ if len (lines) > preview_len:
+ result = lines[0:preview_len]
+ else:
+ result = lines
+
+ result = result.replace("\n",";")
+ result = result.replace ("&", "&")
+ #remove ending newlines, not if result len = 0
+ if len(result) < 2:
+ done = 1
+ else:
+ done = 0
+ while done == 0:
+ if result[-1] == ";":
+ result = result[0:-1]
+ else:
+ done = 1
+ #remove beginning newlines
+ if len(result) < 2:
+ done = 1
+ else:
+ done = 0
+ while done == 0:
+ if result[0] == ";":
+ result = result[1:]
+ else:
+ done = 1
- if len(result) >= preview_len :
- result = result + "..."
+ if len(result) >= preview_len :
+ result = result + "..."
- return result
-
+ return result
+
Modified: trunk/src/atEditor.py
==============================================================================
--- trunk/src/atEditor.py (original)
+++ trunk/src/atEditor.py Sat Feb 14 21:20:56 2009
@@ -33,565 +33,583 @@
class AtEditor:
- def __init__(self, parent, backend, scheduler, template):
- self.ParentClass = parent
- self.xml = self.ParentClass.xml
- self.backend = backend
- self.scheduler = scheduler
- self.template = template
-
-
- self.widget = self.xml.get_widget("at_editor")
- self.xml.signal_connect("on_at_editor_delete", self.on_button_cancel_clicked)
-
- self.mode = 0 # 0 = add, 1 = edit, 2 = template
-
- self.button_save = self.xml.get_widget ("at_button_save")
- self.button_cancel = self.xml.get_widget ("at_button_cancel")
- self.entry_title = self.xml.get_widget ("at_entry_title")
- self.text_task = self.xml.get_widget ("at_text_task")
- self.text_task_buffer = self.text_task.get_buffer()
- self.button_add_template = self.xml.get_widget ("at_button_template")
- self.at_vbox_time = self.xml.get_widget ("at_vbox_time")
-
-
- self.spin_hour = self.xml.get_widget ("at_spin_hour")
- self.spin_minute = self.xml.get_widget ("at_spin_minute")
- self.spin_year = self.xml.get_widget ("at_spin_year")
- self.spin_month = self.xml.get_widget ("at_spin_month")
- self.spin_day = self.xml.get_widget ("at_spin_day")
-
- self.title_box = self.xml.get_widget ("title_box")
-
- self.image_icon = gtk.Image ()
- self.image_icon.set_from_pixbuf (self.ParentClass.bigiconat)
- self.title_box.pack_start (self.image_icon, False, False, 0)
- self.title_box.reorder_child (self.image_icon, 0)
- self.image_icon.show ()
-
- self.cal_button = self.xml.get_widget ("cal_button")
- self.cal_hbox = gtk.HBox ()
- self.calicon = gtk.Image ()
- self.calicon.set_from_pixbuf (self.ParentClass.iconcalendar)
- self.arrow = gtk.Arrow (gtk.ARROW_DOWN, gtk.SHADOW_OUT)
- self.cal_label = gtk.Label (_("Calendar"))
- self.cal_hbox.add (self.calicon)
- self.cal_hbox.add (self.cal_label)
- self.cal_hbox.add (self.arrow)
- self.cal_button.add (self.cal_hbox)
- self.cal_button.show_all ()
-
- self.xml.signal_connect ("on_cal_button_toggled", self.on_cal_button_toggled)
-
- self.cal_loaded = False
- self.x, self.y = self.widget.get_position ()
- self.height, self.wid9847th = self.widget.get_size ()
- self.cal_active = True
-
- self.xml.signal_connect ("on_at_editor_size_changed", self.on_at_editor_size_changed)
-
- self.xml.signal_connect("on_at_button_cancel_clicked", self.on_button_cancel_clicked)
- self.xml.signal_connect("on_at_button_save_clicked", self.on_button_save_clicked)
-
- self.xml.signal_connect("on_at_text_task_popup_menu", self.on_text_task_popup_menu)
- self.xml.signal_connect("on_at_text_task_key_release_event", self.on_text_task_change)
-
- self.xml.signal_connect("on_at_entry_title_changed", self.on_entry_title_changed)
-
- self.xml.signal_connect("on_at_button_cancel_clicked", self.on_button_cancel_clicked)
- self.xml.signal_connect ("on_at_button_template_clicked", self.on_button_template_clicked)
-
- self.check_spin_running = False
-
- self.xml.signal_connect("on_at_spin_hour_changed", self.on_spin_hour_changed)
- self.xml.signal_connect("on_at_spin_minute_changed", self.on_spin_minute_changed)
- self.xml.signal_connect ("on_at_spin_year_changed", self.on_spin_year_changed)
- self.xml.signal_connect ("on_at_spin_month_changed", self.on_spin_month_changed)
- self.xml.signal_connect ("on_at_spin_day_changed", self.on_spin_day_changed)
-
- ctime = time.localtime()
- year = ctime[0]
- self.spin_year.set_range (year, year + 5847) # TODO: Year +5847 compatability
- self.timeout_handler_id = gobject.timeout_add(60 * 1000, self.__check_spins__)
-
-
- def showadd (self, transient):
- self.button_save.set_label (gtk.STOCK_ADD)
- self.__reset__ ()
- self.title = _("Untitled")
- self.mode = 0 # add new task
- self.widget.set_title(_("Create a New Scheduled Task"))
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.__setup_calendar__ ()
- self.button_add_template.show ()
- self.widget.show_all ()
-
- self.__update_textboxes__()
-
- def showadd_template (self, transient, title, command):
- self.button_save.set_label (gtk.STOCK_ADD)
- self.__reset__ ()
- self.title = title
- self.command = command
- self.mode = 0 # add new task
- self.widget.set_title(_("Create a New Scheduled Task"))
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.__setup_calendar__ ()
- self.button_add_template.show ()
- self.widget.show_all ()
-
- self.__update_textboxes__()
-
- def showedit_template (self, transient, id, title, command):
- self.button_save.set_label (gtk.STOCK_ADD)
- self.__reset__ ()
- self.tid = id
- self.title = title
- self.command = command
- self.mode = 2 # edit template
-
- self.widget.set_title(_("Edit template"))
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.__setup_calendar__ ()
- self.widget.show_all ()
-
- # hide time settings
- self.at_vbox_time.hide ()
-
- # save and cancel buttons
- self.button_save.set_label (gtk.STOCK_SAVE)
- self.button_add_template.hide ()
-
- self.__update_textboxes__()
-
- def shownew_template (self, transient):
- self.button_save.set_label (gtk.STOCK_ADD)
- self.__reset__ ()
- self.tid = 0
- self.mode = 2 # edit template
-
- self.widget.set_title(_("New template"))
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.__setup_calendar__ ()
- self.widget.show_all ()
-
- # hide time settings
- self.at_vbox_time.hide ()
-
- # save and cancel buttons
- self.button_save.set_label (gtk.STOCK_ADD)
- self.button_add_template.hide ()
-
- self.__update_textboxes__()
-
- def showedit (self, transient, record, job_id, iter):
- self.button_save.set_label (gtk.STOCK_APPLY)
- self.mode = 1 # edit task
- self.job_id = job_id
- self.date = self.ParentClass.treemodel.get_value(iter, 9)
- self.time = self.ParentClass.treemodel.get_value(iter, 12)
- self.title = self.ParentClass.treemodel.get_value(iter, 0)
- self.class_id = self.ParentClass.treemodel.get_value(iter, 9)
- self.user = self.ParentClass.treemodel.get_value(iter, 10)
- self.command = self.ParentClass.treemodel.get_value(iter, 3)
- # removing beginning newlines.. wherever they come from..
- i = self.command.find ('\n', 0)
- while i == 0:
- self.command = self.command[1:]
- i = self.command.find ('\n', 0)
-
- #parse
- (hour, minute, day, month, year) = self.__parse_time__(self.time, self.date)
- self.runat = hour + minute + " " + day + "." + month + "." + year
- self.spin_year.set_value (int (year))
- self.spin_month.set_value (int (month))
- self.spin_day.set_value (int (day))
-
- self.spin_hour.set_value(int(hour))
- self.spin_minute.set_value(int(minute))
- self.widget.set_title(_("Edit a Scheduled Task"))
-
- self.__update_textboxes__ ()
- self.parentiter = iter
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.__setup_calendar__ ()
- self.button_add_template.show ()
- self.widget.show_all ()
-
-
-
- def on_cal_lost_focus (self, *args):
- self.__hide_calendar__ ()
-
- def on_at_editor_size_changed (self, *args):
- if self.cal_button.get_active ():
- x, y = self.widget.get_position ()
- height, width = self.widget.get_size ()
- if ((x != self.x) or (y != self.y) or (height != self.height) or (width != self.width)):
- self.__hide_calendar__ ()
-
- def on_cal_button_toggled (self, *args):
- if self.cal_button.get_active ():
- self.__show_calendar__ ()
- else:
- self.__hide_calendar__ ()
-
-
- def __setup_calendar__ (self):
- if self.cal_loaded == False:
- self.xml.signal_connect ("on_cal_lost_focus", self.on_cal_lost_focus)
- self.xml.signal_connect ("on_cal_window_destroy", self.__destroy_calendar__) # its actually not destroyed, but deleted
-
- self.xml.signal_connect ("on_cal_day_selected_dc", self.on_cal_day_selected_dc)
- self.xml.signal_connect ("on_cal_day_selected", self.on_cal_day_selected)
-
- self.cal_window = self.xml.get_widget ("cal_window")
- self.calendar = self.xml.get_widget ("calendar")
- self.cal_window.hide_all ()
- self.cal_loaded = True
-
- def __destroy_calendar__ (self):
- self.cal_window.hide_all ()
- return True
-
- def on_cal_day_selected (self, *args):
- if self.cal_active:
- year, month, day = self.calendar.get_date ()
- self.spin_year.set_value (int (year))
- self.spin_month.set_value (int (month) + 1)
- self.spin_day.set_value (int (day))
-
- def on_cal_day_selected_dc (self, *args):
- self.__hide_calendar__ ()
-
- def __show_calendar__ (self):
- x, y = self.widget.window.get_origin ()
- button_rect = self.cal_button.get_allocation ()
- x = x + button_rect.x
- y = y + button_rect.y + button_rect.height
- self.cal_window.move (x, y)
- self.widget.set_modal (False)
- self.x, self.y = self.widget.get_position ()
- self.height, self.width = self.widget.get_size ()
- self.cal_active = False
- self.calendar.select_month (self.spin_month.get_value_as_int () -1 , self.spin_year.get_value_as_int ())
- self.calendar.select_day (self.spin_day.get_value_as_int ())
- self.cal_active = True
- self.cal_window.show_all ()
-
- def __hide_calendar__ (self):
- self.cal_window.hide_all ()
- self.cal_button.set_active (False)
- self.widget.set_modal (True)
-
-
- def on_worded_label_event (self, *args):
- #TODO highlight on mouseover
- pass
-
- def on_defined_label_event (self, *args):
- #TODO highlight on mouseover
- # enable control_option on click
- pass
-
- def on_text_task_popup_menu (self, *args):
- #TODO show at_script_menuons: install t
- # don't forget to attach eventhandling to this popup
- pass
-
-
-
- def on_text_task_change (self, *args):
- start = self.text_task_buffer.get_start_iter()
- end = self.text_task_buffer.get_end_iter()
- self.command = self.text_task_buffer.get_text(start, end)
-
-
- def on_entry_title_changed (self, *args):
- self.title = self.entry_title.get_text()
-
- def on_spin_day_changed (self, *args):
- self.__check_spins__ ()
- self.__update_time_cal__()
-
- def on_spin_month_changed (self, *args):
- self.__check_spins__ ()
- self.__update_time_cal__()
-
- def on_spin_year_changed (self, *args):
- self.__check_spins__ ()
- self.__update_time_cal__()
-
- def on_spin_hour_changed (self, *args):
- self.__check_spins__ ()
- self.__update_time_cal__()
-
- def on_spin_minute_changed (self, *args):
- self.__check_spins__ ()
- self.__update_time_cal__()
-
- def __check_spins__ (self):
- # Is additionally run every minute
- if self.check_spin_running != True:
- self.check_spin_running = True
-
- ctime = time.localtime()
- year = ctime[0]
- month = ctime[1]
- day = ctime[2]
- hour = ctime[3]
- minute = ctime[4]
-
- cyear = False
- cmonth = False
- cday = False
- chour = False
-
- syear = self.spin_year.get_value_as_int ()
- if (syear == year):
- cyear = True
-
- smonth = self.spin_month.get_value_as_int ()
- mi, ma = self.spin_month.get_range ()
- if cyear:
- if (mi != month):
- self.spin_month.set_range (month, 12)
- mi = month
- else:
- if ((mi != 1) or (ma != 12)):
- self.spin_month.set_range (1, 12)
- if (mi <= smonth <= ma):
- self.spin_month.set_value (smonth)
- else:
- if (smonth > ma):
- self.spin_month.set_value (ma)
- else:
- self.spin_month.set_value (mi)
- smonth = self.spin_month.get_value_as_int ()
- if (smonth == month):
- cmonth = True
-
- sday = self.spin_day.get_value_as_int ()
- mi, ma = self.spin_day.get_range ()
- w, days = calendar.monthrange (syear, smonth)
- if (cmonth and cyear):
- if (mi != day):
- self.spin_day.set_range (day, days)
- mi = day
- else:
- if ((mi != 1) or (ma != days)):
- self.spin_day.set_range (1, days)
- if (mi <= sday <= days):
- self.spin_day.set_value (sday)
- else:
- if (sday > days):
- self.spin_day.set_value (days)
- else:
- self.spin_day.set_value (mi)
- sday = self.spin_day.get_value_as_int ()
- if (sday == day):
- cday = True
-
- shour = self.spin_hour.get_value_as_int ()
- mi, ma = self.spin_hour.get_range ()
- if (cyear and cmonth and cday):
- if (mi != hour):
- self.spin_hour.set_range (hour, 24)
- mi = hour
- else:
- if ((mi != 0) or (ma != 24)):
- self.spin_hour.set_range (0, 24)
- if (mi <= shour <= ma):
- self.spin_hour.set_value (shour)
- else:
- if (shour > ma):
- self.spin_hour.set_value (ma)
- else:
- self.spin_hour.set_value (mi)
- shour = self.spin_hour.get_value_as_int ()
- if (shour == hour):
- chour = True
-
- sminute = self.spin_minute.get_value_as_int ()
- mi, ma = self.spin_minute.get_range ()
- if (cyear and cmonth and cday and chour):
- if (mi != minute):
- self.spin_minute.set_range (minute, 59)
- mi = minute
- else:
- if ((mi != 0) or (ma != 59)):
- self.spin_minute.set_range (0, 59)
- if (mi <= sminute <= ma):
- self.spin_minute.set_value (sminute)
- else:
- if (sminute > ma):
- self.spin_minute.set_value (ma)
- else:
- self.spin_minute.set_value (mi)
- self.check_spin_running = False
-
-
- def __update_time_cal__ (self):
- year = self.spin_year.get_text ()
- month = self.spin_month.get_text ()
- day = self.spin_day.get_text ()
- hour = self.spin_hour.get_text()
- minute = self.spin_minute.get_text()
-
- year = str(year)
-
- if hour.isdigit():
- hour = int(hour)
- else:
- return False
-
- if minute.isdigit():
- minute = int(minute)
- else:
- return False
-
- if day.isdigit ():
- day = int (day)
- else:
- return False
-
- if month.isdigit ():
- month = int (month)
- else:
- return False
-
- if year.isdigit () == False:
- return False
-
- if hour < 10:
- hour = "0" + str(hour)
- else:
- hour = str(hour)
-
- if minute < 10:
- minute = "0" + str(minute)
- else:
- minute = str(minute)
-
- if month < 10:
- month = "0" + str(month)
- else:
- month = str(month)
-
- if day < 10:
- day = "0" + str(day)
- else:
- day = str(day)
-
- self.runat = hour + minute + " " + day + "." + month + "." + year
-
-
- def popup_error_no_digit (self, field):
- box_popup = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("In one or both of the fields hour and minute there was entered a letter, or a number out of range. Remember an hour only has 60 minutes and a day only 24 hours."))
- box_popup.set_response_sensitive(gtk.RESPONSE_OK, True)
- run = box_popup.run ()
- box_popup.hide ()
- field.set_text ("0")
-
-
- def __reset__ (self):
- self.title = _("Untitled")
- self.command = ""
-
- ctime = time.localtime()
- year = ctime[0]
- month = ctime[1]
- day = ctime[2]
- hour = ctime[3]
- minute = ctime[4]
-
- self.runat = str(hour) + str(minute) + " " + str(day) + "." + str(month) + "." + str (year)
-
- self.spin_hour.set_value(int(hour))
- self.spin_minute.set_value(int(minute))
- self.spin_year.set_value (int (year))
- self.spin_month.set_value (int (month))
- self.spin_day.set_value (int (day))
-
- self.__update_textboxes__ ()
-
-
- def __update_textboxes__(self, update_runat = 1):
-
- if self.title == None:
- self.title = _("Untitled")
-
- self.entry_title.set_text(self.title)
- self.text_task_buffer.set_text(self.command)
-
- def __parse_time__ (self, time, date):
- regexp_date = re.compile("([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
- regexp_time = re.compile("([0-9][0-9]):([0-9][0-9])")
-
- time_g = regexp_time.match(time)
- if time_g:
- (hour, minute) = time_g.groups()
-
- date_g = regexp_date.match(date)
- if date_g:
- (day, month, year) = date_g.groups()
-
- return hour, minute, day, month, year
-
-
- def on_button_cancel_clicked (self, *args):
- self.__destroy_calendar__ ()
- self.widget.hide()
- return True
-
-
- def __WrongRecordDialog__ (self, x):
- self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is an invalid record! The problem could be: %s") % (x)))
- self.wrongdialog.run()
- self.wrongdialog.destroy()
-
- def on_button_template_clicked (self, *args):
- self.template.savetemplate_at (0, self.title, self.command)
- self.widget.hide ()
-
- def on_button_save_clicked (self, *args):
- if self.mode == 2:
- self.template.savetemplate_at (self.tid, self.title, self.command)
- self.widget.hide ()
- return
-
- (validate, reason) = self.scheduler.checkfield(self.runat)
- if validate == False:
- self.__WrongRecordDialog__ (reason)
- return
-
- if (self.backend.get_not_inform_working_dir_at() != True):
- dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nOne-time tasks will be run from the directory where Gnome schedule is run from (normally the home directory)."))
- dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
- dia2.set_title (_("Warning: Working directory of executed tasks"))
- response = dia2.run ()
- if response == gtk.RESPONSE_CANCEL:
- dia2.destroy ()
- del dia2
- return
- elif response == gtk.RESPONSE_CLOSE:
- self.backend.set_not_inform_working_dir_at (True)
- else:
- pass
- dia2.destroy ()
- del dia2
-
- if self.mode == 1:
- self.scheduler.update (self.job_id, self.runat, self.command, self.title)
- else:
- self.scheduler.append (self.runat, self.command, self.title)
-
- self.ParentClass.schedule_reload ()
-
- self.widget.hide ()
-
+ def __init__(self, parent, backend, scheduler, template):
+ self.ParentClass = parent
+ self.xml = self.ParentClass.xml
+ self.backend = backend
+ self.scheduler = scheduler
+ self.template = template
+
+
+ self.widget = self.xml.get_widget("at_editor")
+ self.xml.signal_connect("on_at_editor_delete", self.on_button_cancel_clicked)
+
+ self.mode = 0 # 0 = add, 1 = edit, 2 = template
+
+ self.button_save = self.xml.get_widget ("at_button_save")
+ self.button_cancel = self.xml.get_widget ("at_button_cancel")
+ self.entry_title = self.xml.get_widget ("at_entry_title")
+ self.text_task = self.xml.get_widget ("at_text_task")
+ self.text_task_buffer = self.text_task.get_buffer()
+ self.button_add_template = self.xml.get_widget ("at_button_template")
+ self.at_vbox_time = self.xml.get_widget ("at_vbox_time")
+
+ self.cb_xoutput = self.xml.get_widget ("cb_xoutput")
+
+ self.spin_hour = self.xml.get_widget ("at_spin_hour")
+ self.spin_minute = self.xml.get_widget ("at_spin_minute")
+ self.spin_year = self.xml.get_widget ("at_spin_year")
+ self.spin_month = self.xml.get_widget ("at_spin_month")
+ self.spin_day = self.xml.get_widget ("at_spin_day")
+
+ self.title_box = self.xml.get_widget ("title_box")
+
+ self.image_icon = gtk.Image ()
+ self.image_icon.set_from_pixbuf (self.ParentClass.bigiconat)
+ self.title_box.pack_start (self.image_icon, False, False, 0)
+ self.title_box.reorder_child (self.image_icon, 0)
+ self.image_icon.show ()
+
+ self.cal_button = self.xml.get_widget ("cal_button")
+ self.cal_hbox = gtk.HBox ()
+ self.calicon = gtk.Image ()
+ self.calicon.set_from_pixbuf (self.ParentClass.iconcalendar)
+ self.arrow = gtk.Arrow (gtk.ARROW_DOWN, gtk.SHADOW_OUT)
+ self.cal_label = gtk.Label (_("Calendar"))
+ self.cal_hbox.add (self.calicon)
+ self.cal_hbox.add (self.cal_label)
+ self.cal_hbox.add (self.arrow)
+ self.cal_button.add (self.cal_hbox)
+ self.cal_button.show_all ()
+
+ self.xml.signal_connect ("on_cal_button_toggled", self.on_cal_button_toggled)
+ self.xml.signal_connect ("on_cb_xoutput_toggled", self.on_cb_xoutput_toggled)
+
+ self.cal_loaded = False
+ self.x, self.y = self.widget.get_position ()
+ self.height, self.width = self.widget.get_size ()
+ self.cal_active = True
+
+ self.xml.signal_connect ("on_at_editor_size_changed", self.on_at_editor_size_changed)
+
+ self.xml.signal_connect("on_at_button_cancel_clicked", self.on_button_cancel_clicked)
+ self.xml.signal_connect("on_at_button_save_clicked", self.on_button_save_clicked)
+
+ self.xml.signal_connect("on_at_text_task_popup_menu", self.on_text_task_popup_menu)
+ self.xml.signal_connect("on_at_text_task_key_release_event", self.on_text_task_change)
+
+ self.xml.signal_connect("on_at_entry_title_changed", self.on_entry_title_changed)
+
+ self.xml.signal_connect("on_at_button_cancel_clicked", self.on_button_cancel_clicked)
+ self.xml.signal_connect ("on_at_button_template_clicked", self.on_button_template_clicked)
+
+ self.check_spin_running = False
+
+ self.xml.signal_connect("on_at_spin_hour_changed", self.on_spin_hour_changed)
+ self.xml.signal_connect("on_at_spin_minute_changed", self.on_spin_minute_changed)
+ self.xml.signal_connect ("on_at_spin_year_changed", self.on_spin_year_changed)
+ self.xml.signal_connect ("on_at_spin_month_changed", self.on_spin_month_changed)
+ self.xml.signal_connect ("on_at_spin_day_changed", self.on_spin_day_changed)
+
+ ctime = time.localtime()
+ year = ctime[0]
+ self.spin_year.set_range (year, year + 5847) # TODO: Year +5847 compatability
+ self.timeout_handler_id = gobject.timeout_add(60 * 1000, self.__check_spins__)
+
+
+ def showadd (self, transient):
+ self.button_save.set_label (gtk.STOCK_ADD)
+ self.__reset__ ()
+ self.title = _("Untitled")
+ self.mode = 0 # add new task
+ self.widget.set_title(_("Create a New Scheduled Task"))
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.__setup_calendar__ ()
+ self.button_add_template.show ()
+ self.widget.show_all ()
+ self.output = 0
+ self.cb_xoutput.set_active (0)
+
+ self.__update_textboxes__()
+
+ def showadd_template (self, transient, title, command, output):
+ self.button_save.set_label (gtk.STOCK_ADD)
+ self.__reset__ ()
+ self.title = title
+ self.command = command
+ self.mode = 0 # add new task
+ self.output = output
+ self.cb_xoutput.set_active (output)
+ self.widget.set_title(_("Create a New Scheduled Task"))
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.__setup_calendar__ ()
+ self.button_add_template.show ()
+ self.widget.show_all ()
+
+ self.__update_textboxes__()
+
+ def showedit_template (self, transient, id, title, command, output):
+ self.button_save.set_label (gtk.STOCK_ADD)
+ self.__reset__ ()
+ self.tid = id
+ self.title = title
+ self.command = command
+ self.mode = 2 # edit template
+ self.output = output
+ self.cb_xoutput.set_active (output)
+ self.widget.set_title(_("Edit template"))
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.__setup_calendar__ ()
+ self.widget.show_all ()
+
+ # hide time settings
+ self.at_vbox_time.hide ()
+
+ # save and cancel buttons
+ self.button_save.set_label (gtk.STOCK_SAVE)
+ self.button_add_template.hide ()
+
+ self.__update_textboxes__()
+
+ def shownew_template (self, transient):
+ self.button_save.set_label (gtk.STOCK_ADD)
+ self.__reset__ ()
+ self.tid = 0
+ self.mode = 2 # edit template
+ self.output = 0
+ self.cb_xoutput.set_active (0)
+ self.widget.set_title(_("New template"))
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.__setup_calendar__ ()
+ self.widget.show_all ()
+
+ # hide time settings
+ self.at_vbox_time.hide ()
+
+ # save and cancel buttons
+ self.button_save.set_label (gtk.STOCK_ADD)
+ self.button_add_template.hide ()
+
+ self.__update_textboxes__()
+
+ def showedit (self, transient, record, job_id, iter):
+ self.button_save.set_label (gtk.STOCK_APPLY)
+ self.mode = 1 # edit task
+ self.job_id = job_id
+ self.date = self.ParentClass.treemodel.get_value(iter, 9)
+ self.time = self.ParentClass.treemodel.get_value(iter, 12)
+ self.title = self.ParentClass.treemodel.get_value(iter, 0)
+ self.class_id = self.ParentClass.treemodel.get_value(iter, 10)
+ self.user = self.ParentClass.treemodel.get_value(iter, 11)
+ self.command = self.ParentClass.treemodel.get_value(iter, 3)
+ self.output = self.ParentClass.treemodel.get_value (iter, 15)
+ self.cb_xoutput.set_active (self.output)
+ # removing beginning newlines.. wherever they come from..
+ i = self.command.find ('\n', 0)
+ while i == 0:
+ self.command = self.command[1:]
+ i = self.command.find ('\n', 0)
+
+ #parse
+ (hour, minute, day, month, year) = self.__parse_time__(self.time, self.date)
+ self.runat = hour + minute + " " + day + "." + month + "." + year
+ self.spin_year.set_value (int (year))
+ self.spin_month.set_value (int (month))
+ self.spin_day.set_value (int (day))
+
+ self.spin_hour.set_value(int(hour))
+ self.spin_minute.set_value(int(minute))
+ self.widget.set_title(_("Edit a Scheduled Task"))
+
+ self.__update_textboxes__ ()
+ self.parentiter = iter
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.__setup_calendar__ ()
+ self.button_add_template.show ()
+ self.widget.show_all ()
+
+
+
+ def on_cal_lost_focus (self, *args):
+ self.__hide_calendar__ ()
+
+ def on_at_editor_size_changed (self, *args):
+ if self.cal_button.get_active ():
+ x, y = self.widget.get_position ()
+ height, width = self.widget.get_size ()
+ if ((x != self.x) or (y != self.y) or (height != self.height) or (width != self.width)):
+ self.__hide_calendar__ ()
+
+ def on_cb_xoutput_toggled (self, *args):
+ if self.cb_xoutput.get_active ():
+ self.output = 1
+ else:
+ self.output = 0
+
+ def on_cal_button_toggled (self, *args):
+ if self.cal_button.get_active ():
+ self.__show_calendar__ ()
+ else:
+ self.__hide_calendar__ ()
+
+
+ def __setup_calendar__ (self):
+ if self.cal_loaded == False:
+ self.xml.signal_connect ("on_cal_lost_focus", self.on_cal_lost_focus)
+ self.xml.signal_connect ("on_cal_window_destroy", self.__destroy_calendar__) # its actually not destroyed, but deleted
+
+ self.xml.signal_connect ("on_cal_day_selected_dc", self.on_cal_day_selected_dc)
+ self.xml.signal_connect ("on_cal_day_selected", self.on_cal_day_selected)
+
+ self.cal_window = self.xml.get_widget ("cal_window")
+ self.calendar = self.xml.get_widget ("calendar")
+ self.cal_window.hide_all ()
+ self.cal_loaded = True
+
+ def __destroy_calendar__ (self):
+ self.cal_window.hide_all ()
+ return True
+
+ def on_cal_day_selected (self, *args):
+ if self.cal_active:
+ year, month, day = self.calendar.get_date ()
+ self.spin_year.set_value (int (year))
+ self.spin_month.set_value (int (month) + 1)
+ self.spin_day.set_value (int (day))
+
+ def on_cal_day_selected_dc (self, *args):
+ self.__hide_calendar__ ()
+
+ def __show_calendar__ (self):
+ x, y = self.widget.window.get_origin ()
+ button_rect = self.cal_button.get_allocation ()
+ x = x + button_rect.x
+ y = y + button_rect.y + button_rect.height
+ self.cal_window.move (x, y)
+ self.widget.set_modal (False)
+ self.x, self.y = self.widget.get_position ()
+ self.height, self.width = self.widget.get_size ()
+ self.cal_active = False
+ self.calendar.select_month (self.spin_month.get_value_as_int () -1 , self.spin_year.get_value_as_int ())
+ self.calendar.select_day (self.spin_day.get_value_as_int ())
+ self.cal_active = True
+ self.cal_window.show_all ()
+
+ def __hide_calendar__ (self):
+ self.cal_window.hide_all ()
+ self.cal_button.set_active (False)
+ self.widget.set_modal (True)
+
+
+ def on_worded_label_event (self, *args):
+ #TODO highlight on mouseover
+ pass
+
+ def on_defined_label_event (self, *args):
+ #TODO highlight on mouseover
+ # enable control_option on click
+ pass
+
+ def on_text_task_popup_menu (self, *args):
+ #TODO show at_script_menuons: install t
+ # don't forget to attach eventhandling to this popup
+ pass
+
+
+
+ def on_text_task_change (self, *args):
+ start = self.text_task_buffer.get_start_iter()
+ end = self.text_task_buffer.get_end_iter()
+ self.command = self.text_task_buffer.get_text(start, end)
+
+
+ def on_entry_title_changed (self, *args):
+ self.title = self.entry_title.get_text()
+
+ def on_spin_day_changed (self, *args):
+ self.__check_spins__ ()
+ self.__update_time_cal__()
+
+ def on_spin_month_changed (self, *args):
+ self.__check_spins__ ()
+ self.__update_time_cal__()
+
+ def on_spin_year_changed (self, *args):
+ self.__check_spins__ ()
+ self.__update_time_cal__()
+
+ def on_spin_hour_changed (self, *args):
+ self.__check_spins__ ()
+ self.__update_time_cal__()
+
+ def on_spin_minute_changed (self, *args):
+ self.__check_spins__ ()
+ self.__update_time_cal__()
+
+ def __check_spins__ (self):
+ # Is additionally run every minute
+ if self.check_spin_running != True:
+ self.check_spin_running = True
+
+ ctime = time.localtime()
+ year = ctime[0]
+ month = ctime[1]
+ day = ctime[2]
+ hour = ctime[3]
+ minute = ctime[4]
+
+ cyear = False
+ cmonth = False
+ cday = False
+ chour = False
+
+ syear = self.spin_year.get_value_as_int ()
+ if (syear == year):
+ cyear = True
+
+ smonth = self.spin_month.get_value_as_int ()
+ mi, ma = self.spin_month.get_range ()
+ if cyear:
+ if (mi != month):
+ self.spin_month.set_range (month, 12)
+ mi = month
+ else:
+ if ((mi != 1) or (ma != 12)):
+ self.spin_month.set_range (1, 12)
+ if (mi <= smonth <= ma):
+ self.spin_month.set_value (smonth)
+ else:
+ if (smonth > ma):
+ self.spin_month.set_value (ma)
+ else:
+ self.spin_month.set_value (mi)
+ smonth = self.spin_month.get_value_as_int ()
+ if (smonth == month):
+ cmonth = True
+
+ sday = self.spin_day.get_value_as_int ()
+ mi, ma = self.spin_day.get_range ()
+ w, days = calendar.monthrange (syear, smonth)
+ if (cmonth and cyear):
+ if (mi != day):
+ self.spin_day.set_range (day, days)
+ mi = day
+ else:
+ if ((mi != 1) or (ma != days)):
+ self.spin_day.set_range (1, days)
+ if (mi <= sday <= days):
+ self.spin_day.set_value (sday)
+ else:
+ if (sday > days):
+ self.spin_day.set_value (days)
+ else:
+ self.spin_day.set_value (mi)
+ sday = self.spin_day.get_value_as_int ()
+ if (sday == day):
+ cday = True
+
+ shour = self.spin_hour.get_value_as_int ()
+ mi, ma = self.spin_hour.get_range ()
+ if (cyear and cmonth and cday):
+ if (mi != hour):
+ self.spin_hour.set_range (hour, 24)
+ mi = hour
+ else:
+ if ((mi != 0) or (ma != 24)):
+ self.spin_hour.set_range (0, 24)
+ if (mi <= shour <= ma):
+ self.spin_hour.set_value (shour)
+ else:
+ if (shour > ma):
+ self.spin_hour.set_value (ma)
+ else:
+ self.spin_hour.set_value (mi)
+ shour = self.spin_hour.get_value_as_int ()
+ if (shour == hour):
+ chour = True
+
+ sminute = self.spin_minute.get_value_as_int ()
+ mi, ma = self.spin_minute.get_range ()
+ if (cyear and cmonth and cday and chour):
+ if (mi != minute):
+ self.spin_minute.set_range (minute, 59)
+ mi = minute
+ else:
+ if ((mi != 0) or (ma != 59)):
+ self.spin_minute.set_range (0, 59)
+ if (mi <= sminute <= ma):
+ self.spin_minute.set_value (sminute)
+ else:
+ if (sminute > ma):
+ self.spin_minute.set_value (ma)
+ else:
+ self.spin_minute.set_value (mi)
+ self.check_spin_running = False
+
+
+ def __update_time_cal__ (self):
+ year = self.spin_year.get_text ()
+ month = self.spin_month.get_text ()
+ day = self.spin_day.get_text ()
+ hour = self.spin_hour.get_text()
+ minute = self.spin_minute.get_text()
+
+ year = str(year)
+
+ if hour.isdigit():
+ hour = int(hour)
+ else:
+ return False
+
+ if minute.isdigit():
+ minute = int(minute)
+ else:
+ return False
+
+ if day.isdigit ():
+ day = int (day)
+ else:
+ return False
+
+ if month.isdigit ():
+ month = int (month)
+ else:
+ return False
+
+ if year.isdigit () == False:
+ return False
+
+ if hour < 10:
+ hour = "0" + str(hour)
+ else:
+ hour = str(hour)
+
+ if minute < 10:
+ minute = "0" + str(minute)
+ else:
+ minute = str(minute)
+
+ if month < 10:
+ month = "0" + str(month)
+ else:
+ month = str(month)
+
+ if day < 10:
+ day = "0" + str(day)
+ else:
+ day = str(day)
+
+ self.runat = hour + minute + " " + day + "." + month + "." + year
+
+
+ def popup_error_no_digit (self, field):
+ box_popup = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("In one or both of the fields hour and minute there was entered a letter, or a number out of range. Remember an hour only has 60 minutes and a day only 24 hours."))
+ box_popup.set_response_sensitive(gtk.RESPONSE_OK, True)
+ run = box_popup.run ()
+ box_popup.hide ()
+ field.set_text ("0")
+
+
+ def __reset__ (self):
+ self.title = _("Untitled")
+ self.command = ""
+
+ ctime = time.localtime()
+ year = ctime[0]
+ month = ctime[1]
+ day = ctime[2]
+ hour = ctime[3]
+ minute = ctime[4]
+
+ self.output = 0
+
+ self.runat = str(hour) + str(minute) + " " + str(day) + "." + str(month) + "." + str (year)
+
+ self.spin_hour.set_value(int(hour))
+ self.spin_minute.set_value(int(minute))
+ self.spin_year.set_value (int (year))
+ self.spin_month.set_value (int (month))
+ self.spin_day.set_value (int (day))
+
+ self.__update_textboxes__ ()
+
+
+ def __update_textboxes__(self, update_runat = 1):
+
+ if self.title == None:
+ self.title = _("Untitled")
+
+ self.entry_title.set_text(self.title)
+ self.text_task_buffer.set_text(self.command)
+
+ def __parse_time__ (self, time, date):
+ regexp_date = re.compile("([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
+ regexp_time = re.compile("([0-9][0-9]):([0-9][0-9])")
+
+ time_g = regexp_time.match(time)
+ if time_g:
+ (hour, minute) = time_g.groups()
+
+ date_g = regexp_date.match(date)
+ if date_g:
+ (day, month, year) = date_g.groups()
+
+ return hour, minute, day, month, year
+
+
+ def on_button_cancel_clicked (self, *args):
+ self.__destroy_calendar__ ()
+ self.widget.hide()
+ return True
+
+
+ def __WrongRecordDialog__ (self, x):
+ self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is an invalid record! The problem could be: %s") % (x)))
+ self.wrongdialog.run()
+ self.wrongdialog.destroy()
+
+ def on_button_template_clicked (self, *args):
+ self.template.savetemplate_at (0, self.title, self.command, self.output)
+ self.widget.hide ()
+
+ def on_button_save_clicked (self, *args):
+ if self.mode == 2:
+ self.template.savetemplate_at (self.tid, self.title, self.command, self.output)
+ self.widget.hide ()
+ return
+
+ (validate, reason) = self.scheduler.checkfield(self.runat)
+ if validate == False:
+ self.__WrongRecordDialog__ (reason)
+ return
+
+ if (self.backend.get_not_inform_working_dir_at() != True):
+ dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nOne-time tasks will be run from the directory where Gnome schedule is run from (normally the home directory)."))
+ dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+ dia2.set_title (_("Warning: Working directory of executed tasks"))
+ response = dia2.run ()
+ if response == gtk.RESPONSE_CANCEL:
+ dia2.destroy ()
+ del dia2
+ return
+ elif response == gtk.RESPONSE_CLOSE:
+ self.backend.set_not_inform_working_dir_at (True)
+ else:
+ pass
+ dia2.destroy ()
+ del dia2
+
+ if self.mode == 1:
+ self.scheduler.update (self.job_id, self.runat, self.command, self.title, self.output)
+ else:
+ self.scheduler.append (self.runat, self.command, self.title, self.output)
+
+ self.ParentClass.schedule_reload ()
+
+ self.widget.hide ()
+
Modified: trunk/src/config.py.in
==============================================================================
--- trunk/src/config.py.in (original)
+++ trunk/src/config.py.in Sat Feb 14 21:20:56 2009
@@ -1,6 +1,8 @@
version = "@VERSION@"
image_dir = "@prefix@/share/pixmaps/gnome-schedule"
-glade_dir = "@prefix@/share/gnome-schedule"
+gs_dir = "@prefix@/share/gnome-schedule"
+glade_dir = gs_dir
+xwrapper_exec = "PYTHONPATH= PYTHONPATH@/gtk-2.0/:$PYTHONPATH @PYTHON@ @prefix@/share/gnome-schedule/xwrapper.py"
locale_dir = "@prefix@/share/locale"
crontabbin = "@CRONTAB_CONFIG@"
atbin = "@AT_CONFIG@"
Modified: trunk/src/crontab.py
==============================================================================
--- trunk/src/crontab.py (original)
+++ trunk/src/crontab.py Sat Feb 14 21:20:56 2009
@@ -29,709 +29,734 @@
class Crontab:
- def __init__(self,root,user,uid,gid, user_home_dir):
- #default preview length
- self.preview_len = 50
- self.root = root
- self.set_rights(user,uid,gid, user_home_dir)
- self.user_home_dir = user_home_dir
-
- self.nooutputtag = ">/dev/null 2>&1"
- self.crontabRecordRegex = re.compile('([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^#\n$]*)(\s#\s([^\n$]*)|$)')
- self.__setup_timespec__()
- self.env_vars = [ ]
-
- self.crontabdata = self.user_home_dir + "/.gnome/gnome-schedule/crontab"
- self.crontabdatafileversion = 3
-
- if os.path.exists (self.user_home_dir + "/.gnome") != True:
- os.mkdir (self.user_home_dir + "/.gnome", 0700)
- os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
- if os.path.exists(self.crontabdata) != True:
- try:
- os.makedirs(self.crontabdata, 0700)
- if self.root == 1:
- os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
- os.chown (self.crontabdata, self.uid, self.gid)
- except:
- print _("Failed to create data dir! Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.")
-
-
-
- def __setup_timespec__ (self):
- self.special = {
- "@reboot" : '@reboot',
- "@hourly" : '0 * * * *',
- "@daily" : '0 0 * * *',
- "@weekly" : '0 0 * * 0',
- "@monthly" : '0 0 1 * *',
- "@yearly" : '0 0 1 1 *',
- "@annually": '0 0 1 1 *',
- "@midnight": '0 0 * * *'
- }
-
- self.timeranges = {
- "minute" : range(0,60),
- "hour" : range(0,24),
- "day" : range(1,32),
- "month" : range(1,13),
- "weekday" : range(0,8)
- }
-
- self.timenames = {
- "minute" : _("Minute"),
- "hour" : _("Hour"),
- "day" : _("Day of Month"),
- "month" : _("Month"),
- "weekday" : _("Weekday")
- }
-
- self.monthnames = {
- "1" : "jan",
- "2" : "feb",
- "3" : "mar",
- "4" : "apr",
- "5" : "may",
- "6" : "jun",
- "7" : "jul",
- "8" : "aug",
- "9" : "sep",
- "10" : "oct",
- "11" : "nov",
- "12" : "dec"
- }
- self.monthnumbers = {
- "jan" : "1",
- "feb" : "2",
- "mar" : "3",
- "apr" : "4",
- "may" : "5",
- "jun" : "6",
- "jul" : "7",
- "aug" : "8",
- "sep" : "9",
- "oct" : "10",
- "nov" : "11",
- "dec" : "12"
- }
-
- self.downames = {
- "0" : "sun",
- "1" : "mon",
- "2" : "tue",
- "3" : "wed",
- "4" : "thu",
- "5" : "fri",
- "6" : "sat",
- "7" : "sun"
- }
-
- self.downumbers = {
- "sun" : "0",
- "mon" : "1",
- "tue" : "2",
- "wed" : "3",
- "thu" : "4",
- "fri" : "5",
- "sat" : "6",
- "sun" : "7"
- }
-
-
- def set_rights(self,user,uid,gid, ud):
- self.user = user
- self.uid = uid
- self.gid = gid
- self.user_home_dir = ud
- self.crontabdata = self.user_home_dir + "/.gnome/gnome-schedule/crontab"
- if os.path.exists (self.user_home_dir + "/.gnome") != True:
- os.mkdir (self.user_home_dir + "/.gnome", 0700)
- os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
- if os.path.exists(self.crontabdata) != True:
- try:
- os.makedirs(self.crontabdata, 0700)
- if self.root == 1:
- os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
- os.chown (self.crontabdata, self.uid, self.gid)
- except:
- print (_("Failed to create data dir: %s. Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.") % (self.crontabdata))
-
- def get_type (self):
- return "crontab"
-
- def checkfield (self, expr, type):
- """Verifies format of Crontab timefields
-
- Checks a single Crontab time expression.
- At first possibly contained alias names will be replaced by their
- corresponding numbers. After that every asterisk will be replaced by
- a "first to last" expression. Then the expression will be splitted
- into the comma separated subexpressions.
-
- Each subexpression will run through:
- 1. Check for stepwidth in range (if it has one)
- 2. Check for validness of range-expression (if it is one)
- 3. If it is no range: Check for simple numeric
- 4. If it is numeric: Check if it's in range
-
- If one of this checks failed, an exception is raised. Otherwise it will
- do nothing. Therefore this function should be used with
- a try/except construct.
- """
-
- # reboot?
- if type == "special":
- if expr in self.special:
- pass
- else:
- raise ValueError ("special", _("Basic"), _("This is not a valid special record: %(record)s") % {"record": expr})
- else:
- timerange = self.timeranges[type]
-
- # Replace alias names only if no leading and following alphanumeric and
- # no leading slash is present. Otherwise terms like "JanJan" or
- # "1Feb" would give a valid check. Values after a slash are stepwidths
- # and shouldn't have an alias.
- if type == "month": alias = self.monthnames.copy()
- elif type == "weekday": alias = self.downames.copy()
- else: alias = None
- if alias != None:
- while True:
- try: key,value = alias.popitem()
- except KeyError: break
- expr = re.sub("(?<!\w|/)" + value + "(?!\w)", key, expr)
-
- expr = expr.replace("*", str(min(timerange)) + "-" + str(max(timerange)) )
-
- list = expr.split(",")
- rexp_step = re.compile("^(\d+-\d+)/(\d+)$")
- rexp_range = re.compile("^(\d+)-(\d+)$")
-
- for field in list:
- result = rexp_step.match(field)
- if result != None:
- field = result.groups()[0]
- if int(result.groups()[1]) not in timerange:
- raise ValueError("stepwidth", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
-
- result = rexp_range.match(field)
- if (result != None):
- if (int(result.groups()[0]) not in timerange) or (int(result.groups()[1]) not in timerange):
- raise ValueError("range", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
- elif field.isdigit() != True:
- raise ValueError("fixed", self.timenames[type], _("%s is not a number") % ( field ) )
- elif int(field) not in timerange:
- raise ValueError("fixed", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
-
-
- def update (self, minute, hour, day, month, weekday, command, linenumber, parentiter, nooutput, job_id, comment, title, desc):
- if self.check_command (command) == False:
- return False
-
- # update crontab
- if minute == "@reboot":
- record = "@reboot " + command
- else:
- record = minute + " " + hour + " " + day + " " + month + " " + weekday + " " + command
- #print "crontab:update:record=" + record
-
- easystring = self.__easy__ (minute, hour, day, month, weekday)
-
- if nooutput:
- record = record + " " + self.nooutputtag
-
- if comment:
- record = record + " #" + comment
-
- if job_id == False:
- ## Create a job_id for an existing task
- f = os.path.join (self.crontabdata, "last_id")
- if os.access (f, os.R_OK):
- fh = open (f, 'r+')
- r = fh.read ()
- if r == "":
- last_id = 1
- else:
- last_id = int (r)
-
- #print "last_id" + str (last_id)
- job_id = last_id + 1
- #print "job_id" + str (job_id)
- fh.seek (0)
- fh.truncate (1)
- fh.write ( str(job_id))
- fh.close ()
- else:
- job_id = 1
- fh = open (f, 'w')
- fh.write ('1')
- fh.close ()
-
- os.chown (f, self.uid, self.gid)
- os.chmod (f, 0600)
-
- record = record + " # JOB_ID_" + str (job_id)
-
-
- if title == None:
- title = _("Untitled")
-
- f = os.path.join (self.crontabdata, str(job_id))
- #print f
- fh = open (f, 'w')
- fh.truncate (1)
- fh.seek (0)
- fh.write ("ver=" + str(self.crontabdatafileversion) + "\n")
- fh.write ("title=" + title + "\n")
- fh.write ("desc=" + desc + "\n")
- if nooutput:
- fh.write ("nooutput=1\n")
- else:
- fh.write ("nooutput=0\n")
- fh.close ()
- os.chown (f, self.uid, self.gid)
- os.chmod (f, 0600)
-
- self.lines[linenumber] = record
-
- # TODO: let write trow an exception if failed
- self.__write__ ()
-
-
- def delete (self, linenumber, iter, job_id):
- # delete file
- f = os.path.join (self.crontabdata, job_id)
- if os.access(f, os.F_OK):
- os.unlink (f)
-
- number = 0
- newlines = list ()
- for line in self.lines:
- if number != linenumber:
- newlines.append (line)
- number = number + 1
-
- self.lines = newlines
- # TODO: let write trow an exception if failed
- self.__write__ ()
-
-
- def append (self, minute, hour, day, month, weekday, command, nooutput, title, desc = None):
- if self.check_command (command) == False:
- return False
-
- if minute == "@reboot":
- record = "@reboot " + command
- else:
- record = minute + " " + hour + " " + day + " " + month + " " + weekday + " " + command
-
- if nooutput:
- space = " "
- if record[len(record)-1] == " ":
- space = ""
- record = record + space + self.nooutputtag
-
- if title == None:
- title = _("Untitled")
-
- if desc == None:
- desc = ""
-
- # Create and write data file
- f = os.path.join (self.crontabdata, "last_id")
- if os.access (f, os.R_OK):
- fh = open (f, 'r+')
- r = fh.read ()
- if r == "":
- last_id = 1
- else:
- last_id = int (r)
-
-
- job_id = last_id + 1
-
- fh.seek (0)
- fh.truncate (1)
- fh.write ( str(job_id))
- fh.close ()
- else:
- job_id = 1
- fh = open (f, 'w')
- fh.write ('1')
- fh.close ()
-
- os.chown (f, self.uid, self.gid)
- os.chmod (f, 0600)
-
- f = os.path.join (self.crontabdata, str(job_id))
-
- fh = open (f, 'w')
- fh.truncate (1)
- fh.seek (0)
- fh.write ("ver=" + str(self.crontabdatafileversion) + "\n")
- fh.write ("title=" + title + "\n")
- fh.write ("desc=" + desc + "\n")
- if nooutput:
- fh.write ("nooutput=1\n")
- else:
- fh.write ("nooutput=0\n")
-
- fh.close ()
- os.chown (f, self.uid, self.gid)
- os.chmod (f, 0600)
-
- record = record + " # JOB_ID_" + str (job_id)
-
- self.lines.append (record)
-
- # TODO: let write trow an exception if failed
- self.__write__ ()
-
-
- #check command for problems
- def check_command (self, command):
- # check if % is part of the command and if it is escaped, and the escapor not escaped.
- i = command.find ("%")
- while i != -1:
- escaped = 0
- part = command[0:i]
- command = command[i + 1:]
- e = part.rfind ("\\")
- while (e != -1) and (e == len(part) - 1):
- escaped = escaped + 1
- part = part[0:len(part) - 1]
- e = part.rfind ("\\")
-
- if (escaped % 2 == 0):
- return False
-
- i = command.find ("%")
- return True
-
- #read tasks in crontab
- def read (self):
-
- data = []
-
- if self.root:
- execute = config.getCrontabbin () + " -l -u " + self.user
- else:
- execute = config.getCrontabbin () + " -l"
-
- linecount = 0
- self.lines = os.popen(execute).readlines()
- for line in self.lines:
- #read line and get info
- array_or_false = self.parse (line)
- if array_or_false != False:
- if array_or_false[0] == 2:
- (minute, hour, day, month, weekday, command, comment, job_id, title, desc, nooutput) = array_or_false[1]
-
- time = minute + " " + hour + " " + day + " " + month + " " + weekday
-
- #make the command smaller if the lenght is to long
- preview = self.__make_preview__ (command)
-
- #add task to treemodel in mainWindow
- if minute == "@reboot":
- data.append([title, self.__easy__ (minute, hour, day, month, weekday), preview, line, linecount, time, self, None, job_id, "", "","", _("Recurrent"), "crontab", nooutput, _("At reboot")])
- else:
- data.append([title, self.__easy__ (minute, hour, day, month, weekday), preview, line, linecount, time, self, None, job_id, "", "","", _("Recurrent"), "crontab", nooutput, time])
-
-
- linecount = linecount + 1
-
-
- return data
-
-
- def translate_frequency (self, frequency):
-
- if frequency == "minute":
- return _("minute")
- if frequency == "hour":
- return _("hour")
- if frequency == "day":
- return _("day")
- if frequency == "month":
- return _("month")
- if frequency == "weekday":
- return _("weekday")
-
- return frequency
-
-
- #get info out of task line
- def parse (self, line, nofile = False):
- # nofile: no datafile for title and icon available
-
- # Format of gnome-schedule job line
- # * * * * * ls -l >/dev/null >2&1 # JOB_ID_1
-
- # Return types
- # 0: Special expression
- # 1: Enivornment variable
- # 2: Standard expression
- # 3: Comment
-
- origline = line
- line = line.lstrip()
- comment = ""
-
-
- if line != "":
- #print "Parsing line: " + line
- if line[0] == "#":
- comment = line[1:]
- line = ""
- return [3, comment]
- else:
- if (line.find ('#') != -1):
- line, comment = line.rsplit('#', 1)
-
- comment = comment.strip ()
- line = line.strip ()
-
- if line == "":
- #Empty
- if comment != "":
- return [3, comment]
- else:
- return False
- #special expressions
- elif line[0] == "@":
- special_expression, line = self.get_exp_sec (line)
-
- if special_expression == "@reboot":
- minute = "@reboot"
- hour = "@reboot"
- dom = "@reboot"
- moy = "@reboot"
- dow = "@reboot"
- else:
-
- if special_expression in self.special:
- expr = self.special[special_expression]
- line = expr + " " + line
-
- # Minute
- minute, line = self.get_exp_sec (line)
-
- # Hour
- hour, line = self.get_exp_sec (line)
-
- # Day of Month
- dom, line = self.get_exp_sec (line)
-
- # Month of Year
- moy, line = self.get_exp_sec (line)
-
- # Day of Week
- dow, line = self.get_exp_sec (line)
-
-
- elif (line[0].isalpha()):
- if line[0] != '*':
- #ENVIRONMENT VARIABLE
- return [1, line]
- else:
- # Minute
- minute, line = self.get_exp_sec (line)
-
- # Hour
- hour, line = self.get_exp_sec (line)
-
- # Day of Month
- dom, line = self.get_exp_sec (line)
- # Crontab bug? Let's not support
- # dom behaves like minute
- """
- dom = self.day
- if dom.isdigit() == False:
- dom = dom.lower ()
- for day in self.scheduler.downumbers:
- dom = dom.replace (day, self.scheduler.downumbers[day])
- """
- try:
- self.checkfield (dom, "day")
- except ValueError, ex:
- print _("Failed to parse the Day of Month field, possibly due to a bug in crontab.")
- return
-
- # Month of Year
- moy, line = self.get_exp_sec (line)
- if moy.isdigit () == False:
- moy = moy.lower ()
- for m in self.monthnumbers:
- moy = moy.replace (m, self.monthnumbers[m])
-
-
- # Day of Week
- dow, line = self.get_exp_sec (line)
- if dow.isdigit() == False:
- dow = dow.lower ()
- for day in self.downumbers:
- dow = dow.replace (day, self.downumbers[day])
-
-
-
- command = line.strip ()
-
- # Retrive jobid
- i = comment.find ('JOB_ID_')
- if (i != -1):
- job_id = int (comment[i + 7:].rstrip ())
- else:
- job_id = False
-
- # Retrive title and icon data
- if nofile == False:
- if job_id:
- ver, title, desc, nooutput = self.get_job_data (job_id)
- else:
- ver = 1
- title = ""
- desc = ""
- nooutput = 0
-
- if nooutput != 0:
- # remove devnull part of command
- # searching reverse, and only if nooutput is saved in the datafile
- pos = command.rfind (self.nooutputtag)
- if pos != -1:
- command = command[:pos]
-
- # support older datafiles/entries without removing the no output tag
- if ver <= 1:
- # old version, no output declaration in datafile, migration
- pos = command.rfind (self.nooutputtag)
- if pos != -1:
- command = command[:pos]
- nooutput = 1
- else:
- nooutput = 0
-
- command = command.strip ()
-
-
- return [2, [minute, hour, dom, moy, dow, command, comment, job_id, title, desc, nooutput]]
- else:
- return minute, hour, dom, moy, dow, command
-
- def get_job_data (self, job_id):
- f = os.path.join (self.crontabdata, str (job_id))
- if os.access (f, os.R_OK):
- fh = open (f, 'r')
- d = fh.read ()
-
- ver_p = d.find ("ver=")
- if ver_p == -1:
- ver = 1
- else:
- ver_s = d[ver_p + 4:d.find ("\n")]
- d = d[d.find ("\n") + 1:]
- ver = int (ver_s)
-
- title = d[6:d.find ("\n")]
- d = d[d.find ("\n") + 1:]
-
- if ver < 3:
- # not in use
- icon = d[5:d.find ("\n")]
- d = d[d.find ("\n") + 1:]
-
- desc = d[5:d.find ("\n")]
- d = d[d.find ("\n") + 1:]
-
- if ver >= 2:
- nooutput_str = d[9:d.find ("\n")]
- if (nooutput_str == "0") or (nooutput_str == "1"):
- nooutput = int (nooutput_str)
- else:
- nooutput = 0
- else:
- nooutput = 0
-
- fh.close ()
-
- return ver, title, desc, nooutput
-
-
- else:
- return "", "", "", 0
-
-
-
-
- def get_exp_sec (self, line):
- line = line.lstrip ()
- #print "line: \"" + line + "\""
-
- ## find next whitespace
- i = 0
- found = False
- while (i <= len(line)) and (found == False):
- if line[i] in string.whitespace:
- found = True
- #print "found: " + str (i)
- else:
- i = i + 1
- sec = line[0:i]
- #print "sec: \"" + sec + "\""
- line = line[i + 1:]
- return sec, line
-
- def __easy__ (self, minute, hour, day, month, weekday):
- return lang.translate_crontab_easy (minute, hour, day, month, weekday)
-
-
- #create temp file with old tasks and new ones and then update crontab
- def __write__ (self):
- tmpfile = tempfile.mkstemp ()
- fd, path = tmpfile
- tmp = os.fdopen(fd, 'w')
- count = 0
- for line in self.lines:
-
- ## Ignore the first three comments:
-
- ## DO NOT EDIT THIS FILE - edit the master and reinstall.
- ## (/tmp/crontab.XXXXXX installed on Xxx Xxx x xx:xx:xx xxxx)
- ## (Cron version -- $Id$)
-
- if not (count < 3 and len(line) > 1 and line[0] == "#"):
- tmp.write (line)
- if line[len(line)-1] != '\n':
- tmp.write ("\n")
- count = count + 1
-
- tmp.close ()
-
- #replace crontab config with new one in file
- if self.root:
- # print config.getCrontabbin () + " -u " + self.ParentClass.user + " " + path
- os.system (config.getCrontabbin () + " " + path + " -u " + self.user)
- else:
- # print config.getCrontabbin () + " " + path
- os.system (config.getCrontabbin () + " " + path)
-
- os.unlink (path)
-
-
- #TODO: check into
- #if a command his lenght is to long the last part is removed
- def __make_preview__ (self, str, preview_len = 0):
- if preview_len == 0:
- preview_len = self.preview_len
- cnt = 0
- result = ""
- for a in str:
- if cnt <= preview_len:
- result = result + a
- cnt = cnt + 1
- if cnt > preview_len:
- result = result + "..."
+ def __init__(self,root,user,uid,gid, user_home_dir):
+ #default preview length
+ self.preview_len = 50
+ self.root = root
+ self.set_rights(user,uid,gid, user_home_dir)
+ self.user_home_dir = user_home_dir
+
+ self.output = ["",
+ ">/dev/null 2>&1",
+ config.gs_dir + "/xwrapper.py",
+ ">/dev/null 2>&1",
+ ]
+
+ self.crontabRecordRegex = re.compile('([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^#\n$]*)(\s#\s([^\n$]*)|$)')
+ self.__setup_timespec__()
+ self.env_vars = [ ]
+
+ self.crontabdata = self.user_home_dir + "/.gnome/gnome-schedule/crontab"
+ self.crontabdatafileversion = 5
+
+ if os.path.exists (self.user_home_dir + "/.gnome") != True:
+ os.mkdir (self.user_home_dir + "/.gnome", 0700)
+ os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
+ if os.path.exists(self.crontabdata) != True:
+ try:
+ os.makedirs(self.crontabdata, 0700)
+ if self.root == 1:
+ os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
+ os.chown (self.crontabdata, self.uid, self.gid)
+ except:
+ print _("Failed to create data dir! Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.")
+
+
+
+ def __setup_timespec__ (self):
+ self.special = {
+ "@reboot" : '@reboot',
+ "@hourly" : '0 * * * *',
+ "@daily" : '0 0 * * *',
+ "@weekly" : '0 0 * * 0',
+ "@monthly" : '0 0 1 * *',
+ "@yearly" : '0 0 1 1 *',
+ "@annually": '0 0 1 1 *',
+ "@midnight": '0 0 * * *'
+ }
+
+ self.timeranges = {
+ "minute" : range(0,60),
+ "hour" : range(0,24),
+ "day" : range(1,32),
+ "month" : range(1,13),
+ "weekday" : range(0,8)
+ }
+
+ self.timenames = {
+ "minute" : _("Minute"),
+ "hour" : _("Hour"),
+ "day" : _("Day of Month"),
+ "month" : _("Month"),
+ "weekday" : _("Weekday")
+ }
+
+ self.monthnames = {
+ "1" : "jan",
+ "2" : "feb",
+ "3" : "mar",
+ "4" : "apr",
+ "5" : "may",
+ "6" : "jun",
+ "7" : "jul",
+ "8" : "aug",
+ "9" : "sep",
+ "10" : "oct",
+ "11" : "nov",
+ "12" : "dec"
+ }
+ self.monthnumbers = {
+ "jan" : "1",
+ "feb" : "2",
+ "mar" : "3",
+ "apr" : "4",
+ "may" : "5",
+ "jun" : "6",
+ "jul" : "7",
+ "aug" : "8",
+ "sep" : "9",
+ "oct" : "10",
+ "nov" : "11",
+ "dec" : "12"
+ }
+
+ self.downames = {
+ "0" : "sun",
+ "1" : "mon",
+ "2" : "tue",
+ "3" : "wed",
+ "4" : "thu",
+ "5" : "fri",
+ "6" : "sat",
+ "7" : "sun"
+ }
+
+ self.downumbers = {
+ "sun" : "0",
+ "mon" : "1",
+ "tue" : "2",
+ "wed" : "3",
+ "thu" : "4",
+ "fri" : "5",
+ "sat" : "6",
+ "sun" : "7"
+ }
+
+
+ def set_rights(self,user,uid,gid, ud):
+ self.user = user
+ self.uid = uid
+ self.gid = gid
+ self.user_home_dir = ud
+ self.crontabdata = self.user_home_dir + "/.gnome/gnome-schedule/crontab"
+ if os.path.exists (self.user_home_dir + "/.gnome") != True:
+ os.mkdir (self.user_home_dir + "/.gnome", 0700)
+ os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
+ if os.path.exists(self.crontabdata) != True:
+ try:
+ os.makedirs(self.crontabdata, 0700)
+ if self.root == 1:
+ os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
+ os.chown (self.crontabdata, self.uid, self.gid)
+ except:
+ print (_("Failed to create data dir: %s. Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.") % (self.crontabdata))
+
+ def get_type (self):
+ return "crontab"
+
+ def checkfield (self, expr, type):
+ """Verifies format of Crontab timefields
+
+ Checks a single Crontab time expression.
+ At first possibly contained alias names will be replaced by their
+ corresponding numbers. After that every asterisk will be replaced by
+ a "first to last" expression. Then the expression will be splitted
+ into the comma separated subexpressions.
+
+ Each subexpression will run through:
+ 1. Check for stepwidth in range (if it has one)
+ 2. Check for validness of range-expression (if it is one)
+ 3. If it is no range: Check for simple numeric
+ 4. If it is numeric: Check if it's in range
+
+ If one of this checks failed, an exception is raised. Otherwise it will
+ do nothing. Therefore this function should be used with
+ a try/except construct.
+ """
+
+ # reboot?
+ if type == "special":
+ if expr in self.special:
+ pass
+ else:
+ raise ValueError ("special", _("Basic"), _("This is not a valid special record: %(record)s") % {"record": expr})
+ else:
+ timerange = self.timeranges[type]
+
+ # Replace alias names only if no leading and following alphanumeric and
+ # no leading slash is present. Otherwise terms like "JanJan" or
+ # "1Feb" would give a valid check. Values after a slash are stepwidths
+ # and shouldn't have an alias.
+ if type == "month": alias = self.monthnames.copy()
+ elif type == "weekday": alias = self.downames.copy()
+ else: alias = None
+ if alias != None:
+ while True:
+ try: key,value = alias.popitem()
+ except KeyError: break
+ expr = re.sub("(?<!\w|/)" + value + "(?!\w)", key, expr)
+
+ expr = expr.replace("*", str(min(timerange)) + "-" + str(max(timerange)) )
+
+ list = expr.split(",")
+ rexp_step = re.compile("^(\d+-\d+)/(\d+)$")
+ rexp_range = re.compile("^(\d+)-(\d+)$")
+
+ for field in list:
+ result = rexp_step.match(field)
+ if result != None:
+ field = result.groups()[0]
+ if int(result.groups()[1]) not in timerange:
+ raise ValueError("stepwidth", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
+
+ result = rexp_range.match(field)
+ if (result != None):
+ if (int(result.groups()[0]) not in timerange) or (int(result.groups()[1]) not in timerange):
+ raise ValueError("range", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
+ elif field.isdigit() != True:
+ raise ValueError("fixed", self.timenames[type], _("%s is not a number") % ( field ) )
+ elif int(field) not in timerange:
+ raise ValueError("fixed", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
+
+
+ def update (self, minute, hour, day, month, weekday, command, linenumber, parentiter, output, job_id, comment, title, desc):
+ if self.check_command (command) == False:
+ return False
+
+ # update crontab
+
+ easystring = self.__easy__ (minute, hour, day, month, weekday)
+
+ if job_id == False:
+ ## Create a job_id for an existing task
+ f = os.path.join (self.crontabdata, "last_id")
+ if os.access (f, os.R_OK):
+ fh = open (f, 'r+')
+ r = fh.read ()
+ if r == "":
+ last_id = 1
+ else:
+ last_id = int (r)
+
+ #print "last_id" + str (last_id)
+ job_id = last_id + 1
+ #print "job_id" + str (job_id)
+ fh.seek (0)
+ fh.truncate (1)
+ fh.write ( str(job_id))
+ fh.close ()
+ else:
+ job_id = 1
+ fh = open (f, 'w')
+ fh.write ('1')
+ fh.close ()
+
+ os.chown (f, self.uid, self.gid)
+ os.chmod (f, 0600)
+
+ record = command
+ display = "0"
+ if output == 1:
+ space = " "
+ if record[len(record)-1] == " ":
+ space = ""
+ record = record + space + self.output[1]
+ elif (output == 2) or (output == 3):
+ display = os.getenv ('DISPLAY')
+ record = config.xwrapper_exec + " c " + str (job_id)
+ if output == 3:
+ record = record + " " + self.output [3]
+
+ if minute == "@reboot":
+ record = "@reboot " + record
+ else:
+ record = minute + " " + hour + " " + day + " " + month + " " + weekday + " " + record
+
+ record = record + " # JOB_ID_" + str (job_id)
+
+ if title == None:
+ title = _("Untitled")
+
+ f = os.path.join (self.crontabdata, str(job_id))
+ #print f
+ fh = open (f, 'w')
+ fh.truncate (1)
+ fh.seek (0)
+ fh.write ("ver=" + str(self.crontabdatafileversion) + "\n")
+ fh.write ("title=" + title + "\n")
+ fh.write ("desc=" + desc + "\n")
+ fh.write ("output=" + str (output) + "\n")
+ fh.write ("display=" + display + "\n")
+ fh.write ("command_d=" + command + "\n")
+ fh.close ()
+ os.chown (f, self.uid, self.gid)
+ os.chmod (f, 0600)
+
+ self.lines[linenumber] = record
+
+ # TODO: let write trow an exception if failed
+ self.__write__ ()
+
+
+ def delete (self, linenumber, iter, job_id):
+ # delete file
+ f = os.path.join (self.crontabdata, job_id)
+ if os.access(f, os.F_OK):
+ os.unlink (f)
+
+ number = 0
+ newlines = list ()
+ for line in self.lines:
+ if number != linenumber:
+ newlines.append (line)
+ number = number + 1
+
+ self.lines = newlines
+ # TODO: let write trow an exception if failed
+ self.__write__ ()
+
+
+ def append (self, minute, hour, day, month, weekday, command, output, title, desc = None):
+ if self.check_command (command) == False:
+ return False
+
+ if title == None:
+ title = _("Untitled")
+
+ if desc == None:
+ desc = ""
+
+ # Create and write data file
+ f = os.path.join (self.crontabdata, "last_id")
+ if os.access (f, os.R_OK):
+ fh = open (f, 'r+')
+ r = fh.read ()
+ if r == "":
+ last_id = 1
+ else:
+ last_id = int (r)
+
+
+ job_id = last_id + 1
+
+ fh.seek (0)
+ fh.truncate (1)
+ fh.write ( str(job_id))
+ fh.close ()
+ else:
+ job_id = 1
+ fh = open (f, 'w')
+ fh.write ('1')
+ fh.close ()
+
+ os.chown (f, self.uid, self.gid)
+ os.chmod (f, 0600)
+
+ record = command
+ display = "0"
+ if output == 1:
+ space = " "
+ if record[len(record)-1] == " ":
+ space = ""
+ record = record + space + self.output[1]
+ elif (output == 2) or (output == 3):
+ display = os.getenv ('DISPLAY')
+ record = config.xwrapper_exec + " c " + str (job_id)
+ if output == 3:
+ record = record + " " + self.output [3]
+
+ if minute == "@reboot":
+ record = "@reboot " + record
+ else:
+ record = minute + " " + hour + " " + day + " " + month + " " + weekday + " " + record
+
+ record = record + " # JOB_ID_" + str (job_id)
+
+ self.lines.append (record)
+
+ f = os.path.join (self.crontabdata, str(job_id))
+ fh = open (f, 'w')
+ fh.truncate (1)
+ fh.seek (0)
+ fh.write ("ver=" + str(self.crontabdatafileversion) + "\n")
+ fh.write ("title=" + title + "\n")
+ fh.write ("desc=" + desc + "\n")
+ fh.write ("output=" + str(output) + "\n")
+ fh.write ("display=" + display + "\n")
+ fh.write ("command_d=" + command + "\n")
+ fh.close ()
+ os.chown (f, self.uid, self.gid)
+ os.chmod (f, 0600)
+ # TODO: let write trow an exception if failed
+ self.__write__ ()
+
+
+ #check command for problems
+ def check_command (self, command):
+ # check if % is part of the command and if it is escaped, and the escapor not escaped.
+ i = command.find ("%")
+ while i != -1:
+ escaped = 0
+ part = command[0:i]
+ command = command[i + 1:]
+ e = part.rfind ("\\")
+ while (e != -1) and (e == len(part) - 1):
+ escaped = escaped + 1
+ part = part[0:len(part) - 1]
+ e = part.rfind ("\\")
+
+ if (escaped % 2 == 0):
+ return False
+
+ i = command.find ("%")
+ return True
+
+ #read tasks in crontab
+ def read (self):
+
+ data = []
+
+ if self.root:
+ execute = config.getCrontabbin () + " -l -u " + self.user
+ else:
+ execute = config.getCrontabbin () + " -l"
+
+ linecount = 0
+ self.lines = os.popen(execute).readlines()
+ for line in self.lines:
+ #read line and get info
+ array_or_false = self.parse (line)
+ if array_or_false != False:
+ if array_or_false[0] == 2:
+ (minute, hour, day, month, weekday, command, comment, job_id, title, desc, output, display) = array_or_false[1]
+
+ time = minute + " " + hour + " " + day + " " + month + " " + weekday
+
+ #make the command smaller if the lenght is to long
+ preview = self.__make_preview__ (command)
+
+ #add task to treemodel in mainWindow
+ if minute == "@reboot":
+ data.append([title, self.__easy__ (minute, hour, day, month, weekday), preview, line, linecount, time, self, None, job_id, "", "","", _("Recurrent"), "crontab", output, _("At reboot")])
+ else:
+ data.append([title, self.__easy__ (minute, hour, day, month, weekday), preview, line, linecount, time, self, None, job_id, "", "","", _("Recurrent"), "crontab", output, time])
+
+
+ linecount = linecount + 1
+
+
+ return data
+
+
+ def translate_frequency (self, frequency):
+
+ if frequency == "minute":
+ return _("minute")
+ if frequency == "hour":
+ return _("hour")
+ if frequency == "day":
+ return _("day")
+ if frequency == "month":
+ return _("month")
+ if frequency == "weekday":
+ return _("weekday")
+
+ return frequency
+
+
+ #get info out of task line
+ def parse (self, line, nofile = False):
+ # nofile: no datafile for title and icon available
+
+ # Format of gnome-schedule job line
+ # * * * * * ls -l >/dev/null >2&1 # JOB_ID_1
+
+ # Return types
+ # 0: Special expression
+ # 1: Enivornment variable
+ # 2: Standard expression
+ # 3: Comment
+
+ origline = line
+ line = line.lstrip()
+ comment = ""
+
+
+ if line != "":
+ #print "Parsing line: " + line
+ if line[0] == "#":
+ comment = line[1:]
+ line = ""
+ return [3, comment]
+ else:
+ if (line.find ('#') != -1):
+ line, comment = line.rsplit('#', 1)
+
+ comment = comment.strip ()
+ line = line.strip ()
+
+ if line == "":
+ #Empty
+ if comment != "":
+ return [3, comment]
+ else:
+ return False
+ #special expressions
+ elif line[0] == "@":
+ special_expression, line = self.get_exp_sec (line)
+
+ if special_expression == "@reboot":
+ minute = "@reboot"
+ hour = "@reboot"
+ dom = "@reboot"
+ moy = "@reboot"
+ dow = "@reboot"
+ else:
+
+ if special_expression in self.special:
+ expr = self.special[special_expression]
+ line = expr + " " + line
+
+ # Minute
+ minute, line = self.get_exp_sec (line)
+
+ # Hour
+ hour, line = self.get_exp_sec (line)
+
+ # Day of Month
+ dom, line = self.get_exp_sec (line)
+
+ # Month of Year
+ moy, line = self.get_exp_sec (line)
+
+ # Day of Week
+ dow, line = self.get_exp_sec (line)
+
+
+ elif (line[0].isalpha()):
+ if line[0] != '*':
+ #ENVIRONMENT VARIABLE
+ return [1, line]
+ else:
+ # Minute
+ minute, line = self.get_exp_sec (line)
+
+ # Hour
+ hour, line = self.get_exp_sec (line)
+
+ # Day of Month
+ dom, line = self.get_exp_sec (line)
+ # Crontab bug? Let's not support
+ # dom behaves like minute
+ """
+ dom = self.day
+ if dom.isdigit() == False:
+ dom = dom.lower ()
+ for day in self.scheduler.downumbers:
+ dom = dom.replace (day, self.scheduler.downumbers[day])
+ """
+ try:
+ self.checkfield (dom, "day")
+ except ValueError, ex:
+ print _("Failed to parse the Day of Month field, possibly due to a bug in crontab.")
+ return
+
+ # Month of Year
+ moy, line = self.get_exp_sec (line)
+ if moy.isdigit () == False:
+ moy = moy.lower ()
+ for m in self.monthnumbers:
+ moy = moy.replace (m, self.monthnumbers[m])
+
+
+ # Day of Week
+ dow, line = self.get_exp_sec (line)
+ if dow.isdigit() == False:
+ dow = dow.lower ()
+ for day in self.downumbers:
+ dow = dow.replace (day, self.downumbers[day])
+
+
+
+ command = line.strip ()
+
+ # Retrive jobid
+ i = comment.find ('JOB_ID_')
+ if (i != -1):
+ job_id = int (comment[i + 7:].rstrip ())
+ else:
+ job_id = False
+
+
+ # Retrive title and icon data
+ if nofile == False:
+ if job_id:
+ success, ver, title, desc, output, display, command_d = self.get_job_data (job_id)
+ else:
+ success = True
+ ver = 1
+ title = ""
+ desc = ""
+ output = 0
+ display = ""
+ command_d = ""
+
+ if (output == 0) or (output == 3):
+ # remove devnull part of command
+ # searching reverse, and only if output is saved in the datafile
+ pos = command.rfind (self.output[1])
+ if pos != -1:
+ command = command[:pos]
+ if output >= 2:
+ # rely on command from datafile, command from crontab line only contains xwrapper stuff
+ command = command_d
+
+ # support older datafiles/entries without removing the no output tag
+ if ver <= 1:
+ # old version, no output declaration in datafile, migration
+ pos = command.rfind (self.output[1])
+ if pos != -1:
+ command = command[:pos]
+ output = 1
+ else:
+ output = 0
+
+ command = command.strip ()
+
+
+ return [2, [minute, hour, dom, moy, dow, command, comment, job_id, title, desc, output, display]]
+ else:
+ return minute, hour, dom, moy, dow, command
+
+ def get_job_data (self, job_id):
+ f = os.path.join (self.crontabdata, str (job_id))
+ if os.access (f, os.R_OK):
+ fh = open (f, 'r')
+ d = fh.read ()
+
+ ver_p = d.find ("ver=")
+ if ver_p == -1:
+ ver = 1
+ else:
+ ver_s = d[ver_p + 4:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+ ver = int (ver_s)
+
+ title = d[6:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+
+ if ver < 3:
+ # not in use
+ icon = d[5:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+
+ desc = d[5:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+
+ if (ver >= 2) and (ver < 4):
+ output_str = d[9:d.find ("\n")]
+ output = int (output_str)
+ d = d[d.find("\n")]
+
+ if ver >= 4:
+ output_str = d[7:d.find ("\n")]
+ output = int (output_str)
+ d = d[d.find ("\n") + 1:]
+
+ if ver >= 4:
+ display = d[8:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+ if (len (display) < 1) or (output < 2):
+ display = ""
+
+ if ver >= 5:
+ command_d = d[10:d.find ("\n")]
+ d = d[d.find ("\n") + 1:]
+ if (len (command_d) < 1) or (output < 2):
+ command_d = ""
+
+ fh.close ()
+
+ return True, ver, title, desc, output, display, command_d
+
+
+ else:
+ return False, "", "", "", 0, 0, ""
+
+ def get_exp_sec (self, line):
+ line = line.lstrip ()
+ #print "line: \"" + line + "\""
+
+ ## find next whitespace
+ i = 0
+ found = False
+ while (i <= len(line)) and (found == False):
+ if line[i] in string.whitespace:
+ found = True
+ #print "found: " + str (i)
+ else:
+ i = i + 1
+ sec = line[0:i]
+ #print "sec: \"" + sec + "\""
+ line = line[i + 1:]
+ return sec, line
+
+ def __easy__ (self, minute, hour, day, month, weekday):
+ return lang.translate_crontab_easy (minute, hour, day, month, weekday)
+
+
+ #create temp file with old tasks and new ones and then update crontab
+ def __write__ (self):
+ tmpfile = tempfile.mkstemp ()
+ fd, path = tmpfile
+ tmp = os.fdopen(fd, 'w')
+ count = 0
+ for line in self.lines:
+
+ ## Ignore the first three comments:
+
+ ## DO NOT EDIT THIS FILE - edit the master and reinstall.
+ ## (/tmp/crontab.XXXXXX installed on Xxx Xxx x xx:xx:xx xxxx)
+ ## (Cron version -- $Id$)
+
+ if not (count < 3 and len(line) > 1 and line[0] == "#"):
+ tmp.write (line)
+ if line[len(line)-1] != '\n':
+ tmp.write ("\n")
+ count = count + 1
+
+ tmp.close ()
+
+ #replace crontab config with new one in file
+ if self.root:
+ # print config.getCrontabbin () + " -u " + self.ParentClass.user + " " + path
+ os.system (config.getCrontabbin () + " " + path + " -u " + self.user)
+ else:
+ # print config.getCrontabbin () + " " + path
+ os.system (config.getCrontabbin () + " " + path)
+
+ os.unlink (path)
+
+
+ def __make_preview__ (self, str, preview_len = 0):
+ if preview_len == 0:
+ preview_len = self.preview_len
+
+ str = str.replace ("&", "&")
+
+ if len (str) <= preview_len:
+ return str
+ else:
+ return str[:preview_len] + "..."
- result = result.replace ("&", "&")
- return result
Modified: trunk/src/crontabEditor.py
==============================================================================
--- trunk/src/crontabEditor.py (original)
+++ trunk/src/crontabEditor.py Sat Feb 14 21:20:56 2009
@@ -32,673 +32,640 @@
class CrontabEditor:
- def __init__(self, parent, backend, scheduler, template):
+ def __init__(self, parent, backend, scheduler, template):
- self.ParentClass = parent
- self.backend = backend
- self.scheduler = scheduler
- self.template = template
-
- self.xml = self.ParentClass.xml
- self.widget = self.xml.get_widget("crontab_editor")
- self.widget.connect("delete-event", self.widget.hide_on_delete)
-
-
- # TODO: move to crontab?
- self.fieldRegex = re.compile('^(\*)$|^([0-9]+)$|^\*\/([0-9]+)$|^([0-9]+)-([0-9]+)$|(^([0-9]+[,])+([0-9]+)$)')
- self.nooutputRegex = re.compile('([^#\n$]*)>(\s|)/dev/null\s2>&1')
-
-
- self.title_box = self.xml.get_widget ("crontab_title_box")
-
- self.image_icon = gtk.Image ()
- self.image_icon.set_from_pixbuf (self.ParentClass.bigiconcrontab)
- self.title_box.pack_start (self.image_icon, False, False, 0)
- self.title_box.reorder_child (self.image_icon, 0)
- self.image_icon.show ()
-
- self.noevents = False
-
-
- ##simple tab
- self.entry_title = self.xml.get_widget ("entry_title")
- self.entry_task = self.xml.get_widget ("entry_task")
-
- self.frequency_combobox = self.xml.get_widget ("frequency_combobox")
- self.frequency_combobox_model = gtk.ListStore (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
- self.frequency_combobox_model.append([_("Every minute"), ["*", "*", "*", "*", "*", ""]])
- self.frequency_combobox_model.append([_("Every hour"), ["0", "*", "*", "*", "*", ""]])
- self.frequency_combobox_model.append([_("Every day"), ["0", "0", "*", "*", "*", ""]])
- self.frequency_combobox_model.append([_("Every month"), ["0", "0", "1", "*", "*", ""]])
- self.frequency_combobox_model.append([_("Every week"), ["0", "0", "*", "*", "1", ""]])
- self.frequency_combobox_model.append([_("At reboot"), ["", "", "", "", "", "@reboot"]])
- self.frequency_combobox.set_model (self.frequency_combobox_model)
-
- self.cb_nooutput = self.xml.get_widget("cb_nooutput")
-
- #self.help_button = self.xml.get_widget ("cron_help_button")
-
- self.button_cancel = self.xml.get_widget ("button_cancel")
- self.button_apply = self.xml.get_widget ("button_apply")
- self.button_template = self.xml.get_widget ("button_template")
- self.rb_advanced = self.xml.get_widget ("rb_advanced")
- self.rb_basic = self.xml.get_widget ("rb_basic")
-
- self.label_preview = self.xml.get_widget ("label_preview")
-
- self.xml.signal_connect("on_button_cancel_clicked", self.on_button_cancel_clicked)
- self.xml.signal_connect("on_button_apply_clicked", self.on_button_apply_clicked)
- self.xml.signal_connect("on_anyadvanced_entry_changed", self.on_anyadvanced_entry_changed)
- self.xml.signal_connect("on_anybasic_entry_changed", self.on_anybasic_entry_changed)
- self.xml.signal_connect("on_frequency_combobox_changed", self.on_frequency_combobox_changed)
- self.xml.signal_connect("on_cb_nooutput_toggeled", self.on_anybasic_entry_changed)
-
- self.xml.signal_connect("on_help_clicked", self.on_fieldHelp_clicked)
-
- self.xml.signal_connect("on_rb_advanced_toggled", self.on_editmode_toggled)
- self.xml.signal_connect("on_rb_basic_toggled", self.on_editmode_toggled)
-
- self.xml.signal_connect ("on_button_template_clicked", self.on_template_clicked)
-
-
- ##
-
- ##advanced
- self.minute_entry = self.xml.get_widget ("minute_entry")
- self.hour_entry = self.xml.get_widget ("hour_entry")
- self.day_entry = self.xml.get_widget ("day_entry")
- self.month_entry = self.xml.get_widget ("month_entry")
- self.weekday_entry = self.xml.get_widget ("weekday_entry")
-
- self.help_minute = self.xml.get_widget ("help_minute")
- self.help_hour = self.xml.get_widget ("help_hour")
- self.help_day = self.xml.get_widget ("help_day")
- self.help_month = self.xml.get_widget ("help_month")
- self.help_weekday = self.xml.get_widget ("help_weekday")
- ##
-
-
- self.editorhelper = crontabEditorHelper.CrontabEditorHelper(self)
-
-
-
- def showadd (self, transient):
- self.button_apply.set_label (gtk.STOCK_ADD)
- self.__reset__ ()
- self.mode = 0
- self.widget.set_title(_("Create a New Scheduled Task"))
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.button_template.show ()
- self.widget.show ()
- self.cb_nooutput.set_active (True)
-
- def showadd_template (self, transient, title, command, nooutput,timeexpression):
- self.button_apply.set_label (gtk.STOCK_ADD)
- self.__reset__ ()
- self.mode = 0
- self.widget.set_title(_("Create a New Scheduled Task"))
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.button_template.show ()
- self.widget.show ()
-
- self.nooutput = nooutput
- # hehe again, why make it less complicated..
- timeexpression = timeexpression + " echo hehe"
- self.minute, self.hour, self.day, self.month, self.weekday, hehe = self.scheduler.parse (timeexpression, True)
- self.special = ""
- if self.minute == "@reboot":
- self.special = "@reboot"
- self.minute = ""
- self.day = ""
- self.hour = ""
- self.month = ""
- self.weekday = ""
- self.command = command
- self.title = title
-
- self.__update_textboxes__ ()
-
- i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
- if i == -1:
- # advanced
- self.rb_advanced.set_active (True)
- else:
- self.rb_basic.set_active (True)
- self.frequency_combobox.set_active (i)
-
- if self.nooutput:
- self.entry_task.set_text (self.command)
- self.cb_nooutput.set_active (True)
-
- else:
- self.cb_nooutput.set_active (False)
-
-
- def showedit_template (self, transient, id, title, command, nooutput, timeexpression):
- self.button_apply.set_label (gtk.STOCK_SAVE)
-
- self.mode = 2
- self.tid = id
- self.__reset__ ()
-
- self.command = command
- self.title = title
- self.nooutput = nooutput
-
- timeexpression = timeexpression + " echo hehe"
- self.minute, self.hour, self.day, self.month, self.weekday, hehe = self.scheduler.parse (timeexpression, True)
- self.special = ""
- if self.minute == "@reboot":
- self.special = "@reboot"
- self.minute = ""
- self.day = ""
- self.hour = ""
- self.month = ""
- self.weekday = ""
-
- self.widget.set_title(_("Edit template"))
- self.__update_textboxes__ ()
-
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.widget.show ()
- self.button_template.hide ()
- i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
- if i == -1:
- # advanced
- self.rb_advanced.set_active (True)
- else:
- self.rb_basic.set_active (True)
- self.frequency_combobox.set_active (i)
-
- if self.nooutput:
- self.entry_task.set_text (self.command)
- self.cb_nooutput.set_active (True)
-
- else:
- self.cb_nooutput.set_active (False)
-
- def shownew_template (self, transient):
- self.button_apply.set_label (gtk.STOCK_ADD)
-
- self.mode = 2
- self.tid = 0
- self.__reset__ ()
-
-
- self.widget.set_title(_("New template"))
- self.__update_textboxes__ ()
-
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.widget.show ()
- self.button_template.hide ()
-
-
- def showedit (self, transient, record, job_id, linenumber, iter):
- self.button_apply.set_label (gtk.STOCK_APPLY)
- self.mode = 1
- self.linenumber = linenumber
- self.record = record
- self.job_id = job_id
- self.__reset__ ()
- (self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.comment, self.job_id, self.title, self.desc, self.nooutput) = self.scheduler.parse (record)[1]
- self.special = ""
- if self.minute == "@reboot":
- self.special = "@reboot"
- self.minute = ""
- self.day = ""
- self.hour = ""
- self.month = ""
- self.weekday = ""
-
- self.widget.set_title(_("Edit a Scheduled Task"))
- self.__update_textboxes__ ()
- self.parentiter = iter
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.button_template.show ()
- self.widget.show ()
- i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
- if i == -1:
- # advanced
- self.rb_advanced.set_active (True)
- else:
- self.rb_basic.set_active (True)
- self.frequency_combobox.set_active (i)
-
- if self.nooutput:
- self.entry_task.set_text (self.command)
- self.cb_nooutput.set_active (True)
-
- else:
- self.cb_nooutput.set_active (False)
-
-
- def __reset__ (self):
- self.noevents = True
- self.minute = "0"
- self.hour = "*"
- self.day = "*"
- self.month = "*"
- self.weekday = "*"
- self.special = ""
- self.command = "ls"
- self.title = _("Untitled")
- self.nooutput = 1
- self.frequency_combobox.set_active (1)
- self.rb_basic.set_active (True)
- self.minute_entry.set_editable (False)
- self.minute_entry.set_sensitive (False)
- self.hour_entry.set_editable (False)
- self.hour_entry.set_sensitive (False)
- self.day_entry.set_editable (False)
- self.day_entry.set_sensitive (False)
- self.month_entry.set_editable (False)
- self.month_entry.set_sensitive (False)
- self.weekday_entry.set_editable (False)
- self.weekday_entry.set_sensitive (False)
- self.help_minute.set_sensitive (False)
- self.help_hour.set_sensitive (False)
- self.help_day.set_sensitive (False)
- self.help_month.set_sensitive (False)
- self.help_weekday.set_sensitive (False)
- self.cb_nooutput.set_active (True)
- self.frequency_combobox.set_sensitive (True)
- self.__update_textboxes__ ()
- self.noevents = False
-
-
- #error dialog box
- def __WrongRecordDialog__ (self, x, y, z):
- self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % (y, z)))
- self.wrongdialog.run()
- self.wrongdialog.destroy()
-
- def __dialog_command_failed__ (self):
- self.wrongdialog2 = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("Your command contains one or more of the character %, this is special for cron and cannot be used with Gnome-schedule because of the format it uses to store extra information on the crontab line. Please use the | redirector character to achieve the same functionality. Refer to the crontab manual for more information about the % character. If you don not want to use it for redirection it must be properly escaped with the \ letter.")))
- self.wrongdialog2.run()
- self.wrongdialog2.destroy()
-
- def __check_field_format__ (self, field, type):
- try:
- # Type should not be translatable!
- self.scheduler.checkfield (field, type)
- except ValueError, ex:
- raise ex
-
- #TODO: Help button?
- """
- def on_cron_help_button_clicked (self, *args):
- try:
- gnome.help_display_with_doc_id (
- self.ParentClass.gprogram, '',
- 'gnome-schedule.xml',
- 'myapp-adding-recurrent')
- except gobject.GError, error:
- dialog = gtk.MessageDialog (
- self.widget,
- gtk.DIALOG_DESTROY_WITH_PARENT,
- gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE)
- dialog.set_markup ("<b>" + _("Could not display help") + "</b>")
- dialog.format_secondary_text ("%s" % error)
- dialog.run ()
- dialog.destroy ()
-
- """
- def on_editmode_toggled (self, widget, *args):
- if widget.get_active() == True:
- if self.noevents == False:
- self.noevents = True
- if widget.get_name () == self.rb_advanced.get_name ():
- self.rb_basic.set_active (False)
- if (self.frequency_combobox.get_active () == 5):
- # reboot, standard every hour
- self.special = ""
- self.minute_entry.set_text ("0")
- self.hour_entry.set_text ("*")
- self.day_entry.set_text ("*")
- self.month_entry.set_text ("*")
- self.weekday_entry.set_text ("*")
- self.minute = "0"
- self.hour = "*"
- self.day = "*"
- self.month = "*"
- self.weekday = "*"
-
- self.update_preview ()
-
- self.rb_advanced.set_active (True)
- self.minute_entry.set_editable (True)
- self.minute_entry.set_sensitive (True)
- self.hour_entry.set_editable (True)
- self.hour_entry.set_sensitive (True)
- self.day_entry.set_editable (True)
- self.day_entry.set_sensitive (True)
- self.month_entry.set_editable (True)
- self.month_entry.set_sensitive (True)
- self.weekday_entry.set_editable (True)
- self.weekday_entry.set_sensitive (True)
- self.help_minute.set_sensitive (True)
- self.help_hour.set_sensitive (True)
- self.help_day.set_sensitive (True)
- self.help_month.set_sensitive (True)
- self.help_weekday.set_sensitive (True)
- self.frequency_combobox.set_sensitive (False)
- else:
- self.rb_basic.set_active (True)
- self.rb_advanced.set_active (False)
- self.minute_entry.set_editable (False)
- self.minute_entry.set_sensitive (False)
- self.hour_entry.set_editable (False)
- self.hour_entry.set_sensitive (False)
- self.day_entry.set_editable (False)
- self.day_entry.set_sensitive (False)
- self.month_entry.set_editable (False)
- self.month_entry.set_sensitive (False)
- self.weekday_entry.set_editable (False)
- self.weekday_entry.set_sensitive (False)
- self.help_minute.set_sensitive (False)
- self.help_hour.set_sensitive (False)
- self.help_day.set_sensitive (False)
- self.help_month.set_sensitive (False)
- self.help_weekday.set_sensitive (False)
- self.frequency_combobox.set_sensitive (True)
- self.on_frequency_combobox_changed (self.frequency_combobox)
- self.noevents = False
-
-
- def on_button_cancel_clicked (self, *args):
- self.widget.hide()
-
- def on_template_clicked (self, *args):
- if self.special != "":
- try:
- self.__check_field_format__ (self.special, "special")
- record = self.special + " " + self.command
- self.minute = "@reboot"
- self.hour = "@reboot"
- self.day = "@reboot"
- self.month = "@reboot"
- self.weekday = "@reboot"
- except ValueError, ex:
- x, y, z = ex
- self.__WrongRecordDialog__ (x, y, z)
- return
- else:
- try:
- # Type should not be translatable!
- self.__check_field_format__ (self.minute, "minute")
- self.__check_field_format__ (self.hour, "hour")
- self.__check_field_format__ (self.day, "day")
- self.__check_field_format__ (self.month, "month")
- self.__check_field_format__ (self.weekday, "weekday")
- record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
- except ValueError, ex:
- x, y, z = ex
- self.__WrongRecordDialog__ (x, y, z)
- return
-
- if self.scheduler.check_command (self.command) == False:
- self.__dialog_command_failed__ ()
- return False
-
- if self.special != "":
- self.template.savetemplate_crontab (0, self.title, self.command, self.nooutput, self.special)
- else:
- self.template.savetemplate_crontab (0, self.title, self.command, self.nooutput, self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday)
-
- self.widget.hide ()
-
- def on_button_apply_clicked (self, *args):
- if self.special != "":
- try:
- self.__check_field_format__ (self.special, "special")
- record = self.special + " " + self.command
- self.minute = "@reboot"
- self.hour = "@reboot"
- self.day = "@reboot"
- self.month = "@reboot"
- self.weekday = "@reboot"
- except ValueError, ex:
- x, y, z = ex
- self.__WrongRecordDialog__ (x, y, z)
- return
- else:
- try:
- # Type should not be translatable!
- self.__check_field_format__ (self.minute, "minute")
- self.__check_field_format__ (self.hour, "hour")
- self.__check_field_format__ (self.day, "day")
- self.__check_field_format__ (self.month, "month")
- self.__check_field_format__ (self.weekday, "weekday")
- record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
- except ValueError, ex:
- x, y, z = ex
- self.__WrongRecordDialog__ (x, y, z)
- return
-
- if self.scheduler.check_command (self.command) == False:
- self.__dialog_command_failed__ ()
- return False
-
-
- if (self.backend.get_not_inform_working_dir_crontab() != True):
- dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nRecurrent tasks will be run from the home directory."))
- dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
- dia2.set_title (_("Warning: Working directory of executed tasks"))
- response = dia2.run ()
- if response == gtk.RESPONSE_CANCEL:
- dia2.destroy ()
- del dia2
- return
- elif response == gtk.RESPONSE_CLOSE:
- self.backend.set_not_inform_working_dir_crontab (True)
- else:
- pass
- dia2.destroy ()
- del dia2
-
- if self.mode == 1:
- self.scheduler.update (self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.linenumber, self.parentiter, self.nooutput, self.job_id, self.comment, self.title, self.desc)
-
- elif self.mode == 0:
- self.scheduler.append (self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.nooutput, self.title)
-
- elif self.mode == 2:
- if self.special != "":
- try:
- self.__check_field_format__ (self.special, "special")
- record = self.special + " " + self.command
- self.minute = "@reboot"
- self.hour = "@reboot"
- self.day = "@reboot"
- self.month = "@reboot"
- self.weekday = "@reboot"
- except ValueError, ex:
- x, y, z = ex
- self.__WrongRecordDialog__ (x, y, z)
- return
- else:
- try:
- # Type should not be translatable!
- self.__check_field_format__ (self.minute, "minute")
- self.__check_field_format__ (self.hour, "hour")
- self.__check_field_format__ (self.day, "day")
- self.__check_field_format__ (self.month, "month")
- self.__check_field_format__ (self.weekday, "weekday")
- record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
- except ValueError, ex:
- x, y, z = ex
- self.__WrongRecordDialog__ (x, y, z)
- return
-
- if self.scheduler.check_command (self.command) == False:
- self.__dialog_command_failed__ ()
- return False
-
- if self.special != "":
- self.template.savetemplate_crontab (self.tid, self.title, self.command, self.nooutput, self.special)
- else:
- self.template.savetemplate_crontab (self.tid, self.title, self.command, self.nooutput, self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday)
-
- self.widget.hide ()
- return
-
- self.ParentClass.schedule_reload ()
- self.widget.hide ()
-
-
- def __set_frequency_combo__ (self):
- if self.noevents == False:
- index = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
- if index != -1:
- self.frequency_combobox.set_active (index)
- else:
- self.rb_advanced.set_active (True)
-
-
- def __getfrequency__ (self, minute, hour, day, month, weekday, special):
- index = -1
-
- if minute == "*" and hour == "*" and month == "*" and day == "*" and weekday == "*":
- index = 0
- if minute == "0" and hour == "*" and month == "*" and day == "*" and weekday == "*":
- index = 1
- if minute == "0" and hour == "0" and month == "*" and day == "*" and weekday == "*":
- index = 2
- if minute == "0" and hour == "0" and month == "*" and day == "1" and weekday == "*":
- index = 3
- if minute == "0" and hour == "0" and month == "*" and day == "*" and weekday == "1":
- index = 4
- if special != "":
- index = 5
-
-
- return index
-
-
- def __update_textboxes__ (self):
- self.noevents = True
- self.cb_nooutput.set_active (self.nooutput)
- self.entry_task.set_text (self.command)
- self.entry_title.set_text (self.title)
- self.minute_entry.set_text (self.minute)
- self.hour_entry.set_text (self.hour)
- self.day_entry.set_text (self.day)
- self.month_entry.set_text (self.month)
- self.weekday_entry.set_text (self.weekday)
- self.update_preview ()
- #self.__set_frequency_combo__()
- self.noevents = False
-
- def update_preview (self):
- if self.special != "":
- try:
- self.__check_field_format__ (self.special, "special")
- record = self.special + " " + self.command
- minute = "@reboot"
- hour = "@reboot"
- day = "@reboot"
- month = "@reboot"
- weekday = "@reboot"
- self.label_preview.set_text ("<b>" + self.scheduler.__easy__ (minute, hour, day, month, weekday) + "</b>")
-
- except ValueError, ex:
- x, y, z = ex
- self.label_preview.set_text (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % ({'field' : y, 'reason' : z}))
-
-
- else:
- try:
- # Type should not be translatable!
- self.__check_field_format__ (self.minute, "minute")
- self.__check_field_format__ (self.hour, "hour")
- self.__check_field_format__ (self.day, "day")
- self.__check_field_format__ (self.month, "month")
- self.__check_field_format__ (self.weekday, "weekday")
-
- # Day of Month
- # Crontab bug? Let's not support
- # dom behaves like minute
- """
- dom = self.day
- if dom.isdigit() == False:
- dom = dom.lower ()
- for day in self.scheduler.downumbers:
- dom = dom.replace (day, self.scheduler.downumbers[day])
- """
-
- # Month of Year
- moy = self.month
- if moy.isdigit () == False:
- moy = moy.lower ()
- for m in self.scheduler.monthnumbers:
- moy = moy.replace (m, self.scheduler.monthnumbers[m])
-
-
- # Day of Week
- dow = self.weekday
- if dow.isdigit() == False:
- dow = dow.lower ()
- for day in self.scheduler.downumbers:
- dow = dow.replace (day, self.scheduler.downumbers[day])
- self.label_preview.set_text ("<b>" + self.scheduler.__easy__ (self.minute, self.hour, self.day, moy, dow) + "</b>")
- except ValueError, ex:
- x, y, z = ex
- self.label_preview.set_text (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % ({'field' : y, 'reason' : z}))
-
- self.label_preview.set_use_markup (True)
-
-
- def on_anyadvanced_entry_changed (self, *args):
- if self.noevents == False:
- self.minute = self.minute_entry.get_text ()
- self.hour = self.hour_entry.get_text ()
- self.day = self.day_entry.get_text ()
- self.month = self.month_entry.get_text ()
- self.weekday = self.weekday_entry.get_text ()
- self.nooutput = self.cb_nooutput.get_active()
-
- self.__update_textboxes__ ()
-
-
- def on_anybasic_entry_changed (self, *args):
- if self.noevents == False:
- self.command = self.entry_task.get_text ()
- self.title = self.entry_title.get_text ()
- self.nooutput = self.cb_nooutput.get_active()
- self.__update_textboxes__ ()
-
-
- def on_frequency_combobox_changed (self, bin):
- iter = self.frequency_combobox.get_active_iter ()
- frequency = self.frequency_combobox_model.get_value(iter, 1)
- if frequency != None:
- self.minute, self.hour, self.day, self.month, self.weekday, self.special = frequency
- self.__update_textboxes__()
-
-
- def on_fieldHelp_clicked(self, widget, *args):
- name = widget.get_name()
- field = "minute"
- if name == "help_minute" :
- field = "minute"
- expression = self.minute_entry.get_text()
- if name == "help_hour" :
- field = "hour"
- expression = self.hour_entry.get_text()
- if name == "help_day" :
- field = "day"
- expression = self.day_entry.get_text()
- if name == "help_month" :
- field = "month"
- expression = self.month_entry.get_text()
- if name == "help_weekday" :
- field = "weekday"
- expression = self.weekday_entry.get_text()
+ self.ParentClass = parent
+ self.backend = backend
+ self.scheduler = scheduler
+ self.template = template
+
+ self.xml = self.ParentClass.xml
+ self.widget = self.xml.get_widget("crontab_editor")
+ self.widget.connect("delete-event", self.widget.hide_on_delete)
+
+
+ # TODO: move to crontab?
+ self.fieldRegex = re.compile('^(\*)$|^([0-9]+)$|^\*\/([0-9]+)$|^([0-9]+)-([0-9]+)$|(^([0-9]+[,])+([0-9]+)$)')
+ self.nooutputRegex = re.compile('([^#\n$]*)>(\s|)/dev/null\s2>&1')
+
+
+ self.title_box = self.xml.get_widget ("crontab_title_box")
+
+ self.image_icon = gtk.Image ()
+ self.image_icon.set_from_pixbuf (self.ParentClass.bigiconcrontab)
+ self.title_box.pack_start (self.image_icon, False, False, 0)
+ self.title_box.reorder_child (self.image_icon, 0)
+ self.image_icon.show ()
+
+ self.noevents = False
+
+
+ ##simple tab
+ self.entry_title = self.xml.get_widget ("entry_title")
+ self.entry_task = self.xml.get_widget ("entry_task")
+
+ self.frequency_combobox = self.xml.get_widget ("frequency_combobox")
+ self.frequency_combobox_model = gtk.ListStore (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
+ self.frequency_combobox_model.append([_("Every minute"), ["*", "*", "*", "*", "*", ""]])
+ self.frequency_combobox_model.append([_("Every hour"), ["0", "*", "*", "*", "*", ""]])
+ self.frequency_combobox_model.append([_("Every day"), ["0", "0", "*", "*", "*", ""]])
+ self.frequency_combobox_model.append([_("Every month"), ["0", "0", "1", "*", "*", ""]])
+ self.frequency_combobox_model.append([_("Every week"), ["0", "0", "*", "*", "1", ""]])
+ self.frequency_combobox_model.append([_("At reboot"), ["", "", "", "", "", "@reboot"]])
+ self.frequency_combobox.set_model (self.frequency_combobox_model)
+
+ self.cb_output = self.xml.get_widget ("combo_output")
+ self.cb_o_model = gtk.ListStore (gobject.TYPE_STRING, gobject.TYPE_INT)
+ self.cb_o_model.append ([self.ParentClass.output_strings[0], 0])
+ self.cb_o_model.append ([self.ParentClass.output_strings[1], 1])
+ self.cb_o_model.append ([self.ParentClass.output_strings[2], 2])
+ self.cb_o_model.append ([self.ParentClass.output_strings[3], 3])
+ self.cb_output.set_model (self.cb_o_model)
+ cell = gtk.CellRendererText ()
+ self.cb_output.pack_start (cell, True)
+ self.cb_output.add_attribute (cell, "text", 0)
+
+ self.button_cancel = self.xml.get_widget ("button_cancel")
+ self.button_apply = self.xml.get_widget ("button_apply")
+ self.button_template = self.xml.get_widget ("button_template")
+ self.rb_advanced = self.xml.get_widget ("rb_advanced")
+ self.rb_basic = self.xml.get_widget ("rb_basic")
+
+ self.label_preview = self.xml.get_widget ("label_preview")
+
+ self.xml.signal_connect("on_button_cancel_clicked", self.on_button_cancel_clicked)
+ self.xml.signal_connect("on_button_apply_clicked", self.on_button_apply_clicked)
+ self.xml.signal_connect("on_anyadvanced_entry_changed", self.on_anyadvanced_entry_changed)
+ self.xml.signal_connect("on_anybasic_entry_changed", self.on_anybasic_entry_changed)
+ self.xml.signal_connect("on_frequency_combobox_changed", self.on_frequency_combobox_changed)
+ self.xml.signal_connect ("on_combo_output_changed", self.on_anybasic_entry_changed)
+
+ self.xml.signal_connect("on_help_clicked", self.on_fieldHelp_clicked)
+
+ self.xml.signal_connect("on_rb_advanced_toggled", self.on_editmode_toggled)
+ self.xml.signal_connect("on_rb_basic_toggled", self.on_editmode_toggled)
+
+ self.xml.signal_connect ("on_button_template_clicked", self.on_template_clicked)
+
+ ##advanced
+ self.minute_entry = self.xml.get_widget ("minute_entry")
+ self.hour_entry = self.xml.get_widget ("hour_entry")
+ self.day_entry = self.xml.get_widget ("day_entry")
+ self.month_entry = self.xml.get_widget ("month_entry")
+ self.weekday_entry = self.xml.get_widget ("weekday_entry")
+
+ self.help_minute = self.xml.get_widget ("help_minute")
+ self.help_hour = self.xml.get_widget ("help_hour")
+ self.help_day = self.xml.get_widget ("help_day")
+ self.help_month = self.xml.get_widget ("help_month")
+ self.help_weekday = self.xml.get_widget ("help_weekday")
+
+ self.editorhelper = crontabEditorHelper.CrontabEditorHelper(self)
+
+
+
+ def showadd (self, transient):
+ self.button_apply.set_label (gtk.STOCK_ADD)
+ self.__reset__ ()
+ self.mode = 0
+ self.widget.set_title(_("Create a New Scheduled Task"))
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.button_template.show ()
+ self.widget.show ()
+ self.cb_output.set_active (0)
+
+ def showadd_template (self, transient, title, command, output,timeexpression):
+ self.button_apply.set_label (gtk.STOCK_ADD)
+ self.__reset__ ()
+ self.mode = 0
+ self.widget.set_title(_("Create a New Scheduled Task"))
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.button_template.show ()
+ self.widget.show ()
+
+ self.output = output
+ # hehe again, why make it less complicated..
+ timeexpression = timeexpression + " echo hehe"
+ self.minute, self.hour, self.day, self.month, self.weekday, hehe = self.scheduler.parse (timeexpression, True)
+ self.special = ""
+ if self.minute == "@reboot":
+ self.special = "@reboot"
+ self.minute = ""
+ self.day = ""
+ self.hour = ""
+ self.month = ""
+ self.weekday = ""
+ self.command = command
+ self.title = title
+
+ self.__update_textboxes__ ()
+
+ i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
+ if i == -1:
+ # advanced
+ self.rb_advanced.set_active (True)
+ else:
+ self.rb_basic.set_active (True)
+ self.frequency_combobox.set_active (i)
+
+ self.cb_output.set_active (self.output)
+
+
+ def showedit_template (self, transient, id, title, command, output, timeexpression):
+ self.button_apply.set_label (gtk.STOCK_SAVE)
+
+ self.mode = 2
+ self.tid = id
+ self.__reset__ ()
+
+ self.command = command
+ self.title = title
+ self.output = output
+
+ timeexpression = timeexpression + " echo hehe"
+ self.minute, self.hour, self.day, self.month, self.weekday, hehe = self.scheduler.parse (timeexpression, True)
+ self.special = ""
+ if self.minute == "@reboot":
+ self.special = "@reboot"
+ self.minute = ""
+ self.day = ""
+ self.hour = ""
+ self.month = ""
+ self.weekday = ""
+
+ self.widget.set_title(_("Edit template"))
+ self.__update_textboxes__ ()
+
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.widget.show ()
+ self.button_template.hide ()
+ i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
+ if i == -1:
+ # advanced
+ self.rb_advanced.set_active (True)
+ else:
+ self.rb_basic.set_active (True)
+ self.frequency_combobox.set_active (i)
+
+ self.cb_output.set_active (self.output)
+
+ def shownew_template (self, transient):
+ self.button_apply.set_label (gtk.STOCK_ADD)
+
+ self.mode = 2
+ self.tid = 0
+ self.__reset__ ()
+
+
+ self.widget.set_title(_("New template"))
+ self.__update_textboxes__ ()
+
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.widget.show ()
+ self.button_template.hide ()
+
+
+ def showedit (self, transient, record, job_id, linenumber, iter):
+ self.button_apply.set_label (gtk.STOCK_APPLY)
+ self.mode = 1
+ self.linenumber = linenumber
+ self.record = record
+ self.job_id = job_id
+ self.__reset__ ()
+ (self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.comment, self.job_id, self.title, self.desc, self.output, display) = self.scheduler.parse (record)[1]
+ self.special = ""
+ if self.minute == "@reboot":
+ self.special = "@reboot"
+ self.minute = ""
+ self.day = ""
+ self.hour = ""
+ self.month = ""
+ self.weekday = ""
+
+ self.widget.set_title(_("Edit a Scheduled Task"))
+ self.__update_textboxes__ ()
+ self.parentiter = iter
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.button_template.show ()
+ self.widget.show ()
+ i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
+ if i == -1:
+ # advanced
+ self.rb_advanced.set_active (True)
+ else:
+ self.rb_basic.set_active (True)
+ self.frequency_combobox.set_active (i)
+
+ self.cb_output.set_active (self.output)
+
+ def __reset__ (self):
+ self.noevents = True
+ self.minute = "0"
+ self.hour = "*"
+ self.day = "*"
+ self.month = "*"
+ self.weekday = "*"
+ self.special = ""
+ self.command = "ls"
+ self.title = _("Untitled")
+ self.output = 0
+ self.frequency_combobox.set_active (1)
+ self.rb_basic.set_active (True)
+ self.minute_entry.set_editable (False)
+ self.minute_entry.set_sensitive (False)
+ self.hour_entry.set_editable (False)
+ self.hour_entry.set_sensitive (False)
+ self.day_entry.set_editable (False)
+ self.day_entry.set_sensitive (False)
+ self.month_entry.set_editable (False)
+ self.month_entry.set_sensitive (False)
+ self.weekday_entry.set_editable (False)
+ self.weekday_entry.set_sensitive (False)
+ self.help_minute.set_sensitive (False)
+ self.help_hour.set_sensitive (False)
+ self.help_day.set_sensitive (False)
+ self.help_month.set_sensitive (False)
+ self.help_weekday.set_sensitive (False)
+ self.cb_output.set_active (0)
+ self.frequency_combobox.set_sensitive (True)
+ self.__update_textboxes__ ()
+ self.noevents = False
+
+
+ #error dialog box
+ def __WrongRecordDialog__ (self, x, y, z):
+ self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % (y, z)))
+ self.wrongdialog.run()
+ self.wrongdialog.destroy()
+
+ def __dialog_command_failed__ (self):
+ self.wrongdialog2 = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("Your command contains one or more of the character %, this is special for cron and cannot be used with Gnome-schedule because of the format it uses to store extra information on the crontab line. Please use the | redirector character to achieve the same functionality. Refer to the crontab manual for more information about the % character. If you don not want to use it for redirection it must be properly escaped with the \ letter.")))
+ self.wrongdialog2.run()
+ self.wrongdialog2.destroy()
+
+ def __check_field_format__ (self, field, type):
+ try:
+ # Type should not be translatable!
+ self.scheduler.checkfield (field, type)
+ except ValueError, ex:
+ raise ex
+
+ def on_editmode_toggled (self, widget, *args):
+ if widget.get_active() == True:
+ if self.noevents == False:
+ self.noevents = True
+ if widget.get_name () == self.rb_advanced.get_name ():
+ self.rb_basic.set_active (False)
+ if (self.frequency_combobox.get_active () == 5):
+ # reboot, standard every hour
+ self.special = ""
+ self.minute_entry.set_text ("0")
+ self.hour_entry.set_text ("*")
+ self.day_entry.set_text ("*")
+ self.month_entry.set_text ("*")
+ self.weekday_entry.set_text ("*")
+ self.minute = "0"
+ self.hour = "*"
+ self.day = "*"
+ self.month = "*"
+ self.weekday = "*"
+
+ self.update_preview ()
+
+ self.rb_advanced.set_active (True)
+ self.minute_entry.set_editable (True)
+ self.minute_entry.set_sensitive (True)
+ self.hour_entry.set_editable (True)
+ self.hour_entry.set_sensitive (True)
+ self.day_entry.set_editable (True)
+ self.day_entry.set_sensitive (True)
+ self.month_entry.set_editable (True)
+ self.month_entry.set_sensitive (True)
+ self.weekday_entry.set_editable (True)
+ self.weekday_entry.set_sensitive (True)
+ self.help_minute.set_sensitive (True)
+ self.help_hour.set_sensitive (True)
+ self.help_day.set_sensitive (True)
+ self.help_month.set_sensitive (True)
+ self.help_weekday.set_sensitive (True)
+ self.frequency_combobox.set_sensitive (False)
+ else:
+ self.rb_basic.set_active (True)
+ self.rb_advanced.set_active (False)
+ self.minute_entry.set_editable (False)
+ self.minute_entry.set_sensitive (False)
+ self.hour_entry.set_editable (False)
+ self.hour_entry.set_sensitive (False)
+ self.day_entry.set_editable (False)
+ self.day_entry.set_sensitive (False)
+ self.month_entry.set_editable (False)
+ self.month_entry.set_sensitive (False)
+ self.weekday_entry.set_editable (False)
+ self.weekday_entry.set_sensitive (False)
+ self.help_minute.set_sensitive (False)
+ self.help_hour.set_sensitive (False)
+ self.help_day.set_sensitive (False)
+ self.help_month.set_sensitive (False)
+ self.help_weekday.set_sensitive (False)
+ self.frequency_combobox.set_sensitive (True)
+ self.on_frequency_combobox_changed (self.frequency_combobox)
+ self.noevents = False
+
+
+ def on_button_cancel_clicked (self, *args):
+ self.widget.hide()
+
+ def on_template_clicked (self, *args):
+ if self.special != "":
+ try:
+ self.__check_field_format__ (self.special, "special")
+ record = self.special + " " + self.command
+ self.minute = "@reboot"
+ self.hour = "@reboot"
+ self.day = "@reboot"
+ self.month = "@reboot"
+ self.weekday = "@reboot"
+ except ValueError, ex:
+ x, y, z = ex
+ self.__WrongRecordDialog__ (x, y, z)
+ return
+ else:
+ try:
+ # Type should not be translatable!
+ self.__check_field_format__ (self.minute, "minute")
+ self.__check_field_format__ (self.hour, "hour")
+ self.__check_field_format__ (self.day, "day")
+ self.__check_field_format__ (self.month, "month")
+ self.__check_field_format__ (self.weekday, "weekday")
+ record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
+ except ValueError, ex:
+ x, y, z = ex
+ self.__WrongRecordDialog__ (x, y, z)
+ return
+
+ if self.scheduler.check_command (self.command) == False:
+ self.__dialog_command_failed__ ()
+ return False
+
+ if self.special != "":
+ self.template.savetemplate_crontab (0, self.title, self.command, self.output, self.special)
+ else:
+ self.template.savetemplate_crontab (0, self.title, self.command, self.output, self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday)
+
+ self.widget.hide ()
+
+ def on_button_apply_clicked (self, *args):
+ if self.special != "":
+ try:
+ self.__check_field_format__ (self.special, "special")
+ record = self.special + " " + self.command
+ self.minute = "@reboot"
+ self.hour = "@reboot"
+ self.day = "@reboot"
+ self.month = "@reboot"
+ self.weekday = "@reboot"
+ except ValueError, ex:
+ x, y, z = ex
+ self.__WrongRecordDialog__ (x, y, z)
+ return
+ else:
+ try:
+ # Type should not be translatable!
+ self.__check_field_format__ (self.minute, "minute")
+ self.__check_field_format__ (self.hour, "hour")
+ self.__check_field_format__ (self.day, "day")
+ self.__check_field_format__ (self.month, "month")
+ self.__check_field_format__ (self.weekday, "weekday")
+ record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
+ except ValueError, ex:
+ x, y, z = ex
+ self.__WrongRecordDialog__ (x, y, z)
+ return
+
+ if self.scheduler.check_command (self.command) == False:
+ self.__dialog_command_failed__ ()
+ return False
+
+
+ if (self.backend.get_not_inform_working_dir_crontab() != True):
+ dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nRecurrent tasks will be run from the home directory."))
+ dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+ dia2.set_title (_("Warning: Working directory of executed tasks"))
+ response = dia2.run ()
+ if response == gtk.RESPONSE_CANCEL:
+ dia2.destroy ()
+ del dia2
+ return
+ elif response == gtk.RESPONSE_CLOSE:
+ self.backend.set_not_inform_working_dir_crontab (True)
+ else:
+ pass
+ dia2.destroy ()
+ del dia2
+
+ if self.mode == 1:
+ self.scheduler.update (self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.linenumber, self.parentiter, self.output, self.job_id, self.comment, self.title, self.desc)
+
+ elif self.mode == 0:
+ self.scheduler.append (self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.output, self.title)
+
+ elif self.mode == 2:
+ if self.special != "":
+ try:
+ self.__check_field_format__ (self.special, "special")
+ record = self.special + " " + self.command
+ self.minute = "@reboot"
+ self.hour = "@reboot"
+ self.day = "@reboot"
+ self.month = "@reboot"
+ self.weekday = "@reboot"
+ except ValueError, ex:
+ x, y, z = ex
+ self.__WrongRecordDialog__ (x, y, z)
+ return
+ else:
+ try:
+ # Type should not be translatable!
+ self.__check_field_format__ (self.minute, "minute")
+ self.__check_field_format__ (self.hour, "hour")
+ self.__check_field_format__ (self.day, "day")
+ self.__check_field_format__ (self.month, "month")
+ self.__check_field_format__ (self.weekday, "weekday")
+ record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
+ except ValueError, ex:
+ x, y, z = ex
+ self.__WrongRecordDialog__ (x, y, z)
+ return
+
+ if self.scheduler.check_command (self.command) == False:
+ self.__dialog_command_failed__ ()
+ return False
+
+ if self.special != "":
+ self.template.savetemplate_crontab (self.tid, self.title, self.command, self.output, self.special)
+ else:
+ self.template.savetemplate_crontab (self.tid, self.title, self.command, self.output, self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday)
+
+ self.widget.hide ()
+ return
+
+ self.ParentClass.schedule_reload ()
+ self.widget.hide ()
+
+
+ def __set_frequency_combo__ (self):
+ if self.noevents == False:
+ index = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
+ if index != -1:
+ self.frequency_combobox.set_active (index)
+ else:
+ self.rb_advanced.set_active (True)
+
+
+ def __getfrequency__ (self, minute, hour, day, month, weekday, special):
+ index = -1
+
+ if minute == "*" and hour == "*" and month == "*" and day == "*" and weekday == "*":
+ index = 0
+ if minute == "0" and hour == "*" and month == "*" and day == "*" and weekday == "*":
+ index = 1
+ if minute == "0" and hour == "0" and month == "*" and day == "*" and weekday == "*":
+ index = 2
+ if minute == "0" and hour == "0" and month == "*" and day == "1" and weekday == "*":
+ index = 3
+ if minute == "0" and hour == "0" and month == "*" and day == "*" and weekday == "1":
+ index = 4
+ if special != "":
+ index = 5
+
+
+ return index
+
+
+ def __update_textboxes__ (self):
+ self.noevents = True
+ self.cb_output.set_active (self.output)
+ self.entry_task.set_text (self.command)
+ self.entry_title.set_text (self.title)
+ self.minute_entry.set_text (self.minute)
+ self.hour_entry.set_text (self.hour)
+ self.day_entry.set_text (self.day)
+ self.month_entry.set_text (self.month)
+ self.weekday_entry.set_text (self.weekday)
+ self.update_preview ()
+ #self.__set_frequency_combo__()
+ self.noevents = False
+
+ def update_preview (self):
+ if self.special != "":
+ try:
+ self.__check_field_format__ (self.special, "special")
+ record = self.special + " " + self.command
+ minute = "@reboot"
+ hour = "@reboot"
+ day = "@reboot"
+ month = "@reboot"
+ weekday = "@reboot"
+ self.label_preview.set_text ("<b>" + self.scheduler.__easy__ (minute, hour, day, month, weekday) + "</b>")
+
+ except ValueError, ex:
+ x, y, z = ex
+ self.label_preview.set_text (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % ({'field' : y, 'reason' : z}))
+
+
+ else:
+ try:
+ # Type should not be translatable!
+ self.__check_field_format__ (self.minute, "minute")
+ self.__check_field_format__ (self.hour, "hour")
+ self.__check_field_format__ (self.day, "day")
+ self.__check_field_format__ (self.month, "month")
+ self.__check_field_format__ (self.weekday, "weekday")
+
+ # Day of Month
+ # Crontab bug? Let's not support
+ # dom behaves like minute
+ """
+ dom = self.day
+ if dom.isdigit() == False:
+ dom = dom.lower ()
+ for day in self.scheduler.downumbers:
+ dom = dom.replace (day, self.scheduler.downumbers[day])
+ """
+
+ # Month of Year
+ moy = self.month
+ if moy.isdigit () == False:
+ moy = moy.lower ()
+ for m in self.scheduler.monthnumbers:
+ moy = moy.replace (m, self.scheduler.monthnumbers[m])
+
+
+ # Day of Week
+ dow = self.weekday
+ if dow.isdigit() == False:
+ dow = dow.lower ()
+ for day in self.scheduler.downumbers:
+ dow = dow.replace (day, self.scheduler.downumbers[day])
+ self.label_preview.set_text ("<b>" + self.scheduler.__easy__ (self.minute, self.hour, self.day, moy, dow) + "</b>")
+ except ValueError, ex:
+ x, y, z = ex
+ self.label_preview.set_text (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % ({'field' : y, 'reason' : z}))
+
+ self.label_preview.set_use_markup (True)
+
+
+ def on_anyadvanced_entry_changed (self, *args):
+ if self.noevents == False:
+ self.minute = self.minute_entry.get_text ()
+ self.hour = self.hour_entry.get_text ()
+ self.day = self.day_entry.get_text ()
+ self.month = self.month_entry.get_text ()
+ self.weekday = self.weekday_entry.get_text ()
+ self.output = self.cb_output.get_active()
+
+ self.__update_textboxes__ ()
+
+
+ def on_anybasic_entry_changed (self, *args):
+ if self.noevents == False:
+ self.command = self.entry_task.get_text ()
+ self.title = self.entry_title.get_text ()
+ self.output = self.cb_output.get_active()
+ self.__update_textboxes__ ()
+
+
+ def on_frequency_combobox_changed (self, bin):
+ iter = self.frequency_combobox.get_active_iter ()
+ frequency = self.frequency_combobox_model.get_value(iter, 1)
+ if frequency != None:
+ self.minute, self.hour, self.day, self.month, self.weekday, self.special = frequency
+ self.__update_textboxes__()
+
+
+ def on_fieldHelp_clicked(self, widget, *args):
+ name = widget.get_name()
+ field = "minute"
+ if name == "help_minute" :
+ field = "minute"
+ expression = self.minute_entry.get_text()
+ if name == "help_hour" :
+ field = "hour"
+ expression = self.hour_entry.get_text()
+ if name == "help_day" :
+ field = "day"
+ expression = self.day_entry.get_text()
+ if name == "help_month" :
+ field = "month"
+ expression = self.month_entry.get_text()
+ if name == "help_weekday" :
+ field = "weekday"
+ expression = self.weekday_entry.get_text()
- self.editorhelper.show (field, expression)
-
+ self.editorhelper.show (field, expression)
+
Modified: trunk/src/crontabEditorHelper.py
==============================================================================
--- trunk/src/crontabEditorHelper.py (original)
+++ trunk/src/crontabEditorHelper.py Sat Feb 14 21:20:56 2009
@@ -24,263 +24,263 @@
class CrontabEditorHelper:
- def __init__(self, parent):
- self.ParentClass = parent
-
- self.xml = self.ParentClass.xml
-
- self.NoExpressionEvents = False
- self.fieldRegex = self.ParentClass.fieldRegex
-
- self.widget = self.xml.get_widget("crontabEditorHelper")
- self.widget.connect("delete-event", self.widget.hide_on_delete)
-
- self.radAll = self.xml.get_widget("radAll")
- self.radEvery = self.xml.get_widget("radEvery")
- self.radRange = self.xml.get_widget("radRange")
- self.radFix = self.xml.get_widget("radFix")
- self.radOth = self.xml.get_widget ("radOth")
-
- self.entExpression = self.xml.get_widget("entExpression")
- self.entEvery = self.xml.get_widget("entEvery")
- self.entFix = self.xml.get_widget("entFix")
- self.entRangeStart = self.xml.get_widget("entRangeStart")
- self.entRangeEnd = self.xml.get_widget("entRangeEnd")
-
- self.header = self.xml.get_widget("label_crontab_editor_title")
-
- self.lblEveryEntity = self.xml.get_widget("lblEveryEntity")
- self.lblFixEntity = self.xml.get_widget("lblFixEntity")
-
- #connect the radiobuttons toggle
- self.xml.signal_connect("on_btnCancel_clicked", self.btnCancel_clicked)
- self.xml.signal_connect("on_btnOk_clicked", self.btnOk_clicked)
- self.xml.signal_connect("on_radAll_toggled", self.RadioButtonChange)
- self.xml.signal_connect("on_radEvery_toggled", self.RadioButtonChange)
- self.xml.signal_connect("on_radRange_toggled", self.RadioButtonChange)
- self.xml.signal_connect("on_radFix_toggled", self.RadioButtonChange)
- self.xml.signal_connect("on_radOth_toggled", self.RadioButtonChange)
-
- #connect the changes of a combo or entry
- self.xml.signal_connect("on_entFix_changed", self.anyEntryChanged)
- self.xml.signal_connect("on_entEvery_changed", self.anyEntryChanged)
- self.xml.signal_connect("on_entRangeStart_changed", self.anyEntryChanged)
- self.xml.signal_connect("on_entRangeEnd_changed", self.anyEntryChanged)
- self.xml.signal_connect("on_entExpression_changed", self.entExpressionChanged)
-
- self.widgetgroups = { "radAll": [],
- "radEvery":["entEvery", "lblEveryEntity"],
- "radRange":["entRangeStart", "entRangeEnd",
- "lblRangeStart", "lblRangeEnd"],
- "radFix": ["entFix", "lblFixEntity"],
- "radOth": ["entExpression",
- "lblExpression"] }
-
-
- def populateLabels(self, field):
- #put the apropiate values in the labels describing entitys, and the 'at' combobox
-
- if field == "minute":
- self.entRangeEnd.set_text ("59")
- self.entRangeStart.set_text ("0")
- self.entFix.set_text("0")
- self.radAll.set_label(_("Every minute"))
-
- if field == "hour":
- self.entRangeEnd.set_text ("23")
- self.entRangeStart.set_text ("0")
- self.entFix.set_text("0")
- self.radAll.set_label(_("Every hour"))
-
- if field == "day":
- self.entRangeEnd.set_text ("31")
- self.entRangeStart.set_text ("1")
- self.entFix.set_text("1")
- self.radAll.set_label(_("Every day"))
-
- if field == "month":
- self.entRangeEnd.set_text ("12")
- self.entRangeStart.set_text ("1")
- self.entFix.set_text("1")
- self.radAll.set_label(_("Every month"))
-
- if field == "weekday":
- self.entRangeEnd.set_text ("7")
- self.entRangeStart.set_text ("0")
- self.entFix.set_text("0")
- self.radAll.set_label(_("Every weekday"))
-
-
- self.entEvery.set_text("2")
- self.entExpression.set_text ("*")
-
- self.trans_field = self.ParentClass.scheduler.translate_frequency (field)
-
-
-
- self.do_label_magic ()
-
-
- def show (self, field, expression):
- self.field = field
- self.populateLabels(field)
-
- m = self.fieldRegex.match (expression)
- self.radOth.set_active (True)
-
- self.NoExpressionEvents = True
- self.entExpression.set_text (expression)
-
- if m != None:
- if m.groups()[0] != None:
- self.radAll.set_active (True)
- # 10 * * * * command
- # */2 * * * * command
- if m.groups()[1] != None or m.groups()[2] != None:
- if m.groups()[1] != None:
- self.radFix.set_active (True)
- self.entFix.set_text (m.groups()[1])
- else:
- self.radEvery.set_active (True)
- self.entEvery.set_text (m.groups()[2])
-
- # 1-10 * * * * command
- if m.groups()[3] != None and m.groups()[4] != None:
- self.radRange.set_active (True)
- self.entRangeStart.set_text(m.groups()[3])
- self.entRangeEnd.set_text (m.groups()[4])
-
- # Unused
- # 1,2,3,4 * * * * command
- # if m.groups()[5] != None:
- # self.radOth.set_active (True)
- # fields = m.groups()[5].split (",")
-
- self.NoExpressionEvents = False
-
- #show the form
- if field == "minute":
- self.widget.set_title(_("Edit minute"))
- elif field == "hour":
- self.widget.set_title(_("Edit hour"))
- elif field == "day":
- self.widget.set_title(_("Edit day"))
- elif field == "month":
- self.widget.set_title(_("Edit month"))
- elif field == "weekday":
- self.widget.set_title(_("Edit weekday"))
-
- self.widget.set_transient_for(self.ParentClass.widget)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.widget.show_all()
-
-
- def btnOk_clicked(self, *args):
- #move expression to field in editor and hide
- expression = self.entExpression.get_text()
- try:
- self.ParentClass.scheduler.checkfield (expression, self.field)
- except ValueError, ex:
- x, y, z = ex
- self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is invalid. Reason: %s") % (z)))
- self.wrongdialog.run()
- self.wrongdialog.destroy()
- return
-
- if self.field == "minute": self.ParentClass.minute_entry.set_text(expression)
- if self.field == "hour": self.ParentClass.hour_entry.set_text(expression)
- if self.field == "day": self.ParentClass.day_entry.set_text(expression)
- if self.field == "month": self.ParentClass.month_entry.set_text(expression)
- if self.field == "weekday": self.ParentClass.weekday_entry.set_text(expression)
-
- self.widget.hide()
-
-
- def btnCancel_clicked(self, *args):
- #hide
- self.widget.hide()
- #return True
-
-
- def RadioButtonChange(self, widget):
- self.NoExpressionEvents = True
- self.do_label_magic ()
- name = widget.get_name()
- if widget.get_active():
- if name == "radAll":
- self.entExpression.set_text("*")
- elif name == "radEvery":
- self.entExpression.set_text("*/" + self.entEvery.get_text())
- elif name == "radRange":
- self.entExpression.set_text(self.entRangeStart.get_text() + "-" + self.entRangeEnd.get_text())
- elif name == "radFix":
- self.entExpression.set_text(self.entFix.get_text())
- self.NoExpressionEvents = False
-
- for groupname, widgetlist in self.widgetgroups.iteritems():
- state = groupname == name
- for widgetname in widgetlist:
- widget = self.xml.get_widget(widgetname)
- widget.set_sensitive(state)
-
-
- def do_label_magic (self):
- translated = ["", ""]
- if self.field == "minute":
- #minute
- translated[0] = _("At an exact minute")
- translated[1] = _("Minute:")
- elif self.field == "hour":
- #hour
- translated[0] = _("At an exact hour")
- translated[1] = _("Hour:")
- elif self.field == "day":
- #day
- translated[0] = _("On a day")
- translated[1] = _("Day:")
- elif self.field == "month":
- #month
- translated[0] = _("In a month")
- translated[1] = _("Month:")
- elif self.field == "weekday":
- #weekday
- translated[0] = _("On a weekday")
- translated[1] = _("Weekday:")
-
- self.radFix.set_label (translated[0])
- self.lblFixEntity.set_label (translated[1])
-
- translated[0] = _("In a step width")
- if self.field == "minute":
- translated[1] = _("Minutes:")
- elif self.field == "hour":
- translated[1] = _("Hours:")
- elif self.field == "day":
- translated[1] = _("Days:")
- elif self.field == "month":
- translated[1] = _("Months:")
- elif self.field == "weekday":
- translated[1] = _("Weekdays:")
-
- self.radEvery.set_label (translated[0])
- self.lblEveryEntity.set_label (translated[1])
-
-
- def entExpressionChanged(self, *args):
- if self.NoExpressionEvents == False:
- self.radOth.set_active (True)
-
-
- def anyEntryChanged(self, *args):
- self.NoExpressionEvents = True
- self.do_label_magic ()
- #create a easy read line for the expression view, put the command into the edit box
- if self.radAll.get_active():
- self.entExpression.set_text("*")
- if self.radEvery.get_active():
- self.entExpression.set_text("*/" + self.entEvery.get_text())
- if self.radRange.get_active():
- self.entExpression.set_text(self.entRangeStart.get_text() + "-" + self.entRangeEnd.get_text())
- if self.radFix.get_active ():
- self.entExpression.set_text(self.entFix.get_text())
- self.NoExpressionEvents = False
+ def __init__(self, parent):
+ self.ParentClass = parent
+
+ self.xml = self.ParentClass.xml
+
+ self.NoExpressionEvents = False
+ self.fieldRegex = self.ParentClass.fieldRegex
+
+ self.widget = self.xml.get_widget("crontabEditorHelper")
+ self.widget.connect("delete-event", self.widget.hide_on_delete)
+
+ self.radAll = self.xml.get_widget("radAll")
+ self.radEvery = self.xml.get_widget("radEvery")
+ self.radRange = self.xml.get_widget("radRange")
+ self.radFix = self.xml.get_widget("radFix")
+ self.radOth = self.xml.get_widget ("radOth")
+
+ self.entExpression = self.xml.get_widget("entExpression")
+ self.entEvery = self.xml.get_widget("entEvery")
+ self.entFix = self.xml.get_widget("entFix")
+ self.entRangeStart = self.xml.get_widget("entRangeStart")
+ self.entRangeEnd = self.xml.get_widget("entRangeEnd")
+
+ self.header = self.xml.get_widget("label_crontab_editor_title")
+
+ self.lblEveryEntity = self.xml.get_widget("lblEveryEntity")
+ self.lblFixEntity = self.xml.get_widget("lblFixEntity")
+
+ #connect the radiobuttons toggle
+ self.xml.signal_connect("on_btnCancel_clicked", self.btnCancel_clicked)
+ self.xml.signal_connect("on_btnOk_clicked", self.btnOk_clicked)
+ self.xml.signal_connect("on_radAll_toggled", self.RadioButtonChange)
+ self.xml.signal_connect("on_radEvery_toggled", self.RadioButtonChange)
+ self.xml.signal_connect("on_radRange_toggled", self.RadioButtonChange)
+ self.xml.signal_connect("on_radFix_toggled", self.RadioButtonChange)
+ self.xml.signal_connect("on_radOth_toggled", self.RadioButtonChange)
+
+ #connect the changes of a combo or entry
+ self.xml.signal_connect("on_entFix_changed", self.anyEntryChanged)
+ self.xml.signal_connect("on_entEvery_changed", self.anyEntryChanged)
+ self.xml.signal_connect("on_entRangeStart_changed", self.anyEntryChanged)
+ self.xml.signal_connect("on_entRangeEnd_changed", self.anyEntryChanged)
+ self.xml.signal_connect("on_entExpression_changed", self.entExpressionChanged)
+
+ self.widgetgroups = { "radAll": [],
+ "radEvery":["entEvery", "lblEveryEntity"],
+ "radRange":["entRangeStart", "entRangeEnd",
+ "lblRangeStart", "lblRangeEnd"],
+ "radFix": ["entFix", "lblFixEntity"],
+ "radOth": ["entExpression",
+ "lblExpression"] }
+
+
+ def populateLabels(self, field):
+ #put the apropiate values in the labels describing entitys, and the 'at' combobox
+
+ if field == "minute":
+ self.entRangeEnd.set_text ("59")
+ self.entRangeStart.set_text ("0")
+ self.entFix.set_text("0")
+ self.radAll.set_label(_("Every minute"))
+
+ if field == "hour":
+ self.entRangeEnd.set_text ("23")
+ self.entRangeStart.set_text ("0")
+ self.entFix.set_text("0")
+ self.radAll.set_label(_("Every hour"))
+
+ if field == "day":
+ self.entRangeEnd.set_text ("31")
+ self.entRangeStart.set_text ("1")
+ self.entFix.set_text("1")
+ self.radAll.set_label(_("Every day"))
+
+ if field == "month":
+ self.entRangeEnd.set_text ("12")
+ self.entRangeStart.set_text ("1")
+ self.entFix.set_text("1")
+ self.radAll.set_label(_("Every month"))
+
+ if field == "weekday":
+ self.entRangeEnd.set_text ("7")
+ self.entRangeStart.set_text ("0")
+ self.entFix.set_text("0")
+ self.radAll.set_label(_("Every weekday"))
+
+
+ self.entEvery.set_text("2")
+ self.entExpression.set_text ("*")
+
+ self.trans_field = self.ParentClass.scheduler.translate_frequency (field)
+
+
+
+ self.do_label_magic ()
+
+
+ def show (self, field, expression):
+ self.field = field
+ self.populateLabels(field)
+
+ m = self.fieldRegex.match (expression)
+ self.radOth.set_active (True)
+
+ self.NoExpressionEvents = True
+ self.entExpression.set_text (expression)
+
+ if m != None:
+ if m.groups()[0] != None:
+ self.radAll.set_active (True)
+ # 10 * * * * command
+ # */2 * * * * command
+ if m.groups()[1] != None or m.groups()[2] != None:
+ if m.groups()[1] != None:
+ self.radFix.set_active (True)
+ self.entFix.set_text (m.groups()[1])
+ else:
+ self.radEvery.set_active (True)
+ self.entEvery.set_text (m.groups()[2])
+
+ # 1-10 * * * * command
+ if m.groups()[3] != None and m.groups()[4] != None:
+ self.radRange.set_active (True)
+ self.entRangeStart.set_text(m.groups()[3])
+ self.entRangeEnd.set_text (m.groups()[4])
+
+ # Unused
+ # 1,2,3,4 * * * * command
+ # if m.groups()[5] != None:
+ # self.radOth.set_active (True)
+ # fields = m.groups()[5].split (",")
+
+ self.NoExpressionEvents = False
+
+ #show the form
+ if field == "minute":
+ self.widget.set_title(_("Edit minute"))
+ elif field == "hour":
+ self.widget.set_title(_("Edit hour"))
+ elif field == "day":
+ self.widget.set_title(_("Edit day"))
+ elif field == "month":
+ self.widget.set_title(_("Edit month"))
+ elif field == "weekday":
+ self.widget.set_title(_("Edit weekday"))
+
+ self.widget.set_transient_for(self.ParentClass.widget)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.widget.show_all()
+
+
+ def btnOk_clicked(self, *args):
+ #move expression to field in editor and hide
+ expression = self.entExpression.get_text()
+ try:
+ self.ParentClass.scheduler.checkfield (expression, self.field)
+ except ValueError, ex:
+ x, y, z = ex
+ self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is invalid. Reason: %s") % (z)))
+ self.wrongdialog.run()
+ self.wrongdialog.destroy()
+ return
+
+ if self.field == "minute": self.ParentClass.minute_entry.set_text(expression)
+ if self.field == "hour": self.ParentClass.hour_entry.set_text(expression)
+ if self.field == "day": self.ParentClass.day_entry.set_text(expression)
+ if self.field == "month": self.ParentClass.month_entry.set_text(expression)
+ if self.field == "weekday": self.ParentClass.weekday_entry.set_text(expression)
+
+ self.widget.hide()
+
+
+ def btnCancel_clicked(self, *args):
+ #hide
+ self.widget.hide()
+ #return True
+
+
+ def RadioButtonChange(self, widget):
+ self.NoExpressionEvents = True
+ self.do_label_magic ()
+ name = widget.get_name()
+ if widget.get_active():
+ if name == "radAll":
+ self.entExpression.set_text("*")
+ elif name == "radEvery":
+ self.entExpression.set_text("*/" + self.entEvery.get_text())
+ elif name == "radRange":
+ self.entExpression.set_text(self.entRangeStart.get_text() + "-" + self.entRangeEnd.get_text())
+ elif name == "radFix":
+ self.entExpression.set_text(self.entFix.get_text())
+ self.NoExpressionEvents = False
+
+ for groupname, widgetlist in self.widgetgroups.iteritems():
+ state = groupname == name
+ for widgetname in widgetlist:
+ widget = self.xml.get_widget(widgetname)
+ widget.set_sensitive(state)
+
+
+ def do_label_magic (self):
+ translated = ["", ""]
+ if self.field == "minute":
+ #minute
+ translated[0] = _("At an exact minute")
+ translated[1] = _("Minute:")
+ elif self.field == "hour":
+ #hour
+ translated[0] = _("At an exact hour")
+ translated[1] = _("Hour:")
+ elif self.field == "day":
+ #day
+ translated[0] = _("On a day")
+ translated[1] = _("Day:")
+ elif self.field == "month":
+ #month
+ translated[0] = _("In a month")
+ translated[1] = _("Month:")
+ elif self.field == "weekday":
+ #weekday
+ translated[0] = _("On a weekday")
+ translated[1] = _("Weekday:")
+
+ self.radFix.set_label (translated[0])
+ self.lblFixEntity.set_label (translated[1])
+
+ translated[0] = _("In a step width")
+ if self.field == "minute":
+ translated[1] = _("Minutes:")
+ elif self.field == "hour":
+ translated[1] = _("Hours:")
+ elif self.field == "day":
+ translated[1] = _("Days:")
+ elif self.field == "month":
+ translated[1] = _("Months:")
+ elif self.field == "weekday":
+ translated[1] = _("Weekdays:")
+
+ self.radEvery.set_label (translated[0])
+ self.lblEveryEntity.set_label (translated[1])
+
+
+ def entExpressionChanged(self, *args):
+ if self.NoExpressionEvents == False:
+ self.radOth.set_active (True)
+
+
+ def anyEntryChanged(self, *args):
+ self.NoExpressionEvents = True
+ self.do_label_magic ()
+ #create a easy read line for the expression view, put the command into the edit box
+ if self.radAll.get_active():
+ self.entExpression.set_text("*")
+ if self.radEvery.get_active():
+ self.entExpression.set_text("*/" + self.entEvery.get_text())
+ if self.radRange.get_active():
+ self.entExpression.set_text(self.entRangeStart.get_text() + "-" + self.entRangeEnd.get_text())
+ if self.radFix.get_active ():
+ self.entExpression.set_text(self.entFix.get_text())
+ self.NoExpressionEvents = False
Modified: trunk/src/data.py
==============================================================================
--- trunk/src/data.py (original)
+++ trunk/src/data.py Sat Feb 14 21:20:56 2009
@@ -27,66 +27,66 @@
import config
class ConfigBackend:
-
- def __init__(self, parent, type):
-
- self.parent = parent
- self.type = "gconf"
-
- self.gconf_client = gconf.client_get_default()
- self.gconf_client.add_dir ("/apps/gnome-schedule", gconf.CLIENT_PRELOAD_NONE)
- self.gconf_client.notify_add ("/apps/gnome-schedule/advanced", self.on_gconfkey_advanced_changed)
-
- def get_not_inform_working_dir (self):
- if ((self.get_not_inform_working_dir_crontab () and self.get_not_inform_working_dir_at ()) or self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir")):
- return True
- else:
- return False
-
-
- def set_not_inform_working_dir (self, value):
- self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir", value)
-
- def get_not_inform_working_dir_crontab (self):
- return self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir_crontab")
-
- def set_not_inform_working_dir_crontab (self, value):
- self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir_crontab", value)
-
- def get_not_inform_working_dir_at (self):
- return self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir_at")
-
- def set_not_inform_working_dir_at (self, value):
- self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir_at", value)
-
-
- def set_window_state (self, x, y, height, width):
- self.gconf_client.set_int ("/apps/gnome-schedule/x", x)
- self.gconf_client.set_int ("/apps/gnome-schedule/y", y)
- self.gconf_client.set_int ("/apps/gnome-schedule/height", height)
- self.gconf_client.set_int ("/apps/gnome-schedule/width", width)
-
- def get_window_state (self):
- h = self.gconf_client.get_int ("/apps/gnome-schedule/height")
- w = self.gconf_client.get_int ("/apps/gnome-schedule/width")
- x = self.gconf_client.get_int ("/apps/gnome-schedule/x")
- y = self.gconf_client.get_int ("/apps/gnome-schedule/y")
- return x, y, h, w
-
- def get_advanced_option(self):
- return self.gconf_client.get_bool ("/apps/gnome-schedule/advanced")
-
-
- def set_advanced_option(self,value):
- self.gconf_client.set_bool ("/apps/gnome-schedule/advanced", value)
-
-
- def on_gconfkey_advanced_changed (self, client, connection_id, entry, args):
- val = self.gconf_client.get_bool ("/apps/gnome-schedule/advanced")
- if val:
- self.parent.switchView("advanced")
- else:
- self.parent.switchView("simple")
+
+ def __init__(self, parent, type):
+
+ self.parent = parent
+ self.type = "gconf"
+
+ self.gconf_client = gconf.client_get_default()
+ self.gconf_client.add_dir ("/apps/gnome-schedule", gconf.CLIENT_PRELOAD_NONE)
+ self.gconf_client.notify_add ("/apps/gnome-schedule/advanced", self.on_gconfkey_advanced_changed)
+
+ def get_not_inform_working_dir (self):
+ if ((self.get_not_inform_working_dir_crontab () and self.get_not_inform_working_dir_at ()) or self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir")):
+ return True
+ else:
+ return False
+
+
+ def set_not_inform_working_dir (self, value):
+ self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir", value)
+
+ def get_not_inform_working_dir_crontab (self):
+ return self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir_crontab")
+
+ def set_not_inform_working_dir_crontab (self, value):
+ self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir_crontab", value)
+
+ def get_not_inform_working_dir_at (self):
+ return self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir_at")
+
+ def set_not_inform_working_dir_at (self, value):
+ self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir_at", value)
+
+
+ def set_window_state (self, x, y, height, width):
+ self.gconf_client.set_int ("/apps/gnome-schedule/x", x)
+ self.gconf_client.set_int ("/apps/gnome-schedule/y", y)
+ self.gconf_client.set_int ("/apps/gnome-schedule/height", height)
+ self.gconf_client.set_int ("/apps/gnome-schedule/width", width)
+
+ def get_window_state (self):
+ h = self.gconf_client.get_int ("/apps/gnome-schedule/height")
+ w = self.gconf_client.get_int ("/apps/gnome-schedule/width")
+ x = self.gconf_client.get_int ("/apps/gnome-schedule/x")
+ y = self.gconf_client.get_int ("/apps/gnome-schedule/y")
+ return x, y, h, w
+
+ def get_advanced_option(self):
+ return self.gconf_client.get_bool ("/apps/gnome-schedule/advanced")
+
+
+ def set_advanced_option(self,value):
+ self.gconf_client.set_bool ("/apps/gnome-schedule/advanced", value)
+
+
+ def on_gconfkey_advanced_changed (self, client, connection_id, entry, args):
+ val = self.gconf_client.get_bool ("/apps/gnome-schedule/advanced")
+ if val:
+ self.parent.switchView("advanced")
+ else:
+ self.parent.switchView("simple")
Modified: trunk/src/gnome-schedule.glade
==============================================================================
--- trunk/src/gnome-schedule.glade (original)
+++ trunk/src/gnome-schedule.glade Sat Feb 14 21:20:56 2009
@@ -268,6 +268,19 @@
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <widget class="GtkCheckButton" id="cb_xoutput">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">X application</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_cb_xoutput_toggled"/>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="padding">5</property>
@@ -629,25 +642,6 @@
<placeholder/>
</child>
<child>
- <widget class="GtkCheckButton" id="cb_nooutput">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_No output (>/dev/null 2>&1)</property>
- <property name="use_underline">True</property>
- <property name="response_id">0</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_anybasic_entry_changed"/>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
<widget class="GtkEntry" id="entry_task">
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -696,6 +690,18 @@
<property name="x_options">GTK_FILL</property>
</packing>
</child>
+ <child>
+ <widget class="GtkComboBox" id="combo_output">
+ <property name="visible">True</property>
+ <signal name="changed" handler="on_combo_output_changed"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="position">1</property>
@@ -1435,6 +1441,60 @@
<property name="column_spacing">5</property>
<property name="row_spacing">1</property>
<child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
<widget class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
Modified: trunk/src/gnome-schedule.py
==============================================================================
--- trunk/src/gnome-schedule.py (original)
+++ trunk/src/gnome-schedule.py Sat Feb 14 21:20:56 2009
@@ -36,20 +36,20 @@
poscorrect_isset = os.getenv ("POSIXLY_CORRECT", False)
manual_poscorrect = False
if poscorrect_isset == False:
- os.putenv ("POSIXLY_CORRECT", "enabled")
- manual_poscorrect = True
+ os.putenv ("POSIXLY_CORRECT", "enabled")
+ manual_poscorrect = True
if __name__ == "__main__":
- signal.signal (signal.SIGINT, signal.SIG_DFL)
+ signal.signal (signal.SIGINT, signal.SIG_DFL)
debug_flag = None
if '--debug' in sys.argv:
- debug_flag = 1
+ debug_flag = 1
try:
- import pygtk
- #tell pyGTK, if possible, that we want GTKv2
- pygtk.require("2.0")
+ import pygtk
+ #tell pyGTK, if possible, that we want GTKv2
+ pygtk.require("2.0")
except:
#Some distributions come with GTK2, but not pyGTK
@@ -61,7 +61,7 @@
# TODO: Gnome specific
import gnome
import gnome.ui
-
+
except:
print _("You need to install pyGTK or GTKv2,\n"
"or set your PYTHONPATH correctly.\n"
Modified: trunk/src/lang.py
==============================================================================
--- trunk/src/lang.py (original)
+++ trunk/src/lang.py Sat Feb 14 21:20:56 2009
@@ -63,68 +63,68 @@
# Fallback to english if locale setting is unknown
# or translation for this locale is not available
if gettext.find(domain) == None:
- language = "C"
+ language = "C"
else:
- language = ""
+ language = ""
try:
- locale.setlocale(locale.LC_ALL, language)
+ locale.setlocale(locale.LC_ALL, language)
except:
- warnings.warn_explicit("Locale not supported by Python. Using the fallback 'C' locale.", Warning, "lang.py", "68")
+ warnings.warn_explicit("Locale not supported by Python. Using the fallback 'C' locale.", Warning, "lang.py", "68")
encoding = locale.getpreferredencoding(False)
language = locale.getlocale()[0]
if language == None:
- language = "C"
+ language = "C"
# Some locale stuff in this section to get
# translated time expressions out of system.
# Don't touch this. Change settings through gettext (po files)
def lc_weekday (weekday):
- weekday = int(weekday)
- if weekday >= 0 and weekday < 7:
- weekday = str(weekday)
- else:
- weekday = "0"
- timevalue = time.strptime(weekday, "%w")
- expression = time.strftime("%A", timevalue)
- return unicode(expression, encoding, 'ignore')
+ weekday = int(weekday)
+ if weekday >= 0 and weekday < 7:
+ weekday = str(weekday)
+ else:
+ weekday = "0"
+ timevalue = time.strptime(weekday, "%w")
+ expression = time.strftime("%A", timevalue)
+ return unicode(expression, encoding, 'ignore')
def lc_month (month):
- month = "%02d" % int(month)
- timevalue = time.strptime(month, "%m")
- expression = time.strftime("%B", timevalue)
- return unicode(expression, encoding, 'ignore')
+ month = "%02d" % int(month)
+ timevalue = time.strptime(month, "%m")
+ expression = time.strftime("%B", timevalue)
+ return unicode(expression, encoding, 'ignore')
def lc_date (day,month,year = None):
- day = "%02d" % int(day)
- month = "%02d" % int(month)
- if year == None:
- timevalue = time.strptime(("%s.%s" % (day, month)), "%d.%m")
- # Translators: Date format for expressions like 'January 21'. %B is month, %d is day number.
- # Run the command 'man strftime' to read more about these and other available specifiers.
- expression = time.strftime(_("%B %d"), timevalue)
- else:
- year = str(year)[-2:]
- year = "%02d" % int(year)
- timevalue = time.strptime(("%s.%s.%s" % (day, month, year)), "%d.%m.%y")
- # Translators: Date format for expressions like 'January 21, 2005'. %B is month, %d is day number, %Y is year with century.
- # Run the command 'man strftime' to read more about these and other available specifiers.
- expression = time.strftime(_("%B %d, %Y"), timevalue)
- return unicode(expression, encoding, 'ignore')
+ day = "%02d" % int(day)
+ month = "%02d" % int(month)
+ if year == None:
+ timevalue = time.strptime(("%s.%s" % (day, month)), "%d.%m")
+ # Translators: Date format for expressions like 'January 21'. %B is month, %d is day number.
+ # Run the command 'man strftime' to read more about these and other available specifiers.
+ expression = time.strftime(_("%B %d"), timevalue)
+ else:
+ year = str(year)[-2:]
+ year = "%02d" % int(year)
+ timevalue = time.strptime(("%s.%s.%s" % (day, month, year)), "%d.%m.%y")
+ # Translators: Date format for expressions like 'January 21, 2005'. %B is month, %d is day number, %Y is year with century.
+ # Run the command 'man strftime' to read more about these and other available specifiers.
+ expression = time.strftime(_("%B %d, %Y"), timevalue)
+ return unicode(expression, encoding, 'ignore')
def lc_time (hour,minute,second = None):
- hour = "%02d" % int(hour)
- minute = "%02d" % int(minute)
- if second == None:
- timevalue = time.strptime(("%s:%s" % (hour, minute)), "%H:%M")
- # Translators: Time without seconds. %H is hour, %M is minute.
- # Run the command 'man strftime' to read more about these and other available specifiers.
- expression = time.strftime(_("%H:%M"), timevalue)
- else:
- second = "%02d" % int(second)
- timevalue = time.strptime(("%s:%s:%s" % (hour, minute, second)), "%H:%M:%S")
- expression = time.strftime("%X", timevalue)
- return unicode(expression, encoding, 'ignore')
+ hour = "%02d" % int(hour)
+ minute = "%02d" % int(minute)
+ if second == None:
+ timevalue = time.strptime(("%s:%s" % (hour, minute)), "%H:%M")
+ # Translators: Time without seconds. %H is hour, %M is minute.
+ # Run the command 'man strftime' to read more about these and other available specifiers.
+ expression = time.strftime(_("%H:%M"), timevalue)
+ else:
+ second = "%02d" % int(second)
+ timevalue = time.strptime(("%s:%s:%s" % (hour, minute, second)), "%H:%M:%S")
+ expression = time.strftime("%X", timevalue)
+ return unicode(expression, encoding, 'ignore')
# So this is for the really really hard languages that have changing
@@ -133,162 +133,162 @@
# language. If you need assistance, read the AUTHORS file and try to
# contact us or use the mailinglists.
def translate_crontab_easy (minute, hour, day, month, weekday):
-# Add support for your language here
-# if language.find ("whatever") != -1:
-# return translate_crontab_easy_whatever (minute, hour, day, month, weekday)
-# else:
- return translate_crontab_easy_common (minute, hour, day, month, weekday)
+# Add support for your language here
+# if language.find ("whatever") != -1:
+# return translate_crontab_easy_whatever (minute, hour, day, month, weekday)
+# else:
+ return translate_crontab_easy_common (minute, hour, day, month, weekday)
# Translate Crontab expressions to human readable ones.
# Don't touch this function. Copy and modify it to create a special translation.
# Changes on this function affects all translations made through po files.
def translate_crontab_easy_common (minute, hour, day, month, weekday):
- # reboot
- if minute == "@reboot":
- return _("At reboot")
-
- # These are unsupported cases
- if minute.find ("/") != -1 or hour.find ("/") != -1 or day.find ("/") != -1 or month.find ("/") != -1 or weekday.find ("/") != -1:
- return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
- if minute.find ("-") != -1 or hour.find ("-") != -1 or day.find ("-") != -1 or month.find ("-") != -1 or weekday.find ("-") != -1:
- return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
- if minute.find (",") != -1 or hour.find (",") != -1 or day.find (",") != -1 or month.find (",") != -1 or weekday.find (",") != -1:
- return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
-
- # So if our case is supported:
-
- # Minute and hour cases
- if month == "*" and day == "*" and weekday == "*":
- if minute == "0" and hour == "*":
- return _("At every full hour")
- elif minute == "*" and hour == "*":
- return _("At every minute")
- elif minute != "*" and hour == "*":
- return (_("At minute %(minute)s of every hour") % { "minute": str(minute) } )
- elif minute == "*" and hour != "*":
- return (_("At every minute between %(time_from)s and %(time_to)s") % { "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
- elif hour != "*" and minute != "*":
- return (_("On every day at %(time)s") % { "time": lc_time(hour, minute) } )
-
- # Day cases
- if month == "*" and day != "*" and weekday == "*":
- if minute == "0" and hour == "*":
- return (_("On day %(monthday)s of every month at every full hour") % { "monthday": str(day) } )
- elif minute == "*" and hour == "*":
- return (_("On day %(monthday)s of every month at every minute") % { "monthday": str(day) } )
- elif minute != "*" and hour == "*":
- return (_("On day %(monthday)s of every month at minute %(minute)s of every hour") % { "monthday": str(day), "minute": str(minute) } )
- elif minute == "*" and hour != "*":
- return (_("On day %(monthday)s of every month at every minute between %(time_from)s and %(time_to)s") % { "monthday": str(day), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
- elif minute != "*" and hour != "*":
- return (_("On day %(monthday)s of every month at %(time)s") % { "monthday": str(day), "time": lc_time(hour, minute) } )
-
- # Month cases
- if month != "*" and weekday == "*" and day == "*":
- if minute == "0" and hour == "*":
- return (_("On every day in %(month)s at every full hour") % { "month": lc_month(month) } )
- elif minute == "*" and hour == "*":
- return (_("On every day in %(month)s at every minute") % { "month": lc_month(month) } )
- elif minute != "*" and hour == "*":
- return (_("On every day in %(month)s at minute %(minute)s of every hour") % { "month": lc_month(month), "minute": str(minute) } )
- elif minute == "*" and hour != "*":
- return (_("On every day in %(month)s at every minute between %(time_from)s and %(time_to)s") % { "month": lc_month(month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
- elif minute != "*" and hour != "*":
- return (_("On every day in %(month)s at %(time)s") % { "month": lc_month(month), "time": lc_time(hour, minute) } )
-
- # Day and month cases
- if month != "*" and weekday == "*" and day != "*":
- if minute == "0" and hour == "*":
- return (_("Every year on %(date)s at every full hour") % { "date": lc_date(day,month) } )
- elif minute == "*" and hour == "*":
- return (_("Every year on %(date)s at every minute") % { "date": lc_date(day,month) } )
- elif minute != "*" and hour == "*":
- return (_("Every year on %(date)s at minute %(minute)s of every hour") % { "date": lc_date(day,month), "minute": str(minute) } )
- elif minute == "*" and hour != "*":
- return (_("Every year on %(date)s at every minute between %(time_from)s and %(time_to)s") % { "date": lc_date(day,month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
- elif minute != "*" and hour != "*":
- return (_("Every year on %(date)s at %(time)s") % { "date": lc_date(day,month), "time": lc_time(hour, minute) } )
-
- # Weekday cases
- if month == "*" and day == "*" and weekday != "*":
- if minute == "0" and hour == "*":
- return (_("On every weekday: %(weekday)s at every full hour") % { "weekday": lc_weekday(weekday) } )
- elif minute == "*" and hour == "*":
- return (_("On every weekday: %(weekday)s at every minute") % { "weekday": lc_weekday(weekday) } )
- elif minute != "*" and hour == "*":
- return (_("On every weekday: %(weekday)s at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "minute": str(minute) } )
- elif minute == "*" and hour != "*":
- return (_("On every weekday: %(weekday)s at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
- elif minute != "*" and hour != "*":
- return (_("On every weekday: %(weekday)s at %(time)s") % { "weekday": lc_weekday(weekday), "time": lc_time(hour, minute) } )
-
- # Day and weekday cases
- if day != "*" and month == "*" and weekday != "*":
- if minute == "0" and hour == "*":
- return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every full hour") % { "monthday": str(day), "weekday": lc_weekday(weekday) } )
- elif minute == "*" and hour == "*":
- return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every minute") % { "monthday": str(day), "weekday": lc_weekday(weekday) } )
- elif minute != "*" and hour == "*":
- return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at minute %(minute)s of every hour") % { "monthday": str(day), "weekday": lc_weekday(weekday), "minute": str(minute) } )
- elif minute == "*" and hour != "*":
- return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every minute between %(time_from)s and %(time_to)s") % { "monthday": str(day), "weekday": lc_weekday(weekday), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
- elif minute != "*" and hour != "*":
- return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at %(time)s") % { "monthday": str(day), "weekday": lc_weekday(weekday), "time": lc_time(hour, minute) } )
-
- # Month and weekday cases
- if day == "*" and month != "*" and weekday != "*":
- if minute == "0" and hour == "*":
- return (_("On every weekday: %(weekday)s in %(month)s at every full hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month) } )
- elif minute == "*" and hour == "*":
- return (_("On every weekday: %(weekday)s in %(month)s at every minute") % { "weekday": lc_weekday(weekday), "month": lc_month(month) } )
- elif minute != "*" and hour == "*":
- return (_("On every weekday: %(weekday)s in %(month)s at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "minute": str(minute) } )
- elif minute == "*" and hour != "*":
- return (_("On every weekday: %(weekday)s in %(month)s at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
- elif minute != "*" and hour != "*":
- return (_("On every weekday: %(weekday)s in %(month)s at %(time)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "time": lc_time(hour, minute) } )
-
- # Day, month and weekday cases
- if day != "*" and month != "*" and weekday != "*":
- if minute == "0" and hour == "*":
- return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every full hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month) } )
- elif minute == "*" and hour == "*":
- return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every minute") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month) } )
- elif minute != "*" and hour == "*":
- return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "minute": str(minute) } )
- elif minute == "*" and hour != "*":
- return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
- elif minute != "*" and hour != "*":
- return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at %(time)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "time": lc_time(hour, minute) } )
+ # reboot
+ if minute == "@reboot":
+ return _("At reboot")
+
+ # These are unsupported cases
+ if minute.find ("/") != -1 or hour.find ("/") != -1 or day.find ("/") != -1 or month.find ("/") != -1 or weekday.find ("/") != -1:
+ return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
+ if minute.find ("-") != -1 or hour.find ("-") != -1 or day.find ("-") != -1 or month.find ("-") != -1 or weekday.find ("-") != -1:
+ return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
+ if minute.find (",") != -1 or hour.find (",") != -1 or day.find (",") != -1 or month.find (",") != -1 or weekday.find (",") != -1:
+ return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
+
+ # So if our case is supported:
+
+ # Minute and hour cases
+ if month == "*" and day == "*" and weekday == "*":
+ if minute == "0" and hour == "*":
+ return _("At every full hour")
+ elif minute == "*" and hour == "*":
+ return _("At every minute")
+ elif minute != "*" and hour == "*":
+ return (_("At minute %(minute)s of every hour") % { "minute": str(minute) } )
+ elif minute == "*" and hour != "*":
+ return (_("At every minute between %(time_from)s and %(time_to)s") % { "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+ elif hour != "*" and minute != "*":
+ return (_("On every day at %(time)s") % { "time": lc_time(hour, minute) } )
+
+ # Day cases
+ if month == "*" and day != "*" and weekday == "*":
+ if minute == "0" and hour == "*":
+ return (_("On day %(monthday)s of every month at every full hour") % { "monthday": str(day) } )
+ elif minute == "*" and hour == "*":
+ return (_("On day %(monthday)s of every month at every minute") % { "monthday": str(day) } )
+ elif minute != "*" and hour == "*":
+ return (_("On day %(monthday)s of every month at minute %(minute)s of every hour") % { "monthday": str(day), "minute": str(minute) } )
+ elif minute == "*" and hour != "*":
+ return (_("On day %(monthday)s of every month at every minute between %(time_from)s and %(time_to)s") % { "monthday": str(day), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+ elif minute != "*" and hour != "*":
+ return (_("On day %(monthday)s of every month at %(time)s") % { "monthday": str(day), "time": lc_time(hour, minute) } )
+
+ # Month cases
+ if month != "*" and weekday == "*" and day == "*":
+ if minute == "0" and hour == "*":
+ return (_("On every day in %(month)s at every full hour") % { "month": lc_month(month) } )
+ elif minute == "*" and hour == "*":
+ return (_("On every day in %(month)s at every minute") % { "month": lc_month(month) } )
+ elif minute != "*" and hour == "*":
+ return (_("On every day in %(month)s at minute %(minute)s of every hour") % { "month": lc_month(month), "minute": str(minute) } )
+ elif minute == "*" and hour != "*":
+ return (_("On every day in %(month)s at every minute between %(time_from)s and %(time_to)s") % { "month": lc_month(month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+ elif minute != "*" and hour != "*":
+ return (_("On every day in %(month)s at %(time)s") % { "month": lc_month(month), "time": lc_time(hour, minute) } )
+
+ # Day and month cases
+ if month != "*" and weekday == "*" and day != "*":
+ if minute == "0" and hour == "*":
+ return (_("Every year on %(date)s at every full hour") % { "date": lc_date(day,month) } )
+ elif minute == "*" and hour == "*":
+ return (_("Every year on %(date)s at every minute") % { "date": lc_date(day,month) } )
+ elif minute != "*" and hour == "*":
+ return (_("Every year on %(date)s at minute %(minute)s of every hour") % { "date": lc_date(day,month), "minute": str(minute) } )
+ elif minute == "*" and hour != "*":
+ return (_("Every year on %(date)s at every minute between %(time_from)s and %(time_to)s") % { "date": lc_date(day,month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+ elif minute != "*" and hour != "*":
+ return (_("Every year on %(date)s at %(time)s") % { "date": lc_date(day,month), "time": lc_time(hour, minute) } )
+
+ # Weekday cases
+ if month == "*" and day == "*" and weekday != "*":
+ if minute == "0" and hour == "*":
+ return (_("On every weekday: %(weekday)s at every full hour") % { "weekday": lc_weekday(weekday) } )
+ elif minute == "*" and hour == "*":
+ return (_("On every weekday: %(weekday)s at every minute") % { "weekday": lc_weekday(weekday) } )
+ elif minute != "*" and hour == "*":
+ return (_("On every weekday: %(weekday)s at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "minute": str(minute) } )
+ elif minute == "*" and hour != "*":
+ return (_("On every weekday: %(weekday)s at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+ elif minute != "*" and hour != "*":
+ return (_("On every weekday: %(weekday)s at %(time)s") % { "weekday": lc_weekday(weekday), "time": lc_time(hour, minute) } )
+
+ # Day and weekday cases
+ if day != "*" and month == "*" and weekday != "*":
+ if minute == "0" and hour == "*":
+ return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every full hour") % { "monthday": str(day), "weekday": lc_weekday(weekday) } )
+ elif minute == "*" and hour == "*":
+ return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every minute") % { "monthday": str(day), "weekday": lc_weekday(weekday) } )
+ elif minute != "*" and hour == "*":
+ return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at minute %(minute)s of every hour") % { "monthday": str(day), "weekday": lc_weekday(weekday), "minute": str(minute) } )
+ elif minute == "*" and hour != "*":
+ return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every minute between %(time_from)s and %(time_to)s") % { "monthday": str(day), "weekday": lc_weekday(weekday), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+ elif minute != "*" and hour != "*":
+ return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at %(time)s") % { "monthday": str(day), "weekday": lc_weekday(weekday), "time": lc_time(hour, minute) } )
+
+ # Month and weekday cases
+ if day == "*" and month != "*" and weekday != "*":
+ if minute == "0" and hour == "*":
+ return (_("On every weekday: %(weekday)s in %(month)s at every full hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month) } )
+ elif minute == "*" and hour == "*":
+ return (_("On every weekday: %(weekday)s in %(month)s at every minute") % { "weekday": lc_weekday(weekday), "month": lc_month(month) } )
+ elif minute != "*" and hour == "*":
+ return (_("On every weekday: %(weekday)s in %(month)s at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "minute": str(minute) } )
+ elif minute == "*" and hour != "*":
+ return (_("On every weekday: %(weekday)s in %(month)s at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+ elif minute != "*" and hour != "*":
+ return (_("On every weekday: %(weekday)s in %(month)s at %(time)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "time": lc_time(hour, minute) } )
+
+ # Day, month and weekday cases
+ if day != "*" and month != "*" and weekday != "*":
+ if minute == "0" and hour == "*":
+ return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every full hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month) } )
+ elif minute == "*" and hour == "*":
+ return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every minute") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month) } )
+ elif minute != "*" and hour == "*":
+ return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "minute": str(minute) } )
+ elif minute == "*" and hour != "*":
+ return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+ elif minute != "*" and hour != "*":
+ return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at %(time)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "time": lc_time(hour, minute) } )
- # If nothing got translated, we fall back to ...
- return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
+ # If nothing got translated, we fall back to ...
+ return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
# This is for cases that don't be covered by translate_crontab_easy
def translate_crontab_easy_fallback (minute, hour, day, month, weekday):
- if minute == "*":
- minute = _("every minute")
- else:
- minute = _("minute: %s") % (minute)
-
- if hour == "*":
- hour = _("every hour")
- else:
- hour = _("hour: %s") % (hour)
-
- if day == "*":
- day = _("every day of month")
- else:
- day = _("day of month: %s") % (day)
-
- if month == "*":
- month = _("every month")
- else:
- month = _("month: %s") % (month)
-
- if weekday == "*":
- return _("At %(minute)s, %(hour)s, %(monthday)s, %(month)s") % { "minute": minute, "hour": hour, "monthday": day, "month": month }
- else:
- weekday = _("weekday: %s") % (weekday)
- return _("At %(minute)s, %(hour)s, %(monthday)s, %(month)s, %(weekday)s") % { "minute": minute, "hour": hour, "monthday": day, "month": month, "weekday": weekday }
+ if minute == "*":
+ minute = _("every minute")
+ else:
+ minute = _("minute: %s") % (minute)
+
+ if hour == "*":
+ hour = _("every hour")
+ else:
+ hour = _("hour: %s") % (hour)
+
+ if day == "*":
+ day = _("every day of month")
+ else:
+ day = _("day of month: %s") % (day)
+
+ if month == "*":
+ month = _("every month")
+ else:
+ month = _("month: %s") % (month)
+
+ if weekday == "*":
+ return _("At %(minute)s, %(hour)s, %(monthday)s, %(month)s") % { "minute": minute, "hour": hour, "monthday": day, "month": month }
+ else:
+ weekday = _("weekday: %s") % (weekday)
+ return _("At %(minute)s, %(hour)s, %(monthday)s, %(month)s, %(weekday)s") % { "minute": minute, "hour": hour, "monthday": day, "month": month, "weekday": weekday }
Modified: trunk/src/mainWindow.py
==============================================================================
--- trunk/src/mainWindow.py (original)
+++ trunk/src/mainWindow.py Sat Feb 14 21:20:56 2009
@@ -22,7 +22,7 @@
import gtk.glade
import gobject
-# TODO: gnome specific
+# gnome specific
import gnome
from gnome import url_show
@@ -52,732 +52,740 @@
## The MainWindow class
##
class main:
- def __init__(self, debug_flag=None, inapplet=False, gprogram = None, manual_poscorrect=False):
- self.debug_flag = debug_flag
- self.inapplet = inapplet
- self.gprogram = gprogram
- self.manual_poscorrect = manual_poscorrect
-
- self.__loadIcon__()
- self.__loadGlade__()
-
- self.editor = None
- self.schedule = None
-
- self.noevents = False
-
- #start the backend where all the user configuration is stored
- self.backend = data.ConfigBackend(self, "gconf")
- self.template = template.Template (self, self.backend)
-
-
- ##configure the window
- self.widget = self.xml.get_widget("mainWindow")
-
- self.widget.connect("delete_event", self.__quit__)
- self.widget.connect("destroy_event", self.__quit__)
-
- self.widget.set_icon(self.iconPixbuf)
-
- #load state
- (x, y, h, w) = self.backend.get_window_state ()
- if (x and y):
- self.widget.move (x, y)
- if (h and w):
- self.widget.resize (h, w)
-
- self.widget.set_resizable (True)
-
- ##
-
-
- ##configure statusbar
- self.statusbar = self.xml.get_widget("statusbar")
-
- self.statusbarUser = self.statusbar.get_context_id("user")
- ##
-
- ##configure the toolbar
- self.toolbar = self.xml.get_widget ("toolbar")
- self.add_button = gtk.MenuToolButton (gtk.STOCK_NEW)
-
- self.add_button_menu = gtk.Menu ()
- self.add_button_menu_add_crontab = gtk.MenuItem ()
- self.add_button_menu_add_at = gtk.MenuItem ()
- self.add_button_menu_add_template = gtk.MenuItem ()
-
- self.recurrenthbox = gtk.HBox ()
- icon = gtk.Image ()
- icon.set_from_pixbuf (self.iconcrontab)
- label = gtk.Label (_("Recurrent task"))
- icon.set_alignment (0, 0.5)
- label.set_justify (gtk.JUSTIFY_LEFT)
- label.set_alignment (0, 0.5)
- self.recurrenthbox.pack_start (icon, False, False, 2)
- self.recurrenthbox.pack_start (label, True, True, 2)
- self.add_button_menu_add_crontab.add (self.recurrenthbox)
-
- self.onetimehbox = gtk.HBox ()
- icon = gtk.Image ()
- icon.set_from_pixbuf (self.iconat)
- label = gtk.Label (_("One-time task"))
- icon.set_alignment (0, 0.5)
- label.set_justify (gtk.JUSTIFY_LEFT)
- label.set_alignment (0, 0.5)
- self.onetimehbox.pack_start (icon, False, False, 2)
- self.onetimehbox.pack_start (label, True, True, 2)
- self.add_button_menu_add_at.add (self.onetimehbox)
-
- self.templatehbox = gtk.HBox ()
- icon = gtk.Image ()
- icon.set_from_pixbuf (self.icontemplate)
- label = gtk.Label (_("From template"))
- icon.set_alignment (0, 0.5)
- label.set_justify (gtk.JUSTIFY_LEFT)
- label.set_alignment (0, 0.5)
- self.templatehbox.pack_start (icon, False, False, 2)
- self.templatehbox.pack_start (label, True, True, 2)
- self.add_button_menu_add_template.add (self.templatehbox)
-
- self.add_button_menu.append (self.add_button_menu_add_crontab)
- self.add_button_menu.append (self.add_button_menu_add_at)
- self.add_button_menu.append (self.add_button_menu_add_template)
-
- self.add_button.set_menu (self.add_button_menu)
-
- self.toolbar.insert (self.add_button, 0)
- self.add_button.set_is_important (True)
- tip = gtk.Tooltips ()
- tip.enable ()
-
- self.add_button.set_tooltip (tip, _("Add a new task"), tip_private=None)
- self.add_button.show_all ()
- self.add_button_menu.show_all ()
- self.add_button_menu_add_crontab.show_all ()
- self.add_button_menu_add_at.show_all ()
-
- self.add_button.connect ("clicked", self.on_add_button_clicked)
- self.add_button_menu_add_crontab.connect ("activate", self.on_add_crontab_task)
- self.add_button_menu_add_at.connect ("activate", self.on_add_at_task)
- self.add_button_menu_add_template.connect ("activate", self.on_add_from_template)
-
-
- self.prop_button = self.xml.get_widget ("prop_button")
- self.del_button = self.xml.get_widget ("del_button")
- self.run_button = self.xml.get_widget ("run_button")
- self.help_button = self.xml.get_widget ("help_button")
- self.btnSetUser = self.xml.get_widget("btnSetUser")
- self.btnExit = self.xml.get_widget("btnExit")
- self.about_button = self.xml.get_widget ("about_button")
- self.edit_mode_button = self.xml.get_widget ("edit_mode_button")
- self.button_template = self.xml.get_widget ("button_m_template")
-
- icon = gtk.Image()
- icon.set_from_pixbuf (self.normalicontemplate)
- self.button_template.set_icon_widget (icon)
- icon.show ()
-
- self.prop_button.set_sensitive (False)
- self.del_button.set_sensitive (False)
- self.run_button.set_sensitive (False)
-
- self.xml.signal_connect("on_prop_button_clicked", self.on_prop_button_clicked)
- self.xml.signal_connect("on_del_button_clicked", self.on_del_button_clicked)
- self.xml.signal_connect("on_help_button_clicked", self.on_help_button_clicked)
- self.xml.signal_connect("on_btnSetUser_clicked", self.on_btnSetUser_clicked)
- self.xml.signal_connect("on_about_menu_activate", self.on_about_menu_activate)
- self.xml.signal_connect("on_edit_mode_button_clicked", self.on_advanced_menu_activate)
- self.xml.signal_connect("on_btnExit_clicked", self.__quit__)
- self.xml.signal_connect("on_mainWindow_delete_event", self.__quit__)
- self.xml.signal_connect("on_run_button_clicked", self.on_run_button_clicked)
-
- self.xml.signal_connect ("on_button_m_template_clicked", self.on_template_manager_button)
-
- ##inittializing the treeview and treemodel
- ## somethins not rite here..:
- ## [0 Title, 1 Frequency, 2 Command, 3 Crontab record, 4 ID, 5 Time, 6 Icon, 7 scheduled instance, 8 icon path, 9 date, 10 class_id, 11 user, 12 time, 13 type, 14 crontab/at, 15 advanced time string]
- ##for at this would be like:
-
+ def __init__(self, debug_flag=None, inapplet=False, gprogram = None, manual_poscorrect=False):
+ self.debug_flag = debug_flag
+ self.inapplet = inapplet
+ self.gprogram = gprogram
+ self.manual_poscorrect = manual_poscorrect
+
+ self.__loadIcon__()
+ self.__loadGlade__()
+
+ self.editor = None
+ self.schedule = None
+
+ self.noevents = False
+
+ # Common string representation for the different output modes
+ self.output_strings = [
+ _("Default behaviour"),
+ _("Supress output"),
+ _("X application"),
+ _("X application: supress output"),
+ ]
+
+ #start the backend where all the user configuration is stored
+ self.backend = data.ConfigBackend(self, "gconf")
+ self.template = template.Template (self, self.backend)
+
+
+ ##configure the window
+ self.widget = self.xml.get_widget("mainWindow")
+
+ self.widget.connect("delete_event", self.__quit__)
+ self.widget.connect("destroy_event", self.__quit__)
+
+ self.widget.set_icon(self.iconPixbuf)
+
+ #load state
+ (x, y, h, w) = self.backend.get_window_state ()
+ if (x and y):
+ self.widget.move (x, y)
+ if (h and w):
+ self.widget.resize (h, w)
+
+ self.widget.set_resizable (True)
+
+ ##
+
+
+ ##configure statusbar
+ self.statusbar = self.xml.get_widget("statusbar")
+
+ self.statusbarUser = self.statusbar.get_context_id("user")
+ ##
+
+ ##configure the toolbar
+ self.toolbar = self.xml.get_widget ("toolbar")
+ self.add_button = gtk.MenuToolButton (gtk.STOCK_NEW)
+
+ self.add_button_menu = gtk.Menu ()
+ self.add_button_menu_add_crontab = gtk.MenuItem ()
+ self.add_button_menu_add_at = gtk.MenuItem ()
+ self.add_button_menu_add_template = gtk.MenuItem ()
+
+ self.recurrenthbox = gtk.HBox ()
+ icon = gtk.Image ()
+ icon.set_from_pixbuf (self.iconcrontab)
+ label = gtk.Label (_("Recurrent task"))
+ icon.set_alignment (0, 0.5)
+ label.set_justify (gtk.JUSTIFY_LEFT)
+ label.set_alignment (0, 0.5)
+ self.recurrenthbox.pack_start (icon, False, False, 2)
+ self.recurrenthbox.pack_start (label, True, True, 2)
+ self.add_button_menu_add_crontab.add (self.recurrenthbox)
+
+ self.onetimehbox = gtk.HBox ()
+ icon = gtk.Image ()
+ icon.set_from_pixbuf (self.iconat)
+ label = gtk.Label (_("One-time task"))
+ icon.set_alignment (0, 0.5)
+ label.set_justify (gtk.JUSTIFY_LEFT)
+ label.set_alignment (0, 0.5)
+ self.onetimehbox.pack_start (icon, False, False, 2)
+ self.onetimehbox.pack_start (label, True, True, 2)
+ self.add_button_menu_add_at.add (self.onetimehbox)
+
+ self.templatehbox = gtk.HBox ()
+ icon = gtk.Image ()
+ icon.set_from_pixbuf (self.icontemplate)
+ label = gtk.Label (_("From template"))
+ icon.set_alignment (0, 0.5)
+ label.set_justify (gtk.JUSTIFY_LEFT)
+ label.set_alignment (0, 0.5)
+ self.templatehbox.pack_start (icon, False, False, 2)
+ self.templatehbox.pack_start (label, True, True, 2)
+ self.add_button_menu_add_template.add (self.templatehbox)
+
+ self.add_button_menu.append (self.add_button_menu_add_crontab)
+ self.add_button_menu.append (self.add_button_menu_add_at)
+ self.add_button_menu.append (self.add_button_menu_add_template)
+
+ self.add_button.set_menu (self.add_button_menu)
+
+ self.toolbar.insert (self.add_button, 0)
+ self.add_button.set_is_important (True)
+ tip = gtk.Tooltips ()
+ tip.enable ()
+
+ self.add_button.set_tooltip (tip, _("Add a new task"), tip_private=None)
+ self.add_button.show_all ()
+ self.add_button_menu.show_all ()
+ self.add_button_menu_add_crontab.show_all ()
+ self.add_button_menu_add_at.show_all ()
+
+ self.add_button.connect ("clicked", self.on_add_button_clicked)
+ self.add_button_menu_add_crontab.connect ("activate", self.on_add_crontab_task)
+ self.add_button_menu_add_at.connect ("activate", self.on_add_at_task)
+ self.add_button_menu_add_template.connect ("activate", self.on_add_from_template)
+
+
+ self.prop_button = self.xml.get_widget ("prop_button")
+ self.del_button = self.xml.get_widget ("del_button")
+ self.run_button = self.xml.get_widget ("run_button")
+ self.help_button = self.xml.get_widget ("help_button")
+ self.btnSetUser = self.xml.get_widget("btnSetUser")
+ self.btnExit = self.xml.get_widget("btnExit")
+ self.about_button = self.xml.get_widget ("about_button")
+ self.edit_mode_button = self.xml.get_widget ("edit_mode_button")
+ self.button_template = self.xml.get_widget ("button_m_template")
+
+ icon = gtk.Image ()
+ icon.set_from_pixbuf (self.normalicontemplate)
+ self.button_template.set_icon_widget (icon)
+ icon.show ()
+
+ self.prop_button.set_sensitive (False)
+ self.del_button.set_sensitive (False)
+ self.run_button.set_sensitive (False)
+
+ self.xml.signal_connect("on_prop_button_clicked", self.on_prop_button_clicked)
+ self.xml.signal_connect("on_del_button_clicked", self.on_del_button_clicked)
+ self.xml.signal_connect("on_help_button_clicked", self.on_help_button_clicked)
+ self.xml.signal_connect("on_btnSetUser_clicked", self.on_btnSetUser_clicked)
+ self.xml.signal_connect("on_about_menu_activate", self.on_about_menu_activate)
+ self.xml.signal_connect("on_edit_mode_button_clicked", self.on_advanced_menu_activate)
+ self.xml.signal_connect("on_btnExit_clicked", self.__quit__)
+ self.xml.signal_connect("on_mainWindow_delete_event", self.__quit__)
+ self.xml.signal_connect("on_run_button_clicked", self.on_run_button_clicked)
+
+ self.xml.signal_connect ("on_button_m_template_clicked", self.on_template_manager_button)
+
+ ##inittializing the treeview and treemodel
+ ## somethins not rite here..:
+ ## [0 Title, 1 Frequency, 2 Command, 3 Crontab record, 4 ID, 5 Time, 6 Icon, 7 scheduled instance, 8 icon path, 9 date, 10 class_id, 11 user, 12 time, 13 type, 14 crontab/at, 15 advanced time string]
+ ##for at this would be like:
+
# ["untitled", "12:50 2004-06-25", "preview", "script", "job_id", "12:50", icon, at instance, icon_path, "2004-06-25", "a", "drzap", "at"]
- ##for crontab it would be:
-
+ ##for crontab it would be:
+
# ["untitled", "every hour", "ls /", "0 * * * * ls / # untitled", "5", "0 * * * *", icon, crontab instance,icon_path, 1(job_id), "", "", "crontab"]
- self.treemodel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING, gtk.gdk.Pixbuf, gobject.TYPE_PYOBJECT, gobject.TYPE_STRING , gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING)
-
- self.treeview = self.xml.get_widget("treeview")
-
- self.xml.signal_connect("on_treeview_button_press_event", self.on_treeview_button_press_event)
- self.xml.signal_connect("on_treeview_key_press_event", self.on_treeview_key_pressed)
-
- self.treeview.set_model (self.treemodel)
- self.treeview.get_selection().connect("changed", self.on_TreeViewSelectRow)
-
- #enable or disable advanced depending on user config
- self.noevents = True
- if self.backend.get_advanced_option():
- self.switchView("advanced")
- self.edit_mode_button.set_active (True)
- else:
- self.switchView("simple")
- self.edit_mode_button.set_active (False)
- self.noevents = False
-
-
- self.__initUser__()
-
- ##create crontab
- self.crontab = crontab.Crontab(self.root, self.user, self.uid, self.gid, self.user_home_dir)
- self.crontab_editor = crontabEditor.CrontabEditor(self, self.backend, self.crontab, self.template)
- ##
-
- ##create at
- self.at = at.At(self.root, self.user, self.uid, self.gid, self.user_home_dir, self.manual_poscorrect)
- self.at_editor = atEditor.AtEditor (self, self.backend, self.at, self.template)
- ##
-
- #set user window
- self.setuserWindow = setuserWindow.SetuserWindow (self)
-
- #set add window
- self.addWindow = addWindow.AddWindow (self)
-
- # template windows
- self.template_chooser = template_chooser.TemplateChooser (self, self.template)
- self.template_manager = template_manager.TemplateManager (self, self.template)
-
- self.schedule_reload ()
-
- self.timeout_handler_id = gobject.timeout_add(9000, self.update_schedule)
-
- # temporary files to be deleted
- self.temp_files = []
-
- if inapplet == False:
- gtk.main()
-
-
- def update_schedule(self):
- selection = self.treeview.get_selection()
- model, iter, = selection.get_selected()
- if iter:
- path = model.get_path(iter)
- self.schedule_reload ()
- if iter:
- selection.select_path(path)
- return True
-
- def changeUser(self,user):
- if user != self.user:
- self.__setUser__(user)
- #change user for the schedulers
- self.crontab.set_rights(self.user, self.uid, self.gid, self.user_home_dir)
- self.at.set_rights(self.user, self.uid, self.gid, self.user_home_dir)
- #adjust statusbar
- if self.root == 1:
- self.statusbar.push(self.statusbarUser, (_("Editing user: %s") % (self.user)))
-
- self.schedule_reload ()
-
-
- def __setUser__(self,user):
- userdb = pwd.getpwnam(user)
- self.user = user
- self.uid = userdb[2]
- self.gid = userdb[3]
- self.user_home_dir = userdb[5]
- self.user_shell = userdb[6]
-
-
- ## TODO: 2 times a loop looks to mutch
- def schedule_reload (self):
- self.treemodel.clear ()
-
- data = self.crontab.read ()
- if data != None:
- self.__fill__ (data)
-
- data = self.at.read ()
- if data != None:
- self.__fill__ (data)
-
-
-
-
- def __fill__ (self, records):
- for title, timestring_show, preview, lines, job_id, timestring, scheduler, icon, date, class_id, user, time, typetext, type, nooutput, timestring_advanced in records:
-
- if scheduler.get_type() == "crontab":
- iter = self.treemodel.append([title, timestring_show, preview, lines, job_id, timestring, self.iconcrontab, scheduler, icon, date, class_id, user, time, typetext, type, nooutput, timestring_advanced])
- elif scheduler.get_type() == "at":
- iter = self.treemodel.append([title, timestring_show, preview, lines, job_id, timestring, self.iconat, scheduler, icon, date, class_id, user, time, typetext, type, nooutput, timestring_advanced])
-
-
-
- def __loadIcon__(self):
- if self.debug_flag:
- if os.access("../icons/gnome-schedule.svg", os.F_OK):
- self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/gnome-schedule.svg", 52, 52)
- else:
- try:
- self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/gnome-schedule.svg", 52, 52)
- except:
- print _("ERROR: Could not load icon")
-
- if self.debug_flag:
- if os.access ("../icons/crontab.svg", os.F_OK):
- self.iconcrontab = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/crontab.svg", 19, 19)
- self.bigiconcrontab = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/crontab.svg", 49, 49)
- else:
- try:
- self.iconcrontab = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/crontab.svg", 19, 19)
- self.bigiconcrontab = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/crontab.svg", 49, 49)
- except:
- print _("ERROR: Could not load icon")
-
- if self.debug_flag:
- if os.access ("../icons/calendar.svg", os.F_OK):
- self.iconcalendar = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/calendar.svg", 19, 19)
- self.bigiconcalendar = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/calendar.svg", 49, 49)
- else:
- try:
- self.iconcalendar = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/calendar.svg", 19, 19)
- self.bigiconcalendar = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/calendar.svg", 49, 49)
- except:
- print _("ERROR: Could not load icon")
-
- if self.debug_flag:
- if os.access ("../icons/template.svg", os.F_OK):
- self.icontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 19, 19)
- self.normalicontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 25, 25)
- self.bigicontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 49, 49)
- self.pathicontemplate = "../icons/template.svg"
- else:
- try:
- self.icontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 19, 19)
- self.normalicontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 25, 25)
- self.bigicontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 49, 49)
- self.pathicontemplate = config.getImagedir() + "/template.svg"
- except:
- print _("ERROR: Could not load icon")
-
- if self.debug_flag:
- if os.access ("../icons/at.svg", os.F_OK):
- self.iconat = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/at.svg", 19, 19)
- self.bigiconat = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/at.svg", 49, 49)
- else:
- try:
- self.iconat = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/at.svg", 19, 19)
- self.bigiconat = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/at.svg", 49, 49)
- except:
- print _("ERROR: Could not load icon")
-
-
- def __loadGlade__(self):
- if self.debug_flag:
- if os.access("gnome-schedule.glade", os.F_OK):
- try:
- self.xml = gtk.glade.XML ("gnome-schedule.glade", domain="gnome-schedule")
- except:
- print _("ERROR: Could not load glade file")
- quit ()
- else:
- try:
- self.xml = gtk.glade.XML (config.getGladedir() + "/gnome-schedule.glade", domain="gnome-schedule")
- except:
- print _("ERROR: Could not load glade file")
- quit ()
-
-
-
- def __initUser__(self):
- self.uid = os.geteuid()
- self.gid = os.getegid()
- self.user = pwd.getpwuid(self.uid)[0]
- self.user_home_dir = pwd.getpwuid(self.uid)[5]
- self.user_shell = pwd.getpwuid(self.uid)[6]
-
- if self.uid != 0:
- self.btnSetUser.hide()
- self.statusbar.hide()
- self.root = 0
- else:
- self.root = 1
- self.btnSetUser.show()
- self.statusbar.show()
- self.statusbar.push(self.statusbarUser, (_("Editing user: %s") % (self.user)))
-
-
- #when the user selects a task, buttons get enabled
- def on_TreeViewSelectRow (self, *args):
- if self.treeview.get_selection().count_selected_rows() > 0 :
- value = True
- else:
- value = False
-
- self.prop_button.set_sensitive (value)
- self.del_button.set_sensitive (value)
- self.run_button.set_sensitive (value)
-
-
-
- #clean existing columns
- def __cleancolumns__ (self):
- columns = len(self.treeview.get_columns()) -1
- while columns > -1:
- temp = self.treeview.get_column(columns)
- self.treeview.remove_column(temp)
- columns = columns - 1
-
-
- #switch between advanced and simple mode
- def switchView(self, mode = "simple"):
- self.__cleancolumns__ ()
-
- self.treeview.get_selection().unselect_all()
- self.edit_mode = mode
-
- cell = gtk.CellRendererPixbuf()
- cell.set_fixed_size(21,21)
- cell2 = gtk.CellRendererText ()
- col = gtk.TreeViewColumn (_("Task"), None)
- col.pack_start (cell, True)
- col.pack_end (cell2, True)
- col.add_attribute (cell, "pixbuf", 6)
- if mode == "simple":
- col.add_attribute (cell2, "text", 13)
- else:
- col.add_attribute (cell2, "text", 14)
-
- self.treeview.append_column(col)
-
- if mode == "simple":
-
- col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text=0)
- col.set_resizable (True)
- self.treeview.append_column(col)
-
- col = gtk.TreeViewColumn(_("Date and Time"), gtk.CellRendererText(), text=1)
- col.set_resizable (True)
- self.treeview.append_column(col)
-
- col = gtk.TreeViewColumn(_("Command preview"), gtk.CellRendererText(), text=2)
- col.set_resizable (True)
- col.set_expand (True)
- self.treeview.append_column(col)
-
-
-
- elif mode == "advanced":
-
- col = gtk.TreeViewColumn(_("Date and Time"), gtk.CellRendererText(), text=16)
- col.set_resizable (True)
- self.treeview.append_column(col)
-
- col = gtk.TreeViewColumn(_("Command preview"), gtk.CellRendererText(), text=2)
- col.set_resizable (True)
- col.set_expand (True)
- self.treeview.append_column(col)
-
- col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text=0)
- col.set_resizable (True)
- self.treeview.append_column(col)
-
-
-
- def on_advanced_menu_activate (self, widget):
- if self.noevents == False:
- if self.backend.get_advanced_option():
- self.backend.set_advanced_option(0)
- else:
- self.backend.set_advanced_option(1)
-
- def on_add_at_task (self, *args):
- self.addWindow.mode = 0
- self.addWindow.on_button_at_clicked (*args)
-
- def on_add_crontab_task (self, *args):
- self.addWindow.mode = 0
- self.addWindow.on_button_crontab_clicked (*args)
-
- def on_add_from_template (self, *args):
- self.addWindow.mode = 0
- self.addWindow.on_button_template_clicked (*args)
-
- def on_template_manager_button (self, *args):
- self.template_manager.show (self.widget)
-
- def on_add_scheduled_task_menu_activate (self, *args):
- self.addWindow.ShowAddWindow (self.widget)
-
- def on_properties_menu_activate (self, *args):
- store, iter = self.treeview.get_selection().get_selected()
-
- try:
- #see what scheduler (at, crontab or ...)
- self.schedule = self.treemodel.get_value(iter, 7)
-
-
-
- record = self.treemodel.get_value(iter, 3)
- linenumber = self.treemodel.get_value(iter, 4)
-
- # TODO: dirty hacky
- if self.schedule.get_type() == "crontab":
- self.editor = self.crontab_editor
- job_id = self.treemodel.get_value (iter, 9)
- self.editor.showedit (self.widget, record, job_id, linenumber, iter)
- else:
- self.editor = self.at_editor
- self.editor.showedit (self.widget, record, linenumber, iter)
-
- except Exception, ex:
- #print ex
- self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task"))
- self.dialog.run ()
- self.dialog.destroy ()
-
-
- # TODO: looks not that clean (is broken)
- def on_delete_menu_activate (self, *args):
- dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("Do you want to delete this task?"))
- if (dialog.run() != gtk.RESPONSE_YES):
- dialog.destroy()
- del dialog
- return
- dialog.destroy()
- del dialog
-
- store, iter = self.treeview.get_selection().get_selected()
-
- try:
- #see what scheduler (at, crontab or ...)
- self.schedule = self.treemodel.get_value(iter, 7)
-
- # TODO: dirty hacky
- if self.schedule.get_type() == "crontab":
- self.editor = self.crontab_editor
- elif self.schedule.get_type() == "at":
- self.editor = self.at_editor
-
- record = self.treemodel.get_value(iter, 3)
- linenumber = self.treemodel.get_value(iter, 4)
-
- path = self.treemodel.get_path(iter)
- pathint = path[0]
- backpath = (pathint - 1,)
-
- if self.schedule.get_type() == "crontab":
- self.schedule.delete (linenumber, iter, self.treemodel.get_value(iter, 9))
- elif self.schedule.get_type() == "at":
- self.schedule.delete (linenumber, iter)
-
- self.schedule_reload()
-
- firstiter = self.treemodel.get_iter_first()
- try:
- nextiter = self.treemodel.get_iter(path)
- #go next
- selection = self.treeview.get_selection()
- selection.select_iter(nextiter)
-
- except:
- if backpath[0] > 0:
- nextiter = self.treemodel.get_iter(backpath)
- #go back
- selection = self.treeview.get_selection()
- selection.select_iter(nextiter)
-
- else:
- if firstiter:
- #go first
- selection = self.treeview.get_selection()
- selection.select_iter(firstiter)
-
- except Exception, ex:
- #print ex
- self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task"))
- self.dialog.run ()
- self.dialog.destroy ()
-
- def on_set_user_menu_activate(self, *args):
- self.setuserWindow.ShowSetuserWindow()
-
-
- def on_btnSetUser_clicked(self, *args):
- self.on_set_user_menu_activate(self, args)
-
- def on_add_button_clicked (self, *args):
- self.on_add_scheduled_task_menu_activate (self, args)
-
- def on_prop_button_clicked (self, *args):
- self.on_properties_menu_activate (self, args)
-
- def on_del_button_clicked (self, *args):
- self.on_delete_menu_activate (self, args)
-
- def on_help_button_clicked (self, *args):
- self.on_manual_menu_activate (self, args)
-
-
- def on_treeview_key_pressed (self, widget, event):
- key = gtk.gdk.keyval_name(event.keyval)
- #remove task from list with DEL key
- if key == "Delete" or key == "KP_Delete":
- self.on_delete_menu_activate()
- #display properties with ENTER key
- if (key == "Return" or key == "KP_Return"):
- self.on_properties_menu_activate(self, widget)
-
-
- #double click on task to get properties
- def on_treeview_button_press_event (self, widget, event):
- if event.type == gtk.gdk._2BUTTON_PRESS:
- self.on_properties_menu_activate(self, widget)
-
-
- #about box
- def open_url (self, *args):
- url_show("http://gnome-schedule.sourceforge.net")
-
-
-
- def on_run_button_clicked (self, *args):
- dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_NONE, _("Are you sure you want to run this task now?\n\nThis is used to preview the task and initiates a one-time run, this does not affect the normal scheduled run times."))
- dialog.add_buttons (gtk.STOCK_EXECUTE, gtk.RESPONSE_YES, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
- dialog.set_title (_("Are you sure you want to run this task?"))
- if (dialog.run() != gtk.RESPONSE_YES):
- dialog.destroy()
- del dialog
- return
- dialog.destroy()
- del dialog
-
- if (self.backend.get_not_inform_working_dir() != True):
- dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nRecurrent tasks will be run from the home directory, one-time tasks from the directory where Gnome schedule was run from at the time of task creation (normally the home directory)."))
- dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
- dia2.set_title (_("Warning: Working directory of executed tasks"))
- response = dia2.run ()
- if response == gtk.RESPONSE_CANCEL:
- dia2.destroy ()
- del dia2
- return
- elif response == gtk.RESPONSE_CLOSE:
- self.backend.set_not_inform_working_dir (True)
- else:
- pass
- dia2.destroy ()
- del dia2
-
- store, iter = self.treeview.get_selection().get_selected()
-
- try:
- # commands are at model[3]
-
- #see what scheduler (at, crontab or ...)
- self.schedule = self.treemodel.get_value(iter, 7)
-
- tmpfile = tempfile.mkstemp ()
- fd, path = tmpfile
- tmp = os.fdopen (fd, 'w')
-
- commands = self.treemodel.get_value(iter, 3)
- linenumber = self.treemodel.get_value(iter, 4)
-
-
- if self.schedule.get_type () == "at":
- script = os.popen (config.getAtbin () + " -c " + str (linenumber)).read ()
- elif self.schedule.get_type () == "crontab":
- script = self.schedule.parse (commands)[1][5]
-
- # left untranslated to protect against any 'translation attacks'..
- script = script + "\necho " + "Press ENTER to continue and close this window." + "\n"
- script = script + "read\nexit\n"
- tmp.write (script)
- tmp.flush ()
- self.temp_files.append ((tmp, path))
-
-
- execute = self.user_shell + " " + path
-
- if self.root == 1:
- if self.user != "root":
- execute = "su " + self.user + " -c \"" + self.user_shell + " " + path
- os.chown (path, self.uid, self.gid)
- os.chmod (path, stat.S_IEXEC | stat.S_IREAD)
-
-
- gnome.execute_terminal_shell (self.user_home_dir, execute)
-
-
-
- except Exception, ex:
- print ex
- self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task!"))
- self.dialog.run ()
- self.dialog.destroy ()
-
- def on_about_menu_activate (self, *args):
-
- gtk.about_dialog_set_url_hook(self.open_url, "bogusbar")
- dlg = gtk.AboutDialog ()
- dlg.set_title (_("About Gnome Schedule"))
- dlg.set_name (_("Gnome Schedule"))
- dlg.set_version (config.getVersion())
- dlg.set_copyright (_("Copyright (c) %(year)s %(name)s.") % ({ 'year' : "2004-2008", 'name' : "Gaute Hope"}))
- #dlg.set_comments ()
- #dlg.set_license ()
- dlg.set_website ("http://gnome-schedule.sourceforge.net")
- dlg.set_website_label("http://gnome-schedule.sourceforge.net")
- dlg.set_authors (
- ["Gaute Hope <eg gaute vetsj com>",
+ self.treemodel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING, gtk.gdk.Pixbuf, gobject.TYPE_PYOBJECT, gobject.TYPE_STRING , gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING)
+
+ self.treeview = self.xml.get_widget("treeview")
+
+ self.xml.signal_connect("on_treeview_button_press_event", self.on_treeview_button_press_event)
+ self.xml.signal_connect("on_treeview_key_press_event", self.on_treeview_key_pressed)
+
+ self.treeview.set_model (self.treemodel)
+ self.treeview.get_selection().connect("changed", self.on_TreeViewSelectRow)
+
+ #enable or disable advanced depending on user config
+ self.noevents = True
+ if self.backend.get_advanced_option():
+ self.switchView("advanced")
+ self.edit_mode_button.set_active (True)
+ else:
+ self.switchView("simple")
+ self.edit_mode_button.set_active (False)
+ self.noevents = False
+
+
+ self.__initUser__()
+
+ ##create crontab
+ self.crontab = crontab.Crontab(self.root, self.user, self.uid, self.gid, self.user_home_dir)
+ self.crontab_editor = crontabEditor.CrontabEditor(self, self.backend, self.crontab, self.template)
+ ##
+
+ ##create at
+ self.at = at.At(self.root, self.user, self.uid, self.gid, self.user_home_dir, self.manual_poscorrect)
+ self.at_editor = atEditor.AtEditor (self, self.backend, self.at, self.template)
+ ##
+
+ #set user window
+ self.setuserWindow = setuserWindow.SetuserWindow (self)
+
+ #set add window
+ self.addWindow = addWindow.AddWindow (self)
+
+ # template windows
+ self.template_chooser = template_chooser.TemplateChooser (self, self.template)
+ self.template_manager = template_manager.TemplateManager (self, self.template)
+
+ self.schedule_reload ()
+
+ self.timeout_handler_id = gobject.timeout_add(9000, self.update_schedule)
+
+ # temporary files to be deleted
+ self.temp_files = []
+
+ if inapplet == False:
+ gtk.main()
+
+
+ def update_schedule(self):
+ selection = self.treeview.get_selection()
+ model, iter, = selection.get_selected()
+ if iter:
+ path = model.get_path(iter)
+ self.schedule_reload ()
+ if iter:
+ selection.select_path(path)
+ return True
+
+ def changeUser(self,user):
+ if user != self.user:
+ self.__setUser__(user)
+ #change user for the schedulers
+ self.crontab.set_rights(self.user, self.uid, self.gid, self.user_home_dir)
+ self.at.set_rights(self.user, self.uid, self.gid, self.user_home_dir)
+ #adjust statusbar
+ if self.root == 1:
+ self.statusbar.push(self.statusbarUser, (_("Editing user: %s") % (self.user)))
+
+ self.schedule_reload ()
+
+
+ def __setUser__(self,user):
+ userdb = pwd.getpwnam(user)
+ self.user = user
+ self.uid = userdb[2]
+ self.gid = userdb[3]
+ self.user_home_dir = userdb[5]
+ self.user_shell = userdb[6]
+
+
+ ## TODO: 2 times a loop looks to mutch
+ def schedule_reload (self):
+ self.treemodel.clear ()
+
+ data = self.crontab.read ()
+ if data != None:
+ self.__fill__ (data)
+
+ data = self.at.read ()
+ if data != None:
+ self.__fill__ (data)
+
+
+
+
+ def __fill__ (self, records):
+ for title, timestring_show, preview, lines, job_id, timestring, scheduler, icon, date, class_id, user, time, typetext, type, output, timestring_advanced in records:
+
+ if scheduler.get_type() == "crontab":
+ iter = self.treemodel.append([title, timestring_show, preview, lines, job_id, timestring, self.iconcrontab, scheduler, icon, date, class_id, user, time, typetext, type, output, timestring_advanced])
+ elif scheduler.get_type() == "at":
+ iter = self.treemodel.append([title, timestring_show, preview, lines, job_id, timestring, self.iconat, scheduler, icon, date, class_id, user, time, typetext, type, output, timestring_advanced])
+
+
+
+ def __loadIcon__(self):
+ if self.debug_flag:
+ if os.access("../icons/gnome-schedule.svg", os.F_OK):
+ self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/gnome-schedule.svg", 52, 52)
+ else:
+ try:
+ self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/gnome-schedule.svg", 52, 52)
+ except:
+ print _("ERROR: Could not load icon")
+
+ if self.debug_flag:
+ if os.access ("../icons/crontab.svg", os.F_OK):
+ self.iconcrontab = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/crontab.svg", 19, 19)
+ self.bigiconcrontab = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/crontab.svg", 49, 49)
+ else:
+ try:
+ self.iconcrontab = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/crontab.svg", 19, 19)
+ self.bigiconcrontab = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/crontab.svg", 49, 49)
+ except:
+ print _("ERROR: Could not load icon")
+
+ if self.debug_flag:
+ if os.access ("../icons/calendar.svg", os.F_OK):
+ self.iconcalendar = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/calendar.svg", 19, 19)
+ self.bigiconcalendar = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/calendar.svg", 49, 49)
+ else:
+ try:
+ self.iconcalendar = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/calendar.svg", 19, 19)
+ self.bigiconcalendar = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/calendar.svg", 49, 49)
+ except:
+ print _("ERROR: Could not load icon")
+
+ if self.debug_flag:
+ if os.access ("../icons/template.svg", os.F_OK):
+ self.icontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 19, 19)
+ self.normalicontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 25, 25)
+ self.bigicontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 49, 49)
+ self.pathicontemplate = "../icons/template.svg"
+ else:
+ try:
+ self.icontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 19, 19)
+ self.normalicontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 25, 25)
+ self.bigicontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 49, 49)
+ self.pathicontemplate = config.getImagedir() + "/template.svg"
+ except:
+ print _("ERROR: Could not load icon")
+
+ if self.debug_flag:
+ if os.access ("../icons/at.svg", os.F_OK):
+ self.iconat = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/at.svg", 19, 19)
+ self.bigiconat = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/at.svg", 49, 49)
+ else:
+ try:
+ self.iconat = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/at.svg", 19, 19)
+ self.bigiconat = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/at.svg", 49, 49)
+ except:
+ print _("ERROR: Could not load icon")
+
+
+ def __loadGlade__(self):
+ if self.debug_flag:
+ if os.access("gnome-schedule.glade", os.F_OK):
+ try:
+ self.xml = gtk.glade.XML ("gnome-schedule.glade", domain="gnome-schedule")
+ except:
+ print _("ERROR: Could not load glade file")
+ quit ()
+ else:
+ try:
+ self.xml = gtk.glade.XML (config.getGladedir() + "/gnome-schedule.glade", domain="gnome-schedule")
+ except:
+ print _("ERROR: Could not load glade file")
+ quit ()
+
+
+
+ def __initUser__(self):
+ self.uid = os.geteuid()
+ self.gid = os.getegid()
+ self.user = pwd.getpwuid(self.uid)[0]
+ self.user_home_dir = pwd.getpwuid(self.uid)[5]
+ self.user_shell = pwd.getpwuid(self.uid)[6]
+
+ if self.uid != 0:
+ self.btnSetUser.hide()
+ self.statusbar.hide()
+ self.root = 0
+ else:
+ self.root = 1
+ self.btnSetUser.show()
+ self.statusbar.show()
+ self.statusbar.push(self.statusbarUser, (_("Editing user: %s") % (self.user)))
+
+
+ #when the user selects a task, buttons get enabled
+ def on_TreeViewSelectRow (self, *args):
+ if self.treeview.get_selection().count_selected_rows() > 0 :
+ value = True
+ else:
+ value = False
+
+ self.prop_button.set_sensitive (value)
+ self.del_button.set_sensitive (value)
+ self.run_button.set_sensitive (value)
+
+
+
+ #clean existing columns
+ def __cleancolumns__ (self):
+ columns = len(self.treeview.get_columns()) -1
+ while columns > -1:
+ temp = self.treeview.get_column(columns)
+ self.treeview.remove_column(temp)
+ columns = columns - 1
+
+
+ #switch between advanced and simple mode
+ def switchView(self, mode = "simple"):
+ self.__cleancolumns__ ()
+
+ self.treeview.get_selection().unselect_all()
+ self.edit_mode = mode
+
+ cell = gtk.CellRendererPixbuf()
+ cell.set_fixed_size(21,21)
+ cell2 = gtk.CellRendererText ()
+ col = gtk.TreeViewColumn (_("Task"), None)
+ col.pack_start (cell, True)
+ col.pack_end (cell2, True)
+ col.add_attribute (cell, "pixbuf", 6)
+ if mode == "simple":
+ col.add_attribute (cell2, "text", 13)
+ else:
+ col.add_attribute (cell2, "text", 14)
+
+ self.treeview.append_column(col)
+
+ if mode == "simple":
+
+ col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text=0)
+ col.set_resizable (True)
+ self.treeview.append_column(col)
+
+ col = gtk.TreeViewColumn(_("Date and Time"), gtk.CellRendererText(), text=1)
+ col.set_resizable (True)
+ self.treeview.append_column(col)
+
+ col = gtk.TreeViewColumn(_("Command preview"), gtk.CellRendererText(), text=2)
+ col.set_resizable (True)
+ col.set_expand (True)
+ self.treeview.append_column(col)
+
+
+
+ elif mode == "advanced":
+
+ col = gtk.TreeViewColumn(_("Date and Time"), gtk.CellRendererText(), text=16)
+ col.set_resizable (True)
+ self.treeview.append_column(col)
+
+ col = gtk.TreeViewColumn(_("Command preview"), gtk.CellRendererText(), text=2)
+ col.set_resizable (True)
+ col.set_expand (True)
+ self.treeview.append_column(col)
+
+ col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text=0)
+ col.set_resizable (True)
+ self.treeview.append_column(col)
+
+
+
+ def on_advanced_menu_activate (self, widget):
+ if self.noevents == False:
+ if self.backend.get_advanced_option():
+ self.backend.set_advanced_option(0)
+ else:
+ self.backend.set_advanced_option(1)
+
+ def on_add_at_task (self, *args):
+ self.addWindow.mode = 0
+ self.addWindow.on_button_at_clicked (*args)
+
+ def on_add_crontab_task (self, *args):
+ self.addWindow.mode = 0
+ self.addWindow.on_button_crontab_clicked (*args)
+
+ def on_add_from_template (self, *args):
+ self.addWindow.mode = 0
+ self.addWindow.on_button_template_clicked (*args)
+
+ def on_template_manager_button (self, *args):
+ self.template_manager.show (self.widget)
+
+ def on_add_scheduled_task_menu_activate (self, *args):
+ self.addWindow.ShowAddWindow (self.widget)
+
+ def on_properties_menu_activate (self, *args):
+ store, iter = self.treeview.get_selection().get_selected()
+
+ try:
+ #see what scheduler (at, crontab or ...)
+ self.schedule = self.treemodel.get_value(iter, 7)
+
+
+
+ record = self.treemodel.get_value(iter, 3)
+ linenumber = self.treemodel.get_value(iter, 4)
+
+ # TODO: dirty hacky
+ if self.schedule.get_type() == "crontab":
+ self.editor = self.crontab_editor
+ job_id = self.treemodel.get_value (iter, 9)
+ self.editor.showedit (self.widget, record, job_id, linenumber, iter)
+ else:
+ self.editor = self.at_editor
+ self.editor.showedit (self.widget, record, linenumber, iter)
+
+ except Exception, ex:
+ print ex
+ self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task"))
+ self.dialog.run ()
+ self.dialog.destroy ()
+
+
+ # TODO: looks not that clean (is broken)
+ def on_delete_menu_activate (self, *args):
+ dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("Do you want to delete this task?"))
+ if (dialog.run() != gtk.RESPONSE_YES):
+ dialog.destroy()
+ del dialog
+ return
+ dialog.destroy()
+ del dialog
+
+ store, iter = self.treeview.get_selection().get_selected()
+
+ try:
+ #see what scheduler (at, crontab or ...)
+ self.schedule = self.treemodel.get_value(iter, 7)
+
+ # TODO: dirty hacky
+ if self.schedule.get_type() == "crontab":
+ self.editor = self.crontab_editor
+ elif self.schedule.get_type() == "at":
+ self.editor = self.at_editor
+
+ record = self.treemodel.get_value(iter, 3)
+ linenumber = self.treemodel.get_value(iter, 4)
+
+ path = self.treemodel.get_path(iter)
+ pathint = path[0]
+ backpath = (pathint - 1,)
+
+ if self.schedule.get_type() == "crontab":
+ self.schedule.delete (linenumber, iter, self.treemodel.get_value(iter, 9))
+ elif self.schedule.get_type() == "at":
+ self.schedule.delete (linenumber, iter)
+
+ self.schedule_reload()
+
+ firstiter = self.treemodel.get_iter_first()
+ try:
+ nextiter = self.treemodel.get_iter(path)
+ #go next
+ selection = self.treeview.get_selection()
+ selection.select_iter(nextiter)
+
+ except:
+ if backpath[0] > 0:
+ nextiter = self.treemodel.get_iter(backpath)
+ #go back
+ selection = self.treeview.get_selection()
+ selection.select_iter(nextiter)
+
+ else:
+ if firstiter:
+ #go first
+ selection = self.treeview.get_selection()
+ selection.select_iter(firstiter)
+
+ except Exception, ex:
+ #print ex
+ self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task"))
+ self.dialog.run ()
+ self.dialog.destroy ()
+
+ def on_set_user_menu_activate(self, *args):
+ self.setuserWindow.ShowSetuserWindow()
+
+
+ def on_btnSetUser_clicked(self, *args):
+ self.on_set_user_menu_activate(self, args)
+
+ def on_add_button_clicked (self, *args):
+ self.on_add_scheduled_task_menu_activate (self, args)
+
+ def on_prop_button_clicked (self, *args):
+ self.on_properties_menu_activate (self, args)
+
+ def on_del_button_clicked (self, *args):
+ self.on_delete_menu_activate (self, args)
+
+ def on_help_button_clicked (self, *args):
+ self.on_manual_menu_activate (self, args)
+
+
+ def on_treeview_key_pressed (self, widget, event):
+ key = gtk.gdk.keyval_name(event.keyval)
+ #remove task from list with DEL key
+ if key == "Delete" or key == "KP_Delete":
+ self.on_delete_menu_activate()
+ #display properties with ENTER key
+ if (key == "Return" or key == "KP_Return"):
+ self.on_properties_menu_activate(self, widget)
+
+
+ #double click on task to get properties
+ def on_treeview_button_press_event (self, widget, event):
+ if event.type == gtk.gdk._2BUTTON_PRESS:
+ self.on_properties_menu_activate(self, widget)
+
+
+ #about box
+ def open_url (self, *args):
+ url_show("http://gnome-schedule.sourceforge.net")
+
+
+
+ def on_run_button_clicked (self, *args):
+ dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_NONE, _("Are you sure you want to run this task now?\n\nThis is used to preview the task and initiates a one-time run, this does not affect the normal scheduled run times."))
+ dialog.add_buttons (gtk.STOCK_EXECUTE, gtk.RESPONSE_YES, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+ dialog.set_title (_("Are you sure you want to run this task?"))
+ if (dialog.run() != gtk.RESPONSE_YES):
+ dialog.destroy()
+ del dialog
+ return
+ dialog.destroy()
+ del dialog
+
+ if (self.backend.get_not_inform_working_dir() != True):
+ dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nRecurrent tasks will be run from the home directory, one-time tasks from the directory where Gnome schedule was run from at the time of task creation (normally the home directory)."))
+ dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+ dia2.set_title (_("Warning: Working directory of executed tasks"))
+ response = dia2.run ()
+ if response == gtk.RESPONSE_CANCEL:
+ dia2.destroy ()
+ del dia2
+ return
+ elif response == gtk.RESPONSE_CLOSE:
+ self.backend.set_not_inform_working_dir (True)
+ else:
+ pass
+ dia2.destroy ()
+ del dia2
+
+ store, iter = self.treeview.get_selection().get_selected()
+
+ try:
+ # commands are at model[3]
+
+ #see what scheduler (at, crontab or ...)
+ self.schedule = self.treemodel.get_value(iter, 7)
+
+ tmpfile = tempfile.mkstemp ()
+ fd, path = tmpfile
+ tmp = os.fdopen (fd, 'w')
+
+ commands = self.treemodel.get_value(iter, 3)
+ linenumber = self.treemodel.get_value(iter, 4)
+
+
+ if self.schedule.get_type () == "at":
+ script = os.popen (config.getAtbin () + " -c " + str (linenumber)).read ()
+ elif self.schedule.get_type () == "crontab":
+ script = self.schedule.parse (commands)[1][5]
+
+ # left untranslated to protect against any 'translation attacks'..
+ script = script + "\necho " + "Press ENTER to continue and close this window." + "\n"
+ script = script + "read\nexit\n"
+ tmp.write (script)
+ tmp.flush ()
+ self.temp_files.append ((tmp, path))
+
+
+ execute = self.user_shell + " " + path
+
+ if self.root == 1:
+ if self.user != "root":
+ execute = "su " + self.user + " -c \"" + self.user_shell + " " + path
+ os.chown (path, self.uid, self.gid)
+ os.chmod (path, stat.S_IEXEC | stat.S_IREAD)
+
+
+ gnome.execute_terminal_shell (self.user_home_dir, execute)
+
+
+
+ except Exception, ex:
+ print ex
+ self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task!"))
+ self.dialog.run ()
+ self.dialog.destroy ()
+
+ def on_about_menu_activate (self, *args):
+
+ gtk.about_dialog_set_url_hook(self.open_url, "bogusbar")
+ dlg = gtk.AboutDialog ()
+ dlg.set_title (_("About Gnome Schedule"))
+ dlg.set_name (_("Gnome Schedule"))
+ dlg.set_version (config.getVersion())
+ dlg.set_copyright (_("Copyright (c) %(year)s %(name)s.") % ({ 'year' : "2004-2008", 'name' : "Gaute Hope"}))
+ #dlg.set_comments ()
+ #dlg.set_license ()
+ dlg.set_website ("http://gnome-schedule.sourceforge.net")
+ dlg.set_website_label("http://gnome-schedule.sourceforge.net")
+ dlg.set_authors (
+ ["Gaute Hope <eg gaute vetsj com>",
"Philip Van Hoof <pvanhoof at gnome dot org>",
- "Kristof Vansant <de_lupus at pandora dot be>"]
- )
- dlg.set_documenters (
- ["Rodrigo Marcos Fombellida <rmarcos_geo yahoo es>"]
- )
- dlg.set_translator_credits (_("translator-credits"))
- dlg.set_logo (self.iconPixbuf)
-
- if (dlg.run() != gtk.RESPONSE_YES):
- dlg.destroy()
- del dlg
- return
- dlg.destroy()
- del dlg
-
- #open help
- def on_manual_menu_activate (self, *args):
- try:
- gnome.help_display (
- 'gnome-schedule',
- None)
- except gobject.GError, error:
- dialog = gtk.MessageDialog (
- self.widget,
- gtk.DIALOG_DESTROY_WITH_PARENT,
- gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE)
- dialog.set_markup ("<b>" + _("Could not display help") + "</b>")
- dialog.format_secondary_text ("%s" % error)
- dialog.run ()
- dialog.destroy ()
-
-
- #quit program
- def __quit__(self, *args):
- for t in self.temp_files:
- f, p = t
- f.close ()
- os.remove (p)
-
- # save state
- x,y = self.widget.get_position ()
- h, w = self.widget.get_size ()
- self.backend.set_window_state(x, y, h, w)
- if self.inapplet:
- self.widget.hide ()
- else:
- gtk.main_quit ()
- return True
-
+ "Kristof Vansant <de_lupus at pandora dot be>"]
+ )
+ dlg.set_documenters (
+ ["Rodrigo Marcos Fombellida <rmarcos_geo yahoo es>"]
+ )
+ dlg.set_translator_credits (_("translator-credits"))
+ dlg.set_logo (self.iconPixbuf)
+
+ if (dlg.run() != gtk.RESPONSE_YES):
+ dlg.destroy()
+ del dlg
+ return
+ dlg.destroy()
+ del dlg
+
+ #open help
+ def on_manual_menu_activate (self, *args):
+ try:
+ gnome.help_display (
+ 'gnome-schedule',
+ None)
+ except gobject.GError, error:
+ dialog = gtk.MessageDialog (
+ self.widget,
+ gtk.DIALOG_DESTROY_WITH_PARENT,
+ gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE)
+ dialog.set_markup ("<b>" + _("Could not display help") + "</b>")
+ dialog.format_secondary_text ("%s" % error)
+ dialog.run ()
+ dialog.destroy ()
+
+
+ #quit program
+ def __quit__(self, *args):
+ for t in self.temp_files:
+ f, p = t
+ f.close ()
+ os.remove (p)
+
+ # save state
+ x,y = self.widget.get_position ()
+ h, w = self.widget.get_size ()
+ self.backend.set_window_state(x, y, h, w)
+ if self.inapplet:
+ self.widget.hide ()
+ else:
+ gtk.main_quit ()
+ return True
+
Modified: trunk/src/scheduleapplet.py
==============================================================================
--- trunk/src/scheduleapplet.py (original)
+++ trunk/src/scheduleapplet.py Sat Feb 14 21:20:56 2009
@@ -28,8 +28,8 @@
poscorrect_isset = os.getenv ("POSIXLY_CORRECT", False)
manual_poscorrect = False
if poscorrect_isset == False:
- os.putenv ("POSIXLY_CORRECT", "enabled")
- manual_poscorrect = True
+ os.putenv ("POSIXLY_CORRECT", "enabled")
+ manual_poscorrect = True
##
## I18N
@@ -39,16 +39,16 @@
gettext.install(config.GETTEXT_PACKAGE(), config.GNOMELOCALEDIR(), unicode=1)
if __name__ == "__main__":
- signal.signal (signal.SIGINT, signal.SIG_DFL)
+ signal.signal (signal.SIGINT, signal.SIG_DFL)
debug_flag = None
if '--debug' in sys.argv:
- debug_flag = 1
+ debug_flag = 1
try:
- import pygtk
- #tell pyGTK, if possible, that we want GTKv2
- pygtk.require("2.0")
+ import pygtk
+ #tell pyGTK, if possible, that we want GTKv2
+ pygtk.require("2.0")
except:
#Some distributions come with GTK2, but not pyGTK
@@ -62,7 +62,7 @@
import gnome.ui
import gnomeapplet
import gobject
-
+
except:
print _("You need to install pyGTK or GTKv2,\n"
"or set your PYTHONPATH correctly.\n"
@@ -75,105 +75,105 @@
class ScheduleApplet(gnomeapplet.Applet):
- def __init__(self, applet, iid, gprogram, debug_flag, manual_poscorrect):
- self.__gobject_init__()
- self.debug_flag = debug_flag
- self.manual_poscorrect = manual_poscorrect
-
- gettext.bindtextdomain(config.GETTEXT_PACKAGE(), config.GNOMELOCALEDIR())
- gettext.textdomain(config.GETTEXT_PACKAGE())
-
- locale.bindtextdomain(config.GETTEXT_PACKAGE(), config.GNOMELOCALEDIR())
- locale.textdomain(config.GETTEXT_PACKAGE())
-
-
- self.applet = applet
- self.gprogram = gprogram
- self.__loadIcon__()
-
-
- self.ev_box = gtk.EventBox()
-
- self.image = gtk.Image()
- self.image.set_from_pixbuf(self.iconPixbuf)
-
- self.main_loaded = False
-
- self.ev_box.add(self.image)
- self.ev_box.show()
- self.ev_box.set_events(gtk.gdk.BUTTON_PRESS_MASK)
- self.ev_box.connect("button_press_event", self.event_box_clicked)
- self.applet.add(self.ev_box)
-
- self.create_menu()
- self.applet.show_all()
-
-
-
-
- def __loadIcon__(self):
- if self.debug_flag:
- if os.access("../icons/gnome-schedule.svg", os.F_OK):
- self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/gnome-schedule.svg", 18, 18)
- else:
- try:
- self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/gnome-schedule.svg", 24, 24)
- except:
- print _("ERROR: Could not load icon")
-
- def create_menu(self):
- self.verbs = [ ("show_main", self.show_main_window),
- ("add", self.add_task),
- ("help", self.show_help),
- ("about", self.show_about)
- ]
-
- #check for file in current dir
- if self.debug_flag:
- if os.access ("gnome-schedule-applet.xml", os.F_OK):
- datadir = './'
- else:
- if os.access (config.getGladedir() + "/gnome-schedule-applet.xml", os.F_OK):
- datadir = config.getGladedir()
- else:
- print _("ERROR: Could not load menu xml file")
- datadir = ''
- quit ()
-
- self.applet.setup_menu_from_file(datadir, "gnome-schedule-applet.xml", "gnome-schedule", self.verbs)
-
-
- def event_box_clicked (self, widget, event):
- if event.type == gtk.gdk._2BUTTON_PRESS:
- self.show_main_window()
-
- def show_main_window(self, *args):
- if self.main_loaded == False:
- self.main_loaded = True
- self.main_window = mainWindow.main(None, True, self.gprogram, self.manual_poscorrect)
- else:
- self.main_window.widget.show ()
- self.main_window.schedule_reload()
-
-
- def add_task(self, *args):
- if self.main_loaded == False:
- self.show_main_window()
- self.main_window.widget.hide()
- self.main_window.on_add_scheduled_task_menu_activate()
-
-
- def show_help(self, *args):
- if self.main_loaded == False:
- self.show_main_window()
- self.main_window.widget.hide()
- self.main_window.on_manual_menu_activate()
-
- def show_about(self, *args):
- if self.main_loaded == False:
- self.show_main_window()
- self.main_window.widget.hide()
- self.main_window.on_about_menu_activate()
+ def __init__(self, applet, iid, gprogram, debug_flag, manual_poscorrect):
+ self.__gobject_init__()
+ self.debug_flag = debug_flag
+ self.manual_poscorrect = manual_poscorrect
+
+ gettext.bindtextdomain(config.GETTEXT_PACKAGE(), config.GNOMELOCALEDIR())
+ gettext.textdomain(config.GETTEXT_PACKAGE())
+
+ locale.bindtextdomain(config.GETTEXT_PACKAGE(), config.GNOMELOCALEDIR())
+ locale.textdomain(config.GETTEXT_PACKAGE())
+
+
+ self.applet = applet
+ self.gprogram = gprogram
+ self.__loadIcon__()
+
+
+ self.ev_box = gtk.EventBox()
+
+ self.image = gtk.Image()
+ self.image.set_from_pixbuf(self.iconPixbuf)
+
+ self.main_loaded = False
+
+ self.ev_box.add(self.image)
+ self.ev_box.show()
+ self.ev_box.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self.ev_box.connect("button_press_event", self.event_box_clicked)
+ self.applet.add(self.ev_box)
+
+ self.create_menu()
+ self.applet.show_all()
+
+
+
+
+ def __loadIcon__(self):
+ if self.debug_flag:
+ if os.access("../icons/gnome-schedule.svg", os.F_OK):
+ self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/gnome-schedule.svg", 18, 18)
+ else:
+ try:
+ self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/gnome-schedule.svg", 24, 24)
+ except:
+ print _("ERROR: Could not load icon")
+
+ def create_menu(self):
+ self.verbs = [ ("show_main", self.show_main_window),
+ ("add", self.add_task),
+ ("help", self.show_help),
+ ("about", self.show_about)
+ ]
+
+ #check for file in current dir
+ if self.debug_flag:
+ if os.access ("gnome-schedule-applet.xml", os.F_OK):
+ datadir = './'
+ else:
+ if os.access (config.getGladedir() + "/gnome-schedule-applet.xml", os.F_OK):
+ datadir = config.getGladedir()
+ else:
+ print _("ERROR: Could not load menu xml file")
+ datadir = ''
+ quit ()
+
+ self.applet.setup_menu_from_file(datadir, "gnome-schedule-applet.xml", "gnome-schedule", self.verbs)
+
+
+ def event_box_clicked (self, widget, event):
+ if event.type == gtk.gdk._2BUTTON_PRESS:
+ self.show_main_window()
+
+ def show_main_window(self, *args):
+ if self.main_loaded == False:
+ self.main_loaded = True
+ self.main_window = mainWindow.main(None, True, self.gprogram, self.manual_poscorrect)
+ else:
+ self.main_window.widget.show ()
+ self.main_window.schedule_reload()
+
+
+ def add_task(self, *args):
+ if self.main_loaded == False:
+ self.show_main_window()
+ self.main_window.widget.hide()
+ self.main_window.on_add_scheduled_task_menu_activate()
+
+
+ def show_help(self, *args):
+ if self.main_loaded == False:
+ self.show_main_window()
+ self.main_window.widget.hide()
+ self.main_window.on_manual_menu_activate()
+
+ def show_about(self, *args):
+ if self.main_loaded == False:
+ self.show_main_window()
+ self.main_window.widget.hide()
+ self.main_window.on_about_menu_activate()
gobject.type_register(ScheduleApplet)
Modified: trunk/src/setuserWindow.py
==============================================================================
--- trunk/src/setuserWindow.py (original)
+++ trunk/src/setuserWindow.py Sat Feb 14 21:20:56 2009
@@ -26,62 +26,62 @@
class SetuserWindow:
- def __init__(self, parent):
- self.ParentClass = parent
- self.xml = self.ParentClass.xml
- self.widget = self.xml.get_widget("setuserWindow")
- self.widget.connect("delete-event", self.widget.hide_on_delete)
-
- ##comboxEntry
- self.entUser = self.xml.get_widget("entUser")
-
- liststore = gtk.ListStore(gobject.TYPE_STRING)
- self.entUser.set_model(liststore)
- self.entUser.set_text_column(0)
-
- #entryCompletion
- # TODO: make it only possible for the user to type something that is in the list
- self.entry = self.entUser.child
- self.entry.set_text(self.ParentClass.user)
- completion = gtk.EntryCompletion()
- self.entry.set_completion(completion)
- completion.set_model(liststore)
- completion.set_text_column(0)
-
- #fill combox with all the users
- pwd_info = pwd.getpwall()
-
- for info in pwd_info:
- self.entUser.append_text(info[0])
- ##
-
- self.cancel_button = self.xml.get_widget ("setuser_cancel_button")
- self.ok_button = self.xml.get_widget ("setuser_ok_button")
- self.xml.signal_connect("on_setuser_cancel_button_clicked", self.on_cancel_button_clicked)
- self.xml.signal_connect("on_setuser_ok_button_clicked", self.on_ok_button_clicked)
-
-
- #public function
- def ShowSetuserWindow (self):
- self.widget.set_transient_for(self.ParentClass.widget)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.widget.show_all()
-
-
- def on_cancel_button_clicked (self, *args):
- self.widget.hide()
-
-
- def on_ok_button_clicked (self, *args):
-
- user = self.entry.get_text()
- try:
- self.ParentClass.changeUser(user)
- self.widget.hide()
-
- except Exception, ex:
- print ex
- self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("No such user"))
- self.dialog.run ()
- self.dialog.destroy ()
-
+ def __init__(self, parent):
+ self.ParentClass = parent
+ self.xml = self.ParentClass.xml
+ self.widget = self.xml.get_widget("setuserWindow")
+ self.widget.connect("delete-event", self.widget.hide_on_delete)
+
+ ##comboxEntry
+ self.entUser = self.xml.get_widget("entUser")
+
+ liststore = gtk.ListStore(gobject.TYPE_STRING)
+ self.entUser.set_model(liststore)
+ self.entUser.set_text_column(0)
+
+ #entryCompletion
+ # TODO: make it only possible for the user to type something that is in the list
+ self.entry = self.entUser.child
+ self.entry.set_text(self.ParentClass.user)
+ completion = gtk.EntryCompletion()
+ self.entry.set_completion(completion)
+ completion.set_model(liststore)
+ completion.set_text_column(0)
+
+ #fill combox with all the users
+ pwd_info = pwd.getpwall()
+
+ for info in pwd_info:
+ self.entUser.append_text(info[0])
+ ##
+
+ self.cancel_button = self.xml.get_widget ("setuser_cancel_button")
+ self.ok_button = self.xml.get_widget ("setuser_ok_button")
+ self.xml.signal_connect("on_setuser_cancel_button_clicked", self.on_cancel_button_clicked)
+ self.xml.signal_connect("on_setuser_ok_button_clicked", self.on_ok_button_clicked)
+
+
+ #public function
+ def ShowSetuserWindow (self):
+ self.widget.set_transient_for(self.ParentClass.widget)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.widget.show_all()
+
+
+ def on_cancel_button_clicked (self, *args):
+ self.widget.hide()
+
+
+ def on_ok_button_clicked (self, *args):
+
+ user = self.entry.get_text()
+ try:
+ self.ParentClass.changeUser(user)
+ self.widget.hide()
+
+ except Exception, ex:
+ print ex
+ self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("No such user"))
+ self.dialog.run ()
+ self.dialog.destroy ()
+
Modified: trunk/src/template.py
==============================================================================
--- trunk/src/template.py (original)
+++ trunk/src/template.py Sat Feb 14 21:20:56 2009
@@ -25,182 +25,193 @@
import config
class Template:
- def __init__ (self, parent, configbackend):
- self.parent = parent
- self.configbackend = configbackend
- self.gconf_client = self.configbackend.gconf_client
-
-
- def removetemplate_at (self, template_id):
- installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/installed")
- newstring = installed
- if installed != None:
- first = True
- newstring = " "
-
- for t in installed.split (", "):
- if t != str (template_id):
- if first == True:
- newstring = t
- first = False
- else:
- newstring = newstring + ", " + t
-
- self.gconf_client.unset("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)))
- self.gconf_client.unset("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)))
-
- if newstring == " ":
- self.gconf_client.unset ("/apps/gnome-schedule/templates/at/installed")
- else:
- self.gconf_client.set_string("/apps/gnome-schedule/templates/at/installed", newstring)
-
- def removetemplate_crontab (self, template_id):
- installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/installed")
- newstring = installed
- if installed != None:
- first = True
- newstring = " "
-
- for t in installed.split (", "):
- if t != str (template_id):
- if first == True:
- newstring = t
- first = False
- else:
- newstring = newstring + ", " + t
-
- self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)))
- self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)))
- self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/timeexpression" % (str (template_id)))
- self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/nooutput" % (str (template_id)))
-
- if newstring == " ":
- self.gconf_client.unset ("/apps/gnome-schedule/templates/crontab/installed")
- else:
- self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/installed", newstring)
-
-
- def create_new_id_crontab (self):
- i = self.gconf_client.get_int ("/apps/gnome-schedule/templates/crontab/last_id")
- if i == None:
- self.gconf_client.set_int ("/apps/gnome-schedule/templates/crontab/last_id", 1)
- return 1
- else:
- i = i + 1
- self.gconf_client.set_int ("/apps/gnome-schedule/templates/crontab/last_id", i)
- return i
-
- def savetemplate_crontab (self, template_id, title, command, nooutput, timeexpression):
-
- if (template_id == 0):
- template_id = self.create_new_id_crontab ()
-
- self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/timeexpression" % (str (template_id)), timeexpression)
- self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)), title)
- self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)), command)
- self.gconf_client.set_bool("/apps/gnome-schedule/templates/crontab/%s/nooutput" % (str (template_id)), nooutput)
-
- installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/installed")
- if installed == None:
- installed = str(template_id)
- else:
- found = False
-
- for t in installed.split (", "):
- if t == str (template_id):
- found = True
-
- if found == False:
- installed = installed + ", " + str (template_id)
-
- self.gconf_client.unset ("/apps/gnome-schedule/templates/crontab/installed")
- self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/installed", installed)
- self.parent.template_manager.reload_tv ()
- self.parent.template_chooser.reload_tv ()
-
-
- def gettemplateids (self, type):
- strlist = self.gconf_client.get_string("/apps/gnome-schedule/templates/" + type + "/installed")
- if strlist != None:
-
- list = strlist.split (", ")
- return list
- else:
- return None
-
-
- def gettemplate (self, type, template_id):
- if type == "crontab":
- try:
- command = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)))
- title = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)))
- nooutput = self.gconf_client.get_bool("/apps/gnome-schedule/templates/" + type + "/%s/nooutput" % (template_id))
- timeexpression = self.gconf_client.get_string("/apps/gnome-schedule/templates/" + type + "/%s/timeexpression" % (template_id))
- return template_id, title, command, nooutput, timeexpression
-
- except Exception, ex:
- return False
-
- elif type == "at":
- try:
- command = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)))
- title = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)))
- return template_id, title, command
-
- except Exception, ex:
- return False
-
- def create_new_id_at (self):
- i = self.gconf_client.get_int ("/apps/gnome-schedule/templates/at/last_id")
- if i == 0:
- self.gconf_client.set_int ("/apps/gnome-schedule/templates/at/last_id", 1)
- return 1
- else:
- i = i + 1
- self.gconf_client.set_int ("/apps/gnome-schedule/templates/at/last_id", i)
- return i
-
- def savetemplate_at (self, template_id, title, command):
-
- if (template_id == 0):
- template_id = self.create_new_id_at ()
-
- self.gconf_client.set_string("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)), title)
- self.gconf_client.set_string("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)), command)
-
-
- installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/installed")
- if installed == None:
- installed = str(template_id)
- else:
- found = False
-
- for t in installed.split (", "):
- if t == str (template_id):
- found = True
-
- if found == False:
- installed = installed + ", " + str (template_id)
-
- self.gconf_client.unset ("/apps/gnome-schedule/templates/at/installed")
- self.gconf_client.set_string("/apps/gnome-schedule/templates/at/installed", installed)
- self.parent.template_manager.reload_tv ()
- self.parent.template_chooser.reload_tv ()
-
- def format_at (self, title, command):
- command = self.parent.at.__make_preview__ (command, 0)
- s = "<b>" + _("Title:") + "</b> " + title + "\n<b>" + _("Command:") + "</b> " + command
- return s
-
- def format_crontab (self, title, command, nooutput, timeexpression):
- command = self.parent.crontab.__make_preview__ (command)
- if self.parent.edit_mode == "simple":
- # hehe.. :)
- timeexpression = timeexpression + " echo hehe"
- minute, hour, dom, moy, dow, hehe = self.parent.crontab.parse (timeexpression, True)
- timeexpression = self.parent.crontab.__easy__ (minute, hour, dom, moy, dow)
- s = "<b>" + _("Title:") + "</b> " + title + "\n<b>" + _("Run:") + "</b> " + timeexpression + "\n<b>" + _("Command:") + "</b> " + command
- if nooutput:
- s = s + " <i>(" + _("No output") + ")</i>"
-
- return s
+ def __init__ (self, parent, configbackend):
+ self.parent = parent
+ self.configbackend = configbackend
+ self.gconf_client = self.configbackend.gconf_client
+
+
+ def removetemplate_at (self, template_id):
+ installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/installed")
+ newstring = installed
+ if installed != None:
+ first = True
+ newstring = " "
+
+ for t in installed.split (", "):
+ if t != str (template_id):
+ if first == True:
+ newstring = t
+ first = False
+ else:
+ newstring = newstring + ", " + t
+
+ self.gconf_client.unset("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)))
+ self.gconf_client.unset("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)))
+ self.gconf_client.unset ("/apps/gnome-schedule/templates/at/%s/output" % (str (template_id)))
+
+ if newstring == " ":
+ self.gconf_client.unset ("/apps/gnome-schedule/templates/at/installed")
+ else:
+ self.gconf_client.set_string("/apps/gnome-schedule/templates/at/installed", newstring)
+
+ def removetemplate_crontab (self, template_id):
+ installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/installed")
+ newstring = installed
+ if installed != None:
+ first = True
+ newstring = " "
+
+ for t in installed.split (", "):
+ if t != str (template_id):
+ if first == True:
+ newstring = t
+ first = False
+ else:
+ newstring = newstring + ", " + t
+
+ self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)))
+ self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)))
+ self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/timeexpression" % (str (template_id)))
+ self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/output" % (str (template_id)))
+
+ if newstring == " ":
+ self.gconf_client.unset ("/apps/gnome-schedule/templates/crontab/installed")
+ else:
+ self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/installed", newstring)
+
+
+ def create_new_id_crontab (self):
+ i = self.gconf_client.get_int ("/apps/gnome-schedule/templates/crontab/last_id")
+ if i == None:
+ self.gconf_client.set_int ("/apps/gnome-schedule/templates/crontab/last_id", 1)
+ return 1
+ else:
+ i = i + 1
+ self.gconf_client.set_int ("/apps/gnome-schedule/templates/crontab/last_id", i)
+ return i
+
+ def savetemplate_crontab (self, template_id, title, command, output, timeexpression):
+
+ if (template_id == 0):
+ template_id = self.create_new_id_crontab ()
+
+ self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/timeexpression" % (str (template_id)), timeexpression)
+ self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)), title)
+ self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)), command)
+ self.gconf_client.set_int("/apps/gnome-schedule/templates/crontab/%s/output" % (str (template_id)), output)
+
+ installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/installed")
+ if installed == None:
+ installed = str(template_id)
+ else:
+ found = False
+
+ for t in installed.split (", "):
+ if t == str (template_id):
+ found = True
+
+ if found == False:
+ installed = installed + ", " + str (template_id)
+
+ self.gconf_client.unset ("/apps/gnome-schedule/templates/crontab/installed")
+ self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/installed", installed)
+ self.parent.template_manager.reload_tv ()
+ self.parent.template_chooser.reload_tv ()
+
+
+ def gettemplateids (self, type):
+ strlist = self.gconf_client.get_string("/apps/gnome-schedule/templates/" + type + "/installed")
+ if strlist != None:
+
+ list = strlist.split (", ")
+ return list
+ else:
+ return None
+
+
+ def gettemplate (self, type, template_id):
+ if type == "crontab":
+ try:
+ command = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)))
+ title = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)))
+ output = self.gconf_client.get_int("/apps/gnome-schedule/templates/" + type + "/%s/output" % (str (template_id)))
+ timeexpression = self.gconf_client.get_string("/apps/gnome-schedule/templates/" + type + "/%s/timeexpression" % (template_id))
+ return template_id, title, command, output, timeexpression
+
+ except Exception, ex:
+ return False
+
+ elif type == "at":
+ try:
+ command = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)))
+ title = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)))
+ output = self.gconf_client.get_int ("/apps/gnome-schedule/templates/at/%s/output" % (str (template_id)))
+ return template_id, title, command, output
+
+ except Exception, ex:
+ return False
+
+ def create_new_id_at (self):
+ i = self.gconf_client.get_int ("/apps/gnome-schedule/templates/at/last_id")
+ if i == 0:
+ self.gconf_client.set_int ("/apps/gnome-schedule/templates/at/last_id", 1)
+ return 1
+ else:
+ i = i + 1
+ self.gconf_client.set_int ("/apps/gnome-schedule/templates/at/last_id", i)
+ return i
+
+ def savetemplate_at (self, template_id, title, command, output):
+ print "savetemplate"
+
+ if (template_id == 0):
+ template_id = self.create_new_id_at ()
+ print "got new id"
+
+ self.gconf_client.set_string("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)), title)
+ self.gconf_client.set_string("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)), command)
+ self.gconf_client.set_int ("/apps/gnome-schedule/templates/at/%s/output" % ( str(template_id)), output)
+
+
+ installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/installed")
+ if installed == None:
+ installed = str(template_id)
+ else:
+ found = False
+
+ for t in installed.split (", "):
+ if t == str (template_id):
+ found = True
+
+ if found == False:
+ installed = installed + ", " + str (template_id)
+
+ self.gconf_client.unset ("/apps/gnome-schedule/templates/at/installed")
+ self.gconf_client.set_string("/apps/gnome-schedule/templates/at/installed", installed)
+ self.parent.template_manager.reload_tv ()
+ self.parent.template_chooser.reload_tv ()
+
+ # TODO: output
+ def format_at (self, title, command, output):
+ command = self.parent.at.__make_preview__ (command, 0)
+ s = "<b>" + _("Title:") + "</b> " + title + "\n<b>" + _("Command:") + "</b> " + command
+ if output > 0:
+ s = (s + " <i>(%s)</i>") % (str (self.parent.output_strings [2]))
+
+ return s
+
+ def format_crontab (self, title, command, output, timeexpression):
+ command = self.parent.crontab.__make_preview__ (command)
+ if self.parent.edit_mode == "simple":
+ # hehe.. :)
+ timeexpression = timeexpression + " echo hehe"
+ minute, hour, dom, moy, dow, hehe = self.parent.crontab.parse (timeexpression, True)
+ timeexpression = self.parent.crontab.__easy__ (minute, hour, dom, moy, dow)
+
+ s = "<b>" + _("Title:") + "</b> " + title + "\n<b>" + _("Run:") + "</b> " + timeexpression + "\n<b>" + _("Command:") + "</b> " + command
+
+ if output > 0:
+ s = (s + " <i>(%s)</i>") % (str (self.parent.output_strings[output]))
+
+ return s
Modified: trunk/src/template_chooser.py
==============================================================================
--- trunk/src/template_chooser.py (original)
+++ trunk/src/template_chooser.py Sat Feb 14 21:20:56 2009
@@ -21,122 +21,122 @@
class TemplateChooser:
- def __init__ (self, parent, template):
- self.parent = parent
- self.template = template
- self.transient = self.parent.widget
-
- # setup window
- self.xml = self.parent.xml
- self.widget = self.xml.get_widget ("template_chooser")
- self.widget.connect("delete-event", self.widget.hide_on_delete)
-
-
- self.treeview = self.xml.get_widget ("tc_treeview")
- self.button_use = self.xml.get_widget ("tc_button_use")
- hbox = gtk.HBox ()
- icon = gtk.Image ()
- icon.set_from_pixbuf (self.parent.normalicontemplate)
- label = gtk.Label (_("Use template"))
- icon.set_alignment (0.5, 0.5)
- label.set_justify (gtk.JUSTIFY_CENTER)
- label.set_alignment (0.5, 0.5)
- hbox.pack_start (icon, True, True, 0)
- hbox.pack_start (label, True, True, 0)
- self.button_use.add (hbox)
- self.button_use.show_all ()
-
- self.button_cancel = self.xml.get_widget ("tc_button_cancel")
-
- self.xml.signal_connect ("on_tc_button_use_clicked", self.on_use_clicked)
- self.xml.signal_connect ("on_tc_button_cancel_clicked", self.on_cancel_clicked)
- self.xml.signal_connect ("on_tc_treeview_button_press_event", self.on_tv_pressed)
-
- self.treeview.get_selection().connect("changed", self.on_tv_changed)
-
- # setup liststore
- # [template id, type, type-string, formatted text, icon/pixbuf]
- self.treemodel = gtk.ListStore (gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gtk.gdk.Pixbuf)
-
- # setup treeview
- self.treeview.set_model (self.treemodel)
- self.treeview.set_headers_visible (True)
-
-
- rend1 = gtk.CellRendererPixbuf ()
- rend2 = gtk.CellRendererText ()
-
- column = gtk.TreeViewColumn(_("Task"))
- column.pack_start (rend1, True)
- column.pack_end (rend2, True)
- column.add_attribute (rend1, "pixbuf", 4)
- column.add_attribute (rend2, "text", 2)
- self.treeview.append_column(column)
-
-
- rend = gtk.CellRendererText ()
- column = gtk.TreeViewColumn(_("Description"), rend, markup=3)
- self.treeview.append_column(column)
-
- def on_tv_changed (self, *args):
- if self.treeview.get_selection().count_selected_rows() > 0 :
- value = True
- else:
- value = False
- self.button_use.set_sensitive (value)
-
- def reload_tv (self):
- self.treemodel.clear ()
- at = self.template.gettemplateids ("at")
- if at != None:
- for id in at:
- t = self.template.gettemplate ("at", int (id))
- if t != False:
- id2, title, command = t
- formatted = self.template.format_at (title, command)
- iter = self.treemodel.append ([int (id), "at", _("One-time"), formatted, self.parent.bigiconat])
-
- crontab = self.template.gettemplateids ("crontab")
- if crontab != None:
- for id in crontab:
- t = self.template.gettemplate ("crontab", int (id))
- if t != False:
- id2, title, command, nooutput, timeexpression = t
- formatted = self.template.format_crontab (title, command, nooutput, timeexpression)
- iter = self.treemodel.append ([int (id), "crontab", _("Recurrent"), formatted, self.parent.bigiconcrontab])
-
-
- def show (self, transient):
- # populate treeview
- self.reload_tv ()
- self.transient = transient
- self.widget.set_transient_for (transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.widget.show_all ()
-
- def on_tv_pressed (self, widget, event):
- if event.type == gtk.gdk._2BUTTON_PRESS:
- self.on_use_clicked(self, widget)
-
- def on_use_clicked (self, *args):
- store, iter = self.treeview.get_selection().get_selected()
- if iter != None:
- type = self.treemodel.get_value(iter, 1)
- id = self.treemodel.get_value(iter, 0)
- if type == "at":
- t = self.template.gettemplate ("at", int (id))
- if t != False:
- id2, title, command = t
- self.parent.at_editor.showadd_template (self.transient, title, command)
- elif type == "crontab":
- t = self.template.gettemplate ("crontab", int (id))
- if t != False:
- id2, title, command, nooutput, timeexpression = t
- self.parent.crontab_editor.showadd_template (self.transient, title, command, nooutput, timeexpression)
-
- self.widget.hide ()
-
- def on_cancel_clicked (self, *args):
- self.widget.hide ()
-
+ def __init__ (self, parent, template):
+ self.parent = parent
+ self.template = template
+ self.transient = self.parent.widget
+
+ # setup window
+ self.xml = self.parent.xml
+ self.widget = self.xml.get_widget ("template_chooser")
+ self.widget.connect("delete-event", self.widget.hide_on_delete)
+
+
+ self.treeview = self.xml.get_widget ("tc_treeview")
+ self.button_use = self.xml.get_widget ("tc_button_use")
+ hbox = gtk.HBox ()
+ icon = gtk.Image ()
+ icon.set_from_pixbuf (self.parent.normalicontemplate)
+ label = gtk.Label (_("Use template"))
+ icon.set_alignment (0.5, 0.5)
+ label.set_justify (gtk.JUSTIFY_CENTER)
+ label.set_alignment (0.5, 0.5)
+ hbox.pack_start (icon, True, True, 0)
+ hbox.pack_start (label, True, True, 0)
+ self.button_use.add (hbox)
+ self.button_use.show_all ()
+
+ self.button_cancel = self.xml.get_widget ("tc_button_cancel")
+
+ self.xml.signal_connect ("on_tc_button_use_clicked", self.on_use_clicked)
+ self.xml.signal_connect ("on_tc_button_cancel_clicked", self.on_cancel_clicked)
+ self.xml.signal_connect ("on_tc_treeview_button_press_event", self.on_tv_pressed)
+
+ self.treeview.get_selection().connect("changed", self.on_tv_changed)
+
+ # setup liststore
+ # [template id, type, type-string, formatted text, icon/pixbuf]
+ self.treemodel = gtk.ListStore (gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gtk.gdk.Pixbuf)
+
+ # setup treeview
+ self.treeview.set_model (self.treemodel)
+ self.treeview.set_headers_visible (True)
+
+
+ rend1 = gtk.CellRendererPixbuf ()
+ rend2 = gtk.CellRendererText ()
+
+ column = gtk.TreeViewColumn(_("Task"))
+ column.pack_start (rend1, True)
+ column.pack_end (rend2, True)
+ column.add_attribute (rend1, "pixbuf", 4)
+ column.add_attribute (rend2, "text", 2)
+ self.treeview.append_column(column)
+
+
+ rend = gtk.CellRendererText ()
+ column = gtk.TreeViewColumn(_("Description"), rend, markup=3)
+ self.treeview.append_column(column)
+
+ def on_tv_changed (self, *args):
+ if self.treeview.get_selection().count_selected_rows() > 0 :
+ value = True
+ else:
+ value = False
+ self.button_use.set_sensitive (value)
+
+ def reload_tv (self):
+ self.treemodel.clear ()
+ at = self.template.gettemplateids ("at")
+ if at != None:
+ for id in at:
+ t = self.template.gettemplate ("at", int (id))
+ if t != False:
+ id2, title, command, output = t
+ formatted = self.template.format_at (title, command, output)
+ iter = self.treemodel.append ([int (id), "at", _("One-time"), formatted, self.parent.bigiconat])
+
+ crontab = self.template.gettemplateids ("crontab")
+ if crontab != None:
+ for id in crontab:
+ t = self.template.gettemplate ("crontab", int (id))
+ if t != False:
+ id2, title, command, output, timeexpression = t
+ formatted = self.template.format_crontab (title, command, output, timeexpression)
+ iter = self.treemodel.append ([int (id), "crontab", _("Recurrent"), formatted, self.parent.bigiconcrontab])
+
+
+ def show (self, transient):
+ # populate treeview
+ self.reload_tv ()
+ self.transient = transient
+ self.widget.set_transient_for (transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.widget.show_all ()
+
+ def on_tv_pressed (self, widget, event):
+ if event.type == gtk.gdk._2BUTTON_PRESS:
+ self.on_use_clicked(self, widget)
+
+ def on_use_clicked (self, *args):
+ store, iter = self.treeview.get_selection().get_selected()
+ if iter != None:
+ type = self.treemodel.get_value(iter, 1)
+ id = self.treemodel.get_value(iter, 0)
+ if type == "at":
+ t = self.template.gettemplate ("at", int (id))
+ if t != False:
+ id2, title, command, output = t
+ self.parent.at_editor.showadd_template (self.transient, title, command, output)
+ elif type == "crontab":
+ t = self.template.gettemplate ("crontab", int (id))
+ if t != False:
+ id2, title, command, output, timeexpression = t
+ self.parent.crontab_editor.showadd_template (self.transient, title, command, output, timeexpression)
+
+ self.widget.hide ()
+
+ def on_cancel_clicked (self, *args):
+ self.widget.hide ()
+
Modified: trunk/src/template_manager.py
==============================================================================
--- trunk/src/template_manager.py (original)
+++ trunk/src/template_manager.py Sat Feb 14 21:20:56 2009
@@ -20,164 +20,164 @@
import gobject
class TemplateManager:
- def __init__ (self, parent, template):
- self.parent = parent
- self.template = template
+ def __init__ (self, parent, template):
+ self.parent = parent
+ self.template = template
- # setup window
- self.xml = self.parent.xml
- self.widget = self.xml.get_widget ("template_manager")
- self.widget.connect("delete-event", self.widget.hide_on_delete)
-
- self.treeview = self.xml.get_widget ("tm_treeview")
- self.button_use = self.xml.get_widget ("tm_button_use")
- hbox = gtk.HBox ()
- icon = gtk.Image ()
- icon.set_from_pixbuf (self.parent.normalicontemplate)
- label = gtk.Label (_("Use template"))
- icon.set_alignment (0.5, 0.5)
- label.set_justify (gtk.JUSTIFY_CENTER)
- label.set_alignment (0.5, 0.5)
- hbox.pack_start (icon, True, True, 0)
- hbox.pack_start (label, True, True, 0)
- self.button_use.add (hbox)
- self.button_use.show_all ()
-
- self.button_cancel = self.xml.get_widget ("tm_button_cancel")
-
- self.xml.signal_connect ("on_tm_button_new_clicked", self.on_new_clicked)
- self.xml.signal_connect ("on_tm_button_use_clicked", self.on_use_clicked)
- self.xml.signal_connect ("on_tm_button_cancel_clicked", self.on_cancel_clicked)
- self.xml.signal_connect ("on_tm_button_edit_clicked", self.on_edit_clicked)
- self.xml.signal_connect ("on_tm_button_delete_clicked", self.on_delete_clicked)
- self.xml.signal_connect ("on_tm_treeview_button_press_event", self.on_tv_pressed)
-
- self.button_edit = self.xml.get_widget ("tm_button_edit")
- self.button_delete = self.xml.get_widget ("tm_button_delete")
-
- self.treeview.get_selection().connect("changed", self.on_tv_changed)
-
- # setup liststore
- # [template id, type, type-string, formatted text, icon/pixbuf]
- self.treemodel = gtk.ListStore (gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gtk.gdk.Pixbuf)
-
- # setup treeview
- self.treeview.set_model (self.treemodel)
- self.treeview.set_headers_visible (True)
-
-
- rend1 = gtk.CellRendererPixbuf ()
- rend2 = gtk.CellRendererText ()
-
- column = gtk.TreeViewColumn(_("Task"))
- column.pack_start (rend1, True)
- column.pack_end (rend2, True)
- column.add_attribute (rend1, "pixbuf", 4)
- column.add_attribute (rend2, "text", 2)
- self.treeview.append_column(column)
-
-
- rend = gtk.CellRendererText ()
- column = gtk.TreeViewColumn(_("Description"), rend, markup=3)
- self.treeview.append_column(column)
+ # setup window
+ self.xml = self.parent.xml
+ self.widget = self.xml.get_widget ("template_manager")
+ self.widget.connect("delete-event", self.widget.hide_on_delete)
+
+ self.treeview = self.xml.get_widget ("tm_treeview")
+ self.button_use = self.xml.get_widget ("tm_button_use")
+ hbox = gtk.HBox ()
+ icon = gtk.Image ()
+ icon.set_from_pixbuf (self.parent.normalicontemplate)
+ label = gtk.Label (_("Use template"))
+ icon.set_alignment (0.5, 0.5)
+ label.set_justify (gtk.JUSTIFY_CENTER)
+ label.set_alignment (0.5, 0.5)
+ hbox.pack_start (icon, True, True, 0)
+ hbox.pack_start (label, True, True, 0)
+ self.button_use.add (hbox)
+ self.button_use.show_all ()
+
+ self.button_cancel = self.xml.get_widget ("tm_button_cancel")
+
+ self.xml.signal_connect ("on_tm_button_new_clicked", self.on_new_clicked)
+ self.xml.signal_connect ("on_tm_button_use_clicked", self.on_use_clicked)
+ self.xml.signal_connect ("on_tm_button_cancel_clicked", self.on_cancel_clicked)
+ self.xml.signal_connect ("on_tm_button_edit_clicked", self.on_edit_clicked)
+ self.xml.signal_connect ("on_tm_button_delete_clicked", self.on_delete_clicked)
+ self.xml.signal_connect ("on_tm_treeview_button_press_event", self.on_tv_pressed)
+
+ self.button_edit = self.xml.get_widget ("tm_button_edit")
+ self.button_delete = self.xml.get_widget ("tm_button_delete")
+
+ self.treeview.get_selection().connect("changed", self.on_tv_changed)
+
+ # setup liststore
+ # [template id, type, type-string, formatted text, icon/pixbuf]
+ self.treemodel = gtk.ListStore (gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gtk.gdk.Pixbuf)
+
+ # setup treeview
+ self.treeview.set_model (self.treemodel)
+ self.treeview.set_headers_visible (True)
+
+
+ rend1 = gtk.CellRendererPixbuf ()
+ rend2 = gtk.CellRendererText ()
+
+ column = gtk.TreeViewColumn(_("Task"))
+ column.pack_start (rend1, True)
+ column.pack_end (rend2, True)
+ column.add_attribute (rend1, "pixbuf", 4)
+ column.add_attribute (rend2, "text", 2)
+ self.treeview.append_column(column)
+
+
+ rend = gtk.CellRendererText ()
+ column = gtk.TreeViewColumn(_("Description"), rend, markup=3)
+ self.treeview.append_column(column)
- def on_tv_changed (self, *args):
- if self.treeview.get_selection().count_selected_rows() > 0 :
- value = True
- else:
- value = False
- self.button_use.set_sensitive (value)
- self.button_edit.set_sensitive (value)
- self.button_delete.set_sensitive (value)
-
- def reload_tv (self):
- self.treemodel.clear ()
- at = self.template.gettemplateids ("at")
- if at != None:
- for id in at:
- t = self.template.gettemplate ("at", int (id))
- if t != False:
- id2, title, command = t
- formatted = self.template.format_at (title, command)
- iter = self.treemodel.append ([int (id), "at", _("One-time"), formatted, self.parent.bigiconat])
+ def on_tv_changed (self, *args):
+ if self.treeview.get_selection().count_selected_rows() > 0 :
+ value = True
+ else:
+ value = False
+ self.button_use.set_sensitive (value)
+ self.button_edit.set_sensitive (value)
+ self.button_delete.set_sensitive (value)
+
+ def reload_tv (self):
+ self.treemodel.clear ()
+ at = self.template.gettemplateids ("at")
+ if at != None:
+ for id in at:
+ t = self.template.gettemplate ("at", int (id))
+ if t != False:
+ id2, title, command, output = t
+ formatted = self.template.format_at (title, command, output)
+ iter = self.treemodel.append ([int (id), "at", _("One-time"), formatted, self.parent.bigiconat])
- crontab = self.template.gettemplateids ("crontab")
- if crontab != None:
- for id in crontab:
- t = self.template.gettemplate ("crontab", int (id))
- if t != False:
- id2, title, command, nooutput, timeexpression = t
- formatted = self.template.format_crontab (title, command, nooutput, timeexpression)
- iter = self.treemodel.append ([int (id), "crontab", _("Recurrent"), formatted, self.parent.bigiconcrontab])
-
- def on_edit_clicked (self, *args):
- store, iter = self.treeview.get_selection().get_selected()
- if iter != None:
- type = self.treemodel.get_value(iter, 1)
- id = self.treemodel.get_value(iter, 0)
- if type == "at":
- t = self.template.gettemplate ("at", int (id))
- if t != False:
- id2, title, command = t
- self.parent.at_editor.showedit_template (self.widget, id2, title, command)
-
- elif type == "crontab":
- t = self.template.gettemplate ("crontab", int (id) )
- if t != False:
- id2, title, command, nooutput, timeexpression = t
- self.parent.crontab_editor.showedit_template (self.widget, id2, title, command, nooutput, timeexpression)
- self.reload_tv ()
-
- def on_new_clicked (self, *args):
- self.parent.addWindow.ShowAddWindow (self.widget, 1)
-
- def on_delete_clicked (self, *args):
- store, iter = self.treeview.get_selection().get_selected()
- if iter != None:
- type = self.treemodel.get_value(iter, 1)
- id = self.treemodel.get_value(iter, 0)
- if type == "at":
- self.template.removetemplate_at (id)
- elif type == "crontab":
- self.template.removetemplate_crontab (id)
-
- self.reload_tv ()
-
-
-
- def show (self, transient):
- # populate treeview
- self.reload_tv ()
-
- self.widget.set_transient_for(transient)
- self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
- self.widget.show_all ()
-
- def on_tv_pressed (self, widget, event):
- if event.type == gtk.gdk._2BUTTON_PRESS:
- self.on_edit_clicked(self, widget)
-
- def on_use_clicked (self, *args):
- store, iter = self.treeview.get_selection().get_selected()
- if iter != None:
- type = self.treemodel.get_value(iter, 1)
- id = self.treemodel.get_value(iter, 0)
- if type == "at":
- t = self.template.gettemplate ("at", int (id))
- if t != False:
- id2, title, command = t
- self.parent.at_editor.showadd_template (self.widget, title, command)
- elif type == "crontab":
- t = self.template.gettemplate ("crontab", int (id) )
- if t != False:
- id2, title, command, nooutput, timeexpression = t
- self.parent.crontab_editor.showadd_template (self.widget, title, command, nooutput, timeexpression)
-
- self.widget.hide ()
-
- def on_cancel_clicked (self, *args):
- self.widget.hide ()
-
+ crontab = self.template.gettemplateids ("crontab")
+ if crontab != None:
+ for id in crontab:
+ t = self.template.gettemplate ("crontab", int (id))
+ if t != False:
+ id2, title, command, output, timeexpression = t
+ formatted = self.template.format_crontab (title, command, output, timeexpression)
+ iter = self.treemodel.append ([int (id), "crontab", _("Recurrent"), formatted, self.parent.bigiconcrontab])
+
+ def on_edit_clicked (self, *args):
+ store, iter = self.treeview.get_selection().get_selected()
+ if iter != None:
+ type = self.treemodel.get_value(iter, 1)
+ id = self.treemodel.get_value(iter, 0)
+ if type == "at":
+ t = self.template.gettemplate ("at", int (id))
+ if t != False:
+ id2, title, command = t
+ self.parent.at_editor.showedit_template (self.widget, id2, title, command)
+
+ elif type == "crontab":
+ t = self.template.gettemplate ("crontab", int (id) )
+ if t != False:
+ id2, title, command, output, timeexpression = t
+ self.parent.crontab_editor.showedit_template (self.widget, id2, title, command, output, timeexpression)
+ self.reload_tv ()
+
+ def on_new_clicked (self, *args):
+ self.parent.addWindow.ShowAddWindow (self.widget, 1)
+
+ def on_delete_clicked (self, *args):
+ store, iter = self.treeview.get_selection().get_selected()
+ if iter != None:
+ type = self.treemodel.get_value(iter, 1)
+ id = self.treemodel.get_value(iter, 0)
+ if type == "at":
+ self.template.removetemplate_at (id)
+ elif type == "crontab":
+ self.template.removetemplate_crontab (id)
+
+ self.reload_tv ()
+
+
+
+ def show (self, transient):
+ # populate treeview
+ self.reload_tv ()
+
+ self.widget.set_transient_for(transient)
+ self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+ self.widget.show_all ()
+
+ def on_tv_pressed (self, widget, event):
+ if event.type == gtk.gdk._2BUTTON_PRESS:
+ self.on_edit_clicked(self, widget)
+
+ def on_use_clicked (self, *args):
+ store, iter = self.treeview.get_selection().get_selected()
+ if iter != None:
+ type = self.treemodel.get_value(iter, 1)
+ id = self.treemodel.get_value(iter, 0)
+ if type == "at":
+ t = self.template.gettemplate ("at", int (id))
+ if t != False:
+ id2, title, command, output = t
+ self.parent.at_editor.showadd_template (self.widget, title, command, output)
+ elif type == "crontab":
+ t = self.template.gettemplate ("crontab", int (id) )
+ if t != False:
+ id2, title, command, output, timeexpression = t
+ self.parent.crontab_editor.showadd_template (self.widget, title, command, output, timeexpression)
+
+ self.widget.hide ()
+
+ def on_cancel_clicked (self, *args):
+ self.widget.hide ()
+
-
-
+
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]