diff --git a/src/plugins/WebCal.py b/src/plugins/WebCal.py index 0ed83a0ec..feb4838d4 100644 --- a/src/plugins/WebCal.py +++ b/src/plugins/WebCal.py @@ -25,16 +25,16 @@ """ Web Calendar generator. -Created 4/22/07 by Thom Sturgill based on Calendar.py (with patches) +Created 4/22/07 by Thom Sturgill based on Calendar.py (with patches) by Doug Blank with input dialog based on NarrativeWeb.py by Don Allingham. 2008-05-11 Jason Simanek Improving markup for optimal separation of content and presentation. 2008-June-22 Rob G. Healey -*** 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 +*** 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 dst start/stop from Calendar.py, etc. Reports/Web Page/Web Calendar @@ -79,13 +79,13 @@ import const import BaseDoc from GrampsCfg import get_researcher from PluginUtils import PluginManager -from ReportBase import (Report, ReportUtils, MenuReportOptions, CATEGORY_WEB, +from ReportBase import (Report, ReportUtils, MenuReportOptions, CATEGORY_WEB, MODE_GUI) 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 = [ + '', + '' - 'Creative Commons License - By attribution', + '' 'Creative Commons License - By attribution, No derivations', + '' 'Creative Commons License - By attribution, Share-alike', + '' 'Creative Commons License - By attribution, Non-commercial', + '' - 'Creative Commons License - By attribution, Non-commercial, No '
-    'derivations', + '' - 'Creative Commons License - By attribution, Non-commerical, '
-    'Share-alike' ] _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'), ] @@ -186,10 +195,10 @@ class WebCalReport(Report): def __init__(self, database, options): Report.__init__(self, database, options) menu = options.menu - + self.database = database self.options = options - + 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() @@ -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.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()] - - def store_file(self, from_path, to_path): + 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. + + 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,9 +262,9 @@ class WebCalReport(Report): "web pages.")) self.warn_dir = False - # code snippets for east and Daylight saving start/ stop - # are borrowed from Calendar.py - + # code snippets for Easter and Daylight saving start/ stop + # are borrowed from Calendar.py + def easter(self): """ Computes the year/month/day of easter. Based on work by @@ -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 @@ -322,14 +342,14 @@ class WebCalReport(Report): self.calendar[month] = month_dict def get_holidays(self, country = "United States"): - """ Looks in multiple places for holidays.xml files + """ Looks in multiple places for holidays.xml files 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 """ - 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, + # 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) + if os.path.exists(from_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) @@ -435,7 +451,7 @@ class WebCalReport(Report): cs = True cs = cs and ' id="CurrentSection"' or '' - of.write(' %s\n' + of.write(' %s\n' % (cs, url, title)) def calendar_build(self, of, cal, month): @@ -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] @@ -529,7 +545,7 @@ class WebCalReport(Report): of.write(' \n') else: # day number if cal == "by": - of.write(' \n' + of.write(' \n' % (day, dayclass)) of.write('
%d
\n' % day) of.write(' \n') @@ -537,23 +553,23 @@ class WebCalReport(Report): of.write(' [])): + 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 lng_month = GrampsLocale.long_months[month] shrt_month = GrampsLocale.short_months[month] - of.write(' \n' + of.write(' \n' % (lng_month, shrt_month, day, self.ext)) of.write('
%d' '
\n' % day) - self.indiv_date(month, day, list) + self.indiv_date(month, day, list_) else: # WebCal of.write('
%d' '
\n' % day) of.write(' \n') else: of.write('class="%s">\n' % dayclass) - of.write('
%d
\n' + of.write('
%d
\n' % day) else: of.write('class="%s">\n' % dayclass) @@ -588,7 +604,7 @@ class WebCalReport(Report): of.write('xml:lang="%s" lang="%s">\n' % (xmllang, xmllang)) of.write('\n') of.write(' %s\n' % title) - of.write(' \n' + of.write(' \n' % self.encoding) of.write(' \n') of.write(' \n' % author) - if ((cal == "yg") or (cal == "by")): # year glance and blank_year + 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(' \n' % fname1) # link to calendar-print css if not cal == "yg": - of.write(' \n' + of.write(' \n' % fname2) # create a link to GRAMPS favicon @@ -646,18 +662,22 @@ class WebCalReport(Report): of.write('

%s

\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">' % 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 = "© %s %s" % (time.localtime()[0], author) of.write(' \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): """ + # 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('
\n') msg = 'Created for %s' % author ip.write(' %s
\n' % msg) - ip.write('

A Peak into One Day

\n') + ip.write('

A Peak into One Day

\n') ip.write(' \n') - + # Create navigation menu ip.write(' \n') - ip.write('

%s %d, %d

\n' + ip.write('

%s %d, %d

\n' % (lng_month, day_num, year)) # if arrow file exists in IMAGE_DIR, use it @@ -753,7 +776,7 @@ class WebCalReport(Report): ip.write('