Author: rfm
Date: Mon Feb 23 11:55:02 2015
New Revision: 38358

URL: http://svn.gna.org/viewcvs/gnustep?rev=38358&view=rev
Log:
Add support for limited activitym periods for a rule

Modified:
    libs/ec/trunk/EcAlerter.h
    libs/ec/trunk/EcAlerter.m

Modified: libs/ec/trunk/EcAlerter.h
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcAlerter.h?rev=38358&r1=38357&r2=38358&view=diff
==============================================================================
--- libs/ec/trunk/EcAlerter.h   (original)
+++ libs/ec/trunk/EcAlerter.h   Mon Feb 23 11:55:02 2015
@@ -118,6 +118,42 @@
  *   of the message.  See the posix regcomp documentation for details
  *   of enhanced posix regular expressions.  If this is not present,
  *   any message text will match.
+ *   </desc>
+ *   <term>ActiveFrom</term>
+ *   <desc>A date/time specifying the earliest point at which this rule
+ *   may match any alarm.  If the current date/time is earlier than
+ *   this (optional) value then the rule simply can't match.
+ *   </desc>
+ *   <term>ActiveTo</term>
+ *   <desc>A date/time specifying the latest point at which this rule
+ *   may match any alarm.  If the current date/time is later than
+ *   this (optional) value then the rule simply can't match.
+ *   </desc>
+ *   <term>ActiveTimes</term>
+ *   <desc>Either a string containing a comma separated list of ranges
+ *   of times specified using a 24 hour clock, or a dictionary of such 
+ *   strings keyed on the days of the week (Monday, Tuesday, Wednesday,
+ *   Thursday, Friday, Saturday, Sunday), possibly with an asterisk used
+ *   as the key for a default string to be used for any day not listed. <br />
+ *   If a simple string, the list applies to all days of the week
+ *   (equivalent to a dictionary containing a single string keyed on
+ *   an asterisk).<br />
+ *   The times are in HH:MM format or may simply be the hours (HH) with
+ *   a minute value of zero implied.<br />
+ *   The range separator is a dash/minus, and the range includes the
+ *   first value and excludes the second one.<br />
+ *   eg. 10:45-11 means that the rule is active in the 15 minute interval
+ *   from 10:45 until 11:00 but becomes inactive again at 11:00<br />
+ *   The end of each range must be later than the start of the range,
+ *   and the starts of each successive range must be later than or equal
+ *   to the end of the preceding range.<br />
+ *   As a special case the time 24:00 may be used as the end of the
+ *   last range in a list.<br />
+ *   If this field is simply omitted, the rule is active all day every day.
+ *   </desc>
+ *   <term>ActiveTimezone</term>
+ *   <desc>The formal name of the time zone in which the system checks
+ *   active date/time information.  If omitted, the GMT timezone is assumed.
  *   </desc>
  *   <term>Stop</term>
  *   <desc>A boolean (YES or NO) saying whether rule matching should

