Пример #1
0
    def occurDay(self, start, now, skip=1, day=6, occur=0):
        startDateTime = datetime.fromtimestamp(start, self.tzInstance)
        timeDelta = relativedelta(hours=startDateTime.hour,
                                  minutes=startDateTime.minute,
                                  seconds=startDateTime.second)
        log.debug('start date: %s; day: %d; occur: %d; skip: %d',
                  str(startDateTime), day, occur, skip)
        # get a list of (mday, wday) tuples for current month
        c = calendar.Calendar(firstweekday=0)
        flatter = sum(
            c.monthdays2calendar(startDateTime.year, startDateTime.month), [])
        if occur == 5:
            flatter = reversed(flatter)
            tmp_occur = 0
        else:
            tmp_occur = occur
        count = 0
        #find Nth occurrence of week day
        for mday, wday in flatter:
            if wday == day and mday > 0:
                count += 1
                log.debug('found wday %d, mday %d, count %d', wday, mday,
                          count)
                if count == tmp_occur + 1 and mday >= startDateTime.day:
                    log.debug('count matched, mday %d', mday)
                    startDateTime = datetime(
                        startDateTime.year,
                        startDateTime.month,
                        mday,
                        tzinfo=self.tzInstance) + timeDelta
                    startTimestamp = Time.awareDatetimeToTimestamp(
                        startDateTime)
                    # do we need to skip this day?
                    if skip > 1:
                        log.debug('skipping this occurrence. skip = %d', skip)
                        return self.occurDay(startTimestamp + DAY_SECONDS, now,
                                             skip - 1, day, tmp_occur)
                    elif startTimestamp >= now:
                        log.debug(
                            'Window will start on: %s',
                            str(
                                datetime.fromtimestamp(startTimestamp,
                                                       self.tzInstance)))
                        return startTimestamp

        # couldn't find start day in current month, switching to 1st day of the next month
        if startDateTime.month == 12:
            startDateTime = datetime(startDateTime.year + 1,
                                     1,
                                     1,
                                     tzinfo=self.tzInstance)
        else:
            startDateTime = datetime(startDateTime.year,
                                     startDateTime.month + 1,
                                     1,
                                     tzinfo=self.tzInstance)
        startDateTime += timeDelta

        return self.occurDay(Time.awareDatetimeToTimestamp(startDateTime), now,
                             skip, day, occur)
Пример #2
0
 def getLocalizedTimestamp(year, month, day, hour, minutes):
     localizedExpectedDateTime = datetime(year,
                                          month,
                                          day,
                                          hour,
                                          minutes,
                                          tzinfo=tzInstance)
     return Time.awareDatetimeToTimestamp(localizedExpectedDateTime)
Пример #3
0
def addMonth(secs, dayOfMonthHint=0, tzInstance=tz.tzutc()):
    dateTime = datetime.fromtimestamp(secs, tzInstance)
    newYear = dateTime.year
    newMonth = dateTime.month + 1

    if newMonth > 12:
        newYear += 1
        newMonth = 1

    lastDayOfMonth = calendar.monthrange(newYear, newMonth)[1]
    newDay = min(dayOfMonthHint, lastDayOfMonth)
    newDateTime = datetime(year=newYear,
                           month=newMonth,
                           day=newDay,
                           hour=dateTime.hour,
                           minute=dateTime.minute,
                           second=dateTime.second,
                           tzinfo=tzInstance)

    return Time.awareDatetimeToTimestamp(newDateTime)
Пример #4
0
 def getLocalizedTimestamp(dateTime):
     localized_expected_time = dateTime.replace(tzinfo=tzInstance)
     return Time.awareDatetimeToTimestamp(localized_expected_time)
Пример #5
0
    def _next(self, now):
        if not self.enabled:
            return None

        if self.skip is None:
            self.skip = 1

        if now is None:
            now = time.time()

        if now < self.start:
            return self.start

        if self.repeat == self.NEVER:
            if now > self.start:
                return None
            return self.start

        elif self.repeat == self.DAILY:
            daysSince = (now - self.start) // DAY_SECONDS
            dateTime = datetime.fromtimestamp(
                self.start,
                self.tzInstance) + relativedelta(days=daysSince + self.skip)
            return Time.awareDatetimeToTimestamp(dateTime)

        elif self.repeat == self.EVERY_WEEKDAY:
            weeksSince = (now - self.start) // WEEK_SECONDS
            weekdaysSince = weeksSince * 5
            # start at the most recent week-even point from the start
            baseDateTime = datetime.fromtimestamp(
                self.start, self.tzInstance) + relativedelta(weeks=weeksSince)
            nowDateTime = datetime.fromtimestamp(now, self.tzInstance)
            while 1:
                dow = baseDateTime.weekday()
                if dow not in (5, 6):
                    if baseDateTime > nowDateTime and weekdaysSince % self.skip == 0:
                        break
                    weekdaysSince += 1
                baseDateTime += relativedelta(days=1)
            assert baseDateTime >= nowDateTime
            return Time.awareDatetimeToTimestamp(baseDateTime)

        elif self.repeat == self.WEEKLY:
            weeksSince = (now - self.start) // WEEK_SECONDS
            dateTime = datetime.fromtimestamp(
                self.start,
                self.tzInstance) + relativedelta(weeks=weeksSince + self.skip)
            return Time.awareDatetimeToTimestamp(dateTime)

        elif self.repeat == self.MONTHLY:
            months = 0
            m = self.start
            dayOfMonthHint = datetime.fromtimestamp(self.start,
                                                    self.tzInstance).day
            while m < now or months % self.skip:
                m = addMonth(m, dayOfMonthHint, self.tzInstance)
                months += 1
            return m

        elif self.repeat == self.NTHWDAY:
            return self.occurDay(self.start, now, self.skip,
                                 self.DAYS.index(self.days),
                                 self.OCCURRENCE.index(self.occurrence))
        raise ValueError('bad value for MaintenanceWindow repeat: %r' %
                         self.repeat)
