#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2004 Donald N. Allingham
#
# 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 Site/Generate Web Site"
#------------------------------------------------------------------------
#
# python modules
#
#------------------------------------------------------------------------
import os
import re
import string
import time
import shutil
#------------------------------------------------------------------------
#
# GNOME/gtk
#
#------------------------------------------------------------------------
import gtk
#------------------------------------------------------------------------
#
# GRAMPS module
#
#------------------------------------------------------------------------
import RelLib
import HtmlDoc
import BaseDoc
import const
import GrampsCfg
import GenericFilter
import Date
import sort
import Report
import Errors
from QuestionDialog import ErrorDialog
from gettext import gettext as _
#------------------------------------------------------------------------
#
# constants
#
#------------------------------------------------------------------------
_month = [
"", "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC" ]
_hline = " " # Everything is underlined, so use blank
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
def by_date(a,b):
return Date.compare_dates(a.getDateObj(),b.getDateObj())
#------------------------------------------------------------------------
#
# HtmlLinkDoc
#
#------------------------------------------------------------------------
class HtmlLinkDoc(HtmlDoc.HtmlDoc):
"""
Version of the HtmlDoc class that provides the ability to create a link
"""
def write_linktarget(self,path):
self.f.write('' % path)
def start_link(self,path):
self.f.write('' % path)
def end_link(self):
self.f.write('')
def newline(self):
self.f.write('
\n')
def write_raw(self,text):
self.f.write(text)
#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
class IndividualPage:
def __init__(self,person,photos,restrict,private,uc,link,mini_tree,map,
dir_name,imgdir,doc,id,idlink,ext):
self.person = person
self.ext = ext
self.doc = doc
self.use_id = id
self.id_link = idlink
self.list = map
self.private = private
self.alive = person.probablyAlive() and restrict
self.photos = (photos == 2) or (photos == 1 and not self.alive)
self.usecomments = not uc
self.dir = dir_name
self.link = link
self.mini_tree = mini_tree
self.slist = []
self.scnt = 1
self.image_dir = imgdir
name = person.getPrimaryName().getRegularName()
self.doc.set_title(_("Summary of %s") % name)
self.doc.fix_title()
#--------------------------------------------------------------------
#
#
#
#--------------------------------------------------------------------
def write_normal_row(self,label,data,sreflist):
self.doc.start_row()
self.doc.start_cell("NormalCell")
self.doc.start_paragraph("Label")
self.doc.write_text(label)
self.doc.end_paragraph()
self.doc.end_cell()
self.doc.start_cell("NormalCell")
self.doc.start_paragraph("Data")
self.doc.write_text(data)
if sreflist:
first = 1
for sref in sreflist:
self.doc.write_raw('')
if first:
first = 0
else:
self.doc.write_text(', ')
self.doc.start_link("#s%d" % self.scnt)
self.doc.write_text('%d' % self.scnt)
self.doc.end_link()
self.doc.write_raw('')
self.scnt = self.scnt + 1
self.slist.append(sref)
self.doc.end_paragraph()
self.doc.end_cell()
self.doc.end_row()
#--------------------------------------------------------------------
#
#
#
#--------------------------------------------------------------------
def write_id_row(self,label,data):
self.doc.start_row()
self.doc.start_cell("NormalCell")
self.doc.start_paragraph("Label")
self.doc.write_text(label)
self.doc.end_paragraph()
self.doc.end_cell()
self.doc.start_cell("NormalCell")
self.doc.start_paragraph("Data")
self.doc.write_raw(data)
self.doc.end_paragraph()
self.doc.end_cell()
self.doc.end_row()
#--------------------------------------------------------------------
#
#
#
#--------------------------------------------------------------------
def write_marriage_row(self,list):
self.doc.start_row()
self.doc.start_cell("NormalCell")
self.doc.start_paragraph("Label")
self.doc.write_text(list[0])
self.doc.end_paragraph()
self.doc.end_cell()
self.doc.start_cell("NormalCell")
self.doc.start_paragraph("Data")
self.doc.write_text(list[1])
self.doc.end_paragraph()
self.doc.end_cell()
self.doc.end_row()
#--------------------------------------------------------------------
#
#
#
#--------------------------------------------------------------------
def write_link_row(self,title,person):
self.doc.start_row()
self.doc.start_cell("NormalCell")
self.doc.start_paragraph("Label")
self.doc.write_text(title)
self.doc.end_paragraph()
self.doc.end_cell()
self.doc.start_cell("NormalCell")
self.doc.start_paragraph("Data")
if person:
if self.list.has_key(person.getId()):
self.doc.start_link("%s.%s" % (person.getId(),self.ext))
self.doc.write_text(person.getPrimaryName().getRegularName())
self.doc.end_link()
else:
self.doc.write_text(person.getPrimaryName().getRegularName())
self.doc.end_paragraph()
self.doc.end_cell()
self.doc.end_row()
def write_sources(self):
self.doc.start_paragraph("SourcesTitle")
self.doc.write_text(_("Sources"))
self.doc.end_paragraph()
index = 1
for sref in self.slist:
self.doc.start_paragraph("SourceParagraph")
self.doc.write_linktarget("s%d" % index)
self.doc.write_text('%d. ' % index)
index = index + 1
self.write_info(sref.getBase().getTitle())
self.write_info(sref.getBase().getAuthor())
self.write_info(sref.getBase().getPubInfo())
self.write_info(sref.getDate().getDate())
self.write_info(sref.getPage())
if self.usecomments:
self.write_info(sref.getText())
self.write_info(sref.getComments())
self.doc.end_paragraph()
def write_info(self,info):
"""Writes a line of text, after stripping leading and trailing
spaces. If the last character is not a period, the period is
appended to produce a sentance"""
info = string.strip(info)
if info != "":
if info[-1] == '.':
self.doc.write_text("%s " % info)
else:
self.doc.write_text("%s. " % info)
def write_tree(self,ind_list):
if not self.mini_tree or not self.person.getMainParents():
return
self.doc.start_paragraph("FamilyTitle")
self.doc.end_paragraph()
self.doc.start_paragraph("Data")
self.doc.write_raw('
\n') tree = MiniTree(self.person,self.doc,ind_list) for line in tree.lines: if line: self.doc.write_raw(line + '\n') self.doc.write_raw('\n') self.doc.end_paragraph() def create_page(self,ind_list): """Generate the HTML page for the specific person""" filebase = "%s.%s" % (self.person.getId(),self.ext) self.doc.open("%s/%s" % (self.dir,filebase)) photo_list = self.person.getPhotoList() name_obj = self.person.getPrimaryName() name = name_obj.getRegularName() # Write out the title line. self.doc.start_paragraph("Title") self.doc.write_text(_("Summary of %s") % name) self.doc.end_paragraph() # blank line for spacing self.doc.start_paragraph("Data") self.doc.end_paragraph() # look for the primary media object if photos have been requested. # make sure that the media object is an image. If so, insert it # into the document. if self.photos and len(photo_list) > 0: object = photo_list[0].getReference() if object.getMimeType()[0:5] == "image": file = object.getPath() if os.path.isfile(file): self.doc.start_paragraph("Data") self.doc.add_photo(file,"row",4.0,4.0) self.doc.end_paragraph() # Start the first table, which consists of basic information, including # name, gender, and parents self.doc.start_table("one","IndTable") self.write_normal_row("%s:" % _("Name"), name, name_obj.getSourceRefList()) if self.use_id: if self.id_link: val = '%s' % (self.id_link,self.person.getId()) val = string.replace(val,'*',self.person.getId()) else: val = self.person.getId() self.write_id_row("%s:" % _("ID Number"),val) if self.person.getGender() == RelLib.Person.male: self.write_normal_row("%s:" % _("Gender"), _("Male"),None) elif self.person.getGender() == RelLib.Person.female: self.write_normal_row("%s:" % _("Gender"), _("Female"),None) else: self.write_normal_row("%s:" % _("Gender"), _("Unknown"),None) family = self.person.getMainParents() if family: self.write_link_row("%s:" % _("Father"), family.getFather()) self.write_link_row("%s:" % _("Mother"), family.getMother()) else: self.write_link_row("%s:" % _("Father"), None) self.write_link_row("%s:" % _("Mother"), None) self.doc.end_table() # Another blank line between the tables self.doc.start_paragraph("Data") self.doc.end_paragraph() self.write_facts() self.write_notes() self.write_families() # if inclusion of photos has been enabled, write the photo # gallery. if self.photos: self.write_gallery() # write source information if self.scnt > 1: self.write_sources() # draw mini-tree self.write_tree(ind_list) if self.link: self.doc.start_paragraph("Data") self.doc.start_link("index.%s" % self.ext) self.doc.write_text(_("Return to the index of people")) self.doc.end_link() self.doc.end_paragraph() def close(self): """Close the document""" self.doc.close() def write_gallery(self): """Write the image gallery. Add images that are not marked as private, creating a thumbnail and copying the original image to the directory.""" # build a list of the images to add, but skip the first image, # since it has been used at the top of the page. my_list = [] index = 0 for object in self.person.getPhotoList(): if object.getReference().getMimeType()[0:5] == "image": if object.getPrivacy() == 0 and index != 0: my_list.append(object) index = 1 # if no images were found, return if len(my_list) == 0: return self.doc.start_paragraph("Data") self.doc.end_paragraph() self.doc.start_paragraph("GalleryTitle") self.doc.write_text(_("Gallery")) self.doc.end_paragraph() self.doc.start_table("gallery","IndTable") for obj in my_list: try: src = obj.getReference().getPath() junk,ext = os.path.splitext(src) base = '%s%s' % (obj.getReference().getId(),ext) if self.image_dir: shutil.copyfile(src,"%s/%s/%s" % (self.dir,self.image_dir,base)) try: shutil.copystat(src,"%s/%s/%s" % (self.dir,self.image_dir,base)) except: pass else: shutil.copyfile(src,"%s/%s" % (self.dir,base)) try: shutil.copystat(src,"%s/%s" % (self.dir,base)) except: pass self.doc.start_row() self.doc.start_cell("ImageCell") self.doc.start_paragraph("Data") if self.image_dir: self.doc.start_link("%s/%s" % (self.image_dir,base)) else: self.doc.start_link("%s" % base) self.doc.add_photo(src,"row",1.5,1.5) self.doc.end_link() self.doc.end_paragraph() self.doc.end_cell() self.doc.start_cell("NoteCell") description = obj.getReference().getDescription() if description != "": self.doc.start_paragraph("PhotoDescription") self.doc.write_text(description) self.doc.end_paragraph() if obj.getNote() != "": self.doc.write_note(obj.getNote(),obj.getNoteFormat(),"PhotoNote") elif obj.getReference().getNote() != "": self.doc.write_note(obj.getReference().getNote(),obj.getReference().getNoteFormat(),"PhotoNote") self.doc.end_cell() self.doc.end_row() except IOError: pass self.doc.end_table() #-------------------------------------------------------------------- # # # #-------------------------------------------------------------------- def write_facts(self): if self.alive: return count = 0 event_list = [ self.person.getBirth(), self.person.getDeath() ] event_list = event_list + self.person.getEventList() event_list.sort(by_date) for event in event_list: if event.getPrivacy(): continue name = _(event.getName()) date = event.getDate() descr = event.getDescription() place = event.getPlaceName() srcref = event.getSourceRefList() if date == "" and descr == "" and place == "" and len(srcref) == 0: continue if count == 0: self.doc.start_paragraph("EventsTitle") self.doc.write_text(_("Facts and Events")) self.doc.end_paragraph() self.doc.start_table("two","IndTable") count = 1 if place != "" and place[-1] == ".": place = place[0:-1] if descr != "" and descr[-1] == ".": descr = descr[0:-1] if date != "": if place != "": val = "%s, %s." % (date,place) else: val = "%s." % date elif place != "": val = "%s." % place else: val = "" if descr != "": val = val + ("%s." % descr) self.write_normal_row(name, val, srcref) if count != 0: self.doc.end_table() def write_notes(self): if self.person.getNote() == "" or self.alive: return self.doc.start_paragraph("NotesTitle") self.doc.write_text(_("Notes")) self.doc.end_paragraph() self.doc.write_note(self.person.getNote(),self.person.getNoteFormat(),"NotesParagraph") def write_fam_fact(self,event): if event == None: return name = _(event.getName()) date = event.getDate() place = event.getPlaceName() descr = event.getDescription() if descr != "" and descr[-1] == ".": descr = descr[0:-1] if place != "" and place[-1] == ".": place = place[0:-1] if date == "" and place == "" and descr == "": return if date == "": if place == "": if descr == "": val = "" else: val = "%s." % descr else: if descr == "": val = "%s." % place else: val = "%s. %s." % (place,descr) else: if place == "": if descr == "": val = "%s." % date else: val = "%s. %s." % (date,descr) else: if descr == "": val = "%s, %s." % (date,place) else: val = "%s, %s. %s." % (date,place,descr) self.write_marriage_row([name, val]) def write_families(self): if len(self.person.getFamilyList()) == 0: return self.doc.start_paragraph("FamilyTitle") self.doc.write_text(_("Marriages/Children")) self.doc.end_paragraph() self.doc.start_table("three","IndTable") for family in self.person.getFamilyList(): if self.person == family.getFather(): spouse = family.getMother() else: spouse = family.getFather() self.doc.start_row() self.doc.start_cell("NormalCell",2) self.doc.start_paragraph("Spouse") if spouse: if self.list.has_key(spouse.getId()): self.doc.start_link("%s.%s" % (spouse.getId(),self.ext)) self.doc.write_text(spouse.getPrimaryName().getRegularName()) self.doc.end_link() else: self.doc.write_text(spouse.getPrimaryName().getRegularName()) else: self.doc.write_text(_("unknown")) self.doc.end_paragraph() self.doc.end_cell() self.doc.end_row() if not self.alive: for event in family.getEventList(): if event.getPrivacy() == 0: self.write_fam_fact(event) child_list = family.getChildList() if len(child_list) > 0: self.doc.start_row() self.doc.start_cell("NormalCell") self.doc.start_paragraph("Label") self.doc.write_text(_("Children")) self.doc.end_paragraph() self.doc.end_cell() self.doc.start_cell("NormalCell") self.doc.start_paragraph("Data") first = 1 for child in family.getChildList(): name = child.getPrimaryName().getRegularName() if first == 1: first = 0 else: self.doc.write_text('\n') if self.list.has_key(child.getId()): self.doc.start_link("%s.%s" % (child.getId(),self.ext)) self.doc.write_text(name) self.doc.end_link() else: self.doc.write_text(name) self.doc.end_paragraph() self.doc.end_cell() self.doc.end_row() self.doc.end_table() #------------------------------------------------------------------------ # # WebReport # #------------------------------------------------------------------------ class WebReport(Report.Report): def __init__(self,db,person,target_path,max_gen,photos,filter,restrict, private, srccomments, include_link, include_mini_tree, style, image_dir, template_name,use_id,id_link,gendex,ext): self.db = db self.ext = ext self.use_id = use_id self.id_link = id_link self.person = person self.target_path = target_path self.max_gen = max_gen self.photos = photos self.filter = filter self.restrict = restrict self.private = private self.srccomments = srccomments self.include_link = include_link self.include_mini_tree = include_mini_tree self.selected_style = style self.image_dir = image_dir self.use_gendex = gendex self.template_name = template_name def get_progressbar_data(self): return (_("Generate HTML reports - GRAMPS"), _("Creating Web Pages")) def make_date(self,date): start = date.get_start_date() if date.isEmpty(): val = date.getText() elif date.isRange(): val = "FROM %s TO %s" % (self.subdate(start), self.subdate(date.get_stop_date())) else: val = self.subdate(start) return val def subdate(self,subdate): retval = "" day = subdate.getDay() mon = subdate.getMonth() year = subdate.getYear() mode = subdate.getModeVal() day_valid = subdate.getDayValid() mon_valid = subdate.getMonthValid() year_valid = subdate.getYearValid() if not day_valid: try: if not mon_valid: retval = str(year) elif not year_valid: retval = _month[mon] else: retval = "%s %d" % (_month[mon],year) except IndexError: print "Month index error - %d" % mon retval = str(year) elif not mon_valid: retval = str(year) else: try: month = _month[mon] if not year_valid: retval = "%d %s ????" % (day,month) else: retval = "%d %s %d" % (day,month,year) except IndexError: print "Month index error - %d" % mon retval = str(year) if mode == Date.Calendar.ABOUT: retval = "ABT %s" % retval elif mode == Date.Calendar.BEFORE: retval = "BEF %s" % retval elif mode == Date.Calendar.AFTER: retval = "AFT %s" % retval return retval def dump_gendex(self,person_list,html_dir): fname = "%s/gendex.txt" % html_dir try: f = open(fname,"w") except: return for p in person_list: name = p.getPrimaryName() firstName = name.getFirstName() surName = name.getSurname() suffix = name.getSuffix() f.write("%s.%s|" % (p.getId(),self.ext)) f.write("%s|" % surName) if suffix == "": f.write("%s /%s/|" % (firstName,surName)) else: f.write("%s /%s/, %s|" % (firstName,surName, suffix)) for e in [p.getBirth(),p.getDeath()]: if e: f.write("%s|" % self.make_date(e.getDateObj())) if e.getPlace(): f.write('%s|' % e.getPlace().get_title()) else: f.write('|') else: f.write('||') f.write('\n') f.close() def dump_index(self,person_list,styles,template,html_dir): """Writes a index file, listing all people in the person list.""" doc = HtmlLinkDoc(self.selected_style,None,template,None) doc.set_extension(self.ext) doc.set_title(_("Family Tree Index")) doc.open("%s/index.%s" % (html_dir,self.ext)) doc.start_paragraph("Title") doc.write_text(_("Family Tree Index")) doc.end_paragraph() person_list.sort(sort.by_last_name) a = {} for person in person_list: n = person.getPrimaryName().getSurname() if n: a[n[0]] = 1 else: a[''] = 1 col_len = len(person_list) + len(a.keys()) col_len = col_len/2 doc.write_raw('
') last = '' end_col = 0 for person in person_list: name = person.getPrimaryName().getName() if name and name[0] != last: last = name[0] doc.start_paragraph('IndexLabel') doc.write_text(name[0]) doc.end_paragraph() col_len = col_len - 1 doc.start_link("%s.%s" % (person.getId(),self.ext)) doc.write_text(name) doc.end_link() if col_len <= 0 and end_col == 0: doc.write_raw(' | ') doc.start_paragraph('IndexLabel') doc.write_text(_("%s (continued)") % name[0]) doc.end_paragraph() end_col = 1 else: doc.newline() col_len = col_len - 1 doc.write_raw(' |