Removed blank calendar year, fixed year_glance filenames, fixed collect_data, fixed one_day, added get_marrital_status, and fill_day_list. More changes will be coming.

svn: r11744
This commit is contained in:
Rob G. Healey 2009-01-27 07:49:47 +00:00
parent e7e91c7269
commit 45a1e7493b

View File

@ -227,7 +227,6 @@ class WebCalReport(Report):
self.end_year = menu.get_option_by_name('end_year').get_value()
self.fullyear = menu.get_option_by_name('fullyear').get_value()
self.blankyear = menu.get_option_by_name('blankyear').get_value()
self.maiden_name = menu.get_option_by_name('maiden_name').get_value()
@ -313,13 +312,13 @@ class WebCalReport(Report):
if month > 0:
try:
my_date = datetime.date(year, month, day)
my_date = _make_date(year, month, day)
except ValueError:
my_date = '...'
else:
my_date = '...' #Incomplete date as in about, circa, etc.
day_list.append((my_date, text, event))
day_list.append((text, event, my_date))
month_dict[day] = day_list
self.calendar[month] = month_dict
@ -359,13 +358,12 @@ class WebCalReport(Report):
holidays_calendar = Holidays(element, country)
date = datetime.date(year, 1, 1)
while date.year == year:
event_date = time.strptime('%d/%d/%d' % (date.year, date.month, date.day), '%Y/%m/%d')
holidays = holidays_calendar.check_date(date)
for text in holidays:
if text == "Easter": # TODO. Verify if this needs translation, and how
easter = _easter(year)
self.add_holiday_item(_("Easter"), easter[0], easter[1], easter[2])
elif text == "Daylight Saving begins": # TODO. Verify if this needs translation, and how
self.add_holiday_item(_("Easter"), easter.get_year(), easter.get_month(), easter.get_day())
elif text == "Daylight Saving begins":
# TODO. There is more than USA and Europe.
if Utils.xml_lang() == "en-US": # DST for United States of America
dst_start, dst_stop = _get_dst_start_stop(year)
@ -378,8 +376,7 @@ class WebCalReport(Report):
elif text == "Daylight Saving ends":
pass # end is already done above
else: # not easter, or Daylight Saving Time
# ???? Why do we need _(text)? Find out what is returned by holidays_calendar.check_date()
self.add_holiday_item(_(text), event_date[0], event_date[1], event_date[2])
self.add_holiday_item(text, date.year, date.month, date.day)
date = date.fromordinal( date.toordinal() + 1)
def add_holiday_item(self, text, year, month, day):
@ -441,9 +438,6 @@ class WebCalReport(Report):
# Add a link for year_glance() if requested
navs.append(('fullyear', _('Year Glance'), self.fullyear))
# add a link to blank_year() if requested
navs.append(('blankyear', _('Blank Calendar'), self.blankyear))
of.write('<div id="subnavigation">\n')
of.write('\t<ul>\n')
@ -568,7 +562,7 @@ class WebCalReport(Report):
def calendar_build(self, of, cal, year, month):
"""
This does the work of building the calendar
'cal' - one of "yg", "by", "wc"
'cal' - one of "yg", "wc"
'month' - month number 1, 2, .., 12
"""
@ -652,11 +646,11 @@ class WebCalReport(Report):
nweeks = len(monthinfo)
for week_row in range(0, nweeks):
week = monthinfo[week_row]
of.write('\t\t<tr class="week%d">\n' % (week_row+1))
# if you look this up in wikipedia, the first week is called week0
of.write('\t\t<tr class="week%d">\n' % week_row)
for day_col in range(0, 7):
dayclass = get_class_for_daycol(day_col)
hilightday = 'highlight ' + dayclass
day = week[day_col]
if day == 0: # a day in the previous or next month
@ -667,64 +661,61 @@ class WebCalReport(Report):
specday = firstweek_nextmonth[day_col]
specclass = "next " + dayclass
#if specclass[0] == 'p': # previous day of last month
# of.write('\t\t\t<td id="prevday%d" ' % specday)
#else: # next day of next month
# of.write('\t\t\t<td id="nextday%d" ' % specday)
of.write('\t\t\t<td class="%s">\n' % specclass)
of.write('\t\t\t\t<div class="date">%d</div>\n' % specday)
of.write('\t\t\t</td>\n')
else: # normal day number in current month
if cal == "by": # blank_year() doesn't need any highlighting or hyperlinks
of.write('\t\t\t<td id="%s%02d" class="%s">\n' % (shrt_month, day, dayclass))
of.write('\t\t\t\t<div class="date">%d</div>\n' % day)
of.write('\t\t\t</td>\n')
else:
thisday = datetime.date.fromordinal(current_ord)
of.write('\t\t\t<td id="%s%02d" ' % (shrt_month, day))
if thisday.month == month: # Something this month
holiday_list = self.holidays.get(month, {}).get(thisday.day, [])
bday_anniv_list = self.calendar.get(month, {}).get(thisday.day, [])
if (holiday_list > []) or (bday_anniv_list > []):
evt_date = time.strptime('%d/%d/%d' % (year, month, day), '%Y/%m/%d')
thisday = datetime.date.fromordinal(current_ord)
of.write('\t\t\t<td id="%s%02d" ' % (shrt_month, day))
if thisday.month == month: # Something this month
holiday_list = self.holidays.get(month, {}).get(thisday.day, [])
bday_anniv_list = self.calendar.get(month, {}).get(thisday.day, [])
if holiday_list > [] or bday_anniv_list > []:
# Year at a Glance
if cal == "yg":
did_some = self.one_day(of, year, evt_date, cal, holiday_list, bday_anniv_list)
if did_some:
# Notice the code in one_day(): cal_fname = '%s%d%s' % (shrt_month, day, self.ext)
# TODO. Create file for one_day()
# The HREF is relative to the year path.
fname = '%s%d%s' % (shrt_month, day, self.ext)
fname = '/'.join([lng_month, fname])
of.write('class="%s">\n' % hilightday)
of.write('\t\t\t\t<a id="%s%d" href="%s" title="%s%d">\n'
% (shrt_month, day, fname, shrt_month, day))
of.write('\t\t\t\t\t<div class="date">%d</div>\n' % day)
of.write('\t\t\t\t</a>\n')
else:
of.write('class="%s">\n' % dayclass)
of.write('\t\t\t\t<div class="date">%d</div>\n' % day)
hilightday = 'highlight ' + dayclass
# WebCal
elif cal == 'wc':
of.write('class="%s">\n' % hilightday)
of.write('\t\t\t\t<div class="date">%d</div>\n' % day)
self.one_day(of, year, evt_date, cal, holiday_list, bday_anniv_list)
# specify day class for this day
of.write('class="%s">\n' % hilightday)
# no holiday/ bday/ anniversary this day
else:
of.write('class="%s">\n' % dayclass)
# Year at a Glance
if cal == "yg":
# create yyyymmdd date string for
# "One Day" calendar pages filename
two_digit_month = '%02d' % month
two_digit_day = '%02d' % day
fname_date = str(year) + str(two_digit_month) + str(two_digit_day)
# create web link to corresponding "One Day" page...
# The HREF is relative to the year path.
fname_date = '/'.join([lng_month, fname_date])
fname_date += self.ext
of.write('\t\t\t\t<a href="%s" title="%s%d">\n'
% (fname_date, shrt_month, day))
of.write('\t\t\t\t\t<div class="date">%d</div>\n' % day)
of.write('\t\t\t\t</a>\n')
one_day_cal = "OneDay"
# WebCal
else:
one_day_cal = "WebCal"
of.write('\t\t\t\t<div class="date">%d</div>\n' % day)
# no holiday/ bday/ anniversary this month
evt_dte = _make_date(thisday.year, thisday.month, thisday.day)
self.one_day(of, evt_dte, one_day_cal, holiday_list, bday_anniv_list)
# no holiday/ bday/ anniversary this day
else:
of.write('class="%s">\n' % dayclass)
of.write('\t\t\t\t<div class="date">%d</div>\n' % day)
# close the day/ column
of.write('\t\t\t</td>\n')
# no holiday/ bday/ anniversary this month
else:
of.write('class="%s">\n' % dayclass)
of.write('\t\t\t\t<div class="date">%d</div>\n' % day)
# close the day/ column
of.write('\t\t\t</td>\n')
# change day number
current_ord += 1
@ -732,7 +723,7 @@ class WebCalReport(Report):
# close the week/ row
of.write('\t\t</tr>\n')
if cal in ("yg", "by"):
if cal == "yg":
# Fill up till we have 6 rows, so that the months align properly
for i in range(nweeks, 6):
of.write('\t\t<tr class="week%d">\n' % (i+1))
@ -839,156 +830,64 @@ class WebCalReport(Report):
def close_file(self, of):
of.close()
def one_day(self, of, year, event_date, cal, holiday_list, bday_anniv_list):
def one_day(self, of, evt_dte, one_day_cal, holiday_list, bday_anniv_list):
"""
This method creates the One Day page for "Year At A Glance"
'holiday_list' - list of holidays to display on this day
'bday_anniv_list' - list of birthdays and anniversaries to display on this day
one or both of these dictionaries will possibly hav something in it
'day_list' - a combination of both dictionaries to be able to create one day
date, text, event --- are necessary for figuring the age or years married
nyears, date, text, event --- are necessary for figuring the age or years married
for each year being created...
"""
# initialize day_list
day_list = []
# holiday on this day
if holiday_list > []:
for p in holiday_list:
for line in p.splitlines():
day_list.append((event_date, line, _('Holiday')))
# call day_list to fill
day_list = fill_day_list(evt_dte, holiday_list, bday_anniv_list)
# birthday/ anniversary on this day
if bday_anniv_list > []:
for date, text, event in bday_anniv_list:
# This is one_day in the year-at-a-glance calendar
if one_day_cal == "OneDay":
# '...' signifies an incomplete date for an event. See add_day_item()
txt_str = None
if date != '...':
years = year - date.year
# break up evt_dte to get year, month, day for this day
year = evt_dte.get_year()
month = evt_dte.get_month()
day = evt_dte.get_day()
# a birthday
if event == 'birthday':
if years == 1:
txt_str = _('%(short_name)s, <em>%(age)d</em> year old') % {
'short_name' : text,
'age' : years}
elif 2 <= years <= 105:
txt_str = _('%(short_name)s, <em>%(age)d</em> years old') % {
'short_name' : text,
'age' : years}
# create fname date string for "One Day" calendar pages filename
# using yyyymmdd for filename
two_digit_month = '%02d' % month
two_digit_day = '%02d' % day
fname_date = str(year) + str(two_digit_month) + str(two_digit_day)
# TODO. Think about this limit a bit more.
# if age is greater than 105,
# STOP! Do Nothing!!!
else:
txt_str = None
# define names for long month
lng_month = _get_long_month_name(month)
# an anniversary
elif event == 'anniversary':
# Name the file, and create it (see code in calendar_build)
fpath = os.path.join(str(year), lng_month)
of = self.create_file(fname_date, fpath)
# if married years is less than 76 years
if 1 <= years < 75:
txt_str = _('%(couple)s, <em>%(nyears)d</em> year anniversary') % {
'couple' : text,
'nyears' : years}
txt_str = '<span class="yearsmarried">%s</span>' % txt_str
nr_up = 2 # number of directory levels up to get to root
# TODO. Think about this limit a bit more.
# if married years is greater than 75 years,
# STOP! Do Nothing!!!
else:
txt_str = None
# set date display as in user prevferences
pg_date = _dd.display(evt_dte)
# incomplete date
else:
txt_str = None
self.calendar_common(of, nr_up, year, lng_month, _('One Day Within A Year'), pg_date)
if txt_str is not None:
day_list.append((date, txt_str, event))
of.write('\t<h3 id="OneDay">%s</h3>\n' % pg_date)
# something for this day
if day_list > []:
# for both "WebCal" and "One Day"
of.write('\t\t\t\t\t<ul>\n')
for nyears, date, text, event in day_list:
of.write('\t\t\t\t\t\t<li>%s</li>\n' % text)
of.write('\t\t\t\t\t</ul>\n')
if cal == 'yg':
# This is a one_day in the year-at-a-glance calendar
# slice up event_date to get year, month, and day
year, month, day = event_date[0], event_date[1], event_date[2]
# define names for long and short month
lng_month = _get_long_month_name(month)
shrt_month = _get_short_month_name(month)
# Name the file, and create it (see code in calendar_build)
cal_fname = '%s%d%s' % (shrt_month, day, self.ext)
fpath = os.path.join(str(year), lng_month)
of = self.create_file(cal_fname, fpath)
# set date display as in user prevferences
my_date = gen.lib.Date()
my_date.set_yr_mon_day(year, month, day)
my_date = _dd.display(my_date)
self.calendar_common(of, 2, year, lng_month, _('One Day Within A Year'), my_date)
of.write('\t<h3 id="OneDay">%s</h3>\n' % my_date)
of.write('\t<ul>\n')
for date, text, event in day_list:
of.write('\t\t<li>%s</li>\n' % text)
of.write('\t</ul>\n')
# Only close the file for "Year At A Glance"
if cal == 'yg':
self.write_footer(of, 2)
self.close_file(of)
# Let caller know we did output something.
return day_list > []
def blank_year(self, year):
"""
This method will create the Printable Full Year One Page Calendar...
"""
nr_up = 1 # Number of directory levels up to get to root
# Name the file, and create it
cal_fname = 'blankyear'
of = self.create_file(cal_fname, str(year))
# Page Title
if not self.multiyear:
title = ' '.join([str(year), _(' Blank Calendar')])
else:
title = _('Blank Calendar')
self.calendar_common(of, nr_up, year, 'blankyear', title, 'fullyear')
# generate progress pass for "Blank Year"
self.progress.set_pass(_('Creating Blank Year calendars'), self.end_month - self.start_month)
for month in range(self.start_month, self.end_month + 1):
# build the calendar
self.calendar_build(of, "by", year, month)
of.write('<tfoot>\n')
of.write('\t<tr><td colspan="7"></td></tr>\n')
of.write('</tfoot>\n')
of.write('</table>\n\n')
# increase progress bar
self.progress.step()
# Write footer and close file
self.write_footer(of, nr_up)
self.close_file(of)
# if calendar is one_day(), write footer, and close the file
if one_day_cal == "OneDay":
self.write_footer(of, nr_up)
self.close_file(of)
def year_glance(self, year):
"""
@ -1096,10 +995,6 @@ class WebCalReport(Report):
# create "WebCal" calendar pages
self.normal_cal(cal_year)
# create "Blank Year" calendar page
if self.blankyear:
self.blank_year(cal_year)
# create "Year At A Glance" and "One Day" calendar pages
if self.fullyear:
self.year_glance(cal_year)
@ -1127,10 +1022,6 @@ class WebCalReport(Report):
# create "WebCal" calendar pages
self.normal_cal(cal_year)
# create "Blank Year" calendar page
if self.blankyear:
self.blank_year(cal_year)
# create "Year At A Glance"
if self.fullyear:
self.year_glance(cal_year)
@ -1207,18 +1098,16 @@ class WebCalReport(Report):
if birth_ref:
birth_event = self.database.get_event_from_handle(birth_ref.ref)
birth_date = birth_event.get_date_object()
death_ref = person.get_death_ref()
death_date = None
if death_ref:
death_event = self.database.get_event_from_handle(death_ref.ref)
death_date = death_event.get_date_object()
# if person is dead, STOP! Nothing further to do
if death_date == None:
living = probably_alive(person, self.database, _make_date(this_year, 1, 1), 0)
# determine birthday information???
if self.birthday and birth_date is not None:
# determine if birthdadate is a valid date???
complete_date = False
if birth_date.is_valid():
complete_date = True
if complete_date:
# add birthday if requested
if self.birthday and birth_date != None and ((self.alive and living) or not self.alive):
year = birth_date.get_year()
month = birth_date.get_month()
day = birth_date.get_day()
@ -1243,48 +1132,50 @@ class WebCalReport(Report):
father_name = father.get_primary_name()
father_lastname = _get_regular_surname(sex, father_name)
short_name = _get_short_name(person, father_lastname)
# Huh? Why translate this?
alive = probably_alive(person, self.database, _make_date(this_year, month, day))
text = _('%(short_name)s') % {'short_name' : short_name}
self.add_day_item(text, year, month, day, 'birthday')
if ((self.alive and alive) or not self.alive):
self.add_day_item(text, year, month, day, 'Birthday')
# add anniversary if requested
if self.anniv and ((self.alive and living) or not self.alive):
for fhandle in family_list:
fam = self.database.get_family_from_handle(fhandle)
father_handle = fam.get_father_handle()
mother_handle = fam.get_mother_handle()
if father_handle == person.get_handle():
spouse_handle = mother_handle
else:
continue # with next person if this was the marriage event
if spouse_handle:
spouse = self.database.get_person_from_handle(spouse_handle)
if spouse:
death_ref = spouse.get_death_ref()
death_date = None
if death_ref:
death_event = self.database.get_event_from_handle(death_ref.ref)
death_date = death_event.get_date_object()
# add anniversary if requested
if self.anniv:
for fhandle in family_list:
fam = self.database.get_family_from_handle(fhandle)
father_handle = fam.get_father_handle()
mother_handle = fam.get_mother_handle()
if father_handle == person.get_handle():
spouse_handle = mother_handle
else:
continue # with next person if this was the marriage event
if spouse_handle:
spouse = self.database.get_person_from_handle(spouse_handle)
if spouse:
spouse_name = _get_short_name(spouse)
short_name = _get_short_name(person)
# if spouse is dead, STOP! Nothing more to do!
if death_date == None:
spouse_name = _get_short_name(spouse)
short_name = _get_short_name(person)
if self.alive:
if not probably_alive(spouse, self.database, _make_date(this_year, 1, 1), 0):
continue
are_married = _get_marrital_status(fam, self.database)
if are_married is not None:
for event_ref in fam.get_event_ref_list():
event = self.database.get_event_from_handle(event_ref.ref)
event_obj = event.get_date_object()
year = event_obj.get_year()
month = event_obj.get_month()
day = event_obj.get_day()
text = _('%(spouse)s and %(person)s') % {
'spouse' : spouse_name,
'person' : short_name}
self.add_day_item(text, year, month, day, 'anniversary')
are_married = get_marrital_status(fam, self.database)
if are_married is not None:
for event_ref in fam.get_event_ref_list():
event = self.database.get_event_from_handle(event_ref.ref)
event_obj = event.get_date_object()
year = event_obj.get_year()
month = event_obj.get_month()
day = event_obj.get_day()
# determine if anniversary date is a valid date???
complete_date = False
if event_obj.get_valid():
complete_date = True
if complete_date:
text = _('%(spouse)s and %(person)s') % {
'spouse' : spouse_name,
'person' : short_name}
alive1 = probably_alive(person, self.database, _make_date(this_year, month, day))
alive2 = probably_alive(spouse, self.database, _make_date(this_year, month, day))
if ((self.alive and alive1 and alive2) or not self.alive):
self.add_day_item(text, year, month, day, 'Anniversary')
#------------------------------------------------------------------------
#
@ -1399,10 +1290,6 @@ class WebCalOptions(MenuReportOptions):
fullyear.set_help(_('Whether to create A one-page mini calendar with dates highlighted'))
menu.add_option(category_name, 'fullyear', fullyear)
blankyear = BooleanOption(_('Create "Printable Blank" Calendar(s)'), False)
blankyear.set_help(_('Whether to create A Full Year Printable calendar'))
menu.add_option(category_name, 'blankyear', blankyear)
country = EnumeratedListOption(_('Country for holidays'), 0 )
for index, item in enumerate(_COUNTRIES):
country.add_item(index, item)
@ -1798,8 +1685,7 @@ def _easter(year):
l = i - j
month = 3 + (l + 40) / 44
day = l + 28 - 31 * (month / 4)
date = time.strptime('%d/%d/%d' % (year, month, day), '%Y/%m/%d')
return date
return _make_date(year, month, day)
def _get_dst_start_stop(year, area="us"):
"""
@ -1808,27 +1694,15 @@ def _get_dst_start_stop(year, area="us"):
"""
if area == "us":
if year > 2006:
month = 3 # March
day = (14 - (math.floor(1 + year * 5 / 4) % 7))
start = time.strptime('%d/%d/%d' % (year, month, day), '%Y/%m/%d')
month = 11 # November
day = (7 - (math.floor(1 + year * 5 / 4) % 7))
stop = time.strptime('%d/%d/%d' % (year, month, day), '%Y/%m/%d')
start = "%d/%d/%d" % (year, 3, 14 - (math.floor(1 + year * 5 / 4) % 7)) # March
stop = "%d/%d/%d" % (year, 11, 7 - (math.floor(1 + year * 5 / 4) % 7)) # November
else:
month = 4 # April
day = (2 + 6 * year - math.floor(year / 4) % 7 + 1)
start = time.strptime('%d/%d/%d' % (year, month, day), '%Y/%m/%d')
month = 10 # October
day = (31 - (math.floor(year * 5 / 4) + 1) % 7)
stop = time.strptime('%d/%d/%d' % (year, month, day), '%Y/%m/%d')
start = "%d/%d/%d" % (year, 4, (2 + 6 * year - math.floor(year / 4)) % 7 + 1) # April
stop = "%d/%d/%d" % (year, 10, (31 - (math.floor(year * 5 / 4) + 1) % 7)) # October
elif area == "eu":
month = 3 # March
day = (31 - (math.floor(year * 5 / 4) + 4) % 7)
start = time.strptime('%d/%d/%d' % (year, month, day), '%Y/%m/%d')
month = 10 # October
day = (31 - (math.floor(year * 5 / 4) + 1) % 7)
stop = time.strptime('%d/%d/%d' % (year, month, day), '%Y/%m/%d')
return start, stop
start = "%d/%d/%d" % (year, 3, (31 - (math.floor(year * 5 / 4) + 4) % 7)) # March
stop = "%d/%d/%d" % (year, 10, (31 - (math.floor(year * 5 / 4) + 1) % 7)) # Oct
return (start, stop)
def _get_regular_surname(sex, name):
"""
@ -1923,6 +1797,100 @@ def _get_long_month_name(month):
def _get_short_month_name(month):
return _shrt_month[month]
def fill_day_list(evt_dte, holiday_list, bday_anniv_list):
"""
Will fill day_list and return it to its caller one_day()
holiday_list, or bday_anniv_list -- will always have something in it...
evt_dte -- date for this day_list
'day_list' - a combination of both dictionaries to be able to create one day
nyears, date, text, event --- are necessary for figuring the age or years married
for each year being created...
"""
# initialize day_list
day_list = []
# holiday on this day
if holiday_list > []:
# will force holidays to be first in the list
nyears = 0
for p in holiday_list:
for line in p.splitlines():
day_list.append((nyears, evt_dte, line, _('Holiday')))
# birthday/ anniversary on this day
if bday_anniv_list > []:
for text, event, date in bday_anniv_list:
# '...' signifies an incomplete date for an event. See add_day_item()
txt_str = None
if date != '...':
# number of years married, ex: 10
nyears = evt_dte.get_year() - date.get_year()
# number of years for birthday, ex: 10 years
age_str = evt_dte - date
age_str.format(precision=1)
# a birthday
if event == 'Birthday':
if nyears == 0:
txt_str = _('%(person)s, <em>birth</em>') % {
'person' : text}
else:
txt_str = _('%(person)s, <em>%(age)s</em> old') % {
'person' : text,
'age' : age_str}
# an anniversary
elif event == 'Anniversary':
if nyears == 0:
txt_str = _('%(couple)s, <em>wedding</em>') % {
'couple' : text}
else:
txt_str = _('%(couple)s, <em>%(years)d</em> year anniversary') % {
'couple' : text,
'years' : nyears}
txt_str = '<span class="yearsmarried">%s</span>' % txt_str
if txt_str is not None:
day_list.append((nyears, date, txt_str, event))
# if there is more than one event on any given date, sort them based on years
# for birthdays and anniversaries.
# holidays will always appear first in the list.
if len(day_list) > 1:
day_list.sort()
return day_list
def get_marrital_status(family, db):
"""
Returns the marital status of two people, a couple
are_married will either be the marriage event or None if not married anymore
"""
are_married = None
for event_ref in family.get_event_ref_list():
event = db.get_event_from_handle(event_ref.ref)
if event.type in [gen.lib.EventType.MARRIAGE,
gen.lib.EventType.MARR_ALT]:
are_married = event
elif event.type in [gen.lib.EventType.DIVORCE,
gen.lib.EventType.ANNULMENT,
gen.lib.EventType.DIV_FILING]:
are_married = None
return are_married
#-------------------------------------------------------------------------
#
#