root/branch/umitweb-ng/umitInventory/Calendar.py @ 4773

Revision 4773, 11.6 kB (checked in by rcarvalho, 4 years ago)

Merged revisions 4233 via svnmerge from
http://svn.umitproject.org/svnroot/umit/trunk

................

r4233 | gpolo | 2009-03-01 20:28:23 -0300 (Dom, 01 Mar 2009) | 9 lines


Merged revisions 4232 via svnmerge from
http://svn.umitproject.org/svnroot/umit/branch/NetworkInventory


........

r4232 | gpolo | 2009-03-01 20:23:10 -0300 (Sun, 01 Mar 2009) | 1 line


Fixed ticket #233: Use temp values stored while running in dryrun to calculate the current month range.

........

................

Line 
1# Copyright (C) 2007 Adriano Monteiro Marques
2#
3# Authors: Guilherme Polo <ggpolo@gmail.com>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18# USA
19"""
20Calendar, this control manages date for Timeline and is also being used
21in other pieces of umitInventory.
22"""
23
24import datetime
25
26from umitCore.I18N import _
27
28(INC_YEAR, INC_MONTH, INC_DAY, INC_HOUR) = (
29    (DEC_YEAR, DEC_MONTH, DEC_DAY, DEC_HOUR)) = range(4)
30
31months = [
32    _("January"), _("February"), _("March"), _("April"), _("May"),
33    _("June"), _("July"), _("August"), _("September"),
34    _("October"), _("November"), _("December")]
35
36weekdays = [
37    _("Monday"), _("Tuesday"), _("Wednesday"), _("Thursday"),
38    _("Friday"), _("Saturday"), _("Sunday")]
39
40# Number of days per month (except for February in leap years)
41mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
42
43def monthname(month, first=-1):
44    return months[month+first]
45
46def isleap(year):
47    """
48    Returns True for leap years.
49    """
50    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
51
52def startup_calendar_opts():
53    """
54    Returns a dict to be used as a standard startup dict for CalendarManager.
55    """
56    methods = ( "year", "month", "day", "hour" )
57    datenow = datetime.datetime.now()
58    date = { }
59
60    for m in methods:
61        date[m] = getattr(datenow, m)
62
63    date["year_range"] = (1970, 3000)
64
65    return date
66
67class Error(Exception):
68    pass
69
70class OutOfRangeError(Error):
71    pass
72
73class YearOutOfRangeError(OutOfRangeError):
74    pass
75
76class YearRangeOutOfRangeError(OutOfRangeError):
77    pass
78
79class MonthOutOfRangeError(OutOfRangeError):
80    pass
81
82class DayOutOfRangeError(OutOfRangeError):
83    pass
84
85class HourOutOfRangeError(OutOfRangeError):
86    pass
87
88class FirstWeekdayOutOfRangeError(OutOfRangeError):
89    pass
90
91class CalendarManager(object):
92    """
93    This class control everything related to dates for TimeLine.
94    """
95
96    def __init__(self, year, month, day, hour, year_range, first_weekday=0):
97        """
98        Parameters:
99       
100        year                 = initial year (1970-3000)
101        month                = initial month (1-12)
102        day                  = initial day (1..monthrange)
103        hour                 = initial hour (0-23)
104        year_range           = year range (n, n) (min 1970, max 3000)
105        first_weekday        = first weekday (0 Mon 6 Sun)
106        """
107        # setting dryrun to True will cause to dates not be modified,
108        # setters will just return the new that would be set.
109        self.dryrun = False
110        self.temp = { } # stores dryrun "changes"
111
112        self.__month_range = (1, 12)
113        self.year_range = year_range
114        self.year = year
115        self.month = month
116        self.day = day
117        self.fwday = first_weekday
118        self.hour = hour
119
120
121    def get_dryrun(self):
122        """
123        Get current dryrun status.
124        """
125        return self.__dryrun
126
127
128    def set_dryrun(self, enable):
129        """
130        Enables/Disable dryrun.
131        """
132        self.__dryrun = enable
133
134        if not self.dryrun:
135            # Clean temp dict used to store changes that would be made if
136            # dryrun was set to False.
137            self.temp = { }
138
139
140    def validate_date(self, year, month, day, hour):
141        pass
142
143
144    def get_current_firstlast_firstwday(self):
145        return self.get_firstlast_firstwday(self.year, self.month)
146
147
148    def get_firstlast_firstwday(self, year, month):
149        """
150        Returns the month range (1..n), first month day no. and name, and
151        first weekdays in the specified date.
152        """
153        range_fmday = self.get_monthrange(year, month)
154        fwday = self.get_first_weekday()
155       
156        fwdays = [ ]
157        for day in xrange(1, range_fmday[1]+1):
158            weekday = self.get_weekday(year, month, day)[0]
159            if weekday == fwday:
160                fwdays.append(day)
161        fwdays = tuple(fwdays)
162       
163        return ((1, range_fmday[1]), (range_fmday[0],
164            weekdays[range_fmday[0]]), fwdays)
165
166
167    def get_date(self, model=None):
168        """
169        Returns current date set based on a model or using the
170        default. Default returns year, month, day, hour, in this order.
171        """
172        if model:
173            try:
174                meths = [ ]
175                for i in model:
176                    meths.append(getattr(self, "get_"+i)())
177                return tuple(meths)
178            except:
179                return self.year, self.month, self.day
180        else:
181            return self.year, self.month, self.day, self.hour
182
183
184    def get_current_weekday_name(self):
185        """
186        Convenience function for get_current_weekday, returns just name
187        """
188        return self.get_current_weekday()[1]
189
190
191    def get_current_weekday_no(self):
192        """
193        Convenience function for get_current_weekday, return just number
194        """
195        return self.get_current_weekday()[0]
196
197
198    def get_current_weekday(self):
199        """
200        Returns weekday day and name for current date.
201        """
202        self.fix_date()
203        return self.get_weekday(self.year, self.month,  self.day)
204   
205   
206    def get_weekday(self, year, month, day):
207        """
208        Returns weekday (0-6 -> Mon-Sun) day and name for a date.
209        Year should be at least 1970, month is in range 1..12, and day
210        is 1..n.
211        """
212        if day == 0:
213            # silently correct day
214            day = 1
215
216        wday = datetime.date(year, month, day).weekday()
217        wname = weekdays[wday]
218        return wday, wname
219
220
221    def get_year_range(self):
222        """
223        Returns current year range.
224        """
225        return self.__year_range
226
227
228    def set_year_range(self, yrange):
229        """
230        Sets new year range
231        """
232        if yrange[0] < 1970 or yrange[1] > 3000 or yrange[0] >= yrange[1] - 1:
233            raise YearRangeOutOfRangeError(yrange)
234
235        if self.dryrun:
236            self.temp["year_range"] = yrange
237            return
238
239        self.__year_range = yrange
240
241
242    def get_year(self):
243        """
244        Returns current year.
245        """
246        return self.__year
247
248
249    def set_year(self, year):
250        """
251        Sets a year.
252        """
253        if not self.year_range[0] <= year <= self.year_range[1]:
254            raise YearOutOfRangeError(year)
255
256        if self.dryrun:
257            self.temp["year"] = year
258            return
259
260        self.__year = year
261
262
263    def get_month(self):
264        """
265        Returns current month.
266        """
267        return self.__month
268
269
270    def set_month(self, month):
271        """
272        Sets a month.
273        """
274        if not 1 <= month <= 12:
275            raise MonthOutOfRangeError(month)
276
277        if self.dryrun:
278            self.temp["month"] = month
279            return
280
281        self.__month = month
282
283    def get_current_monthrange(self):
284        """
285        Returns days range for current date.
286        """
287        month = self.month
288        year = self.month
289        # When running in dryrun mode use the values that would be changed
290        # if not running in this mode.
291        if self.dryrun:
292            month = self.temp.get('month', year)
293            year = self.temp.get('year', year)
294        return self.get_monthrange(year, month)
295
296
297    def get_monthrange(self, year, month):
298        """
299        Returns days range and first weekday for specified date.
300        """
301        day1 = self.get_weekday(year, month, 1)[0]
302        ndays = mdays[month] + (month == 2 and isleap(year))
303
304        return day1, ndays
305
306
307    def get_day(self):
308        """
309        Returns current day.
310        """
311        return self.__day
312
313
314    def set_day(self, day):
315        """
316        Sets a day.
317        """
318        if not 1 <= day <= self.get_current_monthrange()[1]:
319            raise DayOutOfRangeError(day)
320
321        if self.dryrun:
322            self.temp["day"] = day
323            return
324
325        self.__day = day
326
327
328    def get_first_weekday(self):
329        """
330        Returns first weekday.
331        """
332        return self.__fwday
333
334
335    def set_first_weekday(self, fwday):
336        """
337        Sets the first weekday.
338        """
339        if fwday not in (0, 6):
340            raise FirstWeekdayOutOfRangeError(fwday)
341
342        if self.dryrun:
343            self.temp["fwday"] = fwday
344            return
345
346        self.__fwday = fwday
347
348
349    def get_hour(self):
350        """
351        Returns current hour.
352        """
353        return self.__hour
354
355
356    def set_hour(self, hour):
357        """
358        Sets an hour.
359        """
360        if not 0 <= hour <= 23:
361            raise HourOutOfRangeError(hour)
362
363        if self.dryrun:
364            self.temp["hour"] = hour
365            return
366
367        self.__hour = hour
368
369
370    def fix_date(self):
371        """
372        This should be called after setting a date by hand or after
373        incrementing/decrementing an year.
374        """
375        try:
376            self.day = self.day
377        except DayOutOfRangeError: # changed from leap year to non leap year
378            self.day = self.get_current_monthrange()[1]
379
380
381    def inc_date(self, param, inc=1):
382        """
383        Increments or decrements a date.
384        """
385        if inc not in (-1, 1):
386            raise Error, "Increment should be -1 or 1"
387       
388        if param == INC_YEAR:
389            self.__inc_year(inc)
390               
391        elif param == INC_MONTH:
392            self.__inc_month(inc)
393               
394        elif param == INC_DAY:
395            self.__inc_day(inc)
396                       
397        elif param == INC_HOUR:
398            self.__inc_hour(inc)
399
400
401    def dec_date(self, param, inc=-1):
402        """
403        Just for convenience.
404        """
405        self.inc_date(param, inc)
406
407    ## Private methods follows.
408
409    def __inc_year(self, inc=1):
410        """
411        Increments or decrements year.
412        """
413        try:
414            self.year = self.year + inc
415        except YearOutOfRangeError:
416            self.year = self.year_range[(inc == -1) and 1 or 0]
417       
418        self.fix_date()
419
420
421    def __inc_month(self, inc=1):
422        """
423        Increments or decrements month.
424        """
425        try:
426            self.month = self.month + inc
427        except MonthOutOfRangeError:
428            self.__inc_year(inc)
429            self.month = self.__month_range[(inc == -1) and 1 or 0]
430
431
432    def __inc_day(self, inc=1):
433        """
434        Increments or decrements day.
435        """
436        try:
437            self.day = self.day + inc
438        except DayOutOfRangeError:
439            self.__inc_month(inc)
440            self.day = (inc == -1) and self.get_current_monthrange()[1] or 1
441
442    def __inc_hour(self, inc=1):
443        """
444        Increments or decrements hour.
445        """
446        try:
447            self.hour = self.hour + inc
448        except HourOutOfRangeError:
449            self.__inc_day(inc)
450            self.hour = (inc == -1) and 23 or 0
451
452
453    # Properties
454    dryrun = property(get_dryrun, set_dryrun)
455    year = property(get_year, set_year)
456    month = property(get_month, set_month)
457    day = property(get_day, set_day)
458    fwday = property(get_first_weekday, set_first_weekday)
459    hour = property(get_hour, set_hour)
460    year_range = property(get_year_range, set_year_range)
461
Note: See TracBrowser for help on using the browser.