def write_report(self): """ Generate the contents of the report """ self.doc.start_paragraph("SBT-Title") self.doc.write_text(self.title_string) self.doc.end_paragraph() self.doc.start_paragraph("SBT-Subtitle") self.doc.write_text(self.subtitle_string) self.doc.end_paragraph() if self.object_id: the_object = self.database.get_object_from_gramps_id(self.object_id) filename = media_path_full(self.database, the_object.get_path()) if os.path.exists(filename): if self.image_size: image_size = self.image_size else: image_size = min(0.8 * self.doc.get_usable_width(), 0.7 * self.doc.get_usable_height()) self.doc.add_media_object(filename, "center", image_size, image_size) else: self._user.warn(_("Could not add photo to page"), _("File %s does not exist") % filename) self.doc.start_paragraph("SBT-Footer") self.doc.write_text(self.footer_string) self.doc.end_paragraph()
def __init__(self, dbstate, uistate, track, mediaobj, callback=None): """ Create and displays the dialog box db - the database in which the new object is to be stored The mediaobject is updated with the information, and on save, the callback function is called """ ManagedWindow.__init__(self, uistate, track, self) self.dbase = dbstate.db self.obj = mediaobj self.callback = callback self.last_directory = config.get('behavior.addmedia-image-dir') self.relative_path = config.get('behavior.addmedia-relative-path') self.glade = Glade() self.set_window( self.glade.toplevel, self.glade.get_object('title'), _('Select a media object')) self.description = self.glade.get_object("photoDescription") self.image = self.glade.get_object("image") self.file_text = self.glade.get_object("fname") if not(self.last_directory and os.path.isdir(self.last_directory)): self.last_directory = USER_HOME #if existing path, use dir of path if not self.obj.get_path() == "": fullname = media_path_full(self.dbase, self.obj.get_path()) dir = os.path.dirname(fullname) if os.path.isdir(dir): self.last_directory = dir self.file_text.select_filename(fullname) else: self.file_text.set_current_folder(self.last_directory) else: self.file_text.set_current_folder(self.last_directory) if not self.obj.get_description() == "": self.description.set_text(self.obj.get_description()) self.relpath = self.glade.get_object('relpath') self.relpath.set_active(self.relative_path) self.temp_name = "" self.object = None self.glade.get_object('fname').connect('update_preview', self.on_name_changed) self.ok_button = self.glade.get_object('button79') self.help_button = self.glade.get_object('button103') self.cancel_button = self.glade.get_object('button81') self.ok_button.connect('clicked', self.save) self.ok_button.set_sensitive(not self.dbase.readonly) self.help_button.connect('clicked', lambda x: display_help( webpage=WIKI_HELP_PAGE, section=WIKI_HELP_SEC)) self.cancel_button.connect('clicked', self.close) self.show() self.modal_call()
def copy_source_file(self, handle, photo): """ Copy source file in the web tree. @param: handle -- Handle of the source @param: photo -- The source object (image, pdf, ...) """ ext = os.path.splitext(photo.get_path())[1] to_dir = self.report.build_path('images', handle) newpath = os.path.join(to_dir, handle) + ext fullpath = media_path_full(self.r_db, photo.get_path()) if not os.path.isfile(fullpath): _WRONGMEDIAPATH.append([photo.get_gramps_id(), fullpath]) return None try: mtime = os.stat(fullpath).st_mtime if self.report.archive: self.report.archive.add(fullpath, str(newpath)) else: to_dir = os.path.join(self.html_dir, to_dir) if not os.path.isdir(to_dir): os.makedirs(to_dir) new_file = os.path.join(self.html_dir, newpath) shutil.copyfile(fullpath, new_file) os.utime(new_file, (mtime, mtime)) return newpath except (IOError, OSError) as msg: error = _("Missing media object:" ) + "%s (%s)" % (photo.get_description(), photo.get_gramps_id()) self.r_user.warn(error, str(msg)) return None
def load_images(self, obj): """ Load the primary image into the main form if it exists. """ media_list = obj.get_media_list() count = 0 for media_ref in media_list: media_handle = media_ref.get_reference_handle() media = self.dbstate.db.get_media_from_handle(media_handle) full_path = media_path_full(self.dbstate.db, media.get_path()) mime_type = media.get_mime_type() if mime_type and mime_type.startswith("image"): photo = Photo(self.uistate.screen_height() < 1000) photo.set_image(full_path, mime_type, media_ref.get_rectangle()) photo.set_uistate(self.uistate, media_handle) else: photo = Photo(self.uistate.screen_height() < 1000) photo.set_pixbuf(full_path, get_thumbnail_image(full_path, mime_type, media_ref.get_rectangle())) self.image_list.append(photo) self.top.pack_start(photo, False, False, 0) count += 1 self.top.show_all() self.set_has_data(count > 0)
def view_media(self, obj): ref_obj = self.dbstate.db.get_media_from_handle(self.obj.handle) if ref_obj: media_path = media_path_full(self.dbstate.db, ref_obj.get_path()) open_file_with_default_application(media_path, self.uistate)
def detect_faces_clicked(self, event): self.uistate.push_message(self.dbstate, _("Detecting faces...")) media = self.get_current_object() image_path = media_path_full(self.dbstate.db, media.get_path()) faces, img_size = facedetection.detect_faces(image_path, MIN_FACE_SIZE, SENSITIVITY) # verify and enlarge found faces regions for (x, y, width, height) in faces: # calculate enlarged region new_x1 = x - width/5 new_y1 = y - height/3 new_x2 = x + width*6/5 new_y2 = y + height*7/5 # prevent overflow image size new_y1 = 0 if new_y1 < 0 else new_y1 new_y2 = img_size[0] if img_size[0] < new_y2 else new_y2 new_x1 = 0 if new_x1 < 0 else new_x1 new_x2 = img_size[1] if img_size[1] < new_x2 else new_x2 region = Region(new_x1, new_y1, new_x2, new_y2) if (DETECT_INSIDE_EXISTING_BOXES or self.enclosing_region(region) is None): self.regions.append(region) self.refresh() self.uistate.push_message(self.dbstate, _("Detection finished"))
def generate_md5(self, button): """ Generate md5 hashes for media files. """ self.clear_models() progress = ProgressMeter(self.window_name, can_cancel=True, parent=self.window) length = self.db.get_number_of_media() progress.set_pass(_('Generating media hashes'), length) with DbTxn(_("Set media hashes"), self.db, batch=True) as trans: for handle in self.db.get_media_handles(): media = self.db.get_media_from_handle(handle) full_path = media_path_full(self.db, media.get_path()) md5sum = create_checksum(full_path) if not md5sum: error_msg = 'IOError: %s' % full_path self.models[5].append((error_msg, None)) progress.step() continue media.set_checksum(md5sum) self.db.commit_media(media, trans) progress.step() if progress.get_cancelled(): break self.show_tabs() progress.close()
def load_image(self, media): """ Load the primary image if it exists. """ self.full_path = media_path_full(self.dbstate.db, media.get_path()) mime_type = media.get_mime_type() self.photo.set_image(self.full_path, mime_type)
def view_media(self, *obj): """ Launch external viewers for the selected objects. """ for handle in self.selected_handles(): ref_obj = self.dbstate.db.get_media_from_handle(handle) mpath = media_path_full(self.dbstate.db, ref_obj.get_path()) open_file_with_default_application(mpath, self.uistate)
def get_image_path_from_handle(self, identifier): """ Given an image handle, return the full path/filename. """ media = self.database.get_media_from_handle(identifier) if media: return media_path_full(self.database, media.get_path()) return ""
def draw_preview(self): mtype = self.obj.get_mime_type() if mtype: pb = get_thumbnail_image(media_path_full(self.db, self.obj.get_path()), mtype) self.pixmap.set_from_pixbuf(pb) else: pb = find_mime_type_pixbuf("text/plain") self.pixmap.set_from_pixbuf(pb)
def load_image(self, media_ref): """ Display an image from the given media reference. """ media = self.dbstate.db.get_object_from_handle(media_ref.ref) full_path = media_path_full(self.dbstate.db, media.get_path()) mime_type = media.get_mime_type() rectangle = media_ref.get_rectangle() self.photo.set_image(full_path, mime_type, rectangle)
def save(self, *obj): self.ok_button.set_sensitive(False) if self.object_is_empty(): ErrorDialog( _("Cannot save media object"), _("No data exists for this media object. Please " "enter data or cancel the edit."), ) self.ok_button.set_sensitive(True) return (uses_dupe_id, id) = self._uses_duplicate_id() if uses_dupe_id: prim_object = self.get_from_gramps_id(id) name = prim_object.get_description() msg1 = _("Cannot save media object. ID already exists.") msg2 = _( "You have attempted to use the existing Gramps ID with " "value %(id)s. This value is already used by '" "%(prim_object)s'. Please enter a different ID or leave " "blank to get the next available ID value." ) % {"id": id, "prim_object": name} ErrorDialog(msg1, msg2) self.ok_button.set_sensitive(True) return path = self.file_path.get_text() full_path = media_path_full(self.db, path) if os.path.isfile(full_path): self.determine_mime() else: msg1 = _("There is no media matching the current path value!") msg2 = _( "You have attempted to use the path with " "value '%(path)s'. This path does not exist!" " Please enter a different path" ) % {"path": path} ErrorDialog(msg1, msg2) self.ok_button.set_sensitive(True) return self.obj.set_path(path) with DbTxn("", self.db) as trans: if not self.obj.get_handle(): self.db.add_object(self.obj, trans) msg = _("Add Media Object (%s)") % self.obj.get_description() else: if not self.obj.get_gramps_id(): self.obj.set_gramps_id(self.db.find_next_object_gramps_id()) self.db.commit_media_object(self.obj, trans) msg = _("Edit Media Object (%s)") % self.obj.get_description() trans.set_description(msg) if self.callback: self.callback(self.obj) self._do_close()
def get_has_data(self, media): """ Return True if the gramplet has data, else return False. """ if media is None: return False full_path = media_path_full(self.dbstate.db, media.get_path()) return self.view.get_has_data(full_path)
def _row_change(self, obj): id_list = self.get_selected_ids() if not (id_list and id_list[0]): return handle = id_list[0] obj = self.get_from_handle_func()(handle) pix = get_thumbnail_image(media_path_full(self.db, obj.get_path())) self.preview.set_from_pixbuf(pix) gc.collect()
def open_containing_folder(self, *obj): """ Launch external viewers for the selected objects. """ for handle in self.selected_handles(): ref_obj = self.dbstate.db.get_media_from_handle(handle) mpath = media_path_full(self.dbstate.db, ref_obj.get_path()) if mpath: mfolder, mfile = os.path.split(mpath) open_file_with_default_application(mfolder, self.uistate)
def add_media(self, obj, parent_node=None): """ Add media object nodes to the model. """ for media_ref in obj.get_media_list(): handle = media_ref.ref name, media = navigation_label(self.dbstate.db, "Media", handle) full_path = media_path_full(self.dbstate.db, media.get_path()) rect = media_ref.get_rectangle() self.model.add([name], info=media_ref, node=parent_node)
def load_image(self, media): """ Load the primary image if it exists. """ self.full_path = media_path_full(self.dbstate.db, media.get_path()) self.mime_type = media.get_mime_type() self.photo.set_image(self.full_path, self.mime_type) # show where image parts are used by people: rects = self.find_references() self.draw_rectangles([], rects)
def _run(self): if not self.prepared: self.prepare() self.set_total(len(self.handle_list)) for handle in self.handle_list: obj = self.db.get_media_from_handle(handle) new_path = media_path_full(self.db, obj.path) obj.set_path(new_path) self.db.commit_media(obj, self.trans) self.update() return True
def _popup_view_photo(self, obj): """ Open this picture in the default picture viewer. """ media_list = self.obj.get_media_list() if media_list: photo = media_list[0] object_handle = photo.get_reference_handle() ref_obj = self.db.get_object_from_handle(object_handle) photo_path = media_path_full(self.db, ref_obj.get_path()) open_file_with_default_application(photo_path)
def load_photo(self, ref, obj): """ Load the person's main photo using the Thumbnailer. """ pixbuf = get_thumbnail_image( media_path_full(self.dbstate.db, obj.get_path()), obj.get_mime_type(), ref.get_rectangle() ) self.obj_photo.set_from_pixbuf(pixbuf) self.obj_photo.show() self.frame_photo.show_all()
def generate_thumbnails(self, obj): """ Generate thumbnails for media references of a given object. """ for media_ref in obj.get_media_list(): handle = media_ref.get_reference_handle() media = self.db.get_object_from_handle(handle) full_path = media_path_full(self.db, media.get_path()) mime_type = media.get_mime_type() rectangle = media_ref.get_rectangle() generate_thumbnail(full_path, mime_type, rectangle)
def main(self): active_handle = self.get_active('Media') if active_handle: media = self.dbstate.db.get_object_from_handle(active_handle) if media: full_path = media_path_full(self.dbstate.db, media.get_path()) has_data = self.view.display_exif_tags(full_path) self.set_has_data(has_data) else: self.set_has_data(False) else: self.set_has_data(False)
def right_click(self, obj, event): itemlist = [ (True, True, 'list-add', self.add_button_clicked), (True, False, _('Share'), self.share_button_clicked), (False,True, 'gtk-edit', self.edit_button_clicked), (True, True, 'list-remove', self.del_button_clicked), ] self.menu = Gtk.Menu() ref_obj = self.dbstate.db.get_object_from_handle(obj.ref) media_path = media_path_full(self.dbstate.db, ref_obj.get_path()) if media_path: item = Gtk.ImageMenuItem(_('View')) img = Gtk.Image() img.set_from_icon_name("gramps-viewmedia", Gtk.IconSize.MENU) item.set_image(img) item.connect('activate', make_launcher(media_path)) item.show() self.menu.append(item) mfolder, mfile = os.path.split(media_path) item = Gtk.MenuItem(label=_('Open Containing _Folder')) item.connect('activate', make_launcher(mfolder)) item.show() self.menu.append(item) item = Gtk.SeparatorMenuItem() item.show() self.menu.append(item) item = Gtk.MenuItem(_('Make Active Media')) item.connect('activate', lambda obj: self.uistate.set_active(ref_obj.handle, "Media")) item.show() self.menu.append(item) item = Gtk.SeparatorMenuItem() item.show() self.menu.append(item) for (needs_write_access, image, title, func) in itemlist: if image: item = Gtk.ImageMenuItem() img = Gtk.Image.new_from_icon_name(title, Gtk.IconSize.MENU) item.set_image(img) else: item = Gtk.MenuItem(label=title) item.connect('activate', func) if needs_write_access and self.dbstate.db.readonly: item.set_sensitive(False) item.show() self.menu.append(item) self.menu.popup(None, None, None, None, event.button, event.time)
def detect_faces_clicked(self, event): self.uistate.push_message(self.dbstate, _("Detecting faces...")) media = self.get_current_object() image_path = media_path_full(self.dbstate.db, media.get_path()) faces = facedetection.detect_faces(image_path, MIN_FACE_SIZE) for ((x, y, width, height), neighbors) in faces: region = Region(x - DETECTED_REGION_PADDING, y - DETECTED_REGION_PADDING, x + width + DETECTED_REGION_PADDING, y + height + DETECTED_REGION_PADDING) if DETECT_INSIDE_EXISTING_BOXES or self.enclosing_region(region) is None: self.regions.append(region) self.refresh() self.uistate.push_message(self.dbstate, _("Detection finished"))
def load_kml_files(self, obj): """ obj can be an event, a person or a place """ media_list = obj.get_media_list() if media_list: for media_ref in media_list: object_handle = media_ref.get_reference_handle() media_obj = self.dbstate.db.get_media_from_handle(object_handle) path = media_obj.get_path() name, extension = os.path.splitext(path) if extension == ".kml": path = media_path_full(self.dbstate.db, path) if os.path.isfile(path): self.kml_layer.add_kml(path)
def draw_preview(self): """ Draw the two preview images. This method can be called on eg change of the path. """ mtype = self.source.get_mime_type() if mtype: fullpath = media_path_full(self.db, self.source.get_path()) pb = get_thumbnail_image(fullpath, mtype) self.pixmap.set_from_pixbuf(pb) self.selection.load_image(fullpath) else: pb = find_mime_type_pixbuf("text/plain") self.pixmap.set_from_pixbuf(pb) self.selection.load_image("")
def generate_md5(self, button): """ Generate md5 hashes for media files and attach them as attributes to media objects. """ self.clear_models() progress = ProgressMeter(self.window_name, can_cancel=True, parent=self.window) length = self.db.get_number_of_media_objects() progress.set_pass(_('Generating media hashes'), length) with DbTxn(_("Set media hashes"), self.db, batch=True) as trans: for handle in self.db.get_media_object_handles(): media = self.db.get_object_from_handle(handle) full_path = media_path_full(self.db, media.get_path()) try: with io.open(full_path, 'rb') as media_file: md5sum = hashlib.md5(media_file.read()).hexdigest() except IOError as err: error_msg = '%s: %s' % (err.strerror, full_path) self.models[5].append((error_msg, None)) progress.step() continue for attr in media.get_attribute_list(): if str(attr.get_type()) == 'md5': media.remove_attribute(attr) break attr = Attribute() attr.set_type(AttributeType('md5')) attr.set_value(md5sum) media.add_attribute(attr) self.db.commit_media_object(media, trans) progress.step() if progress.get_cancelled(): break self.show_tabs() progress.close()
def summarize_media(self): """ Write a summary of all the media in the database. """ total_media = 0 size_in_bytes = 0 notfound = [] self.doc.start_paragraph("SR-Heading") self.doc.write_text(self._("Media Objects")) self.doc.end_paragraph() total_media = len(self.__db.get_media_handles()) mbytes = "0" for media_id in self.__db.get_media_handles(): media = self.__db.get_media_from_handle(media_id) try: size_in_bytes += posixpath.getsize( media_path_full(self.__db, media.get_path())) length = len(str(size_in_bytes)) if size_in_bytes <= 999999: mbytes = self._("less than 1") else: mbytes = str(size_in_bytes)[:(length-6)] except: notfound.append(media.get_path()) self.doc.start_paragraph("SR-Normal") self.doc.write_text(self._("Number of unique media objects: %d" ) % total_media) self.doc.end_paragraph() self.doc.start_paragraph("SR-Normal") self.doc.write_text(self._("Total size of media objects: %s MB" ) % mbytes) self.doc.end_paragraph() if len(notfound) > 0: self.doc.start_paragraph("SR-Heading") self.doc.write_text(self._("Missing Media Objects")) self.doc.end_paragraph() for media_path in notfound: self.doc.start_paragraph("SR-Normal") self.doc.write_text(media_path) self.doc.end_paragraph()
def right_click(self, obj, event): itemlist = [ (True, _('_Add'), self.add_button_clicked), (True, _('Share'), self.share_button_clicked), (False, _('_Edit'), self.edit_button_clicked), (True, _('_Remove'), self.del_button_clicked), ] self.menu = Gtk.Menu() self.menu.set_reserve_toggle_size(False) ref_obj = self.dbstate.db.get_media_from_handle(obj.ref) media_path = media_path_full(self.dbstate.db, ref_obj.get_path()) if media_path: # Translators: _View means "to look at this" item = Gtk.MenuItem.new_with_mnemonic(_('verb:look at this|_View')) item.connect('activate', make_launcher(media_path, self.uistate)) item.show() self.menu.append(item) mfolder, mfile = os.path.split(media_path) item = Gtk.MenuItem.new_with_mnemonic(_('Open Containing _Folder')) item.connect('activate', make_launcher(mfolder, self.uistate)) item.show() self.menu.append(item) item = Gtk.SeparatorMenuItem() item.show() self.menu.append(item) item = Gtk.MenuItem.new_with_mnemonic(_('_Make Active Media')) item.connect('activate', lambda obj: self.uistate.set_active(ref_obj.handle, "Media")) item.show() self.menu.append(item) item = Gtk.SeparatorMenuItem() item.show() self.menu.append(item) for (needs_write_access, title, func) in itemlist: item = Gtk.MenuItem.new_with_mnemonic(title) item.connect('activate', func) if needs_write_access and self.dbstate.db.readonly: item.set_sensitive(False) item.show() self.menu.append(item) self.menu.popup(None, None, None, None, event.button, event.time)
def writePeople(self): self.doc.add_comment('') # If we're going to attempt to include images, then use the HTML style # of .gv file. bUseHtmlOutput = False if self._incimages: bUseHtmlOutput = True # TODO there could be improvement and is still something wrong (wrong order) # also people should be sorted by their marriage - so first marriage, then 2nd marriage def personSorter(handle): person = self._db.get_person_from_handle(handle) fHandle = person.get_main_parents_family_handle() if fHandle: family = self._db.get_family_from_handle(fHandle) if family: childList = family.get_child_ref_list() childListRef = [] for ch in childList: childListRef.append(ch.ref) try: return childListRef.index(person.get_handle()) except: pass return 0 sorted_people = sorted(self._people, key=personSorter) for handle in sorted_people: person = self._db.get_person_from_handle(handle) name = self._name_display.display(person) # figure out what colour to use gender = person.get_gender() colour = self._colorunknown if gender == Person.MALE: colour = self._colormales elif gender == Person.FEMALE: colour = self._colorfemales # see if we have surname colours that match this person surname = person.get_primary_name().get_surname().encode( 'iso-8859-1', 'xmlcharrefreplace') if surname in self._surnamecolors: colour = self._surnamecolors[surname] # see if we have a birth/death or fallback dates we can use if self._incdates or self._incplaces: bth_event = get_birth_or_fallback(self._db, person) dth_event = get_death_or_fallback(self._db, person) else: bth_event = None dth_event = None # output the birth or fallback event birthStr = None if bth_event and self._incdates: if not bth_event.private or self._incprivate: date = bth_event.get_date_object() if self._just_years and date.get_year_valid(): birthStr = '%i' % date.get_year() else: birthStr = self._get_date(date) # get birth place (one of: city, state, or country) we can use birthplace = None if bth_event and self._incplaces: if not bth_event.private or self._incprivate: place = self._db.get_place_from_handle( bth_event.get_place_handle()) if place: location = get_main_location(self._db, place) if location.get(PlaceType.CITY): birthplace = location.get(PlaceType.CITY) elif location.get(PlaceType.STATE): birthplace = location.get(PlaceType.STATE) elif location.get(PlaceType.COUNTRY): birthplace = location.get(PlaceType.COUNTRY) # see if we have a deceased date we can use deathStr = None if dth_event and self._incdates: if not dth_event.private or self._incprivate: date = dth_event.get_date_object() if self._just_years and date.get_year_valid(): deathStr = '%i' % date.get_year() else: deathStr = self._get_date(date) # get death place (one of: city, state, or country) we can use deathplace = None if dth_event and self._incplaces: if not dth_event.private or self._incprivate: place = self._db.get_place_from_handle( dth_event.get_place_handle()) if place: location = get_main_location(self._db, place) if location.get(PlaceType.CITY): deathplace = location.get(PlaceType.CITY) elif location.get(PlaceType.STATE): deathplace = location.get(PlaceType.STATE) elif location.get(PlaceType.COUNTRY): deathplace = location.get(PlaceType.COUNTRY) occupations = self.getOccupations(person) # see if we have an image to use for this person imagePath = None if self._incimages: mediaList = person.get_media_list() if len(mediaList) > 0: mediaHandle = mediaList[0].get_reference_handle() media = self._db.get_object_from_handle(mediaHandle) mediaMimeType = media.get_mime_type() if mediaMimeType[0:5] == "image": imagePath = get_thumbnail_path( media_path_full(self._db, media.get_path()), rectangle=mediaList[0].get_rectangle()) # put the label together and output this person label = "" lineDelimiter = '\\n' if bUseHtmlOutput: lineDelimiter = '<BR/>' # if we have an image, then start an HTML table; # remember to close the table afterwards! if imagePath: label = ('<TABLE BORDER="0" CELLSPACING="2" CELLPADDING="0" ' 'CELLBORDER="0"><TR><TD><IMG SRC="%s"/></TD>' % imagePath) if self._imageonside == 0: label += '</TR><TR>' label += '<TD>' # at the very least, the label must have the person's name label += name print name if birthStr or deathStr: label += '%s(' % lineDelimiter if birthStr: label += '%s' % birthStr label += ' - ' if deathStr: label += '%s' % deathStr label += ')' if birthplace or deathplace: if birthplace == deathplace: deathplace = None # no need to print the same name twice label += '%s' % lineDelimiter if birthplace: label += '%s' % birthplace if birthplace and deathplace: label += ' / ' if deathplace: label += '%s' % deathplace if len(occupations) > 0: plural = '' if len(occupations) > 1: plural = 'e' label += '%s Beruf%s: %s' % (lineDelimiter, plural, ', '.join(occupations)) for family_handle in person.get_family_handle_list(): if family_handle not in self._families: # label += '<small>' family = self._db.get_family_from_handle(family_handle) children = [] grandChildren = [] for childRef in family.get_child_ref_list(): child = self._db.get_person_from_handle(childRef.ref) if (child.private and self._incprivate) or not child.private: children.append(self.getNameAndBirthDeath(child)) for family_handle2 in child.get_family_handle_list( ): family2 = self._db.get_family_from_handle( family_handle2) for childRef2 in family2.get_child_ref_list(): child2 = self._db.get_person_from_handle( childRef2.ref) if (child2.private and self._incprivate ) or not child2.private: grandChildren.append( self.getNameAndBirthDeath(child2)) if len(children) > 0: # label += '<div style="text-align:left">' label += lineDelimiter + 'Mehr Kinder: ' + unicode( len(children)) if len(children) < 3: for i in children: if i: label += lineDelimiter + i if len(grandChildren) > 0: label += lineDelimiter + 'Enkel: ' + unicode( len(grandChildren)) if len(grandChildren) < 3: for i in grandChildren: if i: label += lineDelimiter + i # label += '</small>' # label += '</div>' # see if we have a table that needs to be terminated if imagePath: label += '</TD></TR></TABLE>' shape = "box" style = "solid" border = colour fill = colour # do not use colour if this is B&W outline if self._colorize == 'outline': border = "" fill = "" if gender == person.FEMALE and self._useroundedcorners: style = "rounded" elif gender == person.UNKNOWN: shape = "hexagon" # if we're filling the entire node: if self._colorize == 'filled': style += ",filled" border = "" # we're done -- add the node self.doc.add_node(person.get_gramps_id(), label=label, shape=shape, color=border, style=style, fillcolor=fill, htmloutput=bUseHtmlOutput)
def save(self, *obj): self.ok_button.set_sensitive(False) if self.object_is_empty(): ErrorDialog(_("Cannot save media object"), _("No data exists for this media object. Please " "enter data or cancel the edit."), parent=self.window) self.ok_button.set_sensitive(True) return (uses_dupe_id, id) = self._uses_duplicate_id() if uses_dupe_id: prim_object = self.get_from_gramps_id(id) name = prim_object.get_description() msg1 = _("Cannot save media object. ID already exists.") msg2 = _("You have attempted to use the existing Gramps ID with " "value %(id)s. This value is already used by '" "%(prim_object)s'. Please enter a different ID or leave " "blank to get the next available ID value.") % { 'id': id, 'prim_object': name } ErrorDialog(msg1, msg2, parent=self.window) self.ok_button.set_sensitive(True) return path = self.file_path.get_text() full_path = media_path_full(self.db, path) if os.path.isfile(full_path): self.determine_mime() else: msg1 = _("There is no media matching the current path value!") msg2 = _("You have attempted to use the path with " "value '%(path)s'. This path does not exist!" " Please enter a different path") % { 'path': path } ErrorDialog(msg1, msg2, parent=self.window) self.ok_button.set_sensitive(True) return self.obj.set_path(path) if not self.obj.handle: with DbTxn( _("Add Media Object (%s)") % self.obj.get_description(), self.db) as trans: self.db.add_media(self.obj, trans) else: if self.data_has_changed(): with DbTxn( _("Edit Media Object (%s)") % self.obj.get_description(), self.db) as trans: if not self.obj.get_gramps_id(): self.obj.set_gramps_id( self.db.find_next_media_gramps_id()) self.db.commit_media(self.obj, trans) self._do_close() if self.callback: self.callback(self.obj)
def get_person_label(self, person): "return person label string" # see if we have an image to use for this person imagePath = None if self.bUseHtmlOutput: mediaList = person.get_media_list() if len(mediaList) > 0: mediaHandle = mediaList[0].get_reference_handle() media = self.database.get_object_from_handle(mediaHandle) mediaMimeType = media.get_mime_type() if mediaMimeType[0:5] == "image": imagePath = get_thumbnail_path( media_path_full(self.database, media.get_path()), rectangle=mediaList[0].get_rectangle()) # test if thumbnail actually exists in thumbs # (import of data means media files might not be present imagePath = find_file(imagePath) label = "" lineDelimiter = '\\n' # If we have an image, then start an HTML table; remember to close # the table afterwards! # # This isn't a free-form HTML format here...just a few keywords that # happen to be # similar to keywords commonly seen in HTML. For additional # information on what # is allowed, see: # # http://www.graphviz.org/info/shapes.html#html # if self.bUseHtmlOutput and imagePath: lineDelimiter = '<BR/>' label += '<TABLE BORDER="0" CELLSPACING="2" CELLPADDING="0" CELLBORDER="0"><TR><TD></TD><TD><IMG SRC="%s"/></TD><TD></TD>' % imagePath if self.imgpos == 0: #trick it into not stretching the image label += '</TR><TR><TD COLSPAN="3">' else: label += '<TD>' else: #no need for html label with this person self.bUseHtmlOutput = False # at the very least, the label must have the person's name nm = self._name_display.display(person) if self.bUseHtmlOutput: # avoid < and > in the name, as this is html text label += nm.replace('<', '<').replace('>', '>') else: label += nm p_id = person.get_gramps_id() if self.includeid: label += " (%s)" % p_id if self.includedates: birth, death = self.get_date_strings(person) if birth or death: label += '%s(' % lineDelimiter if birth: label += '%s' % birth label += ' - ' if death: label += '%s' % death label += ')' if self.increlname and self.center_person != person: # display relationship info if self.advrelinfo: (relationship, Ga, Gb) = self.rel_calc.get_one_relationship(self.database, self.center_person, person, extra_info=True, olocale=self._locale) if relationship: label += "%s(%s Ga=%d Gb=%d)" % (lineDelimiter, relationship, Ga, Gb) else: relationship = self.rel_calc.get_one_relationship( self.database, self.center_person, person, olocale=self._locale) if relationship: label += "%s(%s)" % (lineDelimiter, relationship) # see if we have a table that needs to be terminated if self.bUseHtmlOutput: label += '</TD></TR></TABLE>' return label else: # non html label is enclosed by "" so escape other " return label.replace('"', '\\\"')
def update_checksum(self): self.uistate.set_busy_cursor(True) media_path = media_path_full(self.dbstate.db, self.obj.get_path()) self.obj.set_checksum(create_checksum(os.path.normpath(media_path))) self.uistate.set_busy_cursor(False)
def display(self, path): """ Display the given file. """ full_path = media_path_full(self.db, path) open_file_with_default_application(full_path, self.uistate)
def load_image(self, media): self.regions = [] image_path = media_path_full(self.dbstate.db, media.get_path()) self.selection_widget.load_image(image_path) self.retrieve_backrefs() self.selection_widget.set_regions(self.regions)
def write_people(self): """ write the people """ self.doc.add_comment('') # If we're going to attempt to include images, then use the HTML style # of .gv file. use_html_output = False if self._incimages: use_html_output = True # loop through all the people we need to output for handle in sorted(self._people): # enable a diff person = self._db.get_person_from_handle(handle) name = self._name_display.display(person) p_id = person.get_gramps_id() # figure out what colour to use gender = person.get_gender() colour = self._colorunknown if gender == Person.MALE: colour = self._colormales elif gender == Person.FEMALE: colour = self._colorfemales # see if we have surname colours that match this person surname = person.get_primary_name().get_surname() surname = surname.encode('iso-8859-1', 'xmlcharrefreplace') if surname in self._surnamecolors: colour = self._surnamecolors[surname] # see if we have a birth/death or fallback dates we can use if self._incdates or self._incplaces: bth_event = get_birth_or_fallback(self._db, person) dth_event = get_death_or_fallback(self._db, person) else: bth_event = None dth_event = None # output the birth or fallback event birth_str = None if bth_event and self._incdates: date = bth_event.get_date_object() if self._just_years and date.get_year_valid(): birth_str = '%i' % date.get_year() else: birth_str = self._get_date(date) # get birth place (one of: hamlet, village, town, city, parish, # county, province, region, state or country) birthplace = None if bth_event and self._incplaces: birthplace = self.get_event_place(bth_event) # see if we have a deceased date we can use death_str = None if dth_event and self._incdates: date = dth_event.get_date_object() if self._just_years and date.get_year_valid(): death_str = '%i' % date.get_year() else: death_str = self._get_date(date) # get death place (one of: hamlet, village, town, city, parish, # county, province, region, state or country) deathplace = None if dth_event and self._incplaces: deathplace = self.get_event_place(dth_event) # see if we have an image to use for this person image_path = None if self._incimages: media_list = person.get_media_list() if len(media_list) > 0: media_handle = media_list[0].get_reference_handle() media = self._db.get_media_from_handle(media_handle) media_mime_type = media.get_mime_type() if media_mime_type[0:5] == "image": image_path = get_thumbnail_path( media_path_full(self._db, media.get_path()), rectangle=media_list[0].get_rectangle(), size=self._imagesize) # put the label together and output this person label = "" line_delimiter = '\\n' if use_html_output: line_delimiter = '<BR/>' # if we have an image, then start an HTML table; # remember to close the table afterwards! if image_path: label = ('<TABLE BORDER="0" CELLSPACING="2" CELLPADDING="0" ' 'CELLBORDER="0"><TR><TD><IMG SRC="%s"/></TD>' % image_path) if self._imageonside == 0: label += '</TR><TR>' label += '<TD>' # at the very least, the label must have the person's name label += name if self.includeid == 1: # same line label += " (%s)" % p_id elif self.includeid == 2: # own line label += "%s(%s)" % (line_delimiter, p_id) if birth_str or death_str: label += '%s(' % line_delimiter if birth_str: label += '%s' % birth_str label += ' - ' if death_str: label += '%s' % death_str label += ')' if birthplace or deathplace: if birthplace == deathplace: deathplace = None # no need to print the same name twice label += '%s' % line_delimiter if birthplace: label += '%s' % birthplace if birthplace and deathplace: label += ' / ' if deathplace: label += '%s' % deathplace # see if we have a table that needs to be terminated if image_path: label += '</TD></TR></TABLE>' shape = "box" style = "solid" border = colour fill = colour # do not use colour if this is B&W outline if self._colorize == 'outline': border = "" fill = "" if gender == person.FEMALE and self._useroundedcorners: style = "rounded" elif gender == person.UNKNOWN: shape = "hexagon" # if we're filling the entire node: if self._colorize == 'filled': style += ",filled" border = "" # we're done -- add the node self.doc.add_node(p_id, label=label, shape=shape, color=border, style=style, fillcolor=fill, htmloutput=use_html_output)
def get_person_label(self, person): "return person label string" # see if we have an image to use for this person image_path = None if self.use_html_output: media_list = person.get_media_list() if len(media_list) > 0: media_handle = media_list[0].get_reference_handle() media = self._db.get_media_from_handle(media_handle) media_mime_type = media.get_mime_type() if media_mime_type[0:5] == "image": image_path = get_thumbnail_path( media_path_full(self._db, media.get_path()), rectangle=media_list[0].get_rectangle()) # test if thumbnail actually exists in thumbs # (import of data means media files might not be present image_path = find_file(image_path) label = "" line_delimiter = '\\n' # If we have an image, then start an HTML table; remember to close # the table afterwards! # # This isn't a free-form HTML format here...just a few keywords that # happen to be # similar to keywords commonly seen in HTML. For additional # information on what # is allowed, see: # # http://www.graphviz.org/info/shapes.html#html # if self.use_html_output and image_path: line_delimiter = '<BR/>' label += '<TABLE BORDER="0" CELLSPACING="2" CELLPADDING="0" ' label += 'CELLBORDER="0"><TR><TD></TD><TD>' label += '<IMG SRC="%s"/></TD><TD></TD>' % image_path if self.imgpos == 0: #trick it into not stretching the image label += '</TR><TR><TD COLSPAN="3">' else: label += '<TD>' else: #no need for html label with this person self.use_html_output = False # at the very least, the label must have the person's name p_name = self._name_display.display(person) if self.use_html_output: # avoid < and > in the name, as this is html text label += p_name.replace('<', '<').replace('>', '>') else: label += p_name p_id = person.get_gramps_id() if self.includeid == 1: # same line label += " (%s)" % p_id elif self.includeid == 2: # own line label += "%s(%s)" % (line_delimiter, p_id) if self.event_choice != 0: b_date, d_date, b_place, d_place, b_type, d_type = \ self.get_event_strings(person) if self.event_choice in [1, 2, 3, 4, 5] and (b_date or d_date): label += '%s(' % line_delimiter if b_date: label += '%s' % b_date label += ' - ' if d_date: label += '%s' % d_date label += ')' if (self.event_choice in [2, 3, 5, 6] and (b_place or d_place) and not (self.event_choice == 3 and (b_date or d_date))): label += '%s(' % line_delimiter if b_place: label += '%s' % b_place label += ' - ' if d_place: label += '%s' % d_place label += ')' if self.event_choice == 7: if b_type: label += '%s%s' % (line_delimiter, b_type.get_abbreviation()) if b_date: label += ' %s' % b_date if b_place: label += ' %s' % b_place if d_type: label += '%s%s' % (line_delimiter, d_type.get_abbreviation()) if d_date: label += ' %s' % d_date if d_place: label += ' %s' % d_place if self.increlname and self.center_person != person: # display relationship info if self.advrelinfo: (relationship, _ga, _gb) = self.rel_calc.get_one_relationship( self._db, self.center_person, person, extra_info=True, olocale=self._locale) if relationship: label += "%s(%s Ga=%d Gb=%d)" % (line_delimiter, relationship, _ga, _gb) else: relationship = self.rel_calc.get_one_relationship( self._db, self.center_person, person, olocale=self._locale) if relationship: label += "%s(%s)" % (line_delimiter, relationship) if self.occupation > 0: event_refs = person.get_primary_event_ref_list() events = [ event for event in [ self._db.get_event_from_handle(ref.ref) for ref in event_refs ] if event.get_type() == EventType(EventType.OCCUPATION) ] if len(events) > 0: events.sort(key=lambda x: x.get_date_object()) if self.occupation == 1: occupation = events[-1].get_description() if occupation: label += "%s(%s)" % (line_delimiter, occupation) elif self.occupation == 2: for evt in events: date = self.get_date_string(evt) place = self.get_place_string(evt) desc = evt.get_description() if not date and not desc and not place: continue label += '%s(' % line_delimiter if date: label += '%s' % date if desc: label += ' ' if desc: label += '%s' % desc if place: if date or desc: label += ', ' label += '%s' % place label += ')' # see if we have a table that needs to be terminated if self.use_html_output: label += '</TD></TR></TABLE>' return label else: # non html label is enclosed by "" so escape other " return label.replace('"', '\\\"')
def main(self): self.set_text(_("Processing...")) database = self.dbstate.db personList = database.iter_people() with_media = 0 total_media = 0 incomp_names = 0 disconnected = 0 missing_bday = 0 males = 0 females = 0 unknowns = 0 bytes = 0 namelist = [] notfound = [] mobjects = database.get_number_of_media() mbytes = "0" for media in database.iter_media(): fullname = media_path_full(database, media.get_path()) try: bytes += posixpath.getsize(fullname) length = len(str(bytes)) if bytes <= 999999: mbytes = _("less than 1") else: mbytes = str(bytes)[:(length - 6)] except OSError: notfound.append(media.get_path()) for cnt, person in enumerate(personList): length = len(person.get_media_list()) if length > 0: with_media += 1 total_media += length for name in [person.get_primary_name() ] + person.get_alternate_names(): # Count unique surnames if not name.get_surname().strip() in namelist \ and not name.get_surname().strip() == "": namelist.append(name.get_surname().strip()) if name.get_first_name().strip() == "": incomp_names += 1 else: if name.get_surname_list(): for surname in name.get_surname_list(): if surname.get_surname().strip() == "": incomp_names += 1 else: incomp_names += 1 if (not person.get_main_parents_family_handle() and not len(person.get_family_handle_list())): disconnected += 1 birth_ref = person.get_birth_ref() if birth_ref: birth = database.get_event_from_handle(birth_ref.ref) if not get_date(birth): missing_bday += 1 else: missing_bday += 1 if person.get_gender() == Person.FEMALE: females += 1 elif person.get_gender() == Person.MALE: males += 1 else: unknowns += 1 if not cnt % _YIELD_INTERVAL: yield True self.clear_text() self.append_text(_("Individuals") + "\n") self.append_text("----------------------------\n") self.link(_("Number of individuals") + ":", 'Filter', 'all people') self.append_text(" %s" % database.get_number_of_people()) self.append_text("\n") self.link("%s:" % _("Males"), 'Filter', 'males') self.append_text(" %s" % males) self.append_text("\n") self.link("%s:" % _("Females"), 'Filter', 'females') self.append_text(" %s" % females) self.append_text("\n") self.link("%s:" % _("Individuals with unknown gender"), 'Filter', 'people with unknown gender') self.append_text(" %s" % unknowns) self.append_text("\n") self.link("%s:" % _("Incomplete names"), 'Filter', 'incomplete names') self.append_text(" %s" % incomp_names) self.append_text("\n") self.link("%s:" % _("Individuals missing birth dates"), 'Filter', 'people with missing birth dates') self.append_text(" %s" % missing_bday) self.append_text("\n") self.link("%s:" % _("Disconnected individuals"), 'Filter', 'disconnected people') self.append_text(" %s" % disconnected) self.append_text("\n") self.append_text("\n%s\n" % _("Family Information")) self.append_text("----------------------------\n") self.link("%s:" % _("Number of families"), 'Filter', 'all families') self.append_text(" %s" % database.get_number_of_families()) self.append_text("\n") self.link("%s:" % _("Unique surnames"), 'Filter', 'unique surnames') self.append_text(" %s" % len(namelist)) self.append_text("\n") self.append_text("\n%s\n" % _("Media Objects")) self.append_text("----------------------------\n") self.link("%s:" % _("Individuals with media objects"), 'Filter', 'people with media') self.append_text(" %s" % with_media) self.append_text("\n") self.link("%s:" % _("Total number of media object references"), 'Filter', 'media references') self.append_text(" %s" % total_media) self.append_text("\n") self.link("%s:" % _("Number of unique media objects"), 'Filter', 'unique media') self.append_text(" %s" % mobjects) self.append_text("\n") self.link("%s:" % _("Total size of media objects"), 'Filter', 'media by size') self.append_text(" %s %s" % (mbytes, _("Megabyte|MB"))) self.append_text("\n") self.link("%s:" % _("Missing Media Objects"), 'Filter', 'missing media') self.append_text(" %s\n" % len(notfound)) self.append_text("", scroll_to="begin")
def __init__(self, dbstate, user, options_class, name, callback=None): uistate = user.uistate tool.Tool.__init__(self, dbstate, options_class, name) self.db = dbstate.db progress = ProgressMeter(_('Thumbnail Generator'), can_cancel=True) length = self.db.get_number_of_media() progress.set_pass(_('Generating media thumbnails'), length) for media in dbstate.db.iter_media(): full_path = media_path_full(dbstate.db, media.get_path()) mime_type = media.get_mime_type() generate_thumbnail(full_path, mime_type) progress.step() if progress.get_cancelled(): break length = self.db.get_number_of_people() progress.set_pass(_('Generating thumbnails for person references'), length) for person in dbstate.db.iter_people(): self.generate_thumbnails(person) progress.step() if progress.get_cancelled(): break length = self.db.get_number_of_families() progress.set_pass(_('Generating thumbnails for family references'), length) for family in dbstate.db.iter_families(): self.generate_thumbnails(family) progress.step() if progress.get_cancelled(): break length = self.db.get_number_of_events() progress.set_pass(_('Generating thumbnails for event references'), length) for event in dbstate.db.iter_events(): self.generate_thumbnails(event) progress.step() if progress.get_cancelled(): break length = self.db.get_number_of_places() progress.set_pass(_('Generating thumbnails for place references'), length) for place in dbstate.db.iter_places(): self.generate_thumbnails(place) progress.step() if progress.get_cancelled(): break length = self.db.get_number_of_sources() progress.set_pass(_('Generating thumbnails for source references'), length) for source in dbstate.db.iter_sources(): self.generate_thumbnails(source) progress.step() if progress.get_cancelled(): break progress.close()
def button_press_event(self, obj, event): if (event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS and event.button == 1): photo_path = media_path_full(self.db, self.source.get_path()) open_file_with_default_application(photo_path, self.uistate)
def export(self): # missmedia_action = 0 #-------------------------------------------------------------- # def remove_clicked(): # # File is lost => remove all references and the object itself # for p_id in self.db.iter_family_handles(): # p = self.db.get_family_from_handle(p_id) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_family(p,None) # for key in self.db.iter_person_handles(): # p = self.db.get_person_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_person(p,None) # for key in self.db.get_source_handles(): # p = self.db.get_source_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_source(p,None) # for key in self.db.get_place_handles(): # p = self.db.get_place_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_place(p,None) # for key in self.db.get_event_handles(): # p = self.db.get_event_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_event(p,None) # self.db.remove_media(m_id,None) # def leave_clicked(): # # File is lost => do nothing, leave as is # pass # def select_clicked(): # # File is lost => select a file to replace the lost one # def fs_close_window(obj): # pass # def fs_ok_clicked(obj): # name = fs_top.get_filename() # if os.path.isfile(name): # archive.add(name) # fs_top = gtk.FileChooserDialog("%s - GRAMPS" % _("Select file"), # buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, # gtk.STOCK_OK, Gtk.ResponseType.OK) # ) # response = fs_top.run() # if response == Gtk.ResponseType.OK: # fs_ok_clicked(fs_top) # elif response == gtk.RESPONSE_CANCEL: # fs_close_window(fs_top) # fs_top.destroy() #--------------------------------------------------------------- try: archive = tarfile.open(self.filename,'w:gz') except EnvironmentError as msg: log.warn(str(msg)) self.user.notify_error(_('Failure writing %s') % self.filename, str(msg)) return 0 # Write media files first, since the database may be modified # during the process (i.e. when removing object) for m_id in self.db.get_media_handles(sort_handles=True): mobject = self.db.get_media_from_handle(m_id) filename = media_path_full(self.db, mobject.get_path()) archname = str(mobject.get_path()) if os.path.isfile(filename) and os.access(filename, os.R_OK): archive.add(filename, archname) # else: # # File is lost => ask what to do # if missmedia_action == 0: # mmd = MissingMediaDialog( # _("Media object could not be found"), # _("%(file_name)s is referenced in the database, " # "but no longer exists. The file may have been " # "deleted or moved to a different location. " # "You may choose to either remove the reference " # "from the database, keep the reference to the " # "missing file, or select a new file." # ) % { 'file_name' : filename }, # remove_clicked, leave_clicked, select_clicked) # missmedia_action = mmd.default_action # elif missmedia_action == 1: # remove_clicked() # elif missmedia_action == 2: # leave_clicked() # elif missmedia_action == 3: # select_clicked() # Write XML now g = BytesIO() gfile = XmlWriter(self.db, self.user, 2) gfile.write_handle(g) tarinfo = tarfile.TarInfo('data.gramps') tarinfo.size = len(g.getvalue()) tarinfo.mtime = time.time() if not win(): tarinfo.uid = os.getuid() tarinfo.gid = os.getgid() g.seek(0) archive.addfile(tarinfo, g) archive.close() g.close() return True
def view_photo(self, photo): """ Open this picture in the default picture viewer. """ photo_path = media_path_full(self.dbstate.db, photo.get_path()) open_file_with_default_application(photo_path, self.uistate)
def button_press_event(self, obj, event): if event.button==1 and event.type == Gdk.EventType._2BUTTON_PRESS: photo_path = media_path_full(self.db, self.source.get_path()) open_file_with_default_application(photo_path)
def __init__(self, report, title, step): """ @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page """ import posixpath BasePage.__init__(self, report, title) self.bibli = Bibliography() self.uplink = False self.report = report # set the file name and open file output_file, sio = self.report.create_file("statistics") addressbookpage, head, body = self.write_header(_("Statistics")) (males, females, unknown) = self.get_gender(report.database.iter_person_handles()) step() mobjects = report.database.get_number_of_media() npersons = report.database.get_number_of_people() nfamilies = report.database.get_number_of_families() nsurnames = len(set(report.database.surname_list)) notfound = [] total_media = 0 mbytes = "0" chars = 0 for media in report.database.iter_media(): total_media += 1 fullname = media_path_full(report.database, media.get_path()) try: chars += posixpath.getsize(fullname) length = len(str(chars)) if chars <= 999999: mbytes = _("less than 1") else: mbytes = str(chars)[:(length - 6)] except OSError: notfound.append(media.get_path()) with Html("div", class_="content", id='EventDetail') as section: section += Html("h3", self._("Database overview"), inline=True) body += section with Html("div", class_="content", id='subsection narrative') as sec11: sec11 += Html("h4", self._("Individuals"), inline=True) body += sec11 with Html("div", class_="content", id='subsection narrative') as sec1: sec1 += Html("br", self._("Number of individuals") + self.colon + "%d" % npersons, inline=True) sec1 += Html("br", self._("Males") + self.colon + "%d" % males, inline=True) sec1 += Html("br", self._("Females") + self.colon + "%d" % females, inline=True) sec1 += Html("br", self._("Individuals with unknown gender") + self.colon + "%d" % unknown, inline=True) body += sec1 with Html("div", class_="content", id='subsection narrative') as sec2: sec2 += Html("h4", self._("Family Information"), inline=True) sec2 += Html("br", self._("Number of families") + self.colon + "%d" % nfamilies, inline=True) sec2 += Html("br", self._("Unique surnames") + self.colon + "%d" % nsurnames, inline=True) body += sec2 with Html("div", class_="content", id='subsection narrative') as sec3: sec3 += Html("h4", self._("Media Objects"), inline=True) sec3 += Html("br", self._("Total number of media object references") + self.colon + "%d" % total_media, inline=True) sec3 += Html("br", self._("Number of unique media objects") + self.colon + "%d" % mobjects, inline=True) sec3 += Html("br", self._("Total size of media objects") + self.colon + "%8s %s" % (mbytes, self._("Megabyte|MB")), inline=True) sec3 += Html("br", self._("Missing Media Objects") + self.colon + "%d" % len(notfound), inline=True) body += sec3 with Html("div", class_="content", id='subsection narrative') as sec4: sec4 += Html("h4", self._("Miscellaneous"), inline=True) sec4 += Html("br", self._("Number of events") + self.colon + "%d" % report.database.get_number_of_events(), inline=True) sec4 += Html("br", self._("Number of places") + self.colon + "%d" % report.database.get_number_of_places(), inline=True) nsources = report.database.get_number_of_sources() sec4 += Html("br", self._("Number of sources") + self.colon + "%d" % nsources, inline=True) ncitations = report.database.get_number_of_citations() sec4 += Html("br", self._("Number of citations") + self.colon + "%d" % ncitations, inline=True) nrepo = report.database.get_number_of_repositories() sec4 += Html("br", self._("Number of repositories") + self.colon + "%d" % nrepo, inline=True) body += sec4 (males, females, unknown) = self.get_gender(self.report.bkref_dict[Person].keys()) origin = " :<br/>" + report.filter.get_name(self.rlocale) with Html("div", class_="content", id='EventDetail') as section: section += Html("h3", self._("Narrative web content report for") + origin, inline=True) body += section with Html("div", class_="content", id='subsection narrative') as sec5: sec5 += Html("h4", self._("Individuals"), inline=True) sec5 += Html("br", self._("Number of individuals") + self.colon + "%d" % len(self.report.bkref_dict[Person]), inline=True) sec5 += Html("br", self._("Males") + self.colon + "%d" % males, inline=True) sec5 += Html("br", self._("Females") + self.colon + "%d" % females, inline=True) sec5 += Html("br", self._("Individuals with unknown gender") + self.colon + "%d" % unknown, inline=True) body += sec5 with Html("div", class_="content", id='subsection narrative') as sec6: sec6 += Html("h4", self._("Family Information"), inline=True) sec6 += Html("br", self._("Number of families") + self.colon + "%d" % len(self.report.bkref_dict[Family]), inline=True) body += sec6 with Html("div", class_="content", id='subsection narrative') as sec7: sec7 += Html("h4", self._("Miscellaneous"), inline=True) sec7 += Html("br", self._("Number of events") + self.colon + "%d" % len(self.report.bkref_dict[Event]), inline=True) sec7 += Html("br", self._("Number of places") + self.colon + "%d" % len(self.report.bkref_dict[Place]), inline=True) sec7 += Html("br", self._("Number of sources") + self.colon + "%d" % len(self.report.bkref_dict[Source]), inline=True) sec7 += Html("br", self._("Number of citations") + self.colon + "%d" % len(self.report.bkref_dict[Citation]), inline=True) sec7 += Html("br", self._("Number of repositories") + self.colon + "%d" % len(self.report.bkref_dict[Repository]), inline=True) body += sec7 # add fullclear for proper styling # and footer section to page footer = self.write_footer(None) body += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(addressbookpage, output_file, sio, 0)
def view_media(self, obj): ref_obj = self.dbstate.db.get_object_from_handle(self.obj.handle) if ref_obj: media_path = media_path_full(self.dbstate.db, ref_obj.get_path()) open_file_with_default_application(media_path)
def run(database, document, filter_name, *args, **kwargs): """ Loops through the families that the person is a child in, and display the information about the other children. """ # setup the simple access functions sdb = SimpleAccess(database) sdoc = SimpleDoc(document) stab = QuickTable(sdb) if (filter_name == 'all'): sdoc.title(_("Summary counts of current selection")) sdoc.paragraph("") sdoc.paragraph(_("Right-click row (or press ENTER) to see selected items.")) sdoc.paragraph("") stab.columns(_("Object"), _("Count/Total")) if hasattr(database, "db"): stab.row([_("People"), "Filter", "Person"], "%d/%d" % (len(database.get_person_handles()), len(database.db.get_person_handles()))) stab.row([_("Families"), "Filter", "Family"], "%d/%d" % (len(database.get_family_handles()), len(database.db.get_family_handles()))) stab.row([_("Events"), "Filter", "Event"], "%d/%d" % (len(database.get_event_handles()), len(database.db.get_event_handles()))) stab.row([_("Places"), "Filter", "Place"], "%d/%d" % (len(database.get_place_handles()), len(database.db.get_place_handles()))) stab.row([_("Sources"), "Filter", "Source"], "%d/%d" % (len(database.get_source_handles()), len(database.db.get_source_handles()))) stab.row([_("Repositories"), "Filter", "Repository"], "%d/%d" % (len(database.get_repository_handles()), len(database.db.get_repository_handles()))) stab.row([_("Media"), "Filter", "Media"], "%d/%d" % (len(database.get_media_handles()), len(database.db.get_media_handles()))) stab.row([_("Notes"), "Filter", "Note"], "%d/%d" % (len(database.get_note_handles()), len(database.db.get_note_handles()))) else: stab.row([_("People"), "Filter", "Person"], "%d/%d" % (len(database.get_person_handles()), len(database.basedb.get_person_handles()))) stab.row([_("Families"), "Filter", "Family"], "%d/%d" % (len(database.get_family_handles()), len(database.basedb.get_family_handles()))) stab.row([_("Events"), "Filter", "Event"], "%d/%d" % (len(database.get_event_handles()), len(database.basedb.get_event_handles()))) stab.row([_("Places"), "Filter", "Place"], "%d/%d" % (len(database.get_place_handles()), len(database.basedb.get_place_handles()))) stab.row([_("Sources"), "Filter", "Source"], "%d/%d" % (len(database.get_source_handles()), len(database.basedb.get_source_handles()))) stab.row([_("Repositories"), "Filter", "Repository"], "%d/%d" % (len(database.get_repository_handles()), len(database.basedb.get_repository_handles()))) stab.row([_("Media"), "Filter", "Media"], "%d/%d" % (len(database.get_media_handles()), len(database.basedb.get_media_handles()))) stab.row([_("Notes"), "Filter", "Note"], "%d/%d" % (len(database.get_note_handles()), len(database.basedb.get_note_handles()))) sdoc.paragraph("") stab.write(sdoc) return # display the title if filter_name in fname_map: sdoc.title(_("Filtering on %s") % fname_map[filter_name]) # listed above else: sdoc.title(_("Filtering on %s") % _(filter_name)) sdoc.paragraph("") matches = 0 if (filter_name == 'Inverse Person'): sdb.dbase = database.db stab.columns(_("Person"), _("Gramps ID"), _("Birth Date")) proxy_handles = set(database.iter_person_handles()) for person in database.db.iter_people(): if person.handle not in proxy_handles: stab.row(person, person.gramps_id, sdb.birth_or_fallback(person)) matches += 1 elif (filter_name == 'Inverse Family'): sdb.dbase = database.db stab.columns(_("Family"), _("Gramps ID")) proxy_handles = set(database.iter_family_handles()) for family in database.db.iter_families(): if family.handle not in proxy_handles: stab.row(family, family.gramps_id) matches += 1 elif (filter_name == 'Inverse Event'): sdb.dbase = database.db stab.columns(_("Event"), _("Gramps ID")) proxy_handles = set(database.iter_event_handles()) for event in database.db.iter_events(): if event.handle not in proxy_handles: stab.row(event, event.gramps_id) matches += 1 elif (filter_name == 'Inverse Place'): sdb.dbase = database.db stab.columns(_("Place"), _("Gramps ID")) proxy_handles = set(database.iter_place_handles()) for place in database.db.iter_places(): if place.handle not in proxy_handles: stab.row(place, place.gramps_id) matches += 1 elif (filter_name == 'Inverse Source'): sdb.dbase = database.db stab.columns(_("Source"), _("Gramps ID")) proxy_handles = set(database.iter_source_handles()) for source in database.db.iter_sources(): if source.handle not in proxy_handles: stab.row(source, source.gramps_id) matches += 1 elif (filter_name == 'Inverse Repository'): sdb.dbase = database.db stab.columns(_("Repository"), _("Gramps ID")) proxy_handles = set(database.iter_repository_handles()) for repository in database.db.iter_repositories(): if repository.handle not in proxy_handles: stab.row(repository, repository.gramps_id) matches += 1 elif (filter_name == 'Inverse Media'): sdb.dbase = database.db stab.columns(_("Media"), _("Gramps ID")) proxy_handles = set(database.iter_media_handles()) for media in database.db.iter_media(): if media.handle not in proxy_handles: stab.row(media, media.gramps_id) matches += 1 elif (filter_name == 'Inverse Note'): sdb.dbase = database.db stab.columns(_("Note"), _("Gramps ID")) proxy_handles = set(database.iter_note_handles()) for note in database.db.iter_notes(): if note.handle not in proxy_handles: stab.row(note, note.gramps_id) matches += 1 elif (filter_name in ['all people', 'Person']): stab.columns(_("Person"), _("Gramps ID"), _("Birth Date")) for person in database.iter_people(): stab.row(person, person.gramps_id, sdb.birth_or_fallback(person)) matches += 1 elif (filter_name in ['all families', 'Family']): stab.columns(_("Family"), _("Gramps ID")) for family in database.iter_families(): stab.row(family, family.gramps_id) matches += 1 elif (filter_name in ['all events', 'Event']): stab.columns(_("Event"), _("Gramps ID")) for obj in database.iter_events(): stab.row(obj, obj.gramps_id) matches += 1 elif (filter_name in ['all places', 'Place']): stab.columns(_("Place"), _("Gramps ID")) for obj in database.iter_places(): stab.row(obj, obj.gramps_id) matches += 1 elif (filter_name in ['all sources', 'Source']): stab.columns(_("Source"), _("Gramps ID")) for obj in database.iter_sources(): stab.row(obj, obj.gramps_id) matches += 1 elif (filter_name in ['all repositories', 'Repository']): stab.columns(_("Repository"), _("Gramps ID")) for obj in database.iter_repositories(): stab.row(obj, obj.gramps_id) matches += 1 elif (filter_name in ['all media', 'Media']): stab.columns(_("Media"), _("Gramps ID")) for obj in database.iter_media(): stab.row(obj, obj.gramps_id) matches += 1 elif (filter_name in ['all notes', 'Note']): stab.columns(_("Note"), _("Gramps ID")) for obj in database.iter_notes(): stab.row(obj, obj.gramps_id) matches += 1 elif (filter_name == 'males'): stab.columns(_("Person"), _("Birth Date"), _("Name type")) for person in database.iter_people(): if person.gender == Person.MALE: stab.row(person, sdb.birth_or_fallback(person), str(person.get_primary_name().get_type())) matches += 1 elif (filter_name == 'females'): stab.columns(_("Person"), _("Birth Date"), _("Name type")) for person in database.iter_people(): if person.gender == Person.FEMALE: stab.row(person, sdb.birth_or_fallback(person), str(person.get_primary_name().get_type())) matches += 1 elif (filter_name == 'people with unknown gender'): stab.columns(_("Person"), _("Birth Date"), _("Name type")) for person in database.iter_people(): if person.gender not in [Person.FEMALE, Person.MALE]: stab.row(person, sdb.birth_or_fallback(person), str(person.get_primary_name().get_type())) matches += 1 elif (filter_name == 'incomplete names'): stab.columns(_("Name"), _("Birth Date"), _("Name type")) for person in database.iter_people(): for name in [person.get_primary_name()] + person.get_alternate_names(): if name.get_first_name().strip() == "": stab.row([name.get_name(), "Person", person.handle], sdb.birth_or_fallback(person), str(name.get_type())) matches += 1 else: if name.get_surname_list(): for surname in name.get_surname_list(): if surname.get_surname().strip() == "": stab.row([name.get_first_name(), "Person", person.handle], sdb.birth_or_fallback(person), str(name.get_type())) matches += 1 else: stab.row([name.get_first_name(), "Person", person.handle], sdb.birth_or_fallback(person), str(name.get_type())) matches += 1 elif (filter_name == 'people with missing birth dates'): stab.columns(_("Person"), _("Type")) for person in database.iter_people(): birth_ref = person.get_birth_ref() if birth_ref: birth = database.get_event_from_handle(birth_ref.ref) if not get_date(birth): stab.row(person, _("birth event but no date")) matches += 1 else: stab.row(person, _("missing birth event")) matches += 1 elif (filter_name == 'disconnected people'): stab.columns(_("Person"), _("Birth Date"), _("Name type")) for person in database.iter_people(): if ((not person.get_main_parents_family_handle()) and (not len(person.get_family_handle_list()))): stab.row(person, sdb.birth_or_fallback(person), str(person.get_primary_name().get_type())) matches += 1 elif (filter_name == 'unique surnames'): namelist = defaultdict(int) for person in database.iter_people(): names = [person.get_primary_name()] + person.get_alternate_names() surnames = list(set([name.get_group_name() for name in names])) for surname in surnames: namelist[surname] += 1 stab.columns(_("Surname"), _("Count")) for name in sorted(namelist): stab.row(name, namelist[name]) matches += 1 stab.set_callback("leftdouble", lambda name: run_quick_report_by_name_direct("samesurnames", database, document, name)) elif (filter_name == 'people with media'): stab.columns(_("Person"), _("Media count")) for person in database.iter_people(): length = len(person.get_media_list()) if length > 0: stab.row(person, str(length)) matches += 1 elif (filter_name == 'media references'): stab.columns(_("Person"), _("Reference")) for person in database.iter_people(): medialist = person.get_media_list() for item in medialist: stab.row(person, _("media")) matches += 1 elif (filter_name == 'unique media'): stab.columns(_("Unique Media")) for photo in database.iter_media(): fullname = media_path_full(database, photo.get_path()) stab.row(fullname) matches += 1 elif (filter_name == 'missing media'): stab.columns(_("Missing Media")) for photo in database.iter_media(): fullname = media_path_full(database, photo.get_path()) try: os.path.getsize(fullname) except: stab.row(fullname) matches += 1 elif (filter_name == 'media by size'): stab.columns(_("Media"), _("Size in bytes")) for photo in database.iter_media(): fullname = media_path_full(database, photo.get_path()) try: bytes = os.path.getsize(fullname) stab.row(fullname, str(bytes)) matches += 1 except: pass elif (filter_name == 'list of people'): stab.columns(_("Person"), _("Birth Date"), _("Name type")) handles = kwargs["handles"] for person_handle in handles: person = database.get_person_from_handle(person_handle) stab.row(person, sdb.birth_or_fallback(person), str(person.get_primary_name().get_type())) matches += 1 else: raise AttributeError("invalid filter name: '%s'" % filter_name) # translators: leave all/any {...} untranslated sdoc.paragraph(ngettext("Filter matched {number_of} record.", "Filter matched {number_of} records.", matches ).format(number_of=matches) ) sdoc.paragraph("") document.has_data = matches > 0 if matches > 0: stab.write(sdoc)
def run(self): """ Perform the actual extraction of information. """ # finds prefix, number, suffix of a Gramps ID ignoring a leading or # trailing space. The number must be at least three digits. _prob_id = re.compile(r'^ *([^\d]*)(\d{3,9})([^\d]*) *$') self.db.disable_signals() self.change = False num_merges = 0 with self.user.progress(_("Media Merge"), '', self.db.get_number_of_media()) as step: path_dict = {} for media in self.db.iter_media(): # this should collapse '../' constructs, deal with Windows '\' # and deal with Windows case insensitivity as well as deal # with relative paths and paths with environment variables. # it won't properly compare a Windows UNC path with an assigned # drive letter to that UNC path path = os.path.normcase(os.path.normpath( media_path_full(self.db, media.get_path()))) if path in path_dict: try: media1 = path_dict[path] # lets keep the shorter path, or if same # try to select the lower gramps_id # or lower handle as phoenix match = _prob_id.match(media.gramps_id) match1 = _prob_id.match(media1.gramps_id) mqo = media, media1 if len(media1.get_path()) < len(media.get_path()): mqo = media1, media elif len(media1.get_path()) == len(media.get_path()): if match and match1: if match1.groups()[1] < match.groups()[1]: mqo = media1, media else: # not (match and match1) if media1.handle < media.handle: mqo = media1, media query = MergeMediaQuery(self.dbstate, *mqo) # update to one we are keeping path_dict[path] = mqo[0] query.execute() except AssertionError: print("Tool/Family Tree processing/MediaMerge", "media1 gramps_id", path_dict[path].gramps_id, "media2 gramps_id", media.gramps_id) num_merges += 1 else: path_dict[path] = media step() self.db.enable_signals() self.db.request_rebuild() # translators: leave all/any {...} untranslated message = ngettext("{number_of} media merged", "{number_of} media merged", num_merges ).format(number_of=num_merges) if num_merges: OkDialog(_("Number of merges done"), message, parent=self.user.uistate.window) else: OkDialog(_('No modifications made'), _("No media items merged."), parent=self.user.uistate.window)
def write_person(self, person): newline = '<br/>' label = '<table border="0" cellspacing="2" cellpadding="0" cellborder="0"><tr><td>' media_list = person.get_media_list() if len(media_list) > 0: media_handle = media_list[0].get_reference_handle() media = self.database.get_media_from_handle(media_handle) media_mime_type = media.get_mime_type() if media_mime_type[0:5] == "image": image_path = get_thumbnail_path( media_path_full(self.database, media.get_path()), rectangle=media_list[0].get_rectangle()) if image_path: label += '<img src="%s"/></td><td>' % image_path label += self._name_display.display(person) label += ' %s' % self.symbols[person.get_gender()] for event_ref in person.get_primary_event_ref_list(): event = self.database.get_event_from_handle(event_ref.ref) if event.get_type() == EventType.NOB_TITLE: label += '<br/>%s' % place_displayer.display_event( self.database, event) if event.get_description(): label += ' (%s)' % event.get_description() label += ' %s' % self._get_date(event.get_date_object()) birth = get_birth_or_fallback(self.database, person) if birth: birth_symbol = self.symbols['birth'] fam_handle = person.get_main_parents_family_handle() if fam_handle: family = self.database.get_family_from_handle(fam_handle) if (family.type == FamilyRelType.UNMARRIED): birth_symbol = self.symbols['illegitimate'] birthdate = self._get_date(birth.get_date_object()) birthplace = place_displayer.display_event(self.database, birth) label += '<br/>%s' % birth_symbol if birthdate: label += ' %s' % birthdate if birth.description: label += ' (%s)' % birth.description if birthplace: label += ' %s' % birthplace death = get_death_or_fallback(self.database, person) if death: deathdate = self._get_date(death.get_date_object()) deathplace = place_displayer.display_event(self.database, death) label += '<br/>%s ' % self.symbols['death'] if deathdate: label += ' %s' % deathdate if death.description: label += ' (%s)' % death.description if deathplace: label += ' %s' % deathplace for event_ref in person.get_primary_event_ref_list(): event = self.database.get_event_from_handle(event_ref.ref) if event.get_type() == EventType.MILITARY_SERV: for attribute in event_ref.get_attribute_list(): if ((attribute.get_type() == AttributeType.DESCRIPTION) and (attribute.get_value() == 'Killed in Action')): label += '<br/>%s %s' % (self.symbols['kia'], event.get_description()) label += '</td></tr></table>' self.doc.add_node(node_id=person.get_gramps_id(), label=label, shape=self.nodeshape[person.get_gender()], style='%s,filled' % self.nodestyle[person.get_gender()], fillcolor=self.fillcolor[person.get_gender()], htmloutput=True)
def print_object(self, level, o): if issubclass(o.__class__, gramps.gen.lib.address.Address): # Details of address are printed by the subclass conditions, # primarily by LocationBase, because address is a subclass of # LocationBase pass if issubclass(o.__class__, gramps.gen.lib.addressbase.AddressBase): for address in o.get_address_list(): self.print_header(level, _("Address"), ref=address) self.print_object(level + 1, address) if isinstance(o, gramps.gen.lib.Attribute): # The unique information about attributes (the type) is printed by # AttributeBase pass if issubclass(o.__class__, gramps.gen.lib.attrbase.AttributeBase): for attribute in o.get_attribute_list(): self.print_header(level, _("Attribute") + ". ", type_desc=str(attribute.get_type()), obj_type=attribute.get_value(), privacy=attribute.get_privacy(), ref=attribute) self.print_object(level + 1, attribute) if isinstance(o, gramps.gen.lib.ChildRef): # The unique information about ChildRef (the father relation and # mother relation) is printed by the main write_report function pass if issubclass(o.__class__, gramps.gen.lib.citationbase.CitationBase): if self.print_citations: self.print_header(level, "CitationBase tbd") for citation_handle in o.get_citation_list(): citation = self.database.get_citation_from_handle( citation_handle) self.print_object(level + 1, citation) if isinstance(o, gramps.gen.lib.Citation): # the unique information about Citation (the page) is printed by the # bibliography code. The other unique information, the confidence is # printed here if o.get_confidence_level() != gramps.gen.lib.Citation.CONF_NORMAL: self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text(_("Confidence") + " : ") self.doc.end_bold() self.doc.write_text( conf_strings.get(o.get_confidence_level(), _('Unknown'))) self.doc.end_paragraph() if self.print_citations: source_handle = o.get_reference_handle() source = self.database.get_source_from_handle(source_handle) self.print_object(level + 1, source) if issubclass(o.__class__, gramps.gen.lib.datebase.DateBase): if o.get_date_object() and not o.get_date_object().is_empty(): self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text(_("Date") + " : ") self.doc.end_bold() self.doc.write_text(displayer.display(o.get_date_object())) self.doc.end_paragraph() if isinstance(o, gramps.gen.lib.Event): # The event type is printed by the main write_report function self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text(_("Description") + " : ") self.doc.end_bold() self.doc.write_text(str(o.get_description())) self.doc.end_paragraph() if issubclass(o.__class__, gramps.gen.lib.eventref.EventRef): # The unique information about EventRef (the EventRoleType) is # printed by the main write_report function event = self.database.get_event_from_handle( o.get_reference_handle()) self.print_header(level, _("Event"), event.get_gramps_id(), _("Event type"), str(event.get_type()), event.get_privacy(), ref=event) self.print_object(level + 1, event) if isinstance(o, gramps.gen.lib.Family): # The unique information about Family (father, mother and children, # FamilyRelType and event references) are printed by the main # write_report function pass if isinstance(o, gramps.gen.lib.LdsOrd): # The Ordinance type is printed by LdsOrdBase self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text(_("Temple and status") + " : ") self.doc.end_bold() self.doc.write_text(", ".join( (TEMPLES.name(o.get_temple()), o.status2str()))) self.doc.end_paragraph() f_h = o.get_family_handle() if f_h: family = self.database.get_family_from_handle(f_h) self.print_family_summary(level + 1, family, _("LDS Ordinance family")) if issubclass(o.__class__, gramps.gen.lib.ldsordbase.LdsOrdBase): for ldsord in o.get_lds_ord_list(): self.print_header(level, _("LDS "), type_desc=_("Ordinance"), obj_type=ldsord.type2str(), privacy=ldsord.get_privacy(), ref=ldsord) self.print_object(level + 1, ldsord) if isinstance(o, gramps.gen.lib.Location): # The unique information about location (Parish) is printed by # Place. Location otherwise serves as a pointer to a LocationBase # object pass if issubclass(o.__class__, gramps.gen.lib.locationbase.LocationBase): self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text( _("Street, City, County, State, Postal Code, " "Country, Phone number") + " : ") self.doc.end_bold() self.doc.write_text(", ".join( (o.get_street(), o.get_city(), o.get_county(), o.get_state(), o.get_postal_code(), o.get_country(), o.get_phone()))) self.doc.end_paragraph() if issubclass(o.__class__, gramps.gen.lib.mediabase.MediaBase): for mediaref in o.get_media_list(): self.print_header(level, _("Media Reference"), ref=mediaref) self.print_object(level + 1, mediaref) if isinstance(o, gramps.gen.lib.MediaObject): # thumb is not printed. The mime type is printed by MediaRef self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text(_("Description and Path") + " : ") self.doc.end_bold() self.doc.write_text(o.get_description() + ", ") path = o.get_path() if path: mark = IndexMark( "file://:" + media_path_full(self.database, path), LOCAL_HYPERLINK) self.doc.write_text(path, mark=mark) self.doc.end_paragraph() mime_type = o.get_mime_type() if mime_type and mime_type.startswith("image"): filename = media_path_full(self.database, o.get_path()) if os.path.exists(filename): self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.add_media_object(filename, "single", 4.0, 4.0) self.doc.end_paragraph() else: self._user.warn( _("Could not add photo to page"), "%s: %s" % (filename, _('File does not exist'))) if isinstance(o, gramps.gen.lib.MediaRef): mediaobject_handle = o.get_reference_handle() mediaobject = self.database.get_object_from_handle( mediaobject_handle) if o.get_rectangle(): self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text(_("Referenced Region") + " : ") self.doc.end_bold() self.doc.write_text(", ".join( (("%d" % i) for i in o.get_rectangle()))) self.doc.end_paragraph() mime_type = mediaobject.get_mime_type() if mime_type and mime_type.startswith("image"): filename = media_path_full(self.database, mediaobject.get_path()) if os.path.exists(filename): self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.add_media_object(filename, "single", 4.0, 4.0, crop=o.get_rectangle()) self.doc.end_paragraph() desc = get_description(mediaobject.get_mime_type()) if not desc: desc = _("unknown") self.print_header(level, _("Media Object"), mediaobject.get_gramps_id(), _("Mime type"), desc, mediaobject.get_privacy(), ref=mediaobject) self.print_object(level + 1, mediaobject) if isinstance(o, gramps.gen.lib.Name): # group_as, sort_as and display_as are not printed. NameType is # printed by the main write_report function self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text( _("Given name(s): Title, Given, Suffix, " "Call Name, Nick Name, Family Nick Name") + " : ") self.doc.end_bold() self.doc.write_text(", ".join( (o.get_title(), o.get_first_name(), o.get_suffix(), o.get_call_name(), o.get_nick_name(), o.get_family_nick_name()))) self.doc.end_paragraph() if isinstance(o, gramps.gen.lib.Note): # The NoteType is printed by NoteBase. Whether the note is flowed or # not is not printed, but affects the way the note appears self.doc.write_styled_note( o.get_styledtext(), o.get_format(), "PE-Level%d" % min(level, 32), contains_html=o.get_type() == gramps.gen.lib.notetype.NoteType.HTML_CODE) if issubclass(o.__class__, gramps.gen.lib.notebase.NoteBase): for n_h in o.get_note_list(): note = self.database.get_note_from_handle(n_h) self.print_header(level, _("Note"), note.get_gramps_id(), _("Note type"), str(note.get_type()), note.get_privacy()) self.print_object(level + 1, note) if issubclass(o.__class__, gramps.gen.lib.Person): # This is printed by the main write-report function pass if isinstance(o, gramps.gen.lib.Place): # The title, name, type, code and lat/long are printed by PlaceBase for placeref in o.get_placeref_list(): self.print_header(level, _("Parent Place")) self.print_object(level + 1, placeref) # location = o.get_main_location() # if location.get_parish(): # self.print_header(level, _("Main Location"), # type_desc=_("Parish"), # obj_type=location.get_parish()) # else: # self.print_header(level, _("Main Location")) # # self.print_object(level+1, location) # for location in o.get_alternate_locations(): if location.get_parish(): self.print_header(level, _("Alternate Location"), type_desc=_("Parish"), obj_type=location.get_parish()) else: self.print_header(level, _("Alternate Location")) self.print_object(level + 1, location) if issubclass(o.__class__, gramps.gen.lib.placebase.PlaceBase) or \ issubclass(o.__class__, gramps.gen.lib.placeref.PlaceRef): if issubclass(o.__class__, gramps.gen.lib.placebase.PlaceBase): place_handle = o.get_place_handle() else: place_handle = o.get_reference_handle() if place_handle: place = self.database.get_place_from_handle(place_handle) if place: place_title = place_displayer.display(self.database, place) self.print_header(level, _("Place"), place.get_gramps_id(), _("Place Title"), place_title, privacy=place.get_privacy(), ref=place) self.doc.start_paragraph("PE-Level%d" % min(level + 1, 32)) self.doc.start_bold() self.doc.write_text(_("Name") + " : ") self.doc.end_bold() self.doc.write_text(place.get_name().value) self.doc.start_bold() self.doc.write_text(" " + _("Type") + " : ") self.doc.end_bold() self.doc.write_text(str(place.get_type())) self.doc.start_bold() self.doc.write_text(" " + _("Code") + " : ") self.doc.end_bold() self.doc.write_text(place.get_code()) self.doc.end_paragraph() for name in place.get_alternative_names(): self.doc.start_paragraph("PE-Level%d" % min(level + 1, 32)) self.doc.start_bold() self.doc.write_text(_("Alternative Name") + " : ") self.doc.end_bold() self.doc.write_text(name) self.doc.end_paragraph() if place.get_longitude() or place.get_latitude(): self.doc.start_paragraph("PE-Level%d" % min(level + 1, 32)) self.doc.start_bold() self.doc.write_text(_("Latitude, Longitude") + " : ") self.doc.end_bold() self.doc.write_text(", ".join( (place.get_longitude(), place.get_latitude()))) self.doc.end_paragraph() self.print_object(level + 1, place) if issubclass(o.__class__, gramps.gen.lib.primaryobj.BasicPrimaryObject): # The Gramps ID is printed by the enclosing object pass if issubclass(o.__class__, gramps.gen.lib.privacybase.PrivacyBase): # The privacy is printed by the enclosing object pass if isinstance(o, gramps.gen.lib.RepoRef): # The media type is printed by source self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text(_("Call number") + " : ") self.doc.end_bold() self.doc.write_text(o.get_call_number()) self.doc.end_paragraph() repository_handle = o.get_reference_handle() repository = self.database.get_repository_from_handle( repository_handle) self.print_header(level, _("Repository"), repository.get_gramps_id(), _("Repository type"), str(repository.get_type()), privacy=repository.get_privacy()) self.print_object(level + 1, repository) if isinstance(o, gramps.gen.lib.Repository): # the repository type is printed by RepoRef pass if isinstance(o, gramps.gen.lib.Source): # The title, author, abbreviation and publication information are # printed by the bibliography code # data_map = o.get_data_map() # for key in data_map.keys(): # self.doc.start_paragraph("PE-Level%d" % min(level, 32)) # self.doc.start_bold() # self.doc.write_text(_("Data") + ". " + key + " : ") # self.doc.end_bold() # self.doc.write_text(data_map[key]) # self.doc.end_paragraph() reporef_list = o.get_reporef_list() for reporef in reporef_list: self.print_header(level, _("Repository reference"), type_desc=_("Media type"), obj_type=str(reporef.get_media_type()), privacy=reporef.get_privacy()) self.print_object(level + 1, reporef) if isinstance(o, gramps.gen.lib.Surname): if o.get_origintype(): self.print_header(level, _("Surname"), type_desc=_("Origin type"), obj_type=str(o.get_origintype())) else: self.print_header(level, _("Surname"), privacy=o.get_privacy()) self.doc.start_paragraph("PE-Level%d" % min(level + 1, 32)) self.doc.start_bold() self.doc.write_text(_("Prefix, surname, connector") + " : ") self.doc.end_bold() self.doc.write_text(", ".join( (o.get_prefix(), o.get_surname(), o.get_connector()))) if o.get_primary(): self.doc.write_text(" " + _("{This is the primary surname}")) self.doc.end_paragraph() if isinstance(o, gramps.gen.lib.surnamebase.SurnameBase): surname_list = o.get_surname_list() for surname in surname_list: self.print_object(level, surname) if issubclass(o.__class__, gramps.gen.lib.tagbase.TagBase): for tag_handle in o.get_tag_list(): tag = self.database.get_tag_from_handle(tag_handle) self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text(_("Tag name") + " : ") self.doc.end_bold() self.doc.write_text(tag.get_name()) self.doc.end_paragraph() self.print_object(level + 1, tag) if issubclass(o.__class__, gramps.gen.lib.Tag): # The tag name is printed by TagBase if o.get_color() != "#000000000000" or o.get_priority() != 0: self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text(_("Tag colour and priority") + " : ") self.doc.end_bold() self.doc.write_text(o.get_color() + ", " + "%d" % o.get_priority()) self.doc.end_paragraph() if issubclass(o.__class__, gramps.gen.lib.urlbase.UrlBase): for url in o.get_url_list(): self.print_header(level, _("URL"), type_desc=_("Type"), obj_type=str(url.get_type()), privacy=url.get_privacy()) self.print_object(level + 1, url) if isinstance(o, gramps.gen.lib.Url): self.doc.start_paragraph("PE-Level%d" % min(level, 32)) self.doc.start_bold() self.doc.write_text(_("Description and Path") + " : ") self.doc.end_bold() self.doc.write_text(o.get_description() + ", ") path = o.get_path() if path: mark = IndexMark(path, LOCAL_HYPERLINK) self.doc.write_text(path, mark=mark) self.doc.end_paragraph() return o
def write_person(self, count): if count != 0: self.doc.page_break() self.bibli = Bibliography(Bibliography.MODE_DATE | Bibliography.MODE_PAGE) text = self._name_display.display(self.person) # feature request 2356: avoid genitive form title = self._("Complete Individual Report: %s") % text mark = IndexMark(title, INDEX_TYPE_TOC, 1) self.doc.start_paragraph("IDS-Title") self.doc.write_text(title, mark) self.doc.end_paragraph() self.doc.start_paragraph("IDS-Normal") self.doc.end_paragraph() name = self.person.get_primary_name() text = self.get_name(self.person) mark = ReportUtils.get_person_mark(self._db, self.person) endnotes = self._cite_endnote(self.person) endnotes = self._cite_endnote(name, prior=endnotes) family_handle = self.person.get_main_parents_family_handle() if family_handle: family = self._db.get_family_from_handle(family_handle) father_inst_id = family.get_father_handle() if father_inst_id: father_inst = self._db.get_person_from_handle(father_inst_id) father = self.get_name(father_inst) fmark = ReportUtils.get_person_mark(self._db, father_inst) else: father = "" fmark = None mother_inst_id = family.get_mother_handle() if mother_inst_id: mother_inst = self._db.get_person_from_handle(mother_inst_id) mother = self.get_name(mother_inst) mmark = ReportUtils.get_person_mark(self._db, mother_inst) else: mother = "" mmark = None else: father = "" fmark = None mother = "" mmark = None media_list = self.person.get_media_list() p_style = 'IDS-PersonTable2' self.mime0 = None if self.use_images and len(media_list) > 0: media0 = media_list[0] media_handle = media0.get_reference_handle() media = self._db.get_media_from_handle(media_handle) self.mime0 = media.get_mime_type() if self.mime0 and self.mime0.startswith("image"): image_filename = media_path_full(self._db, media.get_path()) if os.path.exists(image_filename): p_style = 'IDS-PersonTable' # this is tested for, also else: self._user.warn( _("Could not add photo to page"), # translators: for French, else ignore _("%(str1)s: %(str2)s") % { 'str1': image_filename, 'str2': _('File does not exist') }) self.doc.start_table('person', p_style) self.doc.start_row() self.doc.start_cell('IDS-NormalCell') # translators: needed for French, ignore otherwise ignore4 = self._("%s:") self.write_paragraph(self._("%s:") % self._("Name")) self.write_paragraph(self._("%s:") % self._("Gender")) self.write_paragraph(self._("%s:") % self._("Father")) self.write_paragraph(self._("%s:") % self._("Mother")) self.doc.end_cell() self.doc.start_cell('IDS-NormalCell') self.write_paragraph(text, endnotes, mark) if self.person.get_gender() == Person.MALE: self.write_paragraph(self._("Male")) elif self.person.get_gender() == Person.FEMALE: self.write_paragraph(self._("Female")) else: self.write_paragraph(self._("Unknown")) self.write_paragraph(father, mark=fmark) self.write_paragraph(mother, mark=mmark) self.doc.end_cell() if p_style == 'IDS-PersonTable': self.doc.start_cell('IDS-NormalCell') self.doc.add_media(image_filename, "right", 4.0, 4.0, crop=media0.get_rectangle()) endnotes = self._cite_endnote(media0) attr_list = media0.get_attribute_list() if len(attr_list) == 0: text = _('(image)') else: for attr in attr_list: attr_type = attr.get_type().type2base() # translators: needed for French, ignore otherwise text = self._("%(str1)s: %(str2)s") % { 'str1': self._(attr_type), 'str2': attr.get_value() } endnotes = self._cite_endnote(attr, prior=endnotes) self.write_paragraph("(%s)" % text, endnotes=endnotes, style='IDS-ImageNote') endnotes = '' if endnotes and len(attr_list) == 0: self.write_paragraph(text, endnotes=endnotes, style='IDS-ImageNote') self.doc.end_cell() self.doc.end_row() self.doc.end_table() self.doc.start_paragraph("IDS-Normal") self.doc.end_paragraph() self.write_alt_names() self.write_events() self.write_alt_parents() self.write_families() self.write_addresses() self.write_associations() self.write_attributes() self.write_LDS_ordinances() self.write_tags() self.write_images() self.write_note() if self.use_srcs: if self.use_pagebreak and self.bibli.get_citation_count(): self.doc.page_break() Endnotes.write_endnotes(self.bibli, self._db, self.doc, printnotes=self.use_srcs_notes, elocale=self._locale)
def mediapage(self, report, title, media_handle, info): """ Generate and output an individual Media page. @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page @param: media_handle -- The media handle to use @param: info -- A tuple containing the media handle for the next and previous media, the current page number, and the total number of media pages """ media = report.database.get_media_from_handle(media_handle) BasePage.__init__(self, report, title, media.gramps_id) (prev, next_, page_number, total_pages) = info ldatec = media.get_change_time() # get media rectangles _region_items = self.media_ref_rect_regions(media_handle) output_file, sio = self.report.create_file(media_handle, "img") self.uplink = True self.bibli = Bibliography() # get media type to be used primarily with "img" tags mime_type = media.get_mime_type() if mime_type: newpath = self.copy_source_file(media_handle, media) target_exists = newpath is not None else: target_exists = False self.copy_thumbnail(media_handle, media) self.page_title = media.get_description() esc_page_title = html_escape(self.page_title) result = self.write_header("%s - %s" % (self._("Media"), self.page_title)) mediapage, head, dummy_body, outerwrapper = result # if there are media rectangle regions, attach behaviour style sheet if _region_items: fname = "/".join(["css", "behaviour.css"]) url = self.report.build_url_fname(fname, None, self.uplink) head += Html("link", href=url, type="text/css", media="screen", rel="stylesheet") # begin MediaDetail division with Html("div", class_="content", id="GalleryDetail") as mediadetail: outerwrapper += mediadetail # media navigation with Html("div", id="GalleryNav", role="navigation") as medianav: mediadetail += medianav if prev: medianav += self.media_nav_link(prev, self._("Previous"), True) data = self._( '%(strong1_strt)s%(page_number)d%(strong_end)s ' 'of %(strong2_strt)s%(total_pages)d%(strong_end)s') % { 'strong1_strt': '<strong id="GalleryCurrent">', 'strong2_strt': '<strong id="GalleryTotal">', 'strong_end': '</strong>', 'page_number': page_number, 'total_pages': total_pages } medianav += Html("span", data, id="GalleryPages") if next_: medianav += self.media_nav_link(next_, self._("Next"), True) # missing media error message errormsg = self._("The file has been moved or deleted.") # begin summaryarea division with Html("div", id="summaryarea") as summaryarea: mediadetail += summaryarea if mime_type: if mime_type.startswith("image"): if not target_exists: with Html("div", id="MediaDisplay") as mediadisplay: summaryarea += mediadisplay mediadisplay += Html("span", errormsg, class_="MissingImage") else: # Check how big the image is relative to the # requested 'initial' image size. # If it's significantly bigger, scale it down to # improve the site's responsiveness. We don't want # the user to have to await a large download # unnecessarily. Either way, set the display image # size as requested. orig_image_path = media_path_full( self.r_db, media.get_path()) (width, height) = image_size(orig_image_path) max_width = self.report.options[ 'maxinitialimagewidth'] # TODO. Convert disk path to URL. url = self.report.build_url_fname( orig_image_path, None, self.uplink) with Html("div", id="GalleryDisplay", style='max-width: %dpx; height: auto' % (max_width)) as mediadisplay: summaryarea += mediadisplay # Feature #2634; display the mouse-selectable # regions. See the large block at the top of # this function where the various regions are # stored in _region_items if _region_items: ordered = Html("ol", class_="RegionBox") mediadisplay += ordered while _region_items: (name, coord_x, coord_y, width, height, linkurl) = _region_items.pop() ordered += Html( "li", style="left:%d%%; " "top:%d%%; " "width:%d%%; " "height:%d%%;" % (coord_x, coord_y, width, height) ) + (Html("a", name, href=linkurl)) # display the image if orig_image_path != newpath: url = self.report.build_url_fname( newpath, None, self.uplink) s_width = 'width: %dpx;' % max_width mediadisplay += Html("a", href=url) + (Html( "img", src=url, style=s_width, alt=esc_page_title)) else: dirname = tempfile.mkdtemp() thmb_path = os.path.join(dirname, "document.png") if run_thumbnailer( mime_type, media_path_full(self.r_db, media.get_path()), thmb_path, 320): try: path = self.report.build_path( "preview", media.get_handle()) npath = os.path.join(path, media.get_handle()) npath += ".png" self.report.copy_file(thmb_path, npath) path = npath os.unlink(thmb_path) except EnvironmentError: path = os.path.join("images", "document.png") else: path = os.path.join("images", "document.png") os.rmdir(dirname) with Html("div", id="GalleryDisplay") as mediadisplay: summaryarea += mediadisplay img_url = self.report.build_url_fname( path, None, self.uplink) if target_exists: # TODO. Convert disk path to URL url = self.report.build_url_fname( newpath, None, self.uplink) s_width = 'width: 48px;' hyper = Html( "a", href=url, title=esc_page_title) + ( Html("img", src=img_url, style=s_width, alt=esc_page_title)) mediadisplay += hyper else: mediadisplay += Html("span", errormsg, class_="MissingImage") else: with Html("div", id="GalleryDisplay") as mediadisplay: summaryarea += mediadisplay url = self.report.build_url_image( "document.png", "images", self.uplink) s_width = 'width: 48px;' mediadisplay += Html("img", src=url, style=s_width, alt=esc_page_title, title=esc_page_title) # media title title = Html("h3", html_escape(self.page_title.strip()), inline=True) summaryarea += title # begin media table with Html("table", class_="infolist gallery") as table: summaryarea += table # Gramps ID media_gid = media.gramps_id if not self.noid and media_gid: trow = Html("tr") + (Html("td", self._("Gramps ID"), class_="ColumnAttribute", inline=True), Html("td", media_gid, class_="ColumnValue", inline=True)) table += trow # mime type if mime_type: trow = Html("tr") + (Html("td", self._("File Type"), class_="ColumnAttribute", inline=True), Html("td", mime_type, class_="ColumnValue", inline=True)) table += trow # media date date = media.get_date_object() if date and date is not Date.EMPTY: trow = Html("tr") + (Html("td", self._("Date"), class_="ColumnAttribute", inline=True), Html("td", self.rlocale.get_date(date), class_="ColumnValue", inline=True)) table += trow # get media notes notelist = self.display_note_list(media.get_note_list(), Media) if notelist is not None: mediadetail += notelist # get attribute list attrlist = media.get_attribute_list() if attrlist: attrsection, attrtable = self.display_attribute_header() self.display_attr_list(attrlist, attrtable) mediadetail += attrsection # get media sources srclist = self.display_media_sources(media) if srclist is not None: mediadetail += srclist # get media references reflist = self.display_bkref_list(Media, media_handle) if reflist is not None: mediadetail += reflist # 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(mediapage, output_file, sio, ldatec)
def main(self): self.set_text(_("Processing...")) database = self.dbstate.db total_media = 0 males = 0 females = 0 unknowns = 0 bytes = 0 notfound = [] mobjects = database.get_number_of_media() mbytes = "0" for media in database.iter_media(): fullname = media_path_full(database, media.get_path()) try: bytes += posixpath.getsize(fullname) length = len(str(bytes)) if bytes <= 999999: mbytes = _("less than 1") else: mbytes = str(bytes)[:(length - 6)] except OSError: notfound.append(media.get_path()) if hasattr(database, 'genderStats'): males = sum([v[0] for v in database.genderStats.stats.values()]) females = sum([v[1] for v in database.genderStats.stats.values()]) unknowns = sum([v[2] for v in database.genderStats.stats.values()]) self.clear_text() self.append_text(_("Individuals") + "\n") self.append_text("----------------------------\n") self.link(_("Number of individuals") + COLON, 'Filter', 'all people') self.append_text(" %s" % database.get_number_of_people()) self.append_text("\n") self.link(_("%s:") % _("Males"), 'Filter', 'males') self.append_text(" %s" % males) self.append_text("\n") self.link(_("%s:") % _("Females"), 'Filter', 'females') self.append_text(" %s" % females) self.append_text("\n") self.link( _("%s:") % _("Individuals with unknown gender"), 'Filter', 'people with unknown gender') self.append_text(" %s" % unknowns) self.append_text("\n") self.append_text("\n%s\n" % _("Family Information")) self.append_text("----------------------------\n") self.link(_("%s:") % _("Number of families"), 'Filter', 'all families') self.append_text(" %s" % database.get_number_of_families()) self.append_text("\n") if hasattr(database, 'surname_list'): self.link( _("%s:") % _("Unique surnames"), 'Filter', 'unique surnames') self.append_text(" %s" % len(set(database.surname_list))) self.append_text("\n") self.append_text("\n%s\n" % _("Media Objects")) self.append_text("----------------------------\n") self.link( _("%s:") % _("Total number of media object references"), 'Filter', 'media references') self.append_text(" %s" % total_media) self.append_text("\n") self.link( _("%s:") % _("Number of unique media objects"), 'Filter', 'unique media') self.append_text(" %s" % mobjects) self.append_text("\n") self.link( _("%s:") % _("Total size of media objects"), 'Filter', 'media by size') self.append_text(" %s %s" % (mbytes, _("Megabyte|MB"))) self.append_text("\n") self.link( _("%s:") % _("Missing Media Objects"), 'Filter', 'missing media') self.append_text(" %s\n" % len(notfound)) self.append_text("", scroll_to="begin")
def export(self): # missmedia_action = 0 #-------------------------------------------------------------- # def remove_clicked(): # # File is lost => remove all references and the object itself # for p_id in self.db.iter_family_handles(): # p = self.db.get_family_from_handle(p_id) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_family(p,None) # for key in self.db.iter_person_handles(): # p = self.db.get_person_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_person(p,None) # for key in self.db.get_source_handles(): # p = self.db.get_source_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_source(p,None) # for key in self.db.get_place_handles(): # p = self.db.get_place_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_place(p,None) # for key in self.db.get_event_handles(): # p = self.db.get_event_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_event(p,None) # self.db.remove_media(m_id,None) # def leave_clicked(): # # File is lost => do nothing, leave as is # pass # def select_clicked(): # # File is lost => select a file to replace the lost one # def fs_close_window(obj): # pass # def fs_ok_clicked(obj): # name = fs_top.get_filename() # if os.path.isfile(name): # archive.add(name) # fs_top = gtk.FileChooserDialog("%s - GRAMPS" % _("Select file"), # buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, # gtk.STOCK_OK, Gtk.ResponseType.OK) # ) # response = fs_top.run() # if response == Gtk.ResponseType.OK: # fs_ok_clicked(fs_top) # elif response == gtk.RESPONSE_CANCEL: # fs_close_window(fs_top) # fs_top.destroy() #--------------------------------------------------------------- try: with tarfile.open(self.filename, 'w:gz') as archive: # Write media files first, since the database may be modified # during the process (i.e. when removing object) handles = self.db.get_media_handles(sort_handles=True) for indx, m_id in enumerate(handles): self.user.callback(indx * 100 / len(handles)) mobject = self.db.get_media_from_handle(m_id) filename = media_path_full(self.db, mobject.get_path()) archname = str(mobject.get_path()) if os.path.isfile(filename) and os.access(filename, os.R_OK): archive.add(filename, archname, filter=fix_mtime) # Write XML now with BytesIO() as g: gfile = XmlWriter(self.db, self.user, 2) gfile.write_handle(g) tarinfo = tarfile.TarInfo('data.gramps') tarinfo.size = len(g.getvalue()) tarinfo.mtime = time.time() if not win(): tarinfo.uid = os.getuid() tarinfo.gid = os.getgid() g.seek(0) archive.addfile(tarinfo, g) return True except (EnvironmentError, OSError) as msg: log.warning(str(msg)) self.user.notify_error(_('Failure writing %s') % self.filename, str(msg)) return 0