Source code for ls.joyous.holidays

# ------------------------------------------------------------------------------
# Joyous Holidays
# ------------------------------------------------------------------------------
import datetime as dt
from itertools import chain
from collections import defaultdict, OrderedDict
from django.conf import settings
from .parser import parseHolidays

[docs]class Holidays: """Defines what holidays are celebrated on what dates.""" def __init__(self, holidaySetting="JOYOUS_HOLIDAYS"): self.setting = holidaySetting self.simple = {} self.srcs = [ self.simple ] self._parseSettings() def __add__(self, other): retval = Holidays(None) for date, value in chain(self.simple.items(), other.simple.items()): retval.add(date, value) for src in chain(self.srcs[1:], other.srcs[1:]): retval.register(src) return retval def _parseSettings(self): if self.setting: holidaySettings = getattr(settings, self.setting, "") if holidaySettings: hols = parseHolidays(holidaySettings) if hols is not None: self.register(hols)
[docs] def register(self, src): """Register a new source of holiday data.""" self.srcs.append(src)
[docs] def add(self, date, value): """Add a holiday to an individual date.""" oldValue = self.simple.get(date) if oldValue: if oldValue not in value and value not in oldValue: self.simple[date] = "{}, {}".format(oldValue, value) else: self.simple[date] = value
[docs] def get(self, date): """Get all the holidays that are celebrated on this date.""" holidays = [] for src in self.srcs: # get from python-holidays and other dict type srcs getHoliday = getattr(src, "get", None) if not getHoliday: # get from workalendar srcs getHoliday = getattr(src, "get_holiday_label") holiday = getHoliday(date) if holiday: holidays.extend(holiday.split(", ")) holidays = list(OrderedDict.fromkeys(holidays)) # remove duplicates return ", ".join(holidays)
[docs] def names(self): """Get a list of all the holiday names, sorted by month-day.""" thisYear = dt.date.today().year popYears = list(range(thisYear - 1, thisYear + 10)) holidays = defaultdict(list) for src in self.srcs: # populate python-holidays calendar populate = getattr(src, "_populate", None) if populate: for year in popYears: populate(year) # get from python-holidays and other dict type srcs items = getattr(src, "items", None) if items: for date, names in items(): # holidays may have been concatenated together for name in names.split(", "): holidays[name].append(date) else: # get from workalendar srcs getHolidays = getattr(src, "get_calendar_holidays", None) if getHolidays: for year in popYears: for date, name in getHolidays(year): holidays[name].append(date) # sort holidays by month-day with a preference for a more recent year mmddHolidays = [] def moreRecent(date): delta2 = (date.year - thisYear) * 2 if delta2 < 0: # slight preference for future years over past years delta2 = -delta2 + 1 return delta2 for name, dates in holidays.items(): mostRecent = min(dates, key=moreRecent) mmddHolidays.append(((mostRecent.month, mostRecent.day), name)) mmddHolidays.sort() retval = [name for mmdd, name in mmddHolidays] return retval
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------