A bunch of miscelaneous corrections.

- variable names
- added several notes about things todo
- replaced store_file() with copy_file() from NarrativeWeb
- and more
	* src/plugins/WebCal.py


svn: r10873
This commit is contained in:
Kees Bakker 2008-07-17 14:48:54 +00:00
parent 6d67535bf9
commit a6a264d1ce

View File

@ -85,7 +85,7 @@ from PluginUtils import FilterOption, EnumeratedListOption, PersonOption, \
BooleanOption, NumberOption, StringOption, DestinationOption
import Utils
import GrampsLocale
from QuestionDialog import ErrorDialog
from QuestionDialog import ErrorDialog, WarningDialog
from Utils import probably_alive
from DateHandler import displayer as _dd
from DateHandler import parser as _dp
@ -110,6 +110,7 @@ _CSS_FILES = [
]
_CHARACTER_SETS = [
# First is used as default selection.
[_('Unicode (recommended)'), 'utf-8'],
['ISO-8859-1', 'iso-8859-1' ],
['ISO-8859-2', 'iso-8859-2' ],
@ -128,41 +129,49 @@ _CHARACTER_SETS = [
]
_CC = [
'',
'<a rel="license" href="http://creativecommons.org/licenses/by/2.5/">'
'<img alt="Creative Commons License - By attribution" title="Creative '
'Commons License - By attribution" ',
'<img alt="Creative Commons License - By attribution" '
'title="Creative Commons License - By attribution" '
'src="%(gif_fname)s" /></a>',
'<a rel="license" href="http://creativecommons.org/licenses/by-nd/2.5/">'
'<img alt="Creative Commons License - By attribution, No derivations" '
'title="Creative Commons License - By attribution, No derivations" ',
'title="Creative Commons License - By attribution, No derivations" '
'src="%(gif_fname)s" /></a>',
'<a rel="license" href="http://creativecommons.org/licenses/by-sa/2.5/">'
'<img alt="Creative Commons License - By attribution, Share-alike" '
'title="Creative Commons License - By attribution, Share-alike" ',
'title="Creative Commons License - By attribution, Share-alike" '
'src="%(gif_fname)s" /></a>',
'<a rel="license" href="http://creativecommons.org/licenses/by-nc/2.5/">'
'<img alt="Creative Commons License - By attribution, Non-commercial" '
'title="Creative Commons License - By attribution, Non-commercial" ',
'title="Creative Commons License - By attribution, Non-commercial" '
'src="%(gif_fname)s" /></a>',
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/2.5/">'
'<img alt="Creative Commons License - By attribution, Non-commercial, No '
'derivations" title="Creative Commons License - By attribution, '
'Non-commercial, No derivations" ',
'<img alt="Creative Commons License - By attribution, Non-commercial, No derivations" '
'title="Creative Commons License - By attribution, Non-commercial, No derivations" '
'src="%(gif_fname)s" /></a>',
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/">'
'<img alt="Creative Commons License - By attribution, Non-commerical, '
'Share-alike" title="Creative Commons License - By attribution, '
'Non-commerical, Share-alike" '
'<img alt="Creative Commons License - By attribution, Non-commerical, Share-alike" '
'title="Creative Commons License - By attribution, Non-commerical, Share-alike" '
'src="%(gif_fname)s" /></a>'
]
_COPY_OPTIONS = [
_('Standard copyright'),
_('Creative Commons - By attribution'),
_('Creative Commons - By attribution, No derivations'),
_('Creative Commons - By attribution, Share-alike'),
_('Creative Commons - By attribution, Non-commercial'),
_('Creative Commons - By attribution, Non-commercial, No derivations'),
_('Creative Commons - By attribution, Non-commercial, Share-alike'),
_('No copyright notice'),
]
@ -197,40 +206,51 @@ class WebCalReport(Report):
self.copy = menu.get_option_by_name('cright').get_value()
self.encoding = menu.get_option_by_name('encoding').get_value()
self.css = menu.get_option_by_name('css').get_value()
self.Country = menu.get_option_by_name('country').get_value()
self.Year = menu.get_option_by_name('year').get_value()
self.country = menu.get_option_by_name('country').get_value()
self.year = menu.get_option_by_name('year').get_value()
self.fullyear = menu.get_option_by_name('fullyear').get_value()
self.blankyear = menu.get_option_by_name('blankyear').get_value()
self.Surname = menu.get_option_by_name('surname').get_value()
self.Alive = menu.get_option_by_name('alive').get_value()
self.Birthday = menu.get_option_by_name('birthdays').get_value()
self.Anniv = menu.get_option_by_name('anniversaries').get_value()
self.Title_text = menu.get_option_by_name('title').get_value()
self.Home_link = menu.get_option_by_name('home_link').get_value()
self.surname = menu.get_option_by_name('surname').get_value()
self.alive = menu.get_option_by_name('alive').get_value()
self.birthday = menu.get_option_by_name('birthdays').get_value()
self.anniv = menu.get_option_by_name('anniversaries').get_value()
self.title_text = menu.get_option_by_name('title').get_value()
self.home_link = menu.get_option_by_name('home_link').get_value()
self.Note = [ menu.get_option_by_name('note_jan').get_value(),
menu.get_option_by_name('note_feb').get_value(),
menu.get_option_by_name('note_mar').get_value(),
menu.get_option_by_name('note_apr').get_value(),
menu.get_option_by_name('note_may').get_value(),
menu.get_option_by_name('note_jun').get_value(),
menu.get_option_by_name('note_jul').get_value(),
menu.get_option_by_name('note_aug').get_value(),
menu.get_option_by_name('note_sep').get_value(),
menu.get_option_by_name('note_oct').get_value(),
menu.get_option_by_name('note_nov').get_value(),
menu.get_option_by_name('note_dec').get_value()]
self.month_notes = [menu.get_option_by_name('note_jan').get_value(),
menu.get_option_by_name('note_feb').get_value(),
menu.get_option_by_name('note_mar').get_value(),
menu.get_option_by_name('note_apr').get_value(),
menu.get_option_by_name('note_may').get_value(),
menu.get_option_by_name('note_jun').get_value(),
menu.get_option_by_name('note_jul').get_value(),
menu.get_option_by_name('note_aug').get_value(),
menu.get_option_by_name('note_sep').get_value(),
menu.get_option_by_name('note_oct').get_value(),
menu.get_option_by_name('note_nov').get_value(),
menu.get_option_by_name('note_dec').get_value()]
def store_file(self, from_path, to_path):
self.warn_dir = True # Only give warning once.
def copy_file(self, from_fname, to_fname, to_dir=''):
"""
Store the file in the destination.
Copy a file from a source to a (report) destination.
If to_dir is not present and if the target is not an archive,
then the destination directory will be created.
Normally 'to_fname' will be just a filename, without directory path.
'to_dir' is the relative path name in the destination root. It will
be prepended before 'to_fname'.
"""
dest = os.path.join(self.html_dir, to_path)
dirname = os.path.dirname(dest)
if not os.path.isdir(dirname):
os.makedirs(dirname)
if from_path != dest:
shutil.copyfile(from_path, dest)
dest = os.path.join(self.html_dir, to_dir, to_fname)
destdir = os.path.dirname(dest)
if not os.path.isdir(destdir):
os.makedirs(destdir)
if from_fname != dest:
shutil.copyfile(from_fname, dest)
elif self.warn_dir:
WarningDialog(
_("Possible destination error") + "\n" +
@ -242,7 +262,7 @@ class WebCalReport(Report):
"web pages."))
self.warn_dir = False
# code snippets for east and Daylight saving start/ stop
# code snippets for Easter and Daylight saving start/ stop
# are borrowed from Calendar.py
def easter(self):
@ -252,7 +272,7 @@ class WebCalReport(Report):
to the Astronomical Almanac", ed. P. K. Seidelmann (1992). Note:
Ash Wednesday is 46 days before Easter Sunday.
"""
year = self.Year
year = self.year
c = year / 100
n = year - 19 * (year / 19)
k = (c - 17) / 25
@ -272,7 +292,7 @@ class WebCalReport(Report):
Return Daylight Saving Time start/stop in a given area ("us", "eu").
US calculation valid 1976-2099; EU 1996-2099
"""
year = self.Year
year = self.year
if area == "us":
if year > 2006:
start = (year, 3, 14 - (math.floor(1 + year * 5 / 4) % 7)) # March
@ -329,7 +349,7 @@ class WebCalReport(Report):
User directory is first choice if it exists, and does not use both holiday files any longer
"""
year = self.Year
year = self.year
holiday_file = 'holidays.xml'
holiday_full_path = ""
fname1 = os.path.join(const.USER_PLUGINS, holiday_file)
@ -344,13 +364,13 @@ class WebCalReport(Report):
def process_holiday_file(self, filename, country):
""" This will process a holiday file """
year = self.Year
year = self.year
parser = Xml2Obj()
element = parser.Parse(filename)
calendar = Holidays(element, country)
mycalendar = Holidays(element, country)
date = datetime.date(year, 1, 1)
while date.year == year:
holidays = calendar.check_date( date )
holidays = mycalendar.check_date( date )
for text in holidays:
if text == "Easter":
date1 = self.easter()
@ -376,26 +396,22 @@ class WebCalReport(Report):
# Copy the _CALENDARSCREEN css
if self.css != "":
from_file = os.path.join(const.DATA_DIR, self.css)
to_file = os.path.join("styles/", _CALENDARSCREEN)
self.store_file(from_file, to_file)
self.copy_file(from_file, _CALENDARSCREEN, "styles")
# copy calendar-print stylesheet
from_file = os.path.join(const.DATA_DIR, "Web_Print-Default.css")
to_file = os.path.join("styles/", _CALENDARPRINT)
self.store_file(from_file, to_file)
self.copy_file(from_file, _CALENDARPRINT, "styles")
# Copy GRAMPS favicon to target
from_file = os.path.join(const.IMAGE_DIR, "favicon.ico")
to_file = os.path.join("images/", "favicon.ico")
self.store_file(from_file, to_file)
self.copy_file(from_file, "favicon.ico", "images")
# Copy arrow image if "Year At A Glance" is requested,
# and if the file exists
if self.fullyear:
from_file = os.path.join(const.IMAGE_DIR, "arrow102.gif")
if os.path.exists(from_file):
to_file = os.path.join("images/", "arrow102.gif")
self.store_file(from_file, to_file)
self.copy_file(from_file, "arrow102.gif", "images")
def display_nav_links(self, of, currentsection, cal):
@ -418,13 +434,13 @@ class WebCalReport(Report):
]
for url_fname, nav_text, cond in navs:
if cond:
new_dir = str(self.Year) + '/'
new_dir = str(self.year)
if ((cal == "yg") or (cal == "by")):
url = self.subdirs("yg", new_dir, url_fname)
url = _subdirs("yg", new_dir, url_fname)
elif cal == "ip":
url = self.subdirs("ip", new_dir, url_fname)
url = _subdirs("ip", new_dir, url_fname)
else:
url = self.subdirs("wc", new_dir, url_fname)
url = _subdirs("wc", new_dir, url_fname)
url += self.ext
self.display_nav_link(of, url, nav_text, currentsection)
@ -443,7 +459,7 @@ class WebCalReport(Report):
This does the work of building the calendar
"""
year = self.Year
year = self.year
# Begin calendar head
title = GrampsLocale.long_months[month]
@ -537,8 +553,8 @@ class WebCalReport(Report):
of.write(' <td id="day%d" ' % day)
thisday = current_date.fromordinal(current_ord)
if thisday.month == month: # Something this month
list = self.calendar.get(month, {}).get(thisday.day, {})
if ((thisday.day == day) and (list > [])):
list_ = self.calendar.get(month, {}).get(thisday.day, {})
if ((thisday.day == day) and (list_ > [])):
specclass = "highlight " + dayclass
of.write('class="%s">\n' % specclass)
if cal == "yg": # Year at a Glance
@ -548,12 +564,12 @@ class WebCalReport(Report):
% (lng_month, shrt_month, day, self.ext))
of.write(' <div class="date">%d'
'</div></a>\n' % day)
self.indiv_date(month, day, list)
self.indiv_date(month, day, list_)
else: # WebCal
of.write(' <div class="date">%d'
'</div>\n' % day)
of.write(' <ul>\n')
for p in list:
for p in list_:
lines = p.count("\n") + 1 # lines in the text
for line in p.split("\n"):
of.write(' <li>')
@ -598,17 +614,17 @@ class WebCalReport(Report):
if ((cal == "yg") or (cal == "by")): # year glance and blank_year
# have same directory levels
fname1 = self.subdirs("yg", "styles/", _CALENDARSCREEN)
fname2 = self.subdirs("yg", "styles/", _CALENDARPRINT)
fname3 = self.subdirs("yg", "images/", "favicon.ico")
fname1 = _subdirs("yg", "styles", _CALENDARSCREEN)
fname2 = _subdirs("yg", "styles", _CALENDARPRINT)
fname3 = _subdirs("yg", "images", "favicon.ico")
elif cal == "ip":
fname1 = self.subdirs("ip", "styles/", _CALENDARSCREEN)
fname2 = self.subdirs("ip", "styles/", _CALENDARPRINT)
fname3 = self.subdirs("ip", "images/", "favicon.ico")
fname1 = _subdirs("ip", "styles", _CALENDARSCREEN)
fname2 = _subdirs("ip", "styles", _CALENDARPRINT)
fname3 = _subdirs("ip", "images", "favicon.ico")
else:
fname1 = self.subdirs("wc", "styles/", _CALENDARSCREEN)
fname2 = self.subdirs("wc", "styles/", _CALENDARPRINT)
fname3 = self.subdirs("wc", "images/", "favicon.ico")
fname1 = _subdirs("wc", "styles", _CALENDARSCREEN)
fname2 = _subdirs("wc", "styles", _CALENDARPRINT)
fname3 = _subdirs("wc", "images", "favicon.ico")
# link to calendar-screen css
of.write(' <link href="%s" rel="stylesheet" type="text/css" media="screen" />\n' % fname1)
@ -646,18 +662,22 @@ class WebCalReport(Report):
of.write(' <p id="createdate">%s</p>\n' % msg)
# copyright license
if ((cal == "yg") or (cal == "by")):
fname = self.subdirs("yg", "images/", "somerights20.gif")
if cal == "yg" or cal == "by":
to_urldir = os.path.join("yg", "images")
to_dir = os.path.join("yg", "images")
elif cal == "ip":
fname = self.subdirs("ip", "images/", "somerights20.gif")
to_urldir = os.path.join("ip", "images")
to_dir = os.path.join("ip", "images")
else:
fname = self.subdirs("wc", "images/", "somerights20.gif")
if self.copy > 0 and self.copy <= 6:
text = _CC[self.copy-1]
text += 'src="%s"></a>' % fname
from_file = os.path.join(const.IMAGE_DIR,"somerights20.gif")
to_file = os.path.join("images/", "somerights20.gif")
self.store_file(from_file, to_file)
to_urldir = os.path.join("wc", "images")
to_dir = os.path.join("wc", "images")
if self.copy > 0 and self.copy < len(_CC):
text = _CC[self.copy]
fname = os.path.join(to_urldir, "somerights20.gif")
text = text % {'gif_fname' : fname}
from_file = os.path.join(const.IMAGE_DIR, "somerights20.gif")
self.copy_file(from_file, "somerights20.gif", to_dir)
else:
text = "&copy; %s %s" % (time.localtime()[0], author)
of.write(' <p id="copyright">%s</p>\n' % text)
@ -670,18 +690,19 @@ class WebCalReport(Report):
def create_file(self, name):
page_name = os.path.join(self.html_dir, name)
of = codecs.EncodedFile(open(page_name, "w"),'utf-8',self.encoding,'xmlcharrefreplace')
of = codecs.EncodedFile(open(page_name, "w"), 'utf-8', self.encoding, 'xmlcharrefreplace')
return of
def close_file(self, of):
of.close()
def indiv_date(self, month, day_num, list):
def indiv_date(self, month, day_num, list_):
"""
This method creates the indiv pages for "Year At A Glance"
"""
year = self.Year
# TODO. Cleanup the "/" for URLs versus file names.
year = self.year
dest_dir = self.html_dir + "/images"
arrow = os.path.join(dest_dir, "arrow102.gif")
@ -717,6 +738,8 @@ class WebCalReport(Report):
</style>
"""
# TODO. Merge this with code from blank_year(), year_glance(), print_page()
# Add Header to calendar
title = "%d %s %d" % (day_num, lng_month, year)
(ip, author) = self.write_header(ip, title, "ip", mystyle)
@ -727,16 +750,16 @@ class WebCalReport(Report):
ip.write(' <div id="GRAMPSinfo">\n')
msg = 'Created for %s' % author
ip.write(' %s</div>\n' % msg)
ip.write(' <h1 id="SiteTitle">A Peak into One Day</h1>\n')
ip.write(' <h1 id="SiteTitle">A Peak into One Day</h1>\n')
ip.write(' </div>\n')
# Create navigation menu
ip.write(' <div id="navigation">\n')
ip.write(' <ul>\n')
if self.Home_link.strip() != '':
if self.home_link.strip() != '':
ip.write(' <li>')
ip.write('<a href="%s">HOME</a></li>\n' % self.Home_link)
ip.write('<a href="%s">HOME</a></li>\n' % self.home_link)
title = GrampsLocale.short_months[month]
self.display_nav_links(ip, title, "ip")
@ -753,7 +776,7 @@ class WebCalReport(Report):
ip.write(' <ul id="arrow">\n')
else:
ip.write(' <ul>\n')
for p in list:
for p in list_:
lines = p.count("\n") + 1 # lines in the text
for line in p.split("\n"):
ip.write(' <li>')
@ -788,7 +811,7 @@ class WebCalReport(Report):
This method will create the Printable Full Year One Page Calendar...
"""
year = self.Year
year = self.year
# if year dir doesn't exist, create it
new_dir = self.html_dir + "/%d" % year
if not os.path.isdir(new_dir):
@ -814,6 +837,8 @@ class WebCalReport(Report):
</style>
"""
# TODO. See note in indiv_date()
# Add header to page
title = str(year) + "Blank Calendar"
(by, author) = self.write_header(by, title, "by", mystyle)
@ -833,9 +858,9 @@ class WebCalReport(Report):
by.write(' <div id="navigation">\n')
by.write(' <ul>\n')
if self.Home_link.strip() != '':
if self.home_link.strip() != '':
by.write(' <li>')
by.write('<a href="%s">HOME</a></li>\n' % self.Home_link)
by.write('<a href="%s">HOME</a></li>\n' % self.home_link)
self.display_nav_links(by, 'Blank Calendar', "by")
@ -864,7 +889,7 @@ class WebCalReport(Report):
This method will create the Full Year At A Glance Page...
"""
year = self.Year
year = self.year
# if year dir doesn't exist, create it
new_dir = self.html_dir + "/%d/" % year
if not os.path.isdir(new_dir):
@ -910,6 +935,8 @@ class WebCalReport(Report):
</style>
"""
# TODO. See note in indiv_date()
# Add header to page
title = "%d, At A Glance" % year
(yg, author) = self.write_header(yg, title, "yg", mystyle)
@ -929,9 +956,9 @@ class WebCalReport(Report):
yg.write(' <div id="navigation">\n')
yg.write(' <ul>\n')
if self.Home_link.strip() != '':
if self.home_link.strip() != '':
yg.write(' <li>')
yg.write('<a href="%s">HOME</a></li>\n' % self.Home_link)
yg.write('<a href="%s">HOME</a></li>\n' % self.home_link)
self.display_nav_links(yg, 'Year Glance', "yg")
@ -958,13 +985,12 @@ class WebCalReport(Report):
yg.write(' </tbody>\n')
# create note section for each calendar month
note = self.month_notes[month-1].strip()
note = note or "&nbsp;"
yg.write(' <tfoot>\n')
yg.write(' <tr>\n')
yg.write(' <td class="note" colspan="7">\n')
if self.Note[month-1].strip() != '':
yg.write(' %s\n' % self.Note[month-1])
else:
yg.write(' &nbsp;\n')
yg.write(' %s\n' % note)
yg.write(' </td>\n')
yg.write(' </tr>\n')
yg.write(' </tfoot>\n')
@ -980,7 +1006,7 @@ class WebCalReport(Report):
parent_dir = os.path.dirname(self.html_dir)
if not os.path.isdir(parent_dir):
ErrorDialog(_("Neither %s nor %s are directories") % \
(self.html_dir,parent_dir))
(self.html_dir, parent_dir))
return
else:
try:
@ -996,21 +1022,21 @@ class WebCalReport(Report):
# initialize the dict to fill:
self.calendar = {}
self.progress = Utils.ProgressMeter(_("Generate XHTML Calendars"),'')
self.progress = Utils.ProgressMeter(_("Generate XHTML Calendars"), '')
# Generate the CSS file
self.copy_css()
# get the information, first from holidays:
if self.Country != 0: # Don't include holidays
self.get_holidays(_COUNTRIES[self.Country]) # _country is currently global
self.progress.set_pass(_("Getting information from holidays file"),'')
if self.country != 0: # Don't include holidays
self.get_holidays(_COUNTRIES[self.country]) # _country is currently global
self.progress.set_pass(_("Getting information from holidays file"), '')
# get data from database:
self.collect_data()
# generate the report:
self.progress.set_pass(_("Creating Calendar pages"),12)
self.progress.set_pass(_("Creating Calendar pages"), 12)
for month in range(1, 13):
self.progress.step()
@ -1025,31 +1051,12 @@ class WebCalReport(Report):
# Close the progress meter
self.progress.close()
def subdirs(self, cal, dir, name):
"""
his will add the number of subdirs to the filename depending on which
calendar is being called
"wc" = WebCal
yg = Year At A Glance
by = Printable Pocket Calendar
ip = Indiv Pages
"""
if cal == "wc":
subdirs = '.././'
elif ((cal == "yg") or (cal == "by")):
subdirs = '.././'
else:
subdirs = '../.././'
fname = subdirs + '%s%s' % (dir, name)
return fname
def print_page(self, month):
"""
This method provides information and header/ footer to the calendar month
"""
year = self.Year
year = self.year
# if year dir doesn't exist, create it
new_dir = self.html_dir + "/%d" % year
if not os.path.isdir(new_dir):
@ -1070,8 +1077,10 @@ class WebCalReport(Report):
</style>
"""
# TODO. See note in indiv_date()
# Add Header to calendar
(of, author) = self.write_header(of, self.Title_text, "of", mystyle)
of, author = self.write_header(of, self.title_text, "of", mystyle)
of.write('<body id="WebCal">\n') # terminated in write_footer
@ -1081,7 +1090,7 @@ class WebCalReport(Report):
of.write(' <div id="GRAMPSinfo">\n')
msg = 'Created for %s' % author
of.write(' %s</div>\n' % msg)
of.write(' <h1 id="SiteTitle">%s</h1>\n' % self.Title_text)
of.write(' <h1 id="SiteTitle">%s</h1>\n' % self.title_text)
of.write(' <h1>%d</h1>\n' % year)
of.write(' </div>\n') # end header
@ -1089,9 +1098,9 @@ class WebCalReport(Report):
of.write(' <div id="navigation">\n')
of.write(' <ul>\n')
if self.Home_link.strip() != '':
if self.home_link.strip() != '':
of.write(' <li>')
of.write('<a href="%s">HOME</a></li>\n' % self.Home_link)
of.write('<a href="%s">HOME</a></li>\n' % self.home_link)
highlight = GrampsLocale.short_months[month]
self.display_nav_links(of, highlight, "wc")
@ -1112,14 +1121,11 @@ class WebCalReport(Report):
of.write(' </tbody>\n')
# create note section for "WebCal"
note = self.month_notes[month-1].strip()
note = note or "&nbsp;"
of.write(' <tfoot>\n')
of.write(' <tr>\n')
of.write(' <td class="note" colspan="7">')
if self.Note[month-1].strip() != '':
of.write(self.Note[month-1])
else:
of.write("&nbsp;")
of.write('</td>\n')
of.write(' <td class="note" colspan="7">%s</td>\n' % note)
of.write(' </tr>\n')
of.write(' </tfoot>\n')
of.write(' </table>\n\n')
@ -1133,10 +1139,10 @@ class WebCalReport(Report):
This method runs through the data, and collects the relevant dates
and text.
"""
self.progress.set_pass(_("Filtering"),'')
self.progress.set_pass(_("Filtering"), '')
people = self.filter.apply(self.database,
self.database.get_person_handles(sort_handles=False))
self.progress.set_pass(_("Reading database"),len(people))
self.progress.set_pass(_("Reading database"), len(people))
for person_handle in people:
self.progress.step()
person = self.database.get_person_from_handle(person_handle)
@ -1145,15 +1151,15 @@ class WebCalReport(Report):
if birth_ref:
birth_event = self.database.get_event_from_handle(birth_ref.ref)
birth_date = birth_event.get_date_object()
living = probably_alive(person, self.database, make_date(self.Year, 1, 1), 0)
if self.Birthday and birth_date != None and ((self.Alive and living) or not self.Alive):
living = probably_alive(person, self.database, make_date(self.year, 1, 1), 0)
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()
age = self.Year - year
age = self.year - year
# add some things to handle maiden name:
father_lastname = None # husband, actually
if self.Surname == 0: # get husband's last name:
if self.surname == 0: # get husband's last name:
if person.get_gender() == gen.lib.Person.FEMALE:
family_list = person.get_family_handle_list()
if len(family_list) > 0:
@ -1168,13 +1174,14 @@ class WebCalReport(Report):
father_lastname = father.get_primary_name().get_surname()
short_name = self.get_short_name(person, father_lastname)
if age == 0: # person is 0 years old, display nothing
text= ""
text = ""
elif age == 1: # person is 1, and therefore display it correctly
text= '%s, <em>%d</em> year old' % (short_name, age)
# TODO. Make this translatable
text = '%s, <em>%d</em> year old' % (short_name, age)
else:
text= '%s, <em>%d</em> years old' % (short_name, age)
text = '%s, <em>%d</em> years old' % (short_name, age)
self.add_day_item(text, year, month, day)
if self.Anniv and ((self.Alive and living) or not self.Alive):
if self.anniv and ((self.alive and living) or not self.alive):
family_list = person.get_family_handle_list()
for fhandle in family_list:
fam = self.database.get_family_from_handle(fhandle)
@ -1189,8 +1196,8 @@ class WebCalReport(Report):
if spouse:
spouse_name = self.get_short_name(spouse)
short_name = self.get_short_name(person)
if self.Alive:
if not probably_alive(spouse, self.database, make_date(self.Year, 1, 1), 0):
if self.alive:
if not probably_alive(spouse, self.database, make_date(self.year, 1, 1), 0):
continue
married = True
for event_ref in fam.get_event_ref_list():
@ -1206,7 +1213,7 @@ class WebCalReport(Report):
year = event_obj.get_year()
month = event_obj.get_month()
day = event_obj.get_day()
years = self.Year - year
years = self.year - year
if years == 0:
text = "" # zero year anniversary
# display nothing
@ -1249,7 +1256,7 @@ class WebCalOptions(MenuReportOptions):
category_name = _("Report Options")
target = DestinationOption( _("Destination"),
os.path.join(const.USER_HOME,"WEBCAL"))
os.path.join(const.USER_HOME, "WEBCAL"))
target.set_help( _("The destination directory for the web files"))
target.set_directory_entry(True)
menu.add_option(category_name, "target", target)
@ -1285,7 +1292,7 @@ class WebCalOptions(MenuReportOptions):
cright.set_help( _("The copyright to be used for the web files"))
menu.add_option(category_name, "cright", cright)
encoding = EnumeratedListOption(_('Character set encoding'), 'utf-8' )
encoding = EnumeratedListOption(_('Character set encoding'), _CHARACTER_SETS[0][1])
for eopt in _CHARACTER_SETS:
encoding.add_item(eopt[1], eopt[0])
encoding.set_help( _("The encoding to be used for the web files"))
@ -1431,7 +1438,7 @@ class WebCalOptions(MenuReportOptions):
#------------------------------------------------------------------------
class Element:
""" A parsed XML element """
def __init__(self, name,attributes):
def __init__(self, name, attributes):
'Element constructor'
# The element's tag name
self.name = name
@ -1442,11 +1449,11 @@ class Element:
# The element's child element list (sequence)
self.children = []
def AddChild(self,element):
def addChild(self, element):
'Add a reference to a child element'
self.children.append(element)
def getAttribute(self,key):
def getAttribute(self, key):
'Get an attribute value'
return self.attributes.get(key)
@ -1488,14 +1495,14 @@ class Xml2Obj:
self.root = None
self.nodeStack = []
def StartElement(self, name,attributes):
def StartElement(self, name, attributes):
'SAX start element even handler'
# Instantiate an Element object
element = Element(name.encode(),attributes)
element = Element(name.encode(), attributes)
# Push element onto the stack and make it a child of parent
if len(self.nodeStack) > 0:
parent = self.nodeStack[-1]
parent.AddChild(element)
parent.addChild(element)
else:
self.root = element
self.nodeStack.append(element)
@ -1504,7 +1511,7 @@ class Xml2Obj:
'SAX end element event handler'
self.nodeStack = self.nodeStack[:-1]
def CharacterData(self,data):
def CharacterData(self, data):
'SAX character data event handler'
if data.strip():
data = data.encode()
@ -1512,7 +1519,7 @@ class Xml2Obj:
element.cdata += data
return
def Parse(self,filename):
def Parse(self, filename):
# Create a SAX parser
Parser = expat.ParserCreate()
# SAX event handlers
@ -1520,7 +1527,7 @@ class Xml2Obj:
Parser.EndElementHandler = self.EndElement
Parser.CharacterDataHandler = self.CharacterData
# Parse the XML File
ParserStatus = Parser.Parse(open(filename,'r').read(), 1)
ParserStatus = Parser.Parse(open(filename, 'r').read(), 1)
return self.root
class Holidays:
@ -1528,17 +1535,19 @@ class Holidays:
def __init__(self, elements, country="US"):
self.debug = 0
self.elements = elements
self.Country = country
self.country = country
self.dates = []
self.initialize()
def set_country(self, country):
self.Country = country
self.country = country
self.dates = []
self.initialize()
def initialize(self):
# parse the date objects
for country_set in self.elements.children:
if country_set.name == "country" and country_set.attributes["name"] == self.Country:
if country_set.name == "country" and country_set.attributes["name"] == self.country:
for date in country_set.children:
if date.name == "date":
data = {"value" : "",
@ -1550,8 +1559,10 @@ class Holidays:
for attr in date.attributes:
data[attr] = date.attributes[attr]
self.dates.append(data)
def get_daynames(self, y, m, dayname):
if self.debug: print "%s's in %d %d..." % (dayname, m, y)
if self.debug:
print "%s's in %d %d..." % (dayname, m, y)
retval = [0]
dow = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'].index(dayname)
for d in range(1, 32):
@ -1561,17 +1572,20 @@ class Holidays:
continue
if date.weekday() == dow:
retval.append( d )
if self.debug: print "dow=", dow, "days=", retval
if self.debug:
print "dow=", dow, "days=", retval
return retval
def check_date(self, date):
retval = []
for rule in self.dates:
if self.debug: print "Checking ", rule["name"], "..."
if self.debug:
print "Checking ", rule["name"], "..."
offset = 0
if rule["offset"] != "":
if rule["offset"].isdigit():
offset = int(rule["offset"])
elif rule["offset"][0] in ["-","+"] and rule["offset"][1:].isdigit():
elif rule["offset"][0] in ["-", "+"] and rule["offset"][1:].isdigit():
offset = int(rule["offset"])
else:
# must be a dayname
@ -1590,7 +1604,8 @@ class Holidays:
m = ['jan', 'feb', 'mar', 'apr', 'may', 'jun',
'jul', 'aug', 'sep', 'oct', 'nov', 'dec'].index(mon) + 1
dates_of_dayname = self.get_daynames(y, m, dayname)
if self.debug: print "num =", num
if self.debug:
print "num =", num
d = dates_of_dayname[int(num)]
elif rule["value"].count("/") == 2: # year/month/day
y, m, d = rule["value"].split("/")
@ -1607,23 +1622,25 @@ class Holidays:
else:
d = int(d)
ndate = datetime.date(y, m, d)
if self.debug: print ndate, offset, type(offset)
if self.debug:
print ndate, offset, type(offset)
if isinstance(offset, int):
if offset != 0:
ndate = ndate.fromordinal(ndate.toordinal() + offset)
elif isinstance(offset, basestring):
dir = 1
dir_ = 1
if offset[0] == "-":
dir = -1
dir_ = -1
offset = offset[1:]
if offset in ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']:
# next tuesday you come to, including this one
dow = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'].index(offset)
ord = ndate.toordinal()
while ndate.fromordinal(ord).weekday() != dow:
ord += dir
ndate = ndate.fromordinal(ord)
if self.debug: print "ndate:", ndate, "date:", date
ord_ = ndate.toordinal()
while ndate.fromordinal(ord_).weekday() != dow:
ord_ += dir_
ndate = ndate.fromordinal(ord_)
if self.debug:
print "ndate:", ndate, "date:", date
if ndate == date:
if rule["if"] != "":
if not eval(rule["if"]):
@ -1631,6 +1648,32 @@ class Holidays:
retval.append(rule["name"])
return retval
# TODO. Try to understand this function and then to replace it with
# something more Pythonic, more understandable.
# Questions to answer:
# * are the file names URLs or native filesystem names?
# (This matters if we must use os.path.join(), or build_url_fname())
# * the logic path for "wc" and "yg" and "by" give same subdirs
# * why the "./" trailer?
def _subdirs(cal, dir_, name):
"""
This will add the number of subdirs to the filename depending on which
calendar is being called:
wc = WebCal
yg = Year At A Glance
by = Printable Pocket Calendar
ip = Indiv Pages
"""
if cal == "wc":
subdirs = '.././'
elif ((cal == "yg") or (cal == "by")):
subdirs = '.././'
else:
subdirs = '../.././'
fname = subdirs + '%s/%s' % (dir_, name)
return fname
def process_holiday_file(filename):
""" This will process a holiday file for country names """
parser = Xml2Obj()
@ -1647,8 +1690,8 @@ def _get_countries():
locations = [const.PLUGINS_DIR, const.USER_PLUGINS]
holiday_file = 'holidays.xml'
country_list = []
for dir in locations:
holiday_full_path = os.path.join(dir, holiday_file)
for dir_ in locations:
holiday_full_path = os.path.join(dir_, holiday_file)
if os.path.exists(holiday_full_path):
cs = process_holiday_file(holiday_full_path)
for c in cs: