Add support for thumbnailer plugins
This commit is contained in:
parent
a45d86f0ad
commit
b4536666b0
@ -163,11 +163,6 @@ PLUGINS_DIR = os.path.join(ROOT_DIR, "plugins")
|
||||
|
||||
USE_TIPS = False
|
||||
|
||||
if sys.platform == 'win32':
|
||||
USE_THUMBNAILER = False
|
||||
else:
|
||||
USE_THUMBNAILER = True
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Paths to data files.
|
||||
@ -254,6 +249,8 @@ DOCUMENTERS = [
|
||||
#-------------------------------------------------------------------------
|
||||
THUMBSCALE = 96.0
|
||||
THUMBSCALE_LARGE = 180.0
|
||||
SIZE_NORMAL = 0
|
||||
SIZE_LARGE = 1
|
||||
XMLFILE = "data.gramps"
|
||||
NO_SURNAME = "(%s)" % _("none", "surname")
|
||||
NO_GIVEN = "(%s)" % _("none", "given-name")
|
||||
|
@ -41,6 +41,7 @@ from ._export import ExportPlugin
|
||||
from ._docgenplugin import DocGenPlugin
|
||||
from ._manager import BasePluginManager
|
||||
from ._gramplet import Gramplet
|
||||
from ._thumbnailer import Thumbnailer
|
||||
from .utils import *
|
||||
from ._options import (Options, OptionListCollection, OptionList,
|
||||
OptionHandler, MenuOptions)
|
||||
|
@ -448,6 +448,11 @@ class BasePluginManager:
|
||||
"""
|
||||
return self.__pgr.database_plugins()
|
||||
|
||||
def get_reg_thumbnailers(self):
|
||||
""" Return list of registered thumbnailers.
|
||||
"""
|
||||
return self.__pgr.thumbnailer_plugins()
|
||||
|
||||
def get_external_opt_dict(self):
|
||||
""" Return the dictionary of external options. """
|
||||
return self.__external_opt_dict
|
||||
|
@ -73,8 +73,10 @@ GRAMPLET = 10
|
||||
SIDEBAR = 11
|
||||
DATABASE = 12
|
||||
RULE = 13
|
||||
THUMBNAILER = 14
|
||||
PTYPE = [REPORT, QUICKREPORT, TOOL, IMPORT, EXPORT, DOCGEN, GENERAL,
|
||||
MAPSERVICE, VIEW, RELCALC, GRAMPLET, SIDEBAR, DATABASE, RULE]
|
||||
MAPSERVICE, VIEW, RELCALC, GRAMPLET, SIDEBAR, DATABASE, RULE,
|
||||
THUMBNAILER]
|
||||
PTYPE_STR = {
|
||||
REPORT: _('Report') ,
|
||||
QUICKREPORT: _('Quickreport'),
|
||||
@ -89,7 +91,8 @@ PTYPE_STR = {
|
||||
GRAMPLET: _('Gramplet'),
|
||||
SIDEBAR: _('Sidebar'),
|
||||
DATABASE: _('Database'),
|
||||
RULE: _('Rule')
|
||||
RULE: _('Rule'),
|
||||
THUMBNAILER: _('Thumbnailer'),
|
||||
}
|
||||
|
||||
#possible report categories
|
||||
@ -371,6 +374,11 @@ class PluginData:
|
||||
The class (Person, Event, Media, etc.) the rule applies to.
|
||||
.. attribute:: ruleclass
|
||||
The exact class name of the rule; ex: HasSourceParameter
|
||||
|
||||
Attributes for THUMBNAILER plugins
|
||||
|
||||
.. attribute:: thumbnailer
|
||||
The exact class name of the thumbnailer
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
@ -452,6 +460,8 @@ class PluginData:
|
||||
#RULE attr
|
||||
self._ruleclass = None
|
||||
self._namespace = None
|
||||
#THUMBNAILER attr
|
||||
self._thumbnailer = None
|
||||
|
||||
def _set_id(self, id):
|
||||
self._id = id
|
||||
@ -948,10 +958,10 @@ class PluginData:
|
||||
sidebarclass = property(_get_sidebarclass, _set_sidebarclass)
|
||||
menu_label = property(_get_menu_label, _set_menu_label)
|
||||
|
||||
#VIEW and SIDEBAR attributes
|
||||
#VIEW, SIDEBAR and THUMBNAILER attributes
|
||||
def _set_order(self, order):
|
||||
if not self._ptype in (VIEW, SIDEBAR):
|
||||
raise ValueError('order may only be set for VIEW and SIDEBAR plugins')
|
||||
if not self._ptype in (VIEW, SIDEBAR, THUMBNAILER):
|
||||
raise ValueError('order may only be set for VIEW/SIDEBAR/THUMBNAILER plugins')
|
||||
self._order = order
|
||||
|
||||
def _get_order(self):
|
||||
@ -1019,6 +1029,17 @@ class PluginData:
|
||||
ruleclass = property(_get_ruleclass, _set_ruleclass)
|
||||
namespace = property(_get_namespace, _set_namespace)
|
||||
|
||||
#THUMBNAILER attr
|
||||
def _set_thumbnailer(self, data):
|
||||
if self._ptype != THUMBNAILER:
|
||||
raise ValueError('thumbnailer may only be set for THUMBNAILER plugins')
|
||||
self._thumbnailer = data
|
||||
|
||||
def _get_thumbnailer(self):
|
||||
return self._thumbnailer
|
||||
|
||||
thumbnailer = property(_get_thumbnailer, _set_thumbnailer)
|
||||
|
||||
def newplugin():
|
||||
"""
|
||||
Function to create a new plugindata object, add it to list of
|
||||
@ -1072,6 +1093,7 @@ def make_environment(**kwargs):
|
||||
'RELCALC': RELCALC,
|
||||
'GRAMPLET': GRAMPLET,
|
||||
'SIDEBAR': SIDEBAR,
|
||||
'THUMBNAILER': THUMBNAILER,
|
||||
'CATEGORY_TEXT': CATEGORY_TEXT,
|
||||
'CATEGORY_DRAW': CATEGORY_DRAW,
|
||||
'CATEGORY_CODE': CATEGORY_CODE,
|
||||
@ -1389,6 +1411,12 @@ class PluginRegister:
|
||||
"""
|
||||
return self.type_plugins(RULE)
|
||||
|
||||
def thumbnailer_plugins(self):
|
||||
"""
|
||||
Return a list of :class:`PluginData` that are of type THUMBNAILER
|
||||
"""
|
||||
return self.type_plugins(THUMBNAILER)
|
||||
|
||||
def filter_load_on_reg(self):
|
||||
"""
|
||||
Return a list of :class:`PluginData` that have load_on_reg == True
|
||||
|
67
gramps/gen/plug/_thumbnailer.py
Normal file
67
gramps/gen/plug/_thumbnailer.py
Normal file
@ -0,0 +1,67 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2022 Nick Hall
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
"""
|
||||
This module provides the base class for thumbnailer plugins.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Thumbnailer class
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class Thumbnailer(metaclass=ABCMeta):
|
||||
|
||||
@abstractmethod
|
||||
def is_supported(self, mime_type):
|
||||
"""
|
||||
Indicates if a mime type is supported by this thumbnailer.
|
||||
|
||||
:param mime_type: mime type of the source file
|
||||
:type mime_type: unicode
|
||||
:rtype: bool
|
||||
:returns: True if the mime type is supported by this thumbnailer
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def run(self, mime_type, src_file, dest_file, size, rectangle):
|
||||
"""
|
||||
Generates a thumbnail image for the specified file.
|
||||
|
||||
:param mime_type: mime type of the source file
|
||||
:type mime_type: unicode
|
||||
:param src_file: filename of the source file
|
||||
:type src_file: unicode
|
||||
:param dest_file: filename of the destination file
|
||||
:type dest_file: unicode
|
||||
:param size: required size of the thumbnail in pixels
|
||||
:type size: int
|
||||
:param rectangle: subsection rectangle
|
||||
:type rectangle: tuple
|
||||
:rtype: bool
|
||||
:returns: True if the thumbnail was successfully generated
|
||||
"""
|
@ -2,6 +2,7 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# Copyright (C) 2022 Nick Hall
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -51,26 +52,9 @@ except:
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.const import (ICON, IMAGE_DIR, THUMB_LARGE, THUMB_NORMAL,
|
||||
THUMBSCALE, THUMBSCALE_LARGE, USE_THUMBNAILER)
|
||||
from gramps.gen.constfunc import win
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gconf - try loading gconf for GNOME based systems. If we find it, we
|
||||
# might be able to generate thumbnails for non-image files.
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
try:
|
||||
#test first for the key to avoid an error in the importer that causes
|
||||
#the error logger to activate
|
||||
##TODO GTK3: Is this the best way to avoid error?
|
||||
import gi.repository as repo
|
||||
repo.__dict__['GConf']
|
||||
from gi.repository import GConf
|
||||
GCONF = True
|
||||
CLIENT = GConf.Client.get_default()
|
||||
except (ImportError, KeyError) as msg:
|
||||
GCONF = False
|
||||
SIZE_NORMAL, SIZE_LARGE)
|
||||
from gramps.gen.plug import BasePluginManager, START
|
||||
from gramps.gen.mime import get_type
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -78,50 +62,25 @@ except (ImportError, KeyError) as msg:
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
LOG = logging.getLogger(".thumbnail")
|
||||
SIZE_NORMAL = 0
|
||||
SIZE_LARGE = 1
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# __get_gconf_string
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def __get_gconf_string(key):
|
||||
"""
|
||||
Attempt to retrieve a value from the GNOME gconf database based of the
|
||||
passed key.
|
||||
THUMBNAILERS = []
|
||||
def get_thumbnailers():
|
||||
if len(THUMBNAILERS):
|
||||
return THUMBNAILERS
|
||||
|
||||
:param key: GCONF key
|
||||
:type key: unicode
|
||||
:returns: Value associated with the GCONF key
|
||||
:rtype: unicode
|
||||
"""
|
||||
try:
|
||||
val = CLIENT.get_string(key)
|
||||
except GLib.GError:
|
||||
val = None
|
||||
return str(val)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# __get_gconf_bool
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def __get_gconf_bool(key):
|
||||
"""
|
||||
Attempt to retrieve a value from the GNOME gconf database based of the
|
||||
passed key.
|
||||
|
||||
:param key: GCONF key
|
||||
:type key: unicode
|
||||
:returns: Value associated with the GCONF key
|
||||
:rtype: bool
|
||||
"""
|
||||
try:
|
||||
val = CLIENT.get_bool(key)
|
||||
except GLib.GError:
|
||||
val = None
|
||||
return val
|
||||
plugman = BasePluginManager.get_instance()
|
||||
for pdata in plugman.get_reg_thumbnailers():
|
||||
module = plugman.load_plugin(pdata)
|
||||
if not module:
|
||||
print("Error loading thumbnailer '%s': skipping content"
|
||||
% pdata.name)
|
||||
continue
|
||||
thumbnailer = getattr(module, pdata.thumbnailer)()
|
||||
if pdata.order == START:
|
||||
THUMBNAILERS.insert(0, thumbnailer)
|
||||
else:
|
||||
THUMBNAILERS.append(thumbnailer)
|
||||
return THUMBNAILERS
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -176,49 +135,35 @@ def __create_thumbnail_image(src_file, mtype=None, rectangle=None,
|
||||
:rtype: bool
|
||||
:returns: True is the thumbnailwas successfully generated
|
||||
"""
|
||||
if mtype is None:
|
||||
mtype = get_type(src_file)
|
||||
filename = __build_thumb_path(src_file, rectangle, size)
|
||||
return run_thumbnailer(mtype, src_file, filename, size, rectangle)
|
||||
|
||||
if mtype and not mtype.startswith('image/'):
|
||||
# Not an image, so run the thumbnailer
|
||||
return run_thumbnailer(mtype, src_file, filename)
|
||||
else:
|
||||
# build a thumbnail by scaling the image using GTK's built in
|
||||
# routines.
|
||||
try:
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file(src_file)
|
||||
width = pixbuf.get_width()
|
||||
height = pixbuf.get_height()
|
||||
def run_thumbnailer(mime_type, src_file, dest_file, size, rectangle=None):
|
||||
"""
|
||||
This function attempts to generate a thumbnail image. It runs the first
|
||||
thumbnailer plugin that supports the given mime type.
|
||||
|
||||
if rectangle is not None:
|
||||
upper_x = min(rectangle[0], rectangle[2])/100.
|
||||
lower_x = max(rectangle[0], rectangle[2])/100.
|
||||
upper_y = min(rectangle[1], rectangle[3])/100.
|
||||
lower_y = max(rectangle[1], rectangle[3])/100.
|
||||
sub_x = int(upper_x * width)
|
||||
sub_y = int(upper_y * height)
|
||||
sub_width = int((lower_x - upper_x) * width)
|
||||
sub_height = int((lower_y - upper_y) * height)
|
||||
if sub_width > 0 and sub_height > 0:
|
||||
pixbuf = pixbuf.new_subpixbuf(sub_x, sub_y, sub_width, sub_height)
|
||||
width = sub_width
|
||||
height = sub_height
|
||||
|
||||
if size == SIZE_LARGE:
|
||||
thumbscale = THUMBSCALE_LARGE
|
||||
else:
|
||||
thumbscale = THUMBSCALE
|
||||
scale = thumbscale / (float(max(width, height)))
|
||||
|
||||
scaled_width = int(width * scale)
|
||||
scaled_height = int(height * scale)
|
||||
|
||||
pixbuf = pixbuf.scale_simple(scaled_width, scaled_height,
|
||||
GdkPixbuf.InterpType.BILINEAR)
|
||||
pixbuf.savev(filename, "png", "", "")
|
||||
return True
|
||||
except Exception as err:
|
||||
LOG.warning("Error scaling image down: %s", str(err))
|
||||
return False
|
||||
:param mime_type: mime type of the source file
|
||||
:type mime_type: unicode
|
||||
:param src_file: filename of the source file
|
||||
:type src_file: unicode
|
||||
:param dest_file: destination file for the thumbnail image
|
||||
:type dest_file: unicode
|
||||
:param size: option parameters specifying the desired size of the
|
||||
thumbnail
|
||||
:type size: int
|
||||
:param rectangle: subsection rectangle (optional)
|
||||
:type rectangle: tuple
|
||||
:returns: True if the thumbnail was successfully generated
|
||||
:rtype: bool
|
||||
"""
|
||||
for thumbnailer in get_thumbnailers():
|
||||
if thumbnailer.is_supported(mime_type):
|
||||
if thumbnailer.run(mime_type, src_file, dest_file, size, rectangle):
|
||||
return True
|
||||
return False
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -241,55 +186,6 @@ def find_mime_type_pixbuf(mime_type):
|
||||
return GdkPixbuf.Pixbuf.new_from_file(ICON)
|
||||
except:
|
||||
return GdkPixbuf.Pixbuf.new_from_file(ICON)
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# run_thumbnailer
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def run_thumbnailer(mime_type, src_file, dest_file, size=SIZE_NORMAL):
|
||||
"""
|
||||
This function attempts to generate a thumbnail image for a non-image.
|
||||
This includes things such as video and PDF files. This will currently
|
||||
only succeed if the GNOME environment is installed, since at this point,
|
||||
only the GNOME environment has the ability to generate thumbnails.
|
||||
|
||||
:param mime_type: mime type of the source file
|
||||
:type mime_type: unicode
|
||||
:param src_file: filename of the source file
|
||||
:type src_file: unicode
|
||||
:param dest_file: destination file for the thumbnail image
|
||||
:type dest_file: unicode
|
||||
:param size: option parameters specifying the desired size of the
|
||||
thumbnail
|
||||
:type size: int
|
||||
:returns: True if the thumbnail was successfully generated
|
||||
:rtype: bool
|
||||
"""
|
||||
# only try this if GCONF is present, the thumbnailer has not been
|
||||
# disabled, and if the src_file actually exists
|
||||
if GCONF and USE_THUMBNAILER and os.path.isfile(src_file):
|
||||
|
||||
# find the command and enable for the associated mime types by
|
||||
# querying the gconf database
|
||||
base = '/desktop/gnome/thumbnailers/%s' % mime_type.replace('/', '@')
|
||||
cmd = __get_gconf_string(base + '/command')
|
||||
enable = __get_gconf_bool(base + '/enable')
|
||||
|
||||
# if we found the command and it has been enabled, then spawn
|
||||
# of the command to build the thumbnail
|
||||
if cmd and enable:
|
||||
if size == SIZE_LARGE:
|
||||
thumbscale = THUMBSCALE_LARGE
|
||||
else:
|
||||
thumbscale = THUMBSCALE
|
||||
sublist = {
|
||||
'%s' : "%d" % int(thumbscale),
|
||||
'%u' : src_file,
|
||||
'%o' : dest_file,
|
||||
}
|
||||
cmdlist = [ sublist.get(x, x) for x in cmd.split() ]
|
||||
return os.spawnvpe(os.P_WAIT, cmdlist[0], cmdlist, os.environ) == 0
|
||||
return False
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
|
@ -54,7 +54,7 @@ from gramps.gen.config import config
|
||||
from gramps.gen.utils.file import (media_path_full, media_path, relative_path,
|
||||
find_file)
|
||||
from gramps.gen.mime import get_type
|
||||
from gramps.gen.utils.thumbnails import find_mime_type_pixbuf
|
||||
from gramps.gen.utils.thumbnails import get_thumbnail_image
|
||||
from ..display import display_help
|
||||
from ..managedwindow import ManagedWindow
|
||||
from ..dialog import ErrorDialog, WarningDialog
|
||||
@ -214,10 +214,7 @@ class AddMedia(ManagedWindow):
|
||||
filename = find_file( filename)
|
||||
if filename:
|
||||
mtype = get_type(filename)
|
||||
if mtype and mtype.startswith("image"):
|
||||
image = self.scale_image(filename, THUMBSCALE)
|
||||
else:
|
||||
image = find_mime_type_pixbuf(mtype)
|
||||
image = get_thumbnail_image(filename, mtype)
|
||||
self.image.set_from_pixbuf(image)
|
||||
|
||||
def _cleanup_on_exit(self):
|
||||
|
0
gramps/plugins/thumbnailer/__init__.py
Normal file
0
gramps/plugins/thumbnailer/__init__.py
Normal file
105
gramps/plugins/thumbnailer/gnomethumb.py
Normal file
105
gramps/plugins/thumbnailer/gnomethumb.py
Normal file
@ -0,0 +1,105 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# Copyright (C) 2022 Nick Hall
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
"""
|
||||
A thumbnailer that uses other system thumbnailers already installed on a
|
||||
Gmone desktop.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import os
|
||||
import glob
|
||||
import logging
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gi.repository import GLib
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.const import THUMBSCALE, THUMBSCALE_LARGE, SIZE_LARGE
|
||||
from gramps.gen.plug import Thumbnailer
|
||||
from gramps.gen.constfunc import get_env_var, lin
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Constants
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
LOG = logging.getLogger(".thumbnail")
|
||||
|
||||
|
||||
class GnomeThumb(Thumbnailer):
|
||||
def __init__(self):
|
||||
self.all_mime_types = {}
|
||||
if lin():
|
||||
self.__find_thumbnailers()
|
||||
|
||||
def __find_thumbnailers(self):
|
||||
path_list = GLib.get_system_data_dirs()
|
||||
path_list.append(GLib.get_user_data_dir())
|
||||
file_list = []
|
||||
for path in path_list:
|
||||
file_list.extend(
|
||||
glob.glob(os.path.join(path, "thumbnailers", "*.thumbnailer"))
|
||||
)
|
||||
|
||||
for filename in file_list:
|
||||
kf = GLib.KeyFile()
|
||||
try:
|
||||
kf.load_from_file(filename, GLib.KeyFileFlags.NONE)
|
||||
cmd = kf.get_string("Thumbnailer Entry", "Exec")
|
||||
mime_types = kf.get_string_list("Thumbnailer Entry", "MimeType")
|
||||
except GLib.GError:
|
||||
continue
|
||||
if cmd and mime_types:
|
||||
for mime_type in mime_types:
|
||||
self.all_mime_types[mime_type] = cmd
|
||||
|
||||
def is_supported(self, mime_type):
|
||||
return mime_type in self.all_mime_types
|
||||
|
||||
def run(self, mime_type, src_file, dest_file, size, rectangle):
|
||||
cmd = self.all_mime_types.get(mime_type)
|
||||
if cmd:
|
||||
if size == SIZE_LARGE:
|
||||
thumbscale = THUMBSCALE_LARGE
|
||||
else:
|
||||
thumbscale = THUMBSCALE
|
||||
sublist = {
|
||||
"%s": "%d" % int(thumbscale),
|
||||
"%u": "file://" + src_file,
|
||||
"%i": src_file,
|
||||
"%o": dest_file,
|
||||
}
|
||||
cmdlist = [sublist.get(x, x) for x in cmd.split()]
|
||||
return os.spawnvpe(os.P_WAIT, cmdlist[0], cmdlist, os.environ) == 0
|
||||
return False
|
101
gramps/plugins/thumbnailer/imagethumb.py
Normal file
101
gramps/plugins/thumbnailer/imagethumb.py
Normal file
@ -0,0 +1,101 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2000-2007 Donald N. Allingham
|
||||
# Copyright (C) 2022 Nick Hall
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
"""
|
||||
A thumbnailer for images and sub-sections of images.
|
||||
"""
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard python modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
import logging
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gi.repository import GdkPixbuf
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gramps.gen.const import THUMBSCALE, THUMBSCALE_LARGE, SIZE_LARGE
|
||||
from gramps.gen.plug import Thumbnailer
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Constants
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
LOG = logging.getLogger(".thumbnail")
|
||||
|
||||
|
||||
class ImageThumb(Thumbnailer):
|
||||
def is_supported(self, mime_type):
|
||||
if mime_type:
|
||||
return mime_type.startswith("image")
|
||||
else:
|
||||
return False
|
||||
|
||||
def run(self, mime_type, src_file, dest_file, size, rectangle):
|
||||
# build a thumbnail by scaling the image using GTK's built in
|
||||
# routines.
|
||||
try:
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file(src_file)
|
||||
width = pixbuf.get_width()
|
||||
height = pixbuf.get_height()
|
||||
|
||||
if rectangle is not None:
|
||||
upper_x = min(rectangle[0], rectangle[2]) / 100.0
|
||||
lower_x = max(rectangle[0], rectangle[2]) / 100.0
|
||||
upper_y = min(rectangle[1], rectangle[3]) / 100.0
|
||||
lower_y = max(rectangle[1], rectangle[3]) / 100.0
|
||||
sub_x = int(upper_x * width)
|
||||
sub_y = int(upper_y * height)
|
||||
sub_width = int((lower_x - upper_x) * width)
|
||||
sub_height = int((lower_y - upper_y) * height)
|
||||
if sub_width > 0 and sub_height > 0:
|
||||
pixbuf = pixbuf.new_subpixbuf(sub_x, sub_y, sub_width, sub_height)
|
||||
width = sub_width
|
||||
height = sub_height
|
||||
|
||||
if size == SIZE_LARGE:
|
||||
thumbscale = THUMBSCALE_LARGE
|
||||
else:
|
||||
thumbscale = THUMBSCALE
|
||||
scale = thumbscale / (float(max(width, height)))
|
||||
|
||||
scaled_width = int(width * scale)
|
||||
scaled_height = int(height * scale)
|
||||
|
||||
pixbuf = pixbuf.scale_simple(
|
||||
scaled_width, scaled_height, GdkPixbuf.InterpType.BILINEAR
|
||||
)
|
||||
pixbuf.savev(dest_file, "png", "", "")
|
||||
return True
|
||||
except Exception as err:
|
||||
LOG.warning("Error scaling image down: %s", str(err))
|
||||
return False
|
59
gramps/plugins/thumbnailer/thumb.gpr.py
Normal file
59
gramps/plugins/thumbnailer/thumb.gpr.py
Normal file
@ -0,0 +1,59 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2022 Nick Hall
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
from gramps.gen.const import GRAMPS_LOCALE as glocale
|
||||
|
||||
_ = glocale.translation.gettext
|
||||
|
||||
MODULE_VERSION = "5.2"
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Default thumbnailers for Gramps
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
register(
|
||||
THUMBNAILER,
|
||||
id="gnomethumb",
|
||||
name=_("Gnome Thumbnailer"),
|
||||
description=_("Gnome Thumbnailer"),
|
||||
version="1.0",
|
||||
gramps_target_version=MODULE_VERSION,
|
||||
status=STABLE,
|
||||
fname="gnomethumb.py",
|
||||
thumbnailer="GnomeThumb",
|
||||
authors=["The Gramps project"],
|
||||
authors_email=["http://gramps-project.org"],
|
||||
)
|
||||
|
||||
register(
|
||||
THUMBNAILER,
|
||||
id="imagethumb",
|
||||
name=_("Image Thumbnailer"),
|
||||
description=_("Image Thumbnailer"),
|
||||
version="1.0",
|
||||
gramps_target_version=MODULE_VERSION,
|
||||
status=STABLE,
|
||||
order=START,
|
||||
fname="imagethumb.py",
|
||||
thumbnailer="ImageThumb",
|
||||
authors=["The Gramps project"],
|
||||
authors_email=["http://gramps-project.org"],
|
||||
)
|
@ -713,6 +713,7 @@ gramps/plugins/textreport/summary.py
|
||||
gramps/plugins/textreport/tableofcontents.py
|
||||
gramps/plugins/textreport/tagreport.py
|
||||
gramps/plugins/textreport/textplugins.gpr.py
|
||||
gramps/plugins/thumbnailer/thumb.gpr.py
|
||||
gramps/plugins/tool/changenames.glade
|
||||
gramps/plugins/tool/changenames.py
|
||||
gramps/plugins/tool/changetypes.glade
|
||||
|
@ -592,6 +592,12 @@ gramps/plugins/test/imports_test.py
|
||||
gramps/plugins/test/reports_test.py
|
||||
gramps/plugins/test/tools_test.py
|
||||
#
|
||||
# Thumbnailers
|
||||
#
|
||||
gramps/plugins/thumbnailer/__init__.py
|
||||
gramps/plugins/thumbnailer/gnomethumb.py
|
||||
gramps/plugins/thumbnailer/imagethumb.py
|
||||
#
|
||||
# Development tools
|
||||
#
|
||||
gramps/plugins/tool/__init__.py
|
||||
|
Loading…
Reference in New Issue
Block a user