#! /usr/bin/env python # # # Apollia's Relative Scheduler v1.0 # # by Apollia of Astroblahhh.Com - http://astroblahhh.com # # # Original version completed in March or April 2012. # # First releasable version completed July 21, 2014. # # Released July 21, 2014. # # # A Python 2.6 script for Lucid Puppy Linux 5.2.8 version 004. # # Might work on other platforms, or could be modified to do so. # # #------------------------------------------------------------------------------ # # # Warning: If you use cron, this script will wipe out your existing cron # events! # # # This script asks for the time you woke up, then generates a schedule with # events relative to that time (and some fixed events, if you want). # # The schedule is an HTML file viewable in a web browser. # # Also sets up cron to display reminders. # # # See comments throughout the source code for info on how to use this script. # # #------------------------------------------------------------------------------ # # # Copyright (C) 2014 Apollia # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see http://www.gnu.org/licenses/ . # # # Contact info: http://astroblahhh.com/contact-apollia.shtml # # # ---- ########################################################################## # # Variables whose values you can change # # True|False Should_Launch_Console_Window_In_Which_To_Run_This_Script = True Future_Days_to_Display=4 # Maximum 6, otherwise you get duplicate events listed for # today in the HTML schedule. Shell_Command_to__Launch_Web_Browser = "dillo" Shell_Command_to__Launch_Cron = "crond" Shell_Command_to__Kill_Cron = "pkill crond" #----------------------------- # # File paths # Filepath_to__Crontab_File = "/var/spool/cron/crontabs/root" # Location in Lucid Puppy 5.2.8: "/var/spool/cron/crontabs/root" Filepath_to__Most_Recent_Wake_Datime_File = "/root/Most Recent Wake Datime" # The file which will contain your most recent date/time of # waking. That date/time is stored in a file so if you reboot, # you won't have to remember and reinput the time you woke up. # # If you don't care about saving it, you can keep the # file somewhere in the Puppy RAM disk, like: # # /root/Most Recent Wake Datime #----------------------------- # # Log-related Should_Make_Log_Entries = True Filepath_to__Relative_Scheduler_Log = "/root/Relative Scheduler Log" # The log with the dates/times the script was run plus the # date/time of waking that was used or input on each run. # # If you don't care about keeping a log permanently, you can # store it somewhere in the Puppy RAM disk, like: # # /root/Relative Scheduler Log #-------------------------------------------- # # HTML Relative Schedule-related variables # Folderpath_to__HTML_Relative_Schedule_Folder = "/root/Relative Schedules/" # If you don't care about keeping the relative schedule HTML files, # you can just leave this somewhere in the Puppy RAM disk, like: # /root/Relative Schedules/ # # If the folder doesn't already exist, it will be created. Extensionless_Filename_of__HTML_Relative_Schedule = "Relative_Schedule" # Leave off .html, it gets added later automatically. Should_Create_HTML_Relative_Schedules = True Should_Display_HTML_Relative_Schedule_When_Script_is_Done = True Should_Output_Dated_HTML_Relative_Schedule = True # If you want to keep each day's HTML relative schedule, set # this to True so a dated copy of it will be output in addition # to the undated copy. Also, change # Folderpath_to__HTML_Relative_Schedule_Folder to a location # that's not in Puppy's RAM disk. HTML_Relative_Schedule__BG_Color = "black" HTML_Relative_Schedule__Text_Color = "limegreen" # # End of HTML Relative Schedule-related variables # #----------------------------------------------------- # # End of Variables whose values you can change # ########################################################################## ########################################################################## # # gtkdialog-splash Help # # Not by Apollia. The below text is included in Lucid Puppy 5.2.8 # and is shown when you type "gtkdialog-splash" or "yaf-splash" # in a console window. # # Included below for convenience. # #------------------------------------------------------------------------- # # gtkdialog-splash # # an easy replacement for yaf-splash in Puppy (NOT Puppy <=4.x) # mave 30.05.2010 # no warranty # Thanks for Puppy! # # usage: gtkdialog-splash [OPTIONS] [-timeout SEC] -text TEXT | -kill PID # # -text EXPRESSION # -timeout COUNT (in seconds) # -icon GTK-XXX (for example: gtk-info all gtk-stock-symbols, default: none) # -bg COLOR (background color red, blue, yellow..., default: grey) # -fg COLOR (font color, default: black) # -placement center|mouse|top|bottom|top-left|bottom-left (default center) # -close never|mouseover|box (default is mouseover) # -deco TITLE (shows windows decorations, with title) # -fontsize SIZE (small, medium, large, x-large, default: medium) # # -kill PID (process ID called before: PID=0 auto-search fo the last one, # PID=xxxxx kill the last one read by PID=$!) # # #------------------------------------------------------------------------- # Apollia's note: # # The dialogs that gtkdialog-splash creates can interfere with your # typing, so if one pops up at the moment you try to save something with # Ctrl-S, make sure it really got saved. ########################################################################## # # First Few Needed Imports # No need to change anything in this section. import os from subprocess import call import sys # # End of First Few Needed Imports # ########################################################################## ########################################################################## # # RunThisScriptInConsoleWindow() section # # Makes this script run in an RXVT window. # # If you don't have the RXVT console program, you'll have to change # this code, or comment out the line that calls the function, or # set Should_Launch_Console_Window_In_Which_To_Run_This_Script to False: def RunThisScriptInConsoleWindow(): if len (sys.argv)==1 : File_Path_To_This_Script = os.path.realpath( __file__) command_line = "rxvt -rv +sb -sl 999 -title \"Apollia's Simple Relative Scheduler\" -e python \"" + File_Path_To_This_Script + "\" 1" print command_line call(command_line, shell=True); sys.exit() # To stop the above function from running, comment out the next 2 lines, # or set Should_Launch_Console_Window_In_Which_To_Run_This_Script to # False: if Should_Launch_Console_Window_In_Which_To_Run_This_Script==True: RunThisScriptInConsoleWindow() # # End of RunThisScriptInConsoleWindow() section # # ########################################################################## ########################################################################## # # More Imports # No need to change anything in this section. from datetime import datetime from datetime import timedelta # # End of More Imports # ########################################################################## ########################################################################## # # Variables whose values you shouldn't change # Should_End_Script_Early = False Five_Spaces=" " EventsList = [] Num_of_Events = 0 Now_Datime = datetime.now() Now_DateOnly_String = datetime.strftime(Now_Datime, "%x") if Should_Create_HTML_Relative_Schedules: Filepath_to__Todays_HTML_Relative_Schedule = Folderpath_to__HTML_Relative_Schedule_Folder + Extensionless_Filename_of__HTML_Relative_Schedule + ".html" #------------------------------ # # Variables for readability Most_Recent_Wake_Datime__from_file=None Should_Use_10_Minutes_If_Blank_Input=False Should_Make_New_Most_Recent_Wake_Datime_File=False # # End of Variables whose values you shouldn't change # ########################################################################## ########################################################################## # # Functions # # Python annoyingly makes you put functions before the place they get # used, so, here are some near the top, before anything much happens # in the script. # # # #------------------------------------------------------------------------- def EndScript(): print "\n\nScript finished!\n" print "\nYou can press Return (or Enter) to close this window.\n" wait_for_return = raw_input() sys.exit() #------------------------------------------------------------------------- def ConvertDayOfWeekToNum(day_string): if day_string=="Monday" or day_string=="Mon": return 0 elif day_string=="Tuesday" or day_string=="Tue": return 1 elif day_string=="Wednesday" or day_string=="Wed": return 2 elif day_string=="Thursday" or day_string=="Thu": return 3 elif day_string=="Friday" or day_string=="Fri": return 4 elif day_string=="Saturday" or day_string=="Sat": print 5 return 5 elif day_string=="Sunday" or day_string=="Sun": # print "6!!" return 6 else: return -1 #------------------------------- def ConvertNumToDayOfWeek(day_num): if day_num==0: return "Monday" elif day_num==1: return "Tuesday" elif day_num==2: return "Wednesday" elif day_num==3: return "Thursday" elif day_num==4: return "Friday" elif day_num==5: return "Saturday" elif day_num==6: return "Sunday" else: return -1 #------------------------------- ########################################################################## # # # OK, now the script begins. Most_Recent_Wake_Datime__from_file = None if os.path.exists(Filepath_to__Most_Recent_Wake_Datime_File): # If that file exists, we should read the datetime from there # and tell the user to press return to reuse that value. with open(Filepath_to__Most_Recent_Wake_Datime_File) as Filehandle__Most_Recent_Wake_Datime: Most_Recent_Wake_Datime__from_file=Filehandle__Most_Recent_Wake_Datime.readline() Most_Recent_Wake_Datime__from_file=datetime.strptime(Most_Recent_Wake_Datime__from_file, "%c") # Converts the string to a datetime object. print "\n" if os.path.exists(os.path.dirname(Filepath_to__Most_Recent_Wake_Datime_File) )==False: print "\nError: Please either change Filepath_to__Most_Recent_Wake_Datime_File to a path whose directories all exist, or create the nonexistent directories." print "Current Filepath_to__Most_Recent_Wake_Datime_File:" print " " + Filepath_to__Most_Recent_Wake_Datime_File Should_End_Script_Early = True if os.path.exists(os.path.dirname(Filepath_to__Relative_Scheduler_Log) )==False: print "\nError: Please either change Filepath_to__Relative_Scheduler_Log to a path whose directories all exist, or create the nonexistent directories." print "Current Filepath_to__Relative_Scheduler_Log:" print " " + Filepath_to__Relative_Scheduler_Log Should_End_Script_Early = True if Should_End_Script_Early: EndScript(); # The next step is to run the below function, GetWakeTime(). # # Which I can't do until after declaring the function, # because Python annoyingly won't let me. #------------------------------- # # Start of GetWakeTime() function def GetWakeTime(): Should_Use_10_Minutes_If_Blank_Input=False Waking_Datime=None while True: Day_Is_Not_Digit=False print "What time (in 24-hour format) or how many minutes ago did you wake up?" if Most_Recent_Wake_Datime__from_file is not None: print "\nOr press Enter to use " + str(Most_Recent_Wake_Datime__from_file) + ", the previous date/time of waking." else: # If the most recent wake datime file doesn't exist... print "\nOr press Enter to use 10 minutes ago." Should_Use_10_Minutes_If_Blank_Input = True print "\nOr, put the time followed by a space and the number of days ago you woke up." input = raw_input("\n\n> ") if input=="q": print "Quitting...\n" sys.exit() if input.isdigit(): Minutes_Ago_I_Woke=input Waking_Datime = Now_Datime - timedelta(minutes=int(Minutes_Ago_I_Woke) ) elif len(input)<1: if Should_Use_10_Minutes_If_Blank_Input: print "No input, using 10 minutes ago by default.\n" Minutes_Ago_I_Woke=10 Waking_Datime = Now_Datime - timedelta(minutes=int(Minutes_Ago_I_Woke) ) else: print "No input, using previous date/time of waking by default.\n" Waking_Datime = Most_Recent_Wake_Datime__from_file elif input.find(":") != -1: # The user may have input a time. if input.find(" ") != -1: fragments = input.split(' ') Number_Of_Days_Ago = fragments[1] input = fragments[0] if Number_Of_Days_Ago.isdigit() == False: Day_Is_Not_Digit = True DateOnly_String = Now_DateOnly_String else: DaysAgo_Datime = Now_Datime - timedelta(days=int(Number_Of_Days_Ago)) DateOnly_String = datetime.strftime(DaysAgo_Datime, "%x") else: DateOnly_String = Now_DateOnly_String try: Waking_Datime=datetime.strptime(input + " " + DateOnly_String, "%H:%M %x") except ValueError: print "Incorrectly formatted time, please reenter.\n" if Day_Is_Not_Digit: Waking_Datime = None print "The number of days is incorrectly formatted, please reenter it.\n" else: print "Couldn't understand that input, please try again.\n" if Waking_Datime is not None: return Waking_Datime # # End of GetWakeTime() function # #------------------------------- Waking_Datime=GetWakeTime() Now_Datime = datetime.now() Now_DateOnly_String = datetime.strftime(Now_Datime, "%x") Latest_Future_Minutes = (Future_Days_to_Display * 1440) + 1 Latest_Future_Datime = Waking_Datime + timedelta (minutes=Latest_Future_Minutes) # 1441 minutes = 24 hours plus 1 minute. current_day_num=Now_Datime.weekday() Latest_Future_Day_to_Display = current_day_num + Future_Days_to_Display Latest_Future_Day_to_Calculate = current_day_num + 7 Formatted_Wake_Datime_String=Waking_Datime.strftime("%c") Formatted_Now_Datime_String=Now_Datime.strftime("%c") if Most_Recent_Wake_Datime__from_file != None: # If we successfully got the most recent wake datime out of the file... if Formatted_Wake_Datime_String != Most_Recent_Wake_Datime__from_file.strftime("%c"): # If the input wake datime is different from the datime in the file... Should_Make_New_Most_Recent_Wake_Datime_File=True # But if the datimes were the same, no need to remake the file. else: # There was no file with the most recent wake datime, so we better make one. Should_Make_New_Most_Recent_Wake_Datime_File=True if Should_Make_New_Most_Recent_Wake_Datime_File: try: with open(Filepath_to__Most_Recent_Wake_Datime_File, "w") as Filehandle__Most_Recent_Wake_Datime: Filehandle__Most_Recent_Wake_Datime.write(Waking_Datime.strftime("%c")) except IOError as ErrorInfo: print "Couldn't write most recent wake date/time to:" print " " + Filepath_to__Most_Recent_Wake_Datime_File print print ErrorInfo errno = ErrorInfo.args[0] if errno==2: if os.path.exists(os.path.dirname(Filepath_to__Most_Recent_Wake_Datime_File) )==False: print "\nNonexistent parent directory or directories. Please either change Filepath_to__Most_Recent_Wake_Datime_File to a path whose directories all exist, or create the nonexistent directories." EndScript(); if Should_Make_Log_Entries: try: with open(Filepath_to__Relative_Scheduler_Log, "a") as Filehandle__Relative_Scheduler_Log: log_line_to_write = Formatted_Now_Datime_String + ". " + Formatted_Wake_Datime_String + "\n" Filehandle__Relative_Scheduler_Log.write(log_line_to_write) except IOError as ErrorInfo: print "Couldn't write log entry to:" print " " + Filepath_to__Relative_Scheduler_Log print print ErrorInfo errno = ErrorInfo.args[0] if errno==2: if os.path.exists(os.path.dirname(Filepath_to__Relative_Scheduler_Log) )==False: print "\nNonexistent parent directory or directories. Please either change Filepath_to__Relative_Scheduler_Log to a path whose directories all exist, or create the nonexistent directories." EndScript(); call(Shell_Command_to__Kill_Cron, shell=True); if os.path.isfile(Filepath_to__Crontab_File): os.remove(Filepath_to__Crontab_File) ####################################################################### # # Event List # def MakeCrontabFieldsFor(ThisEventObject): occurrence=ThisEventObject.occurrence this_datime=ThisEventObject.datime minute=this_datime.minute hour=this_datime.hour multi_crontab_fields=False day="*" month="*" dayofweek="*" if occurrence=="One Time Event": day=this_datime.day month=this_datime.month elif occurrence=="Sunday" or occurrence=="Sun": dayofweek = 0 elif occurrence=="Monday" or occurrence=="Mon": dayofweek = 1 elif occurrence=="Tuesday" or occurrence=="Tue": dayofweek = 2 elif occurrence=="Wednesday" or occurrence=="Wed": dayofweek = 3 elif occurrence=="Thurday" or occurrence=="Thu": dayofweek = 4 elif occurrence=="Friday" or occurrence=="Fri": dayofweek = 5 elif occurrence=="Saturday" or occurrence=="Sat": dayofweek = 6 elif occurrence=="daily": day = "*" month = "*" dayofweek = "*" num_of_pseudo_events=0 while (num_of_pseudo_events<=Future_Days_to_Display): PseudoEventVarName = "Event%s_%s" % (ThisEventObject.id, num_of_pseudo_events) pseudo_event_day_num=current_day_num+num_of_pseudo_events if pseudo_event_day_num>6: pseudo_event_day_num=pseudo_event_day_num-7 pseudo_event_day_of_week=ConvertNumToDayOfWeek(pseudo_event_day_num) globals()[PseudoEventVarName]=Event(ThisEventObject.name, "HTML Schedule Only", ThisEventObject.datime, pseudo_event_day_of_week) num_of_pseudo_events = num_of_pseudo_events + 1 elif occurrence=="weekends": multi_crontab_fields=True these_crontab_fields=str(minute) + " " + str(hour) + " * * 0" these_crontab_fields+="\n" + str(minute) + " " + str(hour) + " * * 6" PseudoEventName = "Event%s_Sunday" % ThisEventObject.id globals()[PseudoEventName]=Event(ThisEventObject.name, "HTML Schedule Only", ThisEventObject.datime, "Sunday") PseudoEventName = "Event%s_Saturday" % ThisEventObject.id globals()[PseudoEventName]=Event(ThisEventObject.name, "HTML Schedule Only", ThisEventObject.datime, "Saturday") elif occurrence=="weekdays": multi_crontab_fields=True these_crontab_fields=str(minute) + " " + str(hour) + " * * 1" these_crontab_fields+="\n" + str(minute) + " " + str(hour) + " * * 2" these_crontab_fields+="\n" + str(minute) + " " + str(hour) + " * * 3" these_crontab_fields+="\n" + str(minute) + " " + str(hour) + " * * 4" these_crontab_fields+="\n" + str(minute) + " " + str(hour) + " * * 5" PseudoEventName = "Event%s_Monday" % ThisEventObject.id print PseudoEventName globals()[PseudoEventName]=Event(ThisEventObject.name, "HTML Schedule Only", ThisEventObject.datime, "Monday") PseudoEventName = "Event%s_Tuesday" % ThisEventObject.id print PseudoEventName globals()[PseudoEventName]=Event(ThisEventObject.name, "HTML Schedule Only", ThisEventObject.datime, "Tuesday") PseudoEventName = "Event%s_Wednesday" % ThisEventObject.id print PseudoEventName globals()[PseudoEventName]=Event(ThisEventObject.name, "HTML Schedule Only", ThisEventObject.datime, "Wednesday") PseudoEventName = "Event%s_Thursday" % ThisEventObject.id print PseudoEventName globals()[PseudoEventName]=Event(ThisEventObject.name, "HTML Schedule Only", ThisEventObject.datime, "Thursday") PseudoEventName = "Event%s_Friday" % ThisEventObject.id print PseudoEventName globals()[PseudoEventName]=Event(ThisEventObject.name, "HTML Schedule Only", ThisEventObject.datime, "Friday") if multi_crontab_fields==False: these_crontab_fields=str(minute) + " " + str(hour) + " " + str(day) + " " + str(month) + " " + str(dayofweek) return these_crontab_fields #------------------------------- class Event: def __init__(self, event_name, at_text, datime, occurrence=None, time_addition_quantity=None, time_addition_unit=None): # Arguments: # # self - don't know why that has to be there at all # # event_name - the event name. Displayed in HTML schedule. # # at_text - mostly for readability, but if it's set to "HTML Schedule Only", # sets self.HTML_Schedule_Only to True. # # datime - Preferably a datetime object, or, less preferably, a string. # # Optional arguments # -------------------- # occurrence - "plus", "minus", "+" or "-", "today", "weekdays", "weekends", # Sun, Mon, Tue, Wed, Thu, Fri, Sat. # # time_addition_quantity - the number of time units to add. # # time_addition_unit - the type of time unit to add. # # "minutes", "hours", "days", "weeks", "seconds" # and even: # "microseconds", "milliseconds" ######################################################################### global Num_of_Events Num_of_Events=Num_of_Events+1 Add_To_Event_List=True self.id=Num_of_Events self.name=event_name Relative_Event = None if at_text == "HTML Schedule Only": self.HTML_Schedule_Only=True if time_addition_unit == "minute": time_addition_unit = "minutes" elif time_addition_unit == "hour": time_addition_unit = "hours" elif time_addition_unit == "day": time_addition_unit = "days" elif time_addition_unit == "second": time_addition_unit = "seconds" elif time_addition_unit == "microsecond": time_addition_unit = "microseconds" elif time_addition_unit == "millisecond": time_addition_unit = "milliseconds" kwargs = {time_addition_unit: time_addition_quantity} if isinstance(datime, str): # If datime is a string, then... # We assume only a time was provided, and append today's day/month/year to turn # it into a useable datetime object. # Later, if it turns out the user mentioned a day, the datime will be adjusted. datime = datetime.strptime(datime + " " + Now_DateOnly_String, "%H:%M %x") elif isinstance(datime, Event): Relative_Event = datime datime = Relative_Event.datime if occurrence == "plus" or occurrence=="+": self.datime = datime + timedelta(**kwargs) elif occurrence == "minus" or occurrence=="-": self.datime = datime - timedelta(**kwargs) elif occurrence is None or occurrence == "today": self.datime = datime else: event_day_num=ConvertDayOfWeekToNum(occurrence) if event_day_num!=-1: if event_day_num==current_day_num: self.datime = datime else: future_day_num=current_day_num+1 num_of_days_in_future=1 comparison_future_day_num=0 while future_day_num6: comparison_future_day_num=future_day_num-7 else: comparison_future_day_num = future_day_num if event_day_num==comparison_future_day_num: self.datime = datime + timedelta (days = num_of_days_in_future) future_day_num=future_day_num+1 num_of_days_in_future=num_of_days_in_future+1 if hasattr(self, "datime")==False: self.datime = datime Add_To_Event_List=False else: self.datime = datime if Relative_Event is not None: occurrence = Relative_Event.occurrence if occurrence=="daily" or occurrence=="weekdays" or occurrence=="weekends" or occurrence=="Sunday" or occurrence=="Monday" or occurrence=="Tuesday" or occurrence=="Wednesday" or occurrence=="Thursday" or occurrence=="Friday" or occurrence=="Saturday" or occurrence=="Sun" or occurrence=="Mon" or occurrence=="Tue" or occurrence=="Wed" or occurrence=="Thu" or occurrence=="Fri" or occurrence=="Sat" or occurrence=="HTML Schedule Only": self.occurrence = occurrence else: self.occurrence = "One Time Event" if hasattr(self, "HTML_Schedule_Only")==False: self.crontab_fields = MakeCrontabFieldsFor(self) if Add_To_Event_List==True: EventsList.append(self) def MakeCrontabLineOrLines(self, command_line): if self.crontab_fields.find("\n") != -1: # Then, need to make multiple lines. split_crontab_fields = self.crontab_fields.split("\n") self.crontab_line_or_lines = "" for each_field in split_crontab_fields: self.crontab_line_or_lines += each_field + Five_Spaces + command_line + "\n" else: # Just one line. self.crontab_line_or_lines = self.crontab_fields + Five_Spaces + command_line # # End of Event class def # #------------------------------------------- Midnight = Event("Midnight", "at", "0:00", "daily") Midnight.MakeCrontabLineOrLines("yaf-splash -placement center -close mouseover -bg navy -fg lavender -timeout 5 -text 'Midnight...' -fontsize x-large #") Almost_6_AM_Warning = Event("Almost 6 AM Warning", "at", "5:30", "daily") Almost_6_AM_Warning.MakeCrontabLineOrLines("yaf-splash -placement center -close box -bg orange -fg black -text '5:30 AM!' -fontsize x-large #") Waking = Event("Awoke", "at", Waking_Datime, "plus", 0, "minutes") Cron_Startup_Test=Event("Cron Startup Test", "at", Now_Datime, "plus", 1, "minutes") Cron_Startup_Test.MakeCrontabLineOrLines("yaf-splash -placement top-left -timeout 5 -close box -bg violet -fg yellow -text 'Cron startup worked!' -fontsize x-large #") Breakfast=Event("Breakfast", "at", Waking, "plus", 70, "minutes") Breakfast.MakeCrontabLineOrLines("yaf-splash -placement center -close box -bg purple -fg lavender -text 'Time for Breakfast! " + Breakfast.datime.strftime("%X") + "' -fontsize x-large #") Vitamin_B=Event("Vitamin B", "at", Breakfast, "plus", 15, "minutes") Vitamin_B.MakeCrontabLineOrLines("yaf-splash -placement center -close box -bg orange -fg white -text 'Time for Vitamin B! " + Vitamin_B.datime.strftime("%X") + "' -fontsize x-large #") # 22:48 07/20/2014. Things I've read about lucid dreaming say that to encourage yourself # to learn to lucid dream, you should periodically ask yourself throughout the day: # are you dreaming? Are_You_Dreaming_A=Event("Are you dreaming? A", "at", Breakfast, "plus", 60, "minutes") Are_You_Dreaming_A.MakeCrontabLineOrLines("yaf-splash -placement center -close box -bg green -fg yellow -text 'Are you dreaming? " + Are_You_Dreaming_A.datime.strftime("%X") + "' -fontsize x-large #") Noon = Event("Noon", "at", "12:00", "daily") Noon.MakeCrontabLineOrLines("yaf-splash -placement center -close mouseover -bg orange -fg yellow -timeout 5 -text 'Noon...' -fontsize x-large #") Lunch = Event("Lunch", "at", Breakfast, "plus", 320, "minutes") Lunch.MakeCrontabLineOrLines("yaf-splash -placement center -close box -bg purple -fg lavender -text 'Time for Lunch! " + Lunch.datime.strftime("%X") + "' -fontsize x-large #") Are_You_Dreaming_B=Event("Are you dreaming? B", "at", Lunch, "plus", 60, "minutes") Are_You_Dreaming_B.MakeCrontabLineOrLines("yaf-splash -placement center -close box -bg green -fg yellow -text 'Are you dreaming? " + Are_You_Dreaming_B.datime.strftime("%X") + "' -fontsize x-large #") Six_Hours_After_Waking = Event("*** 6 hours after waking", "at", Waking, "plus", 6, "hours") Six_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg green -fg yellow -text '6 hours after waking! " + Six_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Dinner = Event("Dinner", "at", Lunch.datime, "plus", 360, "minutes") Dinner.MakeCrontabLineOrLines("yaf-splash -placement center -close box -bg purple -fg lavender -text 'Time for Dinner! " + Dinner.datime.strftime("%X") + "' -fontsize x-large #") Are_You_Dreaming_C=Event("Are you dreaming? C", "at", Dinner, "plus", 60, "minutes") Are_You_Dreaming_C.MakeCrontabLineOrLines("yaf-splash -placement center -close box -bg green -fg yellow -text 'Are you dreaming? " + Are_You_Dreaming_C.datime.strftime("%X") + "' -fontsize x-large #") Twelve_Hours_After_Waking = Event("*** 12 hours after waking - Wind Down Time!", "at", Waking, "plus", 12, "hours") Twelve_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg violet -fg yellow -text '12 hours after waking! Yay, wind-down time!" + Twelve_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Fourteen_Hours_After_Waking = Event("*** 14 hours after waking", "at", Waking, "plus", 14, "hours") Fourteen_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg navy -fg yellow -text '14 hours after waking! " + Fourteen_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Fifteen_Hours_After_Waking = Event("*** 15 hours after waking", "at", Waking, "plus", 15, "hours") Fifteen_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg navy -fg yellow -text '15 hours after waking! " + Fifteen_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Sixteen_Hours_After_Waking = Event("*** 16 hours after waking", "at", Waking, "plus", 16, "hours") Sixteen_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg navy -fg yellow -text '16 hours after waking! " + Sixteen_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Projected_Wake_Time_If_Asleep_After_16_Hours_Awake = Event("*** Projected Wake Time if Asleep After 16 Hours Awake", "at", Sixteen_Hours_After_Waking, "plus", 8, "hours") Seventeen_Hours_After_Waking = Event("*** 17 hours after waking", "at", Waking, "plus", 17, "hours") Seventeen_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg navy -fg yellow -text '17 hours after waking! " + Seventeen_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Eighteen_Hours_After_Waking = Event("*** 18 hours after waking", "at", Waking, "plus", 18, "hours") Eighteen_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg navy -fg yellow -text '18 hours after waking! " + Eighteen_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Nineteen_Hours_After_Waking = Event("*** 19 hours after waking", "at", Waking, "plus", 19, "hours") Nineteen_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg navy -fg yellow -text '19 hours after waking! " + Nineteen_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Twenty_Hours_After_Waking = Event("*** 20 hours after waking", "at", Waking, "plus", 20, "hours") Twenty_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg red -fg yellow -text '20 hours after waking! " + Twenty_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Twenty_Two_Hours_After_Waking = Event("*** 22 hours after waking", "at", Waking, "plus", 22, "hours") Twenty_Two_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg red -fg yellow -text '22 hours after waking! " + Twenty_Two_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Twenty_Four_Hours_After_Waking = Event("*** 24 hours after waking", "at", Waking, "plus", 24, "hours") Twenty_Four_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg red -fg yellow -text '24 hours after waking! " + Twenty_Four_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Twenty_Five_Hours_After_Waking = Event("*** 25 hours after waking", "at", Waking, "plus", 25, "hours") Twenty_Five_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg red -fg yellow -text '25 hours after waking! " + Twenty_Five_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Twenty_Six_Hours_After_Waking = Event("*** 26 hours after waking", "at", Waking, "plus", 26, "hours") Twenty_Six_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg red -fg yellow -text '26 hours after waking! " + Twenty_Six_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Twenty_Seven_Hours_After_Waking = Event("*** 27 hours after waking", "at", Waking, "plus", 27, "hours") Twenty_Seven_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg red -fg yellow -text '27 hours after waking! " + Twenty_Seven_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") Twenty_Eight_Hours_After_Waking = Event("*** 28 hours after waking", "at", Waking, "plus", 28, "hours") Twenty_Eight_Hours_After_Waking.MakeCrontabLineOrLines("yaf-splash -placement top -close box -bg red -fg yellow -text '28 hours after waking! " + Twenty_Four_Hours_After_Waking.datime.strftime("%X") + "' -fontsize x-large #") #------------- # # Other crontab events, which have to be done manually rather than with Event objects # Output_for_Crontab_File = """\n59 * * * * yaf-splash -placement top-left -close box -bg Purple -fg lavender -text xx:59! -fontsize x-large #""" # 22:52 07/20/2014. On rare occasions my external hard drive mysteriously gets # unmounted, so, I have cron run a script every minute to warn me if this happened: #0-59 * * * * sh /root/Make\ sure\ sdc1\ is\ still\ a\ mountpoint #""" # # End of Event List # ####################################################################### #-------------------------------- # # HTML Relative Scheduler # if Should_Create_HTML_Relative_Schedules: HTML_Relative_Schedule__Output_Datime=Now_Datime.strftime("%A, %b %d, %Y - %I:%M %p") Output_for_HTML_Relative_Schedule = "Relative Schedule\n

