helpers.py
changeset 140 6db2527b67cf
parent 139 9c7769850195
child 141 65c98c9e1716
equal deleted inserted replaced
139:9c7769850195 140:6db2527b67cf
     1 """
       
     2     Some additional helpers
       
     3 """
       
     4 
       
     5 import datetime
       
     6 import calendar as _calendar
       
     7 
       
     8 import qmsk.web.helpers
       
     9 
       
    10 import preferences, urls, config, version
       
    11 
       
    12 class Helpers (qmsk.web.helpers.Helpers) :
       
    13     """
       
    14         Our set of helpers, inheriting from base helpers
       
    15     """
       
    16 
       
    17     # set contructor...
       
    18     set = set
       
    19 
       
    20     # reference to calendar instance
       
    21     calendar = _calendar.Calendar()
       
    22 
       
    23     # list of (month_num, month_name) for the months in the year
       
    24     months = list(enumerate(_calendar.month_name))[1:]
       
    25     
       
    26     def version_link (self) :
       
    27         """
       
    28             Returns a <a href> representing this version of the software
       
    29         """
       
    30 
       
    31         return version.version_link_hg(config.HGWEB_URL, config.HG_WC_PATH)
       
    32 
       
    33     def tz_name (self, tz) :
       
    34         """
       
    35             Returns a string describing the given timezone
       
    36         """
       
    37 
       
    38         return self.now().strftime(config.TIMEZONE_FMT)
       
    39 
       
    40     def fmt_month (self, date) :
       
    41         """
       
    42             Formats a month
       
    43         """
       
    44 
       
    45         return date.strftime(config.MONTH_FMT)
       
    46         
       
    47     def fmt_weekday (self, wday) :
       
    48         """
       
    49             Formats an abbreviated weekday name
       
    50         """
       
    51 
       
    52         return _calendar.day_abbr[wday]
       
    53 
       
    54     def build_date (self, month, mday) :
       
    55         """
       
    56             Returns a datetime.datetime for the given (month.year, month.month, mday)
       
    57         """
       
    58 
       
    59         return self.ctx['prefs'][preferences.timezone].localize(datetime.datetime(month.year, month.month, mday))
       
    60     
       
    61     def now (self) :
       
    62         """
       
    63             Build current time
       
    64         """
       
    65 
       
    66         return self.ctx['prefs'][preferences.timezone].localize(datetime.datetime.now())
       
    67 
       
    68     def today (self) :
       
    69         """
       
    70             Build today's date
       
    71         """
       
    72         
       
    73         return self.now().date()
       
    74 
       
    75     def is_today (self, dt) :
       
    76         """
       
    77             Checks if the given datetime.datetime is today
       
    78         """
       
    79 
       
    80         # compare with current date
       
    81         return dt.date() == self.today()
       
    82     
       
    83     def is_this_month (self, month) :
       
    84         """
       
    85             Checks the given month is the current month
       
    86         """
       
    87 
       
    88         today = self.today()
       
    89 
       
    90         return (month.year == today.year and month.month == today.month)
       
    91 
       
    92     @staticmethod
       
    93     def _wrap_year (year, month) :
       
    94         """
       
    95             Wraps month to between [1, 12], spilling overflow/underflow by to year.
       
    96 
       
    97             Returns (year, month)
       
    98         """
       
    99         
       
   100         # underflow?
       
   101         if month == 0 :
       
   102             # wrap to previous year
       
   103             return (year - 1, 12)
       
   104         
       
   105         # overflow?
       
   106         elif month == 13 :
       
   107             # wrap to next year
       
   108             return (year + 1, 1)
       
   109         
       
   110         # sane value
       
   111         elif 1 <= month <= 12 :
       
   112             return (year, month)
       
   113         
       
   114         # insane value
       
   115         else :
       
   116             assert False, "invalid year/month: %d/%d" % (year, month)
       
   117 
       
   118     def prev_month (self, month) :
       
   119         """
       
   120             Returns the month preceding the given one (as a datetime.datetime)
       
   121         """
       
   122         
       
   123         # previous month
       
   124         y, m = self._wrap_year(month.year, month.month - 1)
       
   125         
       
   126         # build datetime
       
   127         return datetime.datetime(year=y, month=m, day=1, tzinfo=month.tzinfo)
       
   128 
       
   129     def next_month (self, month) :
       
   130         """
       
   131             Returns the month following the given one (as a datetime.datetime)
       
   132         """
       
   133         
       
   134         # previous month
       
   135         y, m = self._wrap_year(month.year, month.month + 1)
       
   136         
       
   137         # build datetime
       
   138         return datetime.datetime(year=y, month=m, day=1, tzinfo=month.tzinfo)
       
   139     
       
   140     def fmt_time (self, time=None) :
       
   141         """
       
   142             Format given time, or current time
       
   143         """
       
   144         
       
   145         # defaults
       
   146         if not time :
       
   147             time = self.now()
       
   148 
       
   149         return time.strftime(self.ctx['prefs'][preferences.time_format])
       
   150 
       
   151     def fmt_date (self, date=None) :
       
   152         """
       
   153             Format given date, or current date
       
   154         """
       
   155         
       
   156         # defaults
       
   157         if not date :
       
   158             date = self.now()
       
   159 
       
   160         return date.strftime(self.ctx['prefs'][preferences.date_format])
       
   161 
       
   162     def url (self, url, **params) :
       
   163         """
       
   164             Build URL with our request object
       
   165         """
       
   166 
       
   167         return url.build(self.ctx['req'], **params)
       
   168 
       
   169     # old name
       
   170     build_url = url
       
   171 
       
   172     def utc_timestamp (self, dtz) :
       
   173         """
       
   174             Build an UTC timestamp from the given datetime
       
   175         """
       
   176 
       
   177         return urls.types['ts'].build(dtz)
       
   178     
       
   179     def skip_next (self, count, skip) :
       
   180         """
       
   181             Return skip offset for next page
       
   182         """
       
   183 
       
   184         return count + skip
       
   185     
       
   186     def skip_page (self, count, page) :
       
   187         """
       
   188             Skip to page
       
   189         """
       
   190 
       
   191         if page :
       
   192             return count * page
       
   193 
       
   194         else :
       
   195             return None
       
   196 
       
   197     def skip_prev (self, count, skip) :
       
   198         """
       
   199             Return skip offset for previous page, None for first page
       
   200         """
       
   201 
       
   202         if skip > count :
       
   203             return skip - count
       
   204 
       
   205         else :
       
   206             return None
       
   207 
       
   208     def max (self, *values) :
       
   209         """
       
   210             Returns the largest of the given values
       
   211         """
       
   212 
       
   213         return max(values)
       
   214     
       
   215     def select_options (self, key_values, selected_key=None) :
       
   216         """
       
   217             Render a series of <option> tags for <select>.
       
   218 
       
   219             The given key_values is an iterable of (key, value) pairs, key may be None if it's the same as value.
       
   220         """
       
   221 
       
   222         return '\n'.join(
       
   223             '\t<option%s%s>%s</option>' % (
       
   224                 ' value="%s"' % key if key is not None else '',
       
   225                 ' selected="selected"' if (key if key is not None else value) == selected_key else '',
       
   226                 value
       
   227             ) for key, value in key_values
       
   228         )
       
   229     
       
   230     def prev_date (self, date) :
       
   231         """
       
   232             Returns the previous date for the given datetime-date
       
   233         """
       
   234 
       
   235         return datetime.datetime(date.year, date.month, date.day, tzinfo=date.tzinfo) - datetime.timedelta(days=1)
       
   236 
       
   237     def next_date (self, date) :
       
   238         """
       
   239             Returns the previous date for the given datetime-date
       
   240         """
       
   241 
       
   242         return datetime.datetime(date.year, date.month, date.day, tzinfo=date.tzinfo) + datetime.timedelta(days=1)
       
   243