Add checksum to media objects
svn: r22870
This commit is contained in:
parent
8d9f6558e5
commit
2d8b44db89
@ -24,8 +24,10 @@
|
||||
from __future__ import with_statement, unicode_literals
|
||||
|
||||
import sys
|
||||
import os
|
||||
from ..lib.markertype import MarkerType
|
||||
from ..lib.tag import Tag
|
||||
from ..utils.file import create_checksum
|
||||
import time
|
||||
import logging
|
||||
LOG = logging.getLogger(".citation")
|
||||
@ -54,10 +56,11 @@ def gramps_upgrade_17(self):
|
||||
1. This upgrade adds tags to event, place, repository, source and
|
||||
citation objects.
|
||||
2. Data of Source becomes SourceAttributes Secondary Object
|
||||
3. Add checksum field to media objects.
|
||||
"""
|
||||
length = (len(self.event_map) + len(self.place_map) +
|
||||
len(self.repository_map) + len(self.source_map) +
|
||||
len(self.citation_map))
|
||||
len(self.citation_map) + len(self.media_map))
|
||||
self.set_total(length)
|
||||
|
||||
# ---------------------------------
|
||||
@ -166,6 +169,27 @@ def gramps_upgrade_17(self):
|
||||
txn.put(handle, new_citation)
|
||||
self.update()
|
||||
|
||||
# ---------------------------------
|
||||
# Modify Media
|
||||
# ---------------------------------
|
||||
# Add new checksum field.
|
||||
base_path = self.metadata[b'mediapath']
|
||||
for handle in self.media_map.keys():
|
||||
media = self.media_map[handle]
|
||||
new_media = list(media)
|
||||
if os.path.isabs(new_media[2]):
|
||||
full_path = new_media[2]
|
||||
else:
|
||||
full_path = os.path.join(base_path, new_media[2])
|
||||
checksum = create_checksum(full_path)
|
||||
new_media = new_media[:5] + [checksum] + new_media[5:]
|
||||
new_media = tuple(new_media)
|
||||
with BSDDBTxn(self.env, self.media_map) as txn:
|
||||
if isinstance(handle, UNITYPE):
|
||||
handle = handle.encode('utf-8')
|
||||
txn.put(handle, new_media)
|
||||
self.update()
|
||||
|
||||
# Bump up database version. Separate transaction to save metadata.
|
||||
with BSDDBTxn(self.env, self.metadata) as txn:
|
||||
txn.put(b'version', 17)
|
||||
|
@ -86,11 +86,13 @@ class MediaObject(CitationBase, NoteBase, DateBase, AttributeBase,
|
||||
self.path = source.path
|
||||
self.mime = source.mime
|
||||
self.desc = source.desc
|
||||
self.checksum = source.checksum
|
||||
self.thumb = source.thumb
|
||||
else:
|
||||
self.path = ""
|
||||
self.mime = ""
|
||||
self.desc = ""
|
||||
self.checksum = ""
|
||||
self.thumb = None
|
||||
|
||||
def serialize(self, no_text_date = False):
|
||||
@ -112,6 +114,7 @@ class MediaObject(CitationBase, NoteBase, DateBase, AttributeBase,
|
||||
:rtype: tuple
|
||||
"""
|
||||
return (self.handle, self.gramps_id, self.path, self.mime, self.desc,
|
||||
self.checksum,
|
||||
AttributeBase.serialize(self),
|
||||
CitationBase.serialize(self),
|
||||
NoteBase.serialize(self),
|
||||
@ -145,6 +148,7 @@ class MediaObject(CitationBase, NoteBase, DateBase, AttributeBase,
|
||||
"path": self.path,
|
||||
"mime": self.mime,
|
||||
"desc": self.desc,
|
||||
"checksum": self.checksum,
|
||||
"attribute_list": AttributeBase.to_struct(self),
|
||||
"citation_list": CitationBase.to_struct(self),
|
||||
"note_list": NoteBase.to_struct(self),
|
||||
@ -162,7 +166,7 @@ class MediaObject(CitationBase, NoteBase, DateBase, AttributeBase,
|
||||
:type data: tuple
|
||||
"""
|
||||
(self.handle, self.gramps_id, self.path, self.mime, self.desc,
|
||||
attribute_list, citation_list, note_list, self.change,
|
||||
self.checksum, attribute_list, citation_list, note_list, self.change,
|
||||
date, tag_list, self.private) = data
|
||||
|
||||
AttributeBase.unserialize(self, attribute_list)
|
||||
@ -287,3 +291,12 @@ class MediaObject(CitationBase, NoteBase, DateBase, AttributeBase,
|
||||
def get_description(self):
|
||||
"""Return the description of the image."""
|
||||
return self.desc
|
||||
|
||||
def set_checksum(self, text):
|
||||
"""Set the checksum of the image."""
|
||||
self.checksum = text
|
||||
|
||||
def get_checksum(self):
|
||||
"""Return the checksum of the image."""
|
||||
return self.checksum
|
||||
|
||||
|
@ -34,6 +34,8 @@ File and folder related utility functions
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import io
|
||||
import hashlib
|
||||
import logging
|
||||
LOG = logging.getLogger(".gen.utils.file")
|
||||
|
||||
@ -294,3 +296,15 @@ def fix_encoding(value, errors='strict'):
|
||||
return value.decode(encoding=codeset, errors=errors)
|
||||
else:
|
||||
return value
|
||||
|
||||
def create_checksum(full_path):
|
||||
"""
|
||||
Create a md5 hash for the given file.
|
||||
"""
|
||||
full_path = os.path.normpath(full_path)
|
||||
try:
|
||||
with io.open(full_path, 'rb') as media_file:
|
||||
md5sum = hashlib.md5(media_file.read()).hexdigest()
|
||||
except IOError:
|
||||
md5sum = ''
|
||||
return md5sum
|
||||
|
@ -64,7 +64,7 @@ from gramps.gen.constfunc import cuni
|
||||
from gramps.gen.lib import MediaObject, MediaRef
|
||||
from gramps.gen.db import DbTxn
|
||||
from gramps.gen.utils.file import (media_path_full, media_path, relative_path,
|
||||
fix_encoding)
|
||||
fix_encoding, create_checksum)
|
||||
from ...thumbnails import get_thumbnail_image
|
||||
from gramps.gen.errors import WindowActiveError
|
||||
from gramps.gen.mime import get_type, is_valid_type
|
||||
@ -525,6 +525,9 @@ class GalleryTab(ButtonTab, DbGUIElement):
|
||||
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 = cuni(media_path(self.dbstate.db))
|
||||
if os.path.exists(base_dir):
|
||||
name = relative_path(name, base_dir)
|
||||
|
@ -49,8 +49,8 @@ from gramps.gen.lib import MediaObject, NoteType
|
||||
from gramps.gen.db import DbTxn
|
||||
from gramps.gen.mime import get_description, get_type
|
||||
from ..thumbnails import get_thumbnail_image, find_mime_type_pixbuf
|
||||
from gramps.gen.utils.file import (media_path_full, find_file,
|
||||
get_unicode_path_from_file_chooser)
|
||||
from gramps.gen.utils.file import (media_path_full, find_file, create_checksum,
|
||||
get_unicode_path_from_file_chooser)
|
||||
from .editprimary import EditPrimary
|
||||
from ..widgets import (MonitoredDate, MonitoredEntry, PrivacyButton,
|
||||
MonitoredTagList)
|
||||
@ -263,8 +263,15 @@ class EditMedia(EditPrimary):
|
||||
fname = self.obj.get_path()
|
||||
self.file_path.set_text(fname)
|
||||
self.determine_mime()
|
||||
self.update_checksum()
|
||||
self.draw_preview()
|
||||
|
||||
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 save(self, *obj):
|
||||
self.ok_button.set_sensitive(False)
|
||||
|
||||
|
@ -49,8 +49,8 @@ from ..utils import open_file_with_default_application
|
||||
from gramps.gen.const import THUMBSCALE
|
||||
from gramps.gen.mime import get_description, get_type
|
||||
from ..thumbnails import get_thumbnail_image, find_mime_type_pixbuf
|
||||
from gramps.gen.utils.file import (media_path_full, find_file,
|
||||
get_unicode_path_from_file_chooser)
|
||||
from gramps.gen.utils.file import (media_path_full, find_file, create_checksum,
|
||||
get_unicode_path_from_file_chooser)
|
||||
from gramps.gen.lib import NoteType
|
||||
from gramps.gen.db import DbTxn
|
||||
from ..glade import Glade
|
||||
@ -553,7 +553,14 @@ class EditMediaRef(EditReference):
|
||||
for obj in (self.descr_window, self.path_obj):
|
||||
obj.update()
|
||||
self.determine_mime()
|
||||
self.update_checksum()
|
||||
self.draw_preview()
|
||||
|
||||
def update_checksum(self):
|
||||
self.uistate.set_busy_cursor(True)
|
||||
media_path = media_path_full(self.dbstate.db, self.source.get_path())
|
||||
self.source.set_checksum(create_checksum(os.path.normpath(media_path)))
|
||||
self.uistate.set_busy_cursor(False)
|
||||
|
||||
def select_file(self, val):
|
||||
self.determine_mime()
|
||||
|
@ -137,9 +137,9 @@ class MediaModel(FlatBaseModel):
|
||||
return cuni(data[1])
|
||||
|
||||
def column_date(self,data):
|
||||
if data[9]:
|
||||
if data[10]:
|
||||
date = Date()
|
||||
date.unserialize(data[9])
|
||||
date.unserialize(data[10])
|
||||
return cuni(displayer.display(date))
|
||||
return ''
|
||||
|
||||
@ -156,17 +156,17 @@ class MediaModel(FlatBaseModel):
|
||||
return cuni(data[0])
|
||||
|
||||
def column_private(self, data):
|
||||
if data[11]:
|
||||
if data[12]:
|
||||
return 'gramps-lock'
|
||||
else:
|
||||
# There is a problem returning None here.
|
||||
return ''
|
||||
|
||||
def sort_change(self,data):
|
||||
return "%012x" % data[8]
|
||||
return "%012x" % data[9]
|
||||
|
||||
def column_change(self,data):
|
||||
return format_time(data[8])
|
||||
return format_time(data[9])
|
||||
|
||||
def column_tooltip(self,data):
|
||||
return cuni('Media tooltip')
|
||||
@ -183,7 +183,7 @@ class MediaModel(FlatBaseModel):
|
||||
"""
|
||||
tag_color = "#000000000000"
|
||||
tag_priority = None
|
||||
for handle in data[10]:
|
||||
for handle in data[11]:
|
||||
tag = self.db.get_tag_from_handle(handle)
|
||||
this_priority = tag.get_priority()
|
||||
if tag_priority is None or this_priority < tag_priority:
|
||||
@ -195,5 +195,5 @@ class MediaModel(FlatBaseModel):
|
||||
"""
|
||||
Return the sorted list of tags.
|
||||
"""
|
||||
tag_list = list(map(self.get_tag_name, data[10]))
|
||||
tag_list = list(map(self.get_tag_name, data[11]))
|
||||
return ', '.join(sorted(tag_list, key=glocale.sort_key))
|
||||
|
@ -1216,6 +1216,7 @@ class GrampsXmlWriter(UpdateCallback):
|
||||
mime_type = obj.get_mime_type()
|
||||
path = obj.get_path()
|
||||
desc = obj.get_description()
|
||||
checksum = obj.get_checksum()
|
||||
if desc:
|
||||
desc_text = ' description="%s"' % self.fix(desc)
|
||||
else:
|
||||
@ -1229,9 +1230,9 @@ class GrampsXmlWriter(UpdateCallback):
|
||||
# Always export path with \ replaced with /. Otherwise import
|
||||
# from Windows to Linux of gpkg's path to images does not work.
|
||||
path = path.replace('\\','/')
|
||||
self.g.write('%s<file src="%s" mime="%s"%s/>\n'
|
||||
self.g.write('%s<file src="%s" mime="%s" checksum="%s"%s/>\n'
|
||||
% (" "*(index+1), self.fix(path), self.fix(mime_type),
|
||||
desc_text))
|
||||
checksum, desc_text))
|
||||
self.write_attribute_list(obj.get_attribute_list())
|
||||
self.write_note_list(obj.get_note_list(), index+1)
|
||||
dval = obj.get_date_object()
|
||||
|
@ -62,6 +62,7 @@ from gramps.gen.errors import GrampsImportError
|
||||
from gramps.gen.utils.id import create_id
|
||||
from gramps.gen.utils.db import family_name
|
||||
from gramps.gen.utils.unknown import make_unknown, create_explanation_note
|
||||
from gramps.gen.utils.file import create_checksum
|
||||
from gramps.gen.datehandler import parser, set_date
|
||||
from gramps.gen.display.name import displayer as name_displayer
|
||||
from gramps.gen.db.dbconst import (PERSON_KEY, FAMILY_KEY, SOURCE_KEY,
|
||||
@ -1603,6 +1604,14 @@ class GrampsParser(UpdateCallback):
|
||||
if self.all_abs and not os.path.isabs(src):
|
||||
self.all_abs = False
|
||||
self.info.add('relative-path', None, None)
|
||||
if 'checksum' in attrs:
|
||||
self.object.checksum = attrs['checksum']
|
||||
else:
|
||||
if os.path.isabs(src):
|
||||
full_path = src
|
||||
else:
|
||||
full_path = os.path.join(self.mediapath, src)
|
||||
self.object.checksum = create_checksum(full_path)
|
||||
|
||||
def start_childof(self, attrs):
|
||||
"""
|
||||
|
@ -63,7 +63,7 @@ from gramps.gui.views.treemodels import MediaModel
|
||||
from gramps.gen.constfunc import win, cuni
|
||||
from gramps.gen.config import config
|
||||
from gramps.gen.utils.file import (media_path, relative_path, media_path_full,
|
||||
fix_encoding)
|
||||
fix_encoding, create_checksum)
|
||||
from gramps.gen.utils.db import get_media_referents
|
||||
from gramps.gui.views.bookmarks import MediaBookmarks
|
||||
from gramps.gen.mime import get_type, is_valid_type
|
||||
@ -199,6 +199,9 @@ class MediaView(ListView):
|
||||
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 = cuni(media_path(self.dbstate.db))
|
||||
if os.path.exists(base_dir):
|
||||
name = relative_path(name, base_dir)
|
||||
|
Loading…
Reference in New Issue
Block a user