Relative Schedule - Generated " + HTML_Relative_Schedule__Output_Datime + "
EventDatime" EventsList.sort(key=lambda ThisEvent: ThisEvent.datime) for ThisEvent in EventsList: print "%s %s \n" % (ThisEvent.name, ThisEvent.datime) #-------------------------------- # # HTML Relative Schedule stuff # if Should_Create_HTML_Relative_Schedules: print "Occurrence: " + ThisEvent.occurrence if ThisEvent.occurrence != "weekends" and ThisEvent.occurrence != "weekdays" and ThisEvent.occurrence != "daily": if ThisEvent.datime < Latest_Future_Datime: ThisEvent_DateOnly_String = datetime.strftime(ThisEvent.datime, "%x") if Now_DateOnly_String == ThisEvent_DateOnly_String: Datime_To_Output = datetime.strftime(ThisEvent.datime, "%I:%M %p") else: Datime_To_Output = datetime.strftime(ThisEvent.datime, "%I:%M %p     %b %d (%a)") Line_for_HTML_Relative_Schedule = "
" + ThisEvent.name + "" + str(Datime_To_Output) + "\n" Output_for_HTML_Relative_Schedule = Output_for_HTML_Relative_Schedule + "\n" + Line_for_HTML_Relative_Schedule #----------------------------------------- if hasattr(ThisEvent, 'crontab_line_or_lines'): Output_for_Crontab_File = Output_for_Crontab_File + "\n" + ThisEvent.crontab_line_or_lines if Should_Create_HTML_Relative_Schedules: if os.path.isdir(Folderpath_to__HTML_Relative_Schedule_Folder) == False: os.makedirs(Folderpath_to__HTML_Relative_Schedule_Folder) if os.path.isfile(Filepath_to__Todays_HTML_Relative_Schedule): os.remove(Filepath_to__Todays_HTML_Relative_Schedule) with open (Filepath_to__Todays_HTML_Relative_Schedule, "w") as Filehandle__Todays_HTML_Relative_Schedule: print >> Filehandle__Todays_HTML_Relative_Schedule, Output_for_HTML_Relative_Schedule if Should_Output_Dated_HTML_Relative_Schedule: Date_String_for_HTML_Relative_Schedule = datetime.strftime(Waking_Datime, "%Y_%m_%d %H,%M") Filepath_to__Dated_HTML_Relative_Schedule = Folderpath_to__HTML_Relative_Schedule_Folder + Date_String_for_HTML_Relative_Schedule + "-" + Extensionless_Filename_of__HTML_Relative_Schedule + ".html" if os.path.isfile(Filepath_to__Dated_HTML_Relative_Schedule): os.remove(Filepath_to__Dated_HTML_Relative_Schedule) with open (Filepath_to__Dated_HTML_Relative_Schedule, "w") as Filehandle__Dated_HTML_Relative_Schedule: print >> Filehandle__Dated_HTML_Relative_Schedule, Output_for_HTML_Relative_Schedule with open(Filepath_to__Crontab_File, "a") as Filehandle__Crontab_File: print >> Filehandle__Crontab_File, Output_for_Crontab_File call (Shell_Command_to__Launch_Cron, shell=True) if Should_Create_HTML_Relative_Schedules: if Should_Display_HTML_Relative_Schedule_When_Script_is_Done: call (Shell_Command_to__Launch_Web_Browser + " " + "'" + Filepath_to__Todays_HTML_Relative_Schedule + "'", shell=True) EndScript()