Пример #6
0
    def manage_editMaintenanceWindow(
            self,
            startDate='',
            startHours='00',
            startMinutes='00',
            durationDays='0',
            durationHours='00',
            durationMinutes='00',
            repeat='Never',
            days='Sunday',
            occurrence='1st',
            startProductionState=300,
            stopProductionState=RETURN_TO_ORIG_PROD_STATE,
            enabled=True,
            skip=1,
            REQUEST=None,
            startDateTime=None,
            timezone=None):
        "Update the maintenance window from GUI elements"

        def makeInt(v, fieldName, minv=None, maxv=None, acceptBlanks=True):
            if acceptBlanks:
                if isinstance(v, str):
                    v = v.strip()
                v = v or '0'
            try:
                v = int(v)
                if minv is not None and v < minv:
                    raise ValueError
                if maxv is not None and v > maxv:
                    raise ValueError
            except ValueError:
                if minv is None and maxv is None:
                    msg = '%s must be an integer.' % fieldName
                elif minv is not None and maxv is not None:
                    msg = '%s must be between %s and %s inclusive.' % (
                        fieldName, minv, maxv)
                elif minv is not None:
                    msg = '%s must be at least %s' % (fieldName, minv)
                else:
                    msg = '%s must be no greater than %s' % (fieldName, maxv)
                msgs.append(msg)
                v = None
            return v

        oldAuditData = self.getAuditData()
        prodStates = dict(
            (key, value)
            for (key, value) in self.dmd.getProdStateConversions())
        msgs = []
        self.enabled = bool(enabled)

        if not timezone:
            # Use container timezone
            timezone = time.strftime('%Z')
        try:
            tzInstance = tz.gettz(timezone)
        except:
            msgs.append("'timezone' has wrong value")

        if startDateTime:
            t = int(startDateTime)
        else:
            startHours = int(startHours) if startHours else 0
            startMinutes = int(startMinutes) if startMinutes else 0
            self.enabled = bool(enabled)
            try:
                month, day, year = re.split('[^ 0-9]', startDate)
            except ValueError:
                msgs.append("Date needs three number fields")
            day = int(day)
            month = int(month)
            year = int(year)
            if not msgs:
                startDateTime = datetime(year,
                                         month,
                                         day,
                                         startHours,
                                         startMinutes,
                                         tzinfo=tzInstance)
                t = Time.awareDatetimeToTimestamp(startDateTime)
        if repeat not in self.REPEAT:
            msgs.append('\'repeat\' has wrong value.')
        if not isinstance(enabled, bool):
            msgs.append('\'enabled\' has wrong value, use true or false.')
        if not (startProductionState in prodStates.values()
                or prodStates.get(startProductionState, None)):
            msgs.append('\'startProductionState\' has wrong value.')
        elif isinstance(startProductionState, str):
            startProductionState = prodStates[startProductionState]
        if not msgs:
            durationDays = makeInt(durationDays, 'Duration days', minv=0)
            durationHours = makeInt(durationHours,
                                    'Duration hours',
                                    minv=0,
                                    maxv=23)
            durationMinutes = makeInt(durationMinutes,
                                      'Duration minutes',
                                      minv=0,
                                      maxv=59)
        if not msgs:
            duration = (durationDays * (60 * 24) + durationHours * 60 +
                        durationMinutes)

            if duration < 1:
                msgs.append('Duration must be at least 1 minute.')
        if msgs:
            if REQUEST:
                messaging.IMessageSender(self).sendToBrowser(
                    'Window Edit Failed', '\n'.join(msgs), messaging.WARNING)
            else:
                raise Exception('Window Edit Failed: ' + '\n'.join(msgs))
        else:
            self.start = t
            self.duration = duration
            self.repeat = repeat
            self.days = days
            self.occurrence = occurrence
            self.startProductionState = startProductionState
            self.stopProductionState = stopProductionState
            self.skip = skip
            self.timezone = timezone
            self.tzInstance = tzInstance
            now = time.time()
            if self.started:
                if ((t + duration * 60) < now) or (t >
                                                   now) or (not self.enabled):
                    # We're running. If we should have already ended OR the start was
                    # moved into the future OR the MW is now disabled, end().
                    self.end()
            elif (t < now) and ((t + duration * 60) > now) and (self.enabled):
                # We aren't running, but we've scheduled the MW to be going on right now.
                self.begin()

            if REQUEST:
                flare = 'Maintenance window changes were saved.'
                if self.enabled:
                    flare += ' Next run on %s' % time.strftime(
                        "%m/%d/%Y %H:%M:%S", time.localtime(self.next()))
                messaging.IMessageSender(self).sendToBrowser(
                    'Window Updated', flare)
                audit('UI.MaintenanceWindow.Edit',
                      self,
                      data_=self.getAuditData(),
                      oldData_=oldAuditData)
        if REQUEST:
            return REQUEST.RESPONSE.redirect(self.getUrlForUserCommands())