2007-08-27 09:22:06 +05:30
|
|
|
#
|
|
|
|
# Gramps - a GTK+/GNOME based genealogy program
|
|
|
|
#
|
2008-02-10 09:39:09 +05:30
|
|
|
# Copyright (C) 2007 Thom Sturgill
|
|
|
|
# Copyright (C) 2007-2008 Brian G. Matherly
|
2008-07-17 18:35:15 +05:30
|
|
|
# Copyright (C) 2008 Rob G. Healey <robhealey1@gmail.com>
|
2007-08-27 09:22:06 +05:30
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Pubilc License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
#
|
|
|
|
|
|
|
|
# $Id$
|
|
|
|
|
|
|
|
"""
|
|
|
|
Web Calendar generator.
|
2008-01-29 13:10:35 +05:30
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
Created 4/22/07 by Thom Sturgill based on Calendar.py (with patches)
|
2007-08-27 09:22:06 +05:30
|
|
|
by Doug Blank with input dialog based on NarrativeWeb.py by Don Allingham.
|
2008-01-29 13:10:35 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
2008-05-11 Jason Simanek
|
|
|
|
Improving markup for optimal separation of content and presentation.
|
|
|
|
|
|
|
|
2008-June-22 Rob G. Healey
|
2008-07-17 20:18:54 +05:30
|
|
|
*** Remove StyleEditor, make it css based as is NarrativeWeb,
|
|
|
|
move title to first tab, re-word note tabs, complete re-write of
|
|
|
|
calendar build, added year glance, and blank year, added easter and
|
2008-07-17 18:35:15 +05:30
|
|
|
dst start/stop from Calendar.py, etc.
|
|
|
|
|
2008-03-02 04:17:48 +05:30
|
|
|
Reports/Web Page/Web Calendar
|
2007-08-27 09:22:06 +05:30
|
|
|
"""
|
|
|
|
|
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# python modules
|
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
|
|
|
import os
|
|
|
|
import time
|
|
|
|
import datetime
|
2008-07-17 18:35:15 +05:30
|
|
|
import calendar
|
|
|
|
import math
|
2007-08-27 09:22:06 +05:30
|
|
|
import codecs
|
|
|
|
import shutil
|
|
|
|
from gettext import gettext as _
|
|
|
|
from xml.parsers import expat
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
set()
|
|
|
|
except:
|
|
|
|
from sets import Set as set
|
|
|
|
|
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Set up logging
|
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
|
|
|
import logging
|
|
|
|
log = logging.getLogger(".WebPage")
|
|
|
|
|
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# GRAMPS module
|
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
2007-10-08 22:11:39 +05:30
|
|
|
import gen.lib
|
2007-08-27 09:22:06 +05:30
|
|
|
import const
|
|
|
|
from GrampsCfg import get_researcher
|
2008-05-19 00:54:28 +05:30
|
|
|
from PluginUtils import PluginManager
|
2008-07-17 20:18:54 +05:30
|
|
|
from ReportBase import (Report, ReportUtils, MenuReportOptions, CATEGORY_WEB,
|
2008-01-29 13:10:35 +05:30
|
|
|
MODE_GUI)
|
2008-02-10 09:39:09 +05:30
|
|
|
from PluginUtils import FilterOption, EnumeratedListOption, PersonOption, \
|
2008-07-17 18:35:15 +05:30
|
|
|
BooleanOption, NumberOption, StringOption, DestinationOption
|
2007-08-27 09:22:06 +05:30
|
|
|
import Utils
|
|
|
|
import GrampsLocale
|
2008-07-17 20:18:54 +05:30
|
|
|
from QuestionDialog import ErrorDialog, WarningDialog
|
2007-08-27 09:22:06 +05:30
|
|
|
from Utils import probably_alive
|
2008-07-17 18:35:15 +05:30
|
|
|
from DateHandler import displayer as _dd
|
|
|
|
from DateHandler import parser as _dp
|
2007-08-27 09:22:06 +05:30
|
|
|
|
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# constants
|
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
2008-07-17 18:35:15 +05:30
|
|
|
_CALENDARSCREEN = "calendar-screen.css"
|
|
|
|
_CALENDARPRINT = "calendar-print.css"
|
|
|
|
|
|
|
|
# This information defines the list of styles in the Web calendar
|
|
|
|
# options dialog as well as the location of the corresponding SCREEN
|
|
|
|
# stylesheets.
|
|
|
|
_CSS_FILES = [
|
|
|
|
# First is used as default selection.
|
|
|
|
[_("Evergreen"), 'Web_Evergreen.css'],
|
|
|
|
[_("Nebraska"), 'Web_Nebraska.css'],
|
|
|
|
[_("Simply Red"), 'Web_Simply-Red.css'],
|
|
|
|
[_("No style sheet"), ''],
|
|
|
|
]
|
2007-08-27 09:22:06 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
_CHARACTER_SETS = [
|
2008-07-17 20:18:54 +05:30
|
|
|
# First is used as default selection.
|
2007-08-27 09:22:06 +05:30
|
|
|
[_('Unicode (recommended)'), 'utf-8'],
|
|
|
|
['ISO-8859-1', 'iso-8859-1' ],
|
|
|
|
['ISO-8859-2', 'iso-8859-2' ],
|
|
|
|
['ISO-8859-3', 'iso-8859-3' ],
|
|
|
|
['ISO-8859-4', 'iso-8859-4' ],
|
|
|
|
['ISO-8859-5', 'iso-8859-5' ],
|
|
|
|
['ISO-8859-6', 'iso-8859-6' ],
|
|
|
|
['ISO-8859-7', 'iso-8859-7' ],
|
|
|
|
['ISO-8859-8', 'iso-8859-8' ],
|
|
|
|
['ISO-8859-9', 'iso-8859-9' ],
|
|
|
|
['ISO-8859-10', 'iso-8859-10' ],
|
|
|
|
['ISO-8859-13', 'iso-8859-13' ],
|
|
|
|
['ISO-8859-14', 'iso-8859-14' ],
|
|
|
|
['ISO-8859-15', 'iso-8859-15' ],
|
|
|
|
['koi8_r', 'koi8_r', ],
|
|
|
|
]
|
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
_CC = [
|
2008-07-17 20:18:54 +05:30
|
|
|
'',
|
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
'<a rel="license" href="http://creativecommons.org/licenses/by/2.5/">'
|
2008-07-17 20:18:54 +05:30
|
|
|
'<img alt="Creative Commons License - By attribution" '
|
|
|
|
'title="Creative Commons License - By attribution" '
|
|
|
|
'src="%(gif_fname)s" /></a>',
|
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
'<a rel="license" href="http://creativecommons.org/licenses/by-nd/2.5/">'
|
|
|
|
'<img alt="Creative Commons License - By attribution, No derivations" '
|
2008-07-17 20:18:54 +05:30
|
|
|
'title="Creative Commons License - By attribution, No derivations" '
|
|
|
|
'src="%(gif_fname)s" /></a>',
|
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
'<a rel="license" href="http://creativecommons.org/licenses/by-sa/2.5/">'
|
|
|
|
'<img alt="Creative Commons License - By attribution, Share-alike" '
|
2008-07-17 20:18:54 +05:30
|
|
|
'title="Creative Commons License - By attribution, Share-alike" '
|
|
|
|
'src="%(gif_fname)s" /></a>',
|
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
'<a rel="license" href="http://creativecommons.org/licenses/by-nc/2.5/">'
|
|
|
|
'<img alt="Creative Commons License - By attribution, Non-commercial" '
|
2008-07-17 20:18:54 +05:30
|
|
|
'title="Creative Commons License - By attribution, Non-commercial" '
|
|
|
|
'src="%(gif_fname)s" /></a>',
|
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/2.5/">'
|
2008-07-17 20:18:54 +05:30
|
|
|
'<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>',
|
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
'<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/">'
|
2008-07-17 20:18:54 +05:30
|
|
|
'<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>'
|
2007-08-27 09:22:06 +05:30
|
|
|
]
|
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
_COPY_OPTIONS = [
|
|
|
|
_('Standard copyright'),
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
_('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'),
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
_('No copyright notice'),
|
|
|
|
]
|
|
|
|
|
2007-12-15 21:19:53 +05:30
|
|
|
def make_date(year, month, day):
|
|
|
|
"""
|
2008-02-24 19:25:55 +05:30
|
|
|
Return a Date object of the particular year/month/day.
|
2007-12-15 21:19:53 +05:30
|
|
|
"""
|
|
|
|
retval = gen.lib.Date()
|
|
|
|
retval.set_yr_mon_day(year, month, day)
|
|
|
|
return retval
|
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
2008-02-10 09:39:09 +05:30
|
|
|
# WebCalReport
|
2007-08-27 09:22:06 +05:30
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
2008-02-10 09:39:09 +05:30
|
|
|
class WebCalReport(Report):
|
|
|
|
"""
|
2008-02-24 19:25:55 +05:30
|
|
|
Create WebCalReport object that produces the report.
|
2008-02-10 09:39:09 +05:30
|
|
|
"""
|
2008-02-20 10:22:10 +05:30
|
|
|
def __init__(self, database, options):
|
|
|
|
Report.__init__(self, database, options)
|
2008-02-10 09:39:09 +05:30
|
|
|
menu = options.menu
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
self.database = database
|
|
|
|
self.options = options
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
self.html_dir = menu.get_option_by_name('target').get_value()
|
|
|
|
filter_option = menu.get_option_by_name('filter')
|
|
|
|
self.filter = filter_option.get_filter()
|
|
|
|
self.ext = menu.get_option_by_name('ext').get_value()
|
|
|
|
self.copy = menu.get_option_by_name('cright').get_value()
|
|
|
|
self.encoding = menu.get_option_by_name('encoding').get_value()
|
2008-07-17 18:35:15 +05:30
|
|
|
self.css = menu.get_option_by_name('css').get_value()
|
2008-07-17 20:18:54 +05:30
|
|
|
self.country = menu.get_option_by_name('country').get_value()
|
|
|
|
self.year = menu.get_option_by_name('year').get_value()
|
2008-07-17 18:35:15 +05:30
|
|
|
self.fullyear = menu.get_option_by_name('fullyear').get_value()
|
|
|
|
self.blankyear = menu.get_option_by_name('blankyear').get_value()
|
2008-07-17 20:18:54 +05:30
|
|
|
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.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()]
|
|
|
|
|
|
|
|
self.warn_dir = True # Only give warning once.
|
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
# Set first weekday according to Locale
|
|
|
|
xmllang = Utils.xml_lang()
|
|
|
|
if xmllang == "en-US":
|
|
|
|
# USA calendar starts on a Sunday
|
|
|
|
calendar.setfirstweekday(calendar.SUNDAY)
|
|
|
|
else:
|
|
|
|
# European calendar starts on Monday, default
|
|
|
|
calendar.setfirstweekday(calendar.MONDAY)
|
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
def copy_file(self, from_fname, to_fname, to_dir=''):
|
2008-07-17 18:35:15 +05:30
|
|
|
"""
|
2008-07-17 20:18:54 +05:30
|
|
|
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'.
|
2008-07-17 18:35:15 +05:30
|
|
|
"""
|
2008-07-17 20:18:54 +05:30
|
|
|
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)
|
2008-07-17 18:35:15 +05:30
|
|
|
elif self.warn_dir:
|
|
|
|
WarningDialog(
|
|
|
|
_("Possible destination error") + "\n" +
|
|
|
|
_("You appear to have set your target directory "
|
|
|
|
"to a directory used for data storage. This "
|
|
|
|
"could create problems with file management. "
|
|
|
|
"It is recommended that you consider using "
|
|
|
|
"a different directory to store your generated "
|
|
|
|
"web pages."))
|
|
|
|
self.warn_dir = False
|
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
def dst(self, area="us"):
|
2008-07-17 18:35:15 +05:30
|
|
|
"""
|
|
|
|
Return Daylight Saving Time start/stop in a given area ("us", "eu").
|
|
|
|
US calculation valid 1976-2099; EU 1996-2099
|
|
|
|
"""
|
2008-07-30 00:07:29 +05:30
|
|
|
year = self.year
|
2008-07-17 18:35:15 +05:30
|
|
|
if area == "us":
|
|
|
|
if year > 2006:
|
|
|
|
start = (year, 3, 14 - (math.floor(1 + year * 5 / 4) % 7)) # March
|
|
|
|
stop = (year, 11, 7 - (math.floor(1 + year * 5 / 4) % 7)) # November
|
|
|
|
else:
|
|
|
|
start = (year, 4, (2 + 6 * year - math.floor(year / 4)) % 7 + 1) # April
|
|
|
|
stop = (year, 10, (31 - (math.floor(year * 5 / 4) + 1) % 7)) # October
|
|
|
|
elif area == "eu":
|
|
|
|
start = (year, 3, (31 - (math.floor(year * 5 / 4) + 4) % 7)) # March
|
|
|
|
stop = (year, 10, (31 - (math.floor(year * 5 / 4) + 1) % 7)) # Oct
|
|
|
|
return (start, stop)
|
2007-08-27 09:22:06 +05:30
|
|
|
|
|
|
|
def add_day_item(self, text, year, month, day):
|
2008-07-31 03:07:24 +05:30
|
|
|
if day == 0:
|
|
|
|
# This may happen for certain "about" dates.
|
|
|
|
day = 1 # Use first day of the month
|
2007-08-27 09:22:06 +05:30
|
|
|
month_dict = self.calendar.get(month, {})
|
|
|
|
day_list = month_dict.get(day, [])
|
|
|
|
day_list.append(text)
|
|
|
|
month_dict[day] = day_list
|
|
|
|
self.calendar[month] = month_dict
|
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
def get_holidays(self, country = "United States"):
|
2008-07-17 20:18:54 +05:30
|
|
|
""" Looks in multiple places for holidays.xml files
|
2008-07-17 18:35:15 +05:30
|
|
|
the holidays file will be used first if it exists in user's plugins, else
|
|
|
|
the GRAMPS plugins will be checked. No more of having duel holidays files being read.
|
|
|
|
|
|
|
|
User directory is first choice if it exists, and does not use both holiday files any longer
|
|
|
|
"""
|
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
holiday_file = 'holidays.xml'
|
2008-07-17 18:35:15 +05:30
|
|
|
holiday_full_path = ""
|
|
|
|
fname1 = os.path.join(const.USER_PLUGINS, holiday_file)
|
|
|
|
fname2 = os.path.join(const.PLUGINS_DIR, holiday_file)
|
2008-07-30 00:07:29 +05:30
|
|
|
if os.path.exists(fname1):
|
2008-07-17 18:35:15 +05:30
|
|
|
holiday_full_path = fname1
|
2008-07-30 00:07:29 +05:30
|
|
|
elif os.path.exists(fname2):
|
2008-07-17 18:35:15 +05:30
|
|
|
holiday_full_path = fname2
|
|
|
|
if holiday_full_path != "":
|
2008-07-30 00:07:29 +05:30
|
|
|
self.process_holiday_file(holiday_full_path, country)
|
2007-08-27 09:22:06 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
def process_holiday_file(self, filename, country):
|
2007-08-27 09:22:06 +05:30
|
|
|
""" This will process a holiday file """
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
year = self.year
|
2007-08-27 09:22:06 +05:30
|
|
|
parser = Xml2Obj()
|
|
|
|
element = parser.Parse(filename)
|
2008-07-17 20:18:54 +05:30
|
|
|
mycalendar = Holidays(element, country)
|
2007-08-27 09:22:06 +05:30
|
|
|
date = datetime.date(year, 1, 1)
|
|
|
|
while date.year == year:
|
2008-07-17 20:18:54 +05:30
|
|
|
holidays = mycalendar.check_date( date )
|
2007-08-27 09:22:06 +05:30
|
|
|
for text in holidays:
|
2008-07-17 18:35:15 +05:30
|
|
|
if text == "Easter":
|
2008-07-30 02:53:44 +05:30
|
|
|
date1 = _easter(year)
|
2008-07-17 18:35:15 +05:30
|
|
|
self.add_day_item(text, date1[0], date1[1], date1[2])
|
|
|
|
elif text == "Daylight Saving begins":
|
|
|
|
if Utils.xml_lang() == "en-US":
|
2008-07-30 00:07:29 +05:30
|
|
|
date2 = self.dst("us")
|
2008-07-17 18:35:15 +05:30
|
|
|
else:
|
2008-07-30 00:07:29 +05:30
|
|
|
date2 = self.dst("eu")
|
2008-07-17 18:35:15 +05:30
|
|
|
dst_start = date2[0]
|
|
|
|
dst_stop = date2[1]
|
|
|
|
self.add_day_item(text, dst_start[0], dst_start[1], dst_start[2])
|
|
|
|
self.add_day_item("Daylight Saving ends", dst_stop[0], dst_stop[1], dst_stop[2])
|
|
|
|
elif text == "Daylight Saving ends":
|
|
|
|
pass
|
2007-08-27 09:22:06 +05:30
|
|
|
self.add_day_item(text, date.year, date.month, date.day)
|
|
|
|
date = date.fromordinal( date.toordinal() + 1)
|
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
def copy_css(self):
|
2007-08-27 09:22:06 +05:30
|
|
|
"""
|
2008-07-17 18:35:15 +05:30
|
|
|
Copies all the necessary files...
|
2007-08-27 09:22:06 +05:30
|
|
|
"""
|
2008-07-17 18:35:15 +05:30
|
|
|
# Copy the _CALENDARSCREEN css
|
|
|
|
if self.css != "":
|
|
|
|
from_file = os.path.join(const.DATA_DIR, self.css)
|
2008-07-17 20:18:54 +05:30
|
|
|
self.copy_file(from_file, _CALENDARSCREEN, "styles")
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# copy calendar-print stylesheet
|
|
|
|
from_file = os.path.join(const.DATA_DIR, "Web_Print-Default.css")
|
2008-07-17 20:18:54 +05:30
|
|
|
self.copy_file(from_file, _CALENDARPRINT, "styles")
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# Copy GRAMPS favicon to target
|
|
|
|
from_file = os.path.join(const.IMAGE_DIR, "favicon.ico")
|
2008-07-17 20:18:54 +05:30
|
|
|
self.copy_file(from_file, "favicon.ico", "images")
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
# Copy arrow image if "Year At A Glance" is requested,
|
2008-07-17 18:35:15 +05:30
|
|
|
# and if the file exists
|
|
|
|
if self.fullyear:
|
|
|
|
from_file = os.path.join(const.IMAGE_DIR, "arrow102.gif")
|
2008-07-17 20:18:54 +05:30
|
|
|
if os.path.exists(from_file):
|
|
|
|
self.copy_file(from_file, "arrow102.gif", "images")
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
def display_nav_links(self, of, currentsection, cal):
|
2008-07-31 03:07:24 +05:30
|
|
|
"""
|
|
|
|
'cal' - one of "yg", "by", "wc", "ip"
|
|
|
|
"""
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# Check to see if home_link will be used???
|
|
|
|
navs = [
|
2008-08-01 02:12:05 +05:30
|
|
|
(self.home_link, _('Home'), self.home_link),
|
|
|
|
(1, _('Jan'), True),
|
|
|
|
(2, _('Feb'), True),
|
|
|
|
(3, _('Mar'), True),
|
|
|
|
(4, _('Apr'), True),
|
|
|
|
(5, _('May'), True),
|
|
|
|
(6, _('Jun'), True),
|
|
|
|
(7, _('Jul'), True),
|
|
|
|
(8, _('Aug'), True),
|
|
|
|
(9, _('Sep'), True),
|
|
|
|
(10, _('Oct'), True),
|
|
|
|
(11, _('Nov'), True),
|
|
|
|
(12, _('Dec'), True),
|
|
|
|
('fullyear', _('Year Glance'), self.fullyear),
|
|
|
|
('blankyear', _('Blank Calendar'), self.blankyear)
|
2008-07-17 18:35:15 +05:30
|
|
|
]
|
|
|
|
for url_fname, nav_text, cond in navs:
|
|
|
|
if cond:
|
2008-08-01 02:12:05 +05:30
|
|
|
# Figure out if we need <li id="CurrentSection"> or just plain <li>
|
|
|
|
cs = ''
|
|
|
|
if url_fname == currentsection:
|
|
|
|
cs = ' id="CurrentSection"'
|
|
|
|
|
|
|
|
if type(url_fname) == int:
|
|
|
|
url_fname = GrampsLocale.long_months[url_fname]
|
2008-07-17 20:18:54 +05:30
|
|
|
new_dir = str(self.year)
|
2008-08-01 02:12:05 +05:30
|
|
|
url = _('unknown')
|
2008-07-17 18:35:15 +05:30
|
|
|
if ((cal == "yg") or (cal == "by")):
|
2008-07-17 20:18:54 +05:30
|
|
|
url = _subdirs("yg", new_dir, url_fname)
|
2008-07-17 18:35:15 +05:30
|
|
|
elif cal == "ip":
|
2008-07-17 20:18:54 +05:30
|
|
|
url = _subdirs("ip", new_dir, url_fname)
|
2008-07-17 18:35:15 +05:30
|
|
|
else:
|
2008-07-17 20:18:54 +05:30
|
|
|
url = _subdirs("wc", new_dir, url_fname)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-08-01 02:12:05 +05:30
|
|
|
if not _has_webpage_extension(url):
|
|
|
|
url += self.ext
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 02:53:44 +05:30
|
|
|
of.write(' <li%s><a href="%s">%s</a></li>\n' % (cs, url, nav_text))
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
def calendar_build(self, of, cal, month):
|
2008-07-17 18:35:15 +05:30
|
|
|
"""
|
|
|
|
This does the work of building the calendar
|
2008-07-31 03:07:24 +05:30
|
|
|
'cal' - one of "yg", "by", "wc"
|
|
|
|
'month' - month number 1, 2, .., 12
|
2008-07-17 18:35:15 +05:30
|
|
|
"""
|
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
year = self.year
|
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
# Begin calendar head
|
|
|
|
title = GrampsLocale.long_months[month]
|
|
|
|
of.write('<!-- %s -->\n' % title)
|
|
|
|
of.write(' <table id="%s" class="calendar">\n' % title)
|
|
|
|
of.write(' <thead>\n')
|
|
|
|
of.write(' <tr>\n')
|
|
|
|
of.write(' <th colspan="7" class="monthName">')
|
|
|
|
of.write('%s</th>\n' % title)
|
|
|
|
of.write(' </tr>\n')
|
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
# This calendar has first column sunday. Do not use locale!
|
|
|
|
calendar.setfirstweekday(calendar.SUNDAY)
|
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
# Calendar weekday names header
|
|
|
|
of.write(' <tr>\n')
|
|
|
|
of.write(' <th class="weekend sunday" />')
|
|
|
|
if cal == "yg":
|
|
|
|
of.write(GrampsLocale.short_days[1])
|
|
|
|
else:
|
|
|
|
of.write(GrampsLocale.long_days[1])
|
|
|
|
of.write('</th>\n')
|
|
|
|
for day_col in range(5):
|
|
|
|
of.write(' <th class="weekday" />')
|
|
|
|
if cal == "yg":
|
|
|
|
of.write(GrampsLocale.short_days[day_col+2])
|
|
|
|
else:
|
|
|
|
of.write(GrampsLocale.long_days[day_col+2])
|
|
|
|
of.write('</th>\n')
|
|
|
|
of.write(' <th class="weekend saturday" />')
|
|
|
|
if cal == "yg":
|
|
|
|
of.write(GrampsLocale.short_days[7])
|
|
|
|
else:
|
|
|
|
of.write(GrampsLocale.long_days[7])
|
|
|
|
of.write('</th>\n')
|
|
|
|
of.write(' </tr>\n')
|
|
|
|
of.write(' </thead>\n')
|
|
|
|
|
|
|
|
of.write(' <tbody>\n')
|
2008-07-31 03:07:24 +05:30
|
|
|
|
|
|
|
# Compute the first day to display for this month.
|
|
|
|
# It can also be a day in the previous month.
|
2008-07-17 18:35:15 +05:30
|
|
|
current_date = datetime.date(year, month, 1) # first day of the month
|
2008-07-31 03:07:24 +05:30
|
|
|
# isoweekday: 1=monday, 2=tuesday, etc
|
2008-07-17 18:35:15 +05:30
|
|
|
if current_date.isoweekday() != 7: # start dow here is 7, sunday
|
2008-07-31 03:07:24 +05:30
|
|
|
# Compute the sunday before this date.
|
2008-07-17 18:35:15 +05:30
|
|
|
current_ord = current_date.toordinal() - current_date.isoweekday()
|
|
|
|
else:
|
2008-07-31 03:07:24 +05:30
|
|
|
# First day of the month is sunday, that's OK
|
2008-07-17 18:35:15 +05:30
|
|
|
current_ord = current_date.toordinal()
|
|
|
|
|
|
|
|
# get last month's last week for previous days in the month
|
|
|
|
if month == 1:
|
|
|
|
prevmonth = calendar.monthcalendar(year-1, 12)
|
|
|
|
else:
|
|
|
|
prevmonth = calendar.monthcalendar(year, month-1)
|
|
|
|
num_weeks = len(prevmonth)
|
2008-07-31 03:07:24 +05:30
|
|
|
lastweek_prevmonth = prevmonth[num_weeks - 1]
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# get next month's first week for next days in the month
|
|
|
|
if month == 12:
|
|
|
|
nextmonth = calendar.monthcalendar(year+1, 1)
|
|
|
|
else:
|
|
|
|
nextmonth = calendar.monthcalendar(year, month + 1)
|
2008-07-31 03:07:24 +05:30
|
|
|
firstweek_nextmonth = nextmonth[0]
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# Begin calendar
|
2008-07-31 03:07:24 +05:30
|
|
|
monthinfo = calendar.monthcalendar(year, month)
|
|
|
|
nweeks = len(monthinfo)
|
2008-07-17 18:35:15 +05:30
|
|
|
for week_row in range(0, nweeks):
|
|
|
|
week = monthinfo[week_row]
|
|
|
|
of.write(' <tr class="week%d">\n' % week_row)
|
2008-07-31 03:07:24 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
for days_row in range(0, 7):
|
|
|
|
if days_row == 0:
|
|
|
|
dayclass = "weekend sunday"
|
|
|
|
elif days_row == 6:
|
|
|
|
dayclass = "weekend saturday"
|
|
|
|
else:
|
|
|
|
dayclass = "weekday"
|
2008-07-31 03:07:24 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
day = week[days_row]
|
2008-07-31 03:07:24 +05:30
|
|
|
if day == 0: # a day in the previous or in the next month
|
|
|
|
if week_row == 0: # day in the previous month
|
|
|
|
specday = lastweek_prevmonth[days_row]
|
2008-07-17 18:35:15 +05:30
|
|
|
specclass = "previous " + dayclass
|
2008-07-31 03:07:24 +05:30
|
|
|
elif week_row == nweeks-1: # day in the next month
|
|
|
|
specday = firstweek_nextmonth[days_row]
|
2008-07-17 18:35:15 +05:30
|
|
|
specclass = "next " + dayclass
|
2008-07-31 03:07:24 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write(' <td id="specday%d" class="%s">\n'
|
|
|
|
% (specday, specclass))
|
2008-07-30 00:07:29 +05:30
|
|
|
of.write(' <div class="date">%d</div>\n'
|
2008-07-17 18:35:15 +05:30
|
|
|
% specday)
|
|
|
|
of.write(' </td>\n')
|
2008-07-31 03:07:24 +05:30
|
|
|
|
|
|
|
else: # normal day number in current month
|
2008-07-17 18:35:15 +05:30
|
|
|
if cal == "by":
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <td id="day%d" class="%s">\n' % (day, dayclass))
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write(' <div class="date">%d</div>\n' % day)
|
|
|
|
of.write(' </td>\n')
|
|
|
|
else:
|
|
|
|
of.write(' <td id="day%d" ' % day)
|
2008-07-31 03:07:24 +05:30
|
|
|
thisday = datetime.date.fromordinal(current_ord)
|
2008-07-17 18:35:15 +05:30
|
|
|
if thisday.month == month: # Something this month
|
2008-07-31 03:07:24 +05:30
|
|
|
day_list = self.calendar.get(month, {}).get(thisday.day, [])
|
|
|
|
if day_list > []:
|
2008-07-17 18:35:15 +05:30
|
|
|
specclass = "highlight " + dayclass
|
|
|
|
of.write('class="%s">\n' % specclass)
|
|
|
|
if cal == "yg": # Year at a Glance
|
|
|
|
lng_month = GrampsLocale.long_months[month]
|
|
|
|
shrt_month = GrampsLocale.short_months[month]
|
2008-07-17 20:18:54 +05:30
|
|
|
of.write(' <a href="%s/%s%d%s">\n'
|
2008-07-17 18:35:15 +05:30
|
|
|
% (lng_month, shrt_month, day, self.ext))
|
|
|
|
of.write(' <div class="date">%d'
|
|
|
|
'</div></a>\n' % day)
|
2008-07-31 03:07:24 +05:30
|
|
|
self.indiv_date(month, day, day_list)
|
2008-07-30 02:53:44 +05:30
|
|
|
else:
|
|
|
|
# WebCal
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <div class="date">%d</div>\n' % day)
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write(' <ul>\n')
|
2008-07-31 03:07:24 +05:30
|
|
|
for p in day_list:
|
2008-07-30 02:53:44 +05:30
|
|
|
for line in p.splitlines():
|
2008-07-30 00:07:29 +05:30
|
|
|
of.write(' <li>')
|
|
|
|
of.write(line)
|
|
|
|
of.write('</li>\n')
|
|
|
|
of.write(' </ul>\n')
|
2008-07-17 18:35:15 +05:30
|
|
|
else:
|
|
|
|
of.write('class="%s">\n' % dayclass)
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <div class="date">%d</div>\n' % day)
|
2008-07-17 18:35:15 +05:30
|
|
|
else:
|
2008-07-31 03:07:24 +05:30
|
|
|
# Either a day of previous month, or a day of next month
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write('class="%s">\n' % dayclass)
|
|
|
|
of.write(' <div class="date">%d</div>\n' % day)
|
|
|
|
of.write(' </td>\n')
|
2008-07-31 03:07:24 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
current_ord += 1
|
2008-07-31 03:07:24 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write(' </tr>\n')
|
|
|
|
|
|
|
|
# Complete six weeks for proper styling
|
2008-07-31 03:07:24 +05:30
|
|
|
# FIXME. Why would we need this? The for loop already
|
|
|
|
# creates all the weeks we need. At most six weeks.
|
|
|
|
# self.six_weeks(of, nweeks)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
def write_header(self, of, title, cal, mystyle):
|
2008-07-17 18:35:15 +05:30
|
|
|
"""
|
2008-07-31 03:07:24 +05:30
|
|
|
This creates the header for the Calendars including style embedded for special purpose
|
2008-07-17 18:35:15 +05:30
|
|
|
"""
|
|
|
|
|
|
|
|
of.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n ')
|
|
|
|
of.write(' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n ')
|
|
|
|
of.write('<html xmlns="http://www.w3.org/1999/xhtml" ')
|
|
|
|
xmllang = Utils.xml_lang()
|
|
|
|
of.write('xml:lang="%s" lang="%s">\n' % (xmllang, xmllang))
|
|
|
|
of.write('<head>\n')
|
|
|
|
of.write(' <title>%s</title>\n' % title)
|
2008-07-17 20:18:54 +05:30
|
|
|
of.write(' <meta http-equiv="Content-Type" content="text/html;charset=%s" />\n'
|
2008-07-17 18:35:15 +05:30
|
|
|
% self.encoding)
|
|
|
|
of.write(' <meta name="robots" content="noindex" />\n')
|
|
|
|
of.write(' <meta name="generator" content="GRAMPS 3.1.x: http://www.gramps-project.org" '
|
|
|
|
'/>\n')
|
|
|
|
author = get_researcher().get_name()
|
|
|
|
of.write(' <meta name="author" content="%s" />\n' % author)
|
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
if ((cal == "yg") or (cal == "by")): # year glance and blank_year
|
|
|
|
# have same directory levels
|
|
|
|
fname1 = _subdirs("yg", "styles", _CALENDARSCREEN)
|
|
|
|
fname2 = _subdirs("yg", "styles", _CALENDARPRINT)
|
|
|
|
fname3 = _subdirs("yg", "images", "favicon.ico")
|
|
|
|
elif cal == "ip":
|
|
|
|
fname1 = _subdirs("ip", "styles", _CALENDARSCREEN)
|
|
|
|
fname2 = _subdirs("ip", "styles", _CALENDARPRINT)
|
|
|
|
fname3 = _subdirs("ip", "images", "favicon.ico")
|
2008-07-17 18:35:15 +05:30
|
|
|
else:
|
2008-07-30 00:07:29 +05:30
|
|
|
fname1 = _subdirs("wc", "styles", _CALENDARSCREEN)
|
|
|
|
fname2 = _subdirs("wc", "styles", _CALENDARPRINT)
|
|
|
|
fname3 = _subdirs("wc", "images", "favicon.ico")
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# link to calendar-screen css
|
2008-07-30 00:07:29 +05:30
|
|
|
of.write(' <link href="%s" rel="stylesheet" type="text/css" media="screen" />\n' % fname1)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# link to calendar-print css
|
2008-07-30 00:07:29 +05:30
|
|
|
if not cal == "yg":
|
|
|
|
of.write(' <link href="%s" rel="stylesheet" type="text/css" media="print" />\n'
|
|
|
|
% fname2)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# create a link to GRAMPS favicon
|
|
|
|
of.write(' <link href="%s" rel="Shortcut Icon" />\n' % fname3)
|
2007-08-27 09:22:06 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
# Add calendar specific embedded style
|
|
|
|
of.write(mystyle)
|
|
|
|
of.write('</head>\n')
|
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
return author
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
def write_footer(self, of, cal):
|
2008-07-17 18:35:15 +05:30
|
|
|
"""
|
|
|
|
Writes the footer section of the pages
|
|
|
|
"""
|
|
|
|
|
|
|
|
# Display date as user set in preferences
|
|
|
|
value = _dp.parse(time.strftime('%b %d %Y'))
|
|
|
|
value = _dd.display(value)
|
|
|
|
|
|
|
|
msg = _('Generated by <a href="http://gramps-project.org" target="_blank">'
|
2008-08-01 02:12:05 +05:30
|
|
|
'GRAMPS</a> on %(date)s') % {'date' : value}
|
2007-08-27 09:22:06 +05:30
|
|
|
|
|
|
|
author = get_researcher().get_name()
|
2008-07-17 18:35:15 +05:30
|
|
|
if author:
|
|
|
|
author = author.replace(',,,', '')
|
|
|
|
of.write(' <div id="footer">\n')
|
|
|
|
of.write(' <p id="createdate">%s</p>\n' % msg)
|
|
|
|
|
|
|
|
# copyright license
|
2008-07-30 00:07:29 +05:30
|
|
|
if cal == "yg" or cal == "by":
|
|
|
|
to_urldir = os.path.join("yg", "images")
|
|
|
|
to_dir = os.path.join("yg", "images")
|
|
|
|
elif cal == "ip":
|
|
|
|
to_urldir = os.path.join("ip", "images")
|
|
|
|
to_dir = os.path.join("ip", "images")
|
2008-07-17 18:35:15 +05:30
|
|
|
else:
|
2008-07-30 00:07:29 +05:30
|
|
|
to_urldir = os.path.join("wc", "images")
|
|
|
|
to_dir = os.path.join("wc", "images")
|
2008-07-17 20:18:54 +05:30
|
|
|
if self.copy > 0 and self.copy < len(_CC):
|
|
|
|
text = _CC[self.copy]
|
2008-07-30 00:07:29 +05:30
|
|
|
fname = os.path.join(to_urldir, "somerights20.gif")
|
2008-07-17 20:18:54 +05:30
|
|
|
text = text % {'gif_fname' : fname}
|
|
|
|
|
|
|
|
from_file = os.path.join(const.IMAGE_DIR, "somerights20.gif")
|
2008-07-30 00:07:29 +05:30
|
|
|
self.copy_file(from_file, "somerights20.gif", to_dir)
|
2007-08-27 09:22:06 +05:30
|
|
|
else:
|
2008-07-17 18:35:15 +05:30
|
|
|
text = "© %s %s" % (time.localtime()[0], author)
|
|
|
|
of.write(' <p id="copyright">%s</p>\n' % text)
|
|
|
|
of.write(' <p id="quality"><a href="http://validator.w3.org/check?uri=referer">')
|
|
|
|
of.write('<img src="http://www.w3.org/Icons/valid-xhtml10" ')
|
|
|
|
of.write('alt="Valid XHTML 1.0 Transitional" height="31" width="88" /></a></p>\n')
|
|
|
|
of.write(' </div>\n')
|
|
|
|
of.write('</body>\n')
|
2007-08-27 09:22:06 +05:30
|
|
|
of.write('</html>\n')
|
|
|
|
|
2008-08-01 02:12:05 +05:30
|
|
|
def create_file(self, fname, subdir=None):
|
|
|
|
"""
|
|
|
|
Create a file in the html_dir tree.
|
|
|
|
If the directory does not exist, create it.
|
|
|
|
"""
|
|
|
|
if subdir:
|
|
|
|
subdir = os.path.join(self.html_dir, subdir)
|
|
|
|
else:
|
|
|
|
subdir = self.html_dir
|
|
|
|
if not os.path.isdir(subdir):
|
|
|
|
os.makedirs(subdir)
|
|
|
|
fname = os.path.join(subdir, fname)
|
|
|
|
of = codecs.EncodedFile(open(fname, "w"), 'utf-8', self.encoding, 'xmlcharrefreplace')
|
2008-07-30 00:07:29 +05:30
|
|
|
return of
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
def close_file(self, of):
|
|
|
|
of.close()
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
def indiv_date(self, month, day_num, day_list):
|
2008-07-28 11:42:46 +05:30
|
|
|
"""
|
2008-07-30 00:07:29 +05:30
|
|
|
This method creates the indiv pages for "Year At A Glance"
|
2008-07-31 03:07:24 +05:30
|
|
|
'dat_list' - lines of text to display at this day
|
2008-07-28 11:42:46 +05:30
|
|
|
"""
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
year = self.year
|
|
|
|
|
2008-08-01 02:12:05 +05:30
|
|
|
# Create names for long and short month names, in LOcale
|
2008-07-30 00:07:29 +05:30
|
|
|
lng_month = GrampsLocale.long_months[month]
|
|
|
|
shrt_month = GrampsLocale.short_months[month]
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
# Name the file, and create it
|
2008-08-01 02:12:05 +05:30
|
|
|
cal_fname = '%s%d%s' % (shrt_month, day_num, self.ext)
|
2008-08-01 14:31:24 +05:30
|
|
|
of = self.create_file(cal_fname, os.path.join(str(year), lng_month))
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-08-01 02:12:05 +05:30
|
|
|
arrow = os.path.join(self.html_dir, "images", "arrow102.gif")
|
2008-07-30 00:07:29 +05:30
|
|
|
mystyle = """
|
|
|
|
<style type="text/css">
|
|
|
|
<!--
|
|
|
|
"""
|
|
|
|
if os.path.isfile(arrow):
|
|
|
|
mystyle += """
|
|
|
|
ul#arrow li {
|
|
|
|
font-size:16px;
|
|
|
|
list-style-image: url("../../images/arrow102.gif"); }
|
|
|
|
"""
|
|
|
|
else:
|
|
|
|
mystyle += """
|
|
|
|
ul li {
|
|
|
|
font-size:16px; }
|
|
|
|
"""
|
|
|
|
mystyle += """
|
|
|
|
-->
|
|
|
|
</style>
|
|
|
|
"""
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
# TODO. Merge this with code from blank_year(), year_glance(), print_page()
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
# Add Header to calendar
|
|
|
|
title = "%d %s %d" % (day_num, lng_month, year)
|
2008-07-31 03:07:24 +05:30
|
|
|
author = self.write_header(of, title, "ip", mystyle)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write('<body id="events-%s%d">\n' % (shrt_month, day_num))
|
2008-08-01 02:12:05 +05:30
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <div id="header">\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
if author:
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <div id="GRAMPSinfo">\n')
|
2008-08-01 02:12:05 +05:30
|
|
|
msg = _('Created for %(author)s') % {'author' : author}
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' %s</div>\n' % msg)
|
2008-08-01 02:12:05 +05:30
|
|
|
msg = _('A Peak into One Day')
|
|
|
|
of.write(' <h1 id="SiteTitle">%s</h1>\n' % msg)
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' </div>\n')
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
# Create navigation menu
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <div id="navigation">\n')
|
|
|
|
of.write(' <ul>\n')
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
if self.home_link.strip() != '':
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <li>')
|
|
|
|
of.write('<a href="%s">HOME</a></li>\n' % self.home_link)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-08-01 02:12:05 +05:30
|
|
|
self.display_nav_links(of, None, "ip")
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' </ul>\n')
|
|
|
|
of.write(' </div>\n')
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <h2 class="monthName" style="display:block;">%s %d, %d</h2>\n'
|
2008-07-30 00:07:29 +05:30
|
|
|
% (lng_month, day_num, year))
|
|
|
|
|
|
|
|
# if arrow file exists in IMAGE_DIR, use it
|
|
|
|
arrow = os.path.join(const.IMAGE_DIR, "arrow102.gif")
|
|
|
|
if os.path.isfile(arrow):
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <ul id="arrow">\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
else:
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <ul>\n')
|
|
|
|
for p in day_list:
|
2008-07-30 02:53:44 +05:30
|
|
|
for line in p.splitlines():
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <li>')
|
|
|
|
of.write(line)
|
|
|
|
of.write('</li>\n')
|
|
|
|
of.write(' </ul>\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
self.write_footer(of, "ip")
|
|
|
|
self.close_file(of)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
def six_weeks(self, of, nweeks):
|
|
|
|
"""
|
2008-07-17 20:18:54 +05:30
|
|
|
Will complete the calendar out to six weeks for
|
2008-07-17 18:35:15 +05:30
|
|
|
proper styling of css sheets
|
|
|
|
"""
|
|
|
|
|
|
|
|
if nweeks == 4: # four weeks, add two weeks
|
|
|
|
for empty_weeks in range(1, 3):
|
|
|
|
of.write(' <tr class="week%d">\n' % (nweeks + empty_weeks))
|
2008-07-30 00:07:29 +05:30
|
|
|
of.write(' <td id="emptyDays" colspan="7">\n')
|
|
|
|
of.write(' </td>\n')
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write(' </tr>\n')
|
|
|
|
elif nweeks == 5: # five weeks, add one week
|
|
|
|
of.write(' <tr class="week6">\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
of.write(' <td id="emptyDays" colspan="7">\n')
|
|
|
|
of.write(' </td>\n')
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write(' </tr>\n')
|
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
def blank_year(self):
|
2008-07-17 18:35:15 +05:30
|
|
|
"""
|
|
|
|
This method will create the Printable Full Year One Page Calendar...
|
|
|
|
"""
|
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
year = self.year
|
|
|
|
|
|
|
|
# Name the file, and create it
|
2008-08-01 02:12:05 +05:30
|
|
|
cal_fname = 'blankyear%s' % self.ext
|
|
|
|
of = self.create_file(cal_fname, "%d" % year)
|
2008-07-30 00:07:29 +05:30
|
|
|
|
|
|
|
# Add specific styles for "Printable Full-Year Calendar" page
|
|
|
|
mystyle = """
|
|
|
|
<style type="text/css">
|
|
|
|
<!--
|
|
|
|
#header {
|
|
|
|
height:2cm;
|
|
|
|
#header h1#SiteTitle {
|
|
|
|
color:#FFF;
|
|
|
|
font-size:24px; }
|
|
|
|
#footer {
|
|
|
|
height:2cm;
|
|
|
|
font-size:16px;
|
|
|
|
-->
|
|
|
|
</style>
|
|
|
|
"""
|
|
|
|
|
|
|
|
# TODO. See note in indiv_date()
|
|
|
|
|
|
|
|
# Add header to page
|
|
|
|
title = str(year) + "Blank Calendar"
|
2008-07-31 03:07:24 +05:30
|
|
|
author = self.write_header(of, title, "by", mystyle)
|
2008-07-30 00:07:29 +05:30
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write('<body id="blankca">\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
|
|
|
|
# Header Title
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <div id="header">\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
if author:
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <div id="GRAMPSinfo">\n')
|
2008-08-01 02:12:05 +05:30
|
|
|
msg = _('Created for %(author)s') % {'author' : author}
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' %s</div>\n' % msg)
|
|
|
|
of.write(' <h1 id="SiteTitle">%d</h1>\n' % year)
|
|
|
|
of.write(' </div>\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
|
|
|
|
# Create navigation menu
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <div id="navigation">\n')
|
|
|
|
of.write(' <ul>\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
|
|
|
|
if self.home_link.strip() != '':
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <li>')
|
|
|
|
of.write('<a href="%s">HOME</a></li>\n' % self.home_link)
|
2008-07-30 00:07:29 +05:30
|
|
|
|
2008-08-01 02:12:05 +05:30
|
|
|
self.display_nav_links(of, 'blankyear', "by")
|
2008-07-30 00:07:29 +05:30
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' </ul>\n')
|
|
|
|
of.write(' </div>\n')
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
# Create progress bar for it
|
2008-07-30 00:07:29 +05:30
|
|
|
self.progress.set_pass(_('Creating Printable Blank Full-Year Calendar Page'), 12)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
for month in range(1, 13): # Create full year
|
2008-07-30 00:07:29 +05:30
|
|
|
self.progress.step()
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# build the calendar
|
2008-07-31 03:07:24 +05:30
|
|
|
self.calendar_build(of, "by", month)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# close table body
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' </tbody>\n')
|
|
|
|
of.write(' </table>\n')
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# Write footer and close file
|
2008-07-31 03:07:24 +05:30
|
|
|
self.write_footer(of, "by")
|
|
|
|
self.close_file(of)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
def year_glance(self):
|
2008-07-17 18:35:15 +05:30
|
|
|
"""
|
|
|
|
This method will create the Full Year At A Glance Page...
|
|
|
|
"""
|
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
year = self.year
|
|
|
|
|
|
|
|
# Name the file, and create it
|
2008-08-01 02:12:05 +05:30
|
|
|
cal_fname = 'fullyear%s' % (self.ext)
|
|
|
|
of = self.create_file(cal_fname, "%d" % year)
|
2008-07-30 00:07:29 +05:30
|
|
|
|
|
|
|
# Add specific styles for "Year At A Glance" page
|
|
|
|
mystyle = """
|
|
|
|
<style type="text/css">
|
|
|
|
<!--
|
|
|
|
.calendar {
|
|
|
|
float:left;
|
|
|
|
width:30em;
|
|
|
|
height:27em;
|
|
|
|
font-size:.8em;
|
|
|
|
margin:1em 1em 1em 4em;
|
|
|
|
padding:1em 0 0 0;
|
|
|
|
border-top:solid 1px #000;}
|
|
|
|
.calendar thead tr th {
|
|
|
|
height:1em;
|
|
|
|
font-size:.8em; }
|
|
|
|
.calendar thead tr th.monthName {
|
|
|
|
background-color:#FFF;
|
|
|
|
height:1.1em;
|
|
|
|
font-size:1em; }
|
|
|
|
.calendar tbody tr.week5 {
|
|
|
|
border-top:solid 1px #000; }
|
|
|
|
.calendar tbody tr.week6 {
|
|
|
|
border-top:solid 1px #000; }
|
|
|
|
.calendar tbody tr td {
|
|
|
|
height:1.2cm; }
|
|
|
|
.calendar tbody tr td.saturday {
|
|
|
|
border-right:solid 1px #000; }
|
|
|
|
.calendar tbody tr td.sunday {
|
|
|
|
border-left:solid 1px #000; }
|
|
|
|
.highlight div.date {
|
|
|
|
background-color:#FA0E18;
|
|
|
|
color:#FFF; }
|
|
|
|
-->
|
|
|
|
</style>
|
|
|
|
"""
|
|
|
|
|
|
|
|
# TODO. See note in indiv_date()
|
|
|
|
|
|
|
|
# Add header to page
|
|
|
|
title = "%d, At A Glance" % year
|
2008-07-31 03:07:24 +05:30
|
|
|
author = self.write_header(of, title, "yg", mystyle)
|
2008-07-30 00:07:29 +05:30
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write('<body id="fullyear">\n') # body will terminate in write_footer
|
2008-07-30 00:07:29 +05:30
|
|
|
|
|
|
|
# Header Title
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <div id="header">\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
if author:
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <div id="GRAMPSinfo">\n')
|
2008-08-01 02:12:05 +05:30
|
|
|
msg = _('Created for %(author)s') % {'author' : author}
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' %s</div>\n' % msg)
|
2008-08-01 02:12:05 +05:30
|
|
|
of.write(' <h1 id="SiteTitle">%s</h1>\n' % title)
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' </div>\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
|
|
|
|
# Create navigation menu
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <div id="navigation">\n')
|
|
|
|
of.write(' <ul>\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
|
|
|
|
if self.home_link.strip() != '':
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <li>')
|
|
|
|
of.write('<a href="%s">HOME</a></li>\n' % self.home_link)
|
2008-07-30 00:07:29 +05:30
|
|
|
|
2008-08-01 02:12:05 +05:30
|
|
|
self.display_nav_links(of, 'fullyear', "yg")
|
2008-07-30 00:07:29 +05:30
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' </ul>\n')
|
|
|
|
of.write(' </div>\n') # End Navigation Menu
|
2008-07-30 00:07:29 +05:30
|
|
|
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <p id="description">\n')
|
2008-08-01 02:12:05 +05:30
|
|
|
of.write(_(' This calendar is meant to give you access to all your data at a glance '
|
2008-07-30 00:07:29 +05:30
|
|
|
'compressed into one page. Clicking on a <b>red square</b> will take you to a '
|
2008-08-01 02:12:05 +05:30
|
|
|
'page that shows all the events for that date!\n'))
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' </p>\n\n')
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# Create progress bar for it
|
|
|
|
self.progress.set_pass(_('Creating Year At A Glance page'), 12)
|
|
|
|
|
|
|
|
for month in range(1, 13): # Create full year
|
2008-07-30 00:07:29 +05:30
|
|
|
self.progress.step()
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# build the calendar
|
2008-07-31 03:07:24 +05:30
|
|
|
self.calendar_build(of, "yg", month)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
|
|
|
|
# close table body before writing note
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' </tbody>\n')
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# create note section for each calendar month
|
2008-07-17 20:18:54 +05:30
|
|
|
note = self.month_notes[month-1].strip()
|
|
|
|
note = note or " "
|
2008-07-31 03:07:24 +05:30
|
|
|
of.write(' <tfoot>\n')
|
|
|
|
of.write(' <tr>\n')
|
|
|
|
of.write(' <td class="note" colspan="7">\n')
|
|
|
|
of.write(' %s\n' % note)
|
|
|
|
of.write(' </td>\n')
|
|
|
|
of.write(' </tr>\n')
|
|
|
|
of.write(' </tfoot>\n')
|
|
|
|
of.write(' </table>\n\n')
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
# write footer section, and close file
|
2008-07-31 03:07:24 +05:30
|
|
|
self.write_footer(of, "yg")
|
|
|
|
self.close_file(of)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
def write_report(self):
|
|
|
|
""" The short method that runs through each month and creates a page. """
|
2007-10-15 17:56:31 +05:30
|
|
|
if not os.path.isdir(self.html_dir):
|
|
|
|
parent_dir = os.path.dirname(self.html_dir)
|
|
|
|
if not os.path.isdir(parent_dir):
|
|
|
|
ErrorDialog(_("Neither %s nor %s are directories") % \
|
2008-07-17 20:18:54 +05:30
|
|
|
(self.html_dir, parent_dir))
|
2007-10-15 17:56:31 +05:30
|
|
|
return
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
os.mkdir(self.html_dir)
|
|
|
|
except IOError, value:
|
|
|
|
ErrorDialog(_("Could not create the directory: %s") % \
|
|
|
|
self.html_dir + "\n" + value[1])
|
|
|
|
return
|
|
|
|
except:
|
|
|
|
ErrorDialog(_("Could not create the directory: %s") % \
|
|
|
|
self.html_dir)
|
|
|
|
return
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
# initialize the dict to fill:
|
|
|
|
self.calendar = {}
|
2008-07-17 20:18:54 +05:30
|
|
|
self.progress = Utils.ProgressMeter(_("Generate XHTML Calendars"), '')
|
2007-08-27 09:22:06 +05:30
|
|
|
|
|
|
|
# Generate the CSS file
|
2008-07-17 18:35:15 +05:30
|
|
|
self.copy_css()
|
2007-08-27 09:22:06 +05:30
|
|
|
|
|
|
|
# get the information, first from holidays:
|
2008-07-17 20:18:54 +05:30
|
|
|
if self.country != 0: # Don't include holidays
|
2008-07-30 00:07:29 +05:30
|
|
|
self.get_holidays(_COUNTRIES[self.country]) # _country is currently global
|
2008-07-17 20:18:54 +05:30
|
|
|
self.progress.set_pass(_("Getting information from holidays file"), '')
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
# get data from database:
|
|
|
|
self.collect_data()
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
# generate the report:
|
2008-07-17 20:18:54 +05:30
|
|
|
self.progress.set_pass(_("Creating Calendar pages"), 12)
|
2007-08-27 09:22:06 +05:30
|
|
|
|
|
|
|
for month in range(1, 13):
|
|
|
|
self.progress.step()
|
2008-07-30 00:07:29 +05:30
|
|
|
self.print_page(month)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
if self.fullyear:
|
2008-07-30 00:07:29 +05:30
|
|
|
self.year_glance()
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
if self.blankyear:
|
2008-07-30 00:07:29 +05:30
|
|
|
self.blank_year()
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# Close the progress meter
|
2007-08-27 09:22:06 +05:30
|
|
|
self.progress.close()
|
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
def print_page(self, month):
|
|
|
|
"""
|
|
|
|
This method provides information and header/ footer to the calendar month
|
|
|
|
"""
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
year = self.year
|
|
|
|
|
|
|
|
# Name the file, and create it
|
2008-08-01 02:12:05 +05:30
|
|
|
# TODO. Do we want locale month name here?
|
|
|
|
cal_fname = "%s%s" % (GrampsLocale.long_months[month], self.ext)
|
|
|
|
of = self.create_file(cal_fname, "%d" % year)
|
2007-08-27 09:22:06 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
# Add specific styles to calendar head
|
|
|
|
mystyle = """
|
2008-07-17 18:35:15 +05:30
|
|
|
<style type="text/css">
|
|
|
|
<! --
|
|
|
|
.calendar thead tr th.monthName {
|
|
|
|
height:1.5cm;
|
|
|
|
font-size:.9cm; }
|
|
|
|
-->
|
2008-07-30 00:07:29 +05:30
|
|
|
</style>
|
|
|
|
"""
|
|
|
|
|
|
|
|
# TODO. See note in indiv_date()
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
# Add Header to calendar
|
2008-07-31 03:07:24 +05:30
|
|
|
author = self.write_header(of, self.title_text, "wc", mystyle)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
of.write('<body id="WebCal">\n') # terminated in write_footer
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# Header Title
|
|
|
|
of.write(' <div id="header">\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
if author:
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write(' <div id="GRAMPSinfo">\n')
|
2008-08-01 02:12:05 +05:30
|
|
|
msg = _('Created for %(author)s') % {'author' : author}
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write(' %s</div>\n' % msg)
|
2008-07-30 00:07:29 +05:30
|
|
|
of.write(' <h1 id="SiteTitle">%s</h1>\n' % self.title_text)
|
|
|
|
of.write(' <h1>%d</h1>\n' % year)
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write(' </div>\n') # end header
|
|
|
|
|
|
|
|
# Create Navigation Menu
|
|
|
|
of.write(' <div id="navigation">\n')
|
2008-07-17 20:18:54 +05:30
|
|
|
of.write(' <ul>\n')
|
2008-07-17 18:35:15 +05:30
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
if self.home_link.strip() != '':
|
|
|
|
of.write(' <li>')
|
|
|
|
of.write('<a href="%s">HOME</a></li>\n' % self.home_link)
|
|
|
|
|
2008-08-01 02:12:05 +05:30
|
|
|
self.display_nav_links(of, month, "wc")
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
of.write(' </ul>\n\n')
|
|
|
|
of.write(' </div>\n') # End Navigation Menu
|
|
|
|
|
|
|
|
# build the calendar
|
2008-07-30 02:53:44 +05:30
|
|
|
self.calendar_build(of, "wc", month)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
# close table body before note section
|
|
|
|
of.write(' </tbody>\n')
|
|
|
|
|
|
|
|
# create note section for "WebCal"
|
2008-07-17 20:18:54 +05:30
|
|
|
note = self.month_notes[month-1].strip()
|
2008-07-30 00:07:29 +05:30
|
|
|
note = note or " "
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write(' <tfoot>\n')
|
|
|
|
of.write(' <tr>\n')
|
2008-07-30 00:07:29 +05:30
|
|
|
of.write(' <td class="note" colspan="7">%s</td>\n' % note)
|
2008-07-17 18:35:15 +05:30
|
|
|
of.write(' </tr>\n')
|
|
|
|
of.write(' </tfoot>\n')
|
|
|
|
of.write(' </table>\n\n')
|
|
|
|
|
|
|
|
# write footer section, and close file
|
2008-07-31 03:07:24 +05:30
|
|
|
self.write_footer(of, "wc")
|
2007-08-27 09:22:06 +05:30
|
|
|
self.close_file(of)
|
|
|
|
|
|
|
|
def collect_data(self):
|
|
|
|
"""
|
|
|
|
This method runs through the data, and collects the relevant dates
|
|
|
|
and text.
|
|
|
|
"""
|
2008-07-17 20:18:54 +05:30
|
|
|
self.progress.set_pass(_("Filtering"), '')
|
2007-08-27 09:22:06 +05:30
|
|
|
people = self.filter.apply(self.database,
|
|
|
|
self.database.get_person_handles(sort_handles=False))
|
2008-07-17 20:18:54 +05:30
|
|
|
self.progress.set_pass(_("Reading database"), len(people))
|
2007-08-27 09:22:06 +05:30
|
|
|
for person_handle in people:
|
2008-07-17 18:35:15 +05:30
|
|
|
self.progress.step()
|
2007-08-27 09:22:06 +05:30
|
|
|
person = self.database.get_person_from_handle(person_handle)
|
|
|
|
birth_ref = person.get_birth_ref()
|
|
|
|
birth_date = None
|
|
|
|
if birth_ref:
|
|
|
|
birth_event = self.database.get_event_from_handle(birth_ref.ref)
|
|
|
|
birth_date = birth_event.get_date_object()
|
2008-07-17 20:18:54 +05:30
|
|
|
living = probably_alive(person, self.database, make_date(self.year, 1, 1), 0)
|
2008-07-30 02:53:44 +05:30
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
if self.birthday and birth_date != None and ((self.alive and living) or not self.alive):
|
2007-08-27 09:22:06 +05:30
|
|
|
year = birth_date.get_year()
|
|
|
|
month = birth_date.get_month()
|
|
|
|
day = birth_date.get_day()
|
2008-07-17 20:18:54 +05:30
|
|
|
age = self.year - year
|
2007-08-27 09:22:06 +05:30
|
|
|
# add some things to handle maiden name:
|
|
|
|
father_lastname = None # husband, actually
|
2008-07-17 20:18:54 +05:30
|
|
|
if self.surname == 0: # get husband's last name:
|
2007-10-08 22:11:39 +05:30
|
|
|
if person.get_gender() == gen.lib.Person.FEMALE:
|
2007-08-27 09:22:06 +05:30
|
|
|
family_list = person.get_family_handle_list()
|
|
|
|
if len(family_list) > 0:
|
|
|
|
fhandle = family_list[0] # first is primary
|
|
|
|
fam = self.database.get_family_from_handle(fhandle)
|
|
|
|
father_handle = fam.get_father_handle()
|
|
|
|
mother_handle = fam.get_mother_handle()
|
|
|
|
if mother_handle == person_handle:
|
|
|
|
if father_handle:
|
|
|
|
father = self.database.get_person_from_handle(father_handle)
|
2008-07-17 18:35:15 +05:30
|
|
|
if father != None:
|
2007-08-27 09:22:06 +05:30
|
|
|
father_lastname = father.get_primary_name().get_surname()
|
2008-07-30 02:53:44 +05:30
|
|
|
short_name = _get_short_name(person, father_lastname)
|
2008-07-17 18:35:15 +05:30
|
|
|
if age == 0: # person is 0 years old, display nothing
|
2008-07-17 20:18:54 +05:30
|
|
|
text = ""
|
2008-07-17 18:35:15 +05:30
|
|
|
elif age == 1: # person is 1, and therefore display it correctly
|
2008-07-17 20:18:54 +05:30
|
|
|
# TODO. Make this translatable
|
2008-08-01 02:12:05 +05:30
|
|
|
text = _('%(short_name)s, <em>%(age)d</em> year old') % {'short_name' : short_name, 'age' : age}
|
2008-07-17 18:35:15 +05:30
|
|
|
else:
|
2008-08-01 02:12:05 +05:30
|
|
|
text = _('%(short_name)s, <em>%(age)d</em> years old') % {'short_name' : short_name, 'age' : age}
|
2008-07-17 18:35:15 +05:30
|
|
|
self.add_day_item(text, year, month, day)
|
2008-07-30 02:53:44 +05:30
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
if self.anniv and ((self.alive and living) or not self.alive):
|
2007-08-27 09:22:06 +05:30
|
|
|
family_list = person.get_family_handle_list()
|
|
|
|
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:
|
2008-07-30 02:53:44 +05:30
|
|
|
spouse_name = _get_short_name(spouse)
|
|
|
|
short_name = _get_short_name(person)
|
2008-07-17 20:18:54 +05:30
|
|
|
if self.alive:
|
|
|
|
if not probably_alive(spouse, self.database, make_date(self.year, 1, 1), 0):
|
2007-08-27 09:22:06 +05:30
|
|
|
continue
|
|
|
|
married = True
|
|
|
|
for event_ref in fam.get_event_ref_list():
|
|
|
|
event = self.database.get_event_from_handle(event_ref.ref)
|
2008-06-02 06:29:14 +05:30
|
|
|
if event and event.type in [gen.lib.EventType.DIVORCE,
|
|
|
|
gen.lib.EventType.ANNULMENT,
|
|
|
|
gen.lib.EventType.DIV_FILING]:
|
2007-10-16 07:56:38 +05:30
|
|
|
married = False
|
2007-08-27 09:22:06 +05:30
|
|
|
if married:
|
|
|
|
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()
|
2008-07-17 20:18:54 +05:30
|
|
|
years = self.year - year
|
2008-07-17 18:35:15 +05:30
|
|
|
if years == 0:
|
|
|
|
text = "" # zero year anniversary
|
2008-07-17 20:18:54 +05:30
|
|
|
# display nothing
|
2008-07-17 18:35:15 +05:30
|
|
|
else:
|
2008-07-17 20:18:54 +05:30
|
|
|
text = _('<span class="yearsmarried">%(spouse)s and %(person)s, <em>%(nyears)d</em> year anniversary</span>') % {
|
2008-07-17 18:35:15 +05:30
|
|
|
'spouse' : spouse_name,
|
|
|
|
'person' : short_name,
|
|
|
|
'nyears' : years,
|
|
|
|
}
|
2007-08-27 09:22:06 +05:30
|
|
|
self.add_day_item(text, year, month, day)
|
|
|
|
|
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
2008-02-10 09:39:09 +05:30
|
|
|
# WebCalOptions
|
2007-08-27 09:22:06 +05:30
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
2008-02-10 09:39:09 +05:30
|
|
|
class WebCalOptions(MenuReportOptions):
|
2007-08-27 09:22:06 +05:30
|
|
|
"""
|
|
|
|
Defines options and provides handling interface.
|
|
|
|
"""
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
def __init__(self, name, dbase):
|
|
|
|
self.__db = dbase
|
|
|
|
self.__pid = None
|
|
|
|
self.__filter = None
|
|
|
|
MenuReportOptions.__init__(self, name, dbase)
|
2007-08-27 09:22:06 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
def add_menu_options(self, menu):
|
|
|
|
"""
|
|
|
|
Add options to the menu for the web calendar.
|
|
|
|
"""
|
|
|
|
self.__add_report_options(menu)
|
|
|
|
self.__add_content_options(menu)
|
|
|
|
self.__add_notes_options(menu)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
def __add_report_options(self, menu):
|
|
|
|
"""
|
|
|
|
Options on the "Report Options" tab.
|
|
|
|
"""
|
|
|
|
category_name = _("Report Options")
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
target = DestinationOption( _("Destination"),
|
|
|
|
os.path.join(const.USER_HOME, "WEBCAL"))
|
2008-02-10 09:39:09 +05:30
|
|
|
target.set_help( _("The destination directory for the web files"))
|
|
|
|
target.set_directory_entry(True)
|
|
|
|
menu.add_option(category_name, "target", target)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
title = StringOption(_('Calendar Title'), _('My Family Calendar'))
|
2008-07-17 18:35:15 +05:30
|
|
|
title.set_help(_("The title of the calendar"))
|
|
|
|
menu.add_option(category_name, "title", title)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
self.__filter = FilterOption(_("Filter"), 0)
|
|
|
|
self.__filter.set_help(
|
|
|
|
_("Select filter to restrict people that appear on calendar"))
|
|
|
|
menu.add_option(category_name, "filter", self.__filter)
|
|
|
|
self.__filter.connect('value-changed', self.__filter_changed)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
self.__pid = PersonOption(_("Filter Person"))
|
|
|
|
self.__pid.set_help(_("The center person for the filter"))
|
|
|
|
menu.add_option(category_name, "pid", self.__pid)
|
|
|
|
self.__pid.connect('value-changed', self.__update_filters)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
self.__update_filters()
|
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
ext = EnumeratedListOption(_("File extension"), ".html" )
|
|
|
|
for etype in ['.html', '.htm', '.shtml', '.php', '.php3', '.cgi']:
|
|
|
|
ext.add_item(etype, etype)
|
|
|
|
ext.set_help( _("The extension to be used for the web files"))
|
|
|
|
menu.add_option(category_name, "ext", ext)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
cright = EnumeratedListOption(_('Copyright'), 0 )
|
|
|
|
index = 0
|
|
|
|
for copt in _COPY_OPTIONS:
|
|
|
|
cright.add_item(index, copt)
|
|
|
|
index += 1
|
|
|
|
cright.set_help( _("The copyright to be used for the web files"))
|
|
|
|
menu.add_option(category_name, "cright", cright)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
encoding = EnumeratedListOption(_('Character set encoding'), _CHARACTER_SETS[0][1])
|
2008-02-10 09:39:09 +05:30
|
|
|
for eopt in _CHARACTER_SETS:
|
|
|
|
encoding.add_item(eopt[1], eopt[0])
|
|
|
|
encoding.set_help( _("The encoding to be used for the web files"))
|
|
|
|
menu.add_option(category_name, "encoding", encoding)
|
2008-07-17 18:35:15 +05:30
|
|
|
|
|
|
|
css = EnumeratedListOption(_('StyleSheet'), _CSS_FILES[0][1])
|
|
|
|
for style in _CSS_FILES:
|
|
|
|
css.add_item(style[1], style[0])
|
|
|
|
css.set_help( _("The Style Sheet to be used for the web page"))
|
|
|
|
menu.add_option(category_name, "css", css)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
def __add_content_options(self, menu):
|
|
|
|
"""
|
|
|
|
Options on the "Content Options" tab.
|
|
|
|
"""
|
|
|
|
category_name = _("Content Options")
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
year = NumberOption(_("Year of calendar"), time.localtime()[0],
|
2008-02-10 09:39:09 +05:30
|
|
|
1000, 3000)
|
|
|
|
year.set_help(_("Year of calendar"))
|
|
|
|
menu.add_option(category_name, "year", year)
|
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
fullyear = BooleanOption(_('Create Year At A Glance'), False)
|
|
|
|
fullyear.set_help(_('Wheather to create A Full Year High-lighted calendar'))
|
|
|
|
menu.add_option(category_name, 'fullyear', fullyear)
|
|
|
|
|
|
|
|
blankyear = BooleanOption(_('Create A Printable Blank Full- Year Calendar'), False)
|
|
|
|
blankyear.set_help(_('Wheather to create A Full Year Printable calendar'))
|
|
|
|
menu.add_option(category_name, 'blankyear', blankyear)
|
2008-02-10 09:39:09 +05:30
|
|
|
|
|
|
|
country = EnumeratedListOption(_('Country for holidays'), 0 )
|
|
|
|
index = 0
|
|
|
|
for item in _COUNTRIES:
|
|
|
|
country.add_item(index, item)
|
|
|
|
index += 1
|
|
|
|
country.set_help( _("Holidays will be included for the selected "
|
|
|
|
"country"))
|
|
|
|
menu.add_option(category_name, "country", country)
|
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
home_link = StringOption(_('Home link'), '../index.html')
|
2008-07-17 18:35:15 +05:30
|
|
|
home_link.set_help(_("The link to be included to direct the user to "
|
|
|
|
"the main page of the web site"))
|
|
|
|
menu.add_option(category_name, "home_link", home_link)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
alive = BooleanOption(_("Include only living people"), True)
|
|
|
|
alive.set_help(_("Include only living people in the calendar"))
|
|
|
|
menu.add_option(category_name, "alive", alive)
|
|
|
|
|
|
|
|
birthdays = BooleanOption(_("Include birthdays"), True)
|
|
|
|
birthdays.set_help(_("Include birthdays in the calendar"))
|
|
|
|
menu.add_option(category_name, "birthdays", birthdays)
|
|
|
|
|
|
|
|
anniversaries = BooleanOption(_("Include anniversaries"), True)
|
|
|
|
anniversaries.set_help(_("Include anniversaries in the calendar"))
|
|
|
|
menu.add_option(category_name, "anniversaries", anniversaries)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
surname = BooleanOption(_('Check for wives to use maiden name'), True)
|
|
|
|
surname.set_help(_("Attempt to use maiden names of women"))
|
|
|
|
menu.add_option(category_name, "surname", surname)
|
2007-08-27 09:22:06 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
def __add_notes_options(self, menu):
|
|
|
|
"""
|
|
|
|
Options on the "Months Notes" tabs.
|
|
|
|
"""
|
2008-07-17 18:35:15 +05:30
|
|
|
category_name = _("Jan - Jun Notes")
|
2007-08-27 09:22:06 +05:30
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
note_jan = StringOption(_('Jan Note'), _('This prints in January'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_jan.set_help(_("The note for the month of January"))
|
|
|
|
menu.add_option(category_name, "note_jan", note_jan)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
note_feb = StringOption(_('Feb Note'), _('This prints in February'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_feb.set_help(_("The note for the month of February"))
|
|
|
|
menu.add_option(category_name, "note_feb", note_feb)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
note_mar = StringOption(_('Mar Note'), _('This prints in March'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_mar.set_help(_("The note for the month of March"))
|
|
|
|
menu.add_option(category_name, "note_mar", note_mar)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
note_apr = StringOption(_('Apr Note'), _('This prints in April'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_apr.set_help(_("The note for the month of April"))
|
|
|
|
menu.add_option(category_name, "note_apr", note_apr)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
note_may = StringOption(_('May Note'), _('This prints in May'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_may.set_help(_("The note for the month of May"))
|
|
|
|
menu.add_option(category_name, "note_may", note_may)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
note_jun = StringOption(_('Jun Note'), _('This prints in June'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_jun.set_help(_("The note for the month of June"))
|
|
|
|
menu.add_option(category_name, "note_jun", note_jun)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-07-17 18:35:15 +05:30
|
|
|
category_name = _("Jul - Dec Notes")
|
2007-08-27 09:22:06 +05:30
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
note_jul = StringOption(_('Jul Note'), _('This prints in July'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_jul.set_help(_("The note for the month of July"))
|
|
|
|
menu.add_option(category_name, "note_jul", note_jul)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
note_aug = StringOption(_('Aug Note'), _('This prints in August'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_aug.set_help(_("The note for the month of August"))
|
|
|
|
menu.add_option(category_name, "note_aug", note_aug)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
note_sep = StringOption(_('Sep Note'), _('This prints in September'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_sep.set_help(_("The note for the month of September"))
|
|
|
|
menu.add_option(category_name, "note_sep", note_sep)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
note_oct = StringOption(_('Oct Note'), _('This prints in October'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_oct.set_help(_("The note for the month of October"))
|
|
|
|
menu.add_option(category_name, "note_oct", note_oct)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
note_nov = StringOption(_('Nov Note'), _('This prints in November'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_nov.set_help(_("The note for the month of November"))
|
|
|
|
menu.add_option(category_name, "note_nov", note_nov)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
|
|
|
note_dec = StringOption(_('Dec Note'), _('This prints in December'))
|
2008-02-10 09:39:09 +05:30
|
|
|
note_dec.set_help(_("The note for the month of December"))
|
|
|
|
menu.add_option(category_name, "note_dec", note_dec)
|
2007-08-27 09:22:06 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
def __update_filters(self):
|
|
|
|
"""
|
|
|
|
Update the filter list based on the selected person
|
|
|
|
"""
|
|
|
|
gid = self.__pid.get_value()
|
|
|
|
person = self.__db.get_person_from_gramps_id(gid)
|
|
|
|
filter_list = ReportUtils.get_person_filters(person, False)
|
|
|
|
self.__filter.set_filters(filter_list)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
def __filter_changed(self):
|
|
|
|
"""
|
|
|
|
Handle filter change. If the filter is not specific to a person,
|
|
|
|
disable the person option
|
|
|
|
"""
|
|
|
|
filter_value = self.__filter.get_value()
|
|
|
|
if filter_value in [1, 2, 3, 4]:
|
|
|
|
# Filters 1, 2, 3 and 4 rely on the center person
|
|
|
|
self.__pid.set_available(True)
|
2007-08-27 09:22:06 +05:30
|
|
|
else:
|
2008-02-10 09:39:09 +05:30
|
|
|
# The rest don't
|
|
|
|
self.__pid.set_available(False)
|
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
#------------------------------------------------------------------------
|
|
|
|
#
|
2008-07-17 20:18:54 +05:30
|
|
|
#
|
2007-08-27 09:22:06 +05:30
|
|
|
#
|
|
|
|
#------------------------------------------------------------------------
|
|
|
|
class Element:
|
|
|
|
""" A parsed XML element """
|
2008-07-17 20:18:54 +05:30
|
|
|
def __init__(self, name, attributes):
|
2007-08-27 09:22:06 +05:30
|
|
|
'Element constructor'
|
|
|
|
# The element's tag name
|
|
|
|
self.name = name
|
|
|
|
# The element's attribute dictionary
|
|
|
|
self.attributes = attributes
|
|
|
|
# The element's cdata
|
|
|
|
self.cdata = ''
|
|
|
|
# The element's child element list (sequence)
|
|
|
|
self.children = []
|
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
def addChild(self, element):
|
2007-08-27 09:22:06 +05:30
|
|
|
'Add a reference to a child element'
|
|
|
|
self.children.append(element)
|
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
def getAttribute(self, key):
|
2007-08-27 09:22:06 +05:30
|
|
|
'Get an attribute value'
|
|
|
|
return self.attributes.get(key)
|
|
|
|
|
|
|
|
def getData(self):
|
|
|
|
'Get the cdata'
|
|
|
|
return self.cdata
|
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
def getElements(self, name=''):
|
2007-08-27 09:22:06 +05:30
|
|
|
'Get a list of child elements'
|
|
|
|
#If no tag name is specified, return the all children
|
|
|
|
if not name:
|
|
|
|
return self.children
|
|
|
|
else:
|
|
|
|
# else return only those children with a matching tag name
|
|
|
|
elements = []
|
|
|
|
for element in self.children:
|
|
|
|
if element.name == name:
|
|
|
|
elements.append(element)
|
|
|
|
return elements
|
|
|
|
|
|
|
|
def toString(self, level=0):
|
|
|
|
retval = " " * level
|
|
|
|
retval += "<%s" % self.name
|
|
|
|
for attribute in self.attributes:
|
|
|
|
retval += " %s=\"%s\"" % (attribute, self.attributes[attribute])
|
|
|
|
c = ""
|
|
|
|
for child in self.children:
|
|
|
|
c += child.toString(level+1)
|
|
|
|
if c == "":
|
|
|
|
retval += "/>\n"
|
|
|
|
else:
|
|
|
|
retval += ">\n" + c + ("</%s>\n" % self.name)
|
|
|
|
return retval
|
|
|
|
|
|
|
|
|
|
|
|
class Xml2Obj:
|
|
|
|
""" XML to Object """
|
|
|
|
def __init__(self):
|
|
|
|
self.root = None
|
|
|
|
self.nodeStack = []
|
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
def StartElement(self, name, attributes):
|
2007-08-27 09:22:06 +05:30
|
|
|
'SAX start element even handler'
|
|
|
|
# Instantiate an Element object
|
2008-07-17 20:18:54 +05:30
|
|
|
element = Element(name.encode(), attributes)
|
2007-08-27 09:22:06 +05:30
|
|
|
# Push element onto the stack and make it a child of parent
|
|
|
|
if len(self.nodeStack) > 0:
|
|
|
|
parent = self.nodeStack[-1]
|
2008-07-17 20:18:54 +05:30
|
|
|
parent.addChild(element)
|
2007-08-27 09:22:06 +05:30
|
|
|
else:
|
|
|
|
self.root = element
|
|
|
|
self.nodeStack.append(element)
|
|
|
|
|
2008-02-24 19:25:55 +05:30
|
|
|
def EndElement(self, name):
|
2007-08-27 09:22:06 +05:30
|
|
|
'SAX end element event handler'
|
|
|
|
self.nodeStack = self.nodeStack[:-1]
|
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
def CharacterData(self, data):
|
2007-08-27 09:22:06 +05:30
|
|
|
'SAX character data event handler'
|
|
|
|
if data.strip():
|
|
|
|
data = data.encode()
|
|
|
|
element = self.nodeStack[-1]
|
|
|
|
element.cdata += data
|
|
|
|
return
|
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
def Parse(self, filename):
|
2007-08-27 09:22:06 +05:30
|
|
|
# Create a SAX parser
|
|
|
|
Parser = expat.ParserCreate()
|
|
|
|
# SAX event handlers
|
|
|
|
Parser.StartElementHandler = self.StartElement
|
|
|
|
Parser.EndElementHandler = self.EndElement
|
|
|
|
Parser.CharacterDataHandler = self.CharacterData
|
|
|
|
# Parse the XML File
|
2008-07-17 20:18:54 +05:30
|
|
|
ParserStatus = Parser.Parse(open(filename, 'r').read(), 1)
|
2007-08-27 09:22:06 +05:30
|
|
|
return self.root
|
|
|
|
|
|
|
|
class Holidays:
|
|
|
|
""" Class used to read XML holidays to add to calendar. """
|
|
|
|
def __init__(self, elements, country="US"):
|
|
|
|
self.debug = 0
|
|
|
|
self.elements = elements
|
2008-07-17 20:18:54 +05:30
|
|
|
self.country = country
|
2007-08-27 09:22:06 +05:30
|
|
|
self.dates = []
|
|
|
|
self.initialize()
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
def set_country(self, country):
|
2008-07-17 20:18:54 +05:30
|
|
|
self.country = country
|
2007-08-27 09:22:06 +05:30
|
|
|
self.dates = []
|
|
|
|
self.initialize()
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
def initialize(self):
|
|
|
|
# parse the date objects
|
|
|
|
for country_set in self.elements.children:
|
2008-07-17 20:18:54 +05:30
|
|
|
if country_set.name == "country" and country_set.attributes["name"] == self.country:
|
2007-08-27 09:22:06 +05:30
|
|
|
for date in country_set.children:
|
|
|
|
if date.name == "date":
|
|
|
|
data = {"value" : "",
|
|
|
|
"name" : "",
|
|
|
|
"offset": "",
|
|
|
|
"type": "",
|
|
|
|
"if": "",
|
|
|
|
} # defaults
|
|
|
|
for attr in date.attributes:
|
|
|
|
data[attr] = date.attributes[attr]
|
|
|
|
self.dates.append(data)
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
def get_daynames(self, y, m, dayname):
|
2008-07-17 20:18:54 +05:30
|
|
|
if self.debug:
|
|
|
|
print "%s's in %d %d..." % (dayname, m, y)
|
2007-08-27 09:22:06 +05:30
|
|
|
retval = [0]
|
|
|
|
dow = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'].index(dayname)
|
|
|
|
for d in range(1, 32):
|
|
|
|
try:
|
|
|
|
date = datetime.date(y, m, d)
|
|
|
|
except ValueError:
|
|
|
|
continue
|
|
|
|
if date.weekday() == dow:
|
|
|
|
retval.append( d )
|
2008-07-17 20:18:54 +05:30
|
|
|
if self.debug:
|
|
|
|
print "dow=", dow, "days=", retval
|
2007-08-27 09:22:06 +05:30
|
|
|
return retval
|
2008-07-17 20:18:54 +05:30
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
def check_date(self, date):
|
|
|
|
retval = []
|
|
|
|
for rule in self.dates:
|
2008-07-17 20:18:54 +05:30
|
|
|
if self.debug:
|
|
|
|
print "Checking ", rule["name"], "..."
|
2007-08-27 09:22:06 +05:30
|
|
|
offset = 0
|
|
|
|
if rule["offset"] != "":
|
|
|
|
if rule["offset"].isdigit():
|
|
|
|
offset = int(rule["offset"])
|
2008-07-17 20:18:54 +05:30
|
|
|
elif rule["offset"][0] in ["-", "+"] and rule["offset"][1:].isdigit():
|
2007-08-27 09:22:06 +05:30
|
|
|
offset = int(rule["offset"])
|
|
|
|
else:
|
|
|
|
# must be a dayname
|
|
|
|
offset = rule["offset"]
|
|
|
|
if rule["value"].count("/") == 3: # year/num/day/month, "3rd wednesday in april"
|
|
|
|
y, num, dayname, mon = rule["value"].split("/")
|
|
|
|
if y == "*":
|
|
|
|
y = date.year
|
|
|
|
else:
|
|
|
|
y = int(y)
|
|
|
|
if mon.isdigit():
|
|
|
|
m = int(mon)
|
|
|
|
elif mon == "*":
|
|
|
|
m = date.month
|
|
|
|
else:
|
|
|
|
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)
|
2008-07-17 20:18:54 +05:30
|
|
|
if self.debug:
|
|
|
|
print "num =", num
|
2007-08-27 09:22:06 +05:30
|
|
|
d = dates_of_dayname[int(num)]
|
|
|
|
elif rule["value"].count("/") == 2: # year/month/day
|
|
|
|
y, m, d = rule["value"].split("/")
|
|
|
|
if y == "*":
|
|
|
|
y = date.year
|
|
|
|
else:
|
|
|
|
y = int(y)
|
|
|
|
if m == "*":
|
|
|
|
m = date.month
|
|
|
|
else:
|
|
|
|
m = int(m)
|
|
|
|
if d == "*":
|
|
|
|
d = date.day
|
|
|
|
else:
|
|
|
|
d = int(d)
|
|
|
|
ndate = datetime.date(y, m, d)
|
2008-07-17 20:18:54 +05:30
|
|
|
if self.debug:
|
|
|
|
print ndate, offset, type(offset)
|
2008-05-26 01:25:47 +05:30
|
|
|
if isinstance(offset, int):
|
2007-08-27 09:22:06 +05:30
|
|
|
if offset != 0:
|
|
|
|
ndate = ndate.fromordinal(ndate.toordinal() + offset)
|
2008-05-26 01:25:47 +05:30
|
|
|
elif isinstance(offset, basestring):
|
2008-07-17 20:18:54 +05:30
|
|
|
dir_ = 1
|
2007-08-27 09:22:06 +05:30
|
|
|
if offset[0] == "-":
|
2008-07-17 20:18:54 +05:30
|
|
|
dir_ = -1
|
2007-08-27 09:22:06 +05:30
|
|
|
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)
|
2008-07-17 20:18:54 +05:30
|
|
|
ord_ = ndate.toordinal()
|
|
|
|
while ndate.fromordinal(ord_).weekday() != dow:
|
|
|
|
ord_ += dir_
|
|
|
|
ndate = ndate.fromordinal(ord_)
|
|
|
|
if self.debug:
|
|
|
|
print "ndate:", ndate, "date:", date
|
2007-08-27 09:22:06 +05:30
|
|
|
if ndate == date:
|
|
|
|
if rule["if"] != "":
|
|
|
|
if not eval(rule["if"]):
|
|
|
|
continue
|
|
|
|
retval.append(rule["name"])
|
|
|
|
return retval
|
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
# 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())
|
2008-07-30 00:07:29 +05:30
|
|
|
# * the logic path for "wc" and "yg" and "by" give same subdirs
|
|
|
|
# * why the "./" trailer?
|
|
|
|
def _subdirs(cal, dir_, name):
|
2008-07-17 20:18:54 +05:30
|
|
|
"""
|
|
|
|
This will add the number of subdirs to the filename depending on which
|
|
|
|
calendar is being called:
|
2008-07-30 00:07:29 +05:30
|
|
|
wc = WebCal
|
|
|
|
yg = Year At A Glance
|
|
|
|
by = Printable Pocket Calendar
|
|
|
|
ip = Indiv Pages
|
2008-07-17 20:18:54 +05:30
|
|
|
"""
|
|
|
|
|
2008-07-30 00:07:29 +05:30
|
|
|
if cal == "wc":
|
|
|
|
subdirs = '.././'
|
|
|
|
elif ((cal == "yg") or (cal == "by")):
|
2008-07-17 20:18:54 +05:30
|
|
|
subdirs = '.././'
|
|
|
|
else:
|
|
|
|
subdirs = '../.././'
|
|
|
|
fname = subdirs + '%s/%s' % (dir_, name)
|
|
|
|
return fname
|
|
|
|
|
2008-02-10 09:39:09 +05:30
|
|
|
def process_holiday_file(filename):
|
|
|
|
""" This will process a holiday file for country names """
|
|
|
|
parser = Xml2Obj()
|
|
|
|
element = parser.Parse(filename)
|
|
|
|
country_list = []
|
|
|
|
for country_set in element.children:
|
|
|
|
if country_set.name == "country":
|
|
|
|
if country_set.attributes["name"] not in country_list:
|
|
|
|
country_list.append(country_set.attributes["name"])
|
|
|
|
return country_list
|
|
|
|
|
|
|
|
def _get_countries():
|
2007-08-27 09:22:06 +05:30
|
|
|
""" Looks in multiple places for holidays.xml files """
|
2007-11-26 10:41:19 +05:30
|
|
|
locations = [const.PLUGINS_DIR, const.USER_PLUGINS]
|
2007-08-27 09:22:06 +05:30
|
|
|
holiday_file = 'holidays.xml'
|
|
|
|
country_list = []
|
2008-07-17 20:18:54 +05:30
|
|
|
for dir_ in locations:
|
|
|
|
holiday_full_path = os.path.join(dir_, holiday_file)
|
2007-08-27 09:22:06 +05:30
|
|
|
if os.path.exists(holiday_full_path):
|
|
|
|
cs = process_holiday_file(holiday_full_path)
|
|
|
|
for c in cs:
|
|
|
|
if c not in country_list:
|
|
|
|
country_list.append(c)
|
|
|
|
country_list.sort()
|
|
|
|
country_list.insert(0, _("Don't include holidays"))
|
|
|
|
return country_list
|
|
|
|
|
2008-07-17 20:18:54 +05:30
|
|
|
# TODO: Only load this once the first time it is actually needed so Gramps
|
2008-02-10 09:39:09 +05:30
|
|
|
# doesn't take so long to start up.
|
|
|
|
_COUNTRIES = _get_countries()
|
2007-08-27 09:22:06 +05:30
|
|
|
|
2008-07-30 02:53:44 +05:30
|
|
|
# code snippets for Easter and Daylight saving start/ stop
|
|
|
|
# are borrowed from Calendar.py
|
|
|
|
def _easter(year):
|
|
|
|
"""
|
|
|
|
Computes the year/month/day of easter. Based on work by
|
|
|
|
J.-M. Oudin (1940) and is reprinted in the "Explanatory Supplement
|
|
|
|
to the Astronomical Almanac", ed. P. K. Seidelmann (1992). Note:
|
|
|
|
Ash Wednesday is 46 days before Easter Sunday.
|
|
|
|
"""
|
|
|
|
c = year / 100
|
|
|
|
n = year - 19 * (year / 19)
|
|
|
|
k = (c - 17) / 25
|
|
|
|
i = c - c / 4 - (c - k) / 3 + 19 * n + 15
|
|
|
|
i = i - 30 * (i / 30)
|
|
|
|
i = i - (i / 28) * (1 - (i / 28) * (29 / (i + 1)) * ((21 - n) / 11))
|
|
|
|
j = year + year / 4 + i + 2 - c + c / 4
|
|
|
|
j = j - 7 * (j / 7)
|
|
|
|
l = i - j
|
|
|
|
month = 3 + (l + 40) / 44
|
|
|
|
day = l + 28 - 31 * (month / 4)
|
|
|
|
return year, month, day
|
|
|
|
|
|
|
|
# FIXME. Missing name prefix, suffix etc.
|
|
|
|
def _get_short_name(person, maiden_name = None):
|
|
|
|
""" Return person's name, unless maiden_name given, unless married_name listed. """
|
|
|
|
# Get all of a person's names:
|
|
|
|
primary_name = person.get_primary_name()
|
|
|
|
|
|
|
|
married_name = None
|
|
|
|
names = [primary_name] + person.get_alternate_names()
|
|
|
|
for n in names:
|
|
|
|
if int(n.get_type()) == gen.lib.NameType.MARRIED:
|
|
|
|
married_name = n
|
|
|
|
|
|
|
|
# Now, decide which to use:
|
|
|
|
if maiden_name is not None:
|
|
|
|
if married_name is not None:
|
|
|
|
first_name, family_name = married_name.get_first_name(), married_name.get_surname()
|
|
|
|
call_name = married_name.get_call_name()
|
|
|
|
else:
|
|
|
|
first_name, family_name = primary_name.get_first_name(), maiden_name
|
|
|
|
call_name = primary_name.get_call_name()
|
|
|
|
else:
|
|
|
|
first_name, family_name = primary_name.get_first_name(), primary_name.get_surname()
|
|
|
|
call_name = primary_name.get_call_name()
|
|
|
|
|
|
|
|
# If they have a nickname use it
|
|
|
|
if call_name is not None and call_name.strip() != "":
|
|
|
|
first_name = call_name.strip()
|
|
|
|
else: # else just get the first name:
|
|
|
|
first_name = first_name.strip()
|
|
|
|
if " " in first_name:
|
|
|
|
first_name, rest = first_name.split(" ", 1) # just one split max
|
|
|
|
|
|
|
|
return ("%s %s" % (first_name, family_name)).strip()
|
|
|
|
|
2008-08-01 02:12:05 +05:30
|
|
|
def _has_webpage_extension(fname):
|
|
|
|
for ext in ('.html', '.htm' '.shtml', '.cgi', '.php', '.php3'):
|
|
|
|
if fname.endswith(ext):
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2007-08-27 09:22:06 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2008-05-19 00:54:28 +05:30
|
|
|
pmgr = PluginManager.get_instance()
|
|
|
|
pmgr.register_report(
|
2007-08-27 09:22:06 +05:30
|
|
|
name = 'WebCal',
|
|
|
|
category = CATEGORY_WEB,
|
2008-02-10 09:39:09 +05:30
|
|
|
report_class = WebCalReport,
|
|
|
|
options_class = WebCalOptions,
|
2007-08-27 09:22:06 +05:30
|
|
|
modes = MODE_GUI,
|
2008-03-02 04:17:48 +05:30
|
|
|
translated_name = _("Web Calendar"),
|
2008-03-03 00:46:34 +05:30
|
|
|
status = _("Stable"),
|
2008-03-02 04:17:48 +05:30
|
|
|
author_name = "Thom Sturgill",
|
|
|
|
author_email = "thsturgill@yahoo.com",
|
|
|
|
description = _("Produces web (HTML) calendars."),
|
2007-08-27 09:22:06 +05:30
|
|
|
)
|