Modified: libs/ec/trunk/EcAlerter.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcAlerter.m?rev=38358&r1=38357&r2=38358&view=diff
==============================================================================
--- libs/ec/trunk/EcAlerter.m   (original)
+++ libs/ec/trunk/EcAlerter.m   Mon Feb 23 11:55:02 2015
@@ -253,12 +253,13 @@
 
 - (BOOL) setRules: (NSArray*)ra
 {
-  NSUInteger    i = 0;
   NSMutableArray        *r = AUTORELEASE([ra mutableCopy]); 
+  NSUInteger            i;
 
   for (i = 0; i < [r count]; i++)
     {
       NSMutableDictionary      *md;
+      NSObject                  *obj;
       NSString                 *str;
       Regex                    *val;
 
@@ -344,6 +345,204 @@
          RELEASE(val);
        }
 
+      str = [md objectForKey: @"ActiveFrom"];
+      if (nil != str)
+        {
+          NSDate        *d = [NSDate dateWithString: str];
+
+          if (nil == d)
+            {
+              NSLog(@"ActiveFrom='%@' is not a valid date/time", str);
+              return NO;
+            }
+          else
+            {
+              [md setObject: d forKey: @"ActiveFrom"];
+            }
+        }
+      str = [md objectForKey: @"ActiveTo"];
+      if (nil != str)
+        {
+          NSDate        *d = [NSDate dateWithString: str];
+
+          if (nil == d)
+            {
+              NSLog(@"ActiveTo='%@' is not a valid date/time", str);
+              return NO;
+            }
+          else
+            {
+              [md setObject: d forKey: @"ActiveTo"];
+            }
+        }
+      str = [md objectForKey: @"ActiveTimezone"];
+      if (nil != str)
+        {
+          NSTimeZone    *d = [NSTimeZone timeZoneWithName: str];
+
+          if (nil == d)
+            {
+              NSLog(@"ActiveTimezone='%@' is not a valid time zone", str);
+              return NO;
+            }
+          [md setObject: d forKey: @"ActiveTimeZone"];
+        }
+      obj = [md objectForKey: @"ActiveTimes"];
+      if ([obj isKindOfClass: [NSString class]])
+        {
+          obj = (NSString*)[NSDictionary dictionaryWithObjectsAndKeys:
+            obj, @"*", nil];
+        }
+      if ([obj isKindOfClass: [NSDictionary class]])
+        {
+          NSMutableDictionary   *t = [[obj mutableCopy] autorelease];
+          NSEnumerator          *e = [[t allKeys] objectEnumerator];
+
+          while (nil != (str = [e nextObject]))
+            {
+              NSString          *k = [str stringByTrimmingSpaces];
+              NSMutableArray    *a;
+              NSUInteger        j;
+              NSInteger         lastMinute = 0;
+
+              if (YES == [k isEqual: @"*"])
+                {
+                  k = @"*";
+                }
+              else if (YES == [k caseInsensitiveCompare: @"Monday"])
+                {
+                  k = @"Monday";
+                }
+              else if (YES == [k caseInsensitiveCompare: @"Tuesday"])
+                {
+                  k = @"Tuesday";
+                }
+              else if (YES == [k caseInsensitiveCompare: @"Wednesday"])
+                {
+                  k = @"Wednesday";
+                }
+              else if (YES == [k caseInsensitiveCompare: @"Thursday"])
+                {
+                  k = @"Thursday";
+                }
+              else if (YES == [k caseInsensitiveCompare: @"Friday"])
+                {
+                  k = @"Friday";
+                }
+              else if (YES == [k caseInsensitiveCompare: @"Saturday"])
+                {
+                  k = @"Saturday";
+                }
+              else if (YES == [k caseInsensitiveCompare: @"Sunday"])
+                {
+                  k = @"Sunday";
+                }
+              else
+                {
+                  NSLog(@"ActiveTimes='%@' with bad day of week", obj);
+                  return NO;
+                }
+              a = [[[[t  objectForKey: str] componentsSeparatedByString: @","]
+                mutableCopy] autorelease];
+              j = [a count];
+              while (j-- > 0)
+                {
+                  NSMutableArray        *r;
+                  int                   from;
+                  int                   to;
+                  int                   h;
+                  int                   m;
+                  int                   c;
+
+                  str = [[a objectAtIndex: j] stringByTrimmingSpaces];
+                  if ([str length] == 0)
+                    {
+                      [a removeObjectAtIndex: j];
+                      continue;
+                    }
+                  r = [[[str componentsSeparatedByString: @"-"]
+                    mutableCopy] autorelease];
+                  if ([r count] != 2)
+                    {
+                      NSLog(@"ActiveTimes='%@' with missing '-' in time range",
+                        obj);
+                      return NO;
+                    }
+                  str = [r objectAtIndex: 0];
+                  c = sscanf([str UTF8String], "%d:%d", &h, &m);
+                  if (0 == c)
+                    {
+                      NSLog(@"ActiveTimes='%@' with missing HH:MM", obj);
+                      return NO;
+                    }
+                  if (1 != c) m = 0;
+                  if (h < 0 || h > 23)
+                    {
+                      NSLog(@"ActiveTimes='%@' with hour out of range", obj);
+                    }
+                  if (m < 0 || m > 59)
+                    {
+                      NSLog(@"ActiveTimes='%@' with minute out of range", obj);
+                      return NO;
+                    }
+                  from = (h * 60) + m;
+                  
+                  str = [r objectAtIndex: 1];
+                  c = sscanf([str UTF8String], "%d:%d", &h, &m);
+                  if (0 == c)
+                    {
+                      NSLog(@"ActiveTimes='%@' with missing HH:MM", obj);
+                      return NO;
+                    }
+                  if (1 != c) m = 0;
+                  if (h < 0 || h > 24 || (24 == h && 0 != m))
+                    {
+                      NSLog(@"ActiveTimes='%@' with hour out of range", obj);
+                    }
+                  if (m < 0 || m > 59)
+                    {
+                      NSLog(@"ActiveTimes='%@' with minute out of range", obj);
+                      return NO;
+                    }
+                  if (0 == h && 0 == m)
+                    {
+                      h = 24;
+                    }
+                  to = (h * 60) + m;
+ 
+                  if (to <= from)
+                    {
+                      NSLog(@"ActiveTimes='%@' range end earlier than start",
+                        obj);
+                      return NO;
+                    }
+                  if (from < lastMinute)
+                    {
+                      NSLog(@"ActiveTimes='%@' range start earlier than"
+                        @" preceding one", obj);
+                      return NO;
+                    }
+                  lastMinute = to;
+                  [r replaceObjectAtIndex: 0
+                               withObject: [NSNumber numberWithInt: from]];
+                  [r replaceObjectAtIndex: 1
+                               withObject: [NSNumber numberWithInt: to]];
+                  [a replaceObjectAtIndex: j withObject: r];
+                }
+              if (0 == [a count])
+                {
+                  NSLog(@"ActiveTimes='%@' with empty time range", obj);
+                  return NO;
+                }
+              [t setObject: a forKey: k];
+            }
+          [md setObject: obj forKey: @"ActiveTimes"];
+        }
+      else if (obj != nil)
+        {
+          NSLog(@"ActiveTimes='%@' is not valid", obj);
+          return NO;
+        }
     }
   ASSIGN(rules, r);
   return YES;
