Skeleton-app for handling recurring events.

Hello.

Here is a skeleton for a stay open, in backgrround (LSUiElement=1) application for handling recurring events.

That is, it is designed to do the same thing over and over a certain number of times, at certain times, during a day, 7 days a week. There are more timeslots, than there are times, to be a little bit flexible.

You configure it, to set the different hours you want to event to be triggered, and a number of times you want that to happen. For the case that your machine sleeps at some point in time.

You fill the executed() event with your code, and it should return whether the event succeeded or not, since further treatment of that event in the list is dependent on that.

Well, the code should be pretty straight forward to read, just ask if there is somehting I have missed to disclose.

The motivation is of course not to have iCal (Calendar) littered with those things, and it can of course also be programmed, (by you) to consider weekdays or workdays/weekends. Please post your work if you do. :slight_smile:

property parent : AppleScript
property appTitle : "Messager"
property executedInListNr : 2
property eventAtTimesList : {{"3", false}, {"5", false}, {"9", false}, {"11", false}, {"14", false}, {"17", false}, {"20", false}, {"23", false}}
-- can be expanded to work for individual days workdays/weekdays etc.

property timeframeInMinues : 20
-- if we are awoken not later than within this timeframe, we execute the event.
property maxEventCountPerDay : 5
-- the maximum number of times we want to show the event.
property eventsExecutedThisDay : 0
property currentDay : 0

-- the proprerties specific for your app comes here.

on run
	try
		-- whatever you need to initialize for your app comes here
		if firstTime() then initializeDayData()
		#	idle {}
	on error e number n
		my logit("OOps run : " & e & " " & n, my appTitle)
	end try
	
end run


on idle
	try
		if firstTime() then initializeDayData()
		-- we can't work with yesterday's data.
		set eventnum to isAnEventToExecute()
		
		if eventnum > 0 then
			if executedEvent() then
				set item executedInListNr of item eventnum of eventAtTimesList to true
				-- and increasing the event count
				set eventsExecutedThisDay to eventsExecutedThisDay + 1
			else
				tell me
					activate
					display dialog "Something failed, tries again in " & timeframeInMinues & " minutes" with title my appTitle
				end tell
			end if
		end if
		
		return timeframeInMinues * minutes
		-- we wake up every 20 minutes
	on error e number n
		my logit("OOps idle : " & e & " " & n, my appTitle)
	end try
	
end idle


on isAnEventToExecute()
	try
		-- figures out if there is an event to execute
		if eventsExecutedThisDay < maxEventCountPerDay then
			set {thisHour, minutesPassed} to {hours, minutes} of (current date)
			log thisHour
			set eventCount to (count eventAtTimesList)
			
			repeat with i from eventCount to 1 by -1
				if thisHour ≥ item 1 of item i of eventAtTimesList then
					exit repeat
				end if
			end repeat
			-- check if has already been executed
			if item executedInListNr of item i of eventAtTimesList then
				return 0
			else
				-- we are marking it as executed anyway
				if minutesPassed ≤ timeframeInMinues then
					return i
				else
					return 0
				end if
				
			end if
		else
			return 0
		end if
	on error e number n
		my logit("OOps : isAnEventToExecute" & e & " " & n, my appTitle)
		return 0
	end try
end isAnEventToExecute

to logit(log_string, log_file)
	do shell script ¬
		"echo `date '+%Y-%m-%d %T: '`\"" & log_string & ¬
		"\" >> $HOME/Library/Logs/" & log_file & ".log"
end logit

to executedEvent()
	-- reworked for the event of failure
	set everythingesokay to true
	if everythinggoesOkay then
		return true
	else
		return false
	end if
end executedEvent

on firstTime()
	-- returns true if it is the first time this day
	set today to day of (current date)
	if my currentDay ≠ today then
		set my currentDay to today
		return true
	else
		return false
	end if
end firstTime


to initializeDayData()
	set my eventsExecutedThisDay to 0
	repeat with anEvent in eventAtTimesList
		set item executedInListNr of anEvent to false
	end repeat
end initializeDayData


Hello.

I have removed a bug, that caused the skeleton to cease working when it rolled over to a new month. Sorry about the delay, I have been aching to do that the last 15 days, but I have been busy, and had enough problems really. :slight_smile: