# Copyright (c) 2016 Huawei, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import collections from django.utils.translation import ugettext_lazy as _ from icalendar.cal import Component from icalendar import Event from oslo_serialization import jsonutils TRIGGERTYPE_CHOICES = [('time', _('Time Trigger')), ('event', _('Event Trigger'))] CRONTAB = 'crontab' CRONTAB_DAY_CHOICES = [('1', _('Monday')), ('2', _('Tuesday')), ('3', _('Wednesday')), ('4', _('Thursday')), ('5', _('Friday')), ('6', _('Saturday')), ('0', _('Sunday'))] CRONTAB_DAY_DICT = collections.OrderedDict(CRONTAB_DAY_CHOICES) EVERYDAY = 'everyday' EVERYWEEK = 'everyweek' EVERYMONTH = 'everymonth' CRONTAB_FREQUENCE_CHOICES = [(EVERYDAY, _('Every Day')), (EVERYWEEK, _('Every Week')), (EVERYMONTH, _('Every Month'))] CRONTAB_FREQUENCE_DICT = collections.OrderedDict(CRONTAB_FREQUENCE_CHOICES) class CrontabUtil(object): """Convert to or from Crontab format. pattern: * * * * * first * is stand for minute 0~59 second * is stand for hour 0~23 third * is stand for day 1~31 fouth * is stand for month 1~12 fifth * is stand for week 0~6 (0 is Sunday) """ @staticmethod def convert_to_crontab(data): dict_crontab = { "format": CRONTAB, "pattern": "* * * * *" } data_day = data["day"] data_date = data["date"] data_time = data["time"] if data['frequence'] == EVERYDAY: dict_crontab["pattern"] = '%s %s * * *' \ % (data_time.minute, data_time.hour) elif data['frequence'] == EVERYWEEK: dict_crontab["pattern"] = '%s %s * * %s' \ % (data_time.minute, data_time.hour, data_day) elif data['frequence'] == EVERYMONTH: dict_crontab["pattern"] = '%s %s %s * *' \ % (data_time.minute, data_time.hour, data_date) return dict_crontab @staticmethod def convert_from_crontab(dict_crontab): data = { 'format': dict_crontab['format'] } if dict_crontab["format"] == CRONTAB: pattern = dict_crontab["pattern"] patterns = pattern.split(" ") if len(patterns) == 5: if patterns[2] == "*" \ and patterns[3] == "*" \ and patterns[4] == "*": data["frequence"] = CRONTAB_FREQUENCE_DICT[EVERYDAY] elif patterns[2] == "*" \ and patterns[3] == "*" \ and patterns[4] != "*": data["frequence"] = CRONTAB_FREQUENCE_DICT[EVERYWEEK] data["day"] = CRONTAB_DAY_DICT[patterns[4]] elif patterns[2] != "*" \ and patterns[3] == "*" \ and patterns[4] == "*": data["frequence"] = CRONTAB_FREQUENCE_DICT[EVERYMONTH] data["date"] = patterns[2] data["time"] = '%s:%s' % (patterns[1].zfill(2), patterns[0].zfill(2)) return data CALENDAR = 'calendar' CALENDAR_DAY_CHOICES = [('1', _('MO')), ('2', _('TU')), ('3', _('WE')), ('4', _('TH')), ('5', _('FR')), ('6', _('SA')), ('0', _('SU'))] CALENDAR_DAY_DICT = collections.OrderedDict(CALENDAR_DAY_CHOICES) CALENDAR_DAY_MAPPING = [('MO', _('Monday')), ('TU', _('Tuesday')), ('WE', _('Wednesday')), ('TH', _('Thursday')), ('FR', _('Friday')), ('SA', _('Saturday')), ('SU', _('Sunday'))] CALENDAR_DAY_MAPPING_DICT = collections.OrderedDict(CALENDAR_DAY_MAPPING) MINUTELY = 'MINUTELY' HOURLY = 'HOURLY' DAILY = 'DAILY' WEEKLY = 'WEEKLY' MONTHLY = 'MONTHLY' class CalendarUtil(object): """Convert to or from calendar format.""" @staticmethod def convert_to_calendar(data): dict_calendar = { "format": CALENDAR, } pattern_frequence = '' if data['frequence'] == EVERYMONTH: pattern_frequence = MONTHLY elif data['frequence'] == EVERYWEEK: pattern_frequence = WEEKLY elif data['frequence'] == EVERYDAY: pattern_frequence = DAILY calendar_event = Event() rule_pattern = { 'freq': pattern_frequence, 'byhour': data["time"].hour, 'byminute': data["time"].minute, } if pattern_frequence == MONTHLY: rule_pattern['bymonthday'] = data["date"] elif pattern_frequence == WEEKLY: rule_pattern['byday'] = CALENDAR_DAY_DICT[data["day"]] calendar_event.add('rrule', rule_pattern) dict_calendar['pattern'] = calendar_event.to_ical() return dict_calendar @staticmethod def decode_calendar_pattern(pattern): try: pattern.index('\\') pattern_dict = jsonutils.loads('{"pattern": "%s"}' % pattern) return pattern_dict["pattern"] except Exception: return pattern @staticmethod def convert_from_calendar(dict_calendar): data = { 'format': dict_calendar['format'] } if dict_calendar["format"] == CALENDAR: pattern = dict_calendar["pattern"] calendar_event = Component.from_ical( CalendarUtil.decode_calendar_pattern(pattern) ) if isinstance(calendar_event, Event): calendar_event_rule = calendar_event['RRULE'] data['frequence'] = calendar_event_rule['FREQ'][0] if data['frequence'] == MONTHLY and not ( 'INTERVAL' in calendar_event['RRULE']): data['date'] = ' '.join( str(date) for date in calendar_event_rule['BYMONTHDAY']) if data['frequence'] == WEEKLY and not ( 'INTERVAL' in calendar_event['RRULE']): data['day'] = ' '.join( str(CALENDAR_DAY_MAPPING_DICT[day]) for day in calendar_event_rule['BYDAY']) if 'BYHOUR' in calendar_event['RRULE']: data['hour'] = ' '.join( str(hour) for hour in calendar_event_rule['BYHOUR']) if 'BYMINUTE' in calendar_event['RRULE']: data['minute'] = ' '.join( str(minute) for minute in calendar_event_rule['BYMINUTE']) if 'INTERVAL' in calendar_event['RRULE']: data['interval'] = ' '.join( str(interval) for interval in calendar_event_rule['INTERVAL']) return data