@@ -440,12 +639,17 @@
 - (void) applyRules: (NSArray*)rulesArray
             toEvent: (EcAlerterEvent*)event
 {
-  CREATE_AUTORELEASE_POOL(pool);
-  BOOL          found = NO;
-  NSUInteger    i;
+  NSAutoreleasePool     *pool = nil;
+  NSTimeZone            *tz = nil;
+  BOOL                  found = NO;
+  NSCalendarDate        *now = [NSCalendarDate date];
+  NSUInteger            minuteOfDay = 0;
+  NSUInteger            dayOfWeek = 0;
+  NSUInteger            i;
 
   for (i = 0; i < [rulesArray count]; i++)
     {
+      NSDictionary     *times;
       NSDictionary     *d;
       NSString         *match = nil;
       Regex            *e;
@@ -455,6 +659,80 @@
       RELEASE(pool);
       pool = [NSAutoreleasePool new];
       d = [rulesArray objectAtIndex: i];
+
+      times = [d objectForKey: @"ActiveTimes"];
+      if (nil != times)
+        {
+          NSDate        *from = [d objectForKey: @"ActiveFrom"];
+          NSDate        *to = [d objectForKey: @"ActiveTo"];
+          BOOL          match = NO;
+
+          if ((nil == from || [from earlierDate: now] == from)
+            && (nil == to || [to laterDate: now] == to))
+            {
+              NSTimeZone        *z = [d objectForKey: @"ActiveTimezone"];
+              NSArray           *ranges;
+              NSUInteger        index;
+
+              if (nil == z)
+                {
+                  static NSTimeZone *gmt = nil;
+
+                  if (nil == gmt)
+                    {
+                      gmt = [[NSTimeZone timeZoneWithName: @"GMT"] retain];
+                    }
+                  z = gmt;
+                }
+              if (NO == [z isEqual: tz])
+                {
+                  ASSIGN(tz, z);
+                  [now setTimeZone: tz];
+                  minuteOfDay = [now hourOfDay] * 60 + [now minuteOfHour];
+                  dayOfWeek = [now dayOfWeek];
+                }
+
+              switch (dayOfWeek)
+                {
+                  case 0: ranges = [times objectForKey: @"Sunday"]; break;
+                  case 1: ranges = [times objectForKey: @"Monday"]; break;
+                  case 2: ranges = [times objectForKey: @"Tuesday"]; break;
+                  case 3: ranges = [times objectForKey: @"Wednesday"]; break;
+                  case 4: ranges = [times objectForKey: @"Thursday"]; break;
+                  case 5: ranges = [times objectForKey: @"Friday"]; break;
+                  default: ranges = [times objectForKey: @"Saturday"]; break;
+                }
+              if (nil == ranges)
+                {
+                  ranges = [times objectForKey: @"*"];
+                }
+              index = [ranges count];
+              while (index-- > 0)
+                {
+                  NSArray           *range;
+                  NSUInteger        start;
+                  
+                  range = [ranges objectAtIndex: index];
+                  start = [[range objectAtIndex: 0] unsignedIntegerValue];
+
+                  if (minuteOfDay >= start)
+                    {
+                      NSUInteger    end;
+
+                      end = [[range objectAtIndex: 1] unsignedIntegerValue];
+                      if (minuteOfDay < end)
+                        {
+                          match = YES;
+                        }
+                      break;
+                    }
+                }
+            }
+          if (NO == match)
+            {
+              continue;
+            }
+        }
 
       s = [d objectForKey: @"Tagged"];
       if (s != nil && NO == [s isEqual: [event->m objectForKey: @"Tag"]])
@@ -816,6 +1094,7 @@
           NSLog(@"No match of %@ with %@", event->m, rulesArray);
         }
     }
+  DESTROY(tz);
   RELEASE(pool);
 }
 


_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs

Reply via email to