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 drag_data_received(self, widget, context, x, y, sel_data, info, time): """ Handle the standard gtk interface for drag_data_received. If the selection data is define, extract the value from sel_data.data, and decide if this is a move or a reorder. The only data we accept on mediaview is dropping a file, so URI_LIST. We assume this is what we obtain """ if not sel_data: return files = sel_data.get_uris() for file in files: protocol, site, mfile, j, k, l = urlparse(file) if protocol == "file": name = url2pathname(mfile) mime = get_type(name) if not is_valid_type(mime): return photo = Media() self.uistate.set_busy_cursor(True) photo.set_checksum(create_checksum(name)) self.uistate.set_busy_cursor(False) base_dir = str(media_path(self.dbstate.db)) if os.path.exists(base_dir): name = relative_path(name, base_dir) photo.set_path(name) photo.set_mime_type(mime) basename = os.path.basename(name) (root, ext) = os.path.splitext(basename) photo.set_description(root) with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans: self.dbstate.db.add_media(photo, trans) widget.emit_stop_by_name('drag_data_received')
def drag_data_received(self, widget, context, x, y, sel_data, info, time): """ Handle the standard gtk interface for drag_data_received. If the selection data is define, extract the value from sel_data.data, and decide if this is a move or a reorder. The only data we accept on mediaview is dropping a file, so URI_LIST. We assume this is what we obtain """ if not sel_data: return files = sel_data.get_uris() for file in files: protocol, site, mfile, j, k, l = urlparse(file) if protocol == "file": name = url2pathname(mfile) mime = get_type(name) if not is_valid_type(mime): return photo = MediaObject() self.uistate.set_busy_cursor(True) photo.set_checksum(create_checksum(name)) self.uistate.set_busy_cursor(False) base_dir = str(media_path(self.dbstate.db)) if os.path.exists(base_dir): name = relative_path(name, base_dir) photo.set_path(name) photo.set_mime_type(mime) basename = os.path.basename(name) (root, ext) = os.path.splitext(basename) photo.set_description(root) with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans: self.dbstate.db.add_object(photo, trans) widget.emit_stop_by_name('drag_data_received')
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 drag_data_received(self, widget, context, x, y, sel_data, info, time): """ Handle the standard gtk interface for drag_data_received. If the selection data is define, extract the value from sel_data.data, and decide if this is a move or a reorder. """ if sel_data and sel_data.get_data(): try: (mytype, selfid, obj, row_from) = pickle.loads(sel_data.get_data()) # make sure this is the correct DND type for this object if mytype == self._DND_TYPE.drag_type: # determine the destination row data = self.iconlist.get_dest_item_at_pos(x, y) if data: (path, pos) = data row = path.get_indices()[0] if pos == Gtk.IconViewDropPosition.DROP_LEFT: row = max(row, 0) elif pos == Gtk.IconViewDropPosition.DROP_RIGHT: row = min(row, len(self.get_data())) elif pos == Gtk.IconViewDropPosition.DROP_INTO: row = min(row+1, len(self.get_data())) else: row = len(self.get_data()) # if the is same object, we have a move, otherwise, # it is a standard drag-n-drop if id(self) == selfid: self._move(row_from, row, obj) else: self._handle_drag(row, obj) self.rebuild() elif mytype == DdTargets.MEDIAOBJ.drag_type: oref = MediaRef() oref.set_reference_handle(obj) self.get_data().append(oref) self.changed = True self.rebuild() elif self._DND_EXTRA and mytype == self._DND_EXTRA.drag_type: self.handle_extra_type(mytype, obj) except pickle.UnpicklingError: files = sel_data.get_uris() for file in files: protocol, site, mfile, j, k, l = urlparse(file) if protocol == "file": name = url2pathname(mfile) mime = get_type(name) if not is_valid_type(mime): return photo = MediaObject() self.uistate.set_busy_cursor(True) photo.set_checksum(create_checksum(name)) self.uistate.set_busy_cursor(False) base_dir = str(media_path(self.dbstate.db)) if os.path.exists(base_dir): name = relative_path(name, base_dir) photo.set_path(name) photo.set_mime_type(mime) basename = os.path.basename(name) (root, ext) = os.path.splitext(basename) photo.set_description(root) with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans: self.dbstate.db.add_object(photo, trans) oref = MediaRef() oref.set_reference_handle(photo.get_handle()) self.get_data().append(oref) self.changed = True self.rebuild()
def drag_data_received(self, widget, context, x, y, sel_data, info, time): """ Handle the standard gtk interface for drag_data_received. If the selection data is define, extract the value from sel_data.data, and decide if this is a move or a reorder. """ if sel_data and sel_data.get_data(): try: (mytype, selfid, obj, row_from) = pickle.loads(sel_data.get_data()) # make sure this is the correct DND type for this object if mytype == self._DND_TYPE.drag_type: # determine the destination row data = self.iconlist.get_dest_item_at_pos(x, y) if data: (path, pos) = data row = path.get_indices()[0] if pos == Gtk.IconViewDropPosition.DROP_LEFT: row = max(row, 0) elif pos == Gtk.IconViewDropPosition.DROP_RIGHT: row = min(row, len(self.get_data())) elif pos == Gtk.IconViewDropPosition.DROP_INTO: row = min(row + 1, len(self.get_data())) else: row = len(self.get_data()) # if the is same object, we have a move, otherwise, # it is a standard drag-n-drop if id(self) == selfid: self._move(row_from, row, obj) else: self._handle_drag(row, obj) self.rebuild() elif mytype == DdTargets.MEDIAOBJ.drag_type: oref = MediaRef() oref.set_reference_handle(obj) self.get_data().append(oref) self.changed = True self.rebuild() elif self._DND_EXTRA and mytype == self._DND_EXTRA.drag_type: self.handle_extra_type(mytype, obj) except pickle.UnpicklingError: files = sel_data.get_uris() for file in files: protocol, site, mfile, j, k, l = urlparse(file) if protocol == "file": name = url2pathname(mfile) mime = get_type(name) if not is_valid_type(mime): return photo = MediaObject() self.uistate.set_busy_cursor(True) photo.set_checksum(create_checksum(name)) self.uistate.set_busy_cursor(False) base_dir = str(media_path(self.dbstate.db)) if os.path.exists(base_dir): name = relative_path(name, base_dir) photo.set_path(name) photo.set_mime_type(mime) basename = os.path.basename(name) (root, ext) = os.path.splitext(basename) photo.set_description(root) with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans: self.dbstate.db.add_object(photo, trans) oref = MediaRef() oref.set_reference_handle(photo.get_handle()) self.get_data().append(oref) self.changed = True self.rebuild()
def __init__(self, report, title): """ @param: report -- The instance of the main report class for this report @param: title -- Is the title of the web page """ BasePage.__init__(self, report, title) # do NOT include a Download Page if not self.report.inc_download: return # menu options for class # download and description #n ( 1 <= n < 5 ) dlfname = self.report.dl_fname dldescr = self.report.dl_descr # if no filenames at all, return??? if dlfname: output_file, sio = self.report.create_file("download") result = self.write_header(self._('Download')) downloadpage, dummy_head, dummy_body, outerwrapper = result # begin download page and table with Html("div", class_="content", id="Download") as download: outerwrapper += download msg = self._("This page is for the user/ creator " "of this Family Tree/ Narrative website " "to share a couple of files with you " "regarding their family. If there are " "any files listed " "below, clicking on them will allow you " "to download them. The " "download page and files have the same " "copyright as the remainder " "of these web pages.") download += Html("p", msg, id="description") # begin download table and table head with Html("table", class_="infolist download") as table: download += table thead = Html("thead") table += thead trow = Html("tr") thead += trow trow.extend( Html("th", label, class_="Column" + colclass, inline=True) for (label, colclass) in [( self._("File Name"), "Filename"), ( self._("Description"), "Description" ), (self._("Last Modified"), "Modified"), (self._("MD5"), "Md5")]) # table body tbody = Html("tbody") table += tbody dwnld = 0 for fnamex in dlfname: # if fnamex is not None, do we have a file to download? if fnamex: fname = os.path.basename(dlfname[fnamex]) # if fname is not None, show it if fname: dwnld += 1 trow = Html("tr", id='Row01') tbody += trow dldescrx = dldescr[fnamex] tcell = Html("td", class_="ColumnFilename") + ( Html("a", fname, href=fname, title=html_escape(dldescrx))) trow += tcell dldescr1 = dldescrx or " " trow += Html("td", dldescr1, inline=True, class_="ColumnDescription") tcell = Html("td", class_="ColumnModified", inline=True) trow += tcell if os.path.exists(dlfname[fnamex]): md5 = create_checksum(dlfname[fnamex]) trow += Html("td", md5, class_="ColumnMd5", inline=True) modified = os.stat( dlfname[fnamex]).st_mtime last_mod = datetime.datetime.fromtimestamp( modified) tcell += last_mod # copy the file self.report.copy_file( dlfname[fnamex], fname) else: tcell += self._("Cannot open file") if not dwnld: # We have several files to download # but all file names are empty dldescrx = _("No file to download") trow = Html("tr", id='Row01') tbody += trow tcell = Html("td", class_="ColumnFilename", colspan=3) + Html("h2", dldescrx) trow += tcell # clear line for proper styling # create footer section footer = self.write_footer(None) outerwrapper += (FULLCLEAR, footer) # send page out for processing # and close the file self.xhtml_writer(downloadpage, output_file, sio, 0)
def verify_media(self, button): """ Verify media objects have the correct path to files in the media directory. List missing files, duplicate files, and files that do not yet have a media file in Gramps. """ self.clear_models() self.moved_files = [] media_path = self.db.get_mediapath() if media_path is None: WarningDialog(self.window_name, _('Media path not set. You must set the "Base path ' 'for relative media paths" in the Preferences.'), self.window) return progress = ProgressMeter(self.window_name, can_cancel=True, parent=self.window) length = 0 for root, dirs, files in os.walk(media_path): length += len(files) progress.set_pass(_('Finding files'), length) all_files = {} for root, dirs, files in os.walk(media_path): for file_name in files: full_path = os.path.join(root, file_name) md5sum = create_checksum(full_path) if not md5sum: error_msg = 'IOError: %s' % full_path self.models[5].append((error_msg, None)) progress.step() continue rel_path = relative_path(full_path, media_path) if md5sum in all_files: all_files[md5sum].append(rel_path) else: all_files[md5sum] = [rel_path] progress.step() if progress.get_cancelled(): break # the following allows cancelling with subdirectries else: # normal exit of for file_name loop continue # just continue with outer loop break # inner loop had break, so break outer as well. length = self.db.get_number_of_media() progress.set_pass(_('Checking paths'), length) in_gramps = [] for handle in self.db.get_media_handles(): media = self.db.get_media_from_handle(handle) md5sum = media.get_checksum() in_gramps.append(md5sum) # Moved files gramps_path = media.get_path() if md5sum in all_files: file_path = all_files[md5sum] if gramps_path not in file_path: if len(file_path) == 1: self.moved_files.append((handle, file_path[0])) text = '%s -> %s' % (gramps_path, file_path[0]) self.models[0].append((text, handle)) else: gramps_name = os.path.basename(gramps_path) for path in file_path: if os.path.basename(path) == gramps_name: self.moved_files.append((handle, path)) text = '%s -> %s' % (gramps_path, path) self.models[0].append((text, handle)) elif md5sum is None: text = '[%s] %s' % (media.get_gramps_id(), gramps_path) self.models[4].append((text, str(handle))) else: self.models[1].append((gramps_path, handle)) progress.step() if progress.get_cancelled(): break # Duplicate files or files not in Gramps for md5sum in all_files: if len(all_files[md5sum]) > 1: text = ', '.join(all_files[md5sum]) self.models[2].append((text, all_files[md5sum][0])) if md5sum not in in_gramps: text = ', '.join(all_files[md5sum]) self.models[3].append((text, all_files[md5sum][0])) self.show_tabs() progress.close()