def alphabet_navigation(sorted_alpha_index, rlocale=glocale): """ Will create the alphabet navigation bar for classes IndividualListPage, SurnameListPage, PlaceListPage, and EventList @param: index_list -- a dictionary of either letters or words @param: rlocale -- The locale to use """ # if no letters, return None to its callers if not sorted_alpha_index: return None num_ltrs = len(sorted_alpha_index) num_of_cols = 26 num_of_rows = ((num_ltrs // num_of_cols) + 1) # begin alphabet navigation division with Html("div", id="alphanav") as alphabetnavigation: index = 0 output = [] dup_index = 0 for dummy_row in range(num_of_rows): unordered = Html("ul") cols = 0 while cols <= num_of_cols and index < num_ltrs: menu_item = sorted_alpha_index[index] if menu_item == ' ': menu_item = ' ' # adding title to hyperlink menu for screen readers and # braille writers title_txt = "Alphabet Menu: %s" % menu_item title_str = rlocale.translation.sgettext(title_txt) # deal with multiple ellipsis which are generated for overflow, # underflow and inflow labels link = menu_item if menu_item in output: link = "%s (%i)" % (menu_item, dup_index) dup_index += 1 output.append(menu_item) hyper = Html("a", menu_item, title=title_str, href="#%s" % link) unordered.extend(Html("li", hyper, inline=True)) index += 1 cols += 1 num_of_rows -= 1 alphabetnavigation += unordered return alphabetnavigation
def alphabet_navigation(index_list, rlocale=glocale): """ Will create the alphabet navigation bar for classes IndividualListPage, SurnameListPage, PlaceListPage, and EventList @param: index_list -- a dictionary of either letters or words @param: rlocale -- The locale to use """ sorted_set = defaultdict(int) for menu_item in index_list: sorted_set[menu_item] += 1 # remove the number of each occurance of each letter sorted_alpha_index = sorted(sorted_set, key=rlocale.sort_key) # if no letters, return None to its callers if not sorted_alpha_index: return None num_ltrs = len(sorted_alpha_index) num_of_cols = 26 num_of_rows = ((num_ltrs // num_of_cols) + 1) # begin alphabet navigation division with Html("div", id="alphanav") as alphabetnavigation: index = 0 for dummy_row in range(num_of_rows): unordered = Html("ul") cols = 0 while cols <= num_of_cols and index < num_ltrs: menu_item = sorted_alpha_index[index] if menu_item == ' ': menu_item = ' ' # adding title to hyperlink menu for screen readers and # braille writers title_txt = "Alphabet Menu: %s" % menu_item title_str = rlocale.translation.sgettext(title_txt) hyper = Html("a", menu_item, title=title_str, href="#%s" % menu_item) unordered.extend(Html("li", hyper, inline=True)) index += 1 cols += 1 num_of_rows -= 1 alphabetnavigation += unordered return alphabetnavigation
def __output_place(self, ldatec, tbody, first_place, pname, place_handle, letter, bucket_link): place = self.r_db.get_place_from_handle(place_handle) if place: if place.get_change_time() > ldatec: ldatec = place.get_change_time() plc_title = pname main_location = get_main_location(self.r_db, place) if not plc_title or plc_title == " ": letter = " " trow = Html("tr") tbody += trow tcell = Html("td", class_="ColumnLetter", inline=True) trow += tcell if first_place: # or primary_difference(letter, prev_letter, self.rlocale): first_place = False # prev_letter = letter trow.attr = 'class = "BeginLetter"' ttle = self._("Places beginning " "with letter %s") % letter tcell += Html("a", letter, name=letter, title=ttle, id_=bucket_link) else: tcell += " " trow += Html("td", self.place_link(place.get_handle(), plc_title, place.get_gramps_id()), class_="ColumnName") trow.extend( Html("td", data or " ", class_=colclass, inline=True) for (colclass, data) in [[ "ColumnState", main_location.get(PlaceType.STATE, '') ], ["ColumnCountry", main_location.get(PlaceType.COUNTRY, '')]]) if self.display_coordinates: tcell1 = Html("td", class_="ColumnLatitude", inline=True) tcell2 = Html("td", class_="ColumnLongitude", inline=True) trow += tcell1, tcell2 if place.lat and place.long: latitude, longitude = conv_lat_lon(place.lat, place.long, "DEG") tcell1 += latitude tcell2 += longitude else: tcell1 += ' ' tcell2 += ' ' return (ldatec, first_place)
def alphabet_navigation(index_list, rlocale=glocale): """ Will create the alphabet navigation bar for classes IndividualListPage, SurnameListPage, PlaceListPage, and EventList @param: index_list -- a dictionary of either letters or words """ sorted_set = defaultdict(int) for menu_item in index_list: sorted_set[menu_item] += 1 # remove the number of each occurance of each letter sorted_alpha_index = sorted(sorted_set, key=rlocale.sort_key) # if no letters, return None to its callers if not sorted_alpha_index: return None num_ltrs = len(sorted_alpha_index) num_of_cols = 26 num_of_rows = ((num_ltrs // num_of_cols) + 1) # begin alphabet navigation division with Html("div", id="alphanav") as alphabetnavigation: index = 0 for row in range(num_of_rows): unordered = Html("ul") cols = 0 while cols <= num_of_cols and index < num_ltrs: menu_item = sorted_alpha_index[index] if menu_item == ' ': menu_item = ' ' # adding title to hyperlink menu for screen readers and # braille writers title_txt = "Alphabet Menu: %s" % menu_item title_str = rlocale.translation.sgettext(title_txt) hyper = Html("a", menu_item, title=title_str, href="#%s" % menu_item) unordered.extend(Html("li", hyper, inline=True)) index += 1 cols += 1 num_of_rows -= 1 alphabetnavigation += unordered return alphabetnavigation
def styledtext_to_html( styledtext: StyledText, space_format: int, contains_html: bool = False, link_format: Optional[str] = None, ): """Return the note in HTML format. Adapted from DynamicWeb. """ backend = HtmlBackend() if link_format is not None: backend.build_link = build_link_factory(link_format) text = str(styledtext) if not text: return "" s_tags = styledtext.get_tags() html_list = Html("div", class_="grampsstylednote") if contains_html: markuptext = backend.add_markup_from_styled(text, s_tags, split="\n", escape=False) html_list += markuptext else: markuptext = backend.add_markup_from_styled(text, s_tags, split="\n") linelist = [] linenb = 1 sigcount = 0 for line in markuptext.split("\n"): [line, sigcount] = process_spaces(line, format=space_format) if sigcount == 0: # The rendering of an empty paragraph '<p></p>' # is undefined so we use a non-breaking space if linenb == 1: linelist.append(" ") html_list.extend(Html("p") + linelist) linelist = [] linenb = 1 else: if linenb > 1: linelist[-1] += "<br />" linelist.append(line) linenb += 1 if linenb > 1: html_list.extend(Html("p") + linelist) # if the last line was blank, then as well as outputting the previous para, # which we have just done, # we also output a new blank para if sigcount == 0: linelist = [" "] html_list.extend(Html("p") + linelist) return "\n".join(html_list)
def styled_note(styledtext, format, contains_html=False): """Return the note in HTML format. Adapted from DynamicWeb. """ _backend = HtmlBackend() text = str(styledtext) if (not text): return ('') s_tags = styledtext.get_tags() htmllist = Html("div", class_="grampsstylednote") if contains_html: markuptext = _backend.add_markup_from_styled(text, s_tags, split='\n', escape=False) htmllist += markuptext else: markuptext = _backend.add_markup_from_styled(text, s_tags, split='\n') linelist = [] linenb = 1 sigcount = 0 for line in markuptext.split('\n'): [line, sigcount] = process_spaces(line, format) if sigcount == 0: # The rendering of an empty paragraph '<p></p>' # is undefined so we use a non-breaking space if linenb == 1: linelist.append(' ') htmllist.extend(Html('p') + linelist) linelist = [] linenb = 1 else: if linenb > 1: linelist[-1] += '<br />' linelist.append(line) linenb += 1 if linenb > 1: htmllist.extend(Html('p') + linelist) # if the last line was blank, then as well as outputting the previous para, # which we have just done, # we also output a new blank para if sigcount == 0: linelist = [" "] htmllist.extend(Html('p') + linelist) return '\n'.join(htmllist)
def medialistpage(self, report, title, sorted_media_handles): """ Generate and output the Media index page. @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: sorted_media_handles -- A list of the handles of the media to be displayed sorted by the media title """ BasePage.__init__(self, report, title) if self.create_images_index: output_file, sio = self.report.create_file("media") # save the media file name in case we create unused media pages self.cur_fname = self.report.cur_fname result = self.write_header(self._('Media')) medialistpage, dummy_head, dummy_body, outerwrapper = result ldatec = 0 # begin gallery division with Html("div", class_="content", id="Gallery") as medialist: outerwrapper += medialist msg = self._( "This page contains an index of all the media objects " "in the database, sorted by their title. Clicking on " "the title will take you to that " "media object’s page. " "If you see media size dimensions " "above an image, click on the " "image to see the full sized version. ") medialist += Html("p", msg, id="description") # begin gallery table and table head with Html("table", class_="infolist primobjlist gallerylist") as table: medialist += table # begin table head thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", trans, class_=colclass, inline=True) for trans, colclass in [( " ", "ColumnRowLabel" ), (self._("Media | Name"), "ColumnName"), ( self._("Date"), "ColumnDate"), (self._("Mime Type"), "ColumnMime")]) # begin table body tbody = Html("tbody") table += tbody index = 1 if self.create_unused_media: media_count = len(self.r_db.get_media_handles()) else: media_count = len(self.report.obj_dict[Media]) message = _("Creating list of media pages") with self.r_user.progress(_("Narrated Web Site Report"), message, media_count + 1) as step: for media_handle in sorted_media_handles: media = self.r_db.get_media_from_handle(media_handle) if media: if media.get_change_time() > ldatec: ldatec = media.get_change_time() title = media.get_description() or "[untitled]" trow = Html("tr") tbody += trow media_data_row = [ [index, "ColumnRowLabel"], [ self.media_ref_link(media_handle, title), "ColumnName" ], [ self.rlocale.get_date( media.get_date_object()), "ColumnDate" ], [media.get_mime_type(), "ColumnMime"] ] trow.extend( Html("td", data, class_=colclass) for data, colclass in media_data_row) step() index += 1 idx = 1 total = len(self.unused_media_handles) if total > 0: trow += Html("tr") trow.extend( Html("td", Html("h4", " "), inline=True) + Html("td", Html("h4", self._("Below unused media objects"), inline=True), class_="") + Html("td", Html("h4", " "), inline=True) + Html("td", Html("h4", " "), inline=True)) for media_handle in self.unused_media_handles: gmfh = self.r_db.get_media_from_handle media = gmfh(media_handle) gc.collect( ) # Reduce memory usage when many images. if idx != total: self.unused_media_handles[idx] trow += Html("tr") media_data_row = [ [index, "ColumnRowLabel"], [ self.media_ref_link( media_handle, media.get_description()), "ColumnName" ], [ self.rlocale.get_date( media.get_date_object()), "ColumnDate" ], [media.get_mime_type(), "ColumnMime"] ] trow.extend( Html("td", data, class_=colclass) for data, colclass in media_data_row) step() index += 1 idx += 1 # add footer section # add clearline for proper styling footer = self.write_footer(ldatec) outerwrapper += (FULLCLEAR, footer) # send page out for processing # and close the file self.report.cur_fname = self.cur_fname if self.create_images_index: self.xhtml_writer(medialistpage, output_file, sio, ldatec)
def eventlistpage(self, report, the_lang, the_title, event_types, event_handle_list): """ Will create the event list page @param: report -- The instance of the main report class for this report @param: the_lang -- The lang to process @param: the_title -- The title page related to the language @param: event_types -- A list of the type in the events database @param: event_handle_list -- A list of event handles """ BasePage.__init__(self, report, the_lang, the_title) ldatec = 0 output_file, sio = self.report.create_file("events") result = self.write_header(self._("Events")) eventslistpage, dummy_head, dummy_body, outerwrapper = result # begin events list division with Html("div", class_="content", id="EventList") as eventlist: outerwrapper += eventlist msg = self._( "This page contains an index of all the events in the " "database, sorted by their type and date (if one is " "present). Clicking on an event’s Gramps ID " "will open a page for that event.") eventlist += Html("p", msg, id="description") # get alphabet navigation... # Assemble all the event types index = AlphabeticIndex(self.rlocale) for (event_type, data_list) in sort_event_types(self.r_db, event_types, event_handle_list, self.rlocale): index.addRecord(event_type, data_list) # Extract the buckets from the index index_list = [] index.resetBucketIterator() while index.nextBucket(): if index.bucketRecordCount != 0: index_list.append(index.bucketLabel) # Output the navigation alpha_nav = alphabet_navigation(index_list, self.rlocale) if alpha_nav: eventlist += alpha_nav # begin alphabet event table with Html("table", class_="infolist primobjlist alphaevent") as table: eventlist += table thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", label, class_=colclass, inline=True) for (label, colclass) in [(self._("Letter"), "ColumnRowLabel"), ( self._("Type"), "ColumnType"), (self._("Date"), "ColumnDate"), (self._("Gramps ID"), "ColumnGRAMPSID"), (self._("Person"), "ColumnPerson")]) tbody = Html("tbody") table += tbody # for each bucket, output the events in that bucket index.resetBucketIterator() output = [] dup_index = 0 while index.nextBucket(): if index.bucketRecordCount != 0: bucket_letter = index.bucketLabel bucket_link = bucket_letter if bucket_letter in output: bucket_link = "%s (%i)" % (bucket_letter, dup_index) dup_index += 1 output.append(bucket_letter) first_letter = True while index.nextRecord(): _event_displayed = [] first_type = True event_type = index.recordName data_list = index.recordData # sort datalist by date of event and by event # handle... data_list = sorted(data_list, key=itemgetter(0, 1)) for (dummy_sort_value, event_handle) in data_list: (ldatec, first_letter, first_type, _event_displayed) \ = self.__output_event(ldatec, event_type, tbody, bucket_letter, bucket_link, first_letter, _event_displayed, first_type, event_handle) # add clearline for proper styling # add footer section footer = self.write_footer(ldatec) outerwrapper += (FULLCLEAR, footer) # send page ut for processing # and close the file self.xhtml_writer(eventslistpage, output_file, sio, ldatec)
def sourcelistpage(self, report, the_lang, the_title, source_handles): """ Generate and output the Sources index page. @param: report -- The instance of the main report class for this report @param: the_lang -- The lang to process @param: the_title -- The title page related to the language @param: source_handles -- A list of the handles of the sources to be displayed """ BasePage.__init__(self, report, the_lang, the_title) source_dict = {} output_file, sio = self.report.create_file("sources") result = self.write_header(self._("Sources")) sourcelistpage, dummy_head, dummy_body, outerwrapper = result # begin source list division with Html("div", class_="content", id="Sources") as sourceslist: outerwrapper += sourceslist # Sort the sources for handle in source_handles: source = self.r_db.get_source_from_handle(handle) if source is not None: key = source.get_title() + source.get_author() key += str(source.get_gramps_id()) source_dict[key] = (source, handle) keys = sorted(source_dict, key=self.rlocale.sort_key) msg = self._("This page contains an index of all the sources " "in the database, sorted by their title. " "Clicking on a source’s " "title will take you to that source’s page.") sourceslist += Html("p", msg, id="description") # begin sourcelist table and table head with Html("table", class_="infolist primobjlist sourcelist") as table: sourceslist += table thead = Html("thead") table += thead trow = Html("tr") thead += trow header_row = [ (self._("Number"), "ColumnRowLabel"), (self._("Author"), "ColumnAuthor"), (self._("Name", "Source Name"), "ColumnName")] trow.extend( Html("th", label or " ", class_=colclass, inline=True) for (label, colclass) in header_row ) # begin table body tbody = Html("tbody") table += tbody for index, key in enumerate(keys): source, source_handle = source_dict[key] trow = Html("tr") + ( Html("td", index + 1, class_="ColumnRowLabel", inline=True) ) tbody += trow trow.extend( Html("td", source.get_author(), class_="ColumnAuthor", inline=True) ) trow.extend( Html("td", self.source_link(source_handle, source.get_title(), source.get_gramps_id()), class_="ColumnName") ) # add clearline for proper styling # add footer section footer = self.write_footer(None) outerwrapper += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(sourcelistpage, output_file, sio, 0)
def medialistpage(self, report, title, sorted_media_handles): """ Generate and output the Media index page. @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: sorted_media_handles -- A list of the handles of the media to be displayed sorted by the media title """ BasePage.__init__(self, report, title) output_file, sio = self.report.create_file("media") # save the media file name in case we create unused media pages self.cur_fname = self.report.cur_fname medialistpage, head, body = self.write_header(self._('Media')) ldatec = 0 # begin gallery division with Html("div", class_="content", id="Gallery") as medialist: body += medialist msg = self._("This page contains an index of all the media objects " "in the database, sorted by their title. Clicking on " "the title will take you to that " "media object’s page. " "If you see media size dimensions " "above an image, click on the " "image to see the full sized version. ") medialist += Html("p", msg, id="description") # begin gallery table and table head with Html("table", class_="infolist primobjlist gallerylist") as table: medialist += table # begin table head thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", trans, class_=colclass, inline=True) for trans, colclass in [(" ", "ColumnRowLabel"), (self._("Media | Name"), "ColumnName"), (self._("Date"), "ColumnDate"), (self._("Mime Type"), "ColumnMime")] ) # begin table body tbody = Html("tbody") table += tbody index = 1 if self.create_unused_media: media_count = len(self.r_db.get_media_handles()) else: media_count = len(self.report.obj_dict[Media]) message = _("Creating list of media pages") with self.r_user.progress(_("Narrated Web Site Report"), message, media_count + 1 ) as step: for media_handle in sorted_media_handles: media = self.r_db.get_media_from_handle(media_handle) if media: if media.get_change_time() > ldatec: ldatec = media.get_change_time() title = media.get_description() or "[untitled]" trow = Html("tr") tbody += trow media_data_row = [ [index, "ColumnRowLabel"], [self.media_ref_link(media_handle, title), "ColumnName"], [self.rlocale.get_date(media.get_date_object()), "ColumnDate"], [media.get_mime_type(), "ColumnMime"]] trow.extend( Html("td", data, class_=colclass) for data, colclass in media_data_row ) step() index += 1 def sort_by_desc_and_gid(obj): """ Sort by media description and gramps ID """ return (obj.desc, obj.gramps_id) idx = 1 prev = None total = len(self.unused_media_handles) if total > 0: trow += Html("tr") trow.extend( Html("td", Html("h4", " "), inline=True) + Html("td", Html("h4", self._("Below unused media objects"), inline=True), class_="") + Html("td", Html("h4", " "), inline=True) + Html("td", Html("h4", " "), inline=True) ) for media_handle in self.unused_media_handles: media = self.r_db.get_media_from_handle(media_handle) gc.collect() # Reduce memory usage when many images. if idx == total: next_ = None else: self.unused_media_handles[idx] trow += Html("tr") media_data_row = [ [index, "ColumnRowLabel"], [self.media_ref_link(media_handle, media.get_description()), "ColumnName"], [self.rlocale.get_date(media.get_date_object()), "ColumnDate"], [media.get_mime_type(), "ColumnMime"]] trow.extend( Html("td", data, class_=colclass) for data, colclass in media_data_row ) prev = media_handle step() index += 1 idx += 1 # add footer section # add clearline for proper styling footer = self.write_footer(ldatec) body += (FULLCLEAR, footer) # send page out for processing # and close the file self.report.cur_fname = self.cur_fname self.xhtml_writer(medialistpage, output_file, sio, ldatec)
def __init__(self, report, the_lang, the_title, has_url_addr_res): """ @param: report -- The instance of the main report class for this report @param: the_lang -- The lang to process @param: the_title -- The title page related to the language @param: has_url_addr_res -- The url, address and residence to use for the report """ BasePage.__init__(self, report, the_lang, the_title) # Name the file, and create it output_file, sio = self.report.create_file("addressbook") # Add xml, doctype, meta and stylesheets result = self.write_header(_("Address Book")) addressbooklistpage, dummy_head, dummy_body, outerwrapper = result # begin AddressBookList division with Html("div", class_="content", id="AddressBookList") as addressbooklist: outerwrapper += addressbooklist # Address Book Page message msg = self._("This page contains an index of all the individuals " "in the database, sorted by their surname, with one " "of the following: Address, Residence, or Web Links. " "Selecting the person’s name will take you " "to their individual Address Book page.") addressbooklist += Html("p", msg, id="description") # begin Address Book table with Html("table", class_="infolist primobjlist addressbook") as table: addressbooklist += table thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", label, class_=colclass, inline=True) for (label, colclass) in [[" ", "ColumnRowLabel"], [_("Full Name"), "ColumnName"], [_("Address"), "ColumnAddress"], [_("Residence"), "ColumnResidence"], [_("Web Links"), "ColumnWebLinks"]]) tbody = Html("tbody") table += tbody index = 1 for (dummy_sort_name, person_handle, has_add, has_res, has_url) in has_url_addr_res: address = None residence = None weblinks = None # has address but no residence event if has_add and not has_res: address = "X" # has residence, but no addresses elif has_res and not has_add: residence = "X" # has residence and addresses too elif has_add and has_res: address = "X" residence = "X" # has Web Links if has_url: weblinks = "X" trow = Html("tr") tbody += trow trow.extend( Html("td", data or " ", class_=colclass, inline=True) for (colclass, data) in [["ColumnRowLabel", index], ["ColumnName", self.addressbook_link(person_handle)], ["ColumnAddress", address], ["ColumnResidence", residence], ["ColumnWebLinks", weblinks]]) index += 1 # Add footer and clearline footer = self.write_footer(None) outerwrapper += (FULLCLEAR, footer) # send the page out for processing # and close the file self.xhtml_writer(addressbooklistpage, output_file, sio, 0)
def familylistpage(self, report, title, fam_list): """ Create a family index @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: fam_list -- The handle for the place to add """ BasePage.__init__(self, report, title) output_file, sio = self.report.create_file("families") familieslistpage, head, body = self.write_header(self._("Families")) ldatec = 0 prev_letter = " " # begin Family Division with Html("div", class_="content", id="Relationships") as relationlist: body += relationlist # Families list page message msg = self._("This page contains an index of all the " "families/ relationships in the " "database, sorted by their family name/ surname. " "Clicking on a person’s " "name will take you to their " "family/ relationship’s page.") relationlist += Html("p", msg, id="description") # go through all the families, and construct a dictionary of all the # people and the families thay are involved in. Note that the people # in the list may be involved in OTHER families, that are not listed # because they are not in the original family list. pers_fam_dict = defaultdict(list) for family_handle in fam_list: family = self.r_db.get_family_from_handle(family_handle) if family: if family.get_change_time() > ldatec: ldatec = family.get_change_time() husband_handle = family.get_father_handle() spouse_handle = family.get_mother_handle() if husband_handle: pers_fam_dict[husband_handle].append(family) if spouse_handle: pers_fam_dict[spouse_handle].append(family) # add alphabet navigation index_list = get_first_letters(self.r_db, pers_fam_dict.keys(), _KEYPERSON, rlocale=self.rlocale) alpha_nav = alphabet_navigation(index_list, self.rlocale) if alpha_nav: relationlist += alpha_nav # begin families table and table head with Html("table", class_="infolist relationships") as table: relationlist += table thead = Html("thead") table += thead trow = Html("tr") thead += trow # set up page columns trow.extend( Html("th", trans, class_=colclass, inline=True) for trans, colclass in [(self._("Letter"), "ColumnRowLabel"), (self._("Person"), "ColumnPartner"), (self._("Family"), "ColumnPartner"), (self._("Marriage"), "ColumnDate"), (self._("Divorce"), "ColumnDate")] ) tbody = Html("tbody") table += tbody # begin displaying index list ppl_handle_list = sort_people(self.r_db, pers_fam_dict.keys(), self.rlocale) first = True for (surname, handle_list) in ppl_handle_list: if surname and not surname.isspace(): letter = get_index_letter(first_letter(surname), index_list, self.rlocale) else: letter = ' ' # get person from sorted database list for person_handle in sorted( handle_list, key=self.sort_on_name_and_grampsid): person = self.r_db.get_person_from_handle(person_handle) if person: family_list = person.get_family_handle_list() first_family = True for family_handle in family_list: get_family = self.r_db.get_family_from_handle family = get_family(family_handle) trow = Html("tr") tbody += trow tcell = Html("td", class_="ColumnRowLabel") trow += tcell if first or primary_difference(letter, prev_letter, self.rlocale): first = False prev_letter = letter trow.attr = 'class="BeginLetter"' ttle = self._("Families beginning with " "letter ") tcell += Html("a", letter, name=letter, title=ttle + letter, inline=True) else: tcell += ' ' tcell = Html("td", class_="ColumnPartner") trow += tcell if first_family: trow.attr = 'class ="BeginFamily"' tcell += self.new_person_link( person_handle, uplink=self.uplink) first_family = False else: tcell += ' ' tcell = Html("td", class_="ColumnPartner") trow += tcell tcell += self.family_link( family.get_handle(), self.report.get_family_name(family), family.get_gramps_id(), self.uplink) # family events; such as marriage and divorce # events fam_evt_ref_list = family.get_event_ref_list() tcell1 = Html("td", class_="ColumnDate", inline=True) tcell2 = Html("td", class_="ColumnDate", inline=True) trow += (tcell1, tcell2) if fam_evt_ref_list: fam_evt_srt_ref_list = sorted( fam_evt_ref_list, key=self.sort_on_grampsid) for evt_ref in fam_evt_srt_ref_list: evt = self.r_db.get_event_from_handle( evt_ref.ref) if evt: evt_type = evt.get_type() if evt_type in [EventType.MARRIAGE, EventType.DIVORCE]: cell = self.rlocale.get_date( evt.get_date_object()) if (evt_type == EventType.MARRIAGE): tcell1 += cell else: tcell1 += ' ' if (evt_type == EventType.DIVORCE): tcell2 += cell else: tcell2 += ' ' else: tcell1 += ' ' tcell2 += ' ' first_family = False # add clearline for proper styling # add footer section footer = self.write_footer(ldatec) body += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(familieslistpage, output_file, sio, ldatec)
def placelistpage(self, report, title, place_handles): """ Create a place index @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: place_handles -- The handle for the place to add """ BasePage.__init__(self, report, title) output_file, sio = self.report.create_file("places") placelistpage, head, body = self.write_header(self._("Places")) ldatec = 0 prev_letter = " " # begin places division with Html("div", class_="content", id="Places") as placelist: body += placelist # place list page message msg = self._("This page contains an index of all the places in the " "database, sorted by their title. " "Clicking on a place’s " "title will take you to that place’s page.") placelist += Html("p", msg, id="description") # begin alphabet navigation index_list = get_first_letters(self.r_db, place_handles, _KEYPLACE, rlocale=self.rlocale) alpha_nav = alphabet_navigation(index_list, self.rlocale) if alpha_nav is not None: placelist += alpha_nav # begin places table and table head with Html("table", class_="infolist primobjlist placelist") as table: placelist += table # begin table head thead = Html("thead") table += thead trow = Html("tr") thead += trow if self.display_coordinates: trow.extend( Html("th", label, class_=colclass, inline=True) for (label, colclass) in [ [self._("Letter"), "ColumnLetter"], [self._("Place Name | Name"), "ColumnName"], [self._("State/ Province"), "ColumnState"], [self._("Country"), "ColumnCountry"], [self._("Latitude"), "ColumnLatitude"], [self._("Longitude"), "ColumnLongitude"] ] ) else: trow.extend( Html("th", label, class_=colclass, inline=True) for (label, colclass) in [ [self._("Letter"), "ColumnLetter"], [self._("Place Name | Name"), "ColumnName"], [self._("State/ Province"), "ColumnState"], [self._("Country"), "ColumnCountry"] ] ) # bug 9495 : incomplete display of place hierarchy labels def sort_by_place_name(obj): """ sort by lower case place name. """ name = self.report.obj_dict[Place][obj][1] return name.lower() handle_list = sorted(place_handles, key=lambda x: sort_by_place_name(x)) first = True # begin table body tbody = Html("tbody") table += tbody for place_handle in handle_list: place = self.r_db.get_place_from_handle(place_handle) if place: if place.get_change_time() > ldatec: ldatec = place.get_change_time() plc_title = self.report.obj_dict[Place][place_handle][1] main_location = get_main_location(self.r_db, place) if plc_title and plc_title != " ": letter = get_index_letter(first_letter(plc_title), index_list, self.rlocale) else: letter = ' ' trow = Html("tr") tbody += trow tcell = Html("td", class_="ColumnLetter", inline=True) trow += tcell if first or primary_difference(letter, prev_letter, self.rlocale): first = False prev_letter = letter trow.attr = 'class = "BeginLetter"' ttle = self._("Places beginning " "with letter %s") % letter tcell += Html("a", letter, name=letter, title=ttle) else: tcell += " " trow += Html("td", self.place_link( place.get_handle(), plc_title, place.get_gramps_id()), class_="ColumnName") trow.extend( Html("td", data or " ", class_=colclass, inline=True) for (colclass, data) in [ ["ColumnState", main_location.get(PlaceType.STATE, '')], ["ColumnCountry", main_location.get(PlaceType.COUNTRY, '')] ] ) if self.display_coordinates: tcell1 = Html("td", class_="ColumnLatitude", inline=True) tcell2 = Html("td", class_="ColumnLongitude", inline=True) trow += (tcell1, tcell2) if place.lat and place.long: latitude, longitude = conv_lat_lon(place.lat, place.long, "DEG") tcell1 += latitude tcell2 += longitude else: tcell1 += ' ' tcell2 += ' ' # add clearline for proper styling # add footer section footer = self.write_footer(ldatec) body += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(placelistpage, output_file, sio, ldatec)
def placelistpage(self, report, the_lang, the_title): """ Create a place index @param: report -- The instance of the main report class for this report @param: the_lang -- The lang to process @param: the_title -- The title page related to the language """ BasePage.__init__(self, report, the_lang, the_title) output_file, sio = self.report.create_file("places") result = self.write_header(self._("Places")) placelistpage, dummy_head, dummy_body, outerwrapper = result ldatec = 0 # begin places division with Html("div", class_="content", id="Places") as placelist: outerwrapper += placelist # place list page message msg = self._("This page contains an index of all the places in the " "database, sorted by their title. " "Clicking on a place’s " "title will take you to that place’s page.") placelist += Html("p", msg, id="description") # begin alphabet navigation # Assemble all the places index = AlphabeticIndex(self.rlocale) # self.report.obj_dict[PlaceName] is a dict with key place_name and # values (place_fname, place_name, place.gramps_id, event) for (place_name, value) in self.report.obj_dict[PlaceName].items(): index.addRecord(place_name, value) # Extract the buckets from the index index_list = [] index.resetBucketIterator() while index.nextBucket(): if index.bucketRecordCount != 0: index_list.append(index.bucketLabel) # Output the navigation alpha_nav = alphabet_navigation(index_list, self.rlocale) if alpha_nav: placelist += alpha_nav # begin places table and table head with Html("table", class_="infolist primobjlist placelist") as table: placelist += table # begin table head thead = Html("thead") table += thead trow = Html("tr") thead += trow if self.display_coordinates: trow.extend( Html("th", label, class_=colclass, inline=True) for (label, colclass) in [ [self._("Letter"), "ColumnLetter"], [self._("Name", "Place Name"), "ColumnName"], [self._("State/Province"), "ColumnState"], [self._("Country"), "ColumnCountry"], [self._("Latitude"), "ColumnLatitude"], [self._("Longitude"), "ColumnLongitude"] ] ) else: trow.extend( Html("th", label, class_=colclass, inline=True) for (label, colclass) in [ [self._("Letter"), "ColumnLetter"], [self._("Name", "Place Name"), "ColumnName"], [self._("State/Province"), "ColumnState"], [self._("Country"), "ColumnCountry"] ] ) # begin table body tbody = Html("tbody") table += tbody # For each bucket, output the places in that bucket index.resetBucketIterator() output = [] dup_index = 0 while index.nextBucket(): if index.bucketRecordCount != 0: bucket_letter = index.bucketLabel bucket_link = bucket_letter if bucket_letter in output: bucket_link = "%s (%i)" % (bucket_letter, dup_index) dup_index += 1 output.append(bucket_letter) # Assemble all the places in this bucket into a dict for # sorting place_dict = dict() while index.nextRecord(): place_name = index.recordName value = index.recordData place_dict[place_name] = value handle_list = sort_places(self.r_db, place_dict, self.rlocale) first_place = True for (pname, place_handle) in handle_list: (ldatec, first_place) \ = self.__output_place(ldatec, trow, first_place, pname, place_handle, bucket_letter, bucket_link) # add clearline for proper styling # add footer section footer = self.write_footer(ldatec) outerwrapper += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(placelistpage, output_file, sio, ldatec)
def familylistpage(self, report, the_lang, the_title, fam_list): """ Create a family index @param: report -- The instance of the main report class for this report @param: the_lang -- The lang to process @param: the_title -- The title page related to the language @param: fam_list -- The handle for the place to add """ BasePage.__init__(self, report, the_lang, the_title) output_file, sio = self.report.create_file("families") result = self.write_header(self._("Families")) familieslistpage, dummy_head, dummy_body, outerwrapper = result ldatec = 0 # begin Family Division with Html("div", class_="content", id="Relationships") as relationlist: outerwrapper += relationlist # Families list page message msg = self._("This page contains an index of all the " "families/ relationships in the " "database, sorted by their family name/ surname. " "Clicking on a person’s " "name will take you to their " "family/ relationship’s page.") relationlist += Html("p", msg, id="description") # go through all the families, and construct a dictionary of all the # people and the families they are involved in. Note that the people # in the list may be involved in OTHER families, that are not listed # because they are not in the original family list. pers_fam_dict = defaultdict(list) for family_handle in fam_list: family = self.r_db.get_family_from_handle(family_handle) if family: if family.get_change_time() > ldatec: ldatec = family.get_change_time() husband_handle = family.get_father_handle() spouse_handle = family.get_mother_handle() if husband_handle: pers_fam_dict[husband_handle].append(family) if spouse_handle: pers_fam_dict[spouse_handle].append(family) # Assemble all the people, we no longer care about their families index = AlphabeticIndex(self.rlocale) for (person_handle, dummy_family) in pers_fam_dict.items(): person = self.r_db.get_person_from_handle(person_handle) surname = get_surname_from_person(self.r_db, person) index.addRecord(surname, person_handle) # Extract the buckets from the index index_list = [] index.resetBucketIterator() while index.nextBucket(): if index.bucketRecordCount != 0: index_list.append(index.bucketLabel) # Output the navigation # add alphabet navigation alpha_nav = alphabet_navigation(index_list, self.rlocale) if alpha_nav: relationlist += alpha_nav # begin families table and table head with Html("table", class_="infolist relationships") as table: relationlist += table thead = Html("thead") table += thead trow = Html("tr") thead += trow # set up page columns trow.extend( Html("th", trans, class_=colclass, inline=True) for trans, colclass in [(self._("Letter"), "ColumnRowLabel"), (self._("Person"), "ColumnPartner"), (self._("Family"), "ColumnPartner"), (self._("Marriage"), "ColumnDate"), (self._("Divorce"), "ColumnDate")] ) tbody = Html("tbody") table += tbody # for each bucket, output the people and their families in that # bucket index.resetBucketIterator() output = [] dup_index = 0 while index.nextBucket(): if index.bucketRecordCount != 0: bucket_letter = index.bucketLabel bucket_link = bucket_letter if bucket_letter in output: bucket_link = "%s (%i)" % (bucket_letter, dup_index) dup_index += 1 output.append(bucket_letter) # Assemble a dict of all the people in this bucket. surname_ppl_handle_dict = OrderedDict() while index.nextRecord(): # The records are returned sorted by recordName, # which is surname. we need to retain that order but # in addition sort by the rest of the name person_surname = index.recordName person_handle = index.recordData if person_surname in surname_ppl_handle_dict.keys(): surname_ppl_handle_dict[person_surname]\ .append(person_handle) else: surname_ppl_handle_dict[person_surname] = \ [person_handle] first_person = True for (surname, handle_list) in \ surname_ppl_handle_dict.items(): # get person from sorted database list for person_handle in sorted( handle_list, key=self.sort_on_name_and_grampsid): person = self.r_db.get_person_from_handle\ (person_handle) if person: family_list = person.\ get_family_handle_list() first_family = True for family_handle in family_list: (ldatec, first_person, first_family) \ = self.__output_family(ldatec, family_handle, person_handle, tbody, bucket_letter, bucket_link, first_person, first_family) # add clearline for proper styling # add footer section footer = self.write_footer(ldatec) outerwrapper += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(familieslistpage, output_file, sio, ldatec)
def eventlistpage(self, report, title, event_types, event_handle_list): """ Will create the event list page @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: event_types -- A list of the type in the events database @param: event_handle_list -- A list of event handles """ BasePage.__init__(self, report, title) ldatec = 0 prev_letter = " " output_file, sio = self.report.create_file("events") eventslistpage, head, body = self.write_header(self._("Events")) # begin events list division with Html("div", class_="content", id="EventList") as eventlist: body += eventlist msg = self._( "This page contains an index of all the events in the " "database, sorted by their type and date (if one is " "present). Clicking on an event’s Gramps ID " "will open a page for that event.") eventlist += Html("p", msg, id="description") # get alphabet navigation... index_list = get_first_letters(self.r_db, event_types, _ALPHAEVENT) alpha_nav = alphabet_navigation(index_list, self.rlocale) if alpha_nav: eventlist += alpha_nav # begin alphabet event table with Html("table", class_="infolist primobjlist alphaevent") as table: eventlist += table thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", label, class_=colclass, inline=True) for (label, colclass) in [(self._("Letter"), "ColumnRowLabel"), ( self._("Type"), "ColumnType"), (self._("Date"), "ColumnDate"), (self._("Gramps ID"), "ColumnGRAMPSID"), (self._("Person"), "ColumnPerson")]) tbody = Html("tbody") table += tbody # separate events by their type and then thier event handles for (evt_type, data_list) in sort_event_types(self.r_db, event_types, event_handle_list, self.rlocale): first = True _event_displayed = [] # sort datalist by date of event and by event handle... data_list = sorted(data_list, key=itemgetter(0, 1)) first_event = True for (sort_value, event_handle) in data_list: event = self.r_db.get_event_from_handle(event_handle) _type = event.get_type() gid = event.get_gramps_id() if event.get_change_time() > ldatec: ldatec = event.get_change_time() # check to see if we have listed this gramps_id yet? if gid not in _event_displayed: # family event if int(_type) in _EVENTMAP: handle_list = set( self.r_db.find_backlink_handles( event_handle, include_classes=['Family', 'Person'])) else: handle_list = set( self.r_db.find_backlink_handles( event_handle, include_classes=['Person'])) if handle_list: trow = Html("tr") tbody += trow # set up hyperlinked letter for # alphabet_navigation tcell = Html("td", class_="ColumnLetter", inline=True) trow += tcell if evt_type and not evt_type.isspace(): letter = get_index_letter( self._(str(evt_type)[0].capitalize()), index_list, self.rlocale) else: letter = " " if first or primary_difference( letter, prev_letter, self.rlocale): first = False prev_letter = letter t_a = 'class = "BeginLetter BeginType"' trow.attr = t_a ttle = self._("Event types beginning " "with letter %s") % letter tcell += Html("a", letter, name=letter, id_=letter, title=ttle, inline=True) else: tcell += " " # display Event type if first in the list tcell = Html("td", class_="ColumnType", title=self._(evt_type), inline=True) trow += tcell if first_event: tcell += self._(evt_type) if trow.attr == "": trow.attr = 'class = "BeginType"' else: tcell += " " # event date tcell = Html("td", class_="ColumnDate", inline=True) trow += tcell date = Date.EMPTY if event: date = event.get_date_object() if date and date is not Date.EMPTY: tcell += self.rlocale.get_date(date) else: tcell += " " # Gramps ID trow += Html("td", class_="ColumnGRAMPSID") + ( self.event_grampsid_link( event_handle, gid, None)) # Person(s) column tcell = Html("td", class_="ColumnPerson") trow += tcell # classname can either be a person or a family first_person = True # get person(s) for ColumnPerson sorted_list = sorted(handle_list) self.complete_people(tcell, first_person, sorted_list, uplink=False) _event_displayed.append(gid) first_event = False # add clearline for proper styling # add footer section footer = self.write_footer(ldatec) body += (FULLCLEAR, footer) # send page ut for processing # and close the file self.xhtml_writer(eventslistpage, output_file, sio, ldatec)
def sourcelistpage(self, report, title, source_handles): """ Generate and output the Sources index page. @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: source_handles -- A list of the handles of the sources to be displayed """ BasePage.__init__(self, report, title) source_dict = {} output_file, sio = self.report.create_file("sources") sourcelistpage, head, body = self.write_header(self._("Sources")) # begin source list division with Html("div", class_="content", id="Sources") as sourceslist: body += sourceslist # Sort the sources for handle in source_handles: source = self.r_db.get_source_from_handle(handle) if source is not None: key = source.get_title() + source.get_author() key += str(source.get_gramps_id()) source_dict[key] = (source, handle) keys = sorted(source_dict, key=self.rlocale.sort_key) msg = self._("This page contains an index of all the sources " "in the database, sorted by their title. " "Clicking on a source’s " "title will take you to that source’s page.") sourceslist += Html("p", msg, id="description") # begin sourcelist table and table head with Html("table", class_="infolist primobjlist sourcelist") as table: sourceslist += table thead = Html("thead") table += thead trow = Html("tr") thead += trow header_row = [ (self._("Number"), "ColumnRowLabel"), (self._("Author"), "ColumnAuthor"), (self._("Source Name|Name"), "ColumnName")] trow.extend( Html("th", label or " ", class_=colclass, inline=True) for (label, colclass) in header_row ) # begin table body tbody = Html("tbody") table += tbody for index, key in enumerate(keys): source, source_handle = source_dict[key] trow = Html("tr") + ( Html("td", index + 1, class_="ColumnRowLabel", inline=True) ) tbody += trow trow.extend( Html("td", source.get_author(), class_="ColumnAuthor", inline=True) ) trow.extend( Html("td", self.source_link(source_handle, source.get_title(), source.get_gramps_id()), class_="ColumnName") ) # add clearline for proper styling # add footer section footer = self.write_footer(None) body += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(sourcelistpage, output_file, sio, 0)
def __init__(self, report, title): """ @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page """ BasePage.__init__(self, report, title) # do NOT include a Download Page if not self.report.inc_download: return # menu options for class # download and description #n ( 1 <= n < 5 ) dlfname = self.report.dl_fname dldescr = self.report.dl_descr # if no filenames at all, return??? if dlfname: output_file, sio = self.report.create_file("download") result = self.write_header(self._('Download')) downloadpage, dummy_head, dummy_body, outerwrapper = result # begin download page and table with Html("div", class_="content", id="Download") as download: outerwrapper += download msg = self._("This page is for the user/ creator " "of this Family Tree/ Narrative website " "to share a couple of files with you " "regarding their family. If there are " "any files listed " "below, clicking on them will allow you " "to download them. The " "download page and files have the same " "copyright as the remainder " "of these web pages.") download += Html("p", msg, id="description") # begin download table and table head with Html("table", class_="infolist download") as table: download += table thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", label, class_="Column" + colclass, inline=True) for (label, colclass) in [( self._("File Name"), "Filename"), ( self._("Description"), "Description" ), (self._("Last Modified"), "Modified"), (self._("MD5"), "Md5")]) # table body tbody = Html("tbody") table += tbody dwnld = 0 for fnamex in dlfname: # if fnamex is not None, do we have a file to download? if fnamex: fname = os.path.basename(dlfname[fnamex]) # if fname is not None, show it if fname: dwnld += 1 trow = Html("tr", id='Row01') tbody += trow dldescrx = dldescr[fnamex] tcell = Html("td", class_="ColumnFilename") + ( Html("a", fname, href=fname, title=html_escape(dldescrx))) trow += tcell dldescr1 = dldescrx or " " trow += Html("td", dldescr1, inline=True, class_="ColumnDescription") tcell = Html("td", class_="ColumnModified", inline=True) trow += tcell if os.path.exists(dlfname[fnamex]): md5 = create_checksum(dlfname[fnamex]) trow += Html("td", md5, class_="ColumnMd5", inline=True) modified = os.stat( dlfname[fnamex]).st_mtime last_mod = datetime.datetime.fromtimestamp( modified) tcell += last_mod # copy the file self.report.copy_file( dlfname[fnamex], fname) else: tcell += self._("Cannot open file") if not dwnld: # We have several files to download # but all file names are empty dldescrx = _("No file to download") trow = Html("tr", id='Row01') tbody += trow tcell = Html("td", class_="ColumnFilename", colspan=3) + Html("h2", dldescrx) trow += tcell # clear line for proper styling # create footer section footer = self.write_footer(None) outerwrapper += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(downloadpage, output_file, sio, 0)
def eventlistpage(self, report, title, event_types, event_handle_list): """ Will create the event list page @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: event_types -- A list of the type in the events database @param: event_handle_list -- A list of event handles """ BasePage.__init__(self, report, title) ldatec = 0 prev_letter = " " output_file, sio = self.report.create_file("events") eventslistpage, head, body = self.write_header(self._("Events")) # begin events list division with Html("div", class_="content", id="EventList") as eventlist: body += eventlist msg = self._("This page contains an index of all the events in the " "database, sorted by their type and date (if one is " "present). Clicking on an event’s Gramps ID " "will open a page for that event.") eventlist += Html("p", msg, id="description") # get alphabet navigation... index_list = get_first_letters(self.r_db, event_types, _ALPHAEVENT) alpha_nav = alphabet_navigation(index_list, self.rlocale) if alpha_nav: eventlist += alpha_nav # begin alphabet event table with Html("table", class_="infolist primobjlist alphaevent") as table: eventlist += table thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", label, class_=colclass, inline=True) for (label, colclass) in [(self._("Letter"), "ColumnRowLabel"), (self._("Type"), "ColumnType"), (self._("Date"), "ColumnDate"), (self._("Gramps ID"), "ColumnGRAMPSID"), (self._("Person"), "ColumnPerson") ] ) tbody = Html("tbody") table += tbody # separate events by their type and then thier event handles for (evt_type, data_list) in sort_event_types(self.r_db, event_types, event_handle_list, self.rlocale): first = True _event_displayed = [] # sort datalist by date of event and by event handle... data_list = sorted(data_list, key=itemgetter(0, 1)) first_event = True for (sort_value, event_handle) in data_list: event = self.r_db.get_event_from_handle(event_handle) _type = event.get_type() gid = event.get_gramps_id() if event.get_change_time() > ldatec: ldatec = event.get_change_time() # check to see if we have listed this gramps_id yet? if gid not in _event_displayed: # family event if int(_type) in _EVENTMAP: handle_list = set( self.r_db.find_backlink_handles( event_handle, include_classes=['Family', 'Person'])) else: handle_list = set( self.r_db.find_backlink_handles( event_handle, include_classes=['Person'])) if handle_list: trow = Html("tr") tbody += trow # set up hyperlinked letter for # alphabet_navigation tcell = Html("td", class_="ColumnLetter", inline=True) trow += tcell if evt_type and not evt_type.isspace(): letter = get_index_letter( self._(str(evt_type)[0].capitalize()), index_list, self.rlocale) else: letter = " " if first or primary_difference(letter, prev_letter, self.rlocale): first = False prev_letter = letter t_a = 'class = "BeginLetter BeginType"' trow.attr = t_a ttle = self._("Event types beginning " "with letter %s") % letter tcell += Html("a", letter, name=letter, id_=letter, title=ttle, inline=True) else: tcell += " " # display Event type if first in the list tcell = Html("td", class_="ColumnType", title=self._(evt_type), inline=True) trow += tcell if first_event: tcell += self._(evt_type) if trow.attr == "": trow.attr = 'class = "BeginType"' else: tcell += " " # event date tcell = Html("td", class_="ColumnDate", inline=True) trow += tcell date = Date.EMPTY if event: date = event.get_date_object() if date and date is not Date.EMPTY: tcell += self.rlocale.get_date(date) else: tcell += " " # Gramps ID trow += Html("td", class_="ColumnGRAMPSID") + ( self.event_grampsid_link(event_handle, gid, None) ) # Person(s) column tcell = Html("td", class_="ColumnPerson") trow += tcell # classname can either be a person or a family first_person = True # get person(s) for ColumnPerson sorted_list = sorted(handle_list) self.complete_people(tcell, first_person, sorted_list, uplink=False) _event_displayed.append(gid) first_event = False # add clearline for proper styling # add footer section footer = self.write_footer(ldatec) body += (FULLCLEAR, footer) # send page ut for processing # and close the file self.xhtml_writer(eventslistpage, output_file, sio, ldatec)
def familylistpage(self, report, title, fam_list): """ Create a family index @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: fam_list -- The handle for the place to add """ BasePage.__init__(self, report, title) output_file, sio = self.report.create_file("families") result = self.write_header(self._("Families")) familieslistpage, dummy_head, dummy_body, outerwrapper = result ldatec = 0 prev_letter = " " # begin Family Division with Html("div", class_="content", id="Relationships") as relationlist: outerwrapper += relationlist # Families list page message msg = self._("This page contains an index of all the " "families/ relationships in the " "database, sorted by their family name/ surname. " "Clicking on a person’s " "name will take you to their " "family/ relationship’s page.") relationlist += Html("p", msg, id="description") # go through all the families, and construct a dictionary of all the # people and the families thay are involved in. Note that the people # in the list may be involved in OTHER families, that are not listed # because they are not in the original family list. pers_fam_dict = defaultdict(list) for family_handle in fam_list: family = self.r_db.get_family_from_handle(family_handle) if family: if family.get_change_time() > ldatec: ldatec = family.get_change_time() husband_handle = family.get_father_handle() spouse_handle = family.get_mother_handle() if husband_handle: pers_fam_dict[husband_handle].append(family) if spouse_handle: pers_fam_dict[spouse_handle].append(family) # add alphabet navigation index_list = get_first_letters(self.r_db, pers_fam_dict.keys(), _KEYPERSON, rlocale=self.rlocale) alpha_nav = alphabet_navigation(index_list, self.rlocale) if alpha_nav: relationlist += alpha_nav # begin families table and table head with Html("table", class_="infolist relationships") as table: relationlist += table thead = Html("thead") table += thead trow = Html("tr") thead += trow # set up page columns trow.extend( Html("th", trans, class_=colclass, inline=True) for trans, colclass in [(self._("Letter"), "ColumnRowLabel"), (self._("Person"), "ColumnPartner"), (self._("Family"), "ColumnPartner"), (self._("Marriage"), "ColumnDate"), (self._("Divorce"), "ColumnDate")] ) tbody = Html("tbody") table += tbody # begin displaying index list ppl_handle_list = sort_people(self.r_db, pers_fam_dict.keys(), self.rlocale) first = True for (surname, handle_list) in ppl_handle_list: if surname and not surname.isspace(): letter = get_index_letter(first_letter(surname), index_list, self.rlocale) else: letter = ' ' # get person from sorted database list for person_handle in sorted( handle_list, key=self.sort_on_name_and_grampsid): person = self.r_db.get_person_from_handle(person_handle) if person: family_list = person.get_family_handle_list() first_family = True for family_handle in family_list: get_family = self.r_db.get_family_from_handle family = get_family(family_handle) trow = Html("tr") tbody += trow tcell = Html("td", class_="ColumnRowLabel") trow += tcell if first or primary_difference(letter, prev_letter, self.rlocale): first = False prev_letter = letter trow.attr = 'class="BeginLetter"' ttle = self._("Families beginning with " "letter ") tcell += Html("a", letter, name=letter, title=ttle + letter, inline=True) else: tcell += ' ' tcell = Html("td", class_="ColumnPartner") trow += tcell if first_family: trow.attr = 'class ="BeginFamily"' tcell += self.new_person_link( person_handle, uplink=self.uplink) first_family = False else: tcell += ' ' tcell = Html("td", class_="ColumnPartner") trow += tcell tcell += self.family_link( family.get_handle(), self.report.get_family_name(family), family.get_gramps_id(), self.uplink) # family events; such as marriage and divorce # events fam_evt_ref_list = family.get_event_ref_list() tcell1 = Html("td", class_="ColumnDate", inline=True) tcell2 = Html("td", class_="ColumnDate", inline=True) trow += (tcell1, tcell2) if fam_evt_ref_list: fam_evt_srt_ref_list = sorted( fam_evt_ref_list, key=self.sort_on_grampsid) for evt_ref in fam_evt_srt_ref_list: evt = self.r_db.get_event_from_handle( evt_ref.ref) if evt: evt_type = evt.get_type() if evt_type in [EventType.MARRIAGE, EventType.DIVORCE]: cell = self.rlocale.get_date( evt.get_date_object()) if (evt_type == EventType.MARRIAGE): tcell1 += cell else: tcell1 += ' ' if (evt_type == EventType.DIVORCE): tcell2 += cell else: tcell2 += ' ' else: tcell1 += ' ' tcell2 += ' ' first_family = False # add clearline for proper styling # add footer section footer = self.write_footer(ldatec) outerwrapper += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(familieslistpage, output_file, sio, ldatec)
def medialistpage(self, report, title, sorted_media_handles): """ Generate and output the Media index page. @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: sorted_media_handles -- A list of the handles of the media to be displayed sorted by the media title """ BasePage.__init__(self, report, title) output_file, sio = self.report.create_file("media") # save the media file name in case we create unused media pages self.cur_fname = self.report.cur_fname medialistpage, head, body = self.write_header(self._('Media')) ldatec = 0 # begin gallery division with Html("div", class_="content", id="Gallery") as medialist: body += medialist msg = self._( "This page contains an index of all the media objects " "in the database, sorted by their title. Clicking on " "the title will take you to that " "media object’s page. " "If you see media size dimensions " "above an image, click on the " "image to see the full sized version. ") medialist += Html("p", msg, id="description") # begin gallery table and table head with Html("table", class_="infolist primobjlist gallerylist") as table: medialist += table # begin table head thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", trans, class_=colclass, inline=True) for trans, colclass in [( " ", "ColumnRowLabel" ), (self._("Media | Name"), "ColumnName"), ( self._("Date"), "ColumnDate"), (self._("Mime Type"), "ColumnMime")]) # begin table body tbody = Html("tbody") table += tbody index = 1 for media_handle in sorted_media_handles: media = self.r_db.get_media_from_handle(media_handle) if media: if media.get_change_time() > ldatec: ldatec = media.get_change_time() title = media.get_description() or "[untitled]" trow = Html("tr") tbody += trow media_data_row = [ [index, "ColumnRowLabel"], [ self.media_ref_link(media_handle, title), "ColumnName" ], [ self.rlocale.get_date(media.get_date_object()), "ColumnDate" ], [media.get_mime_type(), "ColumnMime"] ] trow.extend( Html("td", data, class_=colclass) for data, colclass in media_data_row) index += 1 def sort_by_desc_and_gid(obj): """ Sort by media description and gramps ID """ return (obj.desc, obj.gramps_id) unused_media_handles = [] if self.create_unused_media: # add unused media media_list = self.r_db.get_media_handles() for media_ref in media_list: if media_ref not in self.report.obj_dict[Media]: unused_media_handles.append(media_ref) unused_media_handles = sorted( unused_media_handles, key=lambda x: sort_by_desc_and_gid( self.r_db.get_media_from_handle(x))) idx = 1 prev = None total = len(unused_media_handles) if total > 0: trow += Html("tr") trow.extend( Html("td", Html("h4", " "), inline=True) + Html("td", Html("h4", self._("Below unused media objects"), inline=True), class_="") + Html("td", Html("h4", " "), inline=True) + Html("td", Html("h4", " "), inline=True)) for media_handle in unused_media_handles: media = self.r_db.get_media_from_handle(media_handle) gc.collect() # Reduce memory usage when many images. next_ = None if idx == total else unused_media_handles[idx] trow += Html("tr") media_data_row = [ [index, "ColumnRowLabel"], [ self.media_ref_link(media_handle, media.get_description()), "ColumnName" ], [ self.rlocale.get_date(media.get_date_object()), "ColumnDate" ], [media.get_mime_type(), "ColumnMime"] ] trow.extend( Html("td", data, class_=colclass) for data, colclass in media_data_row) self.mediapage(self.report, title, media_handle, (prev, next_, index, total)) prev = media_handle index += 1 idx += 1 # add footer section # add clearline for proper styling footer = self.write_footer(ldatec) body += (FULLCLEAR, footer) # send page out for processing # and close the file self.report.cur_fname = self.cur_fname self.xhtml_writer(medialistpage, output_file, sio, ldatec)
def placelistpage(self, report, title, place_handles): """ Create a place index @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: place_handles -- The handle for the place to add """ BasePage.__init__(self, report, title) output_file, sio = self.report.create_file("places") result = self.write_header(self._("Places")) placelistpage, dummy_head, dummy_body, outerwrapper = result ldatec = 0 prev_letter = " " # begin places division with Html("div", class_="content", id="Places") as placelist: outerwrapper += placelist # place list page message msg = self._( "This page contains an index of all the places in the " "database, sorted by their title. " "Clicking on a place’s " "title will take you to that place’s page.") placelist += Html("p", msg, id="description") # begin alphabet navigation index_list = get_first_letters(self.r_db, place_handles, _KEYPLACE, rlocale=self.rlocale) alpha_nav = alphabet_navigation(index_list, self.rlocale) if alpha_nav is not None: placelist += alpha_nav # begin places table and table head with Html("table", class_="infolist primobjlist placelist") as table: placelist += table # begin table head thead = Html("thead") table += thead trow = Html("tr") thead += trow if self.display_coordinates: trow.extend( Html("th", label, class_=colclass, inline=True) for (label, colclass ) in [[self._("Letter"), "ColumnLetter"], [self._("Place Name | Name"), "ColumnName"], [self._("State/ Province"), "ColumnState"], [self._("Country"), "ColumnCountry"], [self._("Latitude"), "ColumnLatitude"], [self._("Longitude"), "ColumnLongitude"]]) else: trow.extend( Html("th", label, class_=colclass, inline=True) for (label, colclass ) in [[self._("Letter"), "ColumnLetter"], [self._("Place Name | Name"), "ColumnName"], [self._("State/ Province"), "ColumnState"], [self._("Country"), "ColumnCountry"]]) # bug 9495 : incomplete display of place hierarchy labels def sort_by_place_name(obj): """ sort by lower case place name. """ name = self.report.obj_dict[Place][obj][1] return name.lower() handle_list = sorted(place_handles, key=lambda x: sort_by_place_name(x)) first = True # begin table body tbody = Html("tbody") table += tbody for place_handle in handle_list: place = self.r_db.get_place_from_handle(place_handle) if place: if place.get_change_time() > ldatec: ldatec = place.get_change_time() plc_title = self.report.obj_dict[Place][place_handle][ 1] main_location = get_main_location(self.r_db, place) if plc_title and plc_title != " ": letter = get_index_letter(first_letter(plc_title), index_list, self.rlocale) else: letter = ' ' trow = Html("tr") tbody += trow tcell = Html("td", class_="ColumnLetter", inline=True) trow += tcell if first or primary_difference(letter, prev_letter, self.rlocale): first = False prev_letter = letter trow.attr = 'class = "BeginLetter"' ttle = self._("Places beginning " "with letter %s") % letter tcell += Html("a", letter, name=letter, title=ttle) else: tcell += " " trow += Html("td", self.place_link(place.get_handle(), plc_title, place.get_gramps_id()), class_="ColumnName") trow.extend( Html("td", data or " ", class_=colclass, inline=True) for (colclass, data) in [[ "ColumnState", main_location.get(PlaceType.STATE, '') ], [ "ColumnCountry", main_location.get(PlaceType.COUNTRY, '') ]]) if self.display_coordinates: tcell1 = Html("td", class_="ColumnLatitude", inline=True) tcell2 = Html("td", class_="ColumnLongitude", inline=True) trow += (tcell1, tcell2) if place.lat and place.long: latitude, longitude = conv_lat_lon( place.lat, place.long, "DEG") tcell1 += latitude tcell2 += longitude else: tcell1 += ' ' tcell2 += ' ' # add clearline for proper styling # add footer section footer = self.write_footer(ldatec) outerwrapper += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(placelistpage, output_file, sio, ldatec)
def __init__(self, report, title, has_url_addr_res): """ @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: has_url_addr_res -- The url, address and residence to use for the report """ BasePage.__init__(self, report, title) # Name the file, and create it output_file, sio = self.report.create_file("addressbook") # Add xml, doctype, meta and stylesheets addressbooklistpage, head, body = self.write_header(_("Address Book")) # begin AddressBookList division with Html("div", class_="content", id="AddressBookList") as addressbooklist: body += addressbooklist # Address Book Page message msg = _("This page contains an index of all the individuals in " "the database, sorted by their surname, with one of the " "following: Address, Residence, or Web Links. " "Selecting the person’s name will take you " "to their individual Address Book page.") addressbooklist += Html("p", msg, id="description") # begin Address Book table with Html("table", class_="infolist primobjlist addressbook") as table: addressbooklist += table thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", label, class_=colclass, inline=True) for (label, colclass) in [ [" ", "ColumnRowLabel"], [_("Full Name"), "ColumnName"], [_("Address"), "ColumnAddress"], [_("Residence"), "ColumnResidence"], [_("Web Links"), "ColumnWebLinks"] ] ) tbody = Html("tbody") table += tbody index = 1 for (sort_name, person_handle, has_add, has_res, has_url) in has_url_addr_res: address = None residence = None weblinks = None # has address but no residence event if has_add and not has_res: address = "X" # has residence, but no addresses elif has_res and not has_add: residence = "X" # has residence and addresses too elif has_add and has_res: address = "X" residence = "X" # has Web Links if has_url: weblinks = "X" trow = Html("tr") tbody += trow trow.extend( Html("td", data or " ", class_=colclass, inline=True) for (colclass, data) in [ ["ColumnRowLabel", index], ["ColumnName", self.addressbook_link(person_handle)], ["ColumnAddress", address], ["ColumnResidence", residence], ["ColumnWebLinks", weblinks] ] ) index += 1 # Add footer and clearline footer = self.write_footer(None) body += (FULLCLEAR, footer) # send the page out for processing # and close the file self.xhtml_writer(addressbooklistpage, output_file, sio, 0)
def __init__(self, report, title): """ @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page """ BasePage.__init__(self, report, title) # do NOT include a Download Page if not self.report.inc_download: return # menu options for class # download and description #1 dlfname1 = self.report.dl_fname1 dldescr1 = self.report.dl_descr1 # download and description #2 dlfname2 = self.report.dl_fname2 dldescr2 = self.report.dl_descr2 # if no filenames at all, return??? if dlfname1 or dlfname2: output_file, sio = self.report.create_file("download") downloadpage, head, body = self.write_header(self._('Download')) # begin download page and table with Html("div", class_="content", id="Download") as download: body += download msg = self._("This page is for the user/ creator " "of this Family Tree/ Narrative website " "to share a couple of files with you " "regarding their family. If there are " "any files listed " "below, clicking on them will allow you " "to download them. The " "download page and files have the same " "copyright as the remainder " "of these web pages.") download += Html("p", msg, id="description") # begin download table and table head with Html("table", class_="infolist download") as table: download += table thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", label, class_="Column" + colclass, inline=True) for (label, colclass) in [( self._("File Name"), "Filename"), (self._("Description"), "Description"), (self._("Last Modified"), "Modified")]) # table body tbody = Html("tbody") table += tbody # if dlfname1 is not None, show it??? if dlfname1: trow = Html("tr", id='Row01') tbody += trow fname = os.path.basename(dlfname1) # TODO dlfname1 is filename, convert disk path to URL tcell = Html("td", class_="ColumnFilename") + (Html( "a", fname, href=dlfname1, title=html_escape(dldescr1))) trow += tcell dldescr1 = dldescr1 or " " trow += Html("td", dldescr1, class_="ColumnDescription", inline=True) tcell = Html("td", class_="ColumnModified", inline=True) trow += tcell if os.path.exists(dlfname1): modified = os.stat(dlfname1).st_mtime last_mod = datetime.datetime.fromtimestamp( modified) tcell += last_mod else: tcell += " " # if download filename #2, show it??? if dlfname2: # begin row #2 trow = Html("tr", id='Row02') tbody += trow fname = os.path.basename(dlfname2) tcell = Html("td", class_="ColumnFilename") + (Html( "a", fname, href=dlfname2, title=html_escape(dldescr2))) trow += tcell dldescr2 = dldescr2 or " " trow += Html("td", dldescr2, class_="ColumnDescription", inline=True) tcell = Html("td", id='Col04', class_="ColumnModified", inline=True) trow += tcell if os.path.exists(dlfname2): modified = os.stat(dlfname2).st_mtime last_mod = datetime.datetime.fromtimestamp( modified) tcell += last_mod else: tcell += " " # clear line for proper styling # create footer section footer = self.write_footer(None) body += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(downloadpage, output_file, sio, 0)
def __init__(self, report, title): """ @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page """ BasePage.__init__(self, report, title) # do NOT include a Download Page if not self.report.inc_download: return # menu options for class # download and description #1 dlfname1 = self.report.dl_fname1 dldescr1 = self.report.dl_descr1 # download and description #2 dlfname2 = self.report.dl_fname2 dldescr2 = self.report.dl_descr2 # if no filenames at all, return??? if dlfname1 or dlfname2: output_file, sio = self.report.create_file("download") downloadpage, head, body = self.write_header(self._('Download')) # begin download page and table with Html("div", class_="content", id="Download") as download: body += download msg = self._("This page is for the user/ creator " "of this Family Tree/ Narrative website " "to share a couple of files with you " "regarding their family. If there are " "any files listed " "below, clicking on them will allow you " "to download them. The " "download page and files have the same " "copyright as the remainder " "of these web pages.") download += Html("p", msg, id="description") # begin download table and table head with Html("table", class_="infolist download") as table: download += table thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", label, class_="Column" + colclass, inline=True) for (label, colclass) in [ (self._("File Name"), "Filename"), (self._("Description"), "Description"), (self._("Last Modified"), "Modified")]) # table body tbody = Html("tbody") table += tbody # if dlfname1 is not None, show it??? if dlfname1: trow = Html("tr", id='Row01') tbody += trow fname = os.path.basename(dlfname1) # TODO dlfname1 is filename, convert disk path to URL tcell = Html("td", class_="ColumnFilename") + ( Html("a", fname, href=dlfname1, title=html_escape(dldescr1)) ) trow += tcell dldescr1 = dldescr1 or " " trow += Html("td", dldescr1, class_="ColumnDescription", inline=True) tcell = Html("td", class_="ColumnModified", inline=True) trow += tcell if os.path.exists(dlfname1): modified = os.stat(dlfname1).st_mtime last_mod = datetime.datetime.fromtimestamp(modified) tcell += last_mod else: tcell += " " # if download filename #2, show it??? if dlfname2: # begin row #2 trow = Html("tr", id='Row02') tbody += trow fname = os.path.basename(dlfname2) tcell = Html("td", class_="ColumnFilename") + ( Html("a", fname, href=dlfname2, title=html_escape(dldescr2)) ) trow += tcell dldescr2 = dldescr2 or " " trow += Html("td", dldescr2, class_="ColumnDescription", inline=True) tcell = Html("td", id='Col04', class_="ColumnModified", inline=True) trow += tcell if os.path.exists(dlfname2): modified = os.stat(dlfname2).st_mtime last_mod = datetime.datetime.fromtimestamp(modified) tcell += last_mod else: tcell += " " # clear line for proper styling # create footer section footer = self.write_footer(None) body += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(downloadpage, output_file, sio, 0)