Roxen.git / server / etc / modules / Variable.pmod / Schedule.pike

version» Context lines:

Roxen.git/server/etc/modules/Variable.pmod/Schedule.pike:30:   }      // Deterministic timezone...   #define localtime(X) gmtime(X)      int main(int argc, array(string) argv)   {    int successes;    int failures;    foreach(({ -  ({ ({ 0, 2, 1, 6, 3, }), +  ({ ({ 0, 2, 1, 6, 3, 0, }),    // Disabled.    ({ 0, -1 }),    }), -  ({ ({ 1, 2, 1, 6, 3, }), +  ({ ({ 1, 2, 1, 6, 3, 0, }),    // Every other hour.    // 2022-06-22T14:11:43 (Wed) ==> 2022-06-22T16:11:43 (Wed)    ({ 1655907103, 1655914303 }),    }), -  ({ ({ 2, 2, 1, 6, 3, }), +  ({ ({ 2, 2, 1, 6, 3, 0, }),    // Every Friday at 03:00.    // 2022-06-22T14:11:43 (Wed) ==> 2022-06-24T03:00:00 (Fri)    ({ 1655907103, 1656039600 }),    // 2022-06-23T14:11:43 (Thu) ==> 2022-06-24T03:00:00 (Fri)    ({ 1655993503, 1656039600 }),    // 2022-06-24T02:11:43 (Fri) ==> 2022-06-24T03:00:00 (Fri)    ({ 1656036703, 1656039600 }),    // 2022-06-24T03:11:43 (Fri) ==> 2022-07-01T03:00:00 (Fri)    ({ 1656040303, 1656644400 }),    // 2022-06-24T03:21:43 (Fri) ==> 2022-07-01T03:00:00 (Fri)    ({ 1656040903, 1656644400 }),    // 2022-06-24T03:51:43 (Fri) ==> 2022-07-01T03:00:00 (Fri)    ({ 1656042703, 1656644400 }),    // 2022-06-24T04:11:43 (Fri) ==> 2022-07-01T03:00:00 (Fri)    ({ 1656043903, 1656644400 }),    // 2022-06-24T14:11:43 (Fri) ==> 2022-07-01T03:00:00 (Fri)    ({ 1656079903, 1656644400 }),    }), -  +  ({ ({ 2, 2, 1, 6, 3, 45, }), +  // Every Friday at 03:45. +  // 2022-06-22T14:11:43 (Wed) ==> 2022-06-24T03:45:00 (Fri) +  ({ 1655907103, 1656042300 }), +  // 2022-06-23T14:11:43 (Thu) ==> 2022-06-24T03:45:00 (Fri) +  ({ 1655993503, 1656042300 }), +  // 2022-06-24T02:11:43 (Fri) ==> 2022-06-24T03:45:00 (Fri) +  ({ 1656036703, 1656042300 }), +  // 2022-06-24T03:11:43 (Fri) ==> 2022-06-24T03:45:00 (Fri) +  ({ 1656040303, 1656042300 }), +  // 2022-06-24T03:21:43 (Fri) ==> 2022-06-24T03:45:00 (Fri) +  ({ 1656040903, 1656042300 }), +  // 2022-06-24T03:51:43 (Fri) ==> 2022-07-01T03:45:00 (Fri) +  ({ 1656042703, 1656647100 }), +  // 2022-06-24T04:11:43 (Fri) ==> 2022-07-01T03:45:00 (Fri) +  ({ 1656043903, 1656647100 }), +  // 2022-06-24T14:11:43 (Fri) ==> 2022-07-01T03:45:00 (Fri) +  ({ 1656079903, 1656647100 }), +  }),    }), array(array(int)) test) {    val = test[0];    while(1) {    foreach(test[1..], [int when, int expected]) {    int got = get_next(when);    if (got != expected) {    failures++;    werror("Test failed for %O\n"    "When: %d\n"    "%O\n"
Roxen.git/server/etc/modules/Variable.pmod/Schedule.pike:80:    "Got: %d\n"    "%O\n",    test,    when, localtime(when),    expected, localtime(expected),    got, localtime(got));    } else {    successes++;    }    } +  if ((sizeof(val) > 5) && !val[5]) { +  // Redo in compat mode. +  val = val[..4]; +  continue; +  }    break;    }    }    werror("Succeeded on %d, Failed on %d.\n", successes, failures);    return !!failures;   }      #endif      #define VALS_SORT 0   #define VALS_REPEAT_HOURS 1   #define VALS_REPEAT_COUNT 2   #define VALS_DAY 3   #define VALS_HOUR 4 -  + #define VALS_MINUTE 5      //! Transforms the form variables given in the @[vl] attribute   //! to the internal time representation as follows.   //!   //! @array   //! @elem int(0..2) sort   //! @int   //! @value 0   //! Never   //! @value 1
Roxen.git/server/etc/modules/Variable.pmod/Schedule.pike:123:   //!   //! @elem int(0..7) day   //! @int   //! @value 0   //! Day   //! @value 1   //! Sunday   //! @value 2..7   //! Rest of weekdays   //! @endint - //! @elem int(0..23) time - //! Time at which to restart. + //! @elem int(0..23) time_hour + //! Time at which to restart (hour). + //! @elem int(0..59)|void time_min + //! Time at which to restart (minute). + //! If not present at minute 0 (compat).   //! @endarray   array transform_from_form( string what, mapping vl )   {    array res = query() + ({}); -  if(sizeof(res)!=5) -  res = ({ 0, 2, 1, 6, 3 }); +  if(sizeof(res) <= VALS_HOUR) { +  res = ({ 0, 2, 1, 6, 3, -1 }); +  } else if (sizeof(res) <= VALS_MINUTE) { +  // Compat. +  res += ({ 0 }); +  }       res[VALS_SORT] = (int)what; -  for(int i=1; i <= VALS_HOUR; i++) { +  for(int i=1; i <= VALS_MINUTE; i++) {    res[i] = (int)vl[(string)i]; -  res[i] = max( ({ 0, 1, 1, 0, 0 })[i], res[i] ); -  res[i] = min( ({ 2, 23, 9, 7, 23 })[i], res[i] ); +  res[i] = max( ({ 0, 1, 1, 0, 0, 0 })[i], res[i] ); +  res[i] = min( ({ 2, 23, 9, 7, 23, 59 })[i], res[i] );    }    -  +  if (!res[VALS_MINUTE]) { +  // Compat. +  res = res[..VALS_HOUR]; +  } +     return res;   }      protected int mktime(mapping m)   {    int t = predef::mktime(m);    if (m->timezone) {    // Compensate for cases where predef::mktime() is broken.    // Cf [WS-469].    t += t - predef::mktime(localtime(t));    }    return t;   }    - private mapping next_or_same_day(mapping from, int day, int hour) + private mapping next_or_same_day(mapping from, int day, int hour, int minute)   {    if(from->wday==day && from->hour<hour)    return from; -  +  if(from->wday==day && from->hour == hour && from->min<minute) +  return from;    return next_day(from, day);   }      private mapping next_day(mapping from, int day)   {    int num_days = ((6 + day - from->wday) % 7) + 1;       // NB: Use a time in the middle of the date to ensure that we    // don't miss the next day due to DST or similar.    // Adjust the hour back to 00 afterwards.    from->hour = 12;    mapping m = localtime(mktime(from) + num_days * 3600 * 24);    m->hour = from->hour = 0; -  +  m->min = from->min = 0;    return m;   }    - private mapping next_or_same_time(mapping from, int hour, void|int delta) + private mapping next_or_same_time(mapping from, int hour, int minute, +  void|int delta)   { -  if(from->hour==hour) return from; -  return next_time(from, hour, delta); +  if (from->hour == hour) { +  if (minute < 0) { +  return from;    } -  +  if ((from->min - (from->min % 15)) == minute) { +  return from; +  } +  } +  return next_time(from, hour, minute, delta); + }    - private mapping next_time(mapping from, int hour, void|int delta) + private mapping next_time(mapping from, int hour, int minute, void|int delta)   {    if(from->hour<hour) {    from->hour = hour; -  +  if (minute < 0) { +  from->min = 0; +  } else { +  from->min = minute; +  }    return from; -  +  } else if ((from->hour == hour) && (from->min < minute)) { +  from->min = minute; +  return from;    }    return localtime(mktime(from) + (24 - from->hour + hour)*3600 + delta);   }      int get_next( int last )   //! Get the next time that matches this schedule, starting from the   //! posix time @[last]. If last is 0, time(1) will be used instead.   //!   //! @returns   //! When the next scheduled event is, represented by a posix time integer.   //! Note that the returned time may already have occured, so all return   //! values < time() essentially means go ahead and do it right away.   //! Minutes and seconds are cleared in the return value, so if the scheduler   //! is set to every day at 5 o'clock, and this method is called at 5:42 it   //! will return the posix time representing 5:00, unless of course @[last]   //! was set to a posix time >= 5:00.   //! Returns @tt{-1@} if the schedule is disabled (@tt{"Never"@}).   {    array vals = query(); -  +  if (sizeof(vals) == VALS_MINUTE) { +  vals += ({ 0 }); +  }    if( !vals[VALS_SORT] )    return -1;       // Every n:th hour.    if( vals[VALS_SORT] == 1 )    if( !last )    return time(1);    else    return last + 3600 * vals[VALS_REPEAT_HOURS];       mapping m = localtime( last || time(1) ); -  m->min = m->sec = 0; +  m->sec = 0; +  m->min -= (m->min % 15);    if( !vals[VALS_DAY] ) {    // Every n:th day at x.    if (!last)    {    for(int i; i<vals[VALS_REPEAT_COUNT]; i++) -  m = next_or_same_time( m, vals[VALS_HOUR] ); +  m = next_or_same_time( m, vals[VALS_HOUR], vals[VALS_MINUTE] );    return mktime(m);    }    else    {    for(int i; i<vals[VALS_REPEAT_COUNT]; i++) -  m = next_time( m, vals[VALS_HOUR] ); +  m = next_time( m, vals[VALS_HOUR], vals[VALS_MINUTE] );    return mktime(m);    }    }       // Every x-day at y.    if (!last)    {    for(int i; i<vals[VALS_REPEAT_COUNT]; i++)    {    m = next_or_same_time( next_or_same_day( m, vals[VALS_DAY]-1, -  vals[VALS_HOUR]+1 ), -  vals[VALS_HOUR], 6*24*3600 ); +  vals[VALS_HOUR]+1, +  vals[VALS_MINUTE] ), +  vals[VALS_HOUR], vals[VALS_MINUTE], 6*24*3600 );    }    }    else    {    for(int i; i<vals[VALS_REPEAT_COUNT]; i++)    {    m = next_or_same_time( next_or_same_day( m, vals[VALS_DAY]-1, -  vals[VALS_HOUR] ), -  vals[VALS_HOUR], 6*24*3600 ); +  vals[VALS_HOUR], +  vals[VALS_MINUTE] ), +  vals[VALS_HOUR], vals[VALS_MINUTE], 6*24*3600 );    }    }    return mktime(m);   }      #if constant(roxen)      private string checked( int pos, int alt )   {    if(alt==query()[pos])    return " checked='checked'";    return "";   }      string render_form( RequestID id, void|mapping additional_args )   { -  string res, inp1, inp2, inp3; +  string res, inp1, inp2, inp3, inp4;    array vals = query(); -  +  if (sizeof(vals) == VALS_MINUTE) { +  vals += ({ 0 }); +  }       res = "<table>"    "<tr valign='top'><td><input name='" + path() + "' value='0' type='radio' " +    checked(0,0) + " /></td><td>" + LOCALE(482, "Never") + "</td></tr>\n";       inp1 = HTML.select(path()+"1", "123456789"/1 + "1011121314151617181920212223"/2, (string)vals[VALS_REPEAT_HOURS]);       res += "<tr valign='top'><td><input name='" + path() + "' value='1' type='radio' " +    checked(0,1) + " /></td><td>" + sprintf( LOCALE(483, "Every %s hour(s)."), inp1) +    "</td></tr>\n";
Roxen.git/server/etc/modules/Variable.pmod/Schedule.pike:290: Inside #if constant(roxen)
   ({ "1", LOCALE(485, "Sunday") }),    ({ "2", LOCALE(486, "Monday") }),    ({ "3", LOCALE(487, "Tuesday") }),    ({ "4", LOCALE(488, "Wednesday") }),    ({ "5", LOCALE(489, "Thursday") }),    ({ "6", LOCALE(490, "Friday") }),    ({ "7", LOCALE(491, "Saturday") }) }), (string)vals[VALS_DAY]);    inp3 = HTML.select(path()+"4",    "000102030405060708091011121314151617181920212223"/2,    sprintf("%02d", vals[VALS_HOUR])); +  inp4 = HTML.select(path()+"5", +  "00153045"/2, +  sprintf("%02d", vals[VALS_MINUTE]));       res += "<tr valign='top'><td><input name='" + path() + "' value='2' type='radio' " +    checked(0,2) + " /></td>\n<td>" + -  sprintf(LOCALE(492, "Every %s %s at %s o'clock."), inp1, inp2, inp3) + +  sprintf(LOCALE(492, "Every %s %s at %s:%s o'clock."), +  inp1, inp2, inp3, inp4) +    "</td></tr>\n</table>";       return res;   }      string render_view( RequestID id, void|mapping additional_args )   {    array res = query(); -  +  if (sizeof(res) == VALS_MINUTE) { +  res += ({ 0 }); +  }    switch(res[VALS_SORT]) {    case 0:    return LOCALE(482, "Never");    case 1:    return sprintf(LOCALE(493, "Every %d hour."), res[VALS_REPEAT_HOURS]);    case 2:    string period = ({    LOCALE(484, "Day"),    LOCALE(485, "Sunday"),    LOCALE(486, "Monday"),    LOCALE(487, "Tuesday"),    LOCALE(488, "Wednesday"),    LOCALE(489, "Thursday"),    LOCALE(490, "Friday"),    LOCALE(491, "Saturday")    })[res[VALS_DAY]];    -  return sprintf(LOCALE(494, "Every %d %s at %02d:00"), -  res[VALS_REPEAT_COUNT], period, res[VALS_HOUR]); +  return sprintf(LOCALE(494, "Every %d %s at %02d:%02d"), +  res[VALS_REPEAT_COUNT], period, +  res[VALS_HOUR], res[VALS_MINUTE]);    default:    return LOCALE(495, "Error in stored value.");    }   }      #endif