"""
Some additional helpers
"""
import datetime
import calendar as _calendar
import qmsk.web.helpers
import preferences, urls, config, version
class Helpers (qmsk.web.helpers.Helpers) :
"""
Our set of helpers, inheriting from base helpers
"""
# set contructor...
set = set
# reference to calendar instance
calendar = _calendar.Calendar()
# list of (month_num, month_name) for the months in the year
months = list(enumerate(_calendar.month_name))[1:]
def version_link (self) :
"""
Returns a <a href> representing this version of the software
"""
return version.version_link_hg(config.HGWEB_URL, config.HG_WC_PATH)
def tz_name (self, tz) :
"""
Returns a string describing the given timezone
"""
return self.now().strftime(config.TIMEZONE_FMT)
def fmt_month (self, date) :
"""
Formats a month
"""
return date.strftime(config.MONTH_FMT)
def fmt_weekday (self, wday) :
"""
Formats an abbreviated weekday name
"""
return _calendar.day_abbr[wday]
def build_date (self, month, mday) :
"""
Returns a datetime.datetime for the given (month.year, month.month, mday)
"""
return self.ctx['prefs'][preferences.timezone].localize(datetime.datetime(month.year, month.month, mday))
def now (self) :
"""
Build current time
"""
return self.ctx['prefs'][preferences.timezone].localize(datetime.datetime.now())
def today (self) :
"""
Build today's date
"""
return self.now().date()
def is_today (self, dt) :
"""
Checks if the given datetime.datetime is today
"""
# compare with current date
return dt.date() == self.today()
def is_this_month (self, month) :
"""
Checks the given month is the current month
"""
today = self.today()
return (month.year == today.year and month.month == today.month)
@staticmethod
def _wrap_year (year, month) :
"""
Wraps month to between [1, 12], spilling overflow/underflow by to year.
Returns (year, month)
"""
# underflow?
if month == 0 :
# wrap to previous year
return (year - 1, 12)
# overflow?
elif month == 13 :
# wrap to next year
return (year + 1, 1)
# sane value
elif 1 <= month <= 12 :
return (year, month)
# insane value
else :
assert False, "invalid year/month: %d/%d" % (year, month)
def prev_month (self, month) :
"""
Returns the month preceding the given one (as a datetime.datetime)
"""
# previous month
y, m = self._wrap_year(month.year, month.month - 1)
# build datetime
return datetime.datetime(year=y, month=m, day=1, tzinfo=month.tzinfo)
def next_month (self, month) :
"""
Returns the month following the given one (as a datetime.datetime)
"""
# previous month
y, m = self._wrap_year(month.year, month.month + 1)
# build datetime
return datetime.datetime(year=y, month=m, day=1, tzinfo=month.tzinfo)
def fmt_time (self, time=None) :
"""
Format given time, or current time
"""
# defaults
if not time :
time = self.now()
return time.strftime(self.ctx['prefs'][preferences.time_format])
def fmt_date (self, date=None) :
"""
Format given date, or current date
"""
# defaults
if not date :
date = self.now()
return date.strftime(self.ctx['prefs'][preferences.date_format])
def url (self, url, **params) :
"""
Build URL with our request object
"""
return url.build(self.ctx['req'], **params)
# old name
build_url = url
def utc_timestamp (self, dtz) :
"""
Build an UTC timestamp from the given datetime
"""
return urls.types['ts'].build(dtz)
def skip_next (self, count, skip) :
"""
Return skip offset for next page
"""
return count + skip
def skip_page (self, count, page) :
"""
Skip to page
"""
if page :
return count * page
else :
return None
def skip_prev (self, count, skip) :
"""
Return skip offset for previous page, None for first page
"""
if skip > count :
return skip - count
else :
return None
def max (self, *values) :
"""
Returns the largest of the given values
"""
return max(values)
def select_options (self, key_values, selected_key=None) :
"""
Render a series of <option> tags for <select>.
The given key_values is an iterable of (key, value) pairs, key may be None if it's the same as value.
"""
return '\n'.join(
'\t<option%s%s>%s</option>' % (
' value="%s"' % key if key is not None else '',
' selected="selected"' if (key if key is not None else value) == selected_key else '',
value
) for key, value in key_values
)
def prev_date (self, date) :
"""
Returns the previous date for the given datetime-date
"""
return datetime.datetime(date.year, date.month, date.day, tzinfo=date.tzinfo) - datetime.timedelta(days=1)
def next_date (self, date) :
"""
Returns the previous date for the given datetime-date
"""
return datetime.datetime(date.year, date.month, date.day, tzinfo=date.tzinfo) + datetime.timedelta(days=1)