diff --git a/Gramps.py b/Gramps.py index 1fdaa8a07ab..85c772eafcd 100755 --- a/Gramps.py +++ b/Gramps.py @@ -26,4 +26,5 @@ From this position, import gramps works great """ import gramps.grampsapp as app + app.main() diff --git a/aio/grampsaioc.py b/aio/grampsaioc.py index c4efddc1cf3..77fee9b9016 100644 --- a/aio/grampsaioc.py +++ b/aio/grampsaioc.py @@ -5,36 +5,40 @@ import sys import site -if getattr(sys, 'frozen', False): +if getattr(sys, "frozen", False): aio = os.path.dirname(sys.executable) sys.path.insert(1, aio) - sys.path.insert(1, os.path.join(aio,'lib')) + sys.path.insert(1, os.path.join(aio, "lib")) sys.path.insert(1, site.getusersitepackages()) - environ['PANGOCAIRO_BACKEND'] = 'fontconfig' - environ['SSL_CERT_FILE'] = join(aio, 'ssl/certs/ca-bundle.trust.crt') - environ['GI_TYPELIB_PATH'] = join(aio, 'lib/girepository-1.0') - environ['G_ENABLE_DIAGNOSTIC'] = '0' - environ['G_PARAM_DEPRECATED'] = '0' - environ['GRAMPS_RESOURCES'] = join(aio, 'share') - environ['PATH'] = aio + ';' + aio +'\lib;' + environ['PATH'] + environ["PANGOCAIRO_BACKEND"] = "fontconfig" + environ["SSL_CERT_FILE"] = join(aio, "ssl/certs/ca-bundle.trust.crt") + environ["GI_TYPELIB_PATH"] = join(aio, "lib/girepository-1.0") + environ["G_ENABLE_DIAGNOSTIC"] = "0" + environ["G_PARAM_DEPRECATED"] = "0" + environ["GRAMPS_RESOURCES"] = join(aio, "share") + environ["PATH"] = aio + ";" + aio + "\lib;" + environ["PATH"] + def close(): sys.exit() + import atexit import ctypes HANDLE = ctypes.windll.kernel32.CreateMutexW(None, 1, "org.gramps-project.gramps") ERROR = ctypes.GetLastError() -if ERROR == 183: #ERROR_ALREADY_EXISTS: - print('Gramps is already running!', file=sys.stderr) +if ERROR == 183: # ERROR_ALREADY_EXISTS: + print("Gramps is already running!", file=sys.stderr) close() atexit.register(ctypes.windll.kernel32.CloseHandle, HANDLE) atexit.register(ctypes.windll.kernel32.ReleaseMutex, HANDLE) import warnings + warnings.simplefilter("ignore") import gramps.grampsapp as app + app.run() diff --git a/aio/grampsaiocd.py b/aio/grampsaiocd.py index a8c295abfac..302dcd39bdd 100644 --- a/aio/grampsaiocd.py +++ b/aio/grampsaiocd.py @@ -5,19 +5,20 @@ import sys import site -if getattr(sys, 'frozen', False): +if getattr(sys, "frozen", False): aio = os.path.dirname(sys.executable) sys.path.insert(1, aio) - sys.path.insert(1, os.path.join(aio,'lib')) + sys.path.insert(1, os.path.join(aio, "lib")) sys.path.insert(1, site.getusersitepackages()) - environ['LANG'] = 'en' - environ['PANGOCAIRO_BACKEND'] = 'fontconfig' - environ['SSL_CERT_FILE'] = join(aio, 'ssl/certs/ca-bundle.trust.crt') - environ['GI_TYPELIB_PATH'] = join(aio, 'lib/girepository-1.0') - environ['G_ENABLE_DIAGNOSTIC'] = '0' - environ['G_PARAM_DEPRECATED'] = '0' - environ['GRAMPS_RESOURCES'] = join(aio, 'share') - environ['PATH'] = aio + ';' + aio +'\lib;' + environ['PATH'] + environ["LANG"] = "en" + environ["PANGOCAIRO_BACKEND"] = "fontconfig" + environ["SSL_CERT_FILE"] = join(aio, "ssl/certs/ca-bundle.trust.crt") + environ["GI_TYPELIB_PATH"] = join(aio, "lib/girepository-1.0") + environ["G_ENABLE_DIAGNOSTIC"] = "0" + environ["G_PARAM_DEPRECATED"] = "0" + environ["GRAMPS_RESOURCES"] = join(aio, "share") + environ["PATH"] = aio + ";" + aio + "\lib;" + environ["PATH"] import gramps.grampsapp as app + app.run() diff --git a/aio/grampsaiow.py b/aio/grampsaiow.py index cf5099eb146..fa19e638281 100644 --- a/aio/grampsaiow.py +++ b/aio/grampsaiow.py @@ -1,39 +1,42 @@ #!/usr/bin/env python3 -''' +""" grampsw.exe -''' +""" import os from os import environ from os.path import join import sys import site -if getattr(sys, 'frozen', False): +if getattr(sys, "frozen", False): aio = os.path.dirname(sys.executable) sys.path.insert(1, aio) - sys.path.insert(1, os.path.join(aio,'lib')) + sys.path.insert(1, os.path.join(aio, "lib")) sys.path.insert(1, site.getusersitepackages()) - environ['SSL_CERT_FILE'] = join(aio, 'ssl/certs/ca-bundle.trust.crt') - environ['GI_TYPELIB_PATH'] = join(aio, 'lib/girepository-1.0') - environ['G_ENABLE_DIAGNOSTIC'] = '0' - environ['G_PARAM_DEPRECATED'] = '0' - environ['GRAMPS_RESOURCES'] = join(aio, 'share') - environ['PATH'] = aio + ';' + aio +'\lib;' + environ['PATH'] + environ["SSL_CERT_FILE"] = join(aio, "ssl/certs/ca-bundle.trust.crt") + environ["GI_TYPELIB_PATH"] = join(aio, "lib/girepository-1.0") + environ["G_ENABLE_DIAGNOSTIC"] = "0" + environ["G_PARAM_DEPRECATED"] = "0" + environ["GRAMPS_RESOURCES"] = join(aio, "share") + environ["PATH"] = aio + ";" + aio + "\lib;" + environ["PATH"] import atexit import ctypes + def close(): - ''' Show warning dialog if Gramps is already running''' - sys.exit('Gramps is already running!') + """Show warning dialog if Gramps is already running""" + sys.exit("Gramps is already running!") + HANDLE = ctypes.windll.kernel32.CreateMutexW(None, 1, "org.gramps-project.gramps") ERROR = ctypes.GetLastError() -if ERROR == 183: #ERROR_ALREADY_EXISTS: +if ERROR == 183: # ERROR_ALREADY_EXISTS: close() atexit.register(ctypes.windll.kernel32.CloseHandle, HANDLE) atexit.register(ctypes.windll.kernel32.ReleaseMutex, HANDLE) import gramps.grampsapp as app + app.main() diff --git a/aio/setup.py b/aio/setup.py index a4aba72652e..68d67a16a91 100644 --- a/aio/setup.py +++ b/aio/setup.py @@ -1,7 +1,7 @@ -''' +""" Use with: python3 setup.py build_exe --no-compress -O1 -''' +""" import sys import os import site @@ -11,171 +11,273 @@ import shutil import zipfile import cx_Freeze -sys.path.insert(0,'dist') + +sys.path.insert(0, "dist") import gramps from gramps.version import VERSION_TUPLE + try: from gramps.version import VERSION_QUALIFIER except: - VERSION_QUALIFIER = '' -UPX_ALT_PATH = r'UPX' + VERSION_QUALIFIER = "" +UPX_ALT_PATH = r"UPX" -#import logging -#logging.basicConfig(level=logging.DEBUG) -VQ = {'-alpha1': 10, '-alpha2': 11, '-alpha3': 12, - '-beta1': 21, '-beta2': 22, '-beta3': 23, - '-rc1': 22, '': 0} +# import logging +# logging.basicConfig(level=logging.DEBUG) +VQ = { + "-alpha1": 10, + "-alpha2": 11, + "-alpha3": 12, + "-beta1": 21, + "-beta2": 22, + "-beta3": 23, + "-rc1": 22, + "": 0, +} -VERSION = ('.'.join(map(str, VERSION_TUPLE)) + '.' + - str(VQ.get(VERSION_QUALIFIER, 99))) -COPYRIGHT="Copyright 2020, Gramps developers. GNU General Public License" +VERSION = ".".join(map(str, VERSION_TUPLE)) + "." + str(VQ.get(VERSION_QUALIFIER, 99)) +COPYRIGHT = "Copyright 2020, Gramps developers. GNU General Public License" # Prepare a temporay directory TEMP_DIR = tempfile.TemporaryDirectory() atexit.register(TEMP_DIR.cleanup) BASE_DIR = os.path.split(sys.prefix)[1] SETUP_DIR = os.path.dirname(os.path.realpath(__file__)) -SETUP_FILES = ['setup.py', 'gramps.ico', 'grampsc.ico', 'grampsd.ico', - 'grampsaioc.py', 'grampsaiocd.py', 'grampsaiow.py'] -if '32' in BASE_DIR: - SETUP_FILES.append(''.join(('grampsaio', '32', '.nsi'))) +SETUP_FILES = [ + "setup.py", + "gramps.ico", + "grampsc.ico", + "grampsd.ico", + "grampsaioc.py", + "grampsaiocd.py", + "grampsaiow.py", +] +if "32" in BASE_DIR: + SETUP_FILES.append("".join(("grampsaio", "32", ".nsi"))) else: - SETUP_FILES.append(''.join(('grampsaio', '64', '.nsi'))) + SETUP_FILES.append("".join(("grampsaio", "64", ".nsi"))) -INCLUDE_DLL_PATH = os.path.join(sys.exec_prefix, 'bin') +INCLUDE_DLL_PATH = os.path.join(sys.exec_prefix, "bin") INCLUDE_FILES = [] -INCLUDES = ['gi', 'cgi', 'colorsys', 'site'] -PACKAGES = ['gi', 'cairo', 'xml', 'bsddb3', 'lxml', 'PIL', 'json', 'csv', - 'sqlite3', 'cProfile', 'networkx', 'psycopg2', 'requests', 'logging' - , 'html', 'compileall', 'graphviz', 'pydotplus', 'pygraphviz', 'pydot' ] -EXCLUDES = ['tkinter', 'PyQt5', 'PyQt5.QtCore', 'PyQt5.QtGui', 'pyside' - 'PyQt5.QtWidgets', 'sip', 'lib2to3', 'PIL.ImageQt', 'pip', 'distlib' - ] +INCLUDES = ["gi", "cgi", "colorsys", "site"] +PACKAGES = [ + "gi", + "cairo", + "xml", + "bsddb3", + "lxml", + "PIL", + "json", + "csv", + "sqlite3", + "cProfile", + "networkx", + "psycopg2", + "requests", + "logging", + "html", + "compileall", + "graphviz", + "pydotplus", + "pygraphviz", + "pydot", +] +EXCLUDES = [ + "tkinter", + "PyQt5", + "PyQt5.QtCore", + "PyQt5.QtGui", + "pyside" "PyQt5.QtWidgets", + "sip", + "lib2to3", + "PIL.ImageQt", + "pip", + "distlib", +] -REPLACE_PATHS = [('*', 'AIO/'), - ( site.getsitepackages()[0] - +'cx_freeze-5.0-py3.6-mingw.egg/cx_Freeze', 'cx_Freeze/') - ] -MISSING_DLL = ['libgtk-3-0.dll', 'libgtkspell3-3-0.dll', 'libgexiv2-2.dll', - 'libgoocanvas-3.0-9.dll', 'libosmgpsmap-1.0-1.dll', - 'gswin32c.exe', 'dot.exe', 'libgvplugin_core-6.dll', - 'libgvplugin_dot_layout-6.dll', 'libgvplugin_gd-6.dll', - 'libgvplugin_pango-6.dll', 'libgvplugin_rsvg-6.dll', - 'glib-compile-schemas.exe', - 'gdk-pixbuf-query-loaders.exe', 'gtk-update-icon-cache-3.0.exe', - 'fc-cache.exe', 'fc-match.exe', 'gspawn-win64-helper-console.exe', - 'gspawn-win64-helper.exe', 'libgeocode-glib-0.dll' - ] -BIN_EXCLUDES = ['Qt5Core.dll', 'gdiplus.dll', 'gdiplus'] +REPLACE_PATHS = [ + ("*", "AIO/"), + ( + site.getsitepackages()[0] + "cx_freeze-5.0-py3.6-mingw.egg/cx_Freeze", + "cx_Freeze/", + ), +] +MISSING_DLL = [ + "libgtk-3-0.dll", + "libgtkspell3-3-0.dll", + "libgexiv2-2.dll", + "libgoocanvas-3.0-9.dll", + "libosmgpsmap-1.0-1.dll", + "gswin32c.exe", + "dot.exe", + "libgvplugin_core-6.dll", + "libgvplugin_dot_layout-6.dll", + "libgvplugin_gd-6.dll", + "libgvplugin_pango-6.dll", + "libgvplugin_rsvg-6.dll", + "glib-compile-schemas.exe", + "gdk-pixbuf-query-loaders.exe", + "gtk-update-icon-cache-3.0.exe", + "fc-cache.exe", + "fc-match.exe", + "gspawn-win64-helper-console.exe", + "gspawn-win64-helper.exe", + "libgeocode-glib-0.dll", +] +BIN_EXCLUDES = ["Qt5Core.dll", "gdiplus.dll", "gdiplus"] from os.path import dirname, basename import lib2to3 + lib23_path = dirname(lib2to3.__file__) -INCLUDE_FILES.append((lib23_path, 'lib/lib2to3')) +INCLUDE_FILES.append((lib23_path, "lib/lib2to3")) import pip + libpip_path = dirname(pip.__file__) -INCLUDE_FILES.append((libpip_path,'lib/pip')) +INCLUDE_FILES.append((libpip_path, "lib/pip")) import distlib + libdistlib_path = dirname(distlib.__file__) -INCLUDE_FILES.append((libdistlib_path,'lib/distlib')) +INCLUDE_FILES.append((libdistlib_path, "lib/distlib")) -os.makedirs(os.path.join(BASE_DIR, 'var/cache/fontconfig'), exist_ok=True) +os.makedirs(os.path.join(BASE_DIR, "var/cache/fontconfig"), exist_ok=True) for file in SETUP_FILES: - INCLUDE_FILES.append((os.path.join(SETUP_DIR, file), - os.path.join('src', file))) + INCLUDE_FILES.append((os.path.join(SETUP_DIR, file), os.path.join("src", file))) for dll in MISSING_DLL: - INCLUDE_FILES.append((os.path.join(INCLUDE_DLL_PATH, dll), - os.path.join('lib',dll))) -MISSING_LIBS = ['lib/enchant-2', 'lib/gdk-pixbuf-2.0', 'lib/girepository-1.0', - 'share/enchant', 'share/glib-2.0/schemas', - 'share/xml/iso-codes', 'etc/gtk-3.0', - 'etc/ssl/certs', 'etc/ssl/cert.pem', 'etc/fonts', 'lib/gio', - 'share/icons/gnome', - 'share/icons/hicolor', 'share/icons/gramps.png', - 'share/icons/Adwaita/icon-theme.cache', - 'share/icons/Adwaita/index.theme', 'share/hunspell' - ] -ADWAITA = ['8x8', '16x16', '22x22', '24x24', '32x32', '48x48', '64x64', - '96x96', 'cursors' - ] + INCLUDE_FILES.append( + (os.path.join(INCLUDE_DLL_PATH, dll), os.path.join("lib", dll)) + ) +MISSING_LIBS = [ + "lib/enchant-2", + "lib/gdk-pixbuf-2.0", + "lib/girepository-1.0", + "share/enchant", + "share/glib-2.0/schemas", + "share/xml/iso-codes", + "etc/gtk-3.0", + "etc/ssl/certs", + "etc/ssl/cert.pem", + "etc/fonts", + "lib/gio", + "share/icons/gnome", + "share/icons/hicolor", + "share/icons/gramps.png", + "share/icons/Adwaita/icon-theme.cache", + "share/icons/Adwaita/index.theme", + "share/hunspell", +] +ADWAITA = [ + "8x8", + "16x16", + "22x22", + "24x24", + "32x32", + "48x48", + "64x64", + "96x96", + "cursors", +] for adw in ADWAITA: - INCLUDE_FILES.append((os.path.join(sys.prefix, 'share/icons/Adwaita', adw), - os.path.join('share/icons/Adwaita', adw))) + INCLUDE_FILES.append( + ( + os.path.join(sys.prefix, "share/icons/Adwaita", adw), + os.path.join("share/icons/Adwaita", adw), + ) + ) for lib in MISSING_LIBS: INCLUDE_FILES.append((os.path.join(sys.prefix, lib), lib)) -INCLUDE_FILES.append('dist/gramps') -INCLUDE_FILES.append(('dist/gramps-' + '.'.join(map(str, VERSION_TUPLE)) + '.data/data/share','share')) -EXECUTABLES = [cx_Freeze.Executable("grampsaioc.py", base="Console", - target_name='gramps.exe', - icon='gramps.ico', copyright=COPYRIGHT), - cx_Freeze.Executable("grampsaiow.py", base="Win32GUI", - target_name='grampsw.exe', - icon='gramps.ico', copyright=COPYRIGHT), - cx_Freeze.Executable("grampsaiocd.py", base="Console", - target_name='grampsd.exe', - icon='grampsd.ico', copyright=COPYRIGHT) - ] -BUILD_EXE_OPTIONS = {'packages':PACKAGES, - 'includes':INCLUDES, - 'excludes':EXCLUDES, - 'include_files':INCLUDE_FILES, - 'bin_includes':MISSING_DLL, - 'zip_include_packages': '*', #ZIP_INCLUDE_PACKAGES, - 'zip_exclude_packages':EXCLUDES, - 'bin_excludes':BIN_EXCLUDES, - 'replace_paths':REPLACE_PATHS, - 'build_exe':BASE_DIR, - } -BDIST_MSI_OPTIONS = { #uuid.uuid5(uuid.NAMESPACE_DNS, 'GrampsAIO64-5-trunk') - 'upgrade_code': '{fbccc04b-7b2e-56d3-8bb7-94d5f68de822}', - #uuid.uuid5(uuid.NAMESPACE_DNS, 'v5.0.0-alpha1-476-g473d3aa') - 'product_code': '{48304362-2945-5a10-ad60-241f233be4d2}', - 'add_to_path': False, +INCLUDE_FILES.append("dist/gramps") +INCLUDE_FILES.append( + ("dist/gramps-" + ".".join(map(str, VERSION_TUPLE)) + ".data/data/share", "share") +) +EXECUTABLES = [ + cx_Freeze.Executable( + "grampsaioc.py", + base="Console", + target_name="gramps.exe", + icon="gramps.ico", + copyright=COPYRIGHT, + ), + cx_Freeze.Executable( + "grampsaiow.py", + base="Win32GUI", + target_name="grampsw.exe", + icon="gramps.ico", + copyright=COPYRIGHT, + ), + cx_Freeze.Executable( + "grampsaiocd.py", + base="Console", + target_name="grampsd.exe", + icon="grampsd.ico", + copyright=COPYRIGHT, + ), +] +BUILD_EXE_OPTIONS = { + "packages": PACKAGES, + "includes": INCLUDES, + "excludes": EXCLUDES, + "include_files": INCLUDE_FILES, + "bin_includes": MISSING_DLL, + "zip_include_packages": "*", # ZIP_INCLUDE_PACKAGES, + "zip_exclude_packages": EXCLUDES, + "bin_excludes": BIN_EXCLUDES, + "replace_paths": REPLACE_PATHS, + "build_exe": BASE_DIR, +} +BDIST_MSI_OPTIONS = { # uuid.uuid5(uuid.NAMESPACE_DNS, 'GrampsAIO64-5-trunk') + "upgrade_code": "{fbccc04b-7b2e-56d3-8bb7-94d5f68de822}", + # uuid.uuid5(uuid.NAMESPACE_DNS, 'v5.0.0-alpha1-476-g473d3aa') + "product_code": "{48304362-2945-5a10-ad60-241f233be4d2}", + "add_to_path": False, #'initial_target_dir': r'[ProgramFilesFolder]\%s\%s' % - #(company_name, product_name), - } + # (company_name, product_name), +} cx_Freeze.setup( - name="GrampsAIO32" if '32' in BASE_DIR else "GrampsAIO64", - options={"build_exe": BUILD_EXE_OPTIONS, 'bdist_msi': BDIST_MSI_OPTIONS}, + name="GrampsAIO32" if "32" in BASE_DIR else "GrampsAIO64", + options={"build_exe": BUILD_EXE_OPTIONS, "bdist_msi": BDIST_MSI_OPTIONS}, version=VERSION, description="Gramps Genealogy software", long_description=VERSION_QUALIFIER, - executables=EXECUTABLES) + executables=EXECUTABLES, +) -ZIN = zipfile.ZipFile(os.path.join(BASE_DIR, 'lib/library.zip'), 'r') -ZOUT = zipfile.ZipFile(os.path.join(BASE_DIR, 'lib/pythonx.zip'), 'w') +ZIN = zipfile.ZipFile(os.path.join(BASE_DIR, "lib/library.zip"), "r") +ZOUT = zipfile.ZipFile(os.path.join(BASE_DIR, "lib/pythonx.zip"), "w") for item in ZIN.infolist(): - if not os.path.dirname(item.filename).startswith('gramps'): - #if '/test' in item.filename or 'test/' in item.filename: + if not os.path.dirname(item.filename).startswith("gramps"): + # if '/test' in item.filename or 'test/' in item.filename: # print("Zip Excluded:", item.filename) - #else: + # else: print("Zip Included:", item.filename) buffer = ZIN.read(item.filename) ZOUT.writestr(item, buffer) ZOUT.close() ZIN.close() -shutil.move(os.path.join(BASE_DIR, 'lib/pythonx.zip'), - os.path.join(BASE_DIR, 'lib/library.zip')) +shutil.move( + os.path.join(BASE_DIR, "lib/pythonx.zip"), os.path.join(BASE_DIR, "lib/library.zip") +) if os.path.isfile(UPX_ALT_PATH): UPX = UPX_ALT_PATH else: - WHICH = 'where' if os.name == 'nt' else 'which' + WHICH = "where" if os.name == "nt" else "which" try: - subprocess.check_call([WHICH, 'UPX']) + subprocess.check_call([WHICH, "UPX"]) except subprocess.CalledProcessError: UPX = None else: - UPX = 'upx' + UPX = "upx" if UPX is not None: - ARGS = [UPX, '-7', '--no-progress'] - ARGS.extend(os.path.join(BASE_DIR, filename) for filename in - os.listdir(BASE_DIR) if filename == 'name' or - os.path.splitext(filename)[1].lower() in - ('.exe', '.dll', '.pyd', '.so') and - os.path.splitext(filename)[0].lower() not in - ('libgcc_s_dw2-1', 'gramps', 'grampsw', 'grampsd', - 'libwinpthread-1')) + ARGS = [UPX, "-7", "--no-progress"] + ARGS.extend( + os.path.join(BASE_DIR, filename) + for filename in os.listdir(BASE_DIR) + if filename == "name" + or os.path.splitext(filename)[1].lower() in (".exe", ".dll", ".pyd", ".so") + and os.path.splitext(filename)[0].lower() + not in ("libgcc_s_dw2-1", "gramps", "grampsw", "grampsd", "libwinpthread-1") + ) subprocess.call(ARGS) else: print("\nUPX not found") diff --git a/data/man/conf.py b/data/man/conf.py index bb7fe87e2a0..bac6ac8a228 100644 --- a/data/man/conf.py +++ b/data/man/conf.py @@ -16,210 +16,204 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'Gramps' -copyright = u'2015, Gramps project' +project = "Gramps" +copyright = "2015, Gramps project" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '4.2' +version = "4.2" # The full version, including alpha/beta/rc tags. -release = '4.2.0' +release = "4.2.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#locale_dirs = './locale' -#gettext_compact = True +# locale_dirs = './locale' +# gettext_compact = True # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -today_fmt = '%B %d, %Y' +today_fmt = "%B %d, %Y" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "default" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] +# html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'Grampsdoc' +htmlhelp_basename = "Grampsdoc" # -- Options for LaTeX output -------------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'Gramps.tex', u'Gramps Documentation', - u'.', 'manual'), + ("index", "Gramps.tex", "Gramps Documentation", ".", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('en', 'gramps', u'Gramps Documentation', - ['Gramps project'], 1) -] +man_pages = [("en", "gramps", "Gramps Documentation", ["Gramps project"], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ @@ -228,16 +222,22 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'Gramps', u'Gramps Documentation', - u'.', 'Gramps', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "Gramps", + "Gramps Documentation", + ".", + "Gramps", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' diff --git a/data/man/cs/conf.py b/data/man/cs/conf.py index b831bf55e3f..2327deeebcc 100644 --- a/data/man/cs/conf.py +++ b/data/man/cs/conf.py @@ -16,210 +16,204 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'cs' +master_doc = "cs" # General information about the project. -project = u'Gramps' -copyright = u'2015, Gramps project' +project = "Gramps" +copyright = "2015, Gramps project" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '4.2' +version = "4.2" # The full version, including alpha/beta/rc tags. -release = '4.2.0' +release = "4.2.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -locale_dirs = './locale' +locale_dirs = "./locale" gettext_compact = True # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -today_fmt = '%B %d, %Y' +today_fmt = "%B %d, %Y" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "default" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] +# html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'Grampsdoc' +htmlhelp_basename = "Grampsdoc" # -- Options for LaTeX output -------------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'Gramps.tex', u'Gramps Documentation', - u'.', 'manual'), + ("index", "Gramps.tex", "Gramps Documentation", ".", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('cs', 'gramps', u'Gramps Documentation', - [u'.'], 1) -] +man_pages = [("cs", "gramps", "Gramps Documentation", ["."], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ @@ -228,16 +222,22 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'Gramps', u'Gramps Documentation', - u'.', 'Gramps', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "Gramps", + "Gramps Documentation", + ".", + "Gramps", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' diff --git a/data/man/fr/conf.py b/data/man/fr/conf.py index 17a0d5c83a7..afce5f8756a 100644 --- a/data/man/fr/conf.py +++ b/data/man/fr/conf.py @@ -16,210 +16,204 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'fr' +master_doc = "fr" # General information about the project. -project = u'Gramps' -copyright = u'2015, Gramps project' +project = "Gramps" +copyright = "2015, Gramps project" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '4.2' +version = "4.2" # The full version, including alpha/beta/rc tags. -release = '4.2.0' +release = "4.2.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -locale_dirs = './locale' +locale_dirs = "./locale" gettext_compact = True # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -today_fmt = '%d %B %Y' +today_fmt = "%d %B %Y" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "default" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] +# html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'Grampsdoc' +htmlhelp_basename = "Grampsdoc" # -- Options for LaTeX output -------------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'Gramps.tex', u'Gramps Documentation', - u'.', 'manual'), + ("index", "Gramps.tex", "Gramps Documentation", ".", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('fr', 'gramps', u'Gramps Documentation', - ['Jerome Rapinat'], 1) -] +man_pages = [("fr", "gramps", "Gramps Documentation", ["Jerome Rapinat"], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ @@ -228,16 +222,22 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'Gramps', u'Gramps Documentation', - u'.', 'Gramps', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "Gramps", + "Gramps Documentation", + ".", + "Gramps", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' diff --git a/data/man/nl/conf.py b/data/man/nl/conf.py index 43af3648c0e..e8efd59daf1 100644 --- a/data/man/nl/conf.py +++ b/data/man/nl/conf.py @@ -16,210 +16,204 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'nl' +master_doc = "nl" # General information about the project. -project = u'Gramps' -copyright = u'2015, Gramps project' +project = "Gramps" +copyright = "2015, Gramps project" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '4.2' +version = "4.2" # The full version, including alpha/beta/rc tags. -release = '4.2.0' +release = "4.2.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -locale_dirs = './locale' +locale_dirs = "./locale" gettext_compact = True # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -today_fmt = '%B %d, %Y' +today_fmt = "%B %d, %Y" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "default" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] +# html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'Grampsdoc' +htmlhelp_basename = "Grampsdoc" # -- Options for LaTeX output -------------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'Gramps.tex', u'Gramps Documentation', - u'.', 'manual'), + ("index", "Gramps.tex", "Gramps Documentation", ".", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('nl', 'gramps', u'Gramps Documentation', - [u'.'], 1) -] +man_pages = [("nl", "gramps", "Gramps Documentation", ["."], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ @@ -228,16 +222,22 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'Gramps', u'Gramps Documentation', - u'.', 'Gramps', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "Gramps", + "Gramps Documentation", + ".", + "Gramps", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' diff --git a/data/man/pl/conf.py b/data/man/pl/conf.py index 011536fb44e..d4bb3a8ed3b 100644 --- a/data/man/pl/conf.py +++ b/data/man/pl/conf.py @@ -16,210 +16,204 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'pl' +master_doc = "pl" # General information about the project. -project = u'Gramps' -copyright = u'2015, Gramps project' +project = "Gramps" +copyright = "2015, Gramps project" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '4.2' +version = "4.2" # The full version, including alpha/beta/rc tags. -release = '4.2.0' +release = "4.2.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -locale_dirs = './locale' +locale_dirs = "./locale" gettext_compact = True # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -today_fmt = '%B %d, %Y' +today_fmt = "%B %d, %Y" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "default" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] +# html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'Grampsdoc' +htmlhelp_basename = "Grampsdoc" # -- Options for LaTeX output -------------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'Gramps.tex', u'Gramps Documentation', - u'.', 'manual'), + ("index", "Gramps.tex", "Gramps Documentation", ".", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('pl', 'gramps', u'Gramps Documentation', - [u'.'], 1) -] +man_pages = [("pl", "gramps", "Gramps Documentation", ["."], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ @@ -228,16 +222,22 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'Gramps', u'Gramps Documentation', - u'.', 'Gramps', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "Gramps", + "Gramps Documentation", + ".", + "Gramps", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' diff --git a/data/man/pt_BR/conf.py b/data/man/pt_BR/conf.py index 3e1e931ead1..c8eb91fc74b 100644 --- a/data/man/pt_BR/conf.py +++ b/data/man/pt_BR/conf.py @@ -16,210 +16,204 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'pt_BR' +master_doc = "pt_BR" # General information about the project. -project = u'Gramps' -copyright = u'2015, Gramps project' +project = "Gramps" +copyright = "2015, Gramps project" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '4.2' +version = "4.2" # The full version, including alpha/beta/rc tags. -release = '4.2.0' +release = "4.2.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -locale_dirs = './locale' +locale_dirs = "./locale" gettext_compact = True # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -today_fmt = '%B %d, %Y' +today_fmt = "%B %d, %Y" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "default" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] +# html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'Grampsdoc' +htmlhelp_basename = "Grampsdoc" # -- Options for LaTeX output -------------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'Gramps.tex', u'Gramps Documentation', - u'.', 'manual'), + ("index", "Gramps.tex", "Gramps Documentation", ".", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('pt_BR', 'gramps', u'Gramps Documentation', - [u'.'], 1) -] +man_pages = [("pt_BR", "gramps", "Gramps Documentation", ["."], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ @@ -228,16 +222,22 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'Gramps', u'Gramps Documentation', - u'.', 'Gramps', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "Gramps", + "Gramps Documentation", + ".", + "Gramps", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' diff --git a/data/man/sv/conf.py b/data/man/sv/conf.py index 0e3b21efed9..4fdff95a76d 100644 --- a/data/man/sv/conf.py +++ b/data/man/sv/conf.py @@ -16,210 +16,204 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'sv' +master_doc = "sv" # General information about the project. -project = u'Gramps' -copyright = u'2015, Gramps project' +project = "Gramps" +copyright = "2015, Gramps project" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '4.2' +version = "4.2" # The full version, including alpha/beta/rc tags. -release = '4.2.0' +release = "4.2.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -locale_dirs = './locale' +locale_dirs = "./locale" gettext_compact = True # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -today_fmt = '%B %d, %Y' +today_fmt = "%B %d, %Y" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "default" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] +# html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'Grampsdoc' +htmlhelp_basename = "Grampsdoc" # -- Options for LaTeX output -------------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'Gramps.tex', u'Gramps Documentation', - u'.', 'manual'), + ("index", "Gramps.tex", "Gramps Documentation", ".", "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('sv', 'gramps', u'Gramps Documentation', - [u'.'], 1) -] +man_pages = [("sv", "gramps", "Gramps Documentation", ["."], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ @@ -228,16 +222,22 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'Gramps', u'Gramps Documentation', - u'.', 'Gramps', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "Gramps", + "Gramps Documentation", + ".", + "Gramps", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' diff --git a/data/man/update_man.py b/data/man/update_man.py index 02e43c2cd1c..373d02d9986 100644 --- a/data/man/update_man.py +++ b/data/man/update_man.py @@ -42,23 +42,24 @@ except: DOCUTILS = False -LANGUAGES = ['sv', 'nl', 'pl', 'cs', 'pt_BR', 'fr'] -VERSION = '5.0.0' -DATE = '' +LANGUAGES = ["sv", "nl", "pl", "cs", "pt_BR", "fr"] +VERSION = "5.0.0" +DATE = "" # You can set these variables from the command line. -SPHINXBUILD = 'sphinx-build' +SPHINXBUILD = "sphinx-build" -if sys.platform == 'win32': - pythonCmd = os.path.join(sys.prefix, 'bin', 'python.exe') - sphinxCmd = os.path.join(sys.prefix, 'bin', 'sphinx-build.exe') -elif sys.platform in ['linux2', 'darwin', 'cygwin']: - pythonCmd = os.path.join(sys.prefix, 'bin', 'python') +if sys.platform == "win32": + pythonCmd = os.path.join(sys.prefix, "bin", "python.exe") + sphinxCmd = os.path.join(sys.prefix, "bin", "sphinx-build.exe") +elif sys.platform in ["linux2", "darwin", "cygwin"]: + pythonCmd = os.path.join(sys.prefix, "bin", "python") sphinxCmd = SPHINXBUILD else: - print ("Update Man ERROR: unknown system, don't know sphinx, ... commands") + print("Update Man ERROR: unknown system, don't know sphinx, ... commands") sys.exit(0) + def tests(): """ Testing installed programs. @@ -67,18 +68,19 @@ def tests(): """ try: print("\n=================='python'=============================\n") - os.system('''%(program)s -V''' % {'program': pythonCmd}) + os.system("""%(program)s -V""" % {"program": pythonCmd}) except: - print ('Please, install python') + print("Please, install python") try: print("\n=================='Sphinx-build'=============================\n") - os.system('''%(program)s''' % {'program': sphinxCmd}) + os.system("""%(program)s""" % {"program": sphinxCmd}) except: - print ('Please, install sphinx') + print("Please, install sphinx") if not DOCUTILS: - print('\nNo docutils support, cannot use -m/--man and -o/--odt arguments.') + print("\nNo docutils support, cannot use -m/--man and -o/--odt arguments.") + def main(): """ @@ -87,25 +89,45 @@ def main(): """ parser = ArgumentParser( - description='This program aims to handle documentation' - ' and related translated versions.', - ) - - parser.add_argument("-t", "--test", - action="store_true", dest="test", default=True, - help="test if 'python' and 'sphinx' are properly installed") - - parser.add_argument("-b", "--build", - action="store_true", dest="build", default=False, - help="build man documentation (via sphinx-build)") - - parser.add_argument("-m", "--man", - action="store_true", dest="man", default=False, - help="build man documentation (via docutils)") - - parser.add_argument("-o", "--odt", - action="store_true", dest="odt", default=False, - help="build odt documentation (via docutils)") + description="This program aims to handle documentation" + " and related translated versions.", + ) + + parser.add_argument( + "-t", + "--test", + action="store_true", + dest="test", + default=True, + help="test if 'python' and 'sphinx' are properly installed", + ) + + parser.add_argument( + "-b", + "--build", + action="store_true", + dest="build", + default=False, + help="build man documentation (via sphinx-build)", + ) + + parser.add_argument( + "-m", + "--man", + action="store_true", + dest="man", + default=False, + help="build man documentation (via docutils)", + ) + + parser.add_argument( + "-o", + "--odt", + action="store_true", + dest="odt", + default=False, + help="build odt documentation (via docutils)", + ) args = parser.parse_args() @@ -121,6 +143,7 @@ def main(): if args.odt and DOCUTILS: odt() + def build(): """ Build documentation. @@ -128,28 +151,39 @@ def build(): # testing stage - os.system('''%(program)s -b html . _build/html''' % {'program': sphinxCmd}) - os.system('''%(program)s -b htmlhelp . _build/htmlhelp''' % {'program': sphinxCmd}) + os.system("""%(program)s -b html . _build/html""" % {"program": sphinxCmd}) + os.system("""%(program)s -b htmlhelp . _build/htmlhelp""" % {"program": sphinxCmd}) if DOCUTILS: - os.system('''%(program)s -b man . .''' % {'program': sphinxCmd}) - os.system('''%(program)s -b text . _build/text''' % {'program': sphinxCmd}) - os.system('''%(program)s -b changes . _build/changes''' % {'program': sphinxCmd}) - #os.system('''%(program)s -b linkcheck . _build/linkcheck''' % {'program': sphinxCmd}) - os.system('''%(program)s -b gettext . _build/gettext''' % {'program': sphinxCmd}) + os.system("""%(program)s -b man . .""" % {"program": sphinxCmd}) + os.system("""%(program)s -b text . _build/text""" % {"program": sphinxCmd}) + os.system("""%(program)s -b changes . _build/changes""" % {"program": sphinxCmd}) + # os.system('''%(program)s -b linkcheck . _build/linkcheck''' % {'program': sphinxCmd}) + os.system("""%(program)s -b gettext . _build/gettext""" % {"program": sphinxCmd}) for lang in LANGUAGES: - os.system('''%(program)s -b html -D language="%(lang)s" master_doc="%(lang)s" %(lang)s %(lang)s''' - % {'lang': lang, 'program': sphinxCmd}) - os.system('''%(program)s -b htmlhelp -D language="%(lang)s" master_doc="%(lang)s" %(lang)s %(lang)s''' - % {'lang': lang, 'program': sphinxCmd}) + os.system( + """%(program)s -b html -D language="%(lang)s" master_doc="%(lang)s" %(lang)s %(lang)s""" + % {"lang": lang, "program": sphinxCmd} + ) + os.system( + """%(program)s -b htmlhelp -D language="%(lang)s" master_doc="%(lang)s" %(lang)s %(lang)s""" + % {"lang": lang, "program": sphinxCmd} + ) if DOCUTILS: - os.system('''%(program)s -b man %(lang)s %(lang)s''' - % {'lang': lang, 'program': sphinxCmd}) - os.system('''%(program)s -b text -D language="%(lang)s" master_doc="%(lang)s" %(lang)s %(lang)s''' - % {'lang': lang, 'program': sphinxCmd}) + os.system( + """%(program)s -b man %(lang)s %(lang)s""" + % {"lang": lang, "program": sphinxCmd} + ) + os.system( + """%(program)s -b text -D language="%(lang)s" master_doc="%(lang)s" %(lang)s %(lang)s""" + % {"lang": lang, "program": sphinxCmd} + ) # for update/migration - os.system('''%(program)s -b gettext -D language="%(lang)s" master_doc="%(lang)s" . _build/gettext/%(lang)s''' - % {'lang': lang, 'program': sphinxCmd}) + os.system( + """%(program)s -b gettext -D language="%(lang)s" master_doc="%(lang)s" . _build/gettext/%(lang)s""" + % {"lang": lang, "program": sphinxCmd} + ) + def man(): """ @@ -159,11 +193,14 @@ def man(): from docutils.writers import manpage """ - os.system('''rst2man en.rst gramps.1''') + os.system("""rst2man en.rst gramps.1""") for lang in LANGUAGES: - os.system('''rst2man %(lang)s/%(lang)s.rst -l %(lang)s %(lang)s/gramps.1''' - % {'lang': lang}) + os.system( + """rst2man %(lang)s/%(lang)s.rst -l %(lang)s %(lang)s/gramps.1""" + % {"lang": lang} + ) + def odt(): """ @@ -173,11 +210,14 @@ def odt(): from docutils.writers.odf_odt import Writer, Reader """ - os.system('''rst2odt en.rst gramps.odt''') + os.system("""rst2odt en.rst gramps.odt""") for lang in LANGUAGES: - os.system('''rst2odt %(lang)s/%(lang)s.rst -l %(lang)s %(lang)s/gramps.odt''' - % {'lang': lang}) + os.system( + """rst2odt %(lang)s/%(lang)s.rst -l %(lang)s %(lang)s/gramps.odt""" + % {"lang": lang} + ) + if __name__ == "__main__": main() diff --git a/docs/conf.py b/docs/conf.py index a09b97ca108..2451ffb383d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,54 +20,54 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) -#documentation in root/docs, allow import from root +# documentation in root/docs, allow import from root sys.path.append(os.path.abspath(os.pardir)) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.doctest', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.viewcode', + "sphinx.ext.autodoc", + "sphinx.ext.doctest", + "sphinx.ext.todo", + "sphinx.ext.coverage", + "sphinx.ext.viewcode", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = 'Gramps' -copyright = '2001-2019, The Gramps Project' -author = 'Donald N. Allingham' +project = "Gramps" +copyright = "2001-2019, The Gramps Project" +author = "Donald N. Allingham" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '5.1.0' +version = "5.1.0" # The full version, including alpha/beta/rc tags. -release = '5.1.0' +release = "5.1.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -78,37 +78,37 @@ # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all # documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True @@ -118,157 +118,156 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. default: alabaster -html_theme = 'classic' +html_theme = "classic" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] +# html_static_path = ['_static'] html_static_path = [] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +# html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' -#html_search_language = 'en' +# html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} +# html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' +# html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'Grampsdoc' +htmlhelp_basename = "Grampsdoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Latex figure (float) alignment + #'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('master_doc', 'Gramps.tex', 'Gramps Documentation', - 'The Gramps Project', 'manual'), + ( + "master_doc", + "Gramps.tex", + "Gramps Documentation", + "The Gramps Project", + "manual", + ), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'gramps', 'Gramps Documentation', - [author], 1) -] +man_pages = [(master_doc, "gramps", "Gramps Documentation", [author], 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------- @@ -277,19 +276,25 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'Gramps', 'Gramps Documentation', - author, 'Gramps', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "Gramps", + "Gramps Documentation", + author, + "Gramps", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False diff --git a/docs/update_doc.py b/docs/update_doc.py index 635ad0efd67..0bd47ff902c 100644 --- a/docs/update_doc.py +++ b/docs/update_doc.py @@ -37,18 +37,19 @@ from argparse import ArgumentParser # You can set these variables from the command line. -SPHINXBUILD = 'sphinx-build' +SPHINXBUILD = "sphinx-build" -if sys.platform == 'win32': - pythonCmd = os.path.join(sys.prefix, 'bin', 'python.exe') - sphinxCmd = os.path.join(sys.prefix, 'bin', 'sphinx-build.exe') -elif sys.platform in ['linux', 'linux2', 'darwin', 'cygwin']: - pythonCmd = os.path.join(sys.prefix, 'bin', 'python') +if sys.platform == "win32": + pythonCmd = os.path.join(sys.prefix, "bin", "python.exe") + sphinxCmd = os.path.join(sys.prefix, "bin", "sphinx-build.exe") +elif sys.platform in ["linux", "linux2", "darwin", "cygwin"]: + pythonCmd = os.path.join(sys.prefix, "bin", "python") sphinxCmd = SPHINXBUILD else: - print ("Update Docs ERROR: unknown system, don't know sphinx, ... commands") + print("Update Docs ERROR: unknown system, don't know sphinx, ... commands") sys.exit(0) + def tests(): """ Testing installed programs. @@ -57,15 +58,16 @@ def tests(): """ try: print("\n=================='python'=============================\n") - os.system('''%(program)s -V''' % {'program': pythonCmd}) + os.system("""%(program)s -V""" % {"program": pythonCmd}) except: - print ('Please, install python') + print("Please, install python") try: print("\n=================='sphinx-build'=============================\n") - os.system('''%(program)s''' % {'program': sphinxCmd}) + os.system("""%(program)s""" % {"program": sphinxCmd}) except: - print ('Please, install sphinx') + print("Please, install sphinx") + def main(): """ @@ -74,17 +76,26 @@ def main(): """ parser = ArgumentParser( - description='This program aims to handle manual' - ' and translated version.', - ) - - parser.add_argument("-t", "--test", - action="store_true", dest="test", default=True, - help="test if 'python' and 'sphinx' are properly installed") - - parser.add_argument("-b", "--build", - action="store_true", dest="build", default=True, - help="build documentation") + description="This program aims to handle manual" " and translated version.", + ) + + parser.add_argument( + "-t", + "--test", + action="store_true", + dest="test", + default=True, + help="test if 'python' and 'sphinx' are properly installed", + ) + + parser.add_argument( + "-b", + "--build", + action="store_true", + dest="build", + default=True, + help="build documentation", + ) args = parser.parse_args() @@ -94,6 +105,7 @@ def main(): if args.build: build() + def build(): """ Build documentation. @@ -101,10 +113,11 @@ def build(): # testing stage - os.system('''%(program)s -b html . _build/html''' % {'program': sphinxCmd}) - #os.system('''%(program)s -b changes . _build/changes''' % {'program': sphinxCmd}) - #os.system('''%(program)s -b linkcheck . _build/linkcheck''' % {'program': sphinxCmd}) - #os.system('''%(program)s -b devhelp . _build/devhelp''' % {'program': sphinxCmd}) + os.system("""%(program)s -b html . _build/html""" % {"program": sphinxCmd}) + # os.system('''%(program)s -b changes . _build/changes''' % {'program': sphinxCmd}) + # os.system('''%(program)s -b linkcheck . _build/linkcheck''' % {'program': sphinxCmd}) + # os.system('''%(program)s -b devhelp . _build/devhelp''' % {'program': sphinxCmd}) + if __name__ == "__main__": main() diff --git a/gramps/cli/arghandler.py b/gramps/cli/arghandler.py index 11d59d804c3..17e76421342 100644 --- a/gramps/cli/arghandler.py +++ b/gramps/cli/arghandler.py @@ -29,20 +29,20 @@ Module responsible for handling the command line arguments for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import os import sys import re -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from gramps.gen.recentfiles import recent_files from gramps.gen.utils.file import rm_tempdir, get_empty_tempdir from .clidbman import CLIDbManager, NAME_FILE, find_locker_name @@ -52,14 +52,16 @@ from gramps.gen.plug.report import CATEGORY_BOOK, CATEGORY_CODE, BookList from .plug import cl_report, cl_book from gramps.gen.const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext from gramps.gen.config import config -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # private functions # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- def _split_options(options_str): """ Split the options for the action. @@ -103,32 +105,32 @@ def _split_options(options_str): if not parsing_value: # Parsing the name of the option if char == "=": - #print char, "This value ends the name" + # print char, "This value ends the name" parsing_value = True else: - #print char, "This value is part of the name" + # print char, "This value is part of the name" name += char else: # Parsing the value of the option - if value == "" and char == '[': - #print char, "This character begins a list" + if value == "" and char == "[": + # print char, "This character begins a list" in_list = True value += char - elif in_list == True and char == ']': - #print char, "This character ends the list" + elif in_list == True and char == "]": + # print char, "This character ends the list" in_list = False value += char elif not in_quotes and (char == '"' or char == "'"): - #print char, "This character starts a quoted string" + # print char, "This character starts a quoted string" in_quotes = True quote_type = char value += char elif in_quotes and char == quote_type: - #print char, "This character ends a quoted string" + # print char, "This character ends a quoted string" in_quotes = False value += char elif not in_quotes and not in_list and char == ",": - #print char, "This character ends the value of the option" + # print char, "This character ends the value of the option" options_str_dict[name] = value name = "" value = "" @@ -136,7 +138,7 @@ def _split_options(options_str): in_quotes = False in_list = False else: - #print char, "This character is part of the value" + # print char, "This character is part of the value" value += char if parsing_value and not in_quotes and not in_list: @@ -145,9 +147,10 @@ def _split_options(options_str): return options_str_dict -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # ArgHandler -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ArgHandler: """ This class is responsible for the non GUI handling of commands. @@ -155,8 +158,7 @@ class ArgHandler: actions requested working on a :class:`.DbState`. """ - def __init__(self, dbstate, parser, sessionmanager, - errorfunc=None, gui=False): + def __init__(self, dbstate, parser, sessionmanager, errorfunc=None, gui=False): self.dbstate = dbstate self.smgr = sessionmanager self.errorfunc = errorfunc @@ -198,16 +200,16 @@ def __error(self, msg1, msg2=None): if msg2 is not None: print(msg2, file=sys.stderr) - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # Argument parser: sorts out given arguments - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def sanitize_args(self, importlist, exportlist): """ Check the lists with open, exports, imports, and actions options. """ - for (value, family_tree_format) in importlist: + for value, family_tree_format in importlist: self.__handle_import_option(value, family_tree_format) - for (value, family_tree_format) in exportlist: + for value, family_tree_format in exportlist: self.__handle_export_option(value, family_tree_format) def __handle_open_option(self, value, create): @@ -226,22 +228,29 @@ def __handle_open_option(self, value, create): if not self.check_db(db_path, self.force_unlock): sys.exit(1) if create: - self.__error(_("Error: Family Tree '%s' already exists.\n" - "The '-C' option cannot be used." - ) % value) + self.__error( + _( + "Error: Family Tree '%s' already exists.\n" + "The '-C' option cannot be used." + ) + % value + ) sys.exit(1) return db_path elif create: # create the tree here, and continue - dbid = config.get('database.backend') - db_path, title = self.dbman.create_new_db_cli(title=value, - dbid=dbid) + dbid = config.get("database.backend") + db_path, title = self.dbman.create_new_db_cli(title=value, dbid=dbid) return db_path else: - self.__error(_('Error: Input Family Tree "%s" does not exist.\n' - "If GEDCOM, Gramps-xml or grdb, use the -i option " - "to import into a Family Tree instead." - ) % value) + self.__error( + _( + 'Error: Input Family Tree "%s" does not exist.\n' + "If GEDCOM, Gramps-xml or grdb, use the -i option " + "to import into a Family Tree instead." + ) + % value + ) sys.exit(1) def __handle_import_option(self, value, family_tree_format): @@ -251,8 +260,8 @@ def __handle_import_option(self, value, family_tree_format): """ fname = value fullpath = os.path.abspath(os.path.expanduser(fname)) - if fname != '-' and not os.path.exists(fullpath): - self.__error(_('Error: Import file %s not found.') % fname) + if fname != "-" and not os.path.exists(fullpath): + self.__error(_("Error: Import file %s not found.") % fname) sys.exit(1) if family_tree_format is None: @@ -270,10 +279,13 @@ def __handle_import_option(self, value, family_tree_format): if plugin_found: self.imports.append((fname, family_tree_format)) else: - self.__error(_('Error: Unrecognized type: "%(format)s" for ' - 'import file: %(filename)s' - ) % {'format' : family_tree_format, - 'filename' : fname}) + self.__error( + _( + 'Error: Unrecognized type: "%(format)s" for ' + "import file: %(filename)s" + ) + % {"format": family_tree_format, "filename": fname} + ) sys.exit(1) def __handle_export_option(self, value, family_tree_format): @@ -285,20 +297,27 @@ def __handle_export_option(self, value, family_tree_format): if self.gui: return fname = value - if fname == '-': - fullpath = '-' + if fname == "-": + fullpath = "-" else: fullpath = os.path.abspath(os.path.expanduser(fname)) if os.path.exists(fullpath): - message = _("WARNING: Output file already exists!\n" - "WARNING: It will be overwritten:\n %s" - ) % fullpath - accepted = self.user.prompt(_('OK to overwrite?'), message, - _('yes'), _('no'), - default_label=_('yes')) + message = ( + _( + "WARNING: Output file already exists!\n" + "WARNING: It will be overwritten:\n %s" + ) + % fullpath + ) + accepted = self.user.prompt( + _("OK to overwrite?"), + message, + _("yes"), + _("no"), + default_label=_("yes"), + ) if accepted: - self.__error(_("Will overwrite the existing file: %s" - ) % fullpath) + self.__error(_("Will overwrite the existing file: %s") % fullpath) else: sys.exit(1) @@ -317,8 +336,7 @@ def __handle_export_option(self, value, family_tree_format): if plugin_found: self.exports.append((fullpath, family_tree_format)) else: - self.__error(_("ERROR: Unrecognized format for export file %s" - ) % fname) + self.__error(_("ERROR: Unrecognized format for export file %s") % fname) sys.exit(1) def __deduce_db_path(self, db_name_or_path): @@ -343,10 +361,10 @@ def __deduce_db_path(self, db_name_or_path): return db_path - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # Overall argument handler: # sorts out the sequence and details of operations - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def handle_args_gui(self): """ Method to handle the arguments that can be given for a GUI session. @@ -368,8 +386,7 @@ def handle_args_gui(self): if not db_path: # Apparently it is not a database. See if it is a file that # can be imported. - db_path, title = self.dbman.import_new_db(self.open_gui, - self.user) + db_path, title = self.dbman.import_new_db(self.open_gui, self.user) if db_path: # Test if not locked or problematic @@ -402,17 +419,21 @@ def handle_args_cli(self, cleanup=True): """ # Handle the "-l" List Family Trees option. if self.list: - print(_('List of known Family Trees in your database path\n')) - - for name, dirname in sorted(self.dbman.family_tree_list(), - key=lambda pair: pair[0].lower()): - if (self.database_names is None - or any([(re.match("^" + dbname + "$", name) - or dbname == name) - for dbname in self.database_names])): - print(_('%(full_DB_path)s with name "%(f_t_name)s"' - ) % {'full_DB_path' : dirname, - 'f_t_name' : name}) + print(_("List of known Family Trees in your database path\n")) + + for name, dirname in sorted( + self.dbman.family_tree_list(), key=lambda pair: pair[0].lower() + ): + if self.database_names is None or any( + [ + (re.match("^" + dbname + "$", name) or dbname == name) + for dbname in self.database_names + ] + ): + print( + _('%(full_DB_path)s with name "%(f_t_name)s"') + % {"full_DB_path": dirname, "f_t_name": name} + ) return # Handle the "--remove" Family Tree @@ -428,7 +449,7 @@ def handle_args_cli(self, cleanup=True): # Handle the "-t" List Family Trees, tab delimited option. if self.list_table: - print(_('Gramps Family Trees:')) + print(_("Gramps Family Trees:")) summary_list = self.dbman.family_tree_summary(self.database_names) if not summary_list: return @@ -439,9 +460,9 @@ def handle_args_cli(self, cleanup=True): if key != _("Family Tree"): line_list += [key] print("\t".join(line_list)) - for summary in sorted(summary_list, - key=lambda - sum: sum[_("Family Tree")].lower()): + for summary in sorted( + summary_list, key=lambda sum: sum[_("Family Tree")].lower() + ): line_list = [(_('"%s"') % summary[_("Family Tree")])] for item in sorted(summary): if item != _("Family Tree"): @@ -453,28 +474,25 @@ def handle_args_cli(self, cleanup=True): self.__open_action() self.__import_action() - for (action, op_string) in self.actions: - print(_("Performing action: %s." - ) % action, - file=sys.stderr) + for action, op_string in self.actions: + print(_("Performing action: %s.") % action, file=sys.stderr) if op_string: - print(_("Using options string: %s" - ) % op_string, - file=sys.stderr) + print(_("Using options string: %s") % op_string, file=sys.stderr) self.cl_action(action, op_string) for expt in self.exports: - print(_("Exporting: file %(filename)s, format %(format)s." - ) % {'filename' : expt[0], - 'format' : expt[1]}, - file=sys.stderr) + print( + _("Exporting: file %(filename)s, format %(format)s.") + % {"filename": expt[0], "format": expt[1]}, + file=sys.stderr, + ) self.cl_export(expt[0], expt[1]) if cleanup: self.cleanup() def cleanup(self): - """ clean up any remaining files """ + """clean up any remaining files""" print(_("Cleaning up."), file=sys.stderr) # remove files in import db subdir after use self.dbstate.db.close() @@ -498,19 +516,20 @@ def __import_action(self): if not self.open: # Create empty dir for imported database(s) if self.gui: - dbid = config.get('database.backend') - self.imp_db_path, title = self.dbman.create_new_db_cli( - dbid=dbid) + dbid = config.get("database.backend") + self.imp_db_path, title = self.dbman.create_new_db_cli(dbid=dbid) else: self.imp_db_path = get_empty_tempdir("import_dbdir") - dbid = config.get('database.backend') + dbid = config.get("database.backend") newdb = make_database(dbid) versionpath = os.path.join(self.imp_db_path, str(DBBACKEND)) with open(versionpath, "w") as version_file: version_file.write(dbid) try: - self.smgr.open_activate(self.imp_db_path, self.username, self.password) + self.smgr.open_activate( + self.imp_db_path, self.username, self.password + ) msg = _("Created empty Family Tree successfully") print(msg, file=sys.stderr) except: @@ -519,9 +538,10 @@ def __import_action(self): sys.exit(1) for imp in self.imports: - msg = _("Importing: file %(filename)s, format %(format)s." - ) % {'filename' : imp[0], - 'format' : imp[1]} + msg = _("Importing: file %(filename)s, format %(format)s.") % { + "filename": imp[0], + "format": imp[1], + } print(msg, file=sys.stderr) self.cl_import(imp[0], imp[1]) @@ -552,8 +572,10 @@ def check_db(self, dbpath, force_unlock=False): if force_unlock: self.dbman.break_lock(dbpath) if self.dbman.is_locked(dbpath): - self.__error((_("Database is locked, cannot open it!") + '\n' + - _(" Info: %s")) % find_locker_name(dbpath)) + self.__error( + (_("Database is locked, cannot open it!") + "\n" + _(" Info: %s")) + % find_locker_name(dbpath) + ) return False if self.dbman.needs_recovery(dbpath): self.__error(_("Database needs recovery, cannot open it!")) @@ -563,11 +585,11 @@ def check_db(self, dbpath, force_unlock=False): return False return True - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # # Import handler # - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def cl_import(self, filename, family_tree_format): """ Command-line import routine. @@ -579,11 +601,11 @@ def cl_import(self, filename, family_tree_format): import_function = plugin.get_import_function() import_function(self.dbstate.db, filename, self.user) - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # # Export handler # - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def cl_export(self, filename, family_tree_format): """ Command-line export routine. @@ -595,11 +617,11 @@ def cl_export(self, filename, family_tree_format): export_function = plugin.get_export_function() export_function(self.dbstate.db, filename, self.user) - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # # Action handler # - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def cl_action(self, action, options_str): """ Command-line action routine. Try to perform specified action. @@ -610,117 +632,130 @@ def cl_action(self, action, options_str): options_str_dict = _split_options(options_str) except: options_str_dict = {} - print(_("Ignoring invalid options string."), - file=sys.stderr) + print(_("Ignoring invalid options string."), file=sys.stderr) - name = options_str_dict.pop('name', None) + name = options_str_dict.pop("name", None) _cl_list = pmgr.get_reg_reports(gui=False) if name: for pdata in _cl_list: if name == pdata.id: mod = pmgr.load_plugin(pdata) if not mod: - #import of plugin failed + # import of plugin failed return category = pdata.category report_class = getattr(mod, pdata.reportclass) options_class = getattr(mod, pdata.optionclass) if category in (CATEGORY_BOOK, CATEGORY_CODE): - options_class(self.dbstate.db, name, category, - options_str_dict) + options_class( + self.dbstate.db, name, category, options_str_dict + ) else: - cl_report(self.dbstate.db, name, category, - report_class, options_class, - options_str_dict) + cl_report( + self.dbstate.db, + name, + category, + report_class, + options_class, + options_str_dict, + ) return # name exists, but is not in the list of valid report names msg = _("Unknown report name.") else: - msg = _("Report name not given. " - "Please use one of %(donottranslate)s=reportname" - ) % {'donottranslate' : '[-p|--options] name'} + msg = _( + "Report name not given. " + "Please use one of %(donottranslate)s=reportname" + ) % {"donottranslate": "[-p|--options] name"} print(_("%s\n Available names are:") % msg, file=sys.stderr) for pdata in sorted(_cl_list, key=lambda pdata: pdata.id.lower()): # Print cli report name ([item[0]), GUI report name (item[4]) if len(pdata.id) <= 25: - print(" %s%s- %s" % (pdata.id, - " " * (26 - len(pdata.id)), - pdata.name), - file=sys.stderr) + print( + " %s%s- %s" + % (pdata.id, " " * (26 - len(pdata.id)), pdata.name), + file=sys.stderr, + ) else: - print(" %s\t- %s" % (pdata.id, pdata.name), - file=sys.stderr) + print(" %s\t- %s" % (pdata.id, pdata.name), file=sys.stderr) elif action == "tool": from gramps.gui.plug import tool + try: - options_str_dict = dict([tuple(chunk.split('=')) - for chunk in options_str.split(',')]) + options_str_dict = dict( + [tuple(chunk.split("=")) for chunk in options_str.split(",")] + ) except: options_str_dict = {} - print(_("Ignoring invalid options string."), - file=sys.stderr) + print(_("Ignoring invalid options string."), file=sys.stderr) - name = options_str_dict.pop('name', None) + name = options_str_dict.pop("name", None) _cli_tool_list = pmgr.get_reg_tools(gui=False) if name: for pdata in _cli_tool_list: if name == pdata.id: mod = pmgr.load_plugin(pdata) if not mod: - #import of plugin failed + # import of plugin failed return category = pdata.category tool_class = getattr(mod, pdata.toolclass) options_class = getattr(mod, pdata.optionclass) - tool.cli_tool(dbstate=self.dbstate, - name=name, - category=category, - tool_class=tool_class, - options_class=options_class, - options_str_dict=options_str_dict, - user=self.user) + tool.cli_tool( + dbstate=self.dbstate, + name=name, + category=category, + tool_class=tool_class, + options_class=options_class, + options_str_dict=options_str_dict, + user=self.user, + ) return msg = _("Unknown tool name.") else: - msg = _("Tool name not given. " - "Please use one of %(donottranslate)s=toolname." - ) % {'donottranslate' : '[-p|--options] name'} + msg = _( + "Tool name not given. " + "Please use one of %(donottranslate)s=toolname." + ) % {"donottranslate": "[-p|--options] name"} print(_("%s\n Available names are:") % msg, file=sys.stderr) - for pdata in sorted(_cli_tool_list, - key=lambda pdata: pdata.id.lower()): + for pdata in sorted(_cli_tool_list, key=lambda pdata: pdata.id.lower()): # Print cli report name ([item[0]), GUI report name (item[4]) if len(pdata.id) <= 25: - print(" %s%s- %s" % (pdata.id, - " " * (26 - len(pdata.id)), - pdata.name), - file=sys.stderr) + print( + " %s%s- %s" + % (pdata.id, " " * (26 - len(pdata.id)), pdata.name), + file=sys.stderr, + ) else: - print(" %s\t- %s" % (pdata.id, pdata.name), - file=sys.stderr) + print(" %s\t- %s" % (pdata.id, pdata.name), file=sys.stderr) elif action == "book": try: options_str_dict = _split_options(options_str) except: options_str_dict = {} - print(_("Ignoring invalid options string."), - file=sys.stderr) + print(_("Ignoring invalid options string."), file=sys.stderr) - name = options_str_dict.pop('name', None) - book_list = BookList('books.xml', self.dbstate.db) + name = options_str_dict.pop("name", None) + book_list = BookList("books.xml", self.dbstate.db) if name: if name in book_list.get_book_names(): - cl_book(self.dbstate.db, name, book_list.get_book(name), - options_str_dict) + cl_book( + self.dbstate.db, + name, + book_list.get_book(name), + options_str_dict, + ) return msg = _("Unknown book name.") else: - msg = _("Book name not given. " - "Please use one of %(donottranslate)s=bookname." - ) % {'donottranslate' : '[-p|--options] name'} + msg = _( + "Book name not given. " + "Please use one of %(donottranslate)s=bookname." + ) % {"donottranslate": "[-p|--options] name"} print(_("%s\n Available names are:") % msg, file=sys.stderr) for name in sorted(book_list.get_book_names()): diff --git a/gramps/cli/argparser.py b/gramps/cli/argparser.py index 7ca738ab9d9..f4d4182af1a 100644 --- a/gramps/cli/argparser.py +++ b/gramps/cli/argparser.py @@ -30,11 +30,11 @@ Module responsible for handling the command line arguments for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import sys import os import getopt @@ -42,19 +42,29 @@ import shutil from glob import glob -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- -from gramps.gen.const import (LONGOPTS, SHORTOPTS, USER_PLUGINS, VERSION_DIR, - USER_CACHE, USER_CONFIG, USER_DATA, THUMB_DIR, - USER_CSS) +# ------------------------------------------------------------------------- +from gramps.gen.const import ( + LONGOPTS, + SHORTOPTS, + USER_PLUGINS, + VERSION_DIR, + USER_CACHE, + USER_CONFIG, + USER_DATA, + THUMB_DIR, + USER_CSS, +) from gramps.gen.utils.cast import get_type_converter from gramps.gen.const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -_HELP = _(""" +_HELP = _( + """ Usage: gramps [OPTION...] --load-modules=MODULE1,MODULE2,... Dynamic modules to load @@ -91,9 +101,11 @@ X - Books are cleared, reports and tool settings to default F - filters are cleared E - Everything is set to default or cleared -""") +""" +) -_USAGE = _(""" +_USAGE = _( + """ Example of usage of Gramps command line interface 1. To import four databases (whose formats can be determined from their names) @@ -136,11 +148,13 @@ Note: These examples are for bash shell. Syntax may be different for other shells and for Windows. -""") +""" +) -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # ArgParser -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ArgParser: """ This class is responsible for parsing the command line arguments (if any) @@ -231,9 +245,9 @@ def __init__(self, args): self.errors = [] self.parse_args() - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # Argument parser: sorts out given arguments - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def parse_args(self): """ Fill in lists with open, exports, imports, and actions options. @@ -241,14 +255,13 @@ def parse_args(self): Any errors are added to self.errors """ try: - options, leftargs = getopt.getopt(self.args[1:], - SHORTOPTS, LONGOPTS) + options, leftargs = getopt.getopt(self.args[1:], SHORTOPTS, LONGOPTS) except getopt.GetoptError as getopt_error: self.errors.append( self.construct_error( "Type gramps --help for an overview of " "commands, or read the manual pages.", - error=getopt_error + error=getopt_error, ) ) @@ -257,7 +270,7 @@ def parse_args(self): # Some args can work on a list of databases: if leftargs: for option, value in options: - if option in ['-L', '-l', '-t']: + if option in ["-L", "-l", "-t"]: self.database_names = leftargs leftargs = [] @@ -265,12 +278,10 @@ def parse_args(self): # if there were an argument without option, # use it as a file to open and return self.open_gui = leftargs[0] - print(_("Trying to open: %s ..." - ) % leftargs[0], - file=sys.stderr) - #see if force open is on + print(_("Trying to open: %s ...") % leftargs[0], file=sys.stderr) + # see if force open is on for option, value in options: - if option in ('-u', '--force-unlock'): + if option in ("-u", "--force-unlock"): self.force_unlock = True break return @@ -279,77 +290,81 @@ def parse_args(self): cleandbg = [] need_to_quit = False for opt_ix, (option, value) in enumerate(options): - if option in ['-O', '--open']: + if option in ["-O", "--open"]: self.open = value - elif option in ['-C', '--create']: + elif option in ["-C", "--create"]: self.create = value - elif option in ['-U', '--username']: + elif option in ["-U", "--username"]: self.username = value - elif option in ['-P', '--password']: + elif option in ["-P", "--password"]: self.password = value - elif option in ['-i', '--import']: + elif option in ["-i", "--import"]: family_tree_format = None - if (opt_ix < len(options) - 1 - and options[opt_ix + 1][0] in ('-f', '--format')): + if opt_ix < len(options) - 1 and options[opt_ix + 1][0] in ( + "-f", + "--format", + ): family_tree_format = options[opt_ix + 1][1] self.imports.append((value, family_tree_format)) - elif option in ['-r', '--remove']: + elif option in ["-r", "--remove"]: self.removes.append(value) - elif option in ['-e', '--export']: + elif option in ["-e", "--export"]: family_tree_format = None - if (opt_ix < len(options) - 1 - and options[opt_ix + 1][0] in ('-f', '--format')): + if opt_ix < len(options) - 1 and options[opt_ix + 1][0] in ( + "-f", + "--format", + ): family_tree_format = options[opt_ix + 1][1] abs_name = os.path.abspath(os.path.expanduser(value)) if not os.path.exists(abs_name): # The file doesn't exists, try to create it. try: - open(abs_name, 'w').close() + open(abs_name, "w").close() os.unlink(abs_name) except OSError as e: - message = _("WARNING: %(strerr)s " - "(errno=%(errno)s):\n" - "WARNING: %(name)s\n") % { - 'strerr' : e.strerror, - 'errno' : e.errno, - 'name' : e.filename} + message = _( + "WARNING: %(strerr)s " + "(errno=%(errno)s):\n" + "WARNING: %(name)s\n" + ) % {"strerr": e.strerror, "errno": e.errno, "name": e.filename} print(message) sys.exit(1) self.exports.append((value, family_tree_format)) - elif option in ['-a', '--action']: + elif option in ["-a", "--action"]: action = value - if action not in ('report', 'tool', 'book'): - print(_("Unknown action: %s. Ignoring." - ) % action, - file=sys.stderr) + if action not in ("report", "tool", "book"): + print(_("Unknown action: %s. Ignoring.") % action, file=sys.stderr) continue options_str = "" - if (opt_ix < len(options)-1 - and options[opt_ix+1][0] in ('-p', '--options')): - options_str = options[opt_ix+1][1] + if opt_ix < len(options) - 1 and options[opt_ix + 1][0] in ( + "-p", + "--options", + ): + options_str = options[opt_ix + 1][1] self.actions.append((action, options_str)) - elif option in ['-d', '--debug']: - print(_('setup debugging'), value, file=sys.stderr) + elif option in ["-d", "--debug"]: + print(_("setup debugging"), value, file=sys.stderr) logger = logging.getLogger(value) logger.setLevel(logging.DEBUG) cleandbg += [opt_ix] - elif option in ['-l']: + elif option in ["-l"]: self.list = True - elif option in ['-L']: + elif option in ["-L"]: self.list_more = True - elif option in ['-t']: + elif option in ["-t"]: self.list_table = True - elif option in ['-s', '--show']: + elif option in ["-s", "--show"]: from gramps.gen.config import config - print(_("Gramps config settings from %s:" - ) % config.filename) + + print(_("Gramps config settings from %s:") % config.filename) for sect, settings in config.data.items(): for settings_index, setting in settings.items(): print("%s.%s=%s" % (sect, settings_index, repr(value))) print() sys.exit(0) - elif option in ['-c', '--config']: + elif option in ["-c", "--config"]: from gramps.gen.config import config + cfg_name = value set_value = False if cfg_name: @@ -358,11 +373,11 @@ def parse_args(self): set_value = True if config.has_default(cfg_name): setting_value = config.get(cfg_name) - print(_("Current Gramps config setting: " - "%(name)s:%(value)s" - ) % {'name' : cfg_name, - 'value' : repr(setting_value)}, - file=sys.stderr) + print( + _("Current Gramps config setting: " "%(name)s:%(value)s") + % {"name": cfg_name, "value": repr(setting_value)}, + file=sys.stderr, + ) if set_value: # does a user want the default config value? if new_value in ("DEFAULT", _("DEFAULT")): @@ -372,81 +387,90 @@ def parse_args(self): new_value = converter(new_value) config.set(cfg_name, new_value) # Translators: indent "New" to match "Current" - print(_(" New Gramps config setting: " + print( + _( + " New Gramps config setting: " "%(name)s:%(value)s" - ) % {'name' : cfg_name, - 'value' : repr(config.get(cfg_name))}, - file=sys.stderr) + ) + % { + "name": cfg_name, + "value": repr(config.get(cfg_name)), + }, + file=sys.stderr, + ) else: need_to_quit = True else: - print(_("Gramps: no such config setting: '%s'" - ) % cfg_name, - file=sys.stderr) + print( + _("Gramps: no such config setting: '%s'") % cfg_name, + file=sys.stderr, + ) need_to_quit = True cleandbg += [opt_ix] - elif option in ['-h', '-?', '--help']: + elif option in ["-h", "-?", "--help"]: self.help = True - elif option in ['-u', '--force-unlock']: + elif option in ["-u", "--force-unlock"]: self.force_unlock = True - elif option in ['--usage']: + elif option in ["--usage"]: self.usage = True - elif option in ['-y', '--yes']: + elif option in ["-y", "--yes"]: self.auto_accept = True - elif option in ['-q', '--quiet']: + elif option in ["-q", "--quiet"]: self.quiet = True - elif option in ['-S', '--safe']: + elif option in ["-S", "--safe"]: cleandbg += [opt_ix] - elif option in ['-D', '--default']: + elif option in ["-D", "--default"]: + def rmtree(path): if os.path.isdir(path): shutil.rmtree(path, ignore_errors=True) - if 'E' in value or 'A' in value: # clear addons + if "E" in value or "A" in value: # clear addons rmtree(USER_PLUGINS) - if 'E' in value or 'P' in value: # clear ini preferences + if "E" in value or "P" in value: # clear ini preferences for fil in glob(os.path.join(VERSION_DIR, "*.*")): if "custom_filters.xml" in fil: continue os.remove(fil) # create gramps.ini so config won't load the one from an # older version of Gramps. - with open(os.path.join(VERSION_DIR, 'gramps.ini'), 'w'): + with open(os.path.join(VERSION_DIR, "gramps.ini"), "w"): pass - if 'E' in value or 'F' in value: # clear filters + if "E" in value or "F" in value: # clear filters fil = os.path.join(VERSION_DIR, "custom_filters.xml") if os.path.isfile(fil): os.remove(fil) - if 'E' in value or 'X' in value: # clear xml reports/tools + if "E" in value or "X" in value: # clear xml reports/tools for fil in glob(os.path.join(USER_DATA, "*.xml")): os.remove(fil) - if 'E' in value or 'Z' in value: # clear upgrade zips + if "E" in value or "Z" in value: # clear upgrade zips for fil in glob(os.path.join(USER_DATA, "*.zip")): os.remove(fil) - if 'E' in value: # Everything else + if "E" in value: # Everything else rmtree(THUMB_DIR) rmtree(USER_CSS) rmtree(os.path.join(USER_CACHE, "maps")) - for fil in (glob(os.path.join(USER_CACHE, "*")) - + glob(os.path.join(USER_CONFIG, "*")) - + glob(os.path.join(USER_DATA, "*"))): + for fil in ( + glob(os.path.join(USER_CACHE, "*")) + + glob(os.path.join(USER_CONFIG, "*")) + + glob(os.path.join(USER_DATA, "*")) + ): if os.path.isfile(fil): os.remove(fil) sys.exit(0) # Done with Default - #clean options list + # clean options list cleandbg.reverse() for ind in cleandbg: del options[ind] - if (len(options) > 0 - and self.open is None - and self.imports == [] - and self.removes == [] - and not (self.list - or self.list_more - or self.list_table - or self.help)): + if ( + len(options) > 0 + and self.open is None + and self.imports == [] + and self.removes == [] + and not (self.list or self.list_more or self.list_table or self.help) + ): self.errors.append( self.construct_error( "To use in the command-line mode, supply at " @@ -469,20 +493,19 @@ def construct_error(self, suggestion_message, error=None): translated_message = _(error_message + suggestion_message) % cli_args if error: - translated_message = str(error) + '\n' + translated_message - - return _('Error parsing the arguments'), translated_message + translated_message = str(error) + "\n" + translated_message + return _("Error parsing the arguments"), translated_message - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # Determine the need for GUI - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def need_gui(self): """ Determine whether we need a GUI session for the given tasks. """ if self.errors: - #errors in argument parsing ==> give cli error, no gui needed + # errors in argument parsing ==> give cli error, no gui needed return False if len(self.removes) > 0: @@ -501,9 +524,9 @@ def need_gui(self): # have both data and what to do with it => no GUI return False elif self.create: - if self.open: # create an empty DB, open a GUI to fill it + if self.open: # create an empty DB, open a GUI to fill it return True - else: # create a DB, then do the import, with no GUI + else: # create a DB, then do the import, with no GUI self.open = self.create return False else: diff --git a/gramps/cli/clidbman.py b/gramps/cli/clidbman.py index 6ff9347dc2b..ddaadaae8c5 100644 --- a/gramps/cli/clidbman.py +++ b/gramps/cli/clidbman.py @@ -25,11 +25,11 @@ creating, and deleting of databases. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import re import os import sys @@ -40,61 +40,66 @@ import tempfile import logging -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from gramps.gen.plug import BasePluginManager from gramps.gen.config import config from gramps.gen.constfunc import win from gramps.gen.db.dbconst import DBLOGNAME, DBBACKEND from gramps.gen.db.utils import make_database, get_dbid_from_path from gramps.gen.const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- LOG = logging.getLogger(".clidbman") _LOG = logging.getLogger(DBLOGNAME) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # constants # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- DEFAULT_TITLE = _("Family Tree") NAME_FILE = "name.txt" META_NAME = "meta_data.db" -UNAVAILABLE = _('Unavailable') +UNAVAILABLE = _("Unavailable") + -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # functions # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- def _errordialog(title, errormessage): """ Show the error. A title for the error and an errormessage """ - print(_('ERROR: %(title)s \n %(message)s') % { - 'title': title, - 'message': errormessage}) + print( + _("ERROR: %(title)s \n %(message)s") + % {"title": title, "message": errormessage} + ) sys.exit() -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # CLIDbManager # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class CLIDbManager: """ Database manager without GTK functionality, allows users to create and open databases """ + IND_NAME = 0 IND_PATH = 1 IND_PATH_NAMEFILE = 2 @@ -109,13 +114,14 @@ class CLIDbManager: ICON_OPEN = 3 ICON_MAP = { - ICON_NONE : None, - ICON_RECOVERY : None, - ICON_LOCK : None, - ICON_OPEN : None, - } + ICON_NONE: None, + ICON_RECOVERY: None, + ICON_LOCK: None, + ICON_OPEN: None, + } ERROR = _errordialog + def __init__(self, dbstate): self.dbstate = dbstate self.msg = None @@ -166,12 +172,15 @@ def get_dbdir_summary(self, dirpath, name): retval = {_("Unavailable"): str(msg)[:74] + "..."} else: retval = {_("Unavailable"): "locked"} - retval.update({_("Family Tree"): name, - _("Path"): dirpath, - _("Database"): self.get_backend_name_from_dbid(dbid), - _("Last accessed"): time_val(dirpath)[1], - _("Locked?"): self.is_locked(dirpath), - }) + retval.update( + { + _("Family Tree"): name, + _("Path"): dirpath, + _("Database"): self.get_backend_name_from_dbid(dbid), + _("Last accessed"): time_val(dirpath)[1], + _("Locked?"): self.is_locked(dirpath), + } + ) return retval def get_backend_name_from_dbid(self, dbid): @@ -185,22 +194,34 @@ def print_family_tree_summaries(self, database_names=None): """ Prints a detailed list of the known family trees. """ - print(_('Gramps Family Trees:')) + print(_("Gramps Family Trees:")) for item in self.current_names: - (name, dirpath, path_name, last, - tval, enable, stock_id, backend_type) = item - if (database_names is None or - any([(re.match("^" + dbname + "$", name) or - dbname == name) - for dbname in database_names])): + ( + name, + dirpath, + path_name, + last, + tval, + enable, + stock_id, + backend_type, + ) = item + if database_names is None or any( + [ + (re.match("^" + dbname + "$", name) or dbname == name) + for dbname in database_names + ] + ): summary = self.get_dbdir_summary(dirpath, name) print(_('Family Tree "%s":') % summary[_("Family Tree")]) for item in sorted(summary): if item != "Family Tree": # Translators: needed for French, ignore otherwise - print(' ' + _("%(str1)s: %(str2)s" - ) % {'str1' : item, - 'str2' : summary[item]}) + print( + " " + + _("%(str1)s: %(str2)s") + % {"str1": item, "str2": summary[item]} + ) def family_tree_summary(self, database_names=None): """ @@ -209,12 +230,22 @@ def family_tree_summary(self, database_names=None): # make the default directory if it does not exist summary_list = [] for item in self.current_names: - (name, dirpath, path_name, last, - tval, enable, stock_id, backend_type) = item - if (database_names is None or - any([(re.match("^" + dbname + "$", name) or - dbname == name) - for dbname in database_names])): + ( + name, + dirpath, + path_name, + last, + tval, + enable, + stock_id, + backend_type, + ) = item + if database_names is None or any( + [ + (re.match("^" + dbname + "$", name) or dbname == name) + for dbname in database_names + ] + ): retval = self.get_dbdir_summary(dirpath, name) summary_list.append(retval) return summary_list @@ -224,7 +255,7 @@ def _populate_cli(self): Get the list of current names in the database dir """ # make the default directory if it does not exist - dbdir = os.path.expanduser(config.get('database.path')) + dbdir = os.path.expanduser(config.get("database.path")) db_ok = make_dbdir(dbdir) self.current_names = [] @@ -234,19 +265,29 @@ def _populate_cli(self): path_name = os.path.join(dirpath, NAME_FILE) backend_type = get_dbid_from_path(dirpath) if os.path.isfile(path_name): - with open(path_name, 'r', encoding='utf8') as file: + with open(path_name, "r", encoding="utf8") as file: name = file.readline().strip() (tval, last) = time_val(dirpath) (enable, stock_id) = self.icon_values( - dirpath, self.active, self.dbstate.is_open()) + dirpath, self.active, self.dbstate.is_open() + ) - if stock_id == 'gramps-lock': + if stock_id == "gramps-lock": last = find_locker_name(dirpath) self.current_names.append( - (name, os.path.join(dbdir, dpath), path_name, - last, tval, enable, stock_id, backend_type)) + ( + name, + os.path.join(dbdir, dpath), + path_name, + last, + tval, + enable, + stock_id, + backend_type, + ) + ) self.current_names.sort() @@ -271,13 +312,13 @@ def __start_cursor(self, msg): """ Do needed things to start import visually, eg busy cursor """ - print(_('Starting Import, %s') % msg) + print(_("Starting Import, %s") % msg) def __end_cursor(self): """ Set end of a busy cursor """ - print(_('Import finished...')) + print(_("Import finished...")) def create_new_db_cli(self, title=None, create_db=True, dbid=None): """ @@ -292,22 +333,23 @@ def create_new_db_cli(self, title=None, create_db=True, dbid=None): name_list = [name[0] for name in self.current_names] title = find_next_db_name(name_list) - with open(path_name, "w", encoding='utf8') as name_file: + with open(path_name, "w", encoding="utf8") as name_file: name_file.write(title) if create_db: if dbid is None: - dbid = config.get('database.backend') + dbid = config.get("database.backend") newdb = make_database(dbid) backend_path = os.path.join(new_path, DBBACKEND) - with open(backend_path, "w", encoding='utf8') as backend_file: + with open(backend_path, "w", encoding="utf8") as backend_file: backend_file.write(dbid) (tval, last) = time_val(new_path) - self.current_names.append((title, new_path, path_name, - last, tval, False, "", dbid)) + self.current_names.append( + (title, new_path, path_name, last, tval, False, "", dbid) + ) return new_path, title def _create_new_db(self, title=None, dbid=None, edit_entry=False): @@ -340,7 +382,7 @@ def import_new_db(self, filename, user): if url.scheme == "file": filename = url2pathname(filename[7:]) else: - url_fp = urlopen(filename) # open URL + url_fp = urlopen(filename) # open URL # make a temp local file: ext = os.path.splitext(url.path)[1] fd, filename = tempfile.mkstemp(suffix=ext) @@ -357,10 +399,8 @@ def import_new_db(self, filename, user): for plugin in pmgr.get_import_plugins(): if format == plugin.get_extension(): - - dbid = config.get('database.backend') - new_path, name = self._create_new_db(name, dbid=dbid, - edit_entry=False) + dbid = config.get("database.backend") + new_path, name = self._create_new_db(name, dbid=dbid, edit_entry=False) # Create a new database self.__start_cursor(_("Importing data...")) @@ -406,35 +446,37 @@ def remove_database(self, dbname, user=None): Deletes a database folder given a pattenr that matches its proper name. """ - dbdir = os.path.expanduser(config.get('database.path')) + dbdir = os.path.expanduser(config.get("database.path")) match_list = [] for dpath in os.listdir(dbdir): dirpath = os.path.join(dbdir, dpath) path_name = os.path.join(dirpath, NAME_FILE) if os.path.isfile(path_name): - with open(path_name, 'r', encoding='utf8') as file: + with open(path_name, "r", encoding="utf8") as file: name = file.readline().strip() if re.match("^" + dbname + "$", name) or dbname == name: match_list.append((name, dirpath)) if len(match_list) == 0: - CLIDbManager.ERROR("Family tree not found", - "No matching family tree found: '%s'" % dbname) + CLIDbManager.ERROR( + "Family tree not found", "No matching family tree found: '%s'" % dbname + ) # now delete them: - for (name, directory) in match_list: + for name, directory in match_list: if user is None or user.prompt( - _('Remove family tree warning'), - _('Are you sure you want to remove ' - 'the family tree named\n"%s"?' - ) % name, - _('yes'), _('no'), default_label=_('no')): + _("Remove family tree warning"), + _("Are you sure you want to remove " 'the family tree named\n"%s"?') + % name, + _("yes"), + _("no"), + default_label=_("no"), + ): try: - for (top, dirs, files) in os.walk(directory): + for top, dirs, files in os.walk(directory): for filename in files: os.unlink(os.path.join(top, filename)) os.rmdir(directory) except (IOError, OSError) as msg: - CLIDbManager.ERROR(_("Could not delete Family Tree"), - str(msg)) + CLIDbManager.ERROR(_("Could not delete Family Tree"), str(msg)) def rename_database(self, filepath, new_text): """ @@ -442,9 +484,9 @@ def rename_database(self, filepath, new_text): Returns old_name, new_name if success, None, None if no success """ try: - with open(filepath, "r", encoding='utf8') as name_file: + with open(filepath, "r", encoding="utf8") as name_file: old_text = name_file.read() - with open(filepath, "w", encoding='utf8') as name_file: + with open(filepath, "w", encoding="utf8") as name_file: name_file.write(new_text) except (OSError, IOError) as msg: CLIDbManager.ERROR(_("Could not rename Family Tree"), str(msg)) @@ -472,6 +514,7 @@ def icon_values(self, dirpath, active, is_open): else: return (False, self.ICON_MAP[self.ICON_NONE]) + def make_dbdir(dbdir): """ Create the default database directory, as defined by dbdir @@ -480,13 +523,18 @@ def make_dbdir(dbdir): if not os.path.isdir(dbdir): os.makedirs(dbdir) except (IOError, OSError) as msg: - LOG.error(_("\nERROR: Wrong database path in Edit Menu->Preferences.\n" - "Open preferences and set correct database path.\n\n" - "Details: Could not make database directory:\n %s\n\n"), - str(msg)) + LOG.error( + _( + "\nERROR: Wrong database path in Edit Menu->Preferences.\n" + "Open preferences and set correct database path.\n\n" + "Details: Could not make database directory:\n %s\n\n" + ), + str(msg), + ) return False return True + def find_next_db_name(name_list): """ Scan the name list, looking for names that do not yet exist. @@ -499,6 +547,7 @@ def find_next_db_name(name_list): return title i += 1 + def find_next_db_dir(): """ Searches the default directory for the first available default @@ -507,12 +556,13 @@ def find_next_db_dir(): """ while True: base = "%x" % int(time.time()) - dbdir = os.path.expanduser(config.get('database.path')) + dbdir = os.path.expanduser(config.get("database.path")) new_path = os.path.join(dbdir, base) if not os.path.isdir(new_path): break return new_path + def time_val(dirpath): """ Return the last modified time of the database. We do this by looking @@ -529,12 +579,13 @@ def time_val(dirpath): tval_mod = os.stat(meta)[8] if tval_mod > tval: tval = tval_mod - last = time.strftime('%x %X', time.localtime(tval)) + last = time.strftime("%x %X", time.localtime(tval)) else: tval = 0 last = _("Never") return (tval, last) + def find_locker_name(dirpath): """ Opens the lock file if it exists, reads the contexts which is "USERNAME" @@ -545,7 +596,7 @@ def find_locker_name(dirpath): """ try: fname = os.path.join(dirpath, "lock") - with open(fname, 'r', encoding='utf8') as ifile: + with open(fname, "r", encoding="utf8") as ifile: username = ifile.read().strip() # feature request 2356: avoid genitive form last = _("Locked by %s") % username diff --git a/gramps/cli/grampscli.py b/gramps/cli/grampscli.py index 7106eba61d7..3a48998b8d5 100644 --- a/gramps/cli/grampscli.py +++ b/gramps/cli/grampscli.py @@ -26,12 +26,13 @@ Provides also two small base classes: :class:`CLIDbLoader`, :class:`CLIManager` """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from gramps.gen.const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext import os import sys @@ -39,11 +40,11 @@ import logging LOG = logging.getLogger(".grampscli") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from gramps.gen.display.name import displayer as name_displayer from gramps.gen.config import config from gramps.gen.const import PLUGINS_DIR, USER_PLUGINS @@ -51,26 +52,30 @@ from gramps.gen.db.utils import make_database from gramps.gen.errors import DbError from gramps.gen.dbstate import DbState -from gramps.gen.db.exceptions import (DbUpgradeRequiredError, - DbSupportedError, - DbVersionError, - DbPythonError, - DbConnectionError) +from gramps.gen.db.exceptions import ( + DbUpgradeRequiredError, + DbSupportedError, + DbVersionError, + DbPythonError, + DbConnectionError, +) from gramps.gen.plug import BasePluginManager from gramps.gen.utils.config import get_researcher from gramps.gen.recentfiles import recent_files from gramps.gen.filters import reload_custom_filters -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # CLI DbLoader class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class CLIDbLoader: """ Base class for Db loading action inside a :class:`.DbState`. Only the minimum is present needed for CLI handling """ + def __init__(self, dbstate): self.dbstate = dbstate @@ -78,14 +83,14 @@ def _warn(self, title, warnmessage): """ Issue a warning message. Inherit for GUI action """ - print(_('WARNING: %s') % warnmessage, file=sys.stderr) + print(_("WARNING: %s") % warnmessage, file=sys.stderr) def _errordialog(self, title, errormessage): """ Show the error. A title for the error and an errormessage Inherit for GUI action """ - print(_('ERROR: %s') % errormessage, file=sys.stderr) + print(_("ERROR: %s") % errormessage, file=sys.stderr) sys.exit(1) def _dberrordialog(self, msg): @@ -98,14 +103,18 @@ def _dberrordialog(self, msg): .. note:: Inherit for GUI action """ self._errordialog( - '', + "", _("Low level database corruption detected") - + '\n' + - _("Gramps has detected a problem in the underlying " - "database. This can sometimes be repaired from " - "the Family Tree Manager. Select the database and " - 'click on the Repair button' - ) + '\n\n' + str(msg)) + + "\n" + + _( + "Gramps has detected a problem in the underlying " + "database. This can sometimes be repaired from " + "the Family Tree Manager. Select the database and " + "click on the Repair button" + ) + + "\n\n" + + str(msg), + ) def _begin_progress(self): """ @@ -146,13 +155,14 @@ def read_file(self, filename, username, password): if os.path.exists(filename): if not os.access(filename, os.W_OK): mode = "r" - self._warn(_('Read only database'), - _('You do not have write access ' - 'to the selected file.')) + self._warn( + _("Read only database"), + _("You do not have write access " "to the selected file."), + ) else: mode = "w" else: - mode = 'w' + mode = "w" dbid_path = os.path.join(filename, DBBACKEND) if os.path.isfile(dbid_path): @@ -169,16 +179,26 @@ def read_file(self, filename, username, password): self._begin_progress() try: - self.dbstate.db.load(filename, self._pulse_progress, mode, - username=username, password=password) - except (DbConnectionError, DbSupportedError, DbUpgradeRequiredError, - DbVersionError, DbPythonError, DbConnectionError) as msg: + self.dbstate.db.load( + filename, + self._pulse_progress, + mode, + username=username, + password=password, + ) + except ( + DbConnectionError, + DbSupportedError, + DbUpgradeRequiredError, + DbVersionError, + DbPythonError, + DbConnectionError, + ) as msg: self.dbstate.no_database() self._errordialog(_("Cannot open database"), str(msg)) except OSError as msg: self.dbstate.no_database() - self._errordialog( - _("Could not open file: %s") % filename, str(msg)) + self._errordialog(_("Could not open file: %s") % filename, str(msg)) except DbError as msg: self.dbstate.no_database() self._dberrordialog(msg) @@ -187,11 +207,13 @@ def read_file(self, filename, username, password): LOG.error("Failed to open database.", exc_info=True) return True -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # CLIManager class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- + class CLIManager: """ @@ -201,6 +223,7 @@ class CLIManager: Aim is to manage a dbstate on which to work (load, unload), and interact with the plugin session """ + def __init__(self, dbstate, setloader, user): self.dbstate = dbstate if setloader: @@ -221,7 +244,7 @@ def _errordialog(self, title, errormessage): """ Show the error. A title for the error and an errormessage """ - print(_('ERROR: %s') % errormessage, file=sys.stderr) + print(_("ERROR: %s") % errormessage, file=sys.stderr) sys.exit(1) def _read_recent_file(self, filename, username=None, password=None): @@ -232,29 +255,33 @@ def _read_recent_file(self, filename, username=None, password=None): # If not, do nothing, just return. # This can be handled better if family tree delete/rename # also updated the recent file menu info in displaystate.py - if not os.path.isdir(filename): + if not os.path.isdir(filename): self._errordialog( _("Could not load a recent Family Tree."), - _("Family Tree does not exist, as it has been deleted.")) + _("Family Tree does not exist, as it has been deleted."), + ) return if os.path.isfile(os.path.join(filename, "lock")): self._errordialog( _("The database is locked."), - _("Use the --force-unlock option if you are sure " - "that the database is not in use.")) + _( + "Use the --force-unlock option if you are sure " + "that the database is not in use." + ), + ) return if self.db_loader.read_file(filename, username, password): # Attempt to figure out the database title path = os.path.join(filename, "name.txt") try: - with open(path, encoding='utf8') as ifile: + with open(path, encoding="utf8") as ifile: title = ifile.readline().strip() except: title = filename - self._post_load_newdb(filename, 'x-directory/normal', title) + self._post_load_newdb(filename, "x-directory/normal", title) def _post_load_newdb(self, filename, filetype, title=None): """ @@ -283,20 +310,18 @@ def _post_load_newdb_nongui(self, filename, title=None): # If the DB Owner Info is empty and # [default] Researcher is not empty and # database is empty, then copy default researcher to DB owner - if (res.is_empty() - and not owner.is_empty() - and self.dbstate.db.get_total() == 0): + if res.is_empty() and not owner.is_empty() and self.dbstate.db.get_total() == 0: self.dbstate.db.set_researcher(owner) name_displayer.clear_custom_formats() name_displayer.set_name_format(self.dbstate.db.name_formats) - fmt_default = config.get('preferences.name-format') + fmt_default = config.get("preferences.name-format") name_displayer.set_default_format(fmt_default) self.dbstate.db.enable_signals() self.dbstate.signal_change() - config.set('paths.recent-file', filename) + config.set("paths.recent-file", filename) recent_files(filename, name) self.file_loaded = True @@ -310,6 +335,7 @@ def do_reg_plugins(self, dbstate, uistate, rescan=False): if rescan: # supports updated plugin installs self._pmgr.reload_plugins() + def startcli(errors, argparser): """ Starts a cli session of Gramps. @@ -318,34 +344,35 @@ def startcli(errors, argparser): :param argparser: :class:`.ArgParser` instance """ if errors: - #already errors encountered. Show first one on terminal and exit - errmsg = _('Error encountered: %s') % errors[0][0] + # already errors encountered. Show first one on terminal and exit + errmsg = _("Error encountered: %s") % errors[0][0] print(errmsg, file=sys.stderr) - errmsg = _(' Details: %s') % errors[0][1] + errmsg = _(" Details: %s") % errors[0][1] print(errmsg, file=sys.stderr) sys.exit(1) if argparser.errors: - errmsg = _('Error encountered in argument parsing: %s' - ) % argparser.errors[0][0] + errmsg = _("Error encountered in argument parsing: %s") % argparser.errors[0][0] print(errmsg, file=sys.stderr) - errmsg = _(' Details: %s') % argparser.errors[0][1] + errmsg = _(" Details: %s") % argparser.errors[0][1] print(errmsg, file=sys.stderr) sys.exit(1) - #we need to keep track of the db state + # we need to keep track of the db state dbstate = DbState() - #we need a manager for the CLI session + # we need a manager for the CLI session from .user import User + user = User(auto_accept=argparser.auto_accept, quiet=argparser.quiet) climanager = CLIManager(dbstate, True, user) - #load the plugins + # load the plugins climanager.do_reg_plugins(dbstate, uistate=None) reload_custom_filters() # handle the arguments from .arghandler import ArgHandler + handler = ArgHandler(dbstate, argparser, climanager) # create a manager to manage the database diff --git a/gramps/cli/plug/__init__.py b/gramps/cli/plug/__init__.py index c687a26ddd3..fb02ede32d5 100644 --- a/gramps/cli/plug/__init__.py +++ b/gramps/cli/plug/__init__.py @@ -28,50 +28,75 @@ """ Enable report generation from the command line interface (CLI) """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import traceback import os import sys import logging + LOG = logging.getLogger(".") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from gramps.gen.plug import BasePluginManager -from gramps.gen.plug.docgen import (StyleSheet, StyleSheetList, PaperStyle, - PAPER_PORTRAIT, PAPER_LANDSCAPE, graphdoc, - treedoc) -from gramps.gen.plug.menu import (FamilyOption, PersonOption, NoteOption, - MediaOption, PersonListOption, NumberOption, - BooleanOption, DestinationOption, Option, - TextOption, EnumeratedListOption, - StringOption) +from gramps.gen.plug.docgen import ( + StyleSheet, + StyleSheetList, + PaperStyle, + PAPER_PORTRAIT, + PAPER_LANDSCAPE, + graphdoc, + treedoc, +) +from gramps.gen.plug.menu import ( + FamilyOption, + PersonOption, + NoteOption, + MediaOption, + PersonListOption, + NumberOption, + BooleanOption, + DestinationOption, + Option, + TextOption, + EnumeratedListOption, + StringOption, +) from gramps.gen.display.name import displayer as name_displayer from gramps.gen.errors import ReportError, FilterError -from gramps.gen.plug.report import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK, - CATEGORY_GRAPHVIZ, CATEGORY_TREE, - CATEGORY_CODE, ReportOptions, append_styles) +from gramps.gen.plug.report import ( + CATEGORY_TEXT, + CATEGORY_DRAW, + CATEGORY_BOOK, + CATEGORY_GRAPHVIZ, + CATEGORY_TREE, + CATEGORY_CODE, + ReportOptions, + append_styles, +) from gramps.gen.plug.report._paper import paper_sizes from gramps.gen.const import USER_HOME, DOCGEN_OPTIONS from gramps.gen.dbstate import DbState from ..grampscli import CLIManager from ..user import User from gramps.gen.const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # Private Functions # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ def _convert_str_to_match_type(str_val, type_val): """ Returns a value representing str_val that is the same type as type_val. @@ -80,8 +105,9 @@ def _convert_str_to_match_type(str_val, type_val): ret_type = type(type_val) if isinstance(type_val, str): - if ((str_val.startswith("'") and str_val.endswith("'")) - or (str_val.startswith('"') and str_val.endswith('"'))): + if (str_val.startswith("'") and str_val.endswith("'")) or ( + str_val.startswith('"') and str_val.endswith('"') + ): # Remove enclosing quotes return str(str_val[1:-1]) else: @@ -141,6 +167,7 @@ def _convert_str_to_match_type(str_val, type_val): return ret_val + def _validate_options(options, dbase): """ Validate all options by making sure that their values are consistent with @@ -168,8 +195,7 @@ def _validate_options(options, dbase): phandle = None person = dbase.get_person_from_handle(phandle) if not person: - print(_("ERROR: Please specify a person"), - file=sys.stderr) + print(_("ERROR: Please specify a person"), file=sys.stderr) if person: option.set_value(person.get_gramps_id()) @@ -195,19 +221,20 @@ def _validate_options(options, dbase): else: print(_("ERROR: Please specify a family"), file=sys.stderr) -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # Command-line report # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class CommandLineReport: """ Provide a way to generate report from the command line. """ - def __init__(self, database, name, category, option_class, options_str_dict, - noopt=False): - + def __init__( + self, database, name, category, option_class, options_str_dict, noopt=False + ): pmgr = BasePluginManager.get_instance() self.__textdoc_plugins = [] self.__drawdoc_plugins = [] @@ -217,15 +244,17 @@ def __init__(self, database, name, category, option_class, options_str_dict, self.__textdoc_plugins.append(plugin) if plugin.get_draw_support() and plugin.get_extension(): self.__drawdoc_plugins.append(plugin) - if (plugin.get_extension() - and plugin.get_text_support() - and plugin.get_draw_support()): + if ( + plugin.get_extension() + and plugin.get_text_support() + and plugin.get_draw_support() + ): self.__bookdoc_plugins.append(plugin) self.database = database self.category = category - self.options_dict = None # keep pylint happy + self.options_dict = None # keep pylint happy self.options_help = None self.paper = None self.orien = None @@ -249,8 +278,9 @@ def __init__(self, database, name, category, option_class, options_str_dict, self.__gvoptions.add_menu_options(menu) for name in menu.get_all_option_names(): if name not in self.option_class.options_dict: - self.option_class.options_dict[ - name] = menu.get_option_by_name(name).get_value() + self.option_class.options_dict[name] = menu.get_option_by_name( + name + ).get_value() if category == CATEGORY_TREE: # Need to include Genealogy Tree options self.__toptions = treedoc.TreeOptions() @@ -258,11 +288,12 @@ def __init__(self, database, name, category, option_class, options_str_dict, self.__toptions.add_menu_options(menu) for name in menu.get_all_option_names(): if name not in self.option_class.options_dict: - self.option_class.options_dict[ - name] = menu.get_option_by_name(name).get_value() + self.option_class.options_dict[name] = menu.get_option_by_name( + name + ).get_value() self.option_class.load_previous_values() _validate_options(self.option_class, database) - self.show = options_str_dict.pop('show', None) + self.show = options_str_dict.pop("show", None) self.options_str_dict = options_str_dict self.init_standard_options(noopt) @@ -276,76 +307,76 @@ def init_standard_options(self, noopt): Initialize the options that are hard-coded into the report system. """ self.options_dict = { - 'of' : self.option_class.handler.module_name, - 'off' : self.option_class.handler.get_format_name(), - 'style' : - self.option_class.handler.get_default_stylesheet_name(), - 'papers' : self.option_class.handler.get_paper_name(), - 'papero' : self.option_class.handler.get_orientation(), - 'paperml' : self.option_class.handler.get_margins()[0], - 'papermr' : self.option_class.handler.get_margins()[1], - 'papermt' : self.option_class.handler.get_margins()[2], - 'papermb' : self.option_class.handler.get_margins()[3], - 'css' : self.option_class.handler.get_css_filename(), - } + "of": self.option_class.handler.module_name, + "off": self.option_class.handler.get_format_name(), + "style": self.option_class.handler.get_default_stylesheet_name(), + "papers": self.option_class.handler.get_paper_name(), + "papero": self.option_class.handler.get_orientation(), + "paperml": self.option_class.handler.get_margins()[0], + "papermr": self.option_class.handler.get_margins()[1], + "papermt": self.option_class.handler.get_margins()[2], + "papermb": self.option_class.handler.get_margins()[3], + "css": self.option_class.handler.get_css_filename(), + } self.options_help = { - 'of' : [_("=filename"), - _("Output file name. MANDATORY"), ""], - 'off' : [_("=format"), _("Output file format."), []], - 'style' : [_("=name"), _("Style name."), ""], - 'papers' : [_("=name"), _("Paper size name."), ""], - 'papero' : [_("=number"), _("Paper orientation number."), ""], - 'paperml' : [_("=number"), - _("Left paper margin"), _("Size in cm")], - 'papermr' : [_("=number"), - _("Right paper margin"), _("Size in cm")], - 'papermt' : [_("=number"), - _("Top paper margin"), _("Size in cm")], - 'papermb' : [_("=number"), - _("Bottom paper margin"), _("Size in cm")], - 'css' : [_("=css filename"), - _("CSS filename to use, html format only"), ""], - } + "of": [_("=filename"), _("Output file name. MANDATORY"), ""], + "off": [_("=format"), _("Output file format."), []], + "style": [_("=name"), _("Style name."), ""], + "papers": [_("=name"), _("Paper size name."), ""], + "papero": [_("=number"), _("Paper orientation number."), ""], + "paperml": [_("=number"), _("Left paper margin"), _("Size in cm")], + "papermr": [_("=number"), _("Right paper margin"), _("Size in cm")], + "papermt": [_("=number"), _("Top paper margin"), _("Size in cm")], + "papermb": [_("=number"), _("Bottom paper margin"), _("Size in cm")], + "css": [_("=css filename"), _("CSS filename to use, html format only"), ""], + } if noopt: return - self.options_help['of'][2] = os.path.join(USER_HOME, - "whatever_name") + self.options_help["of"][2] = os.path.join(USER_HOME, "whatever_name") if self.category == CATEGORY_TEXT: for plugin in self.__textdoc_plugins: - self.options_help['off'][2].append( - plugin.get_extension() + "\t" + plugin.get_description()) + self.options_help["off"][2].append( + plugin.get_extension() + "\t" + plugin.get_description() + ) elif self.category == CATEGORY_DRAW: for plugin in self.__drawdoc_plugins: - self.options_help['off'][2].append( - plugin.get_extension() + "\t" + plugin.get_description()) + self.options_help["off"][2].append( + plugin.get_extension() + "\t" + plugin.get_description() + ) elif self.category == CATEGORY_BOOK: for plugin in self.__bookdoc_plugins: - self.options_help['off'][2].append( - plugin.get_extension() + "\t" + plugin.get_description()) + self.options_help["off"][2].append( + plugin.get_extension() + "\t" + plugin.get_description() + ) elif self.category == CATEGORY_GRAPHVIZ: for graph_format in graphdoc.FORMATS: - self.options_help['off'][2].append( - graph_format["type"] + "\t" + graph_format["descr"]) + self.options_help["off"][2].append( + graph_format["type"] + "\t" + graph_format["descr"] + ) elif self.category == CATEGORY_TREE: for tree_format in treedoc.FORMATS: - self.options_help['off'][2].append( - tree_format["type"] + "\t" + tree_format["descr"]) + self.options_help["off"][2].append( + tree_format["type"] + "\t" + tree_format["descr"] + ) else: - self.options_help['off'][2] = "NA" + self.options_help["off"][2] = "NA" - self.options_help['papers'][2] = [ - paper.get_name() for paper in paper_sizes - if paper.get_name() != 'Custom Size'] + self.options_help["papers"][2] = [ + paper.get_name() + for paper in paper_sizes + if paper.get_name() != "Custom Size" + ] - self.options_help['papero'][2] = ["%d\tPortrait" % PAPER_PORTRAIT, - "%d\tLandscape" % PAPER_LANDSCAPE] + self.options_help["papero"][2] = [ + "%d\tPortrait" % PAPER_PORTRAIT, + "%d\tLandscape" % PAPER_LANDSCAPE, + ] - self.options_help['css'][2] = os.path.join(USER_HOME, - "whatever_name.css") + self.options_help["css"][2] = os.path.join(USER_HOME, "whatever_name.css") if self.category in (CATEGORY_TEXT, CATEGORY_DRAW): default_style = StyleSheet() @@ -355,20 +386,19 @@ def init_standard_options(self, noopt): style_file = self.option_class.handler.get_stylesheet_savefile() self.style_list = StyleSheetList(style_file, default_style) - self.options_help['style'][2] = self.style_list.get_style_names() + self.options_help["style"][2] = self.style_list.get_style_names() def init_report_options(self): """ Initialize the options that are defined by each report. """ - if self.category == CATEGORY_BOOK: # a Book Report has no "menu" + if self.category == CATEGORY_BOOK: # a Book Report has no "menu" for key in self.option_class.options_dict: self.options_dict[key] = self.option_class.options_dict[key] - self.options_help[ - key] = self.option_class.options_help[key][:3] + self.options_help[key] = self.option_class.options_help[key][:3] # a Book Report can't have HTML output so "css" is meaningless - self.options_dict.pop('css') + self.options_dict.pop("css") if not hasattr(self.option_class, "menu"): return @@ -393,9 +423,10 @@ def init_report_options_help(self): id_list = [] for person_handle in self.database.get_person_handles(True): person = self.database.get_person_from_handle(person_handle) - id_list.append("%s\t%s" - % (person.get_gramps_id(), - name_displayer.display(person))) + id_list.append( + "%s\t%s" + % (person.get_gramps_id(), name_displayer.display(person)) + ) self.options_help[name].append(id_list) elif isinstance(option, FamilyOption): id_list = [] @@ -413,9 +444,11 @@ def init_report_options_help(self): if father: fname = name_displayer.display(father) # Translators: needed for French, Hebrew and Arabic - text = _("%(id)s:\t%(father)s, %(mother)s" - ) % {'id': family.get_gramps_id(), - 'father': fname, 'mother': mname} + text = _("%(id)s:\t%(father)s, %(mother)s") % { + "id": family.get_gramps_id(), + "father": fname, + "mother": mname, + } id_list.append(text) self.options_help[name].append(id_list) elif isinstance(option, NoteOption): @@ -443,14 +476,15 @@ def init_report_options_help(self): elif isinstance(option, TextOption): self.options_help[name].append( "A list of text values. Each entry in the list " - "represents one line of text.") + "represents one line of text." + ) elif isinstance(option, EnumeratedListOption): ilist = [] - for (value, description) in option.get_items(): - tabs = '\t' + for value, description in option.get_items(): + tabs = "\t" try: - tabs = '\t\t' if len(value) < 10 else '\t' - except TypeError: #Value is a number, use just one tab. + tabs = "\t\t" if len(value) < 10 else "\t" + except TypeError: # Value is a number, use just one tab. pass val = "%s%s%s" % (value, tabs, description) ilist.append(val) @@ -459,13 +493,19 @@ def init_report_options_help(self): self.options_help[name].append(option.get_help()) else: print(_("Unknown option: %s") % option, file=sys.stderr) - print(_(" Valid options are:") + - _(", ").join(list(self.options_dict.keys())), # Arabic OK - file=sys.stderr) - print(_(" Use '%(donottranslate)s' to see description " + print( + _(" Valid options are:") + + _(", ").join(list(self.options_dict.keys())), # Arabic OK + file=sys.stderr, + ) + print( + _( + " Use '%(donottranslate)s' to see description " "and acceptable values" - ) % {'donottranslate' : "show=option"}, - file=sys.stderr) + ) + % {"donottranslate": "show=option"}, + file=sys.stderr, + ) def parse_options(self): """ @@ -477,9 +517,9 @@ def parse_options(self): menu = self.option_class.menu menu_opt_names = menu.get_all_option_names() - _format_str = self.options_str_dict.pop('off', None) + _format_str = self.options_str_dict.pop("off", None) if _format_str: - self.options_dict['off'] = _format_str + self.options_dict["off"] = _format_str self.css_filename = None _chosen_format = None @@ -488,13 +528,13 @@ def parse_options(self): if self.category in [CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK]: if self.category == CATEGORY_TEXT: plugins = self.__textdoc_plugins - self.css_filename = self.options_dict['css'] + self.css_filename = self.options_dict["css"] elif self.category == CATEGORY_DRAW: plugins = self.__drawdoc_plugins elif self.category == CATEGORY_BOOK: plugins = self.__bookdoc_plugins for plugin in plugins: - if plugin.get_extension() == self.options_dict['off']: + if plugin.get_extension() == self.options_dict["off"]: self.format = plugin.get_basedoc() self.doc_option_class = plugin.get_doc_option_class() if self.format is None: @@ -505,8 +545,8 @@ def parse_options(self): _chosen_format = plugin.get_extension() elif self.category == CATEGORY_GRAPHVIZ: for graph_format in graphdoc.FORMATS: - if graph_format['type'] == self.options_dict['off']: - if not self.format: # choose the first one, not the last + if graph_format["type"] == self.options_dict["off"]: + if not self.format: # choose the first one, not the last self.format = graph_format["class"] if self.format is None: # Pick the first one as the default. @@ -514,8 +554,8 @@ def parse_options(self): _chosen_format = graphdoc.FORMATS[0]["type"] elif self.category == CATEGORY_TREE: for tree_format in treedoc.FORMATS: - if tree_format['type'] == self.options_dict['off']: - if not self.format: # choose the first one, not the last + if tree_format["type"] == self.options_dict["off"]: + if not self.format: # choose the first one, not the last self.format = tree_format["class"] if self.format is None: # Pick the first one as the default. @@ -524,24 +564,33 @@ def parse_options(self): else: self.format = None if _chosen_format and _format_str: - print(_("Ignoring '%(notranslate1)s=%(notranslate2)s' " + print( + _( + "Ignoring '%(notranslate1)s=%(notranslate2)s' " "and using '%(notranslate1)s=%(notranslate3)s'." - ) % {'notranslate1' : "off", - 'notranslate2' : self.options_dict['off'], - 'notranslate3' : _chosen_format}, - file=sys.stderr) - print(_("Use '%(notranslate)s' to see valid values." - ) % {'notranslate' : "show=off"}, file=sys.stderr) + ) + % { + "notranslate1": "off", + "notranslate2": self.options_dict["off"], + "notranslate3": _chosen_format, + }, + file=sys.stderr, + ) + print( + _("Use '%(notranslate)s' to see valid values.") + % {"notranslate": "show=off"}, + file=sys.stderr, + ) self.do_doc_options() for opt in self.options_str_dict: if opt in self.options_dict: self.options_dict[opt] = _convert_str_to_match_type( - self.options_str_dict[opt], self.options_dict[opt]) + self.options_str_dict[opt], self.options_dict[opt] + ) - self.option_class.handler.options_dict[ - opt] = self.options_dict[opt] + self.option_class.handler.options_dict[opt] = self.options_dict[opt] if menu and opt in menu_opt_names: option = menu.get_option_by_name(opt) @@ -549,28 +598,34 @@ def parse_options(self): else: print(_("Ignoring unknown option: %s") % opt, file=sys.stderr) - print(_(" Valid options are:"), - _(", ").join(list(self.options_dict.keys())), # Arabic OK - file=sys.stderr) - print(_(" Use '%(donottranslate)s' to see description " + print( + _(" Valid options are:"), + _(", ").join(list(self.options_dict.keys())), # Arabic OK + file=sys.stderr, + ) + print( + _( + " Use '%(donottranslate)s' to see description " "and acceptable values" - ) % {'donottranslate' : "show=option"}, - file=sys.stderr) + ) + % {"donottranslate": "show=option"}, + file=sys.stderr, + ) - self.option_class.handler.output = self.options_dict['of'] + self.option_class.handler.output = self.options_dict["of"] - self.paper = paper_sizes[0] # make sure one exists + self.paper = paper_sizes[0] # make sure one exists for paper in paper_sizes: - if paper.get_name() == self.options_dict['papers']: + if paper.get_name() == self.options_dict["papers"]: self.paper = paper self.option_class.handler.set_paper(self.paper) - self.orien = self.options_dict['papero'] + self.orien = self.options_dict["papero"] - self.marginl = self.options_dict['paperml'] - self.marginr = self.options_dict['papermr'] - self.margint = self.options_dict['papermt'] - self.marginb = self.options_dict['papermb'] + self.marginl = self.options_dict["paperml"] + self.marginr = self.options_dict["papermr"] + self.margint = self.options_dict["papermt"] + self.marginb = self.options_dict["papermb"] if self.category in (CATEGORY_TEXT, CATEGORY_DRAW): default_style = StyleSheet() @@ -590,27 +645,27 @@ def do_doc_options(self): """ self.doc_options = None if not self.doc_option_class: - return # this docgen type has no options + return # this docgen type has no options try: if issubclass(self.doc_option_class, object): - self.doc_options = self.doc_option_class(self.raw_name, - self.database) + self.doc_options = self.doc_option_class(self.raw_name, self.database) doc_options_dict = self.doc_options.options_dict except TypeError: self.doc_options = self.doc_option_class self.doc_options.load_previous_values() docgen_menu = self.doc_options.menu - report_menu = self.option_class.menu # "help" checks the option type + report_menu = self.option_class.menu # "help" checks the option type for oname in docgen_menu.get_option_names(DOCGEN_OPTIONS): docgen_opt = docgen_menu.get_option(DOCGEN_OPTIONS, oname) if oname in self.options_str_dict and oname in doc_options_dict: doc_options_dict[oname] = _convert_str_to_match_type( - self.options_str_dict[oname], doc_options_dict[oname]) + self.options_str_dict[oname], doc_options_dict[oname] + ) self.options_str_dict.pop(oname) if oname in doc_options_dict: docgen_opt.set_value(doc_options_dict[oname]) report_menu.add_option(DOCGEN_OPTIONS, oname, docgen_opt) - for oname in doc_options_dict: # enable "help" + for oname in doc_options_dict: # enable "help" self.options_dict[oname] = doc_options_dict[oname] self.options_help[oname] = self.doc_options.options_help[oname][:3] @@ -620,26 +675,29 @@ def show_options(self): """ if not self.show: return - elif self.show == 'all': + elif self.show == "all": print(_(" Available options:")) for key in sorted(self.options_dict.keys()): if key in self.options_help: opt = self.options_help[key] # Make the output nicer to read, assume a tab has 8 spaces - tabs = '\t\t' if len(key) < 10 else '\t' + tabs = "\t\t" if len(key) < 10 else "\t" optmsg = " %s%s%s (%s)" % (key, tabs, opt[1], opt[0]) else: - optmsg = " %s%s%s" % (key, tabs, - _('(no help available)')) + optmsg = " %s%s%s" % (key, tabs, _("(no help available)")) print(optmsg) - print(_(" Use '%(donottranslate)s' to see description " + print( + _( + " Use '%(donottranslate)s' to see description " "and acceptable values" - ) % {'donottranslate' : "show=option"}) + ) + % {"donottranslate": "show=option"} + ) elif self.show in self.options_help: opt = self.options_help[self.show] - tabs = '\t\t' if len(self.show) < 10 else '\t' + tabs = "\t\t" if len(self.show) < 10 else "\t" print(_(" Available values are:")) - print(' %s%s%s (%s)' % (self.show, tabs, opt[1], opt[0])) + print(" %s%s%s (%s)" % (self.show, tabs, opt[1], opt[0])) vals = opt[2] if isinstance(vals, (list, tuple)): for val in vals: @@ -648,27 +706,29 @@ def show_options(self): print(" %s" % opt[2]) else: - #there was a show option given, but the option is invalid - print(_("option '%(optionname)s' not valid. " + # there was a show option given, but the option is invalid + print( + _( + "option '%(optionname)s' not valid. " "Use '%(donottranslate)s' to see all valid options." - ) % {'optionname' : self.show, - 'donottranslate' : "show=all"}, - file=sys.stderr) + ) + % {"optionname": self.show, "donottranslate": "show=all"}, + file=sys.stderr, + ) -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # Command-line report generic task # -#------------------------------------------------------------------------ -def cl_report(database, name, category, report_class, options_class, - options_str_dict): +# ------------------------------------------------------------------------ +def cl_report(database, name, category, report_class, options_class, options_str_dict): """ function to actually run the selected report """ err_msg = _("Failed to write report. ") - clr = CommandLineReport(database, name, category, options_class, - options_str_dict) + clr = CommandLineReport(database, name, category, options_class, options_str_dict) # Exit here if show option was given if clr.show: @@ -680,21 +740,43 @@ def cl_report(database, name, category, report_class, options_class, if clr.doc_options: clr.option_class.handler.doc = clr.format( clr.selected_style, - PaperStyle(clr.paper, clr.orien, clr.marginl, - clr.marginr, clr.margint, clr.marginb), - clr.doc_options) + PaperStyle( + clr.paper, + clr.orien, + clr.marginl, + clr.marginr, + clr.margint, + clr.marginb, + ), + clr.doc_options, + ) else: clr.option_class.handler.doc = clr.format( clr.selected_style, - PaperStyle(clr.paper, clr.orien, clr.marginl, - clr.marginr, clr.margint, clr.marginb)) + PaperStyle( + clr.paper, + clr.orien, + clr.marginl, + clr.marginr, + clr.margint, + clr.marginb, + ), + ) elif category in [CATEGORY_GRAPHVIZ, CATEGORY_TREE]: clr.option_class.handler.doc = clr.format( clr.option_class, - PaperStyle(clr.paper, clr.orien, clr.marginl, - clr.marginr, clr.margint, clr.marginb)) - if (clr.css_filename is not None - and hasattr(clr.option_class.handler.doc, 'set_css_filename')): + PaperStyle( + clr.paper, + clr.orien, + clr.marginl, + clr.marginr, + clr.margint, + clr.marginb, + ), + ) + if clr.css_filename is not None and hasattr( + clr.option_class.handler.doc, "set_css_filename" + ): clr.option_class.handler.doc.set_css_filename(clr.css_filename) my_report = report_class(database, clr.option_class, User()) my_report.doc.init() @@ -720,6 +802,7 @@ def cl_report(database, name, category, report_class, options_class, except: traceback.print_exc() + def run_report(db, name, **options_str_dict): """ Given a database, run a given report. @@ -742,7 +825,7 @@ def run_report(db, name, **options_str_dict): filename in clr.option_class.get_output() """ dbstate = DbState() - climanager = CLIManager(dbstate, False, User()) # don't load db + climanager = CLIManager(dbstate, False, User()) # don't load db climanager.do_reg_plugins(dbstate, None) pmgr = BasePluginManager.get_instance() cl_list = pmgr.get_reg_reports() @@ -751,48 +834,51 @@ def run_report(db, name, **options_str_dict): if name == pdata.id: mod = pmgr.load_plugin(pdata) if not mod: - #import of plugin failed + # import of plugin failed return clr category = pdata.category report_class = getattr(mod, pdata.reportclass) options_class = getattr(mod, pdata.optionclass) if category in (CATEGORY_BOOK, CATEGORY_CODE): - options_class(db, name, category, - options_str_dict) + options_class(db, name, category, options_str_dict) else: - clr = cl_report(db, name, category, - report_class, options_class, - options_str_dict) + clr = cl_report( + db, name, category, report_class, options_class, options_str_dict + ) return clr return clr -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # Function to write books from command line # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ def cl_book(database, name, book, options_str_dict): """ function to actually run the selected book, which in turn runs whatever reports the book has in it """ - clr = CommandLineReport(database, name, CATEGORY_BOOK, - ReportOptions, options_str_dict) + clr = CommandLineReport( + database, name, CATEGORY_BOOK, ReportOptions, options_str_dict + ) # Exit here if show option was given if clr.show: return # write report - doc = clr.format(None, - PaperStyle(clr.paper, clr.orien, clr.marginl, - clr.marginr, clr.margint, clr.marginb)) + doc = clr.format( + None, + PaperStyle( + clr.paper, clr.orien, clr.marginl, clr.marginr, clr.margint, clr.marginb + ), + ) user = User() rptlist = [] selected_style = StyleSheet() for item in book.get_item_list(): - # The option values were loaded magically by the book parser. # But they still need to be applied to the menu options. opt_dict = item.option_class.options_dict @@ -804,9 +890,10 @@ def cl_book(database, name, book, options_str_dict): item.option_class.set_document(doc) report_class = item.get_write_item() - obj = (write_book_item(database, - report_class, item.option_class, user), - item.get_translated_name()) + obj = ( + write_book_item(database, report_class, item.option_class, user), + item.get_translated_name(), + ) if obj: append_styles(selected_style, item) rptlist.append(obj) @@ -817,7 +904,7 @@ def cl_book(database, name, book, options_str_dict): newpage = 0 err_msg = _("Failed to make '%s' report.") try: - for (rpt, name) in rptlist: + for rpt, name in rptlist: if newpage: doc.page_break() newpage = 1 @@ -826,16 +913,17 @@ def cl_book(database, name, book, options_str_dict): doc.close() except ReportError as msg: (msg1, msg2) = msg.messages() - print(err_msg % name, file=sys.stderr) # which report has the error? + print(err_msg % name, file=sys.stderr) # which report has the error? print(msg1, file=sys.stderr) if msg2: print(msg2, file=sys.stderr) -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # Generic task function for book # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ def write_book_item(database, report_class, options, user): """Write the report using options set. All user dialog has already been handled and the output file opened.""" diff --git a/gramps/cli/test/argparser_test.py b/gramps/cli/test/argparser_test.py index f3162dd08a4..58470862aac 100644 --- a/gramps/cli/test/argparser_test.py +++ b/gramps/cli/test/argparser_test.py @@ -25,6 +25,7 @@ from unittest.mock import Mock from ..argparser import ArgParser + class TestArgParser(unittest.TestCase): def setUp(self): pass @@ -34,47 +35,46 @@ def create_parser(*self_and_args): def triggers_option_error(self, option): ap = self.create_parser(option) - return (str(ap.errors).find("option "+option)>=0, ap) + return (str(ap.errors).find("option " + option) >= 0, ap) def test_wrong_argument_triggers_option_error(self): - bad,ap = self.triggers_option_error('--I-am-a-wrong-argument') + bad, ap = self.triggers_option_error("--I-am-a-wrong-argument") assert bad, ap.__dict__ def test_y_shortopt_sets_auto_accept(self): - bad, ap = self.triggers_option_error('-y') + bad, ap = self.triggers_option_error("-y") self.assertFalse(bad) - expected_errors = [( - 'Error parsing the arguments', - 'Error parsing the arguments: [ -y ] \n' + - 'To use in the command-line mode, supply at least one input file to process.' - )] - self.assertEqual( - expected_errors, - ap.errors - ) + expected_errors = [ + ( + "Error parsing the arguments", + "Error parsing the arguments: [ -y ] \n" + + "To use in the command-line mode, supply at least one input file to process.", + ) + ] + self.assertEqual(expected_errors, ap.errors) self.assertTrue(ap.auto_accept) def test_yes_longopt_sets_auto_accept(self): - bad,ap = self.triggers_option_error('--yes') + bad, ap = self.triggers_option_error("--yes") assert not bad, ap.errors assert ap.auto_accept def test_q_shortopt_sets_quiet(self): - bad,ap = self.triggers_option_error('-q') + bad, ap = self.triggers_option_error("-q") assert not bad, ap.errors assert ap.quiet def test_quiet_longopt_sets_quiet(self): - bad,ap = self.triggers_option_error('--quiet') + bad, ap = self.triggers_option_error("--quiet") assert not bad, ap.errors assert ap.quiet def test_quiet_exists_by_default(self): ap = self.create_parser() - assert hasattr(ap,'quiet') + assert hasattr(ap, "quiet") def test_auto_accept_unset_by_default(self): ap = self.create_parser() @@ -83,20 +83,20 @@ def test_auto_accept_unset_by_default(self): def test_exception(self): argument_parser = self.create_parser("-O") - expected_errors = [( - 'Error parsing the arguments', - 'option -O requires argument\n' - 'Error parsing the arguments: [ -O ] \n' - 'Type gramps --help for an overview of commands, or read the manual pages.' - )] - self.assertEqual( - expected_errors, - argument_parser.errors - ) + expected_errors = [ + ( + "Error parsing the arguments", + "option -O requires argument\n" + "Error parsing the arguments: [ -O ] \n" + "Type gramps --help for an overview of commands, or read the manual pages.", + ) + ] + self.assertEqual(expected_errors, argument_parser.errors) def test_option_with_multiple_arguments(self): - argument_parser = self.create_parser('-l', 'family_tree_name') - self.assertEqual(argument_parser.database_names, ['family_tree_name']) + argument_parser = self.create_parser("-l", "family_tree_name") + self.assertEqual(argument_parser.database_names, ["family_tree_name"]) + if __name__ == "__main__": unittest.main() diff --git a/gramps/cli/test/cli_test.py b/gramps/cli/test/cli_test.py index 342bc52131c..7aed7ac8368 100644 --- a/gramps/cli/test/cli_test.py +++ b/gramps/cli/test/cli_test.py @@ -44,8 +44,8 @@ min1r = os.path.join(ddir, "min1r.ged") out_ged = os.path.join(ddir, "test_out.ged") example_copy = os.path.join(ddir, "copy.gramps") -example = os.path.join(ddir, "..", "..", "..", - "example", "gramps", "data.gramps") +example = os.path.join(ddir, "..", "..", "..", "example", "gramps", "data.gramps") + class Test(unittest.TestCase): def setUp(self): @@ -70,8 +70,7 @@ def tearDownClass(cls): def test1_setup_works(self): self.assertTrue(os.path.exists(ddir), "data dir %r exists" % ddir) self.assertTrue(os.path.exists(min1r), "data file %r exists" % min1r) - self.assertFalse(os.path.exists(out_ged), - "NO out file %r yet" % out_ged) + self.assertFalse(os.path.exists(out_ged), "NO out file %r yet" % out_ged) # This tests the fix for bug #1331-1334 # read trivial gedcom input, write gedcom output @@ -79,13 +78,11 @@ def test2_exec_CLI(self): ifile = min1r ofile = out_ged gcmd = [sys.executable, "Gramps.py", "-i", ifile, "-e", ofile] - process = subprocess.Popen(gcmd, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + process = subprocess.Popen( + gcmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) result_str, err_str = process.communicate() - self.assertEqual(process.returncode, 0, - "executed CLI command %r" % gcmd) + self.assertEqual(process.returncode, 0, "executed CLI command %r" % gcmd) # simple validation o output self.assertTrue(os.path.isfile(ofile), "output file created") with open(ofile) as f: @@ -98,13 +95,11 @@ def test2_exec_cli_m(self): ifile = min1r ofile = out_ged gcmd = [sys.executable, "-m", "gramps", "-i", ifile, "-e", ofile] - process = subprocess.Popen(gcmd, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + process = subprocess.Popen( + gcmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) result_str, err_str = process.communicate() - self.assertEqual(process.returncode, 0, - "executed CLI command %r" % gcmd) + self.assertEqual(process.returncode, 0, "executed CLI command %r" % gcmd) # simple validation o output self.assertTrue(os.path.isfile(ofile), "output file created") with open(ofile) as f: @@ -114,39 +109,47 @@ def test2_exec_cli_m(self): class UnicodeTest(unittest.TestCase): - def setUp(self): from gramps.cli.clidbman import CLIDbManager from gramps.gen.config import set as setconfig, get as getconfig from gramps.gen.dbstate import DbState - self.newpath = os.path.join(os.path.dirname(__file__), - '\u0393\u03c1\u03b1\u03bc\u03c3\u03c0') - self.newtitle = 'Gr\u00e4mps T\u00e9st' + + self.newpath = os.path.join( + os.path.dirname(__file__), "\u0393\u03c1\u03b1\u03bc\u03c3\u03c0" + ) + self.newtitle = "Gr\u00e4mps T\u00e9st" os.makedirs(self.newpath) - self.old_path = getconfig('database.path') - setconfig('database.path', self.newpath) + self.old_path = getconfig("database.path") + setconfig("database.path", self.newpath) self.cli = CLIDbManager(DbState()) def tearDown(self): from gramps.gen.config import set as setconfig - for (dirpath, dirnames, filenames) in os.walk(self.newpath, False): + + for dirpath, dirnames, filenames in os.walk(self.newpath, False): for afile in filenames: os.remove(os.path.join(dirpath, afile)) for adir in dirnames: os.rmdir(os.path.join(dirpath, adir)) os.rmdir(self.newpath) - setconfig('database.path', self.old_path) + setconfig("database.path", self.old_path) # Test that clidbman will open files in a path containing # arbitrary Unicode characters. def test4_arbitrary_uncode_path(self): (dbpath, title) = self.cli.create_new_db_cli(self.newtitle) - self.assertEqual(self.newpath, os.path.dirname(dbpath), - "Compare paths %s and %s" % (repr(self.newpath), - repr(dbpath))) - self.assertEqual(self.newtitle, title, "Compare titles %s and %s" % - (repr(self.newtitle), repr(title))) + self.assertEqual( + self.newpath, + os.path.dirname(dbpath), + "Compare paths %s and %s" % (repr(self.newpath), repr(dbpath)), + ) + self.assertEqual( + self.newtitle, + title, + "Compare titles %s and %s" % (repr(self.newtitle), repr(title)), + ) + class CLITest(unittest.TestCase): def tearDown(self): @@ -167,7 +170,8 @@ def test1a_cli(self): def test1b_cli(self): self.call("-O", "Test: test1_cli", "--export", example_copy) + if __name__ == "__main__": unittest.main() -#===eof=== +# ===eof=== diff --git a/gramps/cli/test/user_test.py b/gramps/cli/test/user_test.py index a72e82f673f..73029210d3d 100644 --- a/gramps/cli/test/user_test.py +++ b/gramps/cli/test/user_test.py @@ -26,12 +26,14 @@ from .. import user import sys + class TestUser: TITLE = "Testing prompt" MSG = "Choices are hard. Nevertheless, please choose!" ACCEPT = "To be" REJECT = "Not to be" + class TestUser_prompt(unittest.TestCase): def setUp(self): self.real_user = user.User() @@ -40,38 +42,46 @@ def setUp(self): self.user._input = Mock(spec=input) def test_default_fileout_has_write(self): - assert hasattr(self.real_user._fileout, 'write') + assert hasattr(self.real_user._fileout, "write") def test_default_input(self): - assert self.real_user._input.__name__.endswith('input') + assert self.real_user._input.__name__.endswith("input") def test_prompt_returns_True_if_ACCEPT_entered(self): - self.user._input.configure_mock(return_value = TestUser.ACCEPT) + self.user._input.configure_mock(return_value=TestUser.ACCEPT) assert self.user.prompt( - TestUser.TITLE, TestUser.MSG, TestUser.ACCEPT, TestUser.REJECT - ), "True expected!" + TestUser.TITLE, TestUser.MSG, TestUser.ACCEPT, TestUser.REJECT + ), "True expected!" self.user._input.assert_called_once_with() def test_prompt_returns_False_if_REJECT_entered(self): - self.user._input.configure_mock(return_value = TestUser.REJECT) + self.user._input.configure_mock(return_value=TestUser.REJECT) assert not self.user.prompt( - TestUser.TITLE, TestUser.MSG, TestUser.ACCEPT, TestUser.REJECT - ), "False expected!" + TestUser.TITLE, TestUser.MSG, TestUser.ACCEPT, TestUser.REJECT + ), "False expected!" self.user._input.assert_called_once_with() - def assert_prompt_contains_text(self, text, - title=TestUser.TITLE, msg=TestUser.MSG, - accept=TestUser.ACCEPT, reject=TestUser.REJECT): - self.user._input.configure_mock(return_value = TestUser.REJECT) + def assert_prompt_contains_text( + self, + text, + title=TestUser.TITLE, + msg=TestUser.MSG, + accept=TestUser.ACCEPT, + reject=TestUser.REJECT, + ): + self.user._input.configure_mock(return_value=TestUser.REJECT) self.user.prompt(title, msg, accept, reject) for call in self.user._fileout.method_calls: name, args, kwargs = call for a in args: if a.find(text) >= 0: return - self.assertTrue(False, - "'{}' never printed in prompt: {}".format( - text, self.user._fileout.method_calls)) + self.assertTrue( + False, + "'{}' never printed in prompt: {}".format( + text, self.user._fileout.method_calls + ), + ) def test_prompt_contains_title_text(self): self.assert_prompt_contains_text(TestUser.TITLE) @@ -95,19 +105,20 @@ def test_auto_accept_accepts_without_prompting(self): u = user.User(auto_accept=True) u._fileout = Mock(spec=sys.stderr) assert u.prompt( - TestUser.TITLE, TestUser.MSG, TestUser.ACCEPT, TestUser.REJECT - ), "True expected!" + TestUser.TITLE, TestUser.MSG, TestUser.ACCEPT, TestUser.REJECT + ), "True expected!" assert len(u._fileout.method_calls) == 0, list(u._fileout.method_calls) def test_EOFError_in_prompt_caught_as_False(self): self.user._input.configure_mock( - side_effect = EOFError, - return_value = TestUser.REJECT) + side_effect=EOFError, return_value=TestUser.REJECT + ) assert not self.user.prompt( - TestUser.TITLE, TestUser.MSG, TestUser.ACCEPT, TestUser.REJECT - ), "False expected!" + TestUser.TITLE, TestUser.MSG, TestUser.ACCEPT, TestUser.REJECT + ), "False expected!" self.user._input.assert_called_once_with() + class TestUser_quiet(unittest.TestCase): def setUp(self): self.user = user.User(quiet=True) @@ -120,11 +131,12 @@ def test_progress_can_begin_step_end(self): self.user.end_progress() def tearDown(self): - assert len(self.user._fileout.method_calls - ) == 0, list(self.user._fileout.method_calls) + assert len(self.user._fileout.method_calls) == 0, list( + self.user._fileout.method_calls + ) -class TestUser_progress(unittest.TestCase): +class TestUser_progress(unittest.TestCase): def setUp(self): self.user = user.User() self.user._fileout = Mock(spec=sys.stderr) @@ -135,19 +147,19 @@ def test_can_step_using_with(self): self.expected_output = list(self.user._fileout.method_calls) self.user._fileout.reset_mock() self.assertTrue( - len(self.user._fileout.method_calls) == 0, - list(self.user._fileout.method_calls)) + len(self.user._fileout.method_calls) == 0, + list(self.user._fileout.method_calls), + ) with self.user.progress("Foo", "Bar", 0) as step: for i in range(10): step() # Output using `with' differs from one with `progress_...' - self.assertEqual(self.expected_output, - list(self.user._fileout.method_calls)) + self.assertEqual(self.expected_output, list(self.user._fileout.method_calls)) def test_ends_progress_upon_exception_in_with(self): - with patch('gramps.cli.user.User.end_progress') as MockEP: + with patch("gramps.cli.user.User.end_progress") as MockEP: try: with self.user.progress("Foo", "Bar", 0) as step: raise Exception() @@ -161,5 +173,6 @@ def _progress_begin_step_end(self): self.user.step_progress() self.user.end_progress() + if __name__ == "__main__": unittest.main() diff --git a/gramps/cli/user.py b/gramps/cli/user.py index 2f07baaf186..dfa2d136cd8 100644 --- a/gramps/cli/user.py +++ b/gramps/cli/user.py @@ -22,36 +22,45 @@ The User class provides basic interaction with the user. """ -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Gramps Modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ from gramps.gen.const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext from gramps.gen.const import URL_BUGHOME from gramps.gen import user -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Private Constants # -#------------------------------------------------------------------------ -_SPINNER = ['|', '/', '-', '\\'] +# ------------------------------------------------------------------------ +_SPINNER = ["|", "/", "-", "\\"] + -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # User class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class User(user.UserBase): """ This class provides a means to interact with the user via CLI. It implements the interface in :class:`.gen.user.UserBase` """ - def __init__(self, callback=None, error=None, - auto_accept=False, quiet=False, - uistate=None, dbstate=None): + + def __init__( + self, + callback=None, + error=None, + auto_accept=False, + quiet=False, + uistate=None, + dbstate=None, + ): """ Init. @@ -59,8 +68,8 @@ def __init__(self, callback=None, error=None, :type error: function(title, error) """ user.UserBase.__init__(self, callback, error, uistate, dbstate) - self.steps = 0; - self.current_step = 0; + self.steps = 0 + self.current_step = 0 self._input = input def yes(*args, **kwargs): @@ -69,8 +78,9 @@ def yes(*args, **kwargs): if auto_accept: self.prompt = yes if quiet: - self.begin_progress = self.end_progress = self.step_progress = \ - self._default_callback = yes + self.begin_progress = ( + self.end_progress + ) = self.step_progress = self._default_callback = yes def begin_progress(self, title, message, steps): """ @@ -88,7 +98,7 @@ def begin_progress(self, title, message, steps): """ self._fileout.write(message) self.steps = steps - self.current_step = 0; + self.current_step = 0 if self.steps == 0: self._fileout.write(_SPINNER[self.current_step]) else: @@ -112,8 +122,15 @@ def end_progress(self): """ self._fileout.write("\r100%\n") - def prompt(self, title, message, accept_label, reject_label, - parent=None, default_label=None): + def prompt( + self, + title, + message, + accept_label, + reject_label, + parent=None, + default_label=None, + ): """ Prompt the user with a message to select an alternative. @@ -142,11 +159,9 @@ def prompt(self, title, message, accept_label, reject_label, reject_text = "[%s]" % reject_text default = False text = "{t}\n{m} ({y}/{n}): ".format( - t = title, - m = message, - y = accept_text, - n = reject_text) - print (text, file = self._fileout) # TODO: python 3.3 add flush=True + t=title, m=message, y=accept_text, n=reject_text + ) + print(text, file=self._fileout) # TODO: python 3.3 add flush=True try: reply = self._input() except EOFError: @@ -198,10 +213,15 @@ def notify_db_error(self, error): """ self.notify_error( _("Low level database corruption detected"), - _("Gramps has detected a problem in the underlying " - "database. This can sometimes be repaired from " - "the Family Tree Manager. Select the database and " - 'click on the Repair button') + '\n\n' + error) + _( + "Gramps has detected a problem in the underlying " + "database. This can sometimes be repaired from " + "the Family Tree Manager. Select the database and " + "click on the Repair button" + ) + + "\n\n" + + error, + ) def notify_db_repair(self, error): """ @@ -214,14 +234,18 @@ def notify_db_repair(self, error): These exact strings are also in gui/dialog.py -- keep them in sync """ self.notify_error( - _('Error detected in database'), - _('Gramps has detected an error in the database. This can ' - 'usually be resolved by running the "Check and Repair Database" ' - 'tool.\n\nIf this problem continues to exist after running this ' - 'tool, please file a bug report at ' - '%(gramps_bugtracker_url)s\n\n' - ) % {'gramps_bugtracker_url' : URL_BUGHOME} - + error + '\n\n') + _("Error detected in database"), + _( + "Gramps has detected an error in the database. This can " + 'usually be resolved by running the "Check and Repair Database" ' + "tool.\n\nIf this problem continues to exist after running this " + "tool, please file a bug report at " + "%(gramps_bugtracker_url)s\n\n" + ) + % {"gramps_bugtracker_url": URL_BUGHOME} + + error + + "\n\n", + ) def info(self, msg1, infotext, parent=None, monospaced=False): """ diff --git a/gramps/gen/__init__.py b/gramps/gen/__init__.py index 999f29a8315..310a05a7332 100644 --- a/gramps/gen/__init__.py +++ b/gramps/gen/__init__.py @@ -23,5 +23,16 @@ interfaces (gui, cli and web). """ -__all__ = ["datehandler", "db", "display", "filters", "lib", "merge", - "mime", "plug", "proxy", "simple", "utils"] +__all__ = [ + "datehandler", + "db", + "display", + "filters", + "lib", + "merge", + "mime", + "plug", + "proxy", + "simple", + "utils", +] diff --git a/gramps/gen/config.py b/gramps/gen/config.py index 2faee1c128f..1d8ab4652f8 100644 --- a/gramps/gen/config.py +++ b/gramps/gen/config.py @@ -27,77 +27,90 @@ This package implements access to Gramps configuration. """ -#--------------------------------------------------------------- +# --------------------------------------------------------------- # # Gramps imports # -#--------------------------------------------------------------- +# --------------------------------------------------------------- import os import re import logging -#--------------------------------------------------------------- +# --------------------------------------------------------------- # # Gramps imports # -#--------------------------------------------------------------- +# --------------------------------------------------------------- from .const import USER_CONFIG, USER_DATA, USER_HOME, VERSION_DIR from .utils.configmanager import ConfigManager from .const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext + # _T_ is a gramps-defined keyword -- see po/update_po.py and po/genpot.sh -def _T_(value, context=''): # enable deferred translations +def _T_(value, context=""): # enable deferred translations return "%s\x04%s" % (context, value) if context else value -#--------------------------------------------------------------- + +# --------------------------------------------------------------- # # Constants # -#--------------------------------------------------------------- +# --------------------------------------------------------------- INIFILE = os.path.join(VERSION_DIR, "gramps.ini") -#--------------------------------------------------------------- + +# --------------------------------------------------------------- # # Module functions # -#--------------------------------------------------------------- +# --------------------------------------------------------------- def register(key, value): - """ Module shortcut to register key, value """ + """Module shortcut to register key, value""" return CONFIGMAN.register(key, value) + def get(key): - """ Module shortcut to get value from key """ + """Module shortcut to get value from key""" return CONFIGMAN.get(key) + def get_default(key): - """ Module shortcut to get default from key """ + """Module shortcut to get default from key""" return CONFIGMAN.get_default(key) + def has_default(key): - """ Module shortcut to get see if there is a default for key """ + """Module shortcut to get see if there is a default for key""" return CONFIGMAN.has_default(key) + def get_sections(): - """ Module shortcut to get all section names of settings """ + """Module shortcut to get all section names of settings""" return CONFIGMAN.get_sections() + def get_section_settings(section): - """ Module shortcut to get all settings of a section """ + """Module shortcut to get all settings of a section""" return CONFIGMAN.get_section_settings(section) + def set(key, value): - """ Module shortcut to set value from key """ + """Module shortcut to set value from key""" return CONFIGMAN.set(key, value) + def is_set(key): - """ Module shortcut to set value from key """ + """Module shortcut to set value from key""" return CONFIGMAN.is_set(key) + def save(filename=None): - """ Module shortcut to save config file """ + """Module shortcut to save config file""" return CONFIGMAN.save(filename) + def connect(key, func): """ Module shortcut to connect a key to a callback func. @@ -105,254 +118,283 @@ def connect(key, func): """ return CONFIGMAN.connect(key, func) + def disconnect(callback_id): - """ Module shortcut to remove callback by ID number """ + """Module shortcut to remove callback by ID number""" return CONFIGMAN.disconnect(callback_id) + def reset(key=None): - """ Module shortcut to reset some or all config data """ + """Module shortcut to reset some or all config data""" return CONFIGMAN.reset(key) + def load(filename=None, oldstyle=False): - """ Module shortcut to load an INI file into config data """ + """Module shortcut to load an INI file into config data""" return CONFIGMAN.load(filename, oldstyle) + def emit(key): - """ Module shortcut to call all callbacks associated with key """ + """Module shortcut to call all callbacks associated with key""" return CONFIGMAN.emit(key) -#--------------------------------------------------------------- + +# --------------------------------------------------------------- # # Register the system-wide settings in a singleton config manager # -#--------------------------------------------------------------- +# --------------------------------------------------------------- CONFIGMAN = ConfigManager(INIFILE, "plugins") -register('behavior.addmedia-image-dir', '') -register('behavior.addmedia-relative-path', False) -register('behavior.autoload', False) -register('behavior.avg-generation-gap', 20) -register('behavior.check-for-addon-updates', 0) -register('behavior.check-for-addon-update-types', ["new"]) -register('behavior.last-check-for-addon-updates', "1970/01/01") -register('behavior.previously-seen-addon-updates', []) -register('behavior.do-not-show-previously-seen-addon-updates', True) -register('behavior.date-about-range', 50) -register('behavior.date-after-range', 50) -register('behavior.date-before-range', 50) -register('behavior.generation-depth', 15) -register('behavior.max-age-prob-alive', 110) -register('behavior.max-sib-age-diff', 20) -register('behavior.min-generation-years', 13) -register('behavior.owner-warn', False) -register('behavior.immediate-warn', False) -register('behavior.pop-plugin-status', False) -register('behavior.recent-export-type', 3) -register('behavior.runcheck', False) -register('behavior.spellcheck', False) -register('behavior.startup', 0) -register('behavior.surname-guessing', 0) -register('behavior.translator-needed', True) -register('behavior.use-tips', False) -register('behavior.welcome', 100) -register('behavior.web-search-url', 'http://google.com/#&q=%(text)s') -register('behavior.addons-url', 'https://raw.githubusercontent.com/gramps-project/addons/master/gramps52') -register('behavior.addons-projects', - [['Gramps', 'https://raw.githubusercontent.com/gramps-project/addons/master/gramps52', True]]) -register('behavior.addons-allow-install', False) - -register('csv.dialect', 'excel') -register('csv.delimiter', ',') - -register('database.backend', 'sqlite') -register('database.compress-backup', True) -register('database.backup-path', USER_HOME) -register('database.backup-on-exit', True) -register('database.autobackup', 0) -register('database.path', os.path.join(USER_DATA, 'grampsdb')) -register('database.host', '') -register('database.port', '') - -register('export.proxy-order', - [["privacy", 0], - ["living", 0], - ["person", 0], - ["note", 0], - ["reference", 0]] - ) - -register('geography.center-lon', 0.0) -register('geography.lock', False) -register('geography.center-lat', 0.0) -register('geography.map_service', 1) -register('geography.zoom', 0) -register('geography.zoom_when_center', 12) -register('geography.show_cross', False) -register('geography.path', "") -register('geography.use-keypad', True) -register('geography.personal-map', "") +register("behavior.addmedia-image-dir", "") +register("behavior.addmedia-relative-path", False) +register("behavior.autoload", False) +register("behavior.avg-generation-gap", 20) +register("behavior.check-for-addon-updates", 0) +register("behavior.check-for-addon-update-types", ["new"]) +register("behavior.last-check-for-addon-updates", "1970/01/01") +register("behavior.previously-seen-addon-updates", []) +register("behavior.do-not-show-previously-seen-addon-updates", True) +register("behavior.date-about-range", 50) +register("behavior.date-after-range", 50) +register("behavior.date-before-range", 50) +register("behavior.generation-depth", 15) +register("behavior.max-age-prob-alive", 110) +register("behavior.max-sib-age-diff", 20) +register("behavior.min-generation-years", 13) +register("behavior.owner-warn", False) +register("behavior.immediate-warn", False) +register("behavior.pop-plugin-status", False) +register("behavior.recent-export-type", 3) +register("behavior.runcheck", False) +register("behavior.spellcheck", False) +register("behavior.startup", 0) +register("behavior.surname-guessing", 0) +register("behavior.translator-needed", True) +register("behavior.use-tips", False) +register("behavior.welcome", 100) +register("behavior.web-search-url", "http://google.com/#&q=%(text)s") +register( + "behavior.addons-url", + "https://raw.githubusercontent.com/gramps-project/addons/master/gramps52", +) +register( + "behavior.addons-projects", + [ + [ + "Gramps", + "https://raw.githubusercontent.com/gramps-project/addons/master/gramps52", + True, + ] + ], +) +register("behavior.addons-allow-install", False) + +register("csv.dialect", "excel") +register("csv.delimiter", ",") + +register("database.backend", "sqlite") +register("database.compress-backup", True) +register("database.backup-path", USER_HOME) +register("database.backup-on-exit", True) +register("database.autobackup", 0) +register("database.path", os.path.join(USER_DATA, "grampsdb")) +register("database.host", "") +register("database.port", "") + +register( + "export.proxy-order", + [["privacy", 0], ["living", 0], ["person", 0], ["note", 0], ["reference", 0]], +) + +register("geography.center-lon", 0.0) +register("geography.lock", False) +register("geography.center-lat", 0.0) +register("geography.map_service", 1) +register("geography.zoom", 0) +register("geography.zoom_when_center", 12) +register("geography.show_cross", False) +register("geography.path", "") +register("geography.use-keypad", True) +register("geography.personal-map", "") # note that other calls to "register" are done in realtime (when # needed), for instance to four 'interface.clipboard' variables -- # so do a recursive grep for "setup_configs" to see all the (base) names -register('interface.dont-ask', False) -register('interface.view-categories', - ["Dashboard", "People", "Relationships", "Families", - "Ancestry", "Events", "Places", "Geography", "Sources", - "Citations", "Repositories", "Media", "Notes"]) -register('interface.filter', False) -register('interface.fullscreen', False) -register('interface.grampletbar-close', False) -register('interface.ignore-gexiv2', False) -register('interface.ignore-pil', False) -register('interface.ignore-osmgpsmap', False) -register('interface.main-window-height', 500) -register('interface.main-window-horiz-position', 15) -register('interface.main-window-vert-position', 10) -register('interface.main-window-width', 775) -register('interface.mapservice', 'OpenStreetMap') -register('interface.open-with-default-viewer', False) -register('interface.pedview-layout', 0) -register('interface.pedview-show-images', True) -register('interface.pedview-show-marriage', False) -register('interface.pedview-tree-size', 5) -register('interface.pedview-tree-direction', 2) -register('interface.pedview-show-unknown-people', False) -register('interface.place-name-height', 100) -register('interface.place-name-width', 450) -register('interface.sidebar-text', True) -register('interface.size-checked', False) -register('interface.statusbar', 1) -register('interface.toolbar-on', True) -register('interface.toolbar-text', False) -register('interface.hide-lds', False) -register('interface.toolbar-clipboard', True) -register('interface.toolbar-addons', True) -register('interface.toolbar-preference', True) -register('interface.toolbar-reports', True) -register('interface.toolbar-tools', True) -register('interface.view', True) -register('interface.surname-box-height', 150) -register('interface.treemodel-cache-size', 1000) - -register('paths.recent-export-dir', USER_HOME) -register('paths.recent-file', '') -register('paths.recent-import-dir', USER_HOME) -register('paths.report-directory', USER_HOME) -register('paths.website-directory', USER_HOME) -register('paths.website-cms-uri', '') -register('paths.website-cal-uri', '') -register('paths.website-extra-page-uri', '') -register('paths.website-extra-page-name', '') -register('paths.quick-backup-directory', USER_HOME) -register('paths.quick-backup-filename', - "%(filename)s_%(year)d-%(month)02d-%(day)02d.%(extension)s") - -register('preferences.quick-backup-include-mode', False) -register('preferences.date-format', 0) -register('preferences.calendar-format-report', 0) -register('preferences.calendar-format-input', 0) -register('preferences.february-29', 0) # 0: 02/28; 1: 03/01; 2: only the 02/29 -register('preferences.cprefix', 'C%04d') -register('preferences.default-source', False) -register('preferences.tag-on-import', False) -register('preferences.tag-on-import-format', _("Imported %Y/%m/%d %H:%M:%S")) -register('preferences.eprefix', 'E%04d') -register('preferences.family-warn', True) -register('preferences.fprefix', 'F%04d') -register('preferences.hide-ep-msg', False) -register('preferences.invalid-date-format', "%s") -register('preferences.iprefix', 'I%04d') -register('preferences.name-format', 1) -register('preferences.place-format', 0) -register('preferences.place-auto', True) -register('preferences.coord-format', 0) -register('preferences.patronimic-surname', False) -register('preferences.no-given-text', "[%s]" % _("Missing Given Name")) -register('preferences.no-record-text', "[%s]" % _("Missing Record")) -register('preferences.no-surname-text', "[%s]" % _("Missing Surname")) -register('preferences.nprefix', 'N%04d') -register('preferences.online-maps', False) -register('preferences.oprefix', 'O%04d') -register('preferences.paper-metric', 0) -register('preferences.paper-preference', 'Letter') -register('preferences.pprefix', 'P%04d') -register('preferences.private-given-text', "%s" % _T_("[Living]")) -register('preferences.private-record-text', "[%s]" % _("Private Record")) -register('preferences.private-surname-text', "%s" % _T_("[Living]")) -register('preferences.rprefix', 'R%04d') -register('preferences.sprefix', 'S%04d') -register('preferences.use-last-view', False) -register('preferences.last-view', '') -register('preferences.last-views', []) -register('preferences.family-relation-type', 3) # UNKNOWN -register('preferences.age-display-precision', 1) -register('preferences.age-after-death', True) -register('preferences.cite-plugin', 'cite-default') - -register('colors.scheme', 0) -register('colors.male-alive', ['#b8cee6', '#1f344a']) -register('colors.male-dead', ['#b8cee6', '#2d3039']) -register('colors.female-alive', ['#feccf0', '#62242D']) -register('colors.female-dead', ['#feccf0', '#3a292b']) -register('colors.other-alive', ['#94ef9e', '#285b27']) -register('colors.other-dead', ['#94ef9e', '#062304']) -register('colors.unknown-alive', ['#f3dbb6', '#75507B']) -register('colors.unknown-dead', ['#f3dbb6', '#35103b']) -register('colors.family', ['#eeeeee', '#454545']) -register('colors.family-married', ['#eeeeee', '#454545']) -register('colors.family-unmarried', ['#eeeeee', '#454545']) -register('colors.family-civil-union', ['#eeeeee', '#454545']) -register('colors.family-unknown', ['#eeeeee', '#454545']) -register('colors.family-divorced', ['#ffdede', '#5c3636']) -register('colors.home-person', ['#bbe68a', '#304918']) -register('colors.border-male-alive', ['#1f4986', '#171d26']) -register('colors.border-male-dead', ['#000000', '#000000']) -register('colors.border-female-alive', ['#861f69', '#261111']) -register('colors.border-female-dead', ['#000000', '#000000']) -register('colors.border-other-alive', ['#2a5f16', '#26a269']) -register('colors.border-other-dead', ['#000000', '#000000']) -register('colors.border-unknown-alive', ['#8e5801', '#8e5801']) -register('colors.border-unknown-dead', ['#000000', '#000000']) -register('colors.border-family', ['#cccccc', '#252525']) -register('colors.border-family-divorced', ['#ff7373', '#720b0b']) - -register('researcher.researcher-addr', '') -register('researcher.researcher-locality', '') -register('researcher.researcher-city', '') -register('researcher.researcher-country', '') -register('researcher.researcher-email', '') -register('researcher.researcher-name', '') -register('researcher.researcher-phone', '') -register('researcher.researcher-postal', '') -register('researcher.researcher-state', '') - -register('plugin.hiddenplugins', []) -register('plugin.addonplugins', []) - -register('utf8.in-use', False) -register('utf8.selected-font', '') -register('utf8.death-symbol', 2) -register('utf8.birth-symbol', "*") -register('utf8.baptism-symbol', "~") -register('utf8.marriage-symbol', "oo") -register('utf8.engaged-symbol', "o") -register('utf8.divorce-symbol', "o|o") -register('utf8.partner-symbol', "o-o") -register('utf8.dead-symbol', "✝") -register('utf8.buried-symbol', "[]") -register('utf8.cremated-symbol', "⚱") -register('utf8.killed-symbol', "x") - -if __debug__: # enable a simple CLI test to see if the datestrings exist - register('test.january', _("January", "localized lexeme inflections")) - -#--------------------------------------------------------------- +register("interface.dont-ask", False) +register( + "interface.view-categories", + [ + "Dashboard", + "People", + "Relationships", + "Families", + "Ancestry", + "Events", + "Places", + "Geography", + "Sources", + "Citations", + "Repositories", + "Media", + "Notes", + ], +) +register("interface.filter", False) +register("interface.fullscreen", False) +register("interface.grampletbar-close", False) +register("interface.ignore-gexiv2", False) +register("interface.ignore-pil", False) +register("interface.ignore-osmgpsmap", False) +register("interface.main-window-height", 500) +register("interface.main-window-horiz-position", 15) +register("interface.main-window-vert-position", 10) +register("interface.main-window-width", 775) +register("interface.mapservice", "OpenStreetMap") +register("interface.open-with-default-viewer", False) +register("interface.pedview-layout", 0) +register("interface.pedview-show-images", True) +register("interface.pedview-show-marriage", False) +register("interface.pedview-tree-size", 5) +register("interface.pedview-tree-direction", 2) +register("interface.pedview-show-unknown-people", False) +register("interface.place-name-height", 100) +register("interface.place-name-width", 450) +register("interface.sidebar-text", True) +register("interface.size-checked", False) +register("interface.statusbar", 1) +register("interface.toolbar-on", True) +register("interface.toolbar-text", False) +register("interface.hide-lds", False) +register("interface.toolbar-clipboard", True) +register("interface.toolbar-addons", True) +register("interface.toolbar-preference", True) +register("interface.toolbar-reports", True) +register("interface.toolbar-tools", True) +register("interface.view", True) +register("interface.surname-box-height", 150) +register("interface.treemodel-cache-size", 1000) + +register("paths.recent-export-dir", USER_HOME) +register("paths.recent-file", "") +register("paths.recent-import-dir", USER_HOME) +register("paths.report-directory", USER_HOME) +register("paths.website-directory", USER_HOME) +register("paths.website-cms-uri", "") +register("paths.website-cal-uri", "") +register("paths.website-extra-page-uri", "") +register("paths.website-extra-page-name", "") +register("paths.quick-backup-directory", USER_HOME) +register( + "paths.quick-backup-filename", + "%(filename)s_%(year)d-%(month)02d-%(day)02d.%(extension)s", +) + +register("preferences.quick-backup-include-mode", False) +register("preferences.date-format", 0) +register("preferences.calendar-format-report", 0) +register("preferences.calendar-format-input", 0) +register("preferences.february-29", 0) # 0: 02/28; 1: 03/01; 2: only the 02/29 +register("preferences.cprefix", "C%04d") +register("preferences.default-source", False) +register("preferences.tag-on-import", False) +register("preferences.tag-on-import-format", _("Imported %Y/%m/%d %H:%M:%S")) +register("preferences.eprefix", "E%04d") +register("preferences.family-warn", True) +register("preferences.fprefix", "F%04d") +register("preferences.hide-ep-msg", False) +register("preferences.invalid-date-format", "%s") +register("preferences.iprefix", "I%04d") +register("preferences.name-format", 1) +register("preferences.place-format", 0) +register("preferences.place-auto", True) +register("preferences.coord-format", 0) +register("preferences.patronimic-surname", False) +register("preferences.no-given-text", "[%s]" % _("Missing Given Name")) +register("preferences.no-record-text", "[%s]" % _("Missing Record")) +register("preferences.no-surname-text", "[%s]" % _("Missing Surname")) +register("preferences.nprefix", "N%04d") +register("preferences.online-maps", False) +register("preferences.oprefix", "O%04d") +register("preferences.paper-metric", 0) +register("preferences.paper-preference", "Letter") +register("preferences.pprefix", "P%04d") +register("preferences.private-given-text", "%s" % _T_("[Living]")) +register("preferences.private-record-text", "[%s]" % _("Private Record")) +register("preferences.private-surname-text", "%s" % _T_("[Living]")) +register("preferences.rprefix", "R%04d") +register("preferences.sprefix", "S%04d") +register("preferences.use-last-view", False) +register("preferences.last-view", "") +register("preferences.last-views", []) +register("preferences.family-relation-type", 3) # UNKNOWN +register("preferences.age-display-precision", 1) +register("preferences.age-after-death", True) +register("preferences.cite-plugin", "cite-default") + +register("colors.scheme", 0) +register("colors.male-alive", ["#b8cee6", "#1f344a"]) +register("colors.male-dead", ["#b8cee6", "#2d3039"]) +register("colors.female-alive", ["#feccf0", "#62242D"]) +register("colors.female-dead", ["#feccf0", "#3a292b"]) +register("colors.other-alive", ["#94ef9e", "#285b27"]) +register("colors.other-dead", ["#94ef9e", "#062304"]) +register("colors.unknown-alive", ["#f3dbb6", "#75507B"]) +register("colors.unknown-dead", ["#f3dbb6", "#35103b"]) +register("colors.family", ["#eeeeee", "#454545"]) +register("colors.family-married", ["#eeeeee", "#454545"]) +register("colors.family-unmarried", ["#eeeeee", "#454545"]) +register("colors.family-civil-union", ["#eeeeee", "#454545"]) +register("colors.family-unknown", ["#eeeeee", "#454545"]) +register("colors.family-divorced", ["#ffdede", "#5c3636"]) +register("colors.home-person", ["#bbe68a", "#304918"]) +register("colors.border-male-alive", ["#1f4986", "#171d26"]) +register("colors.border-male-dead", ["#000000", "#000000"]) +register("colors.border-female-alive", ["#861f69", "#261111"]) +register("colors.border-female-dead", ["#000000", "#000000"]) +register("colors.border-other-alive", ["#2a5f16", "#26a269"]) +register("colors.border-other-dead", ["#000000", "#000000"]) +register("colors.border-unknown-alive", ["#8e5801", "#8e5801"]) +register("colors.border-unknown-dead", ["#000000", "#000000"]) +register("colors.border-family", ["#cccccc", "#252525"]) +register("colors.border-family-divorced", ["#ff7373", "#720b0b"]) + +register("researcher.researcher-addr", "") +register("researcher.researcher-locality", "") +register("researcher.researcher-city", "") +register("researcher.researcher-country", "") +register("researcher.researcher-email", "") +register("researcher.researcher-name", "") +register("researcher.researcher-phone", "") +register("researcher.researcher-postal", "") +register("researcher.researcher-state", "") + +register("plugin.hiddenplugins", []) +register("plugin.addonplugins", []) + +register("utf8.in-use", False) +register("utf8.selected-font", "") +register("utf8.death-symbol", 2) +register("utf8.birth-symbol", "*") +register("utf8.baptism-symbol", "~") +register("utf8.marriage-symbol", "oo") +register("utf8.engaged-symbol", "o") +register("utf8.divorce-symbol", "o|o") +register("utf8.partner-symbol", "o-o") +register("utf8.dead-symbol", "✝") +register("utf8.buried-symbol", "[]") +register("utf8.cremated-symbol", "⚱") +register("utf8.killed-symbol", "x") + +if __debug__: # enable a simple CLI test to see if the datestrings exist + register("test.january", _("January", "localized lexeme inflections")) + +# --------------------------------------------------------------- # # Upgrade Conversions go here. # -#--------------------------------------------------------------- +# --------------------------------------------------------------- # If we have not already upgraded to this version, # we can tell by seeing if there is a key file for this version: @@ -361,17 +403,16 @@ def emit(key): if os.path.exists(os.path.join(USER_CONFIG, "keys.ini")): # read it in old style: logging.warning("Importing old key file 'keys.ini'...") - CONFIGMAN.load(os.path.join(USER_CONFIG, "keys.ini"), - oldstyle=True) + CONFIGMAN.load(os.path.join(USER_CONFIG, "keys.ini"), oldstyle=True) logging.warning("Done importing old key file 'keys.ini'") # other version upgrades here... # check previous version of gramps: fullpath, filename = os.path.split(CONFIGMAN.filename) fullpath, previous = os.path.split(fullpath) - match = re.match(r'gramps(\d*)', previous) + match = re.match(r"gramps(\d*)", previous) if match: # cycle back looking for previous versions of gramps - for i in range(1, 20): # check back 2 gramps versions + for i in range(1, 20): # check back 2 gramps versions # ----------------------------------------- # TODO: Assumes minor version is a decimal, not semantic versioning # Uses ordering ... 4.9, 5.0, 5.1, ... @@ -380,23 +421,22 @@ def emit(key): # Perhaps addings specific list of versions to check # ----------------------------------------- digits = str(int(match.groups()[0]) - i) - previous_grampsini = os.path.join(fullpath, "gramps" + digits, - filename) + previous_grampsini = os.path.join(fullpath, "gramps" + digits, filename) if os.path.exists(previous_grampsini): - logging.warning("Importing old config file '%s'...", - previous_grampsini) + logging.warning("Importing old config file '%s'...", previous_grampsini) CONFIGMAN.load(previous_grampsini) - logging.warning("Done importing old config file '%s'", - previous_grampsini) + logging.warning( + "Done importing old config file '%s'", previous_grampsini + ) break -#--------------------------------------------------------------- +# --------------------------------------------------------------- # # Now, load the settings from the config file, if one # -#--------------------------------------------------------------- +# --------------------------------------------------------------- CONFIGMAN.load() config = CONFIGMAN -if config.get('database.backend') == 'bsddb': - config.set('database.backend', 'sqlite') +if config.get("database.backend") == "bsddb": + config.set("database.backend", "sqlite") diff --git a/gramps/gen/const.py b/gramps/gen/const.py index 51649ddb19b..b24ce6fc397 100644 --- a/gramps/gen/const.py +++ b/gramps/gen/const.py @@ -25,61 +25,61 @@ Provides constants for other modules """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import os import sys import uuid from gi.repository import GLib -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .git_revision import get_git_revision from .constfunc import get_env_var from ..version import VERSION, VERSION_TUPLE, major_version, DEV_VERSION from .utils.resourcepath import ResourcePath from .utils.grampslocale import GrampsLocale -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps program name # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- PROGRAM_NAME = "Gramps" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Gramps Websites # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- URL_HOMEPAGE = "http://gramps-project.org/" URL_MAILINGLIST = "http://sourceforge.net/mail/?group_id=25770" URL_BUGHOME = "http://gramps-project.org/bugs" URL_BUGTRACKER = "http://gramps-project.org/bugs/bug_report_page.php" URL_WIKISTRING = "http://gramps-project.org/wiki/index.php?title=" URL_MANUAL_PAGE = "Gramps_%s_Wiki_Manual" % major_version -URL_MANUAL_DATA = '%s_-_Entering_and_editing_data:_detailed' % URL_MANUAL_PAGE -URL_MANUAL_SECT1 = '%s_-_part_1' % URL_MANUAL_DATA -URL_MANUAL_SECT2 = '%s_-_part_2' % URL_MANUAL_DATA -URL_MANUAL_SECT3 = '%s_-_part_3' % URL_MANUAL_DATA +URL_MANUAL_DATA = "%s_-_Entering_and_editing_data:_detailed" % URL_MANUAL_PAGE +URL_MANUAL_SECT1 = "%s_-_part_1" % URL_MANUAL_DATA +URL_MANUAL_SECT2 = "%s_-_part_2" % URL_MANUAL_DATA +URL_MANUAL_SECT3 = "%s_-_part_3" % URL_MANUAL_DATA WIKI_FAQ = "FAQ" WIKI_KEYBINDINGS = "Gramps_%s_Wiki_Manual_-_Keybindings" % major_version WIKI_EXTRAPLUGINS = "%s_Addons" % major_version WIKI_EXTRAPLUGINS_RAWDATA = "Plugins%s&action=raw" % major_version -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Mime Types # -#------------------------------------------------------------------------- -APP_FAMTREE = 'x-directory/normal' +# ------------------------------------------------------------------------- +APP_FAMTREE = "x-directory/normal" APP_GRAMPS = "application/x-gramps" APP_GRAMPS_XML = "application/x-gramps-xml" APP_GEDCOM = "application/x-gedcom" @@ -87,43 +87,42 @@ APP_GENEWEB = "application/x-geneweb" APP_VCARD = ["text/x-vcard", "text/x-vcalendar"] -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Determine the home directory. According to Wikipedia, most UNIX like # systems use HOME. I'm assuming that this would apply to OS X as well. # Windows apparently uses USERPROFILE # -#------------------------------------------------------------------------- -if 'GRAMPSHOME' in os.environ: - USER_HOME = get_env_var('GRAMPSHOME') - HOME_DIR = os.path.join(USER_HOME, 'gramps') -elif 'USERPROFILE' in os.environ: - USER_HOME = get_env_var('USERPROFILE') - if 'APPDATA' in os.environ: - HOME_DIR = os.path.join(get_env_var('APPDATA'), 'gramps') +# ------------------------------------------------------------------------- +if "GRAMPSHOME" in os.environ: + USER_HOME = get_env_var("GRAMPSHOME") + HOME_DIR = os.path.join(USER_HOME, "gramps") +elif "USERPROFILE" in os.environ: + USER_HOME = get_env_var("USERPROFILE") + if "APPDATA" in os.environ: + HOME_DIR = os.path.join(get_env_var("APPDATA"), "gramps") else: - HOME_DIR = os.path.join(USER_HOME, 'gramps') + HOME_DIR = os.path.join(USER_HOME, "gramps") else: - USER_HOME = get_env_var('HOME') - HOME_DIR = os.path.join(USER_HOME, '.gramps') + USER_HOME = get_env_var("HOME") + HOME_DIR = os.path.join(USER_HOME, ".gramps") ORIG_HOME_DIR = HOME_DIR -if 'SAFEMODE' in os.environ: - if 'USERPROFILE' in os.environ: - USER_HOME = get_env_var('USERPROFILE') +if "SAFEMODE" in os.environ: + if "USERPROFILE" in os.environ: + USER_HOME = get_env_var("USERPROFILE") else: - USER_HOME = get_env_var('HOME') - HOME_DIR = get_env_var('SAFEMODE') + USER_HOME = get_env_var("HOME") + HOME_DIR = get_env_var("SAFEMODE") -if (os.path.exists(HOME_DIR) or 'GRAMPSHOME' in os.environ - or 'SAFEMODE' in os.environ): +if os.path.exists(HOME_DIR) or "GRAMPSHOME" in os.environ or "SAFEMODE" in os.environ: USER_DATA = HOME_DIR USER_CONFIG = HOME_DIR USER_CACHE = HOME_DIR else: - USER_DATA = os.path.join(GLib.get_user_data_dir(), 'gramps') - USER_CONFIG = os.path.join(GLib.get_user_config_dir(), 'gramps') - USER_CACHE = os.path.join(GLib.get_user_cache_dir(), 'gramps') + USER_DATA = os.path.join(GLib.get_user_data_dir(), "gramps") + USER_CONFIG = os.path.join(GLib.get_user_config_dir(), "gramps") + USER_CACHE = os.path.join(GLib.get_user_cache_dir(), "gramps") USER_PICTURES = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES) if not USER_PICTURES: @@ -144,26 +143,36 @@ USER_PLUGINS = os.path.join(USER_DATA_VERSION, "plugins") USER_CSS = os.path.join(USER_DATA, "css") # dirs checked/made for each Gramps session -USER_DIRLIST = (USER_HOME, USER_CACHE, USER_CONFIG, USER_DATA, VERSION_DIR, - USER_DATA_VERSION, THUMB_DIR, THUMB_NORMAL, THUMB_LARGE, - USER_PLUGINS, USER_CSS) - - -#------------------------------------------------------------------------- +USER_DIRLIST = ( + USER_HOME, + USER_CACHE, + USER_CONFIG, + USER_DATA, + VERSION_DIR, + USER_DATA_VERSION, + THUMB_DIR, + THUMB_NORMAL, + THUMB_LARGE, + USER_PLUGINS, + USER_CSS, +) + + +# ------------------------------------------------------------------------- # # Paths to python modules - assumes that the root directory is one level # above this one, and that the plugins directory is below the root directory. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) sys.path.insert(0, ROOT_DIR) -git_revision = get_git_revision(ROOT_DIR).replace('\n', '') -if sys.platform == 'win32' and git_revision == "": +git_revision = get_git_revision(ROOT_DIR).replace("\n", "") +if sys.platform == "win32" and git_revision == "": git_revision = get_git_revision(os.path.split(ROOT_DIR)[1]) if DEV_VERSION: VERSION += git_revision -#VERSION += "-1" +# VERSION += "-1" # # Glade files @@ -180,11 +189,11 @@ USE_TIPS = False -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Paths to data files. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- _resources = ResourcePath() DATA_DIR = _resources.data_dir IMAGE_DIR = _resources.image_dir @@ -196,13 +205,13 @@ LOGO = os.path.join(IMAGE_DIR, "logo.png") SPLASH = os.path.join(IMAGE_DIR, "splash.jpg") -LICENSE_FILE = os.path.join(_resources.doc_dir, 'COPYING') +LICENSE_FILE = os.path.join(_resources.doc_dir, "COPYING") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps environment variables dictionary # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- ENV = { "USER_HOME": USER_HOME, "USER_CACHE": USER_CACHE, @@ -223,25 +232,26 @@ "IMAGE_DIR": IMAGE_DIR, } -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Init Localization # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- GRAMPS_LOCALE = GrampsLocale(localedir=_resources.locale_dir) _ = GRAMPS_LOCALE.translation.sgettext -GTK_GETTEXT_DOMAIN = 'gtk30' +GTK_GETTEXT_DOMAIN = "gtk30" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # About box information # -#------------------------------------------------------------------------- -COPYRIGHT_MSG = "© 2001-2006 Donald N. Allingham\n" \ - "© 2007-2022 The Gramps Developers" -COMMENTS = _("Gramps\n (Genealogical Research and Analysis " - "Management Programming System)\n" - "is a personal genealogy program.") +# ------------------------------------------------------------------------- +COPYRIGHT_MSG = "© 2001-2006 Donald N. Allingham\n" "© 2007-2022 The Gramps Developers" +COMMENTS = _( + "Gramps\n (Genealogical Research and Analysis " + "Management Programming System)\n" + "is a personal genealogy program." +) AUTHORS = [ "Alexander Roitman", "Benny Malengier", @@ -252,20 +262,20 @@ "Martin Hawlisch", "Richard Taylor", "Tim Waugh", - "John Ralls" - ] + "John Ralls", +] AUTHORS_FILE = os.path.join(DATA_DIR, "authors.xml") DOCUMENTERS = [ - 'Alexander Roitman', - ] + "Alexander Roitman", +] -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Constants # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- THUMBSCALE = 96.0 THUMBSCALE_LARGE = 180.0 SIZE_NORMAL = 0 @@ -275,14 +285,14 @@ NO_GIVEN = "(%s)" % _("none", "given-name") ARABIC_COMMA = "،" ARABIC_SEMICOLON = "؛" -DOCGEN_OPTIONS = 'Docgen Options' -COLON = _(':') # Translators: needed for French, ignore otherwise +DOCGEN_OPTIONS = "Docgen Options" +COLON = _(":") # Translators: needed for French, ignore otherwise -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Options Constants # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- LONGOPTS = [ "action=", @@ -307,8 +317,7 @@ "help", "import=", "load-modules=", - "list" - "name=", + "list" "name=", "oaf-activate-iid=", "oaf-ior-fd=", "oaf-private", @@ -333,20 +342,20 @@ SHORTOPTS = "O:U:P:C:i:e:f:a:p:d:c:r:lLthuv?syqSD:" -GRAMPS_UUID = uuid.UUID('516cd010-5a41-470f-99f8-eb22f1098ad6') +GRAMPS_UUID = uuid.UUID("516cd010-5a41-470f-99f8-eb22f1098ad6") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Fanchart Constants # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -PIXELS_PER_GENERATION = 50 # size of radius for generation -BORDER_EDGE_WIDTH = 10 # empty white box size at edge to indicate parents -CHILDRING_WIDTH = 12 # width of the children ring inside the person -TRANSLATE_PX = 10 # size of the central circle, used to move the chart -PAD_PX = 4 # padding with edges -PAD_TEXT = 2 # padding for text in boxes +PIXELS_PER_GENERATION = 50 # size of radius for generation +BORDER_EDGE_WIDTH = 10 # empty white box size at edge to indicate parents +CHILDRING_WIDTH = 12 # width of the children ring inside the person +TRANSLATE_PX = 10 # size of the central circle, used to move the chart +PAD_PX = 4 # padding with edges +PAD_TEXT = 2 # padding for text in boxes BACKGROUND_SCHEME1 = 0 BACKGROUND_SCHEME2 = 1 @@ -357,25 +366,31 @@ BACKGROUND_SINGLE_COLOR = 6 BACKGROUND_GRAD_PERIOD = 7 GENCOLOR = { - BACKGROUND_SCHEME1: ((255, 63, 0), - (255, 175, 15), - (255, 223, 87), - (255, 255, 111), - (159, 255, 159), - (111, 215, 255), - (79, 151, 255), - (231, 23, 255), - (231, 23, 121), - (210, 170, 124), - (189, 153, 112)), - BACKGROUND_SCHEME2: ((229, 191, 252), - (191, 191, 252), - (191, 222, 252), - (183, 219, 197), - (206, 246, 209)), - BACKGROUND_WHITE: ((255, 255, 255), - (255, 255, 255),), - } + BACKGROUND_SCHEME1: ( + (255, 63, 0), + (255, 175, 15), + (255, 223, 87), + (255, 255, 111), + (159, 255, 159), + (111, 215, 255), + (79, 151, 255), + (231, 23, 255), + (231, 23, 121), + (210, 170, 124), + (189, 153, 112), + ), + BACKGROUND_SCHEME2: ( + (229, 191, 252), + (191, 191, 252), + (191, 222, 252), + (183, 219, 197), + (206, 246, 209), + ), + BACKGROUND_WHITE: ( + (255, 255, 255), + (255, 255, 255), + ), +} MAX_AGE = 100 GRADIENTSCALE = 5 diff --git a/gramps/gen/constfunc.py b/gramps/gen/constfunc.py index 5b7089fe004..30ce1fdba6c 100644 --- a/gramps/gen/constfunc.py +++ b/gramps/gen/constfunc.py @@ -25,30 +25,31 @@ perform a translation on import, eg Gtk. """ -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # python modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ import platform import sys import os -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Platforms # Never test on LINUX, handle Linux in the else statement as default # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- LINUX = ["Linux", "linux", "linux2"] MACOS = ["Darwin", "darwin"] WINDOWS = ["Windows", "win32"] -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Platform determination functions # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- + def lin(): """ @@ -59,6 +60,7 @@ def lin(): return True return False + def mac(): """ Return True if a Macintosh system @@ -67,6 +69,7 @@ def mac(): return True return False + def win(): """ Return True if a windows system @@ -75,10 +78,12 @@ def win(): return True return False + ## The following functions do import gtk, but only when called. They ## should only be called after translation system has been ## initialized! + def is_quartz(): """ Tests to see if Python is currently running with gtk and @@ -87,8 +92,9 @@ def is_quartz(): if mac(): try: import gi - gi.require_version('Gtk', '3.0') - gi.require_version('Gdk', '3.0') + + gi.require_version("Gtk", "3.0") + gi.require_version("Gdk", "3.0") from gi.repository import Gtk from gi.repository import Gdk except ImportError: @@ -96,6 +102,7 @@ def is_quartz(): return Gdk.Display.get_default().__class__.__name__.endswith("QuartzDisplay") return False + def has_display(): """ Tests to see if Python is currently running with gtk @@ -105,27 +112,29 @@ def has_display(): temp, sys.argv = sys.argv, sys.argv[:1] try: import gi - gi.require_version('Gtk', '3.0') - gi.require_version('Gdk', '3.0') + + gi.require_version("Gtk", "3.0") + gi.require_version("Gdk", "3.0") from gi.repository import Gtk from gi.repository import Gdk except ImportError: return False try: - test = Gtk.init_check(temp) and \ - Gdk.Display.get_default() + test = Gtk.init_check(temp) and Gdk.Display.get_default() sys.argv = temp return bool(test) except: sys.argv = temp return False + # A couple of places add menu accelerators using , which doesn't # work with Gtk-quartz. is the usually correct replacement, but # in one case the key is a number, and number is used by Spaces # (a mac feature), so we'll use control instead. + def mod_key(): """ Returns a string to pass to an accelerator map. @@ -136,6 +145,7 @@ def mod_key(): return "" + # Python2 on Windows munges environemnt variables to match the system # code page. This breaks all manner of things and the workaround # though a bit ugly, is encapsulated here. Use this to retrieve @@ -146,21 +156,22 @@ def mod_key(): def get_env_var(name, default=None): - ''' + """ Python2 on Windows can't directly read unicode values from environment variables. This routine does so using the native C wide-character function. - ''' + """ if not name or name not in os.environ: return default return os.environ[name] + def get_curr_dir(): - ''' + """ In Python2 on Windows, os.getcwd() returns a string encoded with the current code page, which may not be able to correctly handle an arbitrary unicode character in a path. This function uses the native GetCurrentDirectory function to return a unicode cwd. - ''' + """ return os.getcwd() diff --git a/gramps/gen/datehandler/__init__.py b/gramps/gen/datehandler/__init__.py index 9ef7dce7ef2..788b7acd96b 100644 --- a/gramps/gen/datehandler/__init__.py +++ b/gramps/gen/datehandler/__init__.py @@ -23,24 +23,31 @@ Class handling language-specific selection for date parser and displayer. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..utils.grampslocale import GrampsLocale from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext # import prerequisites for localized handlers -from ._datehandler import (LANG, LANG_SHORT, LANG_TO_PARSER, LANG_TO_DISPLAY, - locale_tformat, main_locale) +from ._datehandler import ( + LANG, + LANG_SHORT, + LANG_TO_PARSER, + LANG_TO_DISPLAY, + locale_tformat, + main_locale, +) from . import _datestrings # Import all the localized handlers @@ -84,14 +91,14 @@ else: parser = LANG_TO_PARSER[LANG_SHORT](plocale=dlocale) except: - logging.warning( - _("Date parser for '%s' not available, using default") % LANG) + logging.warning(_("Date parser for '%s' not available, using default") % LANG) parser = LANG_TO_PARSER["C"](plocale=dlocale) # Initialize global displayer try: from ..config import config - val = config.get('preferences.date-format') + + val = config.get("preferences.date-format") except: val = 0 @@ -101,8 +108,7 @@ else: displayer = LANG_TO_DISPLAY[LANG_SHORT](val, blocale=dlocale) except: - logging.warning( - _("Date displayer for '%s' not available, using default") % LANG) + logging.warning(_("Date displayer for '%s' not available, using default") % LANG) displayer = LANG_TO_DISPLAY["C"](val, blocale=dlocale) @@ -112,17 +118,23 @@ # set GRAMPS_RESOURCES then: python3 -m gramps.gen.datehandler.__init__ if __name__ == "__main__": from ._datedisplay import DateDisplay + m = 0 date_handlers = sorted(LANG_TO_DISPLAY.items()) - for l,d in date_handlers: - if len(l) != 2 and l not in ('zh_TW'): # Chinese has two date_handlers + for l, d in date_handlers: + if len(l) != 2 and l not in ("zh_TW"): # Chinese has two date_handlers continue - if l.upper() == l and (l.lower(),d) in date_handlers: - continue # don't need to see the upper-case variant also + if l.upper() == l and (l.lower(), d) in date_handlers: + continue # don't need to see the upper-case variant also m = max(m, len(d.formats)) - print("{}: {} {} own-f:{} own-dc:{} own-dg:{}".format( - l, len(d.formats), d.formats, - d.formats != DateDisplay.formats, - d._display_calendar != DateDisplay._display_calendar, - d._display_gregorian != DateDisplay._display_gregorian)) + print( + "{}: {} {} own-f:{} own-dc:{} own-dg:{}".format( + l, + len(d.formats), + d.formats, + d.formats != DateDisplay.formats, + d._display_calendar != DateDisplay._display_calendar, + d._display_gregorian != DateDisplay._display_gregorian, + ) + ) print("MAX: ", m) diff --git a/gramps/gen/datehandler/_date_ar.py b/gramps/gen/datehandler/_date_ar.py index df9af008ec2..0fe9222d277 100644 --- a/gramps/gen/datehandler/_date_ar.py +++ b/gramps/gen/datehandler/_date_ar.py @@ -41,6 +41,7 @@ from ._datehandler import register_datehandler from ..const import ARABIC_COMMA + # ------------------------------------------------------------------------- # # Arabic parser class diff --git a/gramps/gen/datehandler/_date_bg.py b/gramps/gen/datehandler/_date_bg.py index bd836323c69..3abb8bd1236 100644 --- a/gramps/gen/datehandler/_date_bg.py +++ b/gramps/gen/datehandler/_date_bg.py @@ -40,13 +40,13 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Bulgarian parser # # ------------------------------------------------------------------------- class DateParserBG(DateParser): - modifier_to_int = { "преди": Date.MOD_BEFORE, "пр.": Date.MOD_BEFORE, diff --git a/gramps/gen/datehandler/_date_ca.py b/gramps/gen/datehandler/_date_ca.py index 1f0fc133ec9..c97fe5d9874 100644 --- a/gramps/gen/datehandler/_date_ca.py +++ b/gramps/gen/datehandler/_date_ca.py @@ -42,13 +42,13 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Catalan parser # # ------------------------------------------------------------------------- class DateParserCA(DateParser): - modifier_to_int = { "abans de": Date.MOD_BEFORE, "abans": Date.MOD_BEFORE, diff --git a/gramps/gen/datehandler/_date_cs.py b/gramps/gen/datehandler/_date_cs.py index fe03eb0c92d..af838114452 100644 --- a/gramps/gen/datehandler/_date_cs.py +++ b/gramps/gen/datehandler/_date_cs.py @@ -40,6 +40,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Czech parser diff --git a/gramps/gen/datehandler/_date_da.py b/gramps/gen/datehandler/_date_da.py index d1470d38ab6..56c939fd028 100644 --- a/gramps/gen/datehandler/_date_da.py +++ b/gramps/gen/datehandler/_date_da.py @@ -40,6 +40,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Danish parser class diff --git a/gramps/gen/datehandler/_date_de.py b/gramps/gen/datehandler/_date_de.py index 1425f7c0ea6..dbadf1debaf 100644 --- a/gramps/gen/datehandler/_date_de.py +++ b/gramps/gen/datehandler/_date_de.py @@ -40,13 +40,13 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # German parser # # ------------------------------------------------------------------------- class DateParserDE(DateParser): - month_to_int = DateParser.month_to_int # Always add german and austrian name variants no matter what the current # locale is diff --git a/gramps/gen/datehandler/_date_el.py b/gramps/gen/datehandler/_date_el.py index 928c56152a7..284ed29b834 100644 --- a/gramps/gen/datehandler/_date_el.py +++ b/gramps/gen/datehandler/_date_el.py @@ -41,6 +41,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Greek parser class diff --git a/gramps/gen/datehandler/_date_es.py b/gramps/gen/datehandler/_date_es.py index 450c61c0c01..88dda3d4f43 100644 --- a/gramps/gen/datehandler/_date_es.py +++ b/gramps/gen/datehandler/_date_es.py @@ -40,13 +40,13 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Spanish parser # # ------------------------------------------------------------------------- class DateParserES(DateParser): - modifier_to_int = { "antes de": Date.MOD_BEFORE, "antes": Date.MOD_BEFORE, @@ -123,15 +123,31 @@ class DateDisplayES(DateDisplay): Spanish language date display class. """ - short_months = ( "", "ene", "feb", "mar", "abr", "may", - "jun", "jul", "ago", "sep", "oct", "nov", - "dic" ) + short_months = ( + "", + "ene", + "feb", + "mar", + "abr", + "may", + "jun", + "jul", + "ago", + "sep", + "oct", + "nov", + "dic", + ) calendar = ( - "", "Juliano", "Hebreo", - "Revolucionario francés", "Persa", "Islámico", - "Sueco" - ) + "", + "Juliano", + "Hebreo", + "Revolucionario francés", + "Persa", + "Islámico", + "Sueco", + ) _mod_str = ("", "antes de ", "después de ", "hacia ", "", "", "") diff --git a/gramps/gen/datehandler/_date_fi.py b/gramps/gen/datehandler/_date_fi.py index 011cdbc55f8..0bd081a9174 100644 --- a/gramps/gen/datehandler/_date_fi.py +++ b/gramps/gen/datehandler/_date_fi.py @@ -40,6 +40,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Finnish parser @@ -49,7 +50,6 @@ # - Parsing Finnish is much more complicated than English # ------------------------------------------------------------------------- class DateParserFI(DateParser): - # NOTE: these need to be in lower case because the "key" comparison # is done as lower case. In the display method correct capitalization # can be used. diff --git a/gramps/gen/datehandler/_date_fr.py b/gramps/gen/datehandler/_date_fr.py index 1ffde97aac3..8609d74c453 100644 --- a/gramps/gen/datehandler/_date_fr.py +++ b/gramps/gen/datehandler/_date_fr.py @@ -44,6 +44,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # French parser @@ -270,7 +271,7 @@ def formats_changed(self): "Jour. MOI Année", # 5 "Mois Jour, Année", # 6 "MOI Jour, Année", # 7 - "JJ/MM/AAAA", # 8 + "JJ/MM/AAAA", # 8 ) # this definition must agree with its "_display_gregorian" method @@ -281,12 +282,10 @@ def _display_gregorian(self, date_val, **kwargs): # this must agree with its locale-specific "formats" definition year = self._slash_year(date_val[2], date_val[3]) if self.format == 0: - # ISO return self.display_iso(date_val) elif self.format == 1: - # numerical if date_val[2] < 0 or date_val[3]: @@ -304,7 +303,6 @@ def _display_gregorian(self, date_val, **kwargs): value = value.replace("%Y", str(date_val[2])) elif self.format == 2: - # day month_name year if date_val[0] == 0: @@ -313,10 +311,8 @@ def _display_gregorian(self, date_val, **kwargs): else: value = "%s %s" % (self.long_months[date_val[1]], year) else: - value = "%d %s %s" % (date_val[0], self.long_months[date_val[1]], year) elif self.format == 3: - # day month_abbreviation year if date_val[0] == 0: @@ -325,10 +321,8 @@ def _display_gregorian(self, date_val, **kwargs): else: value = "%s %s" % (self.short_months[date_val[1]], year) else: - value = "%d %s %s" % (date_val[0], self.short_months[date_val[1]], year) elif self.format == 4: - # day. month_name year if date_val[0] == 0: @@ -337,14 +331,12 @@ def _display_gregorian(self, date_val, **kwargs): else: value = "%s %s" % (self.long_months[date_val[1]], year) else: - # base_display : # value = "%d %s %s" % (date_val[0], # self.long_months[date_val[1]], year) value = "%d. %s %s" % (date_val[0], self.long_months[date_val[1]], year) elif self.format == 5: - # day. month_abbreviation year if date_val[0] == 0: @@ -353,7 +345,6 @@ def _display_gregorian(self, date_val, **kwargs): else: value = "%s %s" % (self.short_months[date_val[1]], year) else: - # base_display : # value = "%d %s %s" % (date_val[0], # self.short_months[date_val[1]], year) @@ -364,7 +355,6 @@ def _display_gregorian(self, date_val, **kwargs): year, ) elif self.format == 6: - # month_name day, year if date_val[0] == 0: @@ -375,7 +365,6 @@ def _display_gregorian(self, date_val, **kwargs): else: value = "%s %d, %s" % (self.long_months[date_val[1]], date_val[0], year) elif self.format == 7: - # month_abbreviation day, year if date_val[0] == 0: @@ -390,7 +379,6 @@ def _display_gregorian(self, date_val, **kwargs): year, ) elif self.format == 8: - # French numerical with 0 if date_val[2] < 0 or date_val[3]: @@ -399,9 +387,9 @@ def _display_gregorian(self, date_val, **kwargs): if date_val[0] == date_val[1] == 0: value = str(date_val[2]) else: - value = self.dhformat.replace('%m', str(date_val[1]).zfill(2)) - value = value.replace('%d', str(date_val[0]).zfill(2)) - value = value.replace('%Y', str(date_val[2])) + value = self.dhformat.replace("%m", str(date_val[1]).zfill(2)) + value = value.replace("%d", str(date_val[0]).zfill(2)) + value = value.replace("%Y", str(date_val[2])) else: return self.display_iso(date_val) diff --git a/gramps/gen/datehandler/_date_hr.py b/gramps/gen/datehandler/_date_hr.py index a7f7582a20d..5dd44037c2b 100644 --- a/gramps/gen/datehandler/_date_hr.py +++ b/gramps/gen/datehandler/_date_hr.py @@ -45,6 +45,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Croatian parser diff --git a/gramps/gen/datehandler/_date_hu.py b/gramps/gen/datehandler/_date_hu.py index 22d86dc3602..485aece6630 100644 --- a/gramps/gen/datehandler/_date_hu.py +++ b/gramps/gen/datehandler/_date_hu.py @@ -41,6 +41,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Hungarian parser @@ -48,7 +49,6 @@ # # ------------------------------------------------------------------------- class DateParserHU(DateParser): - month_to_int = DateParser.month_to_int month_to_int["-"] = 0 # to make the Zero month to work diff --git a/gramps/gen/datehandler/_date_is.py b/gramps/gen/datehandler/_date_is.py index cf6c8114481..fce4f9a9b26 100644 --- a/gramps/gen/datehandler/_date_is.py +++ b/gramps/gen/datehandler/_date_is.py @@ -42,6 +42,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Icelandic parser class diff --git a/gramps/gen/datehandler/_date_it.py b/gramps/gen/datehandler/_date_it.py index 8a814d9fa6f..2cceb5ded5e 100644 --- a/gramps/gen/datehandler/_date_it.py +++ b/gramps/gen/datehandler/_date_it.py @@ -42,13 +42,13 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Italian parser # # ------------------------------------------------------------------------- class DateParserIT(DateParser): - modifier_to_int = { "prima del": Date.MOD_BEFORE, "prima": Date.MOD_BEFORE, diff --git a/gramps/gen/datehandler/_date_ja.py b/gramps/gen/datehandler/_date_ja.py index b2c21b3e8d2..0660b00b2e3 100644 --- a/gramps/gen/datehandler/_date_ja.py +++ b/gramps/gen/datehandler/_date_ja.py @@ -43,6 +43,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Japanese parser diff --git a/gramps/gen/datehandler/_date_lt.py b/gramps/gen/datehandler/_date_lt.py index 5ed5e0817b7..faaadca9db8 100644 --- a/gramps/gen/datehandler/_date_lt.py +++ b/gramps/gen/datehandler/_date_lt.py @@ -40,6 +40,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Lithuanian parser diff --git a/gramps/gen/datehandler/_date_nb.py b/gramps/gen/datehandler/_date_nb.py index 333308a699b..13f1839239e 100644 --- a/gramps/gen/datehandler/_date_nb.py +++ b/gramps/gen/datehandler/_date_nb.py @@ -40,6 +40,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Norwegian parser class diff --git a/gramps/gen/datehandler/_date_nl.py b/gramps/gen/datehandler/_date_nl.py index 55abbefd9c3..60e716a89c4 100644 --- a/gramps/gen/datehandler/_date_nl.py +++ b/gramps/gen/datehandler/_date_nl.py @@ -46,13 +46,13 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Dutch parser # # ------------------------------------------------------------------------- class DateParserNL(DateParser): - month_to_int = DateParser.month_to_int # Always add dutch and flemish name variants # no matter what the current locale is diff --git a/gramps/gen/datehandler/_date_pl.py b/gramps/gen/datehandler/_date_pl.py index b190b168cf4..61218b6dd64 100644 --- a/gramps/gen/datehandler/_date_pl.py +++ b/gramps/gen/datehandler/_date_pl.py @@ -43,13 +43,13 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Polish parser # # ------------------------------------------------------------------------- class DateParserPL(DateParser): - month_to_int = DateParser.month_to_int month_to_int["styczeń"] = 1 month_to_int["sty"] = 1 diff --git a/gramps/gen/datehandler/_date_pt.py b/gramps/gen/datehandler/_date_pt.py index f9715ee9069..e74a277c84f 100644 --- a/gramps/gen/datehandler/_date_pt.py +++ b/gramps/gen/datehandler/_date_pt.py @@ -42,13 +42,13 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Portuguese parser # # ------------------------------------------------------------------------- class DateParserPT(DateParser): - modifier_to_int = { "antes de": Date.MOD_BEFORE, "antes": Date.MOD_BEFORE, diff --git a/gramps/gen/datehandler/_date_ru.py b/gramps/gen/datehandler/_date_ru.py index e7cd224e722..f07bab2e814 100644 --- a/gramps/gen/datehandler/_date_ru.py +++ b/gramps/gen/datehandler/_date_ru.py @@ -40,6 +40,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Russian parser diff --git a/gramps/gen/datehandler/_date_sk.py b/gramps/gen/datehandler/_date_sk.py index d9c0c0c6a29..c3055f76ed9 100644 --- a/gramps/gen/datehandler/_date_sk.py +++ b/gramps/gen/datehandler/_date_sk.py @@ -40,13 +40,13 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Slovak parser # # ------------------------------------------------------------------------- class DateParserSK(DateParser): - modifier_to_int = { "pred": Date.MOD_BEFORE, "do": Date.MOD_BEFORE, diff --git a/gramps/gen/datehandler/_date_sl.py b/gramps/gen/datehandler/_date_sl.py index 291818c18be..9199d8c558a 100644 --- a/gramps/gen/datehandler/_date_sl.py +++ b/gramps/gen/datehandler/_date_sl.py @@ -42,6 +42,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Slovenian parser diff --git a/gramps/gen/datehandler/_date_sr.py b/gramps/gen/datehandler/_date_sr.py index c45e14d397e..f405e41f7ae 100644 --- a/gramps/gen/datehandler/_date_sr.py +++ b/gramps/gen/datehandler/_date_sr.py @@ -43,6 +43,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Serbian parser diff --git a/gramps/gen/datehandler/_date_sv.py b/gramps/gen/datehandler/_date_sv.py index 620a6feba4c..46cc0fb8290 100644 --- a/gramps/gen/datehandler/_date_sv.py +++ b/gramps/gen/datehandler/_date_sv.py @@ -40,6 +40,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Swedish parser class diff --git a/gramps/gen/datehandler/_date_uk.py b/gramps/gen/datehandler/_date_uk.py index cfbf142e57f..e17c8cd41d9 100644 --- a/gramps/gen/datehandler/_date_uk.py +++ b/gramps/gen/datehandler/_date_uk.py @@ -42,6 +42,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Ukrainian parser diff --git a/gramps/gen/datehandler/_date_zh_CN.py b/gramps/gen/datehandler/_date_zh_CN.py index 2e4fa947c35..df7d4a898af 100644 --- a/gramps/gen/datehandler/_date_zh_CN.py +++ b/gramps/gen/datehandler/_date_zh_CN.py @@ -42,6 +42,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Simplified-Chinese parser diff --git a/gramps/gen/datehandler/_date_zh_TW.py b/gramps/gen/datehandler/_date_zh_TW.py index e8b6bac022d..8dc39582648 100644 --- a/gramps/gen/datehandler/_date_zh_TW.py +++ b/gramps/gen/datehandler/_date_zh_TW.py @@ -42,6 +42,7 @@ from ._datedisplay import DateDisplay from ._datehandler import register_datehandler + # ------------------------------------------------------------------------- # # Traditional-Chinese parser diff --git a/gramps/gen/datehandler/_datedisplay.py b/gramps/gen/datehandler/_datedisplay.py index eff253f3950..3e98e86bbd3 100644 --- a/gramps/gen/datehandler/_datedisplay.py +++ b/gramps/gen/datehandler/_datedisplay.py @@ -52,6 +52,7 @@ from ..utils.grampslocale import GrampsLocale from ._datestrings import DateStrings + # _T_ is a gramps-defined keyword -- see po/update_po.py and po/genpot.sh def _T_(value, context=""): # enable deferred translations return "%s\x04%s" % (context, value) if context else value diff --git a/gramps/gen/datehandler/_datehandler.py b/gramps/gen/datehandler/_datehandler.py index e346838a7c5..e07b854a110 100644 --- a/gramps/gen/datehandler/_datehandler.py +++ b/gramps/gen/datehandler/_datehandler.py @@ -23,37 +23,38 @@ Class handling language-specific selection for date parser and displayer. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import os -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + log = logging.getLogger(".gen.datehandler") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ._dateparser import DateParser from ._datedisplay import DateDisplay, DateDisplayEn, DateDisplayGB from ..constfunc import win from ..const import GRAMPS_LOCALE as glocale from ..utils.grampslocale import GrampsLocale -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Constants # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- LANG = glocale.calendar # If LANG contains ".UTF-8" use only the part to the left of "." @@ -66,7 +67,7 @@ LANG = os.environ["LANG"] if LANG: - LANG_SHORT = LANG.split('_')[0] + LANG_SHORT = LANG.split("_")[0] else: LANG_SHORT = "C" @@ -74,39 +75,41 @@ LANG_SHORT = str(LANG_SHORT) LANG_TO_PARSER = { - 'C' : DateParser, - } + "C": DateParser, +} LANG_TO_DISPLAY = { - 'C' : DateDisplayEn, - 'ko_KR' : DateDisplay, - } + "C": DateDisplayEn, + "ko_KR": DateDisplay, +} -main_locale = { } # this will be augmented by calls to register_datehandler +main_locale = {} # this will be augmented by calls to register_datehandler -locale_tformat = {} # locale "tformat" (date format) strings +locale_tformat = {} # locale "tformat" (date format) strings for no_handler in ( - ('C', ('%d/%m/%Y',)), - ('eo_EO', 'eo', 'Esperanto', ('%d/%m/%Y',)), # 'eo_EO' is a placeholder - ('he_IL', 'he', 'Hebrew', ('%d/%m/%Y',)), - ('sq_AL', 'sq', 'Albanian', ('%Y/%b/%d',)), - ('ta_IN', 'ta', 'Tamil', ('%A %d %B %Y',)), - ('tr_TR', 'tr', 'Turkish', ('%d/%m/%Y',)), - ('vi_VN', 'vi', 'Vietnamese', ('%d/%m/%Y',)), - ): - format_string = '' + ("C", ("%d/%m/%Y",)), + ("eo_EO", "eo", "Esperanto", ("%d/%m/%Y",)), # 'eo_EO' is a placeholder + ("he_IL", "he", "Hebrew", ("%d/%m/%Y",)), + ("sq_AL", "sq", "Albanian", ("%Y/%b/%d",)), + ("ta_IN", "ta", "Tamil", ("%A %d %B %Y",)), + ("tr_TR", "tr", "Turkish", ("%d/%m/%Y",)), + ("vi_VN", "vi", "Vietnamese", ("%d/%m/%Y",)), +): + format_string = "" for possible_format in no_handler: if isinstance(possible_format, tuple): - format_string = possible_format[0] # pre-seeded date format string + format_string = possible_format[0] # pre-seeded date format string # maintain legacy gramps transformations - format_string = format_string.replace('%y','%Y').replace('-', '/') + format_string = format_string.replace("%y", "%Y").replace("-", "/") for lang_str in no_handler: - if isinstance(lang_str, tuple): continue + if isinstance(lang_str, tuple): + continue main_locale[lang_str] = no_handler[0] - locale_tformat[lang_str] = format_string # locale's date format string + locale_tformat[lang_str] = format_string # locale's date format string + -def register_datehandler(locales,parse_class,display_class): +def register_datehandler(locales, parse_class, display_class): """ Registers the passed date parser class and date displayer classes with the specified language locales. @@ -123,25 +126,27 @@ def register_datehandler(locales,parse_class,display_class): :param display_class: Class to be associated with displaying :type display_class: :class:`.DateDisplay` """ - format_string = '' - for possible_format in locales: # allow possibly embedding a date format + format_string = "" + for possible_format in locales: # allow possibly embedding a date format if isinstance(possible_format, tuple): - format_string = possible_format[0] # pre-seeded date format string + format_string = possible_format[0] # pre-seeded date format string # maintain legacy gramps transformations - format_string = format_string.replace('%y','%Y').replace('-', '/') + format_string = format_string.replace("%y", "%Y").replace("-", "/") for lang_str in locales: - if isinstance(lang_str, tuple): continue + if isinstance(lang_str, tuple): + continue LANG_TO_PARSER[lang_str] = parse_class LANG_TO_DISPLAY[lang_str] = display_class main_locale[lang_str] = locales[0] - locale_tformat[lang_str] = format_string # locale's date format string + locale_tformat[lang_str] = format_string # locale's date format string parse_class._locale = display_class._locale = GrampsLocale(lang=locales[0]) + register_datehandler( - ('en_GB', 'English_United Kingdom', ("%d/%m/%y",)), - DateParser, DateDisplayGB) + ("en_GB", "English_United Kingdom", ("%d/%m/%y",)), DateParser, DateDisplayGB +) register_datehandler( - ('en_US', 'en', 'English_United States', ("%m/%d/%y",)), - DateParser, DateDisplayEn) + ("en_US", "en", "English_United States", ("%m/%d/%y",)), DateParser, DateDisplayEn +) diff --git a/gramps/gen/datehandler/_dateparser.py b/gramps/gen/datehandler/_dateparser.py index 93b39b8f863..7b520a9af12 100644 --- a/gramps/gen/datehandler/_dateparser.py +++ b/gramps/gen/datehandler/_dateparser.py @@ -544,30 +544,40 @@ def init_strings(self): r"%s\.?(\s+\d+)?\s*,?\s+((\d+)(/\d+)?)?\s*$" % self._mon_str, re.IGNORECASE ) # this next RE has the (possibly-slashed) year at the string's end - self._text2 = re.compile(r'(\d+)?\s+?%s\.?\s*((\d+)(/\d+)?)?\s*$' - % self._mon_str, re.IGNORECASE) - self._jtext = re.compile(r'%s\s+(\d+)?\s*,?\s*((\d+)(/\d+)?)?\s*$' - % self._jmon_str, re.IGNORECASE) - self._jtext2 = re.compile(r'(\d+)?\s+?%s\s*((\d+)(/\d+)?)?\s*$' - % self._jmon_str, re.IGNORECASE) - self._ftext = re.compile(r'%s\s+(\d+)?\s*,?\s*((\d+)(/\d+)?)?\s*$' - % self._fmon_str, re.IGNORECASE) - self._ftext2 = re.compile(r'(\d+)?\s+?%s\s*((\d+)(/\d+)?)?\s*$' - % self._fmon_str, re.IGNORECASE) - self._ptext = re.compile(r'%s\s+(\d+)?\s*,?\s*((\d+)(/\d+)?)?\s*$' - % self._pmon_str, re.IGNORECASE) - self._ptext2 = re.compile(r'(\d+)?\s+?%s\s*((\d+)(/\d+)?)?\s*$' - % self._pmon_str, re.IGNORECASE) - self._itext = re.compile(r'%s\s+(\d+)?\s*,?\s*((\d+)(/\d+)?)?\s*$' - % self._imon_str, re.IGNORECASE) - self._itext2 = re.compile(r'(\d+)?\s+?%s\s*((\d+)(/\d+)?)?\s*$' - % self._imon_str, re.IGNORECASE) - self._stext = re.compile(r'%s\.?\s+(\d+)?\s*,?\s*((\d+)(/\d+)?)?\s*$' - % self._smon_str, re.IGNORECASE) - self._stext2 = re.compile(r'(\d+)?\s+?%s\.?\s*((\d+)(/\d+)?)?\s*$' - % self._smon_str, re.IGNORECASE) - self._numeric = re.compile( - r"((\d+)[/\.]\s*)?((\d+)[/\.]\s*)?(\d+)\s*$") + self._text2 = re.compile( + r"(\d+)?\s+?%s\.?\s*((\d+)(/\d+)?)?\s*$" % self._mon_str, re.IGNORECASE + ) + self._jtext = re.compile( + r"%s\s+(\d+)?\s*,?\s*((\d+)(/\d+)?)?\s*$" % self._jmon_str, re.IGNORECASE + ) + self._jtext2 = re.compile( + r"(\d+)?\s+?%s\s*((\d+)(/\d+)?)?\s*$" % self._jmon_str, re.IGNORECASE + ) + self._ftext = re.compile( + r"%s\s+(\d+)?\s*,?\s*((\d+)(/\d+)?)?\s*$" % self._fmon_str, re.IGNORECASE + ) + self._ftext2 = re.compile( + r"(\d+)?\s+?%s\s*((\d+)(/\d+)?)?\s*$" % self._fmon_str, re.IGNORECASE + ) + self._ptext = re.compile( + r"%s\s+(\d+)?\s*,?\s*((\d+)(/\d+)?)?\s*$" % self._pmon_str, re.IGNORECASE + ) + self._ptext2 = re.compile( + r"(\d+)?\s+?%s\s*((\d+)(/\d+)?)?\s*$" % self._pmon_str, re.IGNORECASE + ) + self._itext = re.compile( + r"%s\s+(\d+)?\s*,?\s*((\d+)(/\d+)?)?\s*$" % self._imon_str, re.IGNORECASE + ) + self._itext2 = re.compile( + r"(\d+)?\s+?%s\s*((\d+)(/\d+)?)?\s*$" % self._imon_str, re.IGNORECASE + ) + self._stext = re.compile( + r"%s\.?\s+(\d+)?\s*,?\s*((\d+)(/\d+)?)?\s*$" % self._smon_str, re.IGNORECASE + ) + self._stext2 = re.compile( + r"(\d+)?\s+?%s\.?\s*((\d+)(/\d+)?)?\s*$" % self._smon_str, re.IGNORECASE + ) + self._numeric = re.compile(r"((\d+)[/\.]\s*)?((\d+)[/\.]\s*)?(\d+)\s*$") self._iso = re.compile(r"(\d+)(/(\d+))?-(\d+)(-(\d+))?\s*$") self._isotimestamp = re.compile( r"^\s*?(\d{4})([01]\d)([0123]\d)(?:(?:[012]\d[0-5]\d[0-5]\d)|" diff --git a/gramps/gen/datehandler/_datestrings.py b/gramps/gen/datehandler/_datestrings.py index 930f511daab..5fee427c964 100644 --- a/gramps/gen/datehandler/_datestrings.py +++ b/gramps/gen/datehandler/_datestrings.py @@ -47,6 +47,7 @@ log = logging.getLogger(".DateStrings") + # ------------------------------------------------------------------------- # # DateStrings @@ -97,7 +98,8 @@ def __init__(self, locale): _("September", "localized lexeme inflections"), _("October", "localized lexeme inflections"), _("November", "localized lexeme inflections"), - _("December", "localized lexeme inflections") ) + _("December", "localized lexeme inflections"), + ) self.short_months = ( "", @@ -116,7 +118,8 @@ def __init__(self, locale): _("Sep", "localized lexeme inflections - short month form"), _("Oct", "localized lexeme inflections - short month form"), _("Nov", "localized lexeme inflections - short month form"), - _("Dec", "localized lexeme inflections - short month form") ) + _("Dec", "localized lexeme inflections - short month form"), + ) _ = locale.translation.sgettext self.alt_long_months = ( @@ -136,7 +139,8 @@ def __init__(self, locale): _("", "alternative month names for September"), _("", "alternative month names for October"), _("", "alternative month names for November"), - _("", "alternative month names for December") ) + _("", "alternative month names for December"), + ) self.calendar = ( # Must appear in the order indexed by Date.CAL_... numeric constants diff --git a/gramps/gen/datehandler/_dateutils.py b/gramps/gen/datehandler/_dateutils.py index acd3098dbf2..18423f68b33 100644 --- a/gramps/gen/datehandler/_dateutils.py +++ b/gramps/gen/datehandler/_dateutils.py @@ -22,27 +22,28 @@ Class handling language-specific selection for date parser and displayer. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import time -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..const import GRAMPS_LOCALE as glocale from ..lib.date import Date from . import LANG_TO_DISPLAY, LANG, parser, displayer -#-------------------------------------------------------------- + +# -------------------------------------------------------------- # # Convenience functions # -#-------------------------------------------------------------- +# -------------------------------------------------------------- def get_date_formats(flocale=glocale): """ Return the list of supported formats for date parsers and displayers. @@ -54,11 +55,12 @@ def get_date_formats(flocale=glocale): # trans_text is a defined keyword (see po/update_po.py, po/genpot.sh) trans_text = flocale.translation.sgettext try: - return tuple(trans_text(fmt) - for fmt in LANG_TO_DISPLAY[flocale.lang](0).formats) + return tuple( + trans_text(fmt) for fmt in LANG_TO_DISPLAY[flocale.lang](0).formats + ) except: - return tuple(trans_text(fmt) - for fmt in LANG_TO_DISPLAY['C'](0).formats) + return tuple(trans_text(fmt) for fmt in LANG_TO_DISPLAY["C"](0).formats) + def set_format(value): try: @@ -66,6 +68,7 @@ def set_format(value): except: pass + def set_date(date_base, text): """ Set the date of the :class:`.DateBase` instance. @@ -79,6 +82,7 @@ def set_date(date_base, text): """ parser.set_date(date_base.get_date_object(), text) + def get_date(date_base): """ Return a string representation of the date of the :class:`.DateBase` @@ -92,10 +96,12 @@ def get_date(date_base): """ return displayer.display(date_base.get_date_object()) + def get_date_valid(date_base): date_obj = date_base.get_date_object() return date_obj.get_valid() + def format_time(secs): """ Format a time in seconds as a date in the preferred date format and a @@ -103,4 +109,4 @@ def format_time(secs): """ t = time.localtime(secs) d = Date(t.tm_year, t.tm_mon, t.tm_mday) - return displayer.display(d) + time.strftime(' %X', t) + return displayer.display(d) + time.strftime(" %X", t) diff --git a/gramps/gen/datehandler/_grampslocale.py b/gramps/gen/datehandler/_grampslocale.py index 724322b55bf..1c57dd06349 100644 --- a/gramps/gen/datehandler/_grampslocale.py +++ b/gramps/gen/datehandler/_grampslocale.py @@ -20,19 +20,19 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import locale -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- -from ..const import GRAMPS_LOCALE as glocale # TODO unneeded? (see codeset) +# ------------------------------------------------------------------------- +from ..const import GRAMPS_LOCALE as glocale # TODO unneeded? (see codeset) """ Some OS environments do not support the locale.nl_langinfo() method @@ -44,10 +44,9 @@ Since these routines return values encoded into selected character set, we have to convert to unicode. """ -codeset = glocale.encoding # TODO I don't think "codeset" is used anymore +codeset = glocale.encoding # TODO I don't think "codeset" is used anymore try: - # here only for the upgrade tool, see _datestrings.py __main__ _deprecated_long_months = ( "", @@ -63,7 +62,7 @@ locale.nl_langinfo(locale.MON_10), locale.nl_langinfo(locale.MON_11), locale.nl_langinfo(locale.MON_12), - ) + ) _deprecated_short_months = ( "", @@ -79,7 +78,7 @@ locale.nl_langinfo(locale.ABMON_10), locale.nl_langinfo(locale.ABMON_11), locale.nl_langinfo(locale.ABMON_12), - ) + ) # Gramps day number: Sunday => 1, Monday => 2, etc # "Return name of the n-th day of the week. Warning: @@ -89,60 +88,60 @@ # see http://docs.python.org/library/locale.html _deprecated_long_days = ( "", - locale.nl_langinfo(locale.DAY_1), # Sunday - locale.nl_langinfo(locale.DAY_2), # Monday - locale.nl_langinfo(locale.DAY_3), # Tuesday - locale.nl_langinfo(locale.DAY_4), # Wednesday - locale.nl_langinfo(locale.DAY_5), # Thursday - locale.nl_langinfo(locale.DAY_6), # Friday - locale.nl_langinfo(locale.DAY_7), # Saturday - ) + locale.nl_langinfo(locale.DAY_1), # Sunday + locale.nl_langinfo(locale.DAY_2), # Monday + locale.nl_langinfo(locale.DAY_3), # Tuesday + locale.nl_langinfo(locale.DAY_4), # Wednesday + locale.nl_langinfo(locale.DAY_5), # Thursday + locale.nl_langinfo(locale.DAY_6), # Friday + locale.nl_langinfo(locale.DAY_7), # Saturday + ) _deprecated_short_days = ( "", - locale.nl_langinfo(locale.ABDAY_1), # Sun - locale.nl_langinfo(locale.ABDAY_2), # Mon - locale.nl_langinfo(locale.ABDAY_3), # Tue - locale.nl_langinfo(locale.ABDAY_4), # Wed - locale.nl_langinfo(locale.ABDAY_5), # Thu - locale.nl_langinfo(locale.ABDAY_6), # Fri - locale.nl_langinfo(locale.ABDAY_7), # Sat - ) + locale.nl_langinfo(locale.ABDAY_1), # Sun + locale.nl_langinfo(locale.ABDAY_2), # Mon + locale.nl_langinfo(locale.ABDAY_3), # Tue + locale.nl_langinfo(locale.ABDAY_4), # Wed + locale.nl_langinfo(locale.ABDAY_5), # Thu + locale.nl_langinfo(locale.ABDAY_6), # Fri + locale.nl_langinfo(locale.ABDAY_7), # Sat + ) except: import time _deprecated_long_months = ( "", - time.strftime('%B',(1,1,1,1,1,1,1,1,1)), - time.strftime('%B',(1,2,1,1,1,1,1,1,1)), - time.strftime('%B',(1,3,1,1,1,1,1,1,1)), - time.strftime('%B',(1,4,1,1,1,1,1,1,1)), - time.strftime('%B',(1,5,1,1,1,1,1,1,1)), - time.strftime('%B',(1,6,1,1,1,1,1,1,1)), - time.strftime('%B',(1,7,1,1,1,1,1,1,1)), - time.strftime('%B',(1,8,1,1,1,1,1,1,1)), - time.strftime('%B',(1,9,1,1,1,1,1,1,1)), - time.strftime('%B',(1,10,1,1,1,1,1,1,1)), - time.strftime('%B',(1,11,1,1,1,1,1,1,1)), - time.strftime('%B',(1,12,1,1,1,1,1,1,1)), - ) + time.strftime("%B", (1, 1, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%B", (1, 2, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%B", (1, 3, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%B", (1, 4, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%B", (1, 5, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%B", (1, 6, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%B", (1, 7, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%B", (1, 8, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%B", (1, 9, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%B", (1, 10, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%B", (1, 11, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%B", (1, 12, 1, 1, 1, 1, 1, 1, 1)), + ) _deprecated_short_months = ( "", - time.strftime('%b',(1,1,1,1,1,1,1,1,1)), - time.strftime('%b',(1,2,1,1,1,1,1,1,1)), - time.strftime('%b',(1,3,1,1,1,1,1,1,1)), - time.strftime('%b',(1,4,1,1,1,1,1,1,1)), - time.strftime('%b',(1,5,1,1,1,1,1,1,1)), - time.strftime('%b',(1,6,1,1,1,1,1,1,1)), - time.strftime('%b',(1,7,1,1,1,1,1,1,1)), - time.strftime('%b',(1,8,1,1,1,1,1,1,1)), - time.strftime('%b',(1,9,1,1,1,1,1,1,1)), - time.strftime('%b',(1,10,1,1,1,1,1,1,1)), - time.strftime('%b',(1,11,1,1,1,1,1,1,1)), - time.strftime('%b',(1,12,1,1,1,1,1,1,1)), - ) + time.strftime("%b", (1, 1, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%b", (1, 2, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%b", (1, 3, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%b", (1, 4, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%b", (1, 5, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%b", (1, 6, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%b", (1, 7, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%b", (1, 8, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%b", (1, 9, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%b", (1, 10, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%b", (1, 11, 1, 1, 1, 1, 1, 1, 1)), + time.strftime("%b", (1, 12, 1, 1, 1, 1, 1, 1, 1)), + ) # Gramps day number: Sunday => 1, Monday => 2, etc # strftime takes a (from the doc of standard Python library "time") @@ -155,22 +154,22 @@ # just a dummy. _deprecated_long_days = ( "", - time.strftime('%A',(1,1,1,1,1,1,6,1,1)), # Sunday - time.strftime('%A',(1,1,1,1,1,1,0,1,1)), # Monday - time.strftime('%A',(1,1,1,1,1,1,1,1,1)), # Tuesday - time.strftime('%A',(1,1,1,1,1,1,2,1,1)), # Wednesday - time.strftime('%A',(1,1,1,1,1,1,3,1,1)), # Thursday - time.strftime('%A',(1,1,1,1,1,1,4,1,1)), # Friday - time.strftime('%A',(1,1,1,1,1,1,5,1,1)), # Saturday - ) + time.strftime("%A", (1, 1, 1, 1, 1, 1, 6, 1, 1)), # Sunday + time.strftime("%A", (1, 1, 1, 1, 1, 1, 0, 1, 1)), # Monday + time.strftime("%A", (1, 1, 1, 1, 1, 1, 1, 1, 1)), # Tuesday + time.strftime("%A", (1, 1, 1, 1, 1, 1, 2, 1, 1)), # Wednesday + time.strftime("%A", (1, 1, 1, 1, 1, 1, 3, 1, 1)), # Thursday + time.strftime("%A", (1, 1, 1, 1, 1, 1, 4, 1, 1)), # Friday + time.strftime("%A", (1, 1, 1, 1, 1, 1, 5, 1, 1)), # Saturday + ) _deprecated_short_days = ( "", - time.strftime('%a',(1,1,1,1,1,1,6,1,1)), # Sun - time.strftime('%a',(1,1,1,1,1,1,0,1,1)), # Mon - time.strftime('%a',(1,1,1,1,1,1,1,1,1)), # Tue - time.strftime('%a',(1,1,1,1,1,1,2,1,1)), # Wed - time.strftime('%a',(1,1,1,1,1,1,3,1,1)), # Thu - time.strftime('%a',(1,1,1,1,1,1,4,1,1)), # Fri - time.strftime('%a',(1,1,1,1,1,1,5,1,1)), # Sat - ) + time.strftime("%a", (1, 1, 1, 1, 1, 1, 6, 1, 1)), # Sun + time.strftime("%a", (1, 1, 1, 1, 1, 1, 0, 1, 1)), # Mon + time.strftime("%a", (1, 1, 1, 1, 1, 1, 1, 1, 1)), # Tue + time.strftime("%a", (1, 1, 1, 1, 1, 1, 2, 1, 1)), # Wed + time.strftime("%a", (1, 1, 1, 1, 1, 1, 3, 1, 1)), # Thu + time.strftime("%a", (1, 1, 1, 1, 1, 1, 4, 1, 1)), # Fri + time.strftime("%a", (1, 1, 1, 1, 1, 1, 5, 1, 1)), # Sat + ) diff --git a/gramps/gen/datehandler/test/datedisplay_test.py b/gramps/gen/datehandler/test/datedisplay_test.py index 03d1c14ae64..355e552ed0b 100644 --- a/gramps/gen/datehandler/test/datedisplay_test.py +++ b/gramps/gen/datehandler/test/datedisplay_test.py @@ -28,11 +28,13 @@ from ...utils.grampslocale import GrampsLocale from ...lib.date import Date + class DateDisplayTest(unittest.TestCase): def setUp(self): from .._datedisplay import DateDisplayEn + self.display = DateDisplayEn() - self.display_RU = GrampsLocale(lang='ru').date_displayer + self.display_RU = GrampsLocale(lang="ru").date_displayer def assert_map_key_val(self, m, k, v): try: @@ -40,12 +42,14 @@ def assert_map_key_val(self, m, k, v): except KeyError: self.assertTrue(False, list(m.items())) + class DateDisplayCalendarTest(DateDisplayTest): def test_calendar_gregorian_is_empty(self): self.assert_map_key_val(self.display.calendar, Date.CAL_GREGORIAN, "") def test_calendar_julian_RU(self): - self.assert_map_key_val(self.display_RU.calendar, Date.CAL_JULIAN, 'Юлианский') + self.assert_map_key_val(self.display_RU.calendar, Date.CAL_JULIAN, "Юлианский") + # This class tests common functionality in DateDisplay as applied to RU, # and so it is coupled to translated strings and inflection names @@ -56,95 +60,95 @@ def setUp(self): self.dd = self.display = self.display_RU self.months = self.dd._ds.long_months # TODO hardwired magic numbers! Bad API smell. - self.dd.set_format(4) # day month_name year + self.dd.set_format(4) # day month_name year self.may = self.months[5] def assertInflectionInDate(self, inflection, date, month=None): if month is None: month = date.get_month() month_lexeme = self.months[month] - self.assertIn(month_lexeme.forms[inflection], - self.dd.display(date)) + self.assertIn(month_lexeme.forms[inflection], self.dd.display(date)) def test_month_only_date_nominative_quality_none(self): d1945may = Date(1945, 5, 0) d1945may.set_quality(Date.QUAL_NONE) - self.assertInflectionInDate('И', d1945may) + self.assertInflectionInDate("И", d1945may) def test_month_only_date_nominative_quality_estimated(self): d1945may = Date(1945, 5, 0) d1945may.set_quality(Date.QUAL_ESTIMATED) - self.assertInflectionInDate('Т', d1945may) + self.assertInflectionInDate("Т", d1945may) def test_month_only_date_nominative_quality_calculated(self): d1945may = Date(1945, 5, 0) d1945may.set_quality(Date.QUAL_CALCULATED) - self.assertInflectionInDate('И', d1945may) + self.assertInflectionInDate("И", d1945may) def test_day_month_date_genitive(self): d1945may9 = Date(1945, 5, 9) - self.assertInflectionInDate('Р', d1945may9) + self.assertInflectionInDate("Р", d1945may9) def test_day_month_date_genitiive_quality_estimated(self): d1945may9 = Date(1945, 5, 9) d1945may9.set_quality(Date.QUAL_ESTIMATED) - self.assertInflectionInDate('Р', d1945may9) + self.assertInflectionInDate("Р", d1945may9) def test_before_month_only_date_genitive(self): d1945may = Date(1945, 5, 0) d1945may.set_modifier(Date.MOD_BEFORE) # TODO hardwired magic numbers! Bad API smell. - for inflecting_format in (3,4): + for inflecting_format in (3, 4): self.dd.set_format(inflecting_format) -# this depends on the fact that in Russian the short and long forms for May -# will be the same! + # this depends on the fact that in Russian the short and long forms for May + # will be the same! self.assertIn("до мая", self.dd.display(d1945may)) def test_after_month_only_date_genitive(self): d1945may = Date(1945, 5, 0) d1945may.set_modifier(Date.MOD_AFTER) # TODO hardwired magic numbers! Bad API smell. - for inflecting_format in (3,4): + for inflecting_format in (3, 4): self.dd.set_format(inflecting_format) -# this depends on the fact that in Russian the short and long forms for May -# will be the same! + # this depends on the fact that in Russian the short and long forms for May + # will be the same! self.assertIn("после мая", self.dd.display(d1945may)) def test_about_month_only_date_genitive(self): d1945may = Date(1945, 5, 0) d1945may.set_modifier(Date.MOD_ABOUT) # TODO hardwired magic numbers! Bad API smell. - for inflecting_format in (3,4): + for inflecting_format in (3, 4): self.dd.set_format(inflecting_format) -# this depends on the fact that in Russian the short and long forms for May -# will be the same! + # this depends on the fact that in Russian the short and long forms for May + # will be the same! self.assertIn("около мая", self.dd.display(d1945may)) def test_between_month_only_dates_ablative(self): b1945may_1946may = Date() b1945may_1946may.set( - modifier=Date.MOD_RANGE, - value=(0, 5, 1945, False, 0, 5, 1946, False)) + modifier=Date.MOD_RANGE, value=(0, 5, 1945, False, 0, 5, 1946, False) + ) # TODO hardwired magic numbers! Bad API smell. - for inflecting_format in (3,4): + for inflecting_format in (3, 4): self.dd.set_format(inflecting_format) -# this depends on the fact that in Russian the short and long forms for May -# will be the same! + # this depends on the fact that in Russian the short and long forms for May + # will be the same! self.assertIn("между маем", self.dd.display(b1945may_1946may)) self.assertIn("и маем", self.dd.display(b1945may_1946may)) def test_month_only_date_span_from_genitive_to_accusative(self): f1945may_t1946may = Date() f1945may_t1946may.set( - modifier=Date.MOD_SPAN, - value=(0, 5, 1945, False, 0, 5, 1946, False)) + modifier=Date.MOD_SPAN, value=(0, 5, 1945, False, 0, 5, 1946, False) + ) # TODO hardwired magic numbers! Bad API smell. - for inflecting_format in (3,4): + for inflecting_format in (3, 4): self.dd.set_format(inflecting_format) -# this depends on the fact that in Russian the short and long forms for May -# will be the same! + # this depends on the fact that in Russian the short and long forms for May + # will be the same! self.assertIn("с мая", self.dd.display(f1945may_t1946may)) self.assertIn("по май", self.dd.display(f1945may_t1946may)) + if __name__ == "__main__": unittest.main() diff --git a/gramps/gen/datehandler/test/datehandler_test.py b/gramps/gen/datehandler/test/datehandler_test.py index 5f4fd6ecf95..c85507e1b70 100644 --- a/gramps/gen/datehandler/test/datehandler_test.py +++ b/gramps/gen/datehandler/test/datehandler_test.py @@ -55,6 +55,7 @@ from ...utils.grampslocale import GrampsLocale, _LOCALE_NAMES from .. import LANG_TO_PARSER + # ------------------------------------------------------------------------- # # @@ -65,7 +66,6 @@ def setUp(self): config.set("preferences.date-format", 0) def __base_test_all_languages(self, dates): - languages = [ lang for lang in LANG_TO_PARSER.keys() if lang in _LOCALE_NAMES.keys() ] @@ -74,7 +74,6 @@ def __base_test_all_languages(self, dates): self.__test_language(language, dates) def __test_language(self, language, dates): - locale = GrampsLocale(lang=language) displayer = locale.date_displayer parser = locale.date_parser @@ -90,7 +89,6 @@ def __test_language(self, language, dates): ) def test_simple(self): - dates = [] for calendar in (Date.CAL_GREGORIAN, Date.CAL_JULIAN): for newyear in (Date.NEWYEAR_JAN1, Date.NEWYEAR_MAR25, (5, 5)): @@ -123,7 +121,6 @@ def test_simple(self): self.__base_test_all_languages(dates) def test_span(self): - dates = [] calendar = Date.CAL_GREGORIAN for quality in (Date.QUAL_NONE, Date.QUAL_ESTIMATED, Date.QUAL_CALCULATED): @@ -207,7 +204,6 @@ def test_span(self): self.__base_test_all_languages(dates) def test_textual(self): - dates = [] calendar = Date.CAL_GREGORIAN modifier = Date.MOD_TEXTONLY diff --git a/gramps/gen/datehandler/test/dateparser_test.py b/gramps/gen/datehandler/test/dateparser_test.py index 2b24ac1e226..c3e8d8a6180 100644 --- a/gramps/gen/datehandler/test/dateparser_test.py +++ b/gramps/gen/datehandler/test/dateparser_test.py @@ -28,11 +28,13 @@ from ...utils.grampslocale import GrampsLocale from ...lib.date import Date + class DateParserTest(unittest.TestCase): def setUp(self): from .._dateparser import DateParser + self.parser = DateParser() - self.parser_RU = GrampsLocale(lang='ru').date_parser + self.parser_RU = GrampsLocale(lang="ru").date_parser def assert_map_key_val(self, m, k, v): try: @@ -41,118 +43,128 @@ def assert_map_key_val(self, m, k, v): self.assertTrue(False, list(m.items())) def test_month_to_int_jan_is_1(self): - self.assert_map_key_val(self.parser.month_to_int, 'jan', 1) + self.assert_map_key_val(self.parser.month_to_int, "jan", 1) def test_prefix_table_for_RU_built(self): - self.assertIn('ru_RU', self.parser._langs) + self.assertIn("ru_RU", self.parser._langs) def test_month_to_int_septem_RU_is_9(self): - self.assert_map_key_val(self.parser.month_to_int, 'сентяб', 9) + self.assert_map_key_val(self.parser.month_to_int, "сентяб", 9) def test_hebrew_to_int_av_is_12(self): - self.assert_map_key_val(self.parser.hebrew_to_int, 'av', 12) - self.assert_map_key_val(self.parser.hebrew_to_int, 'ав', 12) # RU + self.assert_map_key_val(self.parser.hebrew_to_int, "av", 12) + self.assert_map_key_val(self.parser.hebrew_to_int, "ав", 12) # RU def test_french_to_int_thermidor_is_11(self): - self.assert_map_key_val(self.parser.french_to_int, 'thermidor', 11) - self.assert_map_key_val(self.parser.french_to_int, 'термидор', 11) # RU + self.assert_map_key_val(self.parser.french_to_int, "thermidor", 11) + self.assert_map_key_val(self.parser.french_to_int, "термидор", 11) # RU def test_islamic_to_int_ramadan_is_9(self): - self.assert_map_key_val(self.parser.islamic_to_int, 'ramadan', 9) - self.assert_map_key_val(self.parser.islamic_to_int, 'рамадан', 9) # RU + self.assert_map_key_val(self.parser.islamic_to_int, "ramadan", 9) + self.assert_map_key_val(self.parser.islamic_to_int, "рамадан", 9) # RU def test_persian_to_int_tir_is_4(self): - self.assert_map_key_val(self.parser.persian_to_int, 'tir', 4) - self.assert_map_key_val(self.parser.persian_to_int, 'тир', 4) # RU + self.assert_map_key_val(self.parser.persian_to_int, "tir", 4) + self.assert_map_key_val(self.parser.persian_to_int, "тир", 4) # RU def test_calendar_to_int_gregorian(self): - self.assert_map_key_val(self.parser.calendar_to_int, 'gregorian', Date.CAL_GREGORIAN) - self.assert_map_key_val(self.parser.calendar_to_int, 'g', Date.CAL_GREGORIAN) - self.assert_map_key_val(self.parser.calendar_to_int, 'григорианский', Date.CAL_GREGORIAN) - self.assert_map_key_val(self.parser.calendar_to_int, 'г', Date.CAL_GREGORIAN) + self.assert_map_key_val( + self.parser.calendar_to_int, "gregorian", Date.CAL_GREGORIAN + ) + self.assert_map_key_val(self.parser.calendar_to_int, "g", Date.CAL_GREGORIAN) + self.assert_map_key_val( + self.parser.calendar_to_int, "григорианский", Date.CAL_GREGORIAN + ) + self.assert_map_key_val(self.parser.calendar_to_int, "г", Date.CAL_GREGORIAN) def test_calendar_to_int_julian(self): - self.assert_map_key_val(self.parser.calendar_to_int, 'julian', Date.CAL_JULIAN) - self.assert_map_key_val(self.parser.calendar_to_int, 'j', Date.CAL_JULIAN) - self.assert_map_key_val(self.parser.calendar_to_int, 'юлианский', Date.CAL_JULIAN) - self.assert_map_key_val(self.parser.calendar_to_int, 'ю', Date.CAL_JULIAN) + self.assert_map_key_val(self.parser.calendar_to_int, "julian", Date.CAL_JULIAN) + self.assert_map_key_val(self.parser.calendar_to_int, "j", Date.CAL_JULIAN) + self.assert_map_key_val( + self.parser.calendar_to_int, "юлианский", Date.CAL_JULIAN + ) + self.assert_map_key_val(self.parser.calendar_to_int, "ю", Date.CAL_JULIAN) def test_quarter_1(self): - date = self.parser.parse('q1 1900') - self.assertTrue(date.is_equal(self.parser.parse('Q1 1900'))) + date = self.parser.parse("q1 1900") + self.assertTrue(date.is_equal(self.parser.parse("Q1 1900"))) self.assertEqual(date.get_ymd(), (1900, 1, 1)) self.assertEqual(date.get_stop_ymd(), (1900, 3, 31)) self.assertEqual(date.get_modifier(), Date.MOD_RANGE) def test_quarter_2(self): - date = self.parser.parse('q2 1900') - self.assertTrue(date.is_equal(self.parser.parse('Q2 1900'))) + date = self.parser.parse("q2 1900") + self.assertTrue(date.is_equal(self.parser.parse("Q2 1900"))) self.assertEqual(date.get_ymd(), (1900, 4, 1)) self.assertEqual(date.get_stop_ymd(), (1900, 6, 30)) self.assertEqual(date.get_modifier(), Date.MOD_RANGE) def test_quarter_3(self): - date = self.parser.parse('q3 1900') - self.assertTrue(date.is_equal(self.parser.parse('Q3 1900'))) + date = self.parser.parse("q3 1900") + self.assertTrue(date.is_equal(self.parser.parse("Q3 1900"))) self.assertEqual(date.get_ymd(), (1900, 7, 1)) self.assertEqual(date.get_stop_ymd(), (1900, 9, 30)) self.assertEqual(date.get_modifier(), Date.MOD_RANGE) def test_quarter_4(self): - date = self.parser.parse('q4 1900') - self.assertTrue(date.is_equal(self.parser.parse('Q4 1900'))) + date = self.parser.parse("q4 1900") + self.assertTrue(date.is_equal(self.parser.parse("Q4 1900"))) self.assertEqual(date.get_ymd(), (1900, 10, 1)) self.assertEqual(date.get_stop_ymd(), (1900, 12, 31)) self.assertEqual(date.get_modifier(), Date.MOD_RANGE) def test_quarter_quality_calendar(self): - date = self.parser.parse('calc q1 1900 (julian)') + date = self.parser.parse("calc q1 1900 (julian)") self.assertEqual(date.get_quality(), Date.QUAL_CALCULATED) self.assertEqual(date.get_calendar(), Date.CAL_JULIAN) + class Test_generate_variants(unittest.TestCase): def setUp(self): from .. import _datestrings from .._dateparser import _generate_variants - self.ds = ds = _datestrings.DateStrings(GrampsLocale(languages=('ru'))) - self.month_variants = list(_generate_variants( - zip(ds.long_months, ds.short_months, - ds.swedish_SV, ds.alt_long_months))) + + self.ds = ds = _datestrings.DateStrings(GrampsLocale(languages=("ru"))) + self.month_variants = list( + _generate_variants( + zip(ds.long_months, ds.short_months, ds.swedish_SV, ds.alt_long_months) + ) + ) def testVariantsSameLengthAsLongMonths(self): - self.assertEqual(len(self.ds.long_months), - len(self.month_variants)) + self.assertEqual(len(self.ds.long_months), len(self.month_variants)) def testRussianHasDifferentVariantsForEachMonth(self): for i in range(1, 13): - mvi = self.month_variants[i] - self.assertTrue(len(mvi) > 1, msg=mvi) + mvi = self.month_variants[i] + self.assertTrue(len(mvi) > 1, msg=mvi) def testNoEmptyStringInVariants(self): for i in range(1, 13): - mvi = self.month_variants[i] - self.assertNotIn("", mvi) + mvi = self.month_variants[i] + self.assertNotIn("", mvi) def testLongMonthsAppearInVariants(self): for i in range(1, 13): - lmi = self.ds.long_months[i] - mvi = self.month_variants[i] - self.assertIn("{}".format(lmi), mvi) + lmi = self.ds.long_months[i] + mvi = self.month_variants[i] + self.assertIn("{}".format(lmi), mvi) def testShortMonthsAppearInVariants(self): for i in range(1, 13): - smi = self.ds.short_months[i] - mvi = self.month_variants[i] - self.assertIn("{}".format(smi), mvi) + smi = self.ds.short_months[i] + mvi = self.month_variants[i] + self.assertIn("{}".format(smi), mvi) def testLongMonthVariantsUnique(self): for i in range(1, 13): - mvi = self.month_variants[i] - self.assertEqual(len(mvi), len(set(mvi)), msg=mvi) + mvi = self.month_variants[i] + self.assertEqual(len(mvi), len(set(mvi)), msg=mvi) def testRuMayVariantsContainSvMaj(self): v = self.month_variants[5] self.assertIn("Maj", v) + if __name__ == "__main__": unittest.main() diff --git a/gramps/gen/datehandler/test/datestrings_test.py b/gramps/gen/datehandler/test/datestrings_test.py index a5bfe296f5a..ce3ea2568e1 100644 --- a/gramps/gen/datehandler/test/datestrings_test.py +++ b/gramps/gen/datehandler/test/datestrings_test.py @@ -24,22 +24,24 @@ from .. import _datestrings from ...lib.date import Date + class DateStringsTest(unittest.TestCase): def setUp(self): from ...utils.grampslocale import GrampsLocale - self.ds = _datestrings.DateStrings(GrampsLocale()) # whatever the default... - self.ds_EN = _datestrings.DateStrings(GrampsLocale(languages='en')) - self.ds_RU = _datestrings.DateStrings(GrampsLocale(languages='ru')) + + self.ds = _datestrings.DateStrings(GrampsLocale()) # whatever the default... + self.ds_EN = _datestrings.DateStrings(GrampsLocale(languages="en")) + self.ds_RU = _datestrings.DateStrings(GrampsLocale(languages="ru")) def testTwelfthMonthIsDecember(self): - self.assertEqual(self.ds_EN.long_months[12], 'December') - self.assertEqual(self.ds_EN.short_months[12], 'Dec') + self.assertEqual(self.ds_EN.long_months[12], "December") + self.assertEqual(self.ds_EN.short_months[12], "Dec") # May is 3-letter in Russian, and so abbreviated form # will be different for inflections! def testRussianHasDifferentInflectionsForShortMay(self): - v5 = list(self.ds_RU.short_months[5].variants()) - self.assertTrue(len(v5) > 1, msg=v5) + v5 = list(self.ds_RU.short_months[5].variants()) + self.assertTrue(len(v5) > 1, msg=v5) def testEnAdarI_in_AdarII(self): adar1 = self.ds_EN.hebrew[6] @@ -76,5 +78,6 @@ def testCalendarIndex(self): def testDayNamesLenIs8(self): self.assertEqual(len(self.ds.long_days), 8) + if __name__ == "__main__": unittest.main() diff --git a/gramps/gen/db/base.py b/gramps/gen/db/base.py index 7fc9705c1b9..ac561cd9c1d 100644 --- a/gramps/gen/db/base.py +++ b/gramps/gen/db/base.py @@ -25,23 +25,24 @@ from this class. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python libraries # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import re import time from operator import itemgetter import logging -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps libraries # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..db.dbconst import DBLOGNAME from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext from ..lib.childreftype import ChildRefType from ..lib.childref import ChildRef @@ -50,11 +51,11 @@ _LOG = logging.getLogger(DBLOGNAME) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps libraries # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class DbReadBase: @@ -72,14 +73,14 @@ def __init__(self): derived from this class should be created. """ self.basedb = self - self.__feature = {} # {"feature": VALUE, ...} + self.__feature = {} # {"feature": VALUE, ...} def get_feature(self, feature): """ Databases can implement certain features or not. The default is None, unless otherwise explicitly stated. """ - return self.__feature.get(feature, None) # can also be explicitly None + return self.__feature.get(feature, None) # can also be explicitly None def set_feature(self, feature, value): """ @@ -1264,8 +1265,14 @@ def iter_tag_handles(self): """ raise NotImplementedError - def load(self, name, callback, mode=None, force_schema_upgrade=False, - force_bsddb_upgrade=False): + def load( + self, + name, + callback, + mode=None, + force_schema_upgrade=False, + force_bsddb_upgrade=False, + ): """ Open the specified database. """ @@ -1295,8 +1302,9 @@ def version_supported(self): """ raise NotImplementedError - def set_prefixes(self, person, media, family, source, citation, - place, event, repository, note): + def set_prefixes( + self, person, media, family, source, citation, place, event, repository, note + ): """ Set the prefixes for the gramps ids for all gramps objects """ @@ -1797,10 +1805,9 @@ def redo(self, update_history=True): """ raise NotImplementedError - def add_child_to_family(self, family, child, - mrel=ChildRefType(), - frel=ChildRefType(), - trans=None): + def add_child_to_family( + self, family, child, mrel=ChildRefType(), frel=ChildRefType(), trans=None + ): """ Adds a child to a family. """ @@ -1813,26 +1820,23 @@ def add_child_to_family(self, family, child, child.add_parent_family_handle(family.handle) if trans is None: - with DbTxn(_('Add child to family'), self) as trans: + with DbTxn(_("Add child to family"), self) as trans: self.commit_family(family, trans) self.commit_person(child, trans) else: self.commit_family(family, trans) self.commit_person(child, trans) - def remove_child_from_family(self, person_handle, family_handle, - trans=None): + def remove_child_from_family(self, person_handle, family_handle, trans=None): """ Remove a person as a child of the family, deleting the family if it becomes empty. """ if trans is None: with DbTxn(_("Remove child from family"), self) as trans: - self.__remove_child_from_family(person_handle, family_handle, - trans) + self.__remove_child_from_family(person_handle, family_handle, trans) else: - self.__remove_child_from_family(person_handle, family_handle, - trans) + self.__remove_child_from_family(person_handle, family_handle, trans) trans.set_description(_("Remove child from family")) def __remove_child_from_family(self, person_handle, family_handle, trans): @@ -1845,8 +1849,11 @@ def __remove_child_from_family(self, person_handle, family_handle, trans): person.remove_parent_family_handle(family_handle) family.remove_child_handle(person_handle) - if (not family.get_father_handle() and not family.get_mother_handle() - and not family.get_child_ref_list()): + if ( + not family.get_father_handle() + and not family.get_mother_handle() + and not family.get_child_ref_list() + ): self.remove_family_relationships(family_handle, trans) else: self.commit_family(family, trans) @@ -1874,9 +1881,11 @@ def delete_person_from_database(self, person, trans): else: family.set_mother_handle(None) - if not family.get_father_handle() and \ - not family.get_mother_handle() and \ - not family.get_child_ref_list(): + if ( + not family.get_father_handle() + and not family.get_mother_handle() + and not family.get_child_ref_list() + ): self.remove_family_relationships(family_handle, trans) else: self.commit_family(family, trans) @@ -1885,9 +1894,11 @@ def delete_person_from_database(self, person, trans): if family_handle: family = self.get_family_from_handle(family_handle) family.remove_child_handle(person.get_handle()) - if not family.get_father_handle() and \ - not family.get_mother_handle() and \ - not family.get_child_ref_list(): + if ( + not family.get_father_handle() + and not family.get_mother_handle() + and not family.get_child_ref_list() + ): self.remove_family_relationships(family_handle, trans) else: self.commit_family(family, trans) @@ -1896,7 +1907,7 @@ def delete_person_from_database(self, person, trans): for obj_type, ohandle in self.find_backlink_handles(handle): obj = self.method("get_%s_from_handle", obj_type)(ohandle) - obj.remove_handle_references('Person', [handle]) + obj.remove_handle_references("Person", [handle]) self.method("commit_%s", obj_type)(obj, trans) self.remove_person(handle, trans) @@ -1918,24 +1929,23 @@ def __remove_family_relationships(self, family_handle, trans): for obj_type, ohandle in self.find_backlink_handles(family_handle): obj = self.method("get_%s_from_handle", obj_type)(ohandle) if obj: - obj.remove_handle_references('Family', [family_handle]) + obj.remove_handle_references("Family", [family_handle]) self.method("commit_%s", obj_type)(obj, trans) self.remove_family(family_handle, trans) - def remove_parent_from_family(self, person_handle, family_handle, - trans=None): + def remove_parent_from_family(self, person_handle, family_handle, trans=None): """ Remove a person as either the father or mother of a family, deleting the family if it becomes empty. """ if trans is None: - with DbTxn('', self) as trans: - msg = self.__remove_parent_from_family(person_handle, - family_handle, trans) + with DbTxn("", self) as trans: + msg = self.__remove_parent_from_family( + person_handle, family_handle, trans + ) trans.set_description(msg) else: - msg = self.__remove_parent_from_family(person_handle, - family_handle, trans) + msg = self.__remove_parent_from_family(person_handle, family_handle, trans) trans.set_description(msg) def __remove_parent_from_family(self, person_handle, family_handle, trans): @@ -1954,13 +1964,18 @@ def __remove_parent_from_family(self, person_handle, family_handle, trans): msg = _("Remove mother from family") family.set_mother_handle(None) else: - raise DbTransactionCancel("The relation between the person and " + raise DbTransactionCancel( + "The relation between the person and " "the family you try to remove is not consistent, please fix " "that first, for example from the family editor or by running " - "the database repair tool, before removing the family.") - - if (not family.get_father_handle() and not family.get_mother_handle() - and not family.get_child_ref_list()): + "the database repair tool, before removing the family." + ) + + if ( + not family.get_father_handle() + and not family.get_mother_handle() + and not family.get_child_ref_list() + ): self.remove_family_relationships(family_handle, trans) else: self.commit_family(family, trans) @@ -1992,8 +2007,18 @@ def get_total(self): note_len = self.get_number_of_notes() tag_len = self.get_number_of_tags() - return (person_len + family_len + event_len + place_len + repo_len + - source_len + citation_len + media_len + note_len + tag_len) + return ( + person_len + + family_len + + event_len + + place_len + + repo_len + + source_len + + citation_len + + media_len + + note_len + + tag_len + ) def set_birth_death_index(self, person): """ @@ -2004,13 +2029,17 @@ def set_birth_death_index(self, person): event_ref_list = person.get_event_ref_list() for index, ref in enumerate(event_ref_list): event = self.get_event_from_handle(ref.ref) - if (event.type.is_birth() + if ( + event.type.is_birth() and ref.role.is_primary() - and (birth_ref_index == -1)): + and (birth_ref_index == -1) + ): birth_ref_index = index - elif (event.type.is_death() - and ref.role.is_primary() - and (death_ref_index == -1)): + elif ( + event.type.is_death() + and ref.role.is_primary() + and (death_ref_index == -1) + ): death_ref_index = index person.birth_ref_index = birth_ref_index diff --git a/gramps/gen/db/dbconst.py b/gramps/gen/db/dbconst.py index 2300160c39b..38fb34d4d2c 100644 --- a/gramps/gen/db/dbconst.py +++ b/gramps/gen/db/dbconst.py @@ -23,40 +23,66 @@ Declare constants used by database modules """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # constants # -#------------------------------------------------------------------------- -__all__ = ( 'DBPAGE', 'DBMODE', 'DBCACHE', 'DBLOCKS', 'DBOBJECTS', 'DBUNDO', - 'DBEXT', 'DBMODE_R', 'DBMODE_W', 'DBUNDOFN', 'DBLOCKFN', - 'DBRECOVFN','BDBVERSFN', 'DBLOGNAME', 'SCHVERSFN', 'PCKVERSFN', - 'DBBACKEND', - 'PERSON_KEY', 'FAMILY_KEY', 'SOURCE_KEY', 'CITATION_KEY', - 'EVENT_KEY', 'MEDIA_KEY', 'PLACE_KEY', 'REPOSITORY_KEY', - 'NOTE_KEY', 'REFERENCE_KEY', 'TAG_KEY', - 'TXNADD', 'TXNUPD', 'TXNDEL', - "CLASS_TO_KEY_MAP", "KEY_TO_CLASS_MAP", "KEY_TO_NAME_MAP" - ) +# ------------------------------------------------------------------------- +__all__ = ( + "DBPAGE", + "DBMODE", + "DBCACHE", + "DBLOCKS", + "DBOBJECTS", + "DBUNDO", + "DBEXT", + "DBMODE_R", + "DBMODE_W", + "DBUNDOFN", + "DBLOCKFN", + "DBRECOVFN", + "BDBVERSFN", + "DBLOGNAME", + "SCHVERSFN", + "PCKVERSFN", + "DBBACKEND", + "PERSON_KEY", + "FAMILY_KEY", + "SOURCE_KEY", + "CITATION_KEY", + "EVENT_KEY", + "MEDIA_KEY", + "PLACE_KEY", + "REPOSITORY_KEY", + "NOTE_KEY", + "REFERENCE_KEY", + "TAG_KEY", + "TXNADD", + "TXNUPD", + "TXNDEL", + "CLASS_TO_KEY_MAP", + "KEY_TO_CLASS_MAP", + "KEY_TO_NAME_MAP", +) -DBEXT = ".db" # File extension to be used for database files -DBUNDOFN = "undo.db" # File name of 'undo' database -DBLOCKFN = "lock" # File name of lock file +DBEXT = ".db" # File extension to be used for database files +DBUNDOFN = "undo.db" # File name of 'undo' database +DBLOCKFN = "lock" # File name of lock file DBRECOVFN = "need_recover" # File name of recovery file -BDBVERSFN = "bdbversion.txt"# File name of Berkeley DB version file +BDBVERSFN = "bdbversion.txt" # File name of Berkeley DB version file DBBACKEND = "database.txt" # File name of Database backend file -SCHVERSFN = "schemaversion.txt"# File name of schema version file -PCKVERSFN = "pickleupgrade.txt" # Indicator that pickle has been upgrade t Python3 -DBLOGNAME = ".Db" # Name of logger -DBMODE_R = "r" # Read-only access -DBMODE_W = "w" # Full Read/Write access -DBPAGE = 16384 # Size of the pages used to hold items in the database -DBMODE = 0o666 # Unix mode for database creation -DBCACHE = 0x4000000 # Size of the shared memory buffer pool -DBLOCKS = 100000 # Maximum number of locks supported -DBOBJECTS = 100000 # Maximum number of simultaneously locked objects -DBUNDO = 1000 # Maximum size of undo buffer -ARRAYSIZE = 1000 # The arraysize for a SQL cursor +SCHVERSFN = "schemaversion.txt" # File name of schema version file +PCKVERSFN = "pickleupgrade.txt" # Indicator that pickle has been upgrade t Python3 +DBLOGNAME = ".Db" # Name of logger +DBMODE_R = "r" # Read-only access +DBMODE_W = "w" # Full Read/Write access +DBPAGE = 16384 # Size of the pages used to hold items in the database +DBMODE = 0o666 # Unix mode for database creation +DBCACHE = 0x4000000 # Size of the shared memory buffer pool +DBLOCKS = 100000 # Maximum number of locks supported +DBOBJECTS = 100000 # Maximum number of simultaneously locked objects +DBUNDO = 1000 # Maximum size of undo buffer +ARRAYSIZE = 1000 # The arraysize for a SQL cursor PERSON_KEY = 0 FAMILY_KEY = 1 @@ -72,36 +98,42 @@ TXNADD, TXNUPD, TXNDEL = 0, 1, 2 -CLASS_TO_KEY_MAP = {"Person": PERSON_KEY, - "Family": FAMILY_KEY, - "Source": SOURCE_KEY, - "Citation": CITATION_KEY, - "Event": EVENT_KEY, - "Media": MEDIA_KEY, - "Place": PLACE_KEY, - "Repository": REPOSITORY_KEY, - "Note" : NOTE_KEY, - "Tag": TAG_KEY} +CLASS_TO_KEY_MAP = { + "Person": PERSON_KEY, + "Family": FAMILY_KEY, + "Source": SOURCE_KEY, + "Citation": CITATION_KEY, + "Event": EVENT_KEY, + "Media": MEDIA_KEY, + "Place": PLACE_KEY, + "Repository": REPOSITORY_KEY, + "Note": NOTE_KEY, + "Tag": TAG_KEY, +} -KEY_TO_CLASS_MAP = {PERSON_KEY: "Person", - FAMILY_KEY: "Family", - SOURCE_KEY: "Source", - CITATION_KEY: "Citation", - EVENT_KEY: "Event", - MEDIA_KEY: "Media", - PLACE_KEY: "Place", - REPOSITORY_KEY: "Repository", - NOTE_KEY: "Note", - TAG_KEY: "Tag"} +KEY_TO_CLASS_MAP = { + PERSON_KEY: "Person", + FAMILY_KEY: "Family", + SOURCE_KEY: "Source", + CITATION_KEY: "Citation", + EVENT_KEY: "Event", + MEDIA_KEY: "Media", + PLACE_KEY: "Place", + REPOSITORY_KEY: "Repository", + NOTE_KEY: "Note", + TAG_KEY: "Tag", +} -KEY_TO_NAME_MAP = {PERSON_KEY: 'person', - FAMILY_KEY: 'family', - EVENT_KEY: 'event', - SOURCE_KEY: 'source', - CITATION_KEY: 'citation', - PLACE_KEY: 'place', - MEDIA_KEY: 'media', - REPOSITORY_KEY: 'repository', - #REFERENCE_KEY: 'reference', - NOTE_KEY: 'note', - TAG_KEY: 'tag'} +KEY_TO_NAME_MAP = { + PERSON_KEY: "person", + FAMILY_KEY: "family", + EVENT_KEY: "event", + SOURCE_KEY: "source", + CITATION_KEY: "citation", + PLACE_KEY: "place", + MEDIA_KEY: "media", + REPOSITORY_KEY: "repository", + # REFERENCE_KEY: 'reference', + NOTE_KEY: "note", + TAG_KEY: "tag", +} diff --git a/gramps/gen/db/dummydb.py b/gramps/gen/db/dummydb.py index 4ce80a119c0..649b6c0ffac 100644 --- a/gramps/gen/db/dummydb.py +++ b/gramps/gen/db/dummydb.py @@ -46,22 +46,22 @@ 'LOG.debug' to 'raise DbException'. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python libraries # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging import inspect from abc import ABCMeta from types import FunctionType from functools import wraps -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps libraries # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .base import DbReadBase from .bookmarks import DbBookmarks from .dbconst import DBLOGNAME @@ -73,20 +73,21 @@ LOG = logging.getLogger(DBLOGNAME) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # some magic, see http://stackoverflow.com/questions/11349183/how-to-wrap-every- # method-of-a-class # # This processes the DummyDb class for diagnostic purposes to wrap each method # with code to log the method name and where it was called from. -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- def wrapper(method): """ wrapper method that returns a 'wrapped' method which can be wrapped round every function in a class. The 'wrapped' method logs the original function that was called, and where it was called from. """ + @wraps(method) def wrapped(*args, **keywargs): """ @@ -99,10 +100,16 @@ def wrapped(*args, **keywargs): frame = inspect.currentframe() c_frame = frame.f_back c_code = c_frame.f_code - LOG.debug('calling %s.%s()... from file %s, line %s in %s', - class_name, func_name, c_code.co_filename, - c_frame.f_lineno, c_code.co_name) + LOG.debug( + "calling %s.%s()... from file %s, line %s in %s", + class_name, + func_name, + c_code.co_filename, + c_frame.f_lineno, + c_code.co_name, + ) return method(*args, **keywargs) + return wrapped @@ -111,6 +118,7 @@ class MetaClass(type): transform class by wrapping it with a diagnostic wrapper (if __debig__ is not set """ + def __new__(mcs, class_name, bases, classdict): """ When the class this is applied to (DummyDb) is instantiated, each method @@ -134,15 +142,26 @@ class M_A_M_B(ABCMeta, MetaClass): See recipe: http://code.activestate.com/recipes/204197-solving-the- metaclass-conflict/ """ + pass -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # class DummyDb # -#------------------------------------------------------------------------- -class DummyDb(M_A_M_B("NewBaseClass", (DbReadBase, Callback, object,), {})): +# ------------------------------------------------------------------------- +class DummyDb( + M_A_M_B( + "NewBaseClass", + ( + DbReadBase, + Callback, + object, + ), + {}, + ) +): """ Gramps database object. This object is a dummy database class that is always empty and is read-only. @@ -156,7 +175,7 @@ def __init__(self): """ Callback.__init__(self) self.basedb = None - self.__feature = {} # {"feature": VALUE, ...} + self.__feature = {} # {"feature": VALUE, ...} self.db_is_open = False self.readonly = True self.name_formats = [] @@ -176,7 +195,7 @@ def get_feature(self, feature): Databases can implement certain features or not. The default is None, unless otherwise explicitly stated. """ - return self.__feature.get(feature, None) # can also be explicitly None + return self.__feature.get(feature, None) # can also be explicitly None def set_feature(self, feature, value): """ @@ -469,7 +488,7 @@ def get_family_from_handle(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_family_handles(self, sort_handles=False, locale=glocale): """ @@ -611,7 +630,7 @@ def get_note_from_handle(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_note_handles(self): """ @@ -731,7 +750,7 @@ def get_media_from_handle(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_person_attribute_types(self): """ @@ -778,7 +797,7 @@ def get_person_from_handle(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_person_handles(self, sort_handles=False, locale=glocale): """ @@ -839,7 +858,7 @@ def get_place_from_handle(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_place_handles(self, sort_handles=False, locale=glocale): """ @@ -862,7 +881,7 @@ def get_raw_event_data(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_raw_family_data(self, handle): """ @@ -871,7 +890,7 @@ def get_raw_family_data(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_raw_note_data(self, handle): """ @@ -880,7 +899,7 @@ def get_raw_note_data(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_raw_media_data(self, handle): """ @@ -889,7 +908,7 @@ def get_raw_media_data(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_raw_person_data(self, handle): """ @@ -898,7 +917,7 @@ def get_raw_person_data(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_raw_place_data(self, handle): """ @@ -907,7 +926,7 @@ def get_raw_place_data(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_raw_repository_data(self, handle): """ @@ -916,7 +935,7 @@ def get_raw_repository_data(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_raw_source_data(self, handle): """ @@ -925,7 +944,7 @@ def get_raw_source_data(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_raw_citation_data(self, handle): """ @@ -934,7 +953,7 @@ def get_raw_citation_data(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_raw_tag_data(self, handle): """ @@ -943,7 +962,7 @@ def get_raw_tag_data(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_repo_bookmarks(self): """ @@ -981,7 +1000,7 @@ def get_repository_from_handle(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_repository_handles(self): """ @@ -1052,7 +1071,7 @@ def get_source_from_handle(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_source_handles(self, sort_handles=False, locale=glocale): """ @@ -1113,7 +1132,7 @@ def get_citation_from_handle(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_citation_handles(self, sort_handles=False, locale=glocale): """ @@ -1154,7 +1173,7 @@ def get_tag_from_handle(self, handle): if not self.db_is_open: LOG.debug("database is closed") LOG.warning("handle %s does not exist in the dummy database", handle) - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_tag_from_name(self, val): """ @@ -1437,11 +1456,17 @@ def iter_tags(self): LOG.debug("database is closed") return [] - def load(self, name, callback=None, mode=None, force_schema_upgrade=False, - force_bsddb_upgrade=False, - force_bsddb_downgrade=False, - force_python_upgrade=False, - update=True): + def load( + self, + name, + callback=None, + mode=None, + force_schema_upgrade=False, + force_bsddb_upgrade=False, + force_bsddb_downgrade=False, + force_python_upgrade=False, + update=True, + ): """ Open the specified database. """ @@ -1536,8 +1561,9 @@ def set_place_id_prefix(self, val): """ LOG.warning("database is readonly") - def set_prefixes(self, person, media, family, source, citation, - place, event, repository, note): + def set_prefixes( + self, person, media, family, source, citation, place, event, repository, note + ): """ Set the prefixes for the gramps ids for all gramps objects """ diff --git a/gramps/gen/db/exceptions.py b/gramps/gen/db/exceptions.py index ab23ca9d75d..63216f01311 100644 --- a/gramps/gen/db/exceptions.py +++ b/gramps/gen/db/exceptions.py @@ -20,28 +20,29 @@ """Exceptions generated by the Db package.""" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..const import URL_WIKISTRING, URL_MANUAL_PAGE from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Constants # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- URL_WIKI_START = '' URL_BACKUP2_START = URL_MANUAL_START + '#Backing_up_a_Family_Tree">' URL_EXPORT_START = URL_MANUAL_START + '#Export_into_Gramps_formats">' -class DbException(Exception): +class DbException(Exception): def __init__(self, value): Exception.__init__(self) self.value = value @@ -49,10 +50,12 @@ def __init__(self, value): def __str__(self): return self.value + class DbWriteFailure(Exception): """ Error used to indicate that a write to a database has failed. """ + def __init__(self, value, value2=""): Exception.__init__(self) self.value = value @@ -64,11 +67,13 @@ def __str__(self): def messages(self): return self.value, self.value2 + class DbTransactionCancel(Exception): """ Error used to indicate that a transaction needs to be canceled, for example becuase it is lengthy and the users requests so. """ + def __init__(self, value): Exception.__init__(self) self.value = value @@ -76,11 +81,13 @@ def __init__(self, value): def __str__(self): return self.value + class DbVersionError(Exception): """ Error used to report that a file could not be read because it is written in an unsupported version of the file format. """ + def __init__(self, tree_vers, min_vers, max_vers): Exception.__init__(self) self.tree_vers = tree_vers @@ -88,22 +95,27 @@ def __init__(self, tree_vers, min_vers, max_vers): self.max_vers = max_vers def __str__(self): - return _('The schema version is not supported by this version of ' - 'Gramps.\n\n' - 'This Family Tree is schema version %(tree_vers)s, and this ' - 'version of Gramps supports versions %(min_vers)s to ' - '%(max_vers)s\n\n' - 'Please upgrade to the corresponding version or use ' - 'XML for porting data between different schema versions.') %\ - {'tree_vers': self.tree_vers, - 'min_vers': self.min_vers, - 'max_vers': self.max_vers} + return _( + "The schema version is not supported by this version of " + "Gramps.\n\n" + "This Family Tree is schema version %(tree_vers)s, and this " + "version of Gramps supports versions %(min_vers)s to " + "%(max_vers)s\n\n" + "Please upgrade to the corresponding version or use " + "XML for porting data between different schema versions." + ) % { + "tree_vers": self.tree_vers, + "min_vers": self.min_vers, + "max_vers": self.max_vers, + } + class DbPythonError(Exception): """ Error used to report that a file could not be read because it is written in an unsupported version of the Python format. """ + def __init__(self, tree_vers, min_vers, max_vers): Exception.__init__(self) self.tree_vers = tree_vers @@ -111,16 +123,19 @@ def __init__(self, tree_vers, min_vers, max_vers): self.max_vers = max_vers def __str__(self): - return _('The Python version is not supported by this version of ' - 'Gramps.\n\n' - 'This Family Tree is Python version %(tree_vers)s, and this ' - 'version of Gramps supports versions %(min_vers)s to ' - '%(max_vers)s\n\n' - 'Please upgrade to the corresponding version or use ' - 'XML for porting data between different Python versions.') %\ - {'tree_vers': self.tree_vers, - 'min_vers': self.min_vers, - 'max_vers': self.max_vers} + return _( + "The Python version is not supported by this version of " + "Gramps.\n\n" + "This Family Tree is Python version %(tree_vers)s, and this " + "version of Gramps supports versions %(min_vers)s to " + "%(max_vers)s\n\n" + "Please upgrade to the corresponding version or use " + "XML for porting data between different Python versions." + ) % { + "tree_vers": self.tree_vers, + "min_vers": self.min_vers, + "max_vers": self.max_vers, + } class DbUpgradeRequiredError(Exception): @@ -128,84 +143,94 @@ class DbUpgradeRequiredError(Exception): Error used to report that a database needs to be upgraded before it can be used. """ + def __init__(self, oldschema, newschema): Exception.__init__(self) self.oldschema = oldschema self.newschema = newschema def __str__(self): - return _('The Family Tree you are trying to load is in the schema ' - 'version %(oldschema)s format. This version of Gramps uses ' - 'schema version %(newschema)s. Therefore you cannot load this ' - 'Family Tree without upgrading the schema version of the ' - 'Family Tree.\n\n' - 'If you upgrade then you won\'t be able to use the previous ' - 'version of Gramps, even if you subsequently ' - '%(wiki_manual_backup_html_start)sbackup%(html_end)s or ' - '%(wiki_manual_export_html_start)sexport%(html_end)s ' - 'your upgraded Family Tree.\n\n' - 'Upgrading is a difficult task which could irretrievably ' - 'corrupt your Family Tree if it is interrupted or fails.\n\n' - 'If you have not already made a backup of your Family Tree, ' - 'then you should start your %(bold_start)sold%(bold_end)s ' - 'version of Gramps and ' - '%(wiki_backup_html_start)smake a backup%(html_end)s ' - 'of your Family Tree.') % { - 'wiki_backup_html_start' : URL_BACKUP1_START , - 'wiki_manual_backup_html_start' : URL_BACKUP2_START , - 'wiki_manual_export_html_start' : URL_EXPORT_START , - 'html_end' : '' , - 'bold_start' : '' , - 'bold_end' : '' , - 'oldschema' : self.oldschema, - 'newschema' : self.newschema } + return _( + "The Family Tree you are trying to load is in the schema " + "version %(oldschema)s format. This version of Gramps uses " + "schema version %(newschema)s. Therefore you cannot load this " + "Family Tree without upgrading the schema version of the " + "Family Tree.\n\n" + "If you upgrade then you won't be able to use the previous " + "version of Gramps, even if you subsequently " + "%(wiki_manual_backup_html_start)sbackup%(html_end)s or " + "%(wiki_manual_export_html_start)sexport%(html_end)s " + "your upgraded Family Tree.\n\n" + "Upgrading is a difficult task which could irretrievably " + "corrupt your Family Tree if it is interrupted or fails.\n\n" + "If you have not already made a backup of your Family Tree, " + "then you should start your %(bold_start)sold%(bold_end)s " + "version of Gramps and " + "%(wiki_backup_html_start)smake a backup%(html_end)s " + "of your Family Tree." + ) % { + "wiki_backup_html_start": URL_BACKUP1_START, + "wiki_manual_backup_html_start": URL_BACKUP2_START, + "wiki_manual_export_html_start": URL_EXPORT_START, + "html_end": "", + "bold_start": "", + "bold_end": "", + "oldschema": self.oldschema, + "newschema": self.newschema, + } class DbConnectionError(Exception): """ Error used to report that a database connection failed. """ + def __init__(self, msg, settings_file): Exception.__init__(self) self.msg = msg self.settings_file = settings_file def __str__(self): - return _('Database connection failed.\n\n' - '%(message)s\n' - 'Please check your connection settings file:\n' - '%(settings_file)s') % { - 'message': self.msg, - 'settings_file': self.settings_file} + return _( + "Database connection failed.\n\n" + "%(message)s\n" + "Please check your connection settings file:\n" + "%(settings_file)s" + ) % {"message": self.msg, "settings_file": self.settings_file} class DbSupportedError(Exception): """ Error used to report that a database is no longer supported. """ + def __init__(self, msg): Exception.__init__(self) self.msg = msg def __str__(self): - return _('The Family Tree you are trying to load is in the %(dbtype)s ' - 'database, which is no longer supported.\nTherefore you ' - 'cannot load this Family Tree without upgrading.\n\n' - 'If you upgrade then you won\'t be able to use the previous ' - 'version of Gramps, even if you subsequently ' - '%(wiki_manual_backup_html_start)sbackup%(html_end)s or ' - '%(wiki_manual_export_html_start)sexport%(html_end)s ' - 'your upgraded Family Tree.\n\n' - 'You are strongly advised to backup your Family Tree.\n\n' - 'If you have not already made a backup of your Family Tree, ' - 'then you should start your previous version of Gramps and ' - '%(wiki_backup_html_start)smake a backup%(html_end)s ' - 'of your Family Tree.') % { - 'dbtype' : self.msg, - 'wiki_manual_backup_html_start' : URL_BACKUP2_START , - 'wiki_manual_export_html_start' : URL_EXPORT_START , - 'wiki_backup_html_start' : URL_BACKUP1_START , - 'html_end' : ''} + return _( + "The Family Tree you are trying to load is in the %(dbtype)s " + "database, which is no longer supported.\nTherefore you " + "cannot load this Family Tree without upgrading.\n\n" + "If you upgrade then you won't be able to use the previous " + "version of Gramps, even if you subsequently " + "%(wiki_manual_backup_html_start)sbackup%(html_end)s or " + "%(wiki_manual_export_html_start)sexport%(html_end)s " + "your upgraded Family Tree.\n\n" + "You are strongly advised to backup your Family Tree.\n\n" + "If you have not already made a backup of your Family Tree, " + "then you should start your previous version of Gramps and " + "%(wiki_backup_html_start)smake a backup%(html_end)s " + "of your Family Tree." + ) % { + "dbtype": self.msg, + "wiki_manual_backup_html_start": URL_BACKUP2_START, + "wiki_manual_export_html_start": URL_EXPORT_START, + "wiki_backup_html_start": URL_BACKUP1_START, + "html_end": "", + } + if __name__ == "__main__": """ @@ -215,11 +240,8 @@ def __str__(self): """ import sys - print("\nDbVersionError:\n", - DbVersionError('1.6.0', '1.5.0', '1.5.1')) - print("\nDbUpgradeRequiredError:\n", - DbUpgradeRequiredError('1.5.1', '1.6.0')) + print("\nDbVersionError:\n", DbVersionError("1.6.0", "1.5.0", "1.5.1")) + print("\nDbUpgradeRequiredError:\n", DbUpgradeRequiredError("1.5.1", "1.6.0")) sys.exit(0) - print("\nxxx:\n", - xxx('4.8.30', '4.8.29')) + print("\nxxx:\n", xxx("4.8.30", "4.8.29")) diff --git a/gramps/gen/db/generic.py b/gramps/gen/db/generic.py index 674a9aa9216..fbed28b8ba9 100644 --- a/gramps/gen/db/generic.py +++ b/gramps/gen/db/generic.py @@ -19,11 +19,11 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Python Modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ import random import pickle import time @@ -37,16 +37,35 @@ import glob from pathlib import Path -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Gramps Modules # -#------------------------------------------------------------------------ -from . import (DbReadBase, DbWriteBase, DbUndo, DBLOGNAME, DBUNDOFN, - REFERENCE_KEY, PERSON_KEY, FAMILY_KEY, - CITATION_KEY, SOURCE_KEY, EVENT_KEY, MEDIA_KEY, PLACE_KEY, - REPOSITORY_KEY, NOTE_KEY, TAG_KEY, TXNADD, TXNUPD, TXNDEL, - KEY_TO_NAME_MAP, DBMODE_R, DBMODE_W) +# ------------------------------------------------------------------------ +from . import ( + DbReadBase, + DbWriteBase, + DbUndo, + DBLOGNAME, + DBUNDOFN, + REFERENCE_KEY, + PERSON_KEY, + FAMILY_KEY, + CITATION_KEY, + SOURCE_KEY, + EVENT_KEY, + MEDIA_KEY, + PLACE_KEY, + REPOSITORY_KEY, + NOTE_KEY, + TAG_KEY, + TXNADD, + TXNUPD, + TXNDEL, + KEY_TO_NAME_MAP, + DBMODE_R, + DBMODE_W, +) from .utils import write_lock_file, clear_lock_file from .exceptions import DbVersionError, DbUpgradeRequiredError from ..errors import HandleError @@ -56,17 +75,41 @@ from ..utils.id import create_id from ..lib.researcher import Researcher -from ..lib import (Tag, Media, Person, Family, Source, Citation, Event, - Place, Repository, Note, NameOriginType) +from ..lib import ( + Tag, + Media, + Person, + Family, + Source, + Citation, + Event, + Place, + Repository, + Note, + NameOriginType, +) from ..lib.genderstats import GenderStats from ..config import config from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext LOG = logging.getLogger(DBLOGNAME) -SIGBASE = ('person', 'family', 'source', 'event', 'media', - 'place', 'repository', 'reference', 'note', 'tag', 'citation') +SIGBASE = ( + "person", + "family", + "source", + "event", + "media", + "place", + "repository", + "reference", + "note", + "tag", + "citation", +) + class DbGenericUndo(DbUndo): def __init__(self, grampsdb, path): @@ -131,8 +174,9 @@ def _redo(self, update_history): try: self.db._txn_begin() for record_id in subitems: - (key, trans_type, handle, old_data, new_data) = \ - pickle.loads(self.undodb[record_id]) + (key, trans_type, handle, old_data, new_data) = pickle.loads( + self.undodb[record_id] + ) if key == REFERENCE_KEY: self.db.undo_reference(new_data, handle) @@ -154,8 +198,7 @@ def _redo(self, update_history): if db.redo_callback: if self.redo_count > 1: new_transaction = self.redoq[-2] - db.redo_callback(_("_Redo %s") - % new_transaction.get_description()) + db.redo_callback(_("_Redo %s") % new_transaction.get_description()) else: db.redo_callback(None) @@ -180,8 +223,9 @@ def _undo(self, update_history): try: self.db._txn_begin() for record_id in subitems: - (key, trans_type, handle, old_data, new_data) = \ - pickle.loads(self.undodb[record_id]) + (key, trans_type, handle, old_data, new_data) = pickle.loads( + self.undodb[record_id] + ) if key == REFERENCE_KEY: self.db.undo_reference(old_data, handle) @@ -199,14 +243,12 @@ def _undo(self, update_history): # Notify listeners if db.undo_callback: if self.undo_count > 0: - db.undo_callback(_("_Undo %s") - % self.undoq[-1].get_description()) + db.undo_callback(_("_Undo %s") % self.undoq[-1].get_description()) else: db.undo_callback(None) if db.redo_callback: - db.redo_callback(_("_Redo %s") - % transaction.get_description()) + db.redo_callback(_("_Redo %s") % transaction.get_description()) if update_history and db.undo_history_callback: db.undo_history_callback() @@ -222,83 +264,109 @@ def undo_sigs(self, sigs, undo): for obj_type in range(11): handles = sigs[obj_type][trans_type] if handles: - if not undo and trans_type == TXNDEL \ - or undo and trans_type == TXNADD: - typ = '-delete' + if ( + not undo + and trans_type == TXNDEL + or undo + and trans_type == TXNADD + ): + typ = "-delete" else: # don't update a handle if its been deleted, and note # that 'deleted' handles are in the 'add' list if we # are undoing - handles = [handle for handle in handles - if handle not in - sigs[obj_type][TXNADD if undo else TXNDEL]] - if ((not undo) and trans_type == TXNADD) \ - or (undo and trans_type == TXNDEL): - typ = '-add' - else: # TXNUPD - typ = '-update' + handles = [ + handle + for handle in handles + if handle not in sigs[obj_type][TXNADD if undo else TXNDEL] + ] + if ((not undo) and trans_type == TXNADD) or ( + undo and trans_type == TXNDEL + ): + typ = "-add" + else: # TXNUPD + typ = "-update" if handles: - self.db.emit(KEY_TO_NAME_MAP[obj_type] + typ, - (handles,)) + self.db.emit(KEY_TO_NAME_MAP[obj_type] + typ, (handles,)) + class Cursor: def __init__(self, iterator): self.iterator = iterator self._iter = self.__iter__() + def __enter__(self): return self + def __iter__(self): for handle, data in self.iterator(): yield (handle, data) + def __next__(self): try: return self._iter.__next__() except StopIteration: return None + def __exit__(self, *args, **kwargs): pass + def iter(self): for handle, data in self.iterator(): yield (handle, data) + def first(self): self._iter = self.__iter__() try: return next(self._iter) except: return + def next(self): try: return next(self._iter) except: return + def close(self): pass + class DbGeneric(DbWriteBase, DbReadBase, UpdateCallback, Callback): """ A Gramps Database Backend. This replicates the grampsdb functions. """ - __signals__ = dict((obj+'-'+op, signal) - for obj in - ['person', 'family', 'event', 'place', 'repository', - 'source', 'citation', 'media', 'note', 'tag'] - for op, signal in zip( - ['add', 'update', 'delete', 'rebuild'], - [(list,), (list,), (list,), None] - ) - ) + + __signals__ = dict( + (obj + "-" + op, signal) + for obj in [ + "person", + "family", + "event", + "place", + "repository", + "source", + "citation", + "media", + "note", + "tag", + ] + for op, signal in zip( + ["add", "update", "delete", "rebuild"], [(list,), (list,), (list,), None] + ) + ) # 2. Signals for long operations - __signals__.update(('long-op-'+op, signal) for op, signal in zip( - ['start', 'heartbeat', 'end'], - [(object,), None, None] - )) + __signals__.update( + ("long-op-" + op, signal) + for op, signal in zip(["start", "heartbeat", "end"], [(object,), None, None]) + ) # 3. Special signal for change in home person - __signals__['home-person-changed'] = None + __signals__["home-person-changed"] = None # 4. Signal for change in person group name, parameters are - __signals__['person-groupname-rebuild'] = (str, str) + __signals__["person-groupname-rebuild"] = (str, str) __callback_map = {} @@ -309,8 +377,7 @@ def __init__(self, directory=None): DbWriteBase.__init__(self) Callback.__init__(self) self.__tables = { - 'Person': - { + "Person": { "handle_func": self.get_person_from_handle, "gramps_id_func": self.get_person_from_gramps_id, "class_func": Person, @@ -327,8 +394,7 @@ def __init__(self, directory=None): "raw_id_func": self._get_raw_person_from_id_data, "del_func": self.remove_person, }, - 'Family': - { + "Family": { "handle_func": self.get_family_from_handle, "gramps_id_func": self.get_family_from_gramps_id, "class_func": Family, @@ -345,8 +411,7 @@ def __init__(self, directory=None): "raw_id_func": self._get_raw_family_from_id_data, "del_func": self.remove_family, }, - 'Source': - { + "Source": { "handle_func": self.get_source_from_handle, "gramps_id_func": self.get_source_from_gramps_id, "class_func": Source, @@ -362,9 +427,8 @@ def __init__(self, directory=None): "raw_func": self.get_raw_source_data, "raw_id_func": self._get_raw_source_from_id_data, "del_func": self.remove_source, - }, - 'Citation': - { + }, + "Citation": { "handle_func": self.get_citation_from_handle, "gramps_id_func": self.get_citation_from_gramps_id, "class_func": Citation, @@ -381,8 +445,7 @@ def __init__(self, directory=None): "raw_id_func": self._get_raw_citation_from_id_data, "del_func": self.remove_citation, }, - 'Event': - { + "Event": { "handle_func": self.get_event_from_handle, "gramps_id_func": self.get_event_from_gramps_id, "class_func": Event, @@ -399,8 +462,7 @@ def __init__(self, directory=None): "raw_id_func": self._get_raw_event_from_id_data, "del_func": self.remove_event, }, - 'Media': - { + "Media": { "handle_func": self.get_media_from_handle, "gramps_id_func": self.get_media_from_gramps_id, "class_func": Media, @@ -417,8 +479,7 @@ def __init__(self, directory=None): "raw_id_func": self._get_raw_media_from_id_data, "del_func": self.remove_media, }, - 'Place': - { + "Place": { "handle_func": self.get_place_from_handle, "gramps_id_func": self.get_place_from_gramps_id, "class_func": Place, @@ -435,8 +496,7 @@ def __init__(self, directory=None): "raw_id_func": self._get_raw_place_from_id_data, "del_func": self.remove_place, }, - 'Repository': - { + "Repository": { "handle_func": self.get_repository_from_handle, "gramps_id_func": self.get_repository_from_gramps_id, "class_func": Repository, @@ -453,8 +513,7 @@ def __init__(self, directory=None): "raw_id_func": self._get_raw_repository_from_id_data, "del_func": self.remove_repository, }, - 'Note': - { + "Note": { "handle_func": self.get_note_from_handle, "gramps_id_func": self.get_note_from_gramps_id, "class_func": Note, @@ -471,8 +530,7 @@ def __init__(self, directory=None): "raw_id_func": self._get_raw_note_from_id_data, "del_func": self.remove_note, }, - 'Tag': - { + "Tag": { "handle_func": self.get_tag_from_handle, "gramps_id_func": None, "class_func": Tag, @@ -485,7 +543,7 @@ def __init__(self, directory=None): "count_func": self.get_number_of_tags, "raw_func": self.get_raw_tag_data, "del_func": self.remove_tag, - } + }, } self.readonly = False self.db_is_open = False @@ -500,15 +558,15 @@ def __init__(self, directory=None): self.repo_bookmarks = DbBookmarks() self.media_bookmarks = DbBookmarks() self.note_bookmarks = DbBookmarks() - self.set_person_id_prefix('I%04d') - self.set_media_id_prefix('O%04d') - self.set_family_id_prefix('F%04d') - self.set_citation_id_prefix('C%04d') - self.set_source_id_prefix('S%04d') - self.set_place_id_prefix('P%04d') - self.set_event_id_prefix('E%04d') - self.set_repository_id_prefix('R%04d') - self.set_note_id_prefix('N%04d') + self.set_person_id_prefix("I%04d") + self.set_media_id_prefix("O%04d") + self.set_family_id_prefix("F%04d") + self.set_citation_id_prefix("C%04d") + self.set_source_id_prefix("S%04d") + self.set_place_id_prefix("P%04d") + self.set_event_id_prefix("E%04d") + self.set_repository_id_prefix("R%04d") + self.set_note_id_prefix("N%04d") # ---------------------------------- self.undodb = None self.cmap_index = 0 @@ -529,7 +587,7 @@ def __init__(self, directory=None): self._bm_changes = 0 self.has_changed = 0 # Also gives commits since startup self.surname_list = [] - self.genderStats = GenderStats() # can pass in loaded stats as dict + self.genderStats = GenderStats() # can pass in loaded stats as dict self.owner = Researcher() if directory: self.load(directory) @@ -546,7 +604,7 @@ def __check_readonly(self, name): otherwise return False (that is, we DO have read/write access) """ # In-memory databases always allow write access. - if name == ':memory:': + if name == ":memory:": return False # See if we write to the target directory at all? @@ -554,21 +612,26 @@ def __check_readonly(self, name): return True # See if we lack write access to the database file - path = os.path.join(name, 'sqlite.db') + path = os.path.join(name, "sqlite.db") if os.path.isfile(path) and not os.access(path, os.W_OK): return True # All tests passed. Inform caller that we are NOT read only return False - def load(self, directory, callback=None, mode=DBMODE_W, - force_schema_upgrade=False, - force_bsddb_upgrade=False, - force_bsddb_downgrade=False, - force_python_upgrade=False, - update=True, - username=None, - password=None): + def load( + self, + directory, + callback=None, + mode=DBMODE_W, + force_schema_upgrade=False, + force_bsddb_upgrade=False, + force_bsddb_downgrade=False, + force_python_upgrade=False, + update=True, + username=None, + password=None, + ): """ If update is False: then don't update any files """ @@ -577,7 +640,7 @@ def load(self, directory, callback=None, mode=DBMODE_W, self.readonly = mode == DBMODE_R - if not self.readonly and directory != ':memory:': + if not self.readonly and directory != ":memory:": write_lock_file(directory) # run backend-specific code: @@ -585,41 +648,41 @@ def load(self, directory, callback=None, mode=DBMODE_W, if not self._schema_exists(): self._create_schema() - self._set_metadata('version', str(self.VERSION[0])) + self._set_metadata("version", str(self.VERSION[0])) # Load metadata - self.name_formats = self._get_metadata('name_formats') - self.owner = self._get_metadata('researcher', default=Researcher()) + self.name_formats = self._get_metadata("name_formats") + self.owner = self._get_metadata("researcher", default=Researcher()) # Load bookmarks - self.bookmarks.load(self._get_metadata('bookmarks')) - self.family_bookmarks.load(self._get_metadata('family_bookmarks')) - self.event_bookmarks.load(self._get_metadata('event_bookmarks')) - self.source_bookmarks.load(self._get_metadata('source_bookmarks')) - self.citation_bookmarks.load(self._get_metadata('citation_bookmarks')) - self.repo_bookmarks.load(self._get_metadata('repo_bookmarks')) - self.media_bookmarks.load(self._get_metadata('media_bookmarks')) - self.place_bookmarks.load(self._get_metadata('place_bookmarks')) - self.note_bookmarks.load(self._get_metadata('note_bookmarks')) + self.bookmarks.load(self._get_metadata("bookmarks")) + self.family_bookmarks.load(self._get_metadata("family_bookmarks")) + self.event_bookmarks.load(self._get_metadata("event_bookmarks")) + self.source_bookmarks.load(self._get_metadata("source_bookmarks")) + self.citation_bookmarks.load(self._get_metadata("citation_bookmarks")) + self.repo_bookmarks.load(self._get_metadata("repo_bookmarks")) + self.media_bookmarks.load(self._get_metadata("media_bookmarks")) + self.place_bookmarks.load(self._get_metadata("place_bookmarks")) + self.note_bookmarks.load(self._get_metadata("note_bookmarks")) # Custom type values - self.event_names = self._get_metadata('event_names', set()) - self.family_attributes = self._get_metadata('fattr_names', set()) - self.individual_attributes = self._get_metadata('pattr_names', set()) - self.source_attributes = self._get_metadata('sattr_names', set()) - self.marker_names = self._get_metadata('marker_names', set()) - self.child_ref_types = self._get_metadata('child_refs', set()) - self.family_rel_types = self._get_metadata('family_rels', set()) - self.event_role_names = self._get_metadata('event_roles', set()) - self.name_types = self._get_metadata('name_types', set()) - self.origin_types = self._get_metadata('origin_types', set()) - self.repository_types = self._get_metadata('repo_types', set()) - self.note_types = self._get_metadata('note_types', set()) - self.source_media_types = self._get_metadata('sm_types', set()) - self.url_types = self._get_metadata('url_types', set()) - self.media_attributes = self._get_metadata('mattr_names', set()) - self.event_attributes = self._get_metadata('eattr_names', set()) - self.place_types = self._get_metadata('place_types', set()) + self.event_names = self._get_metadata("event_names", set()) + self.family_attributes = self._get_metadata("fattr_names", set()) + self.individual_attributes = self._get_metadata("pattr_names", set()) + self.source_attributes = self._get_metadata("sattr_names", set()) + self.marker_names = self._get_metadata("marker_names", set()) + self.child_ref_types = self._get_metadata("child_refs", set()) + self.family_rel_types = self._get_metadata("family_rels", set()) + self.event_role_names = self._get_metadata("event_roles", set()) + self.name_types = self._get_metadata("name_types", set()) + self.origin_types = self._get_metadata("origin_types", set()) + self.repository_types = self._get_metadata("repo_types", set()) + self.note_types = self._get_metadata("note_types", set()) + self.source_media_types = self._get_metadata("sm_types", set()) + self.url_types = self._get_metadata("url_types", set()) + self.media_attributes = self._get_metadata("mattr_names", set()) + self.event_attributes = self._get_metadata("eattr_names", set()) + self.place_types = self._get_metadata("place_types", set()) # surname list self.surname_list = self.get_surname_list() @@ -638,27 +701,28 @@ def load(self, directory, callback=None, mode=DBMODE_W, self.genderStats = GenderStats(gstats) # Indexes: - self.cmap_index = self._get_metadata('cmap_index', 0) - self.smap_index = self._get_metadata('smap_index', 0) - self.emap_index = self._get_metadata('emap_index', 0) - self.pmap_index = self._get_metadata('pmap_index', 0) - self.fmap_index = self._get_metadata('fmap_index', 0) - self.lmap_index = self._get_metadata('lmap_index', 0) - self.omap_index = self._get_metadata('omap_index', 0) - self.rmap_index = self._get_metadata('rmap_index', 0) - self.nmap_index = self._get_metadata('nmap_index', 0) + self.cmap_index = self._get_metadata("cmap_index", 0) + self.smap_index = self._get_metadata("smap_index", 0) + self.emap_index = self._get_metadata("emap_index", 0) + self.pmap_index = self._get_metadata("pmap_index", 0) + self.fmap_index = self._get_metadata("fmap_index", 0) + self.lmap_index = self._get_metadata("lmap_index", 0) + self.omap_index = self._get_metadata("omap_index", 0) + self.rmap_index = self._get_metadata("rmap_index", 0) + self.nmap_index = self._get_metadata("nmap_index", 0) self.db_is_open = True # Check on db version to see if we need upgrade or too new - dbversion = int(self._get_metadata('version', default='0')) + dbversion = int(self._get_metadata("version", default="0")) if dbversion > self.VERSION[0]: self.close() raise DbVersionError(dbversion, 18, self.VERSION[0]) if not self.readonly and dbversion < self.VERSION[0]: - LOG.debug("Schema upgrade required from %s to %s", - dbversion, self.VERSION[0]) + LOG.debug( + "Schema upgrade required from %s to %s", dbversion, self.VERSION[0] + ) if force_schema_upgrade: self._gramps_upgrade(dbversion, directory, callback) else: @@ -690,56 +754,53 @@ def close(self, update=True, user=None): Path(filename).touch() # Save metadata - self._set_metadata('name_formats', self.name_formats) - self._set_metadata('researcher', self.owner) + self._set_metadata("name_formats", self.name_formats) + self._set_metadata("researcher", self.owner) # Bookmarks - self._set_metadata('bookmarks', self.bookmarks.get()) - self._set_metadata('family_bookmarks', - self.family_bookmarks.get()) - self._set_metadata('event_bookmarks', self.event_bookmarks.get()) - self._set_metadata('place_bookmarks', self.place_bookmarks.get()) - self._set_metadata('repo_bookmarks', self.repo_bookmarks.get()) - self._set_metadata('source_bookmarks', - self.source_bookmarks.get()) - self._set_metadata('citation_bookmarks', - self.citation_bookmarks.get()) - self._set_metadata('media_bookmarks', self.media_bookmarks.get()) - self._set_metadata('note_bookmarks', self.note_bookmarks.get()) + self._set_metadata("bookmarks", self.bookmarks.get()) + self._set_metadata("family_bookmarks", self.family_bookmarks.get()) + self._set_metadata("event_bookmarks", self.event_bookmarks.get()) + self._set_metadata("place_bookmarks", self.place_bookmarks.get()) + self._set_metadata("repo_bookmarks", self.repo_bookmarks.get()) + self._set_metadata("source_bookmarks", self.source_bookmarks.get()) + self._set_metadata("citation_bookmarks", self.citation_bookmarks.get()) + self._set_metadata("media_bookmarks", self.media_bookmarks.get()) + self._set_metadata("note_bookmarks", self.note_bookmarks.get()) # Custom type values, sets - self._set_metadata('event_names', self.event_names) - self._set_metadata('fattr_names', self.family_attributes) - self._set_metadata('pattr_names', self.individual_attributes) - self._set_metadata('sattr_names', self.source_attributes) - self._set_metadata('marker_names', self.marker_names) - self._set_metadata('child_refs', self.child_ref_types) - self._set_metadata('family_rels', self.family_rel_types) - self._set_metadata('event_roles', self.event_role_names) - self._set_metadata('name_types', self.name_types) - self._set_metadata('origin_types', self.origin_types) - self._set_metadata('repo_types', self.repository_types) - self._set_metadata('note_types', self.note_types) - self._set_metadata('sm_types', self.source_media_types) - self._set_metadata('url_types', self.url_types) - self._set_metadata('mattr_names', self.media_attributes) - self._set_metadata('eattr_names', self.event_attributes) - self._set_metadata('place_types', self.place_types) + self._set_metadata("event_names", self.event_names) + self._set_metadata("fattr_names", self.family_attributes) + self._set_metadata("pattr_names", self.individual_attributes) + self._set_metadata("sattr_names", self.source_attributes) + self._set_metadata("marker_names", self.marker_names) + self._set_metadata("child_refs", self.child_ref_types) + self._set_metadata("family_rels", self.family_rel_types) + self._set_metadata("event_roles", self.event_role_names) + self._set_metadata("name_types", self.name_types) + self._set_metadata("origin_types", self.origin_types) + self._set_metadata("repo_types", self.repository_types) + self._set_metadata("note_types", self.note_types) + self._set_metadata("sm_types", self.source_media_types) + self._set_metadata("url_types", self.url_types) + self._set_metadata("mattr_names", self.media_attributes) + self._set_metadata("eattr_names", self.event_attributes) + self._set_metadata("place_types", self.place_types) # Save misc items: if self.has_changed: self.save_gender_stats(self.genderStats) # Indexes: - self._set_metadata('cmap_index', self.cmap_index) - self._set_metadata('smap_index', self.smap_index) - self._set_metadata('emap_index', self.emap_index) - self._set_metadata('pmap_index', self.pmap_index) - self._set_metadata('fmap_index', self.fmap_index) - self._set_metadata('lmap_index', self.lmap_index) - self._set_metadata('omap_index', self.omap_index) - self._set_metadata('rmap_index', self.rmap_index) - self._set_metadata('nmap_index', self.nmap_index) + self._set_metadata("cmap_index", self.cmap_index) + self._set_metadata("smap_index", self.smap_index) + self._set_metadata("emap_index", self.emap_index) + self._set_metadata("pmap_index", self.pmap_index) + self._set_metadata("fmap_index", self.fmap_index) + self._set_metadata("lmap_index", self.lmap_index) + self._set_metadata("omap_index", self.omap_index) + self._set_metadata("rmap_index", self.rmap_index) + self._set_metadata("nmap_index", self.nmap_index) self._close() @@ -769,7 +830,7 @@ def get_dbname(self): if self._directory: filepath = os.path.join(self._directory, "name.txt") try: - with open(filepath, "r", encoding='utf8') as name_file: + with open(filepath, "r", encoding="utf8") as name_file: name = name_file.readline().strip() except (OSError, IOError) as msg: LOG.error(str(msg)) @@ -786,7 +847,7 @@ def _get_table_func(self, table=None, func=None): if table is None: return list(self.__tables.keys()) elif func is None: - return self.__tables[table] # dict of functions + return self.__tables[table] # dict of functions elif func in self.__tables[table].keys(): return self.__tables[table][func] else: @@ -850,14 +911,14 @@ def _validated_id_prefix(val, default): if isinstance(val, str) and val: try: str_ = val % 1 - except TypeError: # missing conversion specifier + except TypeError: # missing conversion specifier prefix_var = val + "%d" - except ValueError: # incomplete format - prefix_var = default+"%04d" + except ValueError: # incomplete format + prefix_var = default + "%04d" else: - prefix_var = val # OK as given + prefix_var = val # OK as given else: - prefix_var = default+"%04d" # not a string or empty string + prefix_var = default + "%04d" # not a string or empty string return prefix_var @staticmethod @@ -869,13 +930,14 @@ def __id2user_format(id_pattern): pattern_match = re.match(r"(.*)%[0 ](\d+)[diu]$", id_pattern) if pattern_match: str_prefix = pattern_match.group(1) - #nr_width = int(pattern_match.group(2)) + + # nr_width = int(pattern_match.group(2)) def closure_func(gramps_id): if gramps_id and gramps_id.startswith(str_prefix): - id_number = gramps_id[len(str_prefix):] + id_number = gramps_id[len(str_prefix) :] if id_number.isdigit(): id_value = int(id_number, 10) - #if len(str(id_value)) > nr_width: + # if len(str(id_value)) > nr_width: # # The ID to be imported is too large to fit in the # # users format. For now just create a new ID, # # because that is also what happens with IDs that @@ -884,12 +946,15 @@ def closure_func(gramps_id): # # present IDs is solved the code here also needs # # some solution. # gramps_id = id_pattern % 1 - #else: + # else: gramps_id = id_pattern % id_value return gramps_id + else: + def closure_func(gramps_id): return gramps_id + return closure_func def set_person_id_prefix(self, val): @@ -990,8 +1055,9 @@ def set_note_id_prefix(self, val): self.note_prefix = self._validated_id_prefix(val, "N") self.nid2user_format = self.__id2user_format(self.note_prefix) - def set_prefixes(self, person, media, family, source, citation, - place, event, repository, note): + def set_prefixes( + self, person, media, family, source, citation, place, event, repository, note + ): self.set_person_id_prefix(person) self.set_media_id_prefix(media) self.set_family_id_prefix(family) @@ -1024,9 +1090,9 @@ def find_next_person_gramps_id(self): Return the next available GRAMPS' ID for a Person object based off the person ID prefix. """ - self.pmap_index, gid = self._find_next_gramps_id(self.person_prefix, - self.pmap_index, - PERSON_KEY) + self.pmap_index, gid = self._find_next_gramps_id( + self.person_prefix, self.pmap_index, PERSON_KEY + ) return gid def find_next_place_gramps_id(self): @@ -1034,9 +1100,9 @@ def find_next_place_gramps_id(self): Return the next available GRAMPS' ID for a Place object based off the place ID prefix. """ - self.lmap_index, gid = self._find_next_gramps_id(self.place_prefix, - self.lmap_index, - PLACE_KEY) + self.lmap_index, gid = self._find_next_gramps_id( + self.place_prefix, self.lmap_index, PLACE_KEY + ) return gid def find_next_event_gramps_id(self): @@ -1044,9 +1110,9 @@ def find_next_event_gramps_id(self): Return the next available GRAMPS' ID for a Event object based off the event ID prefix. """ - self.emap_index, gid = self._find_next_gramps_id(self.event_prefix, - self.emap_index, - EVENT_KEY) + self.emap_index, gid = self._find_next_gramps_id( + self.event_prefix, self.emap_index, EVENT_KEY + ) return gid def find_next_media_gramps_id(self): @@ -1054,9 +1120,9 @@ def find_next_media_gramps_id(self): Return the next available GRAMPS' ID for a Media object based off the media object ID prefix. """ - self.omap_index, gid = self._find_next_gramps_id(self.media_prefix, - self.omap_index, - MEDIA_KEY) + self.omap_index, gid = self._find_next_gramps_id( + self.media_prefix, self.omap_index, MEDIA_KEY + ) return gid def find_next_citation_gramps_id(self): @@ -1064,9 +1130,9 @@ def find_next_citation_gramps_id(self): Return the next available GRAMPS' ID for a Citation object based off the citation ID prefix. """ - self.cmap_index, gid = self._find_next_gramps_id(self.citation_prefix, - self.cmap_index, - CITATION_KEY) + self.cmap_index, gid = self._find_next_gramps_id( + self.citation_prefix, self.cmap_index, CITATION_KEY + ) return gid def find_next_source_gramps_id(self): @@ -1074,9 +1140,9 @@ def find_next_source_gramps_id(self): Return the next available GRAMPS' ID for a Source object based off the source ID prefix. """ - self.smap_index, gid = self._find_next_gramps_id(self.source_prefix, - self.smap_index, - SOURCE_KEY) + self.smap_index, gid = self._find_next_gramps_id( + self.source_prefix, self.smap_index, SOURCE_KEY + ) return gid def find_next_family_gramps_id(self): @@ -1084,9 +1150,9 @@ def find_next_family_gramps_id(self): Return the next available GRAMPS' ID for a Family object based off the family ID prefix. """ - self.fmap_index, gid = self._find_next_gramps_id(self.family_prefix, - self.fmap_index, - FAMILY_KEY) + self.fmap_index, gid = self._find_next_gramps_id( + self.family_prefix, self.fmap_index, FAMILY_KEY + ) return gid def find_next_repository_gramps_id(self): @@ -1094,9 +1160,9 @@ def find_next_repository_gramps_id(self): Return the next available GRAMPS' ID for a Respository object based off the repository ID prefix. """ - self.rmap_index, gid = self._find_next_gramps_id(self.repository_prefix, - self.rmap_index, - REPOSITORY_KEY) + self.rmap_index, gid = self._find_next_gramps_id( + self.repository_prefix, self.rmap_index, REPOSITORY_KEY + ) return gid def find_next_note_gramps_id(self): @@ -1104,9 +1170,9 @@ def find_next_note_gramps_id(self): Return the next available GRAMPS' ID for a Note object based off the note ID prefix. """ - self.nmap_index, gid = self._find_next_gramps_id(self.note_prefix, - self.nmap_index, - NOTE_KEY) + self.nmap_index, gid = self._find_next_gramps_id( + self.note_prefix, self.nmap_index, NOTE_KEY + ) return gid ################################################################ @@ -1265,14 +1331,14 @@ def get_note_gramps_ids(self): def _get_from_handle(self, obj_key, obj_class, handle): if handle is None: - raise HandleError('Handle is None') + raise HandleError("Handle is None") if not handle: - raise HandleError('Handle is empty') + raise HandleError("Handle is empty") data = self._get_raw_data(obj_key, handle) if data: return obj_class.create(data) else: - raise HandleError('Handle %s not found' % handle) + raise HandleError("Handle %s not found" % handle) def get_event_from_handle(self, handle): return self._get_from_handle(EVENT_KEY, Event, handle) @@ -1741,56 +1807,64 @@ def _add_base(self, obj, trans, set_gid, find_func, commit_func): obj.handle = create_id() if (not obj.gramps_id) and set_gid: obj.gramps_id = find_func() - if (not obj.gramps_id): + if not obj.gramps_id: # give it a random value for the moment: obj.gramps_id = str(random.random()) commit_func(obj, trans) return obj.handle def add_person(self, person, trans, set_gid=True): - return self._add_base(person, trans, set_gid, - self.find_next_person_gramps_id, - self.commit_person) + return self._add_base( + person, trans, set_gid, self.find_next_person_gramps_id, self.commit_person + ) def add_family(self, family, trans, set_gid=True): - return self._add_base(family, trans, set_gid, - self.find_next_family_gramps_id, - self.commit_family) + return self._add_base( + family, trans, set_gid, self.find_next_family_gramps_id, self.commit_family + ) def add_event(self, event, trans, set_gid=True): - return self._add_base(event, trans, set_gid, - self.find_next_event_gramps_id, - self.commit_event) + return self._add_base( + event, trans, set_gid, self.find_next_event_gramps_id, self.commit_event + ) def add_place(self, place, trans, set_gid=True): - return self._add_base(place, trans, set_gid, - self.find_next_place_gramps_id, - self.commit_place) + return self._add_base( + place, trans, set_gid, self.find_next_place_gramps_id, self.commit_place + ) def add_repository(self, repository, trans, set_gid=True): - return self._add_base(repository, trans, set_gid, - self.find_next_repository_gramps_id, - self.commit_repository) + return self._add_base( + repository, + trans, + set_gid, + self.find_next_repository_gramps_id, + self.commit_repository, + ) def add_source(self, source, trans, set_gid=True): - return self._add_base(source, trans, set_gid, - self.find_next_source_gramps_id, - self.commit_source) + return self._add_base( + source, trans, set_gid, self.find_next_source_gramps_id, self.commit_source + ) def add_citation(self, citation, trans, set_gid=True): - return self._add_base(citation, trans, set_gid, - self.find_next_citation_gramps_id, - self.commit_citation) + return self._add_base( + citation, + trans, + set_gid, + self.find_next_citation_gramps_id, + self.commit_citation, + ) def add_media(self, media, trans, set_gid=True): - return self._add_base(media, trans, set_gid, - self.find_next_media_gramps_id, - self.commit_media) + return self._add_base( + media, trans, set_gid, self.find_next_media_gramps_id, self.commit_media + ) def add_note(self, note, trans, set_gid=True): - return self._add_base(note, trans, set_gid, - self.find_next_note_gramps_id, - self.commit_note) + return self._add_base( + note, trans, set_gid, self.find_next_note_gramps_id, self.commit_note + ) def add_tag(self, tag, trans): if not tag.handle: @@ -1821,15 +1895,15 @@ def commit_person(self, person, trans, change_time=None): if old_data: old_person = Person(old_data) # Update gender statistics if necessary - if (old_person.gender != person.gender - or (old_person.primary_name.first_name != - person.primary_name.first_name)): - + if old_person.gender != person.gender or ( + old_person.primary_name.first_name != person.primary_name.first_name + ): self.genderStats.uncount_person(old_person) self.genderStats.count_person(person) # Update surname list if necessary - if (self._order_by_person_key(person) != - self._order_by_person_key(old_person)): + if self._order_by_person_key(person) != self._order_by_person_key( + old_person + ): self.remove_from_surname_list(old_person) self.add_to_surname_list(person, trans.batch) else: @@ -1838,30 +1912,42 @@ def commit_person(self, person, trans, change_time=None): # Other misc update tasks: self.individual_attributes.update( - [str(attr.type) for attr in person.attribute_list - if attr.type.is_custom() and str(attr.type)]) + [ + str(attr.type) + for attr in person.attribute_list + if attr.type.is_custom() and str(attr.type) + ] + ) - self.event_role_names.update([str(eref.role) - for eref in person.event_ref_list - if eref.role.is_custom()]) - - self.name_types.update([str(name.type) - for name in ([person.primary_name] - + person.alternate_names) - if name.type.is_custom()]) + self.event_role_names.update( + [str(eref.role) for eref in person.event_ref_list if eref.role.is_custom()] + ) + + self.name_types.update( + [ + str(name.type) + for name in ([person.primary_name] + person.alternate_names) + if name.type.is_custom() + ] + ) all_surn = [] # new list we will use for storage all_surn += person.primary_name.get_surname_list() for asurname in person.alternate_names: all_surn += asurname.get_surname_list() - self.origin_types.update([str(surn.origintype) for surn in all_surn - if surn.origintype.is_custom()]) + self.origin_types.update( + [str(surn.origintype) for surn in all_surn if surn.origintype.is_custom()] + ) all_surn = None - self.url_types.update([str(url.type) for url in person.urls - if url.type.is_custom()]) + self.url_types.update( + [str(url.type) for url in person.urls if url.type.is_custom()] + ) attr_list = [] for mref in person.media_list: - attr_list += [str(attr.type) for attr in mref.attribute_list - if attr.type.is_custom() and str(attr.type)] + attr_list += [ + str(attr.type) + for attr in mref.attribute_list + if attr.type.is_custom() and str(attr.type) + ] self.media_attributes.update(attr_list) def commit_family(self, family, trans, change_time=None): @@ -1873,8 +1959,12 @@ def commit_family(self, family, trans, change_time=None): # Misc updates: self.family_attributes.update( - [str(attr.type) for attr in family.attribute_list - if attr.type.is_custom() and str(attr.type)]) + [ + str(attr.type) + for attr in family.attribute_list + if attr.type.is_custom() and str(attr.type) + ] + ) rel_list = [] for ref in family.child_ref_list: @@ -1885,16 +1975,19 @@ def commit_family(self, family, trans, change_time=None): self.child_ref_types.update(rel_list) self.event_role_names.update( - [str(eref.role) for eref in family.event_ref_list - if eref.role.is_custom()]) + [str(eref.role) for eref in family.event_ref_list if eref.role.is_custom()] + ) if family.type.is_custom(): self.family_rel_types.add(str(family.type)) attr_list = [] for mref in family.media_list: - attr_list += [str(attr.type) for attr in mref.attribute_list - if attr.type.is_custom() and str(attr.type)] + attr_list += [ + str(attr.type) + for attr in mref.attribute_list + if attr.type.is_custom() and str(attr.type) + ] self.media_attributes.update(attr_list) def commit_citation(self, citation, trans, change_time=None): @@ -1907,13 +2000,20 @@ def commit_citation(self, citation, trans, change_time=None): # Misc updates: attr_list = [] for mref in citation.media_list: - attr_list += [str(attr.type) for attr in mref.attribute_list - if attr.type.is_custom() and str(attr.type)] + attr_list += [ + str(attr.type) + for attr in mref.attribute_list + if attr.type.is_custom() and str(attr.type) + ] self.media_attributes.update(attr_list) self.source_attributes.update( - [str(attr.type) for attr in citation.attribute_list - if attr.type.is_custom() and str(attr.type)]) + [ + str(attr.type) + for attr in citation.attribute_list + if attr.type.is_custom() and str(attr.type) + ] + ) def commit_source(self, source, trans, change_time=None): """ @@ -1924,17 +2024,28 @@ def commit_source(self, source, trans, change_time=None): # Misc updates: self.source_media_types.update( - [str(ref.media_type) for ref in source.reporef_list - if ref.media_type.is_custom()]) + [ + str(ref.media_type) + for ref in source.reporef_list + if ref.media_type.is_custom() + ] + ) attr_list = [] for mref in source.media_list: - attr_list += [str(attr.type) for attr in mref.attribute_list - if attr.type.is_custom() and str(attr.type)] + attr_list += [ + str(attr.type) + for attr in mref.attribute_list + if attr.type.is_custom() and str(attr.type) + ] self.media_attributes.update(attr_list) self.source_attributes.update( - [str(attr.type) for attr in source.attribute_list - if attr.type.is_custom() and str(attr.type)]) + [ + str(attr.type) + for attr in source.attribute_list + if attr.type.is_custom() and str(attr.type) + ] + ) def commit_repository(self, repository, trans, change_time=None): """ @@ -1947,8 +2058,9 @@ def commit_repository(self, repository, trans, change_time=None): if repository.type.is_custom(): self.repository_types.add(str(repository.type)) - self.url_types.update([str(url.type) for url in repository.urls - if url.type.is_custom()]) + self.url_types.update( + [str(url.type) for url in repository.urls if url.type.is_custom()] + ) def commit_note(self, note, trans, change_time=None): """ @@ -1972,13 +2084,17 @@ def commit_place(self, place, trans, change_time=None): if place.get_type().is_custom(): self.place_types.add(str(place.get_type())) - self.url_types.update([str(url.type) for url in place.urls - if url.type.is_custom()]) + self.url_types.update( + [str(url.type) for url in place.urls if url.type.is_custom()] + ) attr_list = [] for mref in place.media_list: - attr_list += [str(attr.type) for attr in mref.attribute_list - if attr.type.is_custom() and str(attr.type)] + attr_list += [ + str(attr.type) + for attr in mref.attribute_list + if attr.type.is_custom() and str(attr.type) + ] self.media_attributes.update(attr_list) def commit_event(self, event, trans, change_time=None): @@ -1990,14 +2106,21 @@ def commit_event(self, event, trans, change_time=None): # Misc updates: self.event_attributes.update( - [str(attr.type) for attr in event.attribute_list - if attr.type.is_custom() and str(attr.type)]) + [ + str(attr.type) + for attr in event.attribute_list + if attr.type.is_custom() and str(attr.type) + ] + ) if event.type.is_custom(): self.event_names.add(str(event.type)) attr_list = [] for mref in event.media_list: - attr_list += [str(attr.type) for attr in mref.attribute_list - if attr.type.is_custom() and str(attr.type)] + attr_list += [ + str(attr.type) + for attr in mref.attribute_list + if attr.type.is_custom() and str(attr.type) + ] self.media_attributes.update(attr_list) def commit_tag(self, tag, trans, change_time=None): @@ -2016,8 +2139,12 @@ def commit_media(self, media, trans, change_time=None): # Misc updates: self.media_attributes.update( - [str(attr.type) for attr in media.attribute_list - if attr.type.is_custom() and str(attr.type)]) + [ + str(attr.type) + for attr in media.attribute_list + if attr.type.is_custom() and str(attr.type) + ] + ) def _after_commit(self, transaction): """ @@ -2292,7 +2419,7 @@ def get_default_person(self): def set_default_person_handle(self, handle): self._set_metadata("default-person-handle", handle) - self.emit('home-person-changed') + self.emit("home-person-changed") def get_mediapath(self): return self._get_metadata("media-path", None) @@ -2322,7 +2449,7 @@ def add_to_surname_list(self, person, batch_transaction): return i = bisect.bisect(self.surname_list, name) if 0 < i <= len(self.surname_list): - if self.surname_list[i-1] != name: + if self.surname_list[i - 1] != name: self.surname_list.insert(i, name) else: self.surname_list.insert(i, name) @@ -2363,16 +2490,16 @@ def set_researcher(self, owner): self.owner.set_from(owner) def request_rebuild(self): - self.emit('person-rebuild') - self.emit('family-rebuild') - self.emit('place-rebuild') - self.emit('source-rebuild') - self.emit('citation-rebuild') - self.emit('media-rebuild') - self.emit('event-rebuild') - self.emit('repository-rebuild') - self.emit('note-rebuild') - self.emit('tag-rebuild') + self.emit("person-rebuild") + self.emit("family-rebuild") + self.emit("place-rebuild") + self.emit("source-rebuild") + self.emit("citation-rebuild") + self.emit("media-rebuild") + self.emit("event-rebuild") + self.emit("repository-rebuild") + self.emit("note-rebuild") + self.emit("tag-rebuild") def get_save_path(self): return self._directory @@ -2440,12 +2567,14 @@ def _order_by_person_key(self, person): """ order_by = "" if person.primary_name: - order_by_list = [surname.surname + " " + - person.primary_name.first_name - for surname in person.primary_name.surname_list - if (int(surname.origintype) not in - [NameOriginType.PATRONYMIC, - NameOriginType.MATRONYMIC])] + order_by_list = [ + surname.surname + " " + person.primary_name.first_name + for surname in person.primary_name.surname_list + if ( + int(surname.origintype) + not in [NameOriginType.PATRONYMIC, NameOriginType.MATRONYMIC] + ) + ] order_by = " ".join(order_by_list) return glocale.sort_key(order_by) @@ -2486,9 +2615,14 @@ def _gramps_upgrade(self, version, directory, callback=None): start = time.time() from gramps.gen.db.upgrade import ( - gramps_upgrade_14, gramps_upgrade_15, gramps_upgrade_16, - gramps_upgrade_17, gramps_upgrade_18, gramps_upgrade_19, - gramps_upgrade_20) + gramps_upgrade_14, + gramps_upgrade_15, + gramps_upgrade_16, + gramps_upgrade_17, + gramps_upgrade_18, + gramps_upgrade_19, + gramps_upgrade_20, + ) if version < 14: gramps_upgrade_14(self) @@ -2513,9 +2647,9 @@ def _gramps_upgrade(self, version, directory, callback=None): LOG.debug("Upgrade time: %d seconds" % int(time.time() - start)) def get_schema_version(self): - """ Return current schema version as an int """ - return int(self._get_metadata('version', default='0')) + """Return current schema version as an int""" + return int(self._get_metadata("version", default="0")) def set_schema_version(self, value): - """ set the current schema version """ - self._set_metadata('version', str(value)) + """set the current schema version""" + self._set_metadata("version", str(value)) diff --git a/gramps/gen/db/txn.py b/gramps/gen/db/txn.py index e467a2100f7..333fa316981 100644 --- a/gramps/gen/db/txn.py +++ b/gramps/gen/db/txn.py @@ -23,11 +23,11 @@ database. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import pickle import logging from collections import defaultdict @@ -35,28 +35,36 @@ import inspect import os -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .dbconst import DBLOGNAME _LOG = logging.getLogger(DBLOGNAME) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps transaction class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class DbTxn(defaultdict): """ Define a group of database commits that define a single logical operation. """ - __slots__ = ('msg', 'commitdb', 'db', 'batch', 'first', - 'last', 'timestamp', '__dict__') + __slots__ = ( + "msg", + "commitdb", + "db", + "batch", + "first", + "last", + "timestamp", + "__dict__", + ) def __enter__(self): """ @@ -81,10 +89,15 @@ def __exit__(self, exc_type, exc_val, exc_tb): frame = inspect.currentframe() c_frame = frame.f_back c_code = c_frame.f_code - _LOG.debug(" **** DbTxn %s exited. Called from file %s, " - "line %s, in %s **** %.2f seconds", - hex(id(self)), c_code.co_filename, c_frame.f_lineno, - c_code.co_name, elapsed_time) + _LOG.debug( + " **** DbTxn %s exited. Called from file %s, " + "line %s, in %s **** %.2f seconds", + hex(id(self)), + c_code.co_filename, + c_frame.f_lineno, + c_code.co_name, + elapsed_time, + ) return False @@ -129,18 +142,22 @@ def __init__(self, msg, grampsdb, batch=False, **kwargs): # frame to get any real information. The test does not accurately # check this, but seems to be good enough for the current diagnostic # purposes. - if os.path.split(caller_frame[1])[1] == "generic.py" and \ - caller_frame[3] == "__init__": + if ( + os.path.split(caller_frame[1])[1] == "generic.py" + and caller_frame[3] == "__init__" + ): caller_frame = inspect.stack()[2] - _LOG.debug("%sDbTxn %s instantiated for '%s'. Called from file %s, " - "line %s, in %s" % - (("Batch " if batch else "",)+ - (hex(id(self)),)+ - (msg,)+ - (os.path.split(caller_frame[1])[1],)+ - (tuple(caller_frame[i] for i in range(2, 4))) - ) - ) + _LOG.debug( + "%sDbTxn %s instantiated for '%s'. Called from file %s, " + "line %s, in %s" + % ( + ("Batch " if batch else "",) + + (hex(id(self)),) + + (msg,) + + (os.path.split(caller_frame[1])[1],) + + (tuple(caller_frame[i] for i in range(2, 4))) + ) + ) defaultdict.__init__(self, list, {}) self.msg = msg @@ -176,12 +193,13 @@ def add(self, obj_type, trans_type, handle, old_data, new_data): data is the tuple returned by the object's serialize method. """ self.last = self.commitdb.append( - pickle.dumps((obj_type, trans_type, handle, old_data, new_data), 1)) + pickle.dumps((obj_type, trans_type, handle, old_data, new_data), 1) + ) if self.last is None: - self.last = len(self.commitdb) -1 + self.last = len(self.commitdb) - 1 if self.first is None: self.first = self.last - _LOG.debug('added to trans: %d %d %s' % (obj_type, trans_type, handle)) + _LOG.debug("added to trans: %d %d %s" % (obj_type, trans_type, handle)) self[(obj_type, trans_type)] += [(handle, new_data)] return @@ -196,9 +214,9 @@ def get_recnos(self, reverse=False): if self.first is None or self.last is None: return [] if not reverse: - return range(self.first, self.last+1) + return range(self.first, self.last + 1) else: - return range(self.last, self.first-1, -1) + return range(self.last, self.first - 1, -1) def get_record(self, recno): """ diff --git a/gramps/gen/db/undoredo.py b/gramps/gen/db/undoredo.py index 51fa9dc2d38..25cd2d68b5a 100644 --- a/gramps/gen/db/undoredo.py +++ b/gramps/gen/db/undoredo.py @@ -17,22 +17,23 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from abc import ABCMeta, abstractmethod import time from collections import deque + class DbUndo(metaclass=ABCMeta): """ Base class for the Gramps undo/redo manager. Needs to be subclassed for use with a real backend. """ - __slots__ = ('undodb', 'db', 'undo_history_timestamp', 'undoq', 'redoq') + __slots__ = ("undodb", "db", "undo_history_timestamp", "undoq", "redoq") def __init__(self, db): """ @@ -109,13 +110,11 @@ def __len__(self): @abstractmethod def _redo(self, update_history): - """ - """ + """ """ @abstractmethod def _undo(self, update_history): - """ - """ + """ """ def commit(self, txn, msg): """ @@ -149,5 +148,5 @@ def redo(self, update_history=True): return False return self._redo(update_history) - undo_count = property(lambda self:len(self.undoq)) - redo_count = property(lambda self:len(self.redoq)) + undo_count = property(lambda self: len(self.undoq)) + redo_count = property(lambda self: len(self.redoq)) diff --git a/gramps/gen/db/upgrade.py b/gramps/gen/db/upgrade.py index 36f2de5a532..7a8c56fdc1b 100644 --- a/gramps/gen/db/upgrade.py +++ b/gramps/gen/db/upgrade.py @@ -19,29 +19,40 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # """ Generic upgrade module for dbapi dbs """ -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Python Modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ import os import re import time import logging -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # Gramps Modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ from gramps.cli.clidbman import NAME_FILE from gramps.gen.lib import EventType, NameOriginType, Tag, MarkerType from gramps.gen.utils.file import create_checksum from gramps.gen.utils.id import create_id -from gramps.gui.dialog import (InfoDialog) -from .dbconst import (PERSON_KEY, FAMILY_KEY, EVENT_KEY, MEDIA_KEY, PLACE_KEY, - REPOSITORY_KEY, CITATION_KEY, SOURCE_KEY, NOTE_KEY, - TAG_KEY) +from gramps.gui.dialog import InfoDialog +from .dbconst import ( + PERSON_KEY, + FAMILY_KEY, + EVENT_KEY, + MEDIA_KEY, + PLACE_KEY, + REPOSITORY_KEY, + CITATION_KEY, + SOURCE_KEY, + NOTE_KEY, + TAG_KEY, +) from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext LOG = logging.getLogger(".upgrade") @@ -57,51 +68,111 @@ def gramps_upgrade_20(self): # uid and place upgrade code goes here - #---------------------------------------- + # ---------------------------------------- # Modify Person - #---------------------------------------- + # ---------------------------------------- # Add citation_list to person eventref objects for person_handle in self.get_person_handles(): person = self.get_raw_person_data(person_handle) - (handle, gramps_id, gender, primary_name, alternate_names, - death_ref_index, birth_ref_index, event_ref_list, family_list, - parent_family_list, media_list, address_list, attribute_list, - urls, lds_seal_list, citation_list, note_list, change, tag_list, - private, person_ref_list) = person + ( + handle, + gramps_id, + gender, + primary_name, + alternate_names, + death_ref_index, + birth_ref_index, + event_ref_list, + family_list, + parent_family_list, + media_list, + address_list, + attribute_list, + urls, + lds_seal_list, + citation_list, + note_list, + change, + tag_list, + private, + person_ref_list, + ) = person if event_ref_list: event_ref_list = upgrade_event_ref_list_20(event_ref_list) - new_person = (handle, gramps_id, gender, primary_name, - alternate_names, death_ref_index, - birth_ref_index, event_ref_list, family_list, - parent_family_list, media_list, address_list, - attribute_list, urls, lds_seal_list, - citation_list, note_list, change, tag_list, - private, person_ref_list) + new_person = ( + handle, + gramps_id, + gender, + primary_name, + alternate_names, + death_ref_index, + birth_ref_index, + event_ref_list, + family_list, + parent_family_list, + media_list, + address_list, + attribute_list, + urls, + lds_seal_list, + citation_list, + note_list, + change, + tag_list, + private, + person_ref_list, + ) self._commit_raw(new_person, PERSON_KEY) self.update() - #---------------------------------------- + # ---------------------------------------- # Modify Family - #---------------------------------------- + # ---------------------------------------- # Add citation_list to family eventref objects for family_handle in self.get_family_handles(): family = self.get_raw_family_data(family_handle) - (handle, gramps_id, father_handle, mother_handle, - child_ref_list, the_type, event_ref_list, media_list, - attribute_list, lds_seal_list, citation_list, note_list, - change, marker, private) = family + ( + handle, + gramps_id, + father_handle, + mother_handle, + child_ref_list, + the_type, + event_ref_list, + media_list, + attribute_list, + lds_seal_list, + citation_list, + note_list, + change, + marker, + private, + ) = family if event_ref_list: event_ref_list = upgrade_event_ref_list_20(event_ref_list) - new_family = (handle, gramps_id, father_handle, mother_handle, - child_ref_list, the_type, event_ref_list, - media_list, attribute_list, lds_seal_list, - citation_list, note_list, change, marker, private) + new_family = ( + handle, + gramps_id, + father_handle, + mother_handle, + child_ref_list, + the_type, + event_ref_list, + media_list, + attribute_list, + lds_seal_list, + citation_list, + note_list, + change, + marker, + private, + ) self._commit_raw(new_family, FAMILY_KEY) self.update() self._txn_commit() # Bump up database version. Separate transaction to save metadata. - self._set_metadata('version', 20) + self._set_metadata("version", 20) def upgrade_event_ref_list_20(event_ref_list): @@ -121,7 +192,7 @@ def gramps_upgrade_19(self): Upgrade database from version 18 to 19. """ # This is done in the conversion from bsddb, so just say we did it. - self._set_metadata('version', 19) + self._set_metadata("version", 19) def gramps_upgrade_18(self): @@ -139,10 +210,10 @@ def gramps_upgrade_18(self): for handle in self.get_place_handles(): place = self.get_raw_place_data(handle) new_place = list(place) - new_place[6] = (new_place[6], None, '') + new_place[6] = (new_place[6], None, "") alt_names = [] for name in new_place[7]: - alt_names.append((name, None, '')) + alt_names.append((name, None, "")) new_place[7] = alt_names new_place = tuple(new_place) self._commit_raw(new_place, PLACE_KEY) @@ -150,7 +221,7 @@ def gramps_upgrade_18(self): self._txn_commit() # Bump up database version. Separate transaction to save metadata. - self._set_metadata('version', 18) + self._set_metadata("version", 18) def gramps_upgrade_17(self): @@ -164,9 +235,14 @@ def gramps_upgrade_17(self): 4. Add checksum field to media objects. 5. Rebuild list of custom events. """ - length = (self.get_number_of_events() + self.get_number_of_places() + - self.get_number_of_citations() + self.get_number_of_sources() + - self.get_number_of_repositories() + self.get_number_of_media()) + length = ( + self.get_number_of_events() + + self.get_number_of_places() + + self.get_number_of_citations() + + self.get_number_of_sources() + + self.get_number_of_repositories() + + self.get_number_of_media() + ) self.set_total(length) self._txn_begin() @@ -193,7 +269,7 @@ def gramps_upgrade_17(self): # Convert to hierarchical structure and add new tag_list field. locations = {} self.max_id = 0 - index = re.compile('[0-9]+') + index = re.compile("[0-9]+") for handle in self.get_place_handles(): place = self.get_raw_place_data(handle) match = index.search(place[1]) @@ -207,7 +283,7 @@ def gramps_upgrade_17(self): place = self.get_raw_place_data(handle) new_place = list(place) - zip_code = '' + zip_code = "" if new_place[5]: zip_code = new_place[5][0][6] @@ -218,13 +294,13 @@ def gramps_upgrade_17(self): break loc = list(main_loc[:]) - loc[level] = '' + loc[level] = "" # find top parent parent_handle = None for n in range(7): if loc[n]: - tup = tuple([''] * n + loc[n:]) + tup = tuple([""] * n + loc[n:]) parent_handle = locations.get(tup, None) if parent_handle: break @@ -235,14 +311,13 @@ def gramps_upgrade_17(self): while n > level: if loc[n]: # TODO for Arabic, should the next line's comma be translated? - title = ', '.join([item for item in loc[n:] if item]) - parent_handle = add_place( - self, loc[n], n, parent_handle, title) - locations[tuple([''] * n + loc[n:])] = parent_handle + title = ", ".join([item for item in loc[n:] if item]) + parent_handle = add_place(self, loc[n], n, parent_handle, title) + locations[tuple([""] * n + loc[n:])] = parent_handle n -= 1 if parent_handle is not None: - placeref_list = [(parent_handle.decode('utf-8'), None)] + placeref_list = [(parent_handle.decode("utf-8"), None)] else: placeref_list = [] @@ -251,9 +326,13 @@ def gramps_upgrade_17(self): else: name = new_place[2] type_num = -1 - new_place = (new_place[:5] + [ - placeref_list, name, [], (type_num, ''), zip_code] + - new_place[6:12] + [[]] + new_place[12:]) + new_place = ( + new_place[:5] + + [placeref_list, name, [], (type_num, ""), zip_code] + + new_place[6:12] + + [[]] + + new_place[12:] + ) new_place = tuple(new_place) self._commit_raw(new_place, PLACE_KEY) self.update() @@ -299,24 +378,71 @@ def gramps_upgrade_17(self): # ------------------------------------------------------- for handle in self.get_source_handles(): source = self.get_raw_source_data(handle) - (handle, gramps_id, title, author, pubinfo, - notelist, medialist, abbrev, change, datamap, reporef_list, - taglist, private) = source + ( + handle, + gramps_id, + title, + author, + pubinfo, + notelist, + medialist, + abbrev, + change, + datamap, + reporef_list, + taglist, + private, + ) = source srcattributelist = upgrade_datamap_17(datamap) - new_source = (handle, gramps_id, title, author, pubinfo, - notelist, medialist, abbrev, change, srcattributelist, - reporef_list, taglist, private) + new_source = ( + handle, + gramps_id, + title, + author, + pubinfo, + notelist, + medialist, + abbrev, + change, + srcattributelist, + reporef_list, + taglist, + private, + ) self._commit_raw(new_source, SOURCE_KEY) self.update() for handle in self.get_citation_handles(): citation = self.get_raw_citation_data(handle) - (handle, gramps_id, datelist, page, confidence, source_handle, - notelist, medialist, datamap, change, taglist, private) = citation + ( + handle, + gramps_id, + datelist, + page, + confidence, + source_handle, + notelist, + medialist, + datamap, + change, + taglist, + private, + ) = citation srcattributelist = upgrade_datamap_17(datamap) - new_citation = (handle, gramps_id, datelist, page, confidence, - source_handle, notelist, medialist, srcattributelist, - change, taglist, private) + new_citation = ( + handle, + gramps_id, + datelist, + page, + confidence, + source_handle, + notelist, + medialist, + srcattributelist, + change, + taglist, + private, + ) self._commit_raw(new_citation, CITATION_KEY) self.update() @@ -324,10 +450,10 @@ def gramps_upgrade_17(self): # Modify Media # --------------------------------- # Add new checksum field. - base_path = self._get_metadata('media-path') + base_path = self._get_metadata("media-path") if not base_path: # Check that the mediapath is not set to None (bug #7844). - base_path = '' + base_path = "" for handle in self.get_media_handles(): media = self.get_raw_media_data(handle) new_media = list(media) @@ -343,13 +469,13 @@ def gramps_upgrade_17(self): self._txn_commit() # Bump up database version. Separate transaction to save metadata. - self._set_metadata('version', 17) + self._set_metadata("version", 17) def get_location(loc): # (street, locality, parish, city, county, state, country) if loc is None: - location = ('',) * 7 + location = ("",) * 7 else: location = loc[0][:2] + (loc[1],) + loc[0][2:6] return location @@ -359,13 +485,31 @@ def add_place(self, name, level, parent, title): handle = create_id() self.max_id += 1 gid = self.place_prefix % self.max_id - placetype = (7 - level, '') + placetype = (7 - level, "") if parent is not None: - placeref_list = [(parent.decode('utf-8'), None)] + placeref_list = [(parent.decode("utf-8"), None)] else: placeref_list = [] - place = (handle, gid, title, '', '', placeref_list, name, [], placetype, - '', [], [], [], [], [], 0, [], False) + place = ( + handle, + gid, + title, + "", + "", + placeref_list, + name, + [], + placetype, + "", + [], + [], + [], + [], + [], + 0, + [], + False, + ) self._commit_raw(place, PLACE_KEY) return handle @@ -378,7 +522,8 @@ def upgrade_datamap_17(datamap): new_srcattr_list = [] private = False from gramps.gen.lib.srcattrtype import SrcAttributeType - for (key, value) in datamap.items(): + + for key, value in datamap.items(): the_type = SrcAttributeType(key).serialize() new_srcattr_list.append((private, the_type, value)) return new_srcattr_list @@ -403,40 +548,66 @@ def gramps_upgrade_16(self): # Only People, Families, Events, Media Objects, Places, Sources and # Repositories need to be updated, because these are the only primary # objects that can have source citations. - length = (self.get_number_of_people() + - self.get_number_of_events() + self.get_number_of_families() + - self.get_number_of_repositories() + self.get_number_of_media() + - self.get_number_of_places() + self.get_number_of_sources()) + length = ( + self.get_number_of_people() + + self.get_number_of_events() + + self.get_number_of_families() + + self.get_number_of_repositories() + + self.get_number_of_media() + + self.get_number_of_places() + + self.get_number_of_sources() + ) self.set_total(length) self._txn_begin() # Setup data for upgrade statistics information dialogue - keyorder = [PERSON_KEY, FAMILY_KEY, EVENT_KEY, MEDIA_KEY, - PLACE_KEY, REPOSITORY_KEY, SOURCE_KEY] + keyorder = [ + PERSON_KEY, + FAMILY_KEY, + EVENT_KEY, + MEDIA_KEY, + PLACE_KEY, + REPOSITORY_KEY, + SOURCE_KEY, + ] key2data = { - PERSON_KEY : 0, - FAMILY_KEY : 1, + PERSON_KEY: 0, + FAMILY_KEY: 1, EVENT_KEY: 2, MEDIA_KEY: 3, PLACE_KEY: 4, REPOSITORY_KEY: 5, - SOURCE_KEY : 6, + SOURCE_KEY: 6, } key2string = { - PERSON_KEY : _('%(n1)6d People upgraded with ' - '%(n2)6d citations in %(n3)6d secs\n'), - FAMILY_KEY : _('%(n1)6d Families upgraded with ' - '%(n2)6d citations in %(n3)6d secs\n'), - EVENT_KEY : _('%(n1)6d Events upgraded with ' - '%(n2)6d citations in %(n3)6d secs\n'), - MEDIA_KEY : _('%(n1)6d Media Objects upgraded with ' - '%(n2)6d citations in %(n3)6d secs\n'), - PLACE_KEY : _('%(n1)6d Places upgraded with ' - '%(n2)6d citations in %(n3)6d secs\n'), - REPOSITORY_KEY : _('%(n1)6d Repositories upgraded with ' - '%(n2)6d citations in %(n3)6d secs\n'), - SOURCE_KEY : _('%(n1)6d Sources upgraded with ' - '%(n2)6d citations in %(n3)6d secs\n'), + PERSON_KEY: _( + "%(n1)6d People upgraded with " + "%(n2)6d citations in %(n3)6d secs\n" + ), + FAMILY_KEY: _( + "%(n1)6d Families upgraded with " + "%(n2)6d citations in %(n3)6d secs\n" + ), + EVENT_KEY: _( + "%(n1)6d Events upgraded with " + "%(n2)6d citations in %(n3)6d secs\n" + ), + MEDIA_KEY: _( + "%(n1)6d Media Objects upgraded with " + "%(n2)6d citations in %(n3)6d secs\n" + ), + PLACE_KEY: _( + "%(n1)6d Places upgraded with " + "%(n2)6d citations in %(n3)6d secs\n" + ), + REPOSITORY_KEY: _( + "%(n1)6d Repositories upgraded with " + "%(n2)6d citations in %(n3)6d secs\n" + ), + SOURCE_KEY: _( + "%(n1)6d Sources upgraded with " + "%(n2)6d citations in %(n3)6d secs\n" + ), } data_upgradeobject = [0] * 7 @@ -455,15 +626,35 @@ def gramps_upgrade_16(self): # on or not. Since the retrieval of names is so complex, I think it # is safer to protect this with a try except block, even though it # seems to work for names being present and not. - LOG.debug("upgrade person %s %s" % (person[3][4], - " ".join([name[0] for name in person[3][5]]))) + LOG.debug( + "upgrade person %s %s" + % (person[3][4], " ".join([name[0] for name in person[3][5]])) + ) except: pass - (handle, gramps_id, gender, primary_name, alternate_names, - death_ref_index, birth_ref_index, event_ref_list, family_list, - parent_family_list, media_list, address_list, attribute_list, - urls, lds_seal_list, source_list, note_list, change, tag_list, - private, person_ref_list) = person + ( + handle, + gramps_id, + gender, + primary_name, + alternate_names, + death_ref_index, + birth_ref_index, + event_ref_list, + family_list, + parent_family_list, + media_list, + address_list, + attribute_list, + urls, + lds_seal_list, + source_list, + note_list, + change, + tag_list, + private, + person_ref_list, + ) = person if primary_name: primary_name = upgrade_name_16(self, primary_name) if alternate_names: @@ -478,34 +669,65 @@ def gramps_upgrade_16(self): lds_seal_list = upgrade_lds_seal_list_16(self, lds_seal_list) if source_list: new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) + self, source_list + ) else: new_citation_list = [] if person_ref_list: person_ref_list = upgrade_person_ref_list_16(self, person_ref_list) if event_ref_list: event_ref_list = upgrade_event_ref_list_16(self, event_ref_list) - if(primary_name or alternate_names or address_list or media_list or - attribute_list or lds_seal_list or source_list or - person_ref_list or event_ref_list): - new_person = (handle, gramps_id, gender, primary_name, - alternate_names, death_ref_index, - birth_ref_index, event_ref_list, family_list, - parent_family_list, media_list, address_list, - attribute_list, urls, lds_seal_list, - new_citation_list, note_list, change, tag_list, - private, person_ref_list) + if ( + primary_name + or alternate_names + or address_list + or media_list + or attribute_list + or lds_seal_list + or source_list + or person_ref_list + or event_ref_list + ): + new_person = ( + handle, + gramps_id, + gender, + primary_name, + alternate_names, + death_ref_index, + birth_ref_index, + event_ref_list, + family_list, + parent_family_list, + media_list, + address_list, + attribute_list, + urls, + lds_seal_list, + new_citation_list, + note_list, + change, + tag_list, + private, + person_ref_list, + ) LOG.debug(" upgrade new_person %s" % [new_person]) self._commit_raw(new_person, PERSON_KEY) self.update() - LOG.debug("%d persons upgraded with %d citations in %d seconds. " % - (self.get_number_of_people(), - self.cmap_index - start_num_citations, - time.time() - start_time)) + LOG.debug( + "%d persons upgraded with %d citations in %d seconds. " + % ( + self.get_number_of_people(), + self.cmap_index - start_num_citations, + time.time() - start_time, + ) + ) data_upgradeobject[key2data[PERSON_KEY]] = ( - self.get_number_of_people(), self.cmap_index - start_num_citations, - time.time() - start_time) + self.get_number_of_people(), + self.cmap_index - start_num_citations, + time.time() - start_time, + ) # --------------------------------- # Modify Media @@ -515,27 +737,54 @@ def gramps_upgrade_16(self): for media_handle in self.get_media_handles(): media = self.get_raw_media_data(media_handle) LOG.debug("upgrade media object %s" % media[4]) - (handle, gramps_id, path, mime, desc, - attribute_list, source_list, note_list, change, - date, tag_list, private) = media - new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) + ( + handle, + gramps_id, + path, + mime, + desc, + attribute_list, + source_list, + note_list, + change, + date, + tag_list, + private, + ) = media + new_citation_list = convert_source_list_to_citation_list_16(self, source_list) new_attribute_list = upgrade_attribute_list_16(self, attribute_list) - new_media = (handle, gramps_id, path, mime, desc, - new_attribute_list, new_citation_list, note_list, - change, date, tag_list, private) + new_media = ( + handle, + gramps_id, + path, + mime, + desc, + new_attribute_list, + new_citation_list, + note_list, + change, + date, + tag_list, + private, + ) LOG.debug(" upgrade new_media %s" % [new_media]) self._commit_raw(new_media, MEDIA_KEY) self.update() - LOG.debug("%d media objects upgraded with %d citations in %d seconds" % - (self.get_number_of_media(), - self.cmap_index - start_num_citations, - int(time.time() - start_time))) + LOG.debug( + "%d media objects upgraded with %d citations in %d seconds" + % ( + self.get_number_of_media(), + self.cmap_index - start_num_citations, + int(time.time() - start_time), + ) + ) data_upgradeobject[key2data[MEDIA_KEY]] = ( - self.get_number_of_media(), self.cmap_index - start_num_citations, - time.time() - start_time) + self.get_number_of_media(), + self.cmap_index - start_num_citations, + time.time() - start_time, + ) # --------------------------------- # Modify Places @@ -545,32 +794,62 @@ def gramps_upgrade_16(self): for place_handle in self.get_place_handles(): place = self.get_raw_place_data(place_handle) LOG.debug("upgrade place %s" % place[2]) - (handle, gramps_id, title, longi, lat, - main_loc, alt_loc, urls, media_list, source_list, note_list, - change, private) = place + ( + handle, + gramps_id, + title, + longi, + lat, + main_loc, + alt_loc, + urls, + media_list, + source_list, + note_list, + change, + private, + ) = place if source_list: new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) + self, source_list + ) else: new_citation_list = [] if media_list: media_list = upgrade_media_list_16(self, media_list) if source_list or media_list: - new_place = (handle, gramps_id, title, - longi, lat, main_loc, alt_loc, urls, - media_list, new_citation_list, note_list, - change, private) + new_place = ( + handle, + gramps_id, + title, + longi, + lat, + main_loc, + alt_loc, + urls, + media_list, + new_citation_list, + note_list, + change, + private, + ) LOG.debug(" upgrade new_place %s" % [new_place]) self._commit_raw(new_place, PLACE_KEY) self.update() - LOG.debug("%d places upgraded with %d citations in %d seconds. " % - (self.get_number_of_places(), - self.cmap_index - start_num_citations, - time.time() - start_time)) + LOG.debug( + "%d places upgraded with %d citations in %d seconds. " + % ( + self.get_number_of_places(), + self.cmap_index - start_num_citations, + time.time() - start_time, + ) + ) data_upgradeobject[key2data[PLACE_KEY]] = ( - self.get_number_of_places(), self.cmap_index - start_num_citations, - time.time() - start_time) + self.get_number_of_places(), + self.cmap_index - start_num_citations, + time.time() - start_time, + ) # --------------------------------- # Modify Families @@ -580,13 +859,27 @@ def gramps_upgrade_16(self): for family_handle in self.get_family_handles(): family = self.get_raw_family_data(family_handle) LOG.debug("upgrade family (gramps_id) %s" % family[1]) - (handle, gramps_id, father_handle, mother_handle, - child_ref_list, the_type, event_ref_list, media_list, - attribute_list, lds_seal_list, source_list, note_list, - change, tag_list, private) = family + ( + handle, + gramps_id, + father_handle, + mother_handle, + child_ref_list, + the_type, + event_ref_list, + media_list, + attribute_list, + lds_seal_list, + source_list, + note_list, + change, + tag_list, + private, + ) = family if source_list: new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) + self, source_list + ) else: new_citation_list = [] if child_ref_list: @@ -599,23 +892,48 @@ def gramps_upgrade_16(self): attribute_list = upgrade_attribute_list_16(self, attribute_list) if event_ref_list: event_ref_list = upgrade_event_ref_list_16(self, event_ref_list) - if(source_list or media_list or child_ref_list or - attribute_list or lds_seal_list or event_ref_list): - new_family = (handle, gramps_id, father_handle, mother_handle, - child_ref_list, the_type, event_ref_list, media_list, - attribute_list, lds_seal_list, new_citation_list, - note_list, change, tag_list, private) + if ( + source_list + or media_list + or child_ref_list + or attribute_list + or lds_seal_list + or event_ref_list + ): + new_family = ( + handle, + gramps_id, + father_handle, + mother_handle, + child_ref_list, + the_type, + event_ref_list, + media_list, + attribute_list, + lds_seal_list, + new_citation_list, + note_list, + change, + tag_list, + private, + ) LOG.debug(" upgrade new_family %s" % [new_family]) self._commit_raw(new_family, FAMILY_KEY) self.update() - LOG.debug("%d families upgraded with %d citations in %d seconds. " % - (self.get_number_of_families(), - self.cmap_index - start_num_citations, - time.time() - start_time)) + LOG.debug( + "%d families upgraded with %d citations in %d seconds. " + % ( + self.get_number_of_families(), + self.cmap_index - start_num_citations, + time.time() - start_time, + ) + ) data_upgradeobject[key2data[FAMILY_KEY]] = ( - self.get_number_of_families(), self.cmap_index - start_num_citations, - time.time() - start_time) + self.get_number_of_families(), + self.cmap_index - start_num_citations, + time.time() - start_time, + ) # --------------------------------- # Modify Events # --------------------------------- @@ -624,12 +942,24 @@ def gramps_upgrade_16(self): for event_handle in self.get_event_handles(): event = self.get_raw_event_data(event_handle) LOG.debug("upgrade event %s" % event[4]) - (handle, gramps_id, the_type, date, description, place, - source_list, note_list, media_list, attribute_list, - change, private) = event + ( + handle, + gramps_id, + the_type, + date, + description, + place, + source_list, + note_list, + media_list, + attribute_list, + change, + private, + ) = event if source_list: new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) + self, source_list + ) else: new_citation_list = [] if attribute_list: @@ -637,21 +967,37 @@ def gramps_upgrade_16(self): if media_list: media_list = upgrade_media_list_16(self, media_list) if source_list or attribute_list or media_list: - new_event = (handle, gramps_id, the_type, date, description, place, - new_citation_list, note_list, media_list, - attribute_list, - change, private) + new_event = ( + handle, + gramps_id, + the_type, + date, + description, + place, + new_citation_list, + note_list, + media_list, + attribute_list, + change, + private, + ) LOG.debug(" upgrade new_event %s" % [new_event]) self._commit_raw(new_event, EVENT_KEY) self.update() - LOG.debug("%d events upgraded with %d citations in %d seconds. " % - (self.get_number_of_events(), - self.cmap_index - start_num_citations, - time.time() - start_time)) + LOG.debug( + "%d events upgraded with %d citations in %d seconds. " + % ( + self.get_number_of_events(), + self.cmap_index - start_num_citations, + time.time() - start_time, + ) + ) data_upgradeobject[key2data[EVENT_KEY]] = ( - self.get_number_of_events(), self.cmap_index - start_num_citations, - time.time() - start_time) + self.get_number_of_events(), + self.cmap_index - start_num_citations, + time.time() - start_time, + ) # --------------------------------- # Modify Repositories @@ -661,25 +1007,48 @@ def gramps_upgrade_16(self): for repository_handle in self.get_repository_handles(): repository = self.get_raw_repository_data(repository_handle) LOG.debug("upgrade repository %s" % repository[3]) - (handle, gramps_id, the_type, name, note_list, - address_list, urls, change, private) = repository + ( + handle, + gramps_id, + the_type, + name, + note_list, + address_list, + urls, + change, + private, + ) = repository if address_list: address_list = upgrade_address_list_16(self, address_list) if address_list: - new_repository = (handle, gramps_id, the_type, name, note_list, - address_list, urls, change, private) + new_repository = ( + handle, + gramps_id, + the_type, + name, + note_list, + address_list, + urls, + change, + private, + ) LOG.debug(" upgrade new_repository %s" % [new_repository]) self._commit_raw(new_repository, REPOSITORY_KEY) self.update() - LOG.debug("%d repositories upgraded with %d citations in %d seconds. " % - (self.get_number_of_repositories(), - self.cmap_index - start_num_citations, - time.time() - start_time)) + LOG.debug( + "%d repositories upgraded with %d citations in %d seconds. " + % ( + self.get_number_of_repositories(), + self.cmap_index - start_num_citations, + time.time() - start_time, + ) + ) data_upgradeobject[key2data[REPOSITORY_KEY]] = ( self.get_number_of_repositories(), self.cmap_index - start_num_citations, - time.time() - start_time) + time.time() - start_time, + ) # --------------------------------- # Modify Source @@ -689,117 +1058,151 @@ def gramps_upgrade_16(self): for source_handle in self.get_source_handles(): source = self.get_raw_source_data(source_handle) LOG.debug("upgrade source %s" % source[2]) - (handle, gramps_id, title, author, - pubinfo, note_list, media_list, - abbrev, change, datamap, reporef_list, - private) = source + ( + handle, + gramps_id, + title, + author, + pubinfo, + note_list, + media_list, + abbrev, + change, + datamap, + reporef_list, + private, + ) = source if media_list: media_list = upgrade_media_list_16(self, media_list) - new_source = (handle, gramps_id, title, author, - pubinfo, note_list, media_list, - abbrev, change, datamap, reporef_list, - private) + new_source = ( + handle, + gramps_id, + title, + author, + pubinfo, + note_list, + media_list, + abbrev, + change, + datamap, + reporef_list, + private, + ) LOG.debug(" upgrade new_source %s" % [new_source]) self._commit_raw(new_source, SOURCE_KEY) self.update() - LOG.debug("%d sources upgraded with %d citations in %d seconds" % - (self.get_number_of_sources(), - self.cmap_index - start_num_citations, - int(time.time() - start_time))) + LOG.debug( + "%d sources upgraded with %d citations in %d seconds" + % ( + self.get_number_of_sources(), + self.cmap_index - start_num_citations, + int(time.time() - start_time), + ) + ) data_upgradeobject[key2data[SOURCE_KEY]] = ( - self.get_number_of_sources(), self.cmap_index - start_num_citations, - time.time() - start_time) - -# --------------------------------- -# Example database from repository took: -# 3403 events upgraded with 8 citations in 23 seconds. Backlinks took 1071 secs -# actually 4 of these citations were from: -# Media upgrade 4 citations upgraded in 4 seconds -# by only doing the backlinks when there might be something to do, -# improved to: -# 3403 events upgraded with 8 citations in 19 seconds. Backlinks took 1348 secs -# further improved by skipping debug logging: -# 3403 events upgraded with 8 citations in 2 seconds. Backlinks took 167 secs - -#Number of new objects upgraded: -# 2090 People upgraded with 2092 citations in 2148 secs -# 734 Families upgraded with 735 citations in 768 secs -# 3403 Events upgraded with 4 citations in 212 secs -# 7 Media Objects upgraded with 4 citations in 3 secs -# 852 Places upgraded with 0 citations in 39 secs - -# with reduced diagnostics -#Number of new objects upgraded: -# 73 People upgraded with 76 citations in 74 secs -# 35 Families upgraded with 36 citations in 31 secs -# 3403 Events upgraded with 4 citations in 7 secs -# 7 Media Objects upgraded with 4 citations in 3 secs -# 852 Places upgraded with 0 citations in 1 secs - -# without doing any backlinks -#Number of new objects upgraded: -# 73 People upgraded with 76 citations in 43 secs -# 35 Families upgraded with 36 citations in 24 secs -# 3403 Events upgraded with 4 citations in 6 secs -# 7 Media Objects upgraded with 4 citations in 2 secs -# 852 Places upgraded with 0 citations in 1 secs - -# another run about the same code: -#Number of new objects upgraded: -# 73 People upgraded with 76 citations in 48 secs -# 35 Families upgraded with 36 citations in 21 secs -# 3403 Events upgraded with 4 citations in 9 secs -# 7 Media Objects upgraded with 4 citations in 4 secs -# 852 Places upgraded with 0 citations in 1 secs - -# another run -#Number of new objects upgraded: -# 73 People upgraded with 76 citations in 36 secs -# 35 Families upgraded with 36 citations in 18 secs -# 3403 Events upgraded with 4 citations in 9 secs -# 7 Media Objects upgraded with 4 citations in 2 secs -# 852 Places upgraded with 0 citations in 1 secs - -# without incorrect nested tranaction structure: -#Number of new objects upgraded: -# 73 People upgraded with 76 citations in 0 secs -# 35 Families upgraded with 36 citations in 0 secs -# 3403 Events upgraded with 4 citations in 0 secs -# 7 Media Objects upgraded with 4 citations in 0 secs -# 852 Places upgraded with 0 citations in 0 secs + self.get_number_of_sources(), + self.cmap_index - start_num_citations, + time.time() - start_time, + ) + + # --------------------------------- + # Example database from repository took: + # 3403 events upgraded with 8 citations in 23 seconds. Backlinks took 1071 secs + # actually 4 of these citations were from: + # Media upgrade 4 citations upgraded in 4 seconds + # by only doing the backlinks when there might be something to do, + # improved to: + # 3403 events upgraded with 8 citations in 19 seconds. Backlinks took 1348 secs + # further improved by skipping debug logging: + # 3403 events upgraded with 8 citations in 2 seconds. Backlinks took 167 secs + + # Number of new objects upgraded: + # 2090 People upgraded with 2092 citations in 2148 secs + # 734 Families upgraded with 735 citations in 768 secs + # 3403 Events upgraded with 4 citations in 212 secs + # 7 Media Objects upgraded with 4 citations in 3 secs + # 852 Places upgraded with 0 citations in 39 secs + + # with reduced diagnostics + # Number of new objects upgraded: + # 73 People upgraded with 76 citations in 74 secs + # 35 Families upgraded with 36 citations in 31 secs + # 3403 Events upgraded with 4 citations in 7 secs + # 7 Media Objects upgraded with 4 citations in 3 secs + # 852 Places upgraded with 0 citations in 1 secs + + # without doing any backlinks + # Number of new objects upgraded: + # 73 People upgraded with 76 citations in 43 secs + # 35 Families upgraded with 36 citations in 24 secs + # 3403 Events upgraded with 4 citations in 6 secs + # 7 Media Objects upgraded with 4 citations in 2 secs + # 852 Places upgraded with 0 citations in 1 secs + + # another run about the same code: + # Number of new objects upgraded: + # 73 People upgraded with 76 citations in 48 secs + # 35 Families upgraded with 36 citations in 21 secs + # 3403 Events upgraded with 4 citations in 9 secs + # 7 Media Objects upgraded with 4 citations in 4 secs + # 852 Places upgraded with 0 citations in 1 secs + + # another run + # Number of new objects upgraded: + # 73 People upgraded with 76 citations in 36 secs + # 35 Families upgraded with 36 citations in 18 secs + # 3403 Events upgraded with 4 citations in 9 secs + # 7 Media Objects upgraded with 4 citations in 2 secs + # 852 Places upgraded with 0 citations in 1 secs + + # without incorrect nested tranaction structure: + # Number of new objects upgraded: + # 73 People upgraded with 76 citations in 0 secs + # 35 Families upgraded with 36 citations in 0 secs + # 3403 Events upgraded with 4 citations in 0 secs + # 7 Media Objects upgraded with 4 citations in 0 secs + # 852 Places upgraded with 0 citations in 0 secs self._txn_commit() # Bump up database version. Separate transaction to save metadata. - self._set_metadata('version', 16) + self._set_metadata("version", 16) LOG.debug([data_upgradeobject]) txt = _("Number of new objects upgraded:\n") for key in keyorder: try: txt += key2string[key] % { - 'n1' : data_upgradeobject[key2data[key]][0], - 'n2' : data_upgradeobject[key2data[key]][1], - 'n3' : data_upgradeobject[key2data[key]][2]} + "n1": data_upgradeobject[key2data[key]][0], + "n2": data_upgradeobject[key2data[key]][1], + "n3": data_upgradeobject[key2data[key]][2], + } except: txt += key2string[key] - txt += _("\n\nYou may want to run\n" - "Tools -> Family Tree Processing -> Merge\n" - "in order to merge citations that contain similar\n" - "information") - InfoDialog(_('Upgrade Statistics'), txt, monospaced=True) # TODO no-parent + txt += _( + "\n\nYou may want to run\n" + "Tools -> Family Tree Processing -> Merge\n" + "in order to merge citations that contain similar\n" + "information" + ) + InfoDialog(_("Upgrade Statistics"), txt, monospaced=True) # TODO no-parent def upgrade_media_list_16(self, media_list): new_media_list = [] for media in media_list: (privacy, source_list, note_list, attribute_list, ref, rect) = media - new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) + new_citation_list = convert_source_list_to_citation_list_16(self, source_list) new_attribute_list = upgrade_attribute_list_16(self, attribute_list) - new_media = (privacy, new_citation_list, note_list, new_attribute_list, - ref, rect) + new_media = ( + privacy, + new_citation_list, + note_list, + new_attribute_list, + ref, + rect, + ) new_media_list.append((new_media)) return new_media_list @@ -807,12 +1210,9 @@ def upgrade_media_list_16(self, media_list): def upgrade_attribute_list_16(self, attribute_list): new_attribute_list = [] for attribute in attribute_list: - (privacy, source_list, note_list, the_type, - value) = attribute - new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) - new_attribute = (privacy, new_citation_list, note_list, - the_type, value) + (privacy, source_list, note_list, the_type, value) = attribute + new_citation_list = convert_source_list_to_citation_list_16(self, source_list) + new_attribute = (privacy, new_citation_list, note_list, the_type, value) new_attribute_list.append((new_attribute)) return new_attribute_list @@ -821,10 +1221,8 @@ def upgrade_child_ref_list_16(self, child_ref_list): new_child_ref_list = [] for child_ref in child_ref_list: (privacy, source_list, note_list, ref, frel, mrel) = child_ref - new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) - new_child_ref = (privacy, new_citation_list, note_list, ref, - frel, mrel) + new_citation_list = convert_source_list_to_citation_list_16(self, source_list) + new_child_ref = (privacy, new_citation_list, note_list, ref, frel, mrel) new_child_ref_list.append((new_child_ref)) return new_child_ref_list @@ -832,12 +1230,29 @@ def upgrade_child_ref_list_16(self, child_ref_list): def upgrade_lds_seal_list_16(self, lds_seal_list): new_lds_seal_list = [] for lds_seal in lds_seal_list: - (source_list, note_list, date, type_, place, - famc, temple, status, private) = lds_seal - new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) - new_lds_seal = (new_citation_list, note_list, date, type_, place, - famc, temple, status, private) + ( + source_list, + note_list, + date, + type_, + place, + famc, + temple, + status, + private, + ) = lds_seal + new_citation_list = convert_source_list_to_citation_list_16(self, source_list) + new_lds_seal = ( + new_citation_list, + note_list, + date, + type_, + place, + famc, + temple, + status, + private, + ) new_lds_seal_list.append((new_lds_seal)) return new_lds_seal_list @@ -846,8 +1261,7 @@ def upgrade_address_list_16(self, address_list): new_address_list = [] for address in address_list: (privacy, source_list, note_list, date, location) = address - new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) + new_citation_list = convert_source_list_to_citation_list_16(self, source_list) new_address = (privacy, new_citation_list, note_list, date, location) new_address_list.append((new_address)) return new_address_list @@ -862,14 +1276,41 @@ def upgrade_name_list_16(self, name_list): def upgrade_name_16(self, name): - (privacy, source_list, note, date, first_name, surname_list, suffix, - title, name_type, group_as, sort_as, display_as, call, nick, - famnick) = name - new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) - new_name = (privacy, new_citation_list, note, date, first_name, - surname_list, suffix, title, name_type, group_as, sort_as, - display_as, call, nick, famnick) + ( + privacy, + source_list, + note, + date, + first_name, + surname_list, + suffix, + title, + name_type, + group_as, + sort_as, + display_as, + call, + nick, + famnick, + ) = name + new_citation_list = convert_source_list_to_citation_list_16(self, source_list) + new_name = ( + privacy, + new_citation_list, + note, + date, + first_name, + surname_list, + suffix, + title, + name_type, + group_as, + sort_as, + display_as, + call, + nick, + famnick, + ) return new_name @@ -877,8 +1318,7 @@ def upgrade_person_ref_list_16(self, person_ref_list): new_person_ref_list = [] for person_ref in person_ref_list: (privacy, source_list, note_list, ref, rel) = person_ref - new_citation_list = convert_source_list_to_citation_list_16( - self, source_list) + new_citation_list = convert_source_list_to_citation_list_16(self, source_list) new_person_ref = (privacy, new_citation_list, note_list, ref, rel) new_person_ref_list.append((new_person_ref)) return new_person_ref_list @@ -903,9 +1343,19 @@ def convert_source_list_to_citation_list_16(self, source_list): new_data_map = {} new_change = time.time() new_gramps_id = self.citation_prefix % self.cmap_index - new_citation = (new_handle, new_gramps_id, - date, page, confidence, ref, note_list, new_media_list, - new_data_map, new_change, private) + new_citation = ( + new_handle, + new_gramps_id, + date, + page, + confidence, + ref, + note_list, + new_media_list, + new_data_map, + new_change, + private, + ) citation_list.append((new_handle)) self._commit_raw(new_citation, CITATION_KEY) self.cmap_index += 1 @@ -920,10 +1370,16 @@ def gramps_upgrade_15(self): * surname list * remove marker """ - length = (self.get_number_of_notes() + self.get_number_of_people() + - self.get_number_of_events() + self.get_number_of_families() + - self.get_number_of_repositories() + self.get_number_of_media() + - self.get_number_of_places() + self.get_number_of_sources()) + 10 + length = ( + self.get_number_of_notes() + + self.get_number_of_people() + + self.get_number_of_events() + + self.get_number_of_families() + + self.get_number_of_repositories() + + self.get_number_of_media() + + self.get_number_of_places() + + self.get_number_of_sources() + ) + 10 self.set_total(length) self._txn_begin() self.tags = {} @@ -935,28 +1391,29 @@ def gramps_upgrade_15(self): for handle in self.get_person_handles(): person = self.get_raw_person_data(handle) - (junk_handle, # 0 - gramps_id, # 1 - gender, # 2 - primary_name, # 3 - alternate_names, # 4 - death_ref_index, # 5 - birth_ref_index, # 6 - event_ref_list, # 7 - family_list, # 8 - parent_family_list, # 9 - media_list, # 10 - address_list, # 11 - attribute_list, # 12 - urls, # 13 - ord_list, # 14 - psource_list, # 15 - pnote_list, # 16 - change, # 17 - marker, # 18 - pprivate, # 19 - person_ref_list, # 20 - ) = person + ( + junk_handle, # 0 + gramps_id, # 1 + gender, # 2 + primary_name, # 3 + alternate_names, # 4 + death_ref_index, # 5 + birth_ref_index, # 6 + event_ref_list, # 7 + family_list, # 8 + parent_family_list, # 9 + media_list, # 10 + address_list, # 11 + attribute_list, # 12 + urls, # 13 + ord_list, # 14 + psource_list, # 15 + pnote_list, # 16 + change, # 17 + marker, # 18 + pprivate, # 19 + person_ref_list, # 20 + ) = person tag_handle = convert_marker(self, marker) if tag_handle: @@ -966,28 +1423,29 @@ def gramps_upgrade_15(self): address_list = list(map(convert_address, address_list)) new_primary_name = convert_name_15(primary_name) new_alternate_names = list(map(convert_name_15, alternate_names)) - new_person = (junk_handle, # 0 - gramps_id, # 1 - gender, # 2 - new_primary_name, # 3 - new_alternate_names, # 4 - death_ref_index, # 5 - birth_ref_index, # 6 - event_ref_list, # 7 - family_list, # 8 - parent_family_list, # 9 - media_list, # 10 - address_list, # 11 - attribute_list, # 12 - urls, # 13 - ord_list, # 14 - psource_list, # 15 - pnote_list, # 16 - change, # 17 - tags, # 18 - pprivate, # 19 - person_ref_list # 20 - ) + new_person = ( + junk_handle, # 0 + gramps_id, # 1 + gender, # 2 + new_primary_name, # 3 + new_alternate_names, # 4 + death_ref_index, # 5 + birth_ref_index, # 6 + event_ref_list, # 7 + family_list, # 8 + parent_family_list, # 9 + media_list, # 10 + address_list, # 11 + attribute_list, # 12 + urls, # 13 + ord_list, # 14 + psource_list, # 15 + pnote_list, # 16 + change, # 17 + tags, # 18 + pprivate, # 19 + person_ref_list, # 20 + ) self._commit_raw(new_person, PERSON_KEY) self.update() @@ -1044,7 +1502,7 @@ def gramps_upgrade_15(self): event = self.get_raw_event_data(handle) new_event = list(event) new_event = new_event[:11] + new_event[12:] - #new_event[11] = [] + # new_event[11] = [] new_event = tuple(new_event) self._commit_raw(new_event, EVENT_KEY) self.update() @@ -1091,7 +1549,7 @@ def gramps_upgrade_15(self): self._txn_commit() # Bump up database version. Separate transaction to save metadata. - self._set_metadata('version', 15) + self._set_metadata("version", 15) def convert_marker(self, marker_field): @@ -1100,7 +1558,7 @@ def convert_marker(self, marker_field): marker.unserialize(marker_field) tag_name = str(marker) - if tag_name != '': + if tag_name != "": if tag_name not in self.tags: tag = Tag() handle = create_id() @@ -1117,7 +1575,7 @@ def convert_marker(self, marker_field): def convert_locbase(loc): """Convert location base to include an empty locality field.""" - return tuple([loc[0], ''] + list(loc[1:])) + return tuple([loc[0], ""] + list(loc[1:])) def convert_location(loc): @@ -1131,41 +1589,75 @@ def convert_address(addr): def convert_name_15(name): - (privacy, source_list, note_list, date, - first_name, surname, suffix, title, - name_type, prefix, patronymic, - group_as, sort_as, display_as, call) = name + ( + privacy, + source_list, + note_list, + date, + first_name, + surname, + suffix, + title, + name_type, + prefix, + patronymic, + group_as, + sort_as, + display_as, + call, + ) = name connector = "" origintype = (NameOriginType.NONE, "") patorigintype = (NameOriginType.PATRONYMIC, "") if patronymic.strip() == "": - #no patronymic, create a single surname + # no patronymic, create a single surname surname_list = [(surname, prefix, True, origintype, connector)] else: - #a patronymic, if no surname or equal as patronymic, a single surname + # a patronymic, if no surname or equal as patronymic, a single surname if (surname.strip() == "") or (surname == patronymic and prefix == ""): - surname_list = [ - (patronymic, prefix, True, patorigintype, connector)] + surname_list = [(patronymic, prefix, True, patorigintype, connector)] else: - #two surnames, first patronymic, then surname which is primary - surname_list = [(patronymic, "", False, patorigintype, ""), - (surname, prefix, True, origintype, connector)] - - #return new value, add two empty strings for nick and family nick - return (privacy, source_list, note_list, date, - first_name, surname_list, suffix, title, name_type, - group_as, sort_as, display_as, call, "", "") + # two surnames, first patronymic, then surname which is primary + surname_list = [ + (patronymic, "", False, patorigintype, ""), + (surname, prefix, True, origintype, connector), + ] + + # return new value, add two empty strings for nick and family nick + return ( + privacy, + source_list, + note_list, + date, + first_name, + surname_list, + suffix, + title, + name_type, + group_as, + sort_as, + display_as, + call, + "", + "", + ) def gramps_upgrade_14(self): """Upgrade database from version 13 to 14.""" # This upgrade modifies notes and dates - length = (self.get_number_of_notes() + self.get_number_of_people() + - self.get_number_of_events() + self.get_number_of_families() + - self.get_number_of_repositories() + self.get_number_of_media() + - self.get_number_of_places() + self.get_number_of_sources()) + length = ( + self.get_number_of_notes() + + self.get_number_of_people() + + self.get_number_of_events() + + self.get_number_of_families() + + self.get_number_of_repositories() + + self.get_number_of_media() + + self.get_number_of_places() + + self.get_number_of_sources() + ) self.set_total(length) self._txn_begin() @@ -1175,11 +1667,27 @@ def gramps_upgrade_14(self): # replace clear text with StyledText in Notes for handle in self.get_note_handles(): note = self.get_raw_note_data(handle) - (junk_handle, gramps_id, text, format_, note_type, - change, marker, private) = note + ( + junk_handle, + gramps_id, + text, + format_, + note_type, + change, + marker, + private, + ) = note styled_text = (text, []) - new_note = (handle, gramps_id, styled_text, format_, note_type, - change, marker, private) + new_note = ( + handle, + gramps_id, + styled_text, + format_, + note_type, + change, + marker, + private, + ) self._commit_raw(new_note, NOTE_KEY) self.update() @@ -1189,16 +1697,40 @@ def gramps_upgrade_14(self): # update dates with newyear for handle in self.get_event_handles(): event = self.get_raw_event_data(handle) - (junk_handle, gramps_id, the_type, date, description, place, - source_list, note_list, media_list, attribute_list, - change, marker, private) = event + ( + junk_handle, + gramps_id, + the_type, + date, + description, + place, + source_list, + note_list, + media_list, + attribute_list, + change, + marker, + private, + ) = event new_date = convert_date_14(date) new_source_list = new_source_list_14(source_list) new_media_list = new_media_list_14(media_list) new_attribute_list = new_attribute_list_14(attribute_list) - new_event = (junk_handle, gramps_id, the_type, new_date, description, - place, new_source_list, note_list, new_media_list, - new_attribute_list, change, marker, private) + new_event = ( + junk_handle, + gramps_id, + the_type, + new_date, + description, + place, + new_source_list, + note_list, + new_media_list, + new_attribute_list, + change, + marker, + private, + ) self._commit_raw(new_event, EVENT_KEY) self.update() @@ -1208,77 +1740,99 @@ def gramps_upgrade_14(self): # update dates with newyear for handle in self.get_person_handles(): person = self.get_raw_person_data(handle) - (junk_handle, # 0 - gramps_id, # 1 - gender, # 2 - primary_name, # 3 - alternate_names, # 4 - death_ref_index, # 5 - birth_ref_index, # 6 - event_ref_list, # 7 - family_list, # 8 - parent_family_list, # 9 - media_list, # 10 - address_list, # 11 - attribute_list, # 12 - urls, # 13 - lds_ord_list, # 14 - psource_list, # 15 - pnote_list, # 16 - change, # 17 - marker, # 18 - pprivate, # 19 - person_ref_list, # 20 - ) = person + ( + junk_handle, # 0 + gramps_id, # 1 + gender, # 2 + primary_name, # 3 + alternate_names, # 4 + death_ref_index, # 5 + birth_ref_index, # 6 + event_ref_list, # 7 + family_list, # 8 + parent_family_list, # 9 + media_list, # 10 + address_list, # 11 + attribute_list, # 12 + urls, # 13 + lds_ord_list, # 14 + psource_list, # 15 + pnote_list, # 16 + change, # 17 + marker, # 18 + pprivate, # 19 + person_ref_list, # 20 + ) = person new_address_list = [] for address in address_list: (privacy, asource_list, anote_list, date, location) = address new_date = convert_date_14(date) new_asource_list = new_source_list_14(asource_list) - new_address_list.append((privacy, new_asource_list, anote_list, - new_date, location)) + new_address_list.append( + (privacy, new_asource_list, anote_list, new_date, location) + ) new_ord_list = [] for ldsord in lds_ord_list: - (lsource_list, lnote_list, date, type_, place, - famc, temple, status, lprivate) = ldsord + ( + lsource_list, + lnote_list, + date, + type_, + place, + famc, + temple, + status, + lprivate, + ) = ldsord new_date = convert_date_14(date) new_lsource_list = new_source_list_14(lsource_list) - new_ord_list.append((new_lsource_list, lnote_list, new_date, type_, - place, famc, temple, status, lprivate)) + new_ord_list.append( + ( + new_lsource_list, + lnote_list, + new_date, + type_, + place, + famc, + temple, + status, + lprivate, + ) + ) new_primary_name = convert_name_14(primary_name) - new_alternate_names = [convert_name_14(name) for name - in alternate_names] + new_alternate_names = [convert_name_14(name) for name in alternate_names] new_media_list = new_media_list_14(media_list) new_psource_list = new_source_list_14(psource_list) new_attribute_list = new_attribute_list_14(attribute_list) new_person_ref_list = new_person_ref_list_14(person_ref_list) - new_person = (junk_handle, # 0 - gramps_id, # 1 - gender, # 2 - new_primary_name, # 3 - new_alternate_names, # 4 - death_ref_index, # 5 - birth_ref_index, # 6 - event_ref_list, # 7 - family_list, # 8 - parent_family_list, # 9 - new_media_list, # 10 - new_address_list, # 11 - new_attribute_list, # 12 - urls, # 13 - new_ord_list, # 14 - new_psource_list, # 15 - pnote_list, # 16 - change, # 17 - marker, # 18 - pprivate, # 19 - new_person_ref_list, # 20 - ) + new_person = ( + junk_handle, # 0 + gramps_id, # 1 + gender, # 2 + new_primary_name, # 3 + new_alternate_names, # 4 + death_ref_index, # 5 + birth_ref_index, # 6 + event_ref_list, # 7 + family_list, # 8 + parent_family_list, # 9 + new_media_list, # 10 + new_address_list, # 11 + new_attribute_list, # 12 + urls, # 13 + new_ord_list, # 14 + new_psource_list, # 15 + pnote_list, # 16 + change, # 17 + marker, # 18 + pprivate, # 19 + new_person_ref_list, # 20 + ) self._commit_raw(new_person, PERSON_KEY) self.update() @@ -1289,28 +1843,73 @@ def gramps_upgrade_14(self): # update dates with newyear for handle in self.get_family_handles(): family = self.get_raw_family_data(handle) - (junk_handle, gramps_id, father_handle, mother_handle, - child_ref_list, the_type, event_ref_list, media_list, - attribute_list, lds_seal_list, source_list, note_list, - change, marker, private) = family + ( + junk_handle, + gramps_id, + father_handle, + mother_handle, + child_ref_list, + the_type, + event_ref_list, + media_list, + attribute_list, + lds_seal_list, + source_list, + note_list, + change, + marker, + private, + ) = family new_child_ref_list = new_child_ref_list_14(child_ref_list) new_media_list = new_media_list_14(media_list) new_source_list = new_source_list_14(source_list) new_attribute_list = new_attribute_list_14(attribute_list) new_seal_list = [] for ldsord in lds_seal_list: - (lsource_list, lnote_list, date, type_, place, - famc, temple, status, lprivate) = ldsord + ( + lsource_list, + lnote_list, + date, + type_, + place, + famc, + temple, + status, + lprivate, + ) = ldsord new_date = convert_date_14(date) new_lsource_list = new_source_list_14(lsource_list) - new_seal_list.append((new_lsource_list, lnote_list, new_date, - type_, place, famc, temple, status, - lprivate)) - - new_family = (junk_handle, gramps_id, father_handle, mother_handle, - new_child_ref_list, the_type, event_ref_list, - new_media_list, new_attribute_list, new_seal_list, - new_source_list, note_list, change, marker, private) + new_seal_list.append( + ( + new_lsource_list, + lnote_list, + new_date, + type_, + place, + famc, + temple, + status, + lprivate, + ) + ) + + new_family = ( + junk_handle, + gramps_id, + father_handle, + mother_handle, + new_child_ref_list, + the_type, + event_ref_list, + new_media_list, + new_attribute_list, + new_seal_list, + new_source_list, + note_list, + change, + marker, + private, + ) self._commit_raw(new_family, FAMILY_KEY) self.update() @@ -1322,19 +1921,40 @@ def gramps_upgrade_14(self): for handle in self.get_repository_handles(): repository = self.get_raw_repository_data(handle) # address - (junk_handle, gramps_id, the_type, name, note_list, - address_list, urls, change, marker, private) = repository + ( + junk_handle, + gramps_id, + the_type, + name, + note_list, + address_list, + urls, + change, + marker, + private, + ) = repository new_address_list = [] for address in address_list: (privacy, asource_list, anote_list, date, location) = address new_date = convert_date_14(date) new_asource_list = new_source_list_14(asource_list) - new_address_list.append((privacy, new_asource_list, anote_list, - new_date, location)) - - new_repository = (junk_handle, gramps_id, the_type, name, note_list, - new_address_list, urls, change, marker, private) + new_address_list.append( + (privacy, new_asource_list, anote_list, new_date, location) + ) + + new_repository = ( + junk_handle, + gramps_id, + the_type, + name, + note_list, + new_address_list, + urls, + change, + marker, + private, + ) self._commit_raw(new_repository, REPOSITORY_KEY) self.update() @@ -1344,14 +1964,36 @@ def gramps_upgrade_14(self): # --------------------------------- for media_handle in self.get_media_handles(): media = self.get_raw_media_data(media_handle) - (handle, gramps_id, path, mime, desc, - attribute_list, source_list, note_list, change, - date, marker, private) = media + ( + handle, + gramps_id, + path, + mime, + desc, + attribute_list, + source_list, + note_list, + change, + date, + marker, + private, + ) = media new_source_list = new_source_list_14(source_list) new_date = convert_date_14(date) - new_media = (handle, gramps_id, path, mime, desc, - attribute_list, new_source_list, note_list, change, - new_date, marker, private) + new_media = ( + handle, + gramps_id, + path, + mime, + desc, + attribute_list, + new_source_list, + note_list, + change, + new_date, + marker, + private, + ) self._commit_raw(new_media, MEDIA_KEY) self.update() @@ -1361,14 +2003,40 @@ def gramps_upgrade_14(self): # --------------------------------- for place_handle in self.get_place_handles(): place = self.get_raw_place_data(place_handle) - (handle, gramps_id, title, longi, lat, - main_loc, alt_loc, urls, media_list, source_list, note_list, - change, marker, private) = place + ( + handle, + gramps_id, + title, + longi, + lat, + main_loc, + alt_loc, + urls, + media_list, + source_list, + note_list, + change, + marker, + private, + ) = place new_media_list = new_media_list_14(media_list) new_source_list = new_source_list_14(source_list) - new_place = (handle, gramps_id, title, longi, lat, - main_loc, alt_loc, urls, new_media_list, - new_source_list, note_list, change, marker, private) + new_place = ( + handle, + gramps_id, + title, + longi, + lat, + main_loc, + alt_loc, + urls, + new_media_list, + new_source_list, + note_list, + change, + marker, + private, + ) self._commit_raw(new_place, PLACE_KEY) self.update() @@ -1378,22 +2046,44 @@ def gramps_upgrade_14(self): # --------------------------------- for source_handle in self.get_source_handles(): source = self.get_raw_source_data(source_handle) - (handle, gramps_id, title, author, - pubinfo, note_list, media_list, - abbrev, change, datamap, reporef_list, - marker, private) = source + ( + handle, + gramps_id, + title, + author, + pubinfo, + note_list, + media_list, + abbrev, + change, + datamap, + reporef_list, + marker, + private, + ) = source new_media_list = new_media_list_14(media_list) - new_source = (handle, gramps_id, title, author, - pubinfo, note_list, new_media_list, - abbrev, change, datamap, reporef_list, - marker, private) + new_source = ( + handle, + gramps_id, + title, + author, + pubinfo, + note_list, + new_media_list, + abbrev, + change, + datamap, + reporef_list, + marker, + private, + ) self._commit_raw(new_source, SOURCE_KEY) self.update() self._txn_commit() # Bump up database version. Separate transaction to save metadata. - self._set_metadata('version', 14) + self._set_metadata("version", 14) def new_source_list_14(source_list): @@ -1401,8 +2091,7 @@ def new_source_list_14(source_list): for source in source_list: (date, private, note_list, confidence, ref, page) = source new_date = convert_date_14(date) - new_source_list.append((new_date, private, note_list, confidence, ref, - page)) + new_source_list.append((new_date, private, note_list, confidence, ref, page)) return new_source_list @@ -1411,8 +2100,9 @@ def new_attribute_list_14(attribute_list): for attribute in attribute_list: (private, asource_list, note_list, the_type, value) = attribute new_asource_list = new_source_list_14(asource_list) - new_attribute_list.append((private, new_asource_list, note_list, - the_type, value)) + new_attribute_list.append( + (private, new_asource_list, note_list, the_type, value) + ) return new_attribute_list @@ -1425,8 +2115,9 @@ def new_media_list_14(media_list): (private, source_list, note_list, attribute_list, ref, role) = media new_source_list = new_source_list_14(source_list) new_attribute_list = new_attribute_list_14(attribute_list) - new_media_list.append((private, new_source_list, note_list, - new_attribute_list, ref, role)) + new_media_list.append( + (private, new_source_list, note_list, new_attribute_list, ref, role) + ) return new_media_list @@ -1435,8 +2126,7 @@ def new_person_ref_list_14(person_ref_list): for person_ref in person_ref_list: (private, source_list, note_list, ref, rel) = person_ref new_source_list = new_source_list_14(source_list) - new_person_ref_list.append((private, new_source_list, note_list, ref, - rel)) + new_person_ref_list.append((private, new_source_list, note_list, ref, rel)) return new_person_ref_list @@ -1445,8 +2135,9 @@ def new_child_ref_list_14(child_ref_list): for data in child_ref_list: (private, source_list, note_list, ref, frel, mrel) = data new_source_list = new_source_list_14(source_list) - new_child_ref_list.append((private, new_source_list, note_list, ref, - frel, mrel)) + new_child_ref_list.append( + (private, new_source_list, note_list, ref, frel, mrel) + ) return new_child_ref_list @@ -1459,16 +2150,42 @@ def convert_date_14(date): def convert_name_14(name): - (privacy, source_list, note_list, date, - first_name, surname, suffix, title, - name_type, prefix, patronymic, - group_as, sort_as, display_as, call) = name + ( + privacy, + source_list, + note_list, + date, + first_name, + surname, + suffix, + title, + name_type, + prefix, + patronymic, + group_as, + sort_as, + display_as, + call, + ) = name new_date = convert_date_14(date) new_source_list = new_source_list_14(source_list) - return (privacy, new_source_list, note_list, new_date, - first_name, surname, suffix, title, - name_type, prefix, patronymic, - group_as, sort_as, display_as, call) + return ( + privacy, + new_source_list, + note_list, + new_date, + first_name, + surname, + suffix, + title, + name_type, + prefix, + patronymic, + group_as, + sort_as, + display_as, + call, + ) def make_zip_backup(dirname): @@ -1477,11 +2194,12 @@ def make_zip_backup(dirname): """ LOG.debug("Make backup prior to schema upgrade") import zipfile + # In Windows reserved characters is "<>:"/\|?*" reserved_char = r':,<>"/\|?* ' replace_char = "-__________" filepath = os.path.join(dirname, NAME_FILE) - with open(filepath, "r", encoding='utf8') as name_file: + with open(filepath, "r", encoding="utf8") as name_file: title = name_file.readline().strip() trans = title.maketrans(reserved_char, replace_char) title = title.translate(trans) @@ -1493,9 +2211,12 @@ def make_zip_backup(dirname): dotgramps_path = os.path.dirname(grampsdb_path) zipname = title + time.strftime("_%Y-%m-%d_%H-%M-%S") + ".zip" zippath = os.path.join(dotgramps_path, zipname) - with zipfile.ZipFile(zippath, 'w') as myzip: + with zipfile.ZipFile(zippath, "w") as myzip: for filename in os.listdir(dirname): pathname = os.path.join(dirname, filename) myzip.write(pathname, os.path.join(db_code, filename)) - LOG.warning("If upgrade and loading the Family Tree works, you can " - "delete the zip file at %s", zippath) + LOG.warning( + "If upgrade and loading the Family Tree works, you can " + "delete the zip file at %s", + zippath, + ) diff --git a/gramps/gen/db/utils.py b/gramps/gen/db/utils.py index 7df6c6ed8c4..9f8837eb03a 100644 --- a/gramps/gen/db/utils.py +++ b/gramps/gen/db/utils.py @@ -24,34 +24,36 @@ Database utilites """ -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Python modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ import os import logging -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Gramps modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ from ..plug import BasePluginManager from ..const import PLUGINS_DIR, USER_PLUGINS from ..constfunc import win, get_env_var from ..config import config from .dbconst import DBLOGNAME, DBLOCKFN, DBBACKEND from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- _LOG = logging.getLogger(DBLOGNAME) + def make_database(plugin_id): """ Make a database, given a plugin id. @@ -73,19 +75,26 @@ def make_database(plugin_id): db = database() if __debug__ and _LOG.isEnabledFor(logging.DEBUG): import inspect + frame = inspect.currentframe() c_frame = frame.f_back c_code = c_frame.f_code - _LOG.debug("Database class instance created Class:%s instance:%s. " - "Called from File %s, line %s, in %s", - db.__class__.__name__, hex(id(db)), c_code.co_filename, - c_frame.f_lineno, c_code.co_name) + _LOG.debug( + "Database class instance created Class:%s instance:%s. " + "Called from File %s, line %s, in %s", + db.__class__.__name__, + hex(id(db)), + c_code.co_filename, + c_frame.f_lineno, + c_code.co_name, + ) return db else: raise Exception("can't load database backend: '%s'" % plugin_id) else: raise Exception("no such database backend: '%s'" % plugin_id) + def open_database(dbname, force_unlock=False, callback=None): """ Open a database by name and return the database. @@ -99,16 +108,17 @@ def open_database(dbname, force_unlock=False, callback=None): database.load(dbpath, callback=callback) return database + def lookup_family_tree(dbname): """ Find a Family Tree given its name, and return properties. """ - dbdir = os.path.expanduser(config.get('database.path')) + dbdir = os.path.expanduser(config.get("database.path")) for dpath in os.listdir(dbdir): dirpath = os.path.join(dbdir, dpath) path_name = os.path.join(dirpath, "name.txt") if os.path.isfile(path_name): - with open(path_name, 'r', encoding='utf8') as file: + with open(path_name, "r", encoding="utf8") as file: name = file.readline().strip() if dbname == name: locked = False @@ -116,7 +126,7 @@ def lookup_family_tree(dbname): backend = get_dbid_from_path(dirpath) try: fname = os.path.join(dirpath, "lock") - with open(fname, 'r', encoding='utf8') as ifile: + with open(fname, "r", encoding="utf8") as ifile: locked_by = ifile.read().strip() locked = True except (OSError, IOError): @@ -124,6 +134,7 @@ def lookup_family_tree(dbname): return (dirpath, locked, locked_by, backend) return None + def get_dbid_from_path(dirpath): """ Return a database backend from a directory path. @@ -135,6 +146,7 @@ def get_dbid_from_path(dirpath): dbid = file.read().strip() return dbid + def import_as_dict(filename, user, skp_imp_adds=True): """ Import the filename into a InMemoryDB and return it. @@ -143,18 +155,20 @@ def import_as_dict(filename, user, skp_imp_adds=True): db.load(":memory:") db.set_feature("skip-import-additions", skp_imp_adds) db.set_prefixes( - config.get('preferences.iprefix'), - config.get('preferences.oprefix'), - config.get('preferences.fprefix'), - config.get('preferences.sprefix'), - config.get('preferences.cprefix'), - config.get('preferences.pprefix'), - config.get('preferences.eprefix'), - config.get('preferences.rprefix'), - config.get('preferences.nprefix')) + config.get("preferences.iprefix"), + config.get("preferences.oprefix"), + config.get("preferences.fprefix"), + config.get("preferences.sprefix"), + config.get("preferences.cprefix"), + config.get("preferences.pprefix"), + config.get("preferences.eprefix"), + config.get("preferences.rprefix"), + config.get("preferences.nprefix"), + ) status = import_from_filename(db, filename, user) return db if status else None + def import_from_filename(db, filename, user): """ Import a file into a database. @@ -179,6 +193,7 @@ def import_from_filename(db, filename, user): return True return False + def find_surname_name(key, data): """ Creating a surname from raw name, to use for sort and index @@ -186,6 +201,7 @@ def find_surname_name(key, data): """ return __index_surname(data[5]) + def __index_surname(surn_list): """ All non pa/matronymic surnames are used in indexing. @@ -193,26 +209,36 @@ def __index_surname(surn_list): returns a byte string """ from ..lib import NameOriginType + if surn_list: - surn = " ".join([x[0] for x in surn_list if not (x[3][0] in [ - NameOriginType.PATRONYMIC, NameOriginType.MATRONYMIC])]) + surn = " ".join( + [ + x[0] + for x in surn_list + if not ( + x[3][0] in [NameOriginType.PATRONYMIC, NameOriginType.MATRONYMIC] + ) + ] + ) else: surn = "" return surn + def clear_lock_file(name): try: os.unlink(os.path.join(name, DBLOCKFN)) except OSError: return + def write_lock_file(name): if not os.path.isdir(name): os.mkdir(name) - with open(os.path.join(name, DBLOCKFN), "w", encoding='utf8') as f: + with open(os.path.join(name, DBLOCKFN), "w", encoding="utf8") as f: if win(): - user = get_env_var('USERNAME') - host = get_env_var('USERDOMAIN') + user = get_env_var("USERNAME") + host = get_env_var("USERDOMAIN") if not user: user = _("Unknown") else: @@ -223,7 +249,7 @@ def write_lock_file(name): except: # not win, so don't need get_env_var. # under cron getlogin() throws and there is no USER. - user = os.environ.get('USER', 'noUSER') + user = os.environ.get("USER", "noUSER") if host: text = "%s@%s" % (user, host) else: diff --git a/gramps/gen/dbstate.py b/gramps/gen/dbstate.py index ffe831e0c85..e6ff847b04e 100644 --- a/gramps/gen/dbstate.py +++ b/gramps/gen/dbstate.py @@ -23,20 +23,20 @@ Provide the database state class """ -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Python modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ import sys import logging import inspect -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Gramps modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ from .db import DbReadBase from .proxy.proxybase import ProxyDbBase from .utils.callback import Callback @@ -44,23 +44,24 @@ from .db.dbconst import DBLOGNAME from .db.dummydb import DummyDb -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- LOG = logging.getLogger(".dbstate") _LOG = logging.getLogger(DBLOGNAME) + class DbState(Callback): """ Provide a class to encapsulate the state of the database. """ __signals__ = { - 'database-changed' : ((DbReadBase, ProxyDbBase), ), - 'no-database' : None, - } + "database-changed": ((DbReadBase, ProxyDbBase),), + "no-database": None, + } def __init__(self): """ @@ -91,9 +92,14 @@ def is_open(self): frame = inspect.currentframe() c_frame = frame.f_back c_code = c_frame.f_code - _LOG.debug('calling %s.%s()... from file %s, line %s in %s', - class_name, func_name, c_code.co_filename, - c_frame.f_lineno, c_code.co_name) + _LOG.debug( + "calling %s.%s()... from file %s, line %s in %s", + class_name, + func_name, + c_code.co_filename, + c_frame.f_lineno, + c_code.co_name, + ) return (self.db is not None) and self.db.is_open() def change_database(self, database): @@ -102,7 +108,7 @@ def change_database(self, database): Retained for backward compatibility. """ if database: - self.emit('no-database', ()) + self.emit("no-database", ()) if self.is_open(): self.db.close() self.change_database_noclose(database) @@ -113,33 +119,34 @@ def change_database_noclose(self, database): """ self.db = database self.db.set_prefixes( - config.get('preferences.iprefix'), - config.get('preferences.oprefix'), - config.get('preferences.fprefix'), - config.get('preferences.sprefix'), - config.get('preferences.cprefix'), - config.get('preferences.pprefix'), - config.get('preferences.eprefix'), - config.get('preferences.rprefix'), - config.get('preferences.nprefix')) + config.get("preferences.iprefix"), + config.get("preferences.oprefix"), + config.get("preferences.fprefix"), + config.get("preferences.sprefix"), + config.get("preferences.cprefix"), + config.get("preferences.pprefix"), + config.get("preferences.eprefix"), + config.get("preferences.rprefix"), + config.get("preferences.nprefix"), + ) self.open = True def signal_change(self): """ Emits the database-changed signal with the new database """ - self.emit('database-changed', (self.db, )) + self.emit("database-changed", (self.db,)) def no_database(self): """ Closes the database without a new database (except for the DummyDb) """ - self.emit('no-database', ()) + self.emit("no-database", ()) if self.is_open(): self.db.close() self.db = DummyDb() self.open = False - self.emit('database-changed', (self.db, )) + self.emit("database-changed", (self.db,)) def get_database(self): """ @@ -168,7 +175,7 @@ def apply_proxy(self, proxy, *args, **kwargs): """ self.stack.append(self.db) self.db = proxy(self.db, *args, **kwargs) - self.emit('database-changed', (self.db, )) + self.emit("database-changed", (self.db,)) def pop_proxy(self): """ @@ -180,4 +187,4 @@ def pop_proxy(self): >>> dbstate.pop_proxy() """ self.db = self.stack.pop() - self.emit('database-changed', (self.db, )) + self.emit("database-changed", (self.db,)) diff --git a/gramps/gen/display/__init__.py b/gramps/gen/display/__init__.py index 442b87dcef3..ebdeef9b910 100644 --- a/gramps/gen/display/__init__.py +++ b/gramps/gen/display/__init__.py @@ -18,4 +18,3 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # - diff --git a/gramps/gen/display/name.py b/gramps/gen/display/name.py index ff7e1d79766..d6807781d19 100644 --- a/gramps/gen/display/name.py +++ b/gramps/gen/display/name.py @@ -52,38 +52,40 @@ ====== =============================================================== """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import re import logging LOG = logging.getLogger(".gramps.gen") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..const import ARABIC_COMMA, ARABIC_SEMICOLON, GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext from ..lib.name import Name from ..lib.nameorigintype import NameOriginType try: from ..config import config - WITH_GRAMPS_CONFIG=True + + WITH_GRAMPS_CONFIG = True except ImportError: - WITH_GRAMPS_CONFIG=False + WITH_GRAMPS_CONFIG = False -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Constants # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- _FIRSTNAME = 4 _SURNAME_LIST = 5 _SUFFIX = 6 @@ -107,35 +109,39 @@ _INA = False _F_NAME = 0 # name of the format -_F_FMT = 1 # the format string -_F_ACT = 2 # if the format is active -_F_FN = 3 # name format function -_F_RAWFN = 4 # name format raw function +_F_FMT = 1 # the format string +_F_ACT = 2 # if the format is active +_F_FN = 3 # name format function +_F_RAWFN = 4 # name format raw function PAT_AS_SURN = False -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Local functions # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # Because of occurring in an exec(), this couldn't be in a lambda: # we sort names first on longest first, then last letter first, this to # avoid translations of shorter terms which appear in longer ones, eg # namelast may not be mistaken with name, so namelast must first be # converted to %k before name is converted. ##def _make_cmp(a, b): return -cmp((len(a[1]),a[1]), (len(b[1]), b[1])) -def _make_cmp_key(a): return (len(a[1]),a[1]) # set reverse to True!! +def _make_cmp_key(a): + return (len(a[1]), a[1]) # set reverse to True!! + -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # NameDisplayError class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class NameDisplayError(Exception): """ Error used to report that the name display format string is invalid. """ + def __init__(self, value): Exception.__init__(self) self.value = value @@ -143,20 +149,25 @@ def __init__(self, value): def __str__(self): return self.value -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Functions to extract data from raw lists (unserialized objects) # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- + def _raw_full_surname(raw_surn_data_list): """method for the 'l' symbol: full surnames""" result = "" for raw_surn_data in raw_surn_data_list: - result += "%s %s %s " % (raw_surn_data[_PREFIX_IN_LIST], - raw_surn_data[_SURNAME_IN_LIST], - raw_surn_data[_CONNECTOR_IN_LIST]) - return ' '.join(result.split()).strip() + result += "%s %s %s " % ( + raw_surn_data[_PREFIX_IN_LIST], + raw_surn_data[_SURNAME_IN_LIST], + raw_surn_data[_CONNECTOR_IN_LIST], + ) + return " ".join(result.split()).strip() + def _raw_primary_surname(raw_surn_data_list): """method for the 'm' symbol: primary surname""" @@ -164,35 +175,48 @@ def _raw_primary_surname(raw_surn_data_list): nrsur = len(raw_surn_data_list) for raw_surn_data in raw_surn_data_list: if raw_surn_data[_PRIMARY_IN_LIST]: - #if there are multiple surnames, return the primary. If there - #is only one surname, then primary has little meaning, and we - #assume a pa/matronymic should not be given as primary as it - #normally is defined independently - if not PAT_AS_SURN and nrsur == 1 and \ - (raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO - or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO): - return '' + # if there are multiple surnames, return the primary. If there + # is only one surname, then primary has little meaning, and we + # assume a pa/matronymic should not be given as primary as it + # normally is defined independently + if ( + not PAT_AS_SURN + and nrsur == 1 + and ( + raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO + or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO + ) + ): + return "" else: - result = "%s %s %s" % (raw_surn_data[_PREFIX_IN_LIST], - raw_surn_data[_SURNAME_IN_LIST], - raw_surn_data[_CONNECTOR_IN_LIST]) - return ' '.join(result.split()) - return '' + result = "%s %s %s" % ( + raw_surn_data[_PREFIX_IN_LIST], + raw_surn_data[_SURNAME_IN_LIST], + raw_surn_data[_CONNECTOR_IN_LIST], + ) + return " ".join(result.split()) + return "" + def _raw_primary_surname_only(raw_surn_data_list): - """method to obtain the raw primary surname data, so this returns a string - """ + """method to obtain the raw primary surname data, so this returns a string""" global PAT_AS_SURN nrsur = len(raw_surn_data_list) for raw_surn_data in raw_surn_data_list: if raw_surn_data[_PRIMARY_IN_LIST]: - if not PAT_AS_SURN and nrsur == 1 and \ - (raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO - or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO): - return '' + if ( + not PAT_AS_SURN + and nrsur == 1 + and ( + raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO + or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO + ) + ): + return "" else: return raw_surn_data[_SURNAME_IN_LIST] - return '' + return "" + def _raw_primary_prefix_only(raw_surn_data_list): """method to obtain the raw primary surname data""" @@ -200,13 +224,19 @@ def _raw_primary_prefix_only(raw_surn_data_list): nrsur = len(raw_surn_data_list) for raw_surn_data in raw_surn_data_list: if raw_surn_data[_PRIMARY_IN_LIST]: - if not PAT_AS_SURN and nrsur == 1 and \ - (raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO - or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO): - return '' + if ( + not PAT_AS_SURN + and nrsur == 1 + and ( + raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO + or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO + ) + ): + return "" else: return raw_surn_data[_PREFIX_IN_LIST] - return '' + return "" + def _raw_primary_conn_only(raw_surn_data_list): """method to obtain the raw primary surname data""" @@ -214,111 +244,142 @@ def _raw_primary_conn_only(raw_surn_data_list): nrsur = len(raw_surn_data_list) for raw_surn_data in raw_surn_data_list: if raw_surn_data[_PRIMARY_IN_LIST]: - if not PAT_AS_SURN and nrsur == 1 and \ - (raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO - or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO): - return '' + if ( + not PAT_AS_SURN + and nrsur == 1 + and ( + raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO + or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO + ) + ): + return "" else: return raw_surn_data[_CONNECTOR_IN_LIST] - return '' + return "" + def _raw_patro_surname(raw_surn_data_list): """method for the 'y' symbol: patronymic surname""" for raw_surn_data in raw_surn_data_list: - if (raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO or - raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO): - result = "%s %s %s" % (raw_surn_data[_PREFIX_IN_LIST], - raw_surn_data[_SURNAME_IN_LIST], - raw_surn_data[_CONNECTOR_IN_LIST]) - return ' '.join(result.split()) - return '' + if ( + raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO + or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO + ): + result = "%s %s %s" % ( + raw_surn_data[_PREFIX_IN_LIST], + raw_surn_data[_SURNAME_IN_LIST], + raw_surn_data[_CONNECTOR_IN_LIST], + ) + return " ".join(result.split()) + return "" + def _raw_patro_surname_only(raw_surn_data_list): """method for the '1y' symbol: patronymic surname only""" for raw_surn_data in raw_surn_data_list: - if (raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO or - raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO): + if ( + raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO + or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO + ): result = "%s" % (raw_surn_data[_SURNAME_IN_LIST]) - return ' '.join(result.split()) - return '' + return " ".join(result.split()) + return "" + def _raw_patro_prefix_only(raw_surn_data_list): """method for the '0y' symbol: patronymic prefix only""" for raw_surn_data in raw_surn_data_list: - if (raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO or - raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO): + if ( + raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO + or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO + ): result = "%s" % (raw_surn_data[_PREFIX_IN_LIST]) - return ' '.join(result.split()) - return '' + return " ".join(result.split()) + return "" + def _raw_patro_conn_only(raw_surn_data_list): """method for the '2y' symbol: patronymic conn only""" for raw_surn_data in raw_surn_data_list: - if (raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO or - raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO): + if ( + raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINPATRO + or raw_surn_data[_TYPE_IN_LIST][0] == _ORIGINMATRO + ): result = "%s" % (raw_surn_data[_CONNECTOR_IN_LIST]) - return ' '.join(result.split()) - return '' + return " ".join(result.split()) + return "" + def _raw_nonpatro_surname(raw_surn_data_list): """method for the 'o' symbol: full surnames without pa/matronymic or - primary + primary """ result = "" for raw_surn_data in raw_surn_data_list: - if ((not raw_surn_data[_PRIMARY_IN_LIST]) and - raw_surn_data[_TYPE_IN_LIST][0] != _ORIGINPATRO and - raw_surn_data[_TYPE_IN_LIST][0] != _ORIGINMATRO): - result += "%s %s %s " % (raw_surn_data[_PREFIX_IN_LIST], - raw_surn_data[_SURNAME_IN_LIST], - raw_surn_data[_CONNECTOR_IN_LIST]) - return ' '.join(result.split()).strip() + if ( + (not raw_surn_data[_PRIMARY_IN_LIST]) + and raw_surn_data[_TYPE_IN_LIST][0] != _ORIGINPATRO + and raw_surn_data[_TYPE_IN_LIST][0] != _ORIGINMATRO + ): + result += "%s %s %s " % ( + raw_surn_data[_PREFIX_IN_LIST], + raw_surn_data[_SURNAME_IN_LIST], + raw_surn_data[_CONNECTOR_IN_LIST], + ) + return " ".join(result.split()).strip() + def _raw_nonprimary_surname(raw_surn_data_list): """method for the 'r' symbol: nonprimary surnames""" - result = '' + result = "" for raw_surn_data in raw_surn_data_list: if not raw_surn_data[_PRIMARY_IN_LIST]: - result = "%s %s %s %s" % (result, raw_surn_data[_PREFIX_IN_LIST], - raw_surn_data[_SURNAME_IN_LIST], - raw_surn_data[_CONNECTOR_IN_LIST]) - return ' '.join(result.split()) + result = "%s %s %s %s" % ( + result, + raw_surn_data[_PREFIX_IN_LIST], + raw_surn_data[_SURNAME_IN_LIST], + raw_surn_data[_CONNECTOR_IN_LIST], + ) + return " ".join(result.split()) + def _raw_prefix_surname(raw_surn_data_list): """method for the 'p' symbol: all prefixes""" result = "" for raw_surn_data in raw_surn_data_list: result += "%s " % (raw_surn_data[_PREFIX_IN_LIST]) - return ' '.join(result.split()).strip() + return " ".join(result.split()).strip() + def _raw_single_surname(raw_surn_data_list): """method for the 'q' symbol: surnames without prefix and connectors""" result = "" for raw_surn_data in raw_surn_data_list: result += "%s " % (raw_surn_data[_SURNAME_IN_LIST]) - return ' '.join(result.split()).strip() + return " ".join(result.split()).strip() + def cleanup_name(namestring): """Remove too long white space due to missing name parts, - so "a b" becomes "a b" and "a , b" becomes "a, b" + so "a b" becomes "a b" and "a , b" becomes "a, b" """ parts = namestring.split() if not parts: return "" result = parts[0] for val in parts[1:]: - if len(val) == 1 and val in [',', ';', ':', - ARABIC_COMMA, ARABIC_SEMICOLON]: - result += val + if len(val) == 1 and val in [",", ";", ":", ARABIC_COMMA, ARABIC_SEMICOLON]: + result += val else: - result += ' ' + val + result += " " + val return result -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # NameDisplay class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class NameDisplay: """ Base class for displaying of Name instances. @@ -347,24 +408,23 @@ def __init__(self, xlocale=glocale): global PAT_AS_SURN # Translators: needed for Arabic, ignore otherwise - COMMAGLYPH = xlocale.translation.gettext(',') + COMMAGLYPH = xlocale.translation.gettext(",") self.STANDARD_FORMATS = [ - (Name.DEF, _("Default format (defined by Gramps preferences)"), - '', _ACT), - (Name.LNFN, _("Surname, Given Suffix"), - '%l' + COMMAGLYPH + ' %f %s', _ACT), - (Name.FN, _("Given"), - '%f', _ACT), - (Name.FNLN, _("Given Surname Suffix"), - '%f %l %s', _ACT), + (Name.DEF, _("Default format (defined by Gramps preferences)"), "", _ACT), + (Name.LNFN, _("Surname, Given Suffix"), "%l" + COMMAGLYPH + " %f %s", _ACT), + (Name.FN, _("Given"), "%f", _ACT), + (Name.FNLN, _("Given Surname Suffix"), "%f %l %s", _ACT), # primary name primconnector other, given pa/matronynic suffix, primprefix # Translators: long string, have a look at Preferences dialog - (Name.LNFNP, _("Main Surnames, Given Patronymic Suffix Prefix"), - '%1m %2m %o' + COMMAGLYPH + ' %f %1y %s %0m', _ACT), + ( + Name.LNFNP, + _("Main Surnames, Given Patronymic Suffix Prefix"), + "%1m %2m %o" + COMMAGLYPH + " %f %1y %s %0m", + _ACT, + ), # DEPRECATED FORMATS - (Name.PTFN, _("Patronymic, Given"), - '%y' + COMMAGLYPH + ' %s %f', _INA), + (Name.PTFN, _("Patronymic, Given"), "%y" + COMMAGLYPH + " %s %f", _INA), ] self.LNFN_STR = "%s" + COMMAGLYPH + " %s %s" @@ -372,26 +432,26 @@ def __init__(self, xlocale=glocale): self.name_formats = {} if WITH_GRAMPS_CONFIG: - self.default_format = config.get('preferences.name-format') + self.default_format = config.get("preferences.name-format") if self.default_format == 0: self.default_format = Name.LNFN - config.set('preferences.name-format', self.default_format) - #if only one surname, see if pa/ma should be considered as + config.set("preferences.name-format", self.default_format) + # if only one surname, see if pa/ma should be considered as # 'the' surname. - PAT_AS_SURN = config.get('preferences.patronimic-surname') - config.connect('preferences.patronimic-surname', self.change_pa_sur) + PAT_AS_SURN = config.get("preferences.patronimic-surname") + config.connect("preferences.patronimic-surname", self.change_pa_sur) else: self.default_format = Name.LNFN PAT_AS_SURN = False - #preinit the name formats, this should be updated with the data - #in the database once a database is loaded + # preinit the name formats, this should be updated with the data + # in the database once a database is loaded self.set_name_format(self.STANDARD_FORMATS) def change_pa_sur(self, *args): - """ How to handle single patronymic as surname is changed""" + """How to handle single patronymic as surname is changed""" global PAT_AS_SURN - PAT_AS_SURN = config.get('preferences.patronimic-surname') + PAT_AS_SURN = config.get("preferences.patronimic-surname") def get_pat_as_surn(self): global PAT_AS_SURN @@ -404,35 +464,38 @@ def _format_raw_fn(self, fmt_str): return lambda x: self.format_str_raw(x, fmt_str) def _raw_lnfn(self, raw_data): - result = self.LNFN_STR % (_raw_full_surname(raw_data[_SURNAME_LIST]), - raw_data[_FIRSTNAME], - raw_data[_SUFFIX]) - return ' '.join(result.split()) + result = self.LNFN_STR % ( + _raw_full_surname(raw_data[_SURNAME_LIST]), + raw_data[_FIRSTNAME], + raw_data[_SUFFIX], + ) + return " ".join(result.split()) def _raw_fnln(self, raw_data): - result = "%s %s %s" % (raw_data[_FIRSTNAME], - _raw_full_surname(raw_data[_SURNAME_LIST]), - raw_data[_SUFFIX]) - return ' '.join(result.split()) + result = "%s %s %s" % ( + raw_data[_FIRSTNAME], + _raw_full_surname(raw_data[_SURNAME_LIST]), + raw_data[_SUFFIX], + ) + return " ".join(result.split()) def _raw_fn(self, raw_data): result = raw_data[_FIRSTNAME] - return ' '.join(result.split()) + return " ".join(result.split()) def clear_custom_formats(self): - self.name_formats = {num: value - for num, value in self.name_formats.items() - if num >= 0} + self.name_formats = { + num: value for num, value in self.name_formats.items() if num >= 0 + } def set_name_format(self, formats): - raw_func_dict = { - Name.LNFN : self._raw_lnfn, - Name.FNLN : self._raw_fnln, - Name.FN : self._raw_fn, - } + Name.LNFN: self._raw_lnfn, + Name.FNLN: self._raw_fnln, + Name.FN: self._raw_fn, + } - for (num, name, fmt_str, act) in formats: + for num, name, fmt_str, act in formats: func = self._format_fn(fmt_str) func_raw = raw_func_dict.get(num, self._format_raw_fn(fmt_str)) self.name_formats[num] = (name, fmt_str, act, func, func_raw) @@ -445,11 +508,11 @@ def add_name_format(self, name, fmt_str): num = -1 while num in self.name_formats: num -= 1 - self.set_name_format([(num, name, fmt_str,_ACT)]) + self.set_name_format([(num, name, fmt_str, _ACT)]) return num def edit_name_format(self, num, name, fmt_str): - self.set_name_format([(num, name, fmt_str,_ACT)]) + self.set_name_format([(num, name, fmt_str, _ACT)]) if self.default_format == num: self.set_default_format(num) @@ -469,28 +532,30 @@ def set_default_format(self, num): self.default_format = num - self.name_formats[Name.DEF] = (self.name_formats[Name.DEF][_F_NAME], - self.name_formats[Name.DEF][_F_FMT], - self.name_formats[Name.DEF][_F_ACT], - self.name_formats[num][_F_FN], - self.name_formats[num][_F_RAWFN]) + self.name_formats[Name.DEF] = ( + self.name_formats[Name.DEF][_F_NAME], + self.name_formats[Name.DEF][_F_FMT], + self.name_formats[Name.DEF][_F_ACT], + self.name_formats[num][_F_FN], + self.name_formats[num][_F_RAWFN], + ) def get_default_format(self): return self.default_format def set_format_inactive(self, num): try: - self.name_formats[num] = (self.name_formats[num][_F_NAME], - self.name_formats[num][_F_FMT], - _INA, - self.name_formats[num][_F_FN], - self.name_formats[num][_F_RAWFN]) + self.name_formats[num] = ( + self.name_formats[num][_F_NAME], + self.name_formats[num][_F_FMT], + _INA, + self.name_formats[num][_F_FN], + self.name_formats[num][_F_RAWFN], + ) except: pass - def get_name_format(self, also_default=False, - only_custom=False, - only_active=True): + def get_name_format(self, also_default=False, only_custom=False, only_active=True): """ Returns a list of name formats as tuples on the form (index, name,fmt_str,act). @@ -499,20 +564,36 @@ def get_name_format(self, also_default=False, their indices. """ - custom_formats = sorted([ - (index, name, format_string, active) - for index, (name, format_string, active, *rest) in self.name_formats.items() - if index < 0 and (not only_active or active) - ]) + custom_formats = sorted( + [ + (index, name, format_string, active) + for index, ( + name, + format_string, + active, + *rest, + ) in self.name_formats.items() + if index < 0 and (not only_active or active) + ] + ) if only_custom: return custom_formats - standard_formats = sorted([ - (index, name, format_string, active) - for index, (name, format_string, active, *rest) in self.name_formats.items() - if index >= 0 and (also_default or index) and (not only_active or active) - ]) + standard_formats = sorted( + [ + (index, name, format_string, active) + for index, ( + name, + format_string, + active, + *rest, + ) in self.name_formats.items() + if index >= 0 + and (also_default or index) + and (not only_active or active) + ] + ) return standard_formats + custom_formats @@ -524,8 +605,7 @@ def _is_format_valid(self, num): num = 0 return num - #------------------------------------------------------------------------- - + # ------------------------------------------------------------------------- def _gen_raw_func(self, format_str): """The job of building the name from a format string is rather @@ -574,59 +654,90 @@ def fn(raw_data): # we need the names of each of the variables or methods that are # called to fill in each format flag. # Dictionary is "code": ("expression", "keyword", "i18n-keyword") - d = {"t": ("raw_data[_TITLE]", "title", - _("title", "Person")), - "f": ("raw_data[_FIRSTNAME]", "given", - _("given")), - "l": ("_raw_full_surname(raw_data[_SURNAME_LIST])", "surname", - _("surname")), - "s": ("raw_data[_SUFFIX]", "suffix", - _("suffix")), - "c": ("raw_data[_CALL]", "call", - _("call", "Name")), - "x": ("(raw_data[_NICK] or raw_data[_CALL] or raw_data[_FIRSTNAME].split(' ')[0])", - "common", - _("common", "Name")), - "i": ("''.join([word[0] +'.' for word in ('. ' +" + - " raw_data[_FIRSTNAME]).split()][1:])", - "initials", - _("initials")), - "m": ("_raw_primary_surname(raw_data[_SURNAME_LIST])", - "primary", - _("primary", "Name")), - "0m": ("_raw_primary_prefix_only(raw_data[_SURNAME_LIST])", - "primary[pre]", - _("primary[pre]")), - "1m": ("_raw_primary_surname_only(raw_data[_SURNAME_LIST])", - "primary[sur]", - _("primary[sur]")), - "2m": ("_raw_primary_conn_only(raw_data[_SURNAME_LIST])", - "primary[con]", - _("primary[con]")), - "y": ("_raw_patro_surname(raw_data[_SURNAME_LIST])", "patronymic", - _("patronymic")), - "0y": ("_raw_patro_prefix_only(raw_data[_SURNAME_LIST])", "patronymic[pre]", - _("patronymic[pre]")), - "1y": ("_raw_patro_surname_only(raw_data[_SURNAME_LIST])", "patronymic[sur]", - _("patronymic[sur]")), - "2y": ("_raw_patro_conn_only(raw_data[_SURNAME_LIST])", "patronymic[con]", - _("patronymic[con]")), - "o": ("_raw_nonpatro_surname(raw_data[_SURNAME_LIST])", "notpatronymic", - _("notpatronymic")), - "r": ("_raw_nonprimary_surname(raw_data[_SURNAME_LIST])", - "rest", - _("rest", "Remaining names")), - "p": ("_raw_prefix_surname(raw_data[_SURNAME_LIST])", - "prefix", - _("prefix")), - "q": ("_raw_single_surname(raw_data[_SURNAME_LIST])", - "rawsurnames", - _("rawsurnames")), - "n": ("raw_data[_NICK]", "nickname", - _("nickname")), - "g": ("raw_data[_FAMNICK]", "familynick", - _("familynick")), - } + d = { + "t": ("raw_data[_TITLE]", "title", _("title", "Person")), + "f": ("raw_data[_FIRSTNAME]", "given", _("given")), + "l": ( + "_raw_full_surname(raw_data[_SURNAME_LIST])", + "surname", + _("surname"), + ), + "s": ("raw_data[_SUFFIX]", "suffix", _("suffix")), + "c": ("raw_data[_CALL]", "call", _("call", "Name")), + "x": ( + "(raw_data[_NICK] or raw_data[_CALL] or raw_data[_FIRSTNAME].split(' ')[0])", + "common", + _("common", "Name"), + ), + "i": ( + "''.join([word[0] +'.' for word in ('. ' +" + + " raw_data[_FIRSTNAME]).split()][1:])", + "initials", + _("initials"), + ), + "m": ( + "_raw_primary_surname(raw_data[_SURNAME_LIST])", + "primary", + _("primary", "Name"), + ), + "0m": ( + "_raw_primary_prefix_only(raw_data[_SURNAME_LIST])", + "primary[pre]", + _("primary[pre]"), + ), + "1m": ( + "_raw_primary_surname_only(raw_data[_SURNAME_LIST])", + "primary[sur]", + _("primary[sur]"), + ), + "2m": ( + "_raw_primary_conn_only(raw_data[_SURNAME_LIST])", + "primary[con]", + _("primary[con]"), + ), + "y": ( + "_raw_patro_surname(raw_data[_SURNAME_LIST])", + "patronymic", + _("patronymic"), + ), + "0y": ( + "_raw_patro_prefix_only(raw_data[_SURNAME_LIST])", + "patronymic[pre]", + _("patronymic[pre]"), + ), + "1y": ( + "_raw_patro_surname_only(raw_data[_SURNAME_LIST])", + "patronymic[sur]", + _("patronymic[sur]"), + ), + "2y": ( + "_raw_patro_conn_only(raw_data[_SURNAME_LIST])", + "patronymic[con]", + _("patronymic[con]"), + ), + "o": ( + "_raw_nonpatro_surname(raw_data[_SURNAME_LIST])", + "notpatronymic", + _("notpatronymic"), + ), + "r": ( + "_raw_nonprimary_surname(raw_data[_SURNAME_LIST])", + "rest", + _("rest", "Remaining names"), + ), + "p": ( + "_raw_prefix_surname(raw_data[_SURNAME_LIST])", + "prefix", + _("prefix"), + ), + "q": ( + "_raw_single_surname(raw_data[_SURNAME_LIST])", + "rawsurnames", + _("rawsurnames"), + ), + "n": ("raw_data[_NICK]", "nickname", _("nickname")), + "g": ("raw_data[_FAMNICK]", "familynick", _("familynick")), + } args = "raw_data" return self._make_fn(format_str, d, args) @@ -674,58 +785,95 @@ def fn(first, raw_surname_list, suffix, title, call,): # we need the names of each of the variables or methods that are # called to fill in each format flag. # Dictionary is "code": ("expression", "keyword", "i18n-keyword") - d = {"t": ("title", "title", - _("title", "Person")), - "f": ("first", "given", - _("given")), - "l": ("_raw_full_surname(raw_surname_list)", "surname", - _("surname")), - "s": ("suffix", "suffix", - _("suffix")), - "c": ("call", "call", - _("call", "Name")), - "x": ("(nick or call or first.split(' ')[0])", "common", - _("common", "Name")), - "i": ("''.join([word[0] +'.' for word in ('. ' + first).split()][1:])", - "initials", - _("initials")), - "m": ("_raw_primary_surname(raw_surname_list)", "primary", - _("primary", "Name")), - "0m":("_raw_primary_prefix_only(raw_surname_list)", - "primary[pre]", _("primary[pre]")), - "1m":("_raw_primary_surname_only(raw_surname_list)", - "primary[sur]",_("primary[sur]")), - "2m":("_raw_primary_conn_only(raw_surname_list)", - "primary[con]", _("primary[con]")), - "y": ("_raw_patro_surname(raw_surname_list)", "patronymic", - _("patronymic")), - "0y":("_raw_patro_prefix_only(raw_surname_list)", "patronymic[pre]", - _("patronymic[pre]")), - "1y":("_raw_patro_surname_only(raw_surname_list)", "patronymic[sur]", - _("patronymic[sur]")), - "2y":("_raw_patro_conn_only(raw_surname_list)", "patronymic[con]", - _("patronymic[con]")), - "o": ("_raw_nonpatro_surname(raw_surname_list)", "notpatronymic", - _("notpatronymic")), - "r": ("_raw_nonprimary_surname(raw_surname_list)", "rest", - _("rest", "Remaining names")), - "p": ("_raw_prefix_surname(raw_surname_list)", "prefix", - _("prefix")), - "q": ("_raw_single_surname(raw_surname_list)", "rawsurnames", - _("rawsurnames")), - "n": ("nick", "nickname", - _("nickname")), - "g": ("famnick", "familynick", - _("familynick")), - } + d = { + "t": ("title", "title", _("title", "Person")), + "f": ("first", "given", _("given")), + "l": ("_raw_full_surname(raw_surname_list)", "surname", _("surname")), + "s": ("suffix", "suffix", _("suffix")), + "c": ("call", "call", _("call", "Name")), + "x": ( + "(nick or call or first.split(' ')[0])", + "common", + _("common", "Name"), + ), + "i": ( + "''.join([word[0] +'.' for word in ('. ' + first).split()][1:])", + "initials", + _("initials"), + ), + "m": ( + "_raw_primary_surname(raw_surname_list)", + "primary", + _("primary", "Name"), + ), + "0m": ( + "_raw_primary_prefix_only(raw_surname_list)", + "primary[pre]", + _("primary[pre]"), + ), + "1m": ( + "_raw_primary_surname_only(raw_surname_list)", + "primary[sur]", + _("primary[sur]"), + ), + "2m": ( + "_raw_primary_conn_only(raw_surname_list)", + "primary[con]", + _("primary[con]"), + ), + "y": ( + "_raw_patro_surname(raw_surname_list)", + "patronymic", + _("patronymic"), + ), + "0y": ( + "_raw_patro_prefix_only(raw_surname_list)", + "patronymic[pre]", + _("patronymic[pre]"), + ), + "1y": ( + "_raw_patro_surname_only(raw_surname_list)", + "patronymic[sur]", + _("patronymic[sur]"), + ), + "2y": ( + "_raw_patro_conn_only(raw_surname_list)", + "patronymic[con]", + _("patronymic[con]"), + ), + "o": ( + "_raw_nonpatro_surname(raw_surname_list)", + "notpatronymic", + _("notpatronymic"), + ), + "r": ( + "_raw_nonprimary_surname(raw_surname_list)", + "rest", + _("rest", "Remaining names"), + ), + "p": ("_raw_prefix_surname(raw_surname_list)", "prefix", _("prefix")), + "q": ( + "_raw_single_surname(raw_surname_list)", + "rawsurnames", + _("rawsurnames"), + ), + "n": ("nick", "nickname", _("nickname")), + "g": ("famnick", "familynick", _("familynick")), + } args = "first,raw_surname_list,suffix,title,call,nick,famnick" return self._make_fn(format_str, d, args) def format_str(self, name, format_str): - return self._format_str_base(name.first_name, name.surname_list, - name.suffix, name.title, - name.call, name.nick, name.famnick, - format_str) + return self._format_str_base( + name.first_name, + name.surname_list, + name.suffix, + name.title, + name.call, + name.nick, + name.famnick, + format_str, + ) def format_str_raw(self, raw_data, format_str): """ @@ -743,8 +891,9 @@ def format_str_raw(self, raw_data, format_str): return func(raw_data) - def _format_str_base(self, first, surname_list, suffix, title, call, - nick, famnick, format_str): + def _format_str_base( + self, first, surname_list, suffix, title, call, nick, famnick, format_str + ): """ Generates name from a format string. @@ -779,28 +928,46 @@ def _format_str_base(self, first, surname_list, suffix, title, call, func = self._gen_cooked_func(format_str) self.__class__.format_funcs[format_str] = func try: - s = func(first, [surn.serialize() for surn in surname_list], - suffix, title, call, nick, famnick) - except (ValueError, TypeError,): + s = func( + first, + [surn.serialize() for surn in surname_list], + suffix, + title, + call, + nick, + famnick, + ) + except ( + ValueError, + TypeError, + ): raise NameDisplayError("Incomplete format string") return s - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def primary_surname(self, name): global PAT_AS_SURN nrsur = len(name.surname_list) sur = name.get_primary_surname() - if not PAT_AS_SURN and nrsur <= 1 and \ - (sur.get_origintype().value == _ORIGINPATRO - or sur.get_origintype().value == _ORIGINMATRO): - return '' + if ( + not PAT_AS_SURN + and nrsur <= 1 + and ( + sur.get_origintype().value == _ORIGINPATRO + or sur.get_origintype().value == _ORIGINMATRO + ) + ): + return "" return sur.get_surname() def sort_string(self, name): - return "%-25s%-30s%s" % (self.primary_surname(name), - name.first_name, name.suffix) + return "%-25s%-30s%s" % ( + self.primary_surname(name), + name.first_name, + name.suffix, + ) def sorted(self, person): """ @@ -938,7 +1105,7 @@ def raw_display_name(self, raw_data): return self.name_formats[num][_F_RAWFN](raw_data) def display_given(self, person): - return self.format_str(person.get_primary_name(),'%f') + return self.format_str(person.get_primary_name(), "%f") def name_grouping(self, db, person): """ @@ -992,8 +1159,10 @@ def name_grouping_data(self, db, pn): srnme = pn[_ORIGINPATRO] surname = [] for _surname in srnme: - if (_surname[_TYPE_IN_LIST][0] == _ORIGINPATRO - or _surname[_TYPE_IN_LIST][0] == _ORIGINMATRO): + if ( + _surname[_TYPE_IN_LIST][0] == _ORIGINPATRO + or _surname[_TYPE_IN_LIST][0] == _ORIGINMATRO + ): # Yes, we have one. surname = [_surname] # name1 is the ma/patronymic name. @@ -1001,8 +1170,9 @@ def name_grouping_data(self, db, pn): if name1 and len(srnme) == 1: name = db.get_name_group_mapping(name1) if not name: - name = db.get_name_group_mapping(_raw_primary_surname_only( - pn[_SURNAME_LIST])) + name = db.get_name_group_mapping( + _raw_primary_surname_only(pn[_SURNAME_LIST]) + ) return name def _make_fn(self, format_str, d, args): @@ -1017,51 +1187,54 @@ def _make_fn(self, format_str, d, args): # %codes (ie, replace "irstnamefay" with "%f", and # "IRSTNAMEFAY" for %F) - if (len(format_str) > 2 and - format_str[0] == format_str[-1] == '"'): + if len(format_str) > 2 and format_str[0] == format_str[-1] == '"': pass else: d_keys = [(code, _tuple[2]) for code, _tuple in d.items()] - d_keys.sort(key=_make_cmp_key, reverse=True) # reverse on length and by ikeyword - for (code, ikeyword) in d_keys: + d_keys.sort( + key=_make_cmp_key, reverse=True + ) # reverse on length and by ikeyword + for code, ikeyword in d_keys: exp, keyword, ikeyword = d[code] - format_str = format_str.replace(ikeyword, "%"+ code) - format_str = format_str.replace(ikeyword.title(), "%"+ code) - format_str = format_str.replace(ikeyword.upper(), "%"+ code.upper()) + format_str = format_str.replace(ikeyword, "%" + code) + format_str = format_str.replace(ikeyword.title(), "%" + code) + format_str = format_str.replace(ikeyword.upper(), "%" + code.upper()) # Next, go through and do key-word replacement. # Just replace keywords with # %codes (ie, replace "firstname" with "%f", and # "FIRSTNAME" for %F) - if (len(format_str) > 2 and - format_str[0] == format_str[-1] == '"'): + if len(format_str) > 2 and format_str[0] == format_str[-1] == '"': pass else: d_keys = [(code, _tuple[1]) for code, _tuple in d.items()] - d_keys.sort(key=_make_cmp_key, reverse=True) # reverse sort on length and by keyword + d_keys.sort( + key=_make_cmp_key, reverse=True + ) # reverse sort on length and by keyword # if in double quotes, just use % codes - for (code, keyword) in d_keys: + for code, keyword in d_keys: exp, keyword, ikeyword = d[code] - format_str = format_str.replace(keyword, "%"+ code) - format_str = format_str.replace(keyword.title(), "%"+ code) - format_str = format_str.replace(keyword.upper(), "%"+ code.upper()) + format_str = format_str.replace(keyword, "%" + code) + format_str = format_str.replace(keyword.title(), "%" + code) + format_str = format_str.replace(keyword.upper(), "%" + code.upper()) # Get lower and upper versions of codes: codes = list(d.keys()) + [c.upper() for c in d] # Next, list out the matching patterns: # If it starts with "!" however, treat the punctuation verbatim: if len(format_str) > 0 and format_str[0] == "!": - patterns = ["%(" + ("|".join(codes)) + ")", # %s - ] + patterns = [ + "%(" + ("|".join(codes)) + ")", # %s + ] format_str = format_str[1:] else: patterns = [ - ",\\W*\"%(" + ("|".join(codes)) + ")\"", # ,\W*"%s" + ',\\W*"%(' + ("|".join(codes)) + ')"', # ,\W*"%s" ",\\W*\\(%(" + ("|".join(codes)) + ")\\)", # ,\W*(%s) - ",\\W*%(" + ("|".join(codes)) + ")", # ,\W*%s - "\"%(" + ("|".join(codes)) + ")\"", # "%s" - "_%(" + ("|".join(codes)) + ")_", # _%s_ - "\\(%(" + ("|".join(codes)) + ")\\)", # (%s) - "%(" + ("|".join(codes)) + ")", # %s - ] + ",\\W*%(" + ("|".join(codes)) + ")", # ,\W*%s + '"%(' + ("|".join(codes)) + ')"', # "%s" + "_%(" + ("|".join(codes)) + ")_", # _%s_ + "\\(%(" + ("|".join(codes)) + ")\\)", # (%s) + "%(" + ("|".join(codes)) + ")", # %s + ] new_fmt = format_str # replace the specific format string flags with a @@ -1069,12 +1242,12 @@ def _make_fn(self, format_str, d, args): new_fmt = re.sub("|".join(patterns), "%s", new_fmt) # replace special meaning codes we need to have verbatim in output - if (len(new_fmt) > 2 and new_fmt[0] == new_fmt[-1] == '"'): - new_fmt = new_fmt.replace('\\', r'\\') - new_fmt = new_fmt[1:-1].replace('"', r'\"') + if len(new_fmt) > 2 and new_fmt[0] == new_fmt[-1] == '"': + new_fmt = new_fmt.replace("\\", r"\\") + new_fmt = new_fmt[1:-1].replace('"', r"\"") else: - new_fmt = new_fmt.replace('\\', r'\\') - new_fmt = new_fmt.replace('"', '\\\"') + new_fmt = new_fmt.replace("\\", r"\\") + new_fmt = new_fmt.replace('"', '\\"') # find each format flag in the original format string # for each one we find the variable name that is needed to @@ -1086,19 +1259,19 @@ def _make_fn(self, format_str, d, args): param = () mat = pat.search(format_str) while mat: - match_pattern = mat.group(0) # the matching pattern + match_pattern = mat.group(0) # the matching pattern # prefix, code, suffix: p, code, s = re.split("%(.)", match_pattern) - if code in '0123456789': + if code in "0123456789": code = code + s[0] s = s[1:] field = d[code.lower()][0] if code.isupper(): field += ".upper()" - if p == '' and s == '': + if p == "" and s == "": param = param + (field,) else: - param = param + ("ifNotEmpty(%s,'%s','%s')" % (field, p, s), ) + param = param + ("ifNotEmpty(%s,'%s','%s')" % (field, p, s),) mat = pat.search(format_str, mat.end()) s = """ def fn(%s): @@ -1107,18 +1280,30 @@ def ifNotEmpty(str,p,s): return '' else: return p + str + s - return cleanup_name("%s" %% (%s))""" % (args, new_fmt, ",".join(param)) + return cleanup_name("%s" %% (%s))""" % ( + args, + new_fmt, + ",".join(param), + ) try: exec(s) in globals(), locals() - return locals()['fn'] + return locals()["fn"] except: - LOG.error("\n" + 'Wrong name format string %s' % new_fmt - +"\n" + ("ERROR, Edit Name format in Preferences->Display to correct") - +"\n" + _('Wrong name format string %s') % new_fmt - +"\n" + ("ERROR, Edit Name format in Preferences->Display to correct") - ) + LOG.error( + "\n" + + "Wrong name format string %s" % new_fmt + + "\n" + + ("ERROR, Edit Name format in Preferences->Display to correct") + + "\n" + + _("Wrong name format string %s") % new_fmt + + "\n" + + ("ERROR, Edit Name format in Preferences->Display to correct") + ) + def errfn(*arg): return _("ERROR, Edit Name format in Preferences") + return errfn + displayer = NameDisplay() diff --git a/gramps/gen/display/place.py b/gramps/gen/display/place.py index 5bb1c204c54..8a44270968c 100644 --- a/gramps/gen/display/place.py +++ b/gramps/gen/display/place.py @@ -22,30 +22,32 @@ Class handling displaying of places. """ -#--------------------------------------------------------------- +# --------------------------------------------------------------- # # Python imports # -#--------------------------------------------------------------- +# --------------------------------------------------------------- import os import xml.dom.minidom -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..const import PLACE_FORMATS, GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext from ..config import config from ..utils.location import get_location_list from ..lib import PlaceType -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # PlaceFormat class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PlaceFormat: def __init__(self, name, levels, language, street, reverse): self.name = name @@ -55,23 +57,22 @@ def __init__(self, name, levels, language, street, reverse): self.reverse = reverse -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # PlaceDisplay class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PlaceDisplay: - def __init__(self): self.place_formats = [] - self.default_format = config.get('preferences.place-format') + self.default_format = config.get("preferences.place-format") if os.path.exists(PLACE_FORMATS): try: self.load_formats() return except BaseException: print(_("Error in '%s' file: cannot load.") % PLACE_FORMATS) - pf = PlaceFormat(_('Full'), ':', '', 0, False) + pf = PlaceFormat(_("Full"), ":", "", 0, False) self.place_formats.append(pf) def display_event(self, db, event, fmt=-1): @@ -87,11 +88,11 @@ def display_event(self, db, event, fmt=-1): def display(self, db, place, date=None, fmt=-1): if not place: return "" - if not config.get('preferences.place-auto'): + if not config.get("preferences.place-auto"): return place.title else: if fmt == -1: - fmt = config.get('preferences.place-format') + fmt = config.get("preferences.place-format") pf = self.place_formats[fmt] lang = pf.language all_places = get_location_list(db, place, date, lang) @@ -99,8 +100,8 @@ def display(self, db, place, date=None, fmt=-1): # Apply format string to place list index = _find_populated_place(all_places) places = [] - for slice in pf.levels.split(','): - parts = slice.split(':') + for slice in pf.levels.split(","): + parts = slice.split(":") if len(parts) == 1: offset = _get_offset(parts[0], index) if offset is not None: @@ -124,14 +125,18 @@ def display(self, db, place, date=None, fmt=-1): idx = types.index(PlaceType.NUMBER) except ValueError: idx = None - if idx is not None and len(places) > idx+1: + if idx is not None and len(places) > idx + 1: if pf.street == 1: - combined = (places[idx][0] + ' ' + places[idx+1][0], - places[idx+1][1]) + combined = ( + places[idx][0] + " " + places[idx + 1][0], + places[idx + 1][1], + ) else: - combined = (places[idx+1][0] + ' ' + places[idx][0], - places[idx+1][1]) - places = places[:idx] + [combined] + places[idx+2:] + combined = ( + places[idx + 1][0] + " " + places[idx][0], + places[idx + 1][1], + ) + places = places[:idx] + [combined] + places[idx + 2 :] names = [item[0] for item in places] if pf.reverse: @@ -148,14 +153,14 @@ def set_formats(self, formats): def load_formats(self): dom = xml.dom.minidom.parse(PLACE_FORMATS) - top = dom.getElementsByTagName('place_formats') - - for fmt in top[0].getElementsByTagName('format'): - name = fmt.attributes['name'].value - levels = fmt.attributes['levels'].value - language = fmt.attributes['language'].value - street = int(fmt.attributes['street'].value) - reverse = fmt.attributes['reverse'].value == 'True' + top = dom.getElementsByTagName("place_formats") + + for fmt in top[0].getElementsByTagName("format"): + name = fmt.attributes["name"].value + levels = fmt.attributes["levels"].value + language = fmt.attributes["language"].value + street = int(fmt.attributes["street"].value) + reverse = fmt.attributes["reverse"].value == "True" pf = PlaceFormat(name, levels, language, street, reverse) self.place_formats.append(pf) @@ -163,22 +168,22 @@ def load_formats(self): def save_formats(self): doc = xml.dom.minidom.Document() - place_formats = doc.createElement('place_formats') + place_formats = doc.createElement("place_formats") doc.appendChild(place_formats) for fmt in self.place_formats: - node = doc.createElement('format') + node = doc.createElement("format") place_formats.appendChild(node) - node.setAttribute('name', fmt.name) - node.setAttribute('levels', fmt.levels) - node.setAttribute('language', fmt.language) - node.setAttribute('street', str(fmt.street)) - node.setAttribute('reverse', str(fmt.reverse)) - with open(PLACE_FORMATS, 'w', encoding='utf-8') as f_d: - doc.writexml(f_d, addindent=' ', newl='\n', encoding='utf-8') + node.setAttribute("name", fmt.name) + node.setAttribute("levels", fmt.levels) + node.setAttribute("language", fmt.language) + node.setAttribute("street", str(fmt.street)) + node.setAttribute("reverse", str(fmt.reverse)) + with open(PLACE_FORMATS, "w", encoding="utf-8") as f_d: + doc.writexml(f_d, addindent=" ", newl="\n", encoding="utf-8") def _get_offset(value, index): - if index is not None and value.startswith('p'): + if index is not None and value.startswith("p"): try: offset = int(value[1:]) except ValueError: @@ -191,12 +196,18 @@ def _get_offset(value, index): offset = None return offset + def _find_populated_place(places): populated_place = None for index, item in enumerate(places): - if int(item[1]) in [PlaceType.HAMLET, PlaceType.VILLAGE, - PlaceType.TOWN, PlaceType.CITY]: + if int(item[1]) in [ + PlaceType.HAMLET, + PlaceType.VILLAGE, + PlaceType.TOWN, + PlaceType.CITY, + ]: populated_place = index return populated_place + displayer = PlaceDisplay() diff --git a/gramps/gen/display/test/name_test.py b/gramps/gen/display/test/name_test.py index ef1480abc92..07a0a1b66f2 100644 --- a/gramps/gen/display/test/name_test.py +++ b/gramps/gen/display/test/name_test.py @@ -25,185 +25,231 @@ class NameTest(unittest.TestCase): - def setUp(self): self.name_display = NameDisplay() def test_get_name_format_for_all_without_default_format(self): - self.add_custom_name_format('Surname, Name|Common Suffix') - self.add_inactive_custom_name_format('SURNAME, Given Suffix (Call)') + self.add_custom_name_format("Surname, Name|Common Suffix") + self.add_inactive_custom_name_format("SURNAME, Given Suffix (Call)") - actual_name_format = self.name_display.get_name_format(also_default=False, only_custom=False, only_active=False) + actual_name_format = self.name_display.get_name_format( + also_default=False, only_custom=False, only_active=False + ) expected_name_format = [ - (1, 'Surname, Given Suffix', '%l, %f %s', True), - (2, 'Given Surname Suffix', '%f %l %s', True), - (3, 'Patronymic, Given', '%y, %s %f', False), - (4, 'Given', '%f', True), - (5, 'Main Surnames, Given Patronymic Suffix Prefix', '%1m %2m %o, %f %1y %s %0m', True), - (-2, 'SURNAME, Given Suffix (Call)', 'SURNAME, Given Suffix (Call)', False), - (-1, 'Surname, Name|Common Suffix', 'Surname, Name|Common Suffix', True) + (1, "Surname, Given Suffix", "%l, %f %s", True), + (2, "Given Surname Suffix", "%f %l %s", True), + (3, "Patronymic, Given", "%y, %s %f", False), + (4, "Given", "%f", True), + ( + 5, + "Main Surnames, Given Patronymic Suffix Prefix", + "%1m %2m %o, %f %1y %s %0m", + True, + ), + (-2, "SURNAME, Given Suffix (Call)", "SURNAME, Given Suffix (Call)", False), + (-1, "Surname, Name|Common Suffix", "Surname, Name|Common Suffix", True), ] self.assertEqual(expected_name_format, actual_name_format) def test_get_name_format_for_all_active_without_default_format(self): + self.add_custom_name_format("Surname, Name|Common Suffix") + self.add_inactive_custom_name_format("SURNAME, Given Suffix (Call)") - self.add_custom_name_format('Surname, Name|Common Suffix') - self.add_inactive_custom_name_format('SURNAME, Given Suffix (Call)') - - actual_name_format = self.name_display.get_name_format(also_default=False, only_custom=False, only_active=True) + actual_name_format = self.name_display.get_name_format( + also_default=False, only_custom=False, only_active=True + ) expected_name_format = [ - (1, 'Surname, Given Suffix', '%l, %f %s', True), - (2, 'Given Surname Suffix', '%f %l %s', True), - (4, 'Given', '%f', True), - (5, 'Main Surnames, Given Patronymic Suffix Prefix', '%1m %2m %o, %f %1y %s %0m', True), - (-1, 'Surname, Name|Common Suffix', 'Surname, Name|Common Suffix', True) + (1, "Surname, Given Suffix", "%l, %f %s", True), + (2, "Given Surname Suffix", "%f %l %s", True), + (4, "Given", "%f", True), + ( + 5, + "Main Surnames, Given Patronymic Suffix Prefix", + "%1m %2m %o, %f %1y %s %0m", + True, + ), + (-1, "Surname, Name|Common Suffix", "Surname, Name|Common Suffix", True), ] self.assertEqual(expected_name_format, actual_name_format) def test_get_name_format_for_all_custom_formats_without_default_format(self): + self.add_custom_name_format("Surname, Name|Common Suffix") + self.add_inactive_custom_name_format("SURNAME, Given Suffix (Call)") - self.add_custom_name_format('Surname, Name|Common Suffix') - self.add_inactive_custom_name_format('SURNAME, Given Suffix (Call)') - - actual_name_format = self.name_display.get_name_format(also_default=False, only_custom=True, only_active=False) + actual_name_format = self.name_display.get_name_format( + also_default=False, only_custom=True, only_active=False + ) expected_name_format = [ - (-2, 'SURNAME, Given Suffix (Call)', 'SURNAME, Given Suffix (Call)', False), - (-1, 'Surname, Name|Common Suffix', 'Surname, Name|Common Suffix', True) + (-2, "SURNAME, Given Suffix (Call)", "SURNAME, Given Suffix (Call)", False), + (-1, "Surname, Name|Common Suffix", "Surname, Name|Common Suffix", True), ] self.assertEqual(expected_name_format, actual_name_format) def test_get_name_format_for_active_custom_formats_without_default_format(self): - self.add_custom_name_format('Surname, Name|Common Suffix') - self.add_inactive_custom_name_format('SURNAME, Given Suffix (Call)') + self.add_custom_name_format("Surname, Name|Common Suffix") + self.add_inactive_custom_name_format("SURNAME, Given Suffix (Call)") - actual_name_format = self.name_display.get_name_format(also_default=False, only_custom=True, only_active=True) + actual_name_format = self.name_display.get_name_format( + also_default=False, only_custom=True, only_active=True + ) expected_name_format = [ - (-1, 'Surname, Name|Common Suffix', 'Surname, Name|Common Suffix', True) + (-1, "Surname, Name|Common Suffix", "Surname, Name|Common Suffix", True) ] self.assertEqual(expected_name_format, actual_name_format) def test_get_name_format_for_all(self): - self.add_custom_name_format('Surname, Name|Common Suffix') - self.add_inactive_custom_name_format('SURNAME, Given Suffix (Call)') + self.add_custom_name_format("Surname, Name|Common Suffix") + self.add_inactive_custom_name_format("SURNAME, Given Suffix (Call)") - actual_name_format = self.name_display.get_name_format(also_default=True, only_custom=False, only_active=False) + actual_name_format = self.name_display.get_name_format( + also_default=True, only_custom=False, only_active=False + ) expected_name_format = [ - (0, 'Default format (defined by Gramps preferences)', '', True), - (1, 'Surname, Given Suffix', '%l, %f %s', True), - (2, 'Given Surname Suffix', '%f %l %s', True), - (3, 'Patronymic, Given', '%y, %s %f', False), - (4, 'Given', '%f', True), - (5, 'Main Surnames, Given Patronymic Suffix Prefix', '%1m %2m %o, %f %1y %s %0m', True), - (-2, 'SURNAME, Given Suffix (Call)', 'SURNAME, Given Suffix (Call)', False), - (-1, 'Surname, Name|Common Suffix', 'Surname, Name|Common Suffix', True) + (0, "Default format (defined by Gramps preferences)", "", True), + (1, "Surname, Given Suffix", "%l, %f %s", True), + (2, "Given Surname Suffix", "%f %l %s", True), + (3, "Patronymic, Given", "%y, %s %f", False), + (4, "Given", "%f", True), + ( + 5, + "Main Surnames, Given Patronymic Suffix Prefix", + "%1m %2m %o, %f %1y %s %0m", + True, + ), + (-2, "SURNAME, Given Suffix (Call)", "SURNAME, Given Suffix (Call)", False), + (-1, "Surname, Name|Common Suffix", "Surname, Name|Common Suffix", True), ] self.assertEqual(expected_name_format, actual_name_format) def test_get_name_format_for_all_active(self): - self.add_custom_name_format('Surname, Name|Common Suffix') - self.add_inactive_custom_name_format('SURNAME, Given Suffix (Call)') + self.add_custom_name_format("Surname, Name|Common Suffix") + self.add_inactive_custom_name_format("SURNAME, Given Suffix (Call)") - actual_name_format = self.name_display.get_name_format(also_default=True, only_custom=False, only_active=True) + actual_name_format = self.name_display.get_name_format( + also_default=True, only_custom=False, only_active=True + ) expected_name_format = [ - (0, 'Default format (defined by Gramps preferences)', '', True), - (1, 'Surname, Given Suffix', '%l, %f %s', True), - (2, 'Given Surname Suffix', '%f %l %s', True), - (4, 'Given', '%f', True), - (5, 'Main Surnames, Given Patronymic Suffix Prefix', '%1m %2m %o, %f %1y %s %0m', True), - (-1, 'Surname, Name|Common Suffix', 'Surname, Name|Common Suffix', True) + (0, "Default format (defined by Gramps preferences)", "", True), + (1, "Surname, Given Suffix", "%l, %f %s", True), + (2, "Given Surname Suffix", "%f %l %s", True), + (4, "Given", "%f", True), + ( + 5, + "Main Surnames, Given Patronymic Suffix Prefix", + "%1m %2m %o, %f %1y %s %0m", + True, + ), + (-1, "Surname, Name|Common Suffix", "Surname, Name|Common Suffix", True), ] self.assertEqual(expected_name_format, actual_name_format) def test_get_name_format_for_all_custom_formats(self): - self.add_custom_name_format('Surname, Name|Common Suffix') - self.add_inactive_custom_name_format('SURNAME, Given Suffix (Call)') + self.add_custom_name_format("Surname, Name|Common Suffix") + self.add_inactive_custom_name_format("SURNAME, Given Suffix (Call)") - actual_name_format = self.name_display.get_name_format(also_default=True, only_custom=True, only_active=False) + actual_name_format = self.name_display.get_name_format( + also_default=True, only_custom=True, only_active=False + ) expected_name_format = [ - (-2, 'SURNAME, Given Suffix (Call)', 'SURNAME, Given Suffix (Call)', False), - (-1, 'Surname, Name|Common Suffix', 'Surname, Name|Common Suffix', True) + (-2, "SURNAME, Given Suffix (Call)", "SURNAME, Given Suffix (Call)", False), + (-1, "Surname, Name|Common Suffix", "Surname, Name|Common Suffix", True), ] self.assertEqual(expected_name_format, actual_name_format) def test_get_name_format_for_active_custom_formats(self): - self.add_custom_name_format('Surname, Name|Common Suffix') - self.add_inactive_custom_name_format('SURNAME, Given Suffix (Call)') + self.add_custom_name_format("Surname, Name|Common Suffix") + self.add_inactive_custom_name_format("SURNAME, Given Suffix (Call)") - actual_name_format = self.name_display.get_name_format(also_default=True, only_custom=True, only_active=True) + actual_name_format = self.name_display.get_name_format( + also_default=True, only_custom=True, only_active=True + ) expected_name_format = [ - (-1, 'Surname, Name|Common Suffix', 'Surname, Name|Common Suffix', True) + (-1, "Surname, Name|Common Suffix", "Surname, Name|Common Suffix", True) ] self.assertEqual(expected_name_format, actual_name_format) def test_clear_custom_formats(self): - self.add_custom_name_format('Surname, Name|Common Suffix') - self.add_inactive_custom_name_format('SURNAME, Given Suffix (Call)') + self.add_custom_name_format("Surname, Name|Common Suffix") + self.add_inactive_custom_name_format("SURNAME, Given Suffix (Call)") self.name_display.clear_custom_formats() - actual_name_format = self.name_display.get_name_format(also_default=False, only_custom=True, only_active=False) + actual_name_format = self.name_display.get_name_format( + also_default=False, only_custom=True, only_active=False + ) self.assertEqual([], actual_name_format) def test_do_not_clear_default_formats(self): - self.add_custom_name_format('Surname, Name|Common Suffix') - self.add_inactive_custom_name_format('SURNAME, Given Suffix (Call)') + self.add_custom_name_format("Surname, Name|Common Suffix") + self.add_inactive_custom_name_format("SURNAME, Given Suffix (Call)") self.name_display.clear_custom_formats() - actual_name_format = self.name_display.get_name_format(also_default=True, only_custom=False, only_active=False) + actual_name_format = self.name_display.get_name_format( + also_default=True, only_custom=False, only_active=False + ) expected_name_format = [ - (0, 'Default format (defined by Gramps preferences)', '', True), - (1, 'Surname, Given Suffix', '%l, %f %s', True), - (2, 'Given Surname Suffix', '%f %l %s', True), - (3, 'Patronymic, Given', '%y, %s %f', False), - (4, 'Given', '%f', True), - (5, 'Main Surnames, Given Patronymic Suffix Prefix', '%1m %2m %o, %f %1y %s %0m', True), + (0, "Default format (defined by Gramps preferences)", "", True), + (1, "Surname, Given Suffix", "%l, %f %s", True), + (2, "Given Surname Suffix", "%f %l %s", True), + (3, "Patronymic, Given", "%y, %s %f", False), + (4, "Given", "%f", True), + ( + 5, + "Main Surnames, Given Patronymic Suffix Prefix", + "%1m %2m %o, %f %1y %s %0m", + True, + ), ] self.assertEqual(expected_name_format, actual_name_format) def test_set_name_format(self): standard_formats_overrides = [ - (0, "Default", '', True), - (1, "Surname", '%l', True), - (2, "Suffix", '%s', True), - (3, "Given", '%s', False), - (4, "Patronymic", '%y', True), - (5, "Prefix", '%0m', True), + (0, "Default", "", True), + (1, "Surname", "%l", True), + (2, "Suffix", "%s", True), + (3, "Given", "%s", False), + (4, "Patronymic", "%y", True), + (5, "Prefix", "%0m", True), ] self.name_display.set_name_format(standard_formats_overrides) - actual_name_format = self.name_display.get_name_format(also_default=True, only_custom=False, only_active=False) + actual_name_format = self.name_display.get_name_format( + also_default=True, only_custom=False, only_active=False + ) self.assertEqual(standard_formats_overrides, actual_name_format) def test_add_existing_name_format(self): self.assertEqual( - self.add_custom_name_format('Surname, Name|Common Suffix'), - self.add_custom_name_format('Surname, Name|Common Suffix') + self.add_custom_name_format("Surname, Name|Common Suffix"), + self.add_custom_name_format("Surname, Name|Common Suffix"), ) def test_delete_name_format(self): - index = self.add_custom_name_format('Surname, Name|Common Suffix') + index = self.add_custom_name_format("Surname, Name|Common Suffix") self.name_display.del_name_format(index) - actual_name_format = self.name_display.get_name_format(also_default=True, only_custom=True, only_active=True) + actual_name_format = self.name_display.get_name_format( + also_default=True, only_custom=True, only_active=True + ) self.assertEqual([], actual_name_format) def test_set_default_format_to_custom_format(self): - index = self.add_custom_name_format('Surname, Name|Common Suffix') + index = self.add_custom_name_format("Surname, Name|Common Suffix") self.name_display.set_default_format(index) self.assertEqual(index, self.name_display.get_default_format()) @@ -214,26 +260,26 @@ def test_set_default_format_to_non_existing_format(self): def test_display_name_with_valid_format(self): name = Name() - name.set_first_name('William') - name.set_call_name('Will') + name.set_first_name("William") + name.set_call_name("Will") name.set_display_as(4) actual_display_name = self.name_display.display_name(name) - self.assertEqual('William', actual_display_name) + self.assertEqual("William", actual_display_name) def test_display_name_with_invalid_format(self): name = Name() - name.set_first_name('William') - name.set_call_name('Will') + name.set_first_name("William") + name.set_call_name("Will") name.set_display_as(-100) display_name = self.name_display.display_name(name) - self.assertEqual(', William', display_name) + self.assertEqual(", William", display_name) def test_display_no_name(self): - self.assertEqual('', self.name_display.display_name(None)) + self.assertEqual("", self.name_display.display_name(None)) def add_custom_name_format(self, name_format): return self.name_display.add_name_format(name_format, name_format) @@ -243,5 +289,5 @@ def add_inactive_custom_name_format(self, name_format): self.name_display.set_format_inactive(index) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/gramps/gen/errors.py b/gramps/gen/errors.py index 7816e33945e..0eea8bf6834 100644 --- a/gramps/gen/errors.py +++ b/gramps/gen/errors.py @@ -22,8 +22,10 @@ Provide Error objects """ + class FilterError(Exception): """Error used to report Filter errors""" + def __init__(self, value, value2=""): Exception.__init__(self) self.value = value @@ -37,12 +39,14 @@ def messages(self): "Return the messages" return (self.value, self.value2) + class DateError(Exception): """Error used to report Date errors Might have a .date attribute holding an invalid Date object that triggered the error. """ + def __init__(self, value=""): Exception.__init__(self) self.value = value @@ -51,8 +55,10 @@ def __str__(self): "Return string representation" return self.value + class DatabaseError(Exception): """Error used to report database errors""" + def __init__(self, value=""): Exception.__init__(self) self.value = value @@ -61,8 +67,10 @@ def __str__(self): "Return string representation" return self.value + class ReportError(Exception): """Error used to report Report errors.""" + def __init__(self, value, value2=""): Exception.__init__(self) self.value = value @@ -76,8 +84,10 @@ def messages(self): "Return the messages" return (self.value, self.value2) + class GedcomError(Exception): """Error used to report GEDCOM errors""" + def __init__(self, value): Exception.__init__(self) self.value = value @@ -86,8 +96,10 @@ def __str__(self): "Return string representation" return self.value + class GrampsImportError(Exception): """Error used to report mistakes during import of files into Gramps""" + def __init__(self, value, value2=""): Exception.__init__(self) self.value = value @@ -101,8 +113,10 @@ def messages(self): "Return the messages" return (self.value, self.value2) + class PluginError(Exception): """Error used to report plugin errors""" + def __init__(self, value): Exception.__init__(self) self.value = value @@ -111,8 +125,10 @@ def __str__(self): "Return string representation" return self.value + class HandleError(Exception): """Error used to report wrong database handle errors""" + def __init__(self, value): Exception.__init__(self) self.value = value @@ -121,8 +137,10 @@ def __str__(self): "Return string representation" return self.value + class WindowActiveError(Exception): """Error used to report that the request window is already displayed.""" + def __init__(self, value): Exception.__init__(self) self.value = value @@ -131,6 +149,7 @@ def __str__(self): "Return string representation" return self.value + class UnavailableError(Exception): def __init__(self, value): Exception.__init__(self) @@ -140,14 +159,18 @@ def __str__(self): "Return string representation" return self.value + class MaskError(Exception): pass + class ValidationError(Exception): pass + class DbError(Exception): """Error used to report BerkeleyDB errors.""" + def __init__(self, value): Exception.__init__(self) try: @@ -160,8 +183,10 @@ def __str__(self): "Return string representation" return self.value + class MergeError(Exception): """Error used to report merge errors""" + def __init__(self, value=""): Exception.__init__(self) self.value = value diff --git a/gramps/gen/filters/__init__.py b/gramps/gen/filters/__init__.py index 7c39072b90c..b54e9d07e5e 100644 --- a/gramps/gen/filters/__init__.py +++ b/gramps/gen/filters/__init__.py @@ -26,15 +26,21 @@ from ..const import CUSTOM_FILTERS from ._filterlist import FilterList -from ._genericfilter import (GenericFilter, GenericFilterFactory, - DeferredFilter, DeferredFamilyFilter) +from ._genericfilter import ( + GenericFilter, + GenericFilterFactory, + DeferredFilter, + DeferredFamilyFilter, +) from ._paramfilter import ParamFilter from ._searchfilter import SearchFilter, ExactSearchFilter + def reload_custom_filters(): global CustomFilters CustomFilters = FilterList(CUSTOM_FILTERS) CustomFilters.load() + # if not CustomFilters: # moved to viewmanager - # reload_custom_filters() +# reload_custom_filters() diff --git a/gramps/gen/filters/_filterlist.py b/gramps/gen/filters/_filterlist.py index 881b18bf20a..fc91ac6a6e3 100644 --- a/gramps/gen/filters/_filterlist.py +++ b/gramps/gen/filters/_filterlist.py @@ -20,30 +20,32 @@ """ Container class for managing the generic filters """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from xml.sax import make_parser, SAXParseException import os from collections import abc -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ._filterparser import FilterParser from ..plug import BasePluginManager from ..const import GRAMPS_LOCALE as glocale PLUGMAN = BasePluginManager.get_instance() -#------------------------------------------------------------------------- + + +# ------------------------------------------------------------------------- # # FilterList # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class FilterList: """ Container class for managing the generic filters. @@ -55,17 +57,16 @@ def __init__(self, file): self.file = os.path.expanduser(file) self._cached = {} - def get_filters_dict(self, namespace='generic'): + def get_filters_dict(self, namespace="generic"): """ This runs every for every item to be matched! """ if self._cached.get(namespace, None) is None: filters = self.get_filters(namespace) - self._cached[namespace] = dict([(filt.name, filt) for filt - in filters]) + self._cached[namespace] = dict([(filt.name, filt) for filt in filters]) return self._cached[namespace] - def get_filters(self, namespace='generic'): + def get_filters(self, namespace="generic"): """ This runs every for every item to be matched! """ @@ -73,7 +74,7 @@ def get_filters(self, namespace='generic'): filters = self.filter_namespaces[namespace] else: filters = [] - plugins = PLUGMAN.process_plugin_data('Filters') + plugins = PLUGMAN.process_plugin_data("Filters") if plugins: plugin_filters = [] try: @@ -88,12 +89,13 @@ def get_filters(self, namespace='generic'): plugin_filters.append(plug) except: import traceback + traceback.print_exc() filters += plugin_filters return filters def add(self, namespace, filt): - """ add a custom filter """ + """add a custom filter""" assert isinstance(namespace, str) if namespace not in self.filter_namespaces: @@ -101,12 +103,12 @@ def add(self, namespace, filt): self.filter_namespaces[namespace].append(filt) def load(self): - """ load a custom filter """ + """load a custom filter""" try: if os.path.isfile(self.file): parser = make_parser() parser.setContentHandler(FilterParser(self)) - with open(self.file, 'r', encoding='utf8') as the_file: + with open(self.file, "r", encoding="utf8") as the_file: parser.parse(the_file) except (IOError, OSError): print("IO/OSError in _filterlist.py") @@ -114,25 +116,26 @@ def load(self): print("Parser error") def fix(self, line): - """ sanitize the custom filter name, if needed """ + """sanitize the custom filter name, if needed""" new_line = line.strip() - new_line = new_line.replace('&', '&') - new_line = new_line.replace('>', '>') - new_line = new_line.replace('<', '<') - return new_line.replace('"', '"') + new_line = new_line.replace("&", "&") + new_line = new_line.replace(">", ">") + new_line = new_line.replace("<", "<") + return new_line.replace('"', """) def save(self): - """ save the list of custom filters """ - with open(self.file, 'w', encoding='utf8') as file: - file.write("\n") - file.write('\n') + """save the list of custom filters""" + with open(self.file, "w", encoding="utf8") as file: + file.write('\n') + file.write("\n") for namespace in self.filter_namespaces: file.write(' \n' % namespace) filter_list = self.filter_namespaces[namespace] - sorted_filters = sorted([(filter.get_name(), filter) - for filter in filter_list], - key=lambda x: glocale.sort_key(x[0])) - for (name, the_filter) in sorted_filters: # enable a diff + sorted_filters = sorted( + [(filter.get_name(), filter) for filter in filter_list], + key=lambda x: glocale.sort_key(x[0]), + ) + for name, the_filter in sorted_filters: # enable a diff file.write(' \n') + file.write(">\n") for rule in the_filter.get_rules(): - file.write(' ' - '\n' % (rule.__class__.__name__, - rule.use_regex, rule.use_case)) + file.write( + ' ' + "\n" + % (rule.__class__.__name__, rule.use_regex, rule.use_case) + ) for value in list(rule.values()): - file.write(' ' - '\n' % self.fix(value)) - file.write(' \n') - file.write(' \n') - file.write(' \n') - file.write('\n') + file.write( + ' ' "\n" % self.fix(value) + ) + file.write(" \n") + file.write(" \n") + file.write(" \n") + file.write("\n") diff --git a/gramps/gen/filters/_filterparser.py b/gramps/gen/filters/_filterparser.py index bd4d0cc505a..30bf16e98e0 100644 --- a/gramps/gen/filters/_filterparser.py +++ b/gramps/gen/filters/_filterparser.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from xml.sax import handler from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ._genericfilter import GenericFilterFactory from . import rules -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # FilterParser # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class FilterParser(handler.ContentHandler): """Parses the XML file and builds the list of filters""" @@ -50,7 +52,7 @@ def __init__(self, gfilter_list): self.r = None self.a = [] self.cname = None - self.namespace = 'Person' + self.namespace = "Person" self.use_regex = False self.use_case = False @@ -59,86 +61,101 @@ def setDocumentLocator(self, locator): def startElement(self, tag, attrs): if tag == "object": - if 'type' in attrs: - self.namespace = attrs['type'] + if "type" in attrs: + self.namespace = attrs["type"] else: self.namespace = "generic" - if self.namespace == 'MediaObject': + if self.namespace == "MediaObject": # deals with older custom filters - self.namespace = 'Media' + self.namespace = "Media" elif tag == "filter": self.f = GenericFilterFactory(self.namespace)() - self.f.set_name(attrs['name']) - if 'function' in attrs: + self.f.set_name(attrs["name"]) + if "function" in attrs: try: - if int(attrs['function']): - op = 'or' + if int(attrs["function"]): + op = "or" else: - op = 'and' + op = "and" except ValueError: - op = attrs['function'] + op = attrs["function"] self.f.set_logical_op(op) - if 'invert' in attrs: - self.f.set_invert(attrs['invert']) - if 'comment' in attrs: - self.f.set_comment(attrs['comment']) + if "invert" in attrs: + self.f.set_invert(attrs["invert"]) + if "comment" in attrs: + self.f.set_comment(attrs["comment"]) self.gfilter_list.add(self.namespace, self.f) elif tag == "rule": - if 'use_regex' in attrs: - self.use_regex = attrs['use_regex'] == 'True' + if "use_regex" in attrs: + self.use_regex = attrs["use_regex"] == "True" else: self.use_regex = False - if 'use_case' in attrs: - self.use_case = attrs['use_case'] == 'True' + if "use_case" in attrs: + self.use_case = attrs["use_case"] == "True" else: self.use_case = False - save_name = attrs['class'] + save_name = attrs["class"] if save_name in old_names_2_class: self.r = old_names_2_class[save_name] else: try: # First try to use fully qualified name - exec('self.r = %s' % save_name) - except (ImportError, NameError, AttributeError ): + exec("self.r = %s" % save_name) + except (ImportError, NameError, AttributeError): # Now try to use name from rules.namespace - mc_match = save_name.split('.') + mc_match = save_name.split(".") last_name = mc_match[-1] try: - exec('self.r = rules.%s.%s' % ( - self.namespace.lower(), last_name)) - except (ImportError, NameError, AttributeError ): - print("ERROR: Filter rule '%s' in "\ - "filter '%s' not found!"\ - % (save_name, self.f.get_name())) + exec( + "self.r = rules.%s.%s" % (self.namespace.lower(), last_name) + ) + except (ImportError, NameError, AttributeError): + print( + "ERROR: Filter rule '%s' in " + "filter '%s' not found!" % (save_name, self.f.get_name()) + ) self.r = None return self.a = [] elif tag == "arg": - self.a.append(attrs['value']) + self.a.append(attrs["value"]) def endElement(self, tag): if tag == "rule" and self.r is not None: if len(self.r.labels) != len(self.a): self.__upgrade() if len(self.r.labels) < len(self.a): - print(_("WARNING: Too many arguments in filter '%s'!\n"\ - "Trying to load with subset of arguments.") %\ - self.f.get_name()) + print( + _( + "WARNING: Too many arguments in filter '%s'!\n" + "Trying to load with subset of arguments." + ) + % self.f.get_name() + ) nargs = len(self.r.labels) rule = self.r(self.a[0:nargs], self.use_regex, self.use_case) self.f.add_rule(rule) else: if len(self.r.labels) > len(self.a): - print(_("WARNING: Too few arguments in filter '%s'!\n" \ - " Trying to load anyway in the hope this "\ - "will be upgraded.") %\ - self.f.get_name()) + print( + _( + "WARNING: Too few arguments in filter '%s'!\n" + " Trying to load anyway in the hope this " + "will be upgraded." + ) + % self.f.get_name() + ) try: rule = self.r(self.a, self.use_regex, self.use_case) except AssertionError as msg: print(msg) - print(_("ERROR: filter %s could not be correctly loaded. " - "Edit the filter!") % self.f.get_name()) + print( + _( + "ERROR: filter %s could not be correctly loaded. " + "Edit the filter!" + ) + % self.f.get_name() + ) return self.f.add_rule(rule) @@ -152,94 +169,98 @@ def __upgrade(self): """ # HasPlace rule has extra locality field in v3.3 if self.r == rules.place.HasPlace and len(self.a) == 8: - self.a = self.a[0:2] + [''] + self.a[4:8] + [self.a[3]] + \ - [self.a[2]] + self.a = self.a[0:2] + [""] + self.a[4:8] + [self.a[3]] + [self.a[2]] # HasNameOf rule has new fields for surnames in v3.3 if self.r == rules.person.HasNameOf and len(self.a) == 7: - self.a = self.a[0:2] + [self.a[3]] + [self.a[2]] + [self.a[6]] + \ - [''] + [self.a[4]] + ['', ''] + [self.a[5]] + \ - ['', '0'] + self.a = ( + self.a[0:2] + + [self.a[3]] + + [self.a[2]] + + [self.a[6]] + + [""] + + [self.a[4]] + + ["", ""] + + [self.a[5]] + + ["", "0"] + ) # New regular expression code in v3.4 - if (self.r in (rules.person.HasNameOf, - rules.family.FatherHasNameOf, - rules.family.MotherHasNameOf, - rules.family.ChildHasNameOf) - and len(self.a) == 12): - self.use_regex = self.a[11] == '1' + if ( + self.r + in ( + rules.person.HasNameOf, + rules.family.FatherHasNameOf, + rules.family.MotherHasNameOf, + rules.family.ChildHasNameOf, + ) + and len(self.a) == 12 + ): + self.use_regex = self.a[11] == "1" self.a = self.a[:11] - if (self.r == rules.person.HasTextMatchingSubstringOf - and len(self.a) == 3): - self.use_regex = self.a[2] == '1' + if self.r == rules.person.HasTextMatchingSubstringOf and len(self.a) == 3: + self.use_regex = self.a[2] == "1" self.a = self.a[:2] # HasEvent rule has extra primary role field in v3.4.7 if self.r == rules.person.HasEvent and len(self.a) == 5: - self.a.append('1') + self.a.append("1") # IsEnclosedBy rule has extra inclusive field in v4.2.4 if self.r == rules.place.IsEnclosedBy and len(self.a) == 1: - self.a.append('0') + self.a.append("0") + -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Name to class mappings # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # This dict is mapping from old names to new names, so that the existing # custom_filters.xml will continue working old_names_2_class = { - "Everyone" : rules.person.Everyone, - "Is default person" : rules.person.IsDefaultPerson, - "Is bookmarked person" : rules.person.IsBookmarked, - "Has the Id" : rules.person.HasIdOf, - "Has a name" : rules.person.HasNameOf, - "Has the relationships" : rules.person.HasRelationship, - "Has the death" : rules.person.HasDeath, - "Has the birth" : rules.person.HasBirth, - "Is a descendant of" : rules.person.IsDescendantOf, - "Is a descendant family member of" : rules.person.IsDescendantFamilyOf, + "Everyone": rules.person.Everyone, + "Is default person": rules.person.IsDefaultPerson, + "Is bookmarked person": rules.person.IsBookmarked, + "Has the Id": rules.person.HasIdOf, + "Has a name": rules.person.HasNameOf, + "Has the relationships": rules.person.HasRelationship, + "Has the death": rules.person.HasDeath, + "Has the birth": rules.person.HasBirth, + "Is a descendant of": rules.person.IsDescendantOf, + "Is a descendant family member of": rules.person.IsDescendantFamilyOf, "Is a descendant of filter match": rules.person.IsDescendantOfFilterMatch, - "Is a descendant of person not more than N generations away": - rules.person.IsLessThanNthGenerationDescendantOf, - "Is a descendant of person at least N generations away": - rules.person.IsMoreThanNthGenerationDescendantOf, - "Is an descendant of person at least N generations away" : - rules.person.IsMoreThanNthGenerationDescendantOf, - "Is a child of filter match" : rules.person.IsChildOfFilterMatch, - "Is an ancestor of" : rules.person.IsAncestorOf, + "Is a descendant of person not more than N generations away": rules.person.IsLessThanNthGenerationDescendantOf, + "Is a descendant of person at least N generations away": rules.person.IsMoreThanNthGenerationDescendantOf, + "Is an descendant of person at least N generations away": rules.person.IsMoreThanNthGenerationDescendantOf, + "Is a child of filter match": rules.person.IsChildOfFilterMatch, + "Is an ancestor of": rules.person.IsAncestorOf, "Is an ancestor of filter match": rules.person.IsAncestorOfFilterMatch, - "Is an ancestor of person not more than N generations away" : - rules.person.IsLessThanNthGenerationAncestorOf, - "Is an ancestor of person at least N generations away": - rules.person.IsMoreThanNthGenerationAncestorOf, - "Is a parent of filter match" : rules.person.IsParentOfFilterMatch, - "Has a common ancestor with" : rules.person.HasCommonAncestorWith, - "Has a common ancestor with filter match" : - rules.person.HasCommonAncestorWithFilterMatch, - "Is a female" : rules.person.IsFemale, - "Is a male" : rules.person.IsMale, - "Has the personal event" : rules.person.HasEvent, - "Has the family event" : rules.person.HasFamilyEvent, - "Has the personal attribute" : rules.person.HasAttribute, - "Has the family attribute" : rules.person.HasFamilyAttribute, - "Has source of" : rules.person.HasSourceOf, - "Matches the filter named" : rules.person.HasSourceOf, - "Is spouse of filter match" : rules.person.IsSpouseOfFilterMatch, - "Is a sibling of filter match" : rules.person.IsSiblingOfFilterMatch, - "Relationship path between two people" : - rules.person.RelationshipPathBetween, - "Relationship paths between a person and a list of people" : - rules.person.DeepRelationshipPathBetween, - "People who were adopted" : rules.person.HaveAltFamilies, - "People who have images" : rules.person.HavePhotos, - "People with children" : rules.person.HaveChildren, - "People with incomplete names" : rules.person.IncompleteNames, - "People with no marriage records" : rules.person.NeverMarried, + "Is an ancestor of person not more than N generations away": rules.person.IsLessThanNthGenerationAncestorOf, + "Is an ancestor of person at least N generations away": rules.person.IsMoreThanNthGenerationAncestorOf, + "Is a parent of filter match": rules.person.IsParentOfFilterMatch, + "Has a common ancestor with": rules.person.HasCommonAncestorWith, + "Has a common ancestor with filter match": rules.person.HasCommonAncestorWithFilterMatch, + "Is a female": rules.person.IsFemale, + "Is a male": rules.person.IsMale, + "Has the personal event": rules.person.HasEvent, + "Has the family event": rules.person.HasFamilyEvent, + "Has the personal attribute": rules.person.HasAttribute, + "Has the family attribute": rules.person.HasFamilyAttribute, + "Has source of": rules.person.HasSourceOf, + "Matches the filter named": rules.person.HasSourceOf, + "Is spouse of filter match": rules.person.IsSpouseOfFilterMatch, + "Is a sibling of filter match": rules.person.IsSiblingOfFilterMatch, + "Relationship path between two people": rules.person.RelationshipPathBetween, + "Relationship paths between a person and a list of people": rules.person.DeepRelationshipPathBetween, + "People who were adopted": rules.person.HaveAltFamilies, + "People who have images": rules.person.HavePhotos, + "People with children": rules.person.HaveChildren, + "People with incomplete names": rules.person.IncompleteNames, + "People with no marriage records": rules.person.NeverMarried, "People with multiple marriage records": rules.person.MultipleMarriages, - "People without a birth date" : rules.person.NoBirthdate, - "People with incomplete events" : rules.person.PersonWithIncompleteEvent, - "Families with incomplete events" :rules.person.FamilyWithIncompleteEvent, - "People probably alive" : rules.person.ProbablyAlive, - "People marked private" : rules.person.PeoplePrivate, - "People marked public" : rules.person.PeoplePublic, - "Witnesses" : rules.person.IsWitness, + "People without a birth date": rules.person.NoBirthdate, + "People with incomplete events": rules.person.PersonWithIncompleteEvent, + "Families with incomplete events": rules.person.FamilyWithIncompleteEvent, + "People probably alive": rules.person.ProbablyAlive, + "People marked private": rules.person.PeoplePrivate, + "People marked public": rules.person.PeoplePublic, + "Witnesses": rules.person.IsWitness, "Has text matching substring of": rules.person.HasTextMatchingSubstringOf, } diff --git a/gramps/gen/filters/_genericfilter.py b/gramps/gen/filters/_genericfilter.py index bab2f4da74a..87fd849f56b 100644 --- a/gramps/gen/filters/_genericfilter.py +++ b/gramps/gen/filters/_genericfilter.py @@ -24,11 +24,11 @@ Package providing filtering framework for Gramps. """ -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Gramps imports # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ from ..lib.person import Person from ..lib.family import Family from ..lib.src import Source @@ -40,17 +40,19 @@ from ..lib.note import Note from ..lib.tag import Tag from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # GenericFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class GenericFilter: """Filter class that consists of several rules.""" - logical_functions = ['or', 'and', 'xor', 'one'] + logical_functions = ["or", "and", "xor", "one"] def __init__(self, source=None): if source: @@ -63,9 +65,9 @@ def __init__(self, source=None): else: self.need_param = 0 self.flist = [] - self.name = '' - self.comment = '' - self.logical_op = 'and' + self.name = "" + self.comment = "" + self.logical_op = "and" self.invert = False def match(self, handle, db): @@ -78,15 +80,15 @@ def match(self, handle, db): return False def is_empty(self): - return ((len(self.flist) == 0) or - (len(self.flist) == 1 and ((self.flist[0].is_empty() and - not self.invert)))) + return (len(self.flist) == 0) or ( + len(self.flist) == 1 and ((self.flist[0].is_empty() and not self.invert)) + ) def set_logical_op(self, val): if val in GenericFilter.logical_functions: self.logical_op = val else: - self.logical_op = 'and' + self.logical_op = "and" def get_logical_op(self): return self.logical_op @@ -136,15 +138,12 @@ def find_from_handle(self, db, handle): def get_number(self, db): return db.get_number_of_people() - def check_func(self, db, id_list, task, user=None, tupleind=None, - tree=False): + def check_func(self, db, id_list, task, user=None, tupleind=None, tree=False): final_list = [] if user: - user.begin_progress(_('Filter'), _('Applying ...'), - self.get_number(db)) + user.begin_progress(_("Filter"), _("Applying ..."), self.get_number(db)) if id_list is None: - with (self.get_tree_cursor(db) if tree else - self.get_cursor(db)) as cursor: + with self.get_tree_cursor(db) if tree else self.get_cursor(db) as cursor: for handle, data in cursor: person = self.make_obj() person.unserialize(data) @@ -171,11 +170,9 @@ def check_and(self, db, id_list, user=None, tupleind=None, tree=False): final_list = [] flist = self.flist if user: - user.begin_progress(_('Filter'), _('Applying ...'), - self.get_number(db)) + user.begin_progress(_("Filter"), _("Applying ..."), self.get_number(db)) if id_list is None: - with (self.get_tree_cursor(db) if tree else - self.get_cursor(db)) as cursor: + with self.get_tree_cursor(db) if tree else self.get_cursor(db) as cursor: for handle, data in cursor: person = self.make_obj() person.unserialize(data) @@ -201,16 +198,13 @@ def check_and(self, db, id_list, user=None, tupleind=None, tree=False): return final_list def check_or(self, db, id_list, user=None, tupleind=None, tree=False): - return self.check_func(db, id_list, self.or_test, user, tupleind, - tree=False) + return self.check_func(db, id_list, self.or_test, user, tupleind, tree=False) def check_one(self, db, id_list, user=None, tupleind=None, tree=False): - return self.check_func(db, id_list, self.one_test, user, tupleind, - tree=False) + return self.check_func(db, id_list, self.one_test, user, tupleind, tree=False) def check_xor(self, db, id_list, user=None, tupleind=None, tree=False): - return self.check_func(db, id_list, self.xor_test, user, tupleind, - tree=False) + return self.check_func(db, id_list, self.xor_test, user, tupleind, tree=False) def xor_test(self, db, person): test = False @@ -223,7 +217,7 @@ def one_test(self, db, person): for rule in self.flist: if rule.apply(db, person): if found_one: - return False # There can be only one! + return False # There can be only one! found_one = True return found_one @@ -232,7 +226,7 @@ def or_test(self, db, person): def get_check_func(self): try: - m = getattr(self, 'check_' + self.logical_op) + m = getattr(self, "check_" + self.logical_op) except AttributeError: m = self.check_and return m @@ -265,8 +259,8 @@ def apply(self, db, id_list=None, tupleind=None, user=None, tree=False): rule.requestreset() return res -class GenericFamilyFilter(GenericFilter): +class GenericFamilyFilter(GenericFilter): def __init__(self, source=None): GenericFilter.__init__(self, source) @@ -282,8 +276,8 @@ def find_from_handle(self, db, handle): def get_number(self, db): return db.get_number_of_families() -class GenericEventFilter(GenericFilter): +class GenericEventFilter(GenericFilter): def __init__(self, source=None): GenericFilter.__init__(self, source) @@ -299,8 +293,8 @@ def find_from_handle(self, db, handle): def get_number(self, db): return db.get_number_of_events() -class GenericSourceFilter(GenericFilter): +class GenericSourceFilter(GenericFilter): def __init__(self, source=None): GenericFilter.__init__(self, source) @@ -316,8 +310,8 @@ def find_from_handle(self, db, handle): def get_number(self, db): return db.get_number_of_sources() -class GenericCitationFilter(GenericFilter): +class GenericCitationFilter(GenericFilter): def __init__(self, source=None): GenericFilter.__init__(self, source) @@ -336,8 +330,8 @@ def find_from_handle(self, db, handle): def get_number(self, db): return db.get_number_of_citations() -class GenericPlaceFilter(GenericFilter): +class GenericPlaceFilter(GenericFilter): def __init__(self, source=None): GenericFilter.__init__(self, source) @@ -356,8 +350,8 @@ def find_from_handle(self, db, handle): def get_number(self, db): return db.get_number_of_places() -class GenericMediaFilter(GenericFilter): +class GenericMediaFilter(GenericFilter): def __init__(self, source=None): GenericFilter.__init__(self, source) @@ -373,8 +367,8 @@ def find_from_handle(self, db, handle): def get_number(self, db): return db.get_number_of_media() -class GenericRepoFilter(GenericFilter): +class GenericRepoFilter(GenericFilter): def __init__(self, source=None): GenericFilter.__init__(self, source) @@ -390,8 +384,8 @@ def find_from_handle(self, db, handle): def get_number(self, db): return db.get_number_of_repositories() -class GenericNoteFilter(GenericFilter): +class GenericNoteFilter(GenericFilter): def __init__(self, source=None): GenericFilter.__init__(self, source) @@ -409,23 +403,23 @@ def get_number(self, db): def GenericFilterFactory(namespace): - if namespace == 'Person': + if namespace == "Person": return GenericFilter - elif namespace == 'Family': + elif namespace == "Family": return GenericFamilyFilter - elif namespace == 'Event': + elif namespace == "Event": return GenericEventFilter - elif namespace == 'Source': + elif namespace == "Source": return GenericSourceFilter - elif namespace == 'Citation': + elif namespace == "Citation": return GenericCitationFilter - elif namespace == 'Place': + elif namespace == "Place": return GenericPlaceFilter - elif namespace == 'Media': + elif namespace == "Media": return GenericMediaFilter - elif namespace == 'Repository': + elif namespace == "Repository": return GenericRepoFilter - elif namespace == 'Note': + elif namespace == "Note": return GenericNoteFilter @@ -453,6 +447,7 @@ def get_name(self, ulocale=glocale): return self._(self.name_pair[0]) % self.name_pair[1] return self._(self.name_pair[0]) + class DeferredFamilyFilter(GenericFamilyFilter): """ Filter class allowing for deferred translation of the filter name diff --git a/gramps/gen/filters/_paramfilter.py b/gramps/gen/filters/_paramfilter.py index 4f160521768..ebcd5d2a717 100644 --- a/gramps/gen/filters/_paramfilter.py +++ b/gramps/gen/filters/_paramfilter.py @@ -22,21 +22,21 @@ Package providing filtering framework for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ._genericfilter import GenericFilter from ..errors import FilterError -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ParamFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ParamFilter(GenericFilter): - def __init__(self, source=None): GenericFilter.__init__(self, source) self.need_param = 1 @@ -47,7 +47,7 @@ def set_parameter(self, param): def apply(self, db, id_list=None, user=None): for rule in self.flist: - #rule.set_list(self.param_list) + # rule.set_list(self.param_list) # # The above breaks filters with more than one param # Need to change existing params one by one to keep @@ -58,8 +58,9 @@ def apply(self, db, id_list=None, user=None): rule.set_list(new_list) for rule in self.flist: if rule.nrprepare > 0: - raise FilterError('Custom filters can not twice be used' \ - ' in a parameter filter') + raise FilterError( + "Custom filters can not twice be used" " in a parameter filter" + ) rule.requestprepare(db, user) result = GenericFilter.apply(self, db, id_list) for rule in self.flist: diff --git a/gramps/gen/filters/_searchfilter.py b/gramps/gen/filters/_searchfilter.py index 831716b1721..82ebdaffcb1 100644 --- a/gramps/gen/filters/_searchfilter.py +++ b/gramps/gen/filters/_searchfilter.py @@ -22,6 +22,7 @@ Package providing filtering framework for Gramps. """ + class SearchFilter: def __init__(self, func, text, invert): self.func = func @@ -31,10 +32,10 @@ def __init__(self, func, text, invert): def match(self, handle, db): return self.invert ^ (self.func(handle).upper().find(self.text) != -1) + class ExactSearchFilter(SearchFilter): def __init__(self, func, text, invert): SearchFilter.__init__(self, func, text, invert) def match(self, handle, db): return self.invert ^ (self.func(handle).upper() == self.text.strip()) - diff --git a/gramps/gen/filters/rules/__init__.py b/gramps/gen/filters/rules/__init__.py index 470a214aa7b..612533e9090 100644 --- a/gramps/gen/filters/rules/__init__.py +++ b/gramps/gen/filters/rules/__init__.py @@ -81,7 +81,8 @@ from ._matchessourceconfidencebase import MatchesSourceConfidenceBase from ._matchessourcefilterbase import MatchesSourceFilterBase from ._changedsincebase import ChangedSinceBase -#object filters + +# object filters from . import person from . import family from . import event diff --git a/gramps/gen/filters/rules/_changedsincebase.py b/gramps/gen/filters/rules/_changedsincebase.py index 426aa76a8e7..3cc57b1ed92 100644 --- a/gramps/gen/filters/rules/_changedsincebase.py +++ b/gramps/gen/filters/rules/_changedsincebase.py @@ -20,40 +20,44 @@ # gen.filters.rules/_ChangedSinceBase.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import re import time -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule from ...errors import FilterError from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ChangedSince # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChangedSinceBase(Rule): """ Rule that checks for primary objects changed since a specific time. """ - labels = [ 'Changed after:', 'but before:' ] - name = 'Objects changed after ' - description = "Matches object records changed after a specified " \ - "date/time (yyyy-mm-dd hh:mm:ss) or in range, if a second " \ - "date/time is given." - category = _('General filters') + labels = ["Changed after:", "but before:"] + name = "Objects changed after " + description = ( + "Matches object records changed after a specified " + "date/time (yyyy-mm-dd hh:mm:ss) or in range, if a second " + "date/time is given." + ) + category = _("General filters") def add_time(self, date): if re.search(r"\d.*\s+\d{1,2}:\d{2}:\d{2}", date): @@ -80,9 +84,13 @@ def time_str_to_sec(self, time_str): except ValueError: raise FilterError( _("Wrong format of date-time"), - _("Only date-times in the iso format of yyyy-mm-dd " - "hh:mm:ss, where the time part is optional, are " - "accepted. %s does not satisfy.") % iso_date_time) + _( + "Only date-times in the iso format of yyyy-mm-dd " + "hh:mm:ss, where the time part is optional, are " + "accepted. %s does not satisfy." + ) + % iso_date_time, + ) return time_sec def prepare(self, db, user): diff --git a/gramps/gen/filters/rules/_everything.py b/gramps/gen/filters/rules/_everything.py index abf6be825ec..3ec66484367 100644 --- a/gramps/gen/filters/rules/_everything.py +++ b/gramps/gen/filters/rules/_everything.py @@ -18,32 +18,34 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Everyone # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Everything(Rule): """Match Everyone.""" - name = 'Every object' - category = _('General filters') - description = 'Matches every object in the database' + name = "Every object" + category = _("General filters") + description = "Matches every object in the database" def is_empty(self): return True diff --git a/gramps/gen/filters/rules/_hasattributebase.py b/gramps/gen/filters/rules/_hasattributebase.py index 7aa22c52fa6..4abdd11256a 100644 --- a/gramps/gen/filters/rules/_hasattributebase.py +++ b/gramps/gen/filters/rules/_hasattributebase.py @@ -19,38 +19,38 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...lib.attrtype import AttributeType from . import Rule -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # HasAttribute # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasAttributeBase(Rule): """ Rule that checks for an object with a particular attribute. """ - labels = ['Attribute:', 'Value:'] - name = 'Objects with the ' - description = "Matches objects with the given attribute " \ - "of a particular value" - category = _('General filters') + labels = ["Attribute:", "Value:"] + name = "Objects with the " + description = "Matches objects with the given attribute " "of a particular value" + category = _("General filters") allow_regex = True def apply(self, db, obj): diff --git a/gramps/gen/filters/rules/_hascitationbase.py b/gramps/gen/filters/rules/_hascitationbase.py index 14455512e6f..0d2c0cfcff7 100644 --- a/gramps/gen/filters/rules/_hascitationbase.py +++ b/gramps/gen/filters/rules/_hascitationbase.py @@ -19,39 +19,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...datehandler import parser from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasCitation # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasCitationBase(Rule): """Rule that checks for a citation with a particular value First parameter is [Volume/page, Date, Confidence] """ - labels = [ _('Volume/Page:'), - _('Date:'), - _('Confidence:') ] - name = _('Citations matching parameters') + labels = [_("Volume/Page:"), _("Date:"), _("Confidence:")] + name = _("Citations matching parameters") description = _("Matches citations with particular parameters") - category = _('Citation/source filters') + category = _("Citation/source filters") allow_regex = True def prepare(self, db, user): diff --git a/gramps/gen/filters/rules/_haseventbase.py b/gramps/gen/filters/rules/_haseventbase.py index fd6fd9ce471..b5a9371d304 100644 --- a/gramps/gen/filters/rules/_haseventbase.py +++ b/gramps/gen/filters/rules/_haseventbase.py @@ -18,42 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...datehandler import parser from ...lib.eventtype import EventType from . import Rule from ...utils.db import get_participant_from_event from ...display.place import displayer as place_displayer -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasEventBase # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasEventBase(Rule): """Rule that checks for an event with a particular value.""" - - labels = [ 'Event type:', - 'Date:', - 'Place:', - 'Description:', - 'Main Participants:' ] - name = 'Events matching parameters' + labels = ["Event type:", "Date:", "Place:", "Description:", "Main Participants:"] + name = "Events matching parameters" description = "Matches events with particular parameters" - category = _('Event filters') + category = _("Event filters") allow_regex = True def prepare(self, db, user): @@ -94,8 +91,9 @@ def apply(self, db, event): else: return False - if not self.match_substring(4, - get_participant_from_event(db, event.get_handle(), all_=True)): + if not self.match_substring( + 4, get_participant_from_event(db, event.get_handle(), all_=True) + ): return False return True diff --git a/gramps/gen/filters/rules/_hasgallerybase.py b/gramps/gen/filters/rules/_hasgallerybase.py index d384e82a856..5bf5c61bee2 100644 --- a/gramps/gen/filters/rules/_hasgallerybase.py +++ b/gramps/gen/filters/rules/_hasgallerybase.py @@ -21,48 +21,50 @@ # # gen.filters.rules/_HasGalleryBase.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People who have images" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasGalleryBase(Rule): """Objects who have Media Object""" - labels = [ _('Number of instances:'), _('Number must be:')] - name = 'Object with Media references' + labels = [_("Number of instances:"), _("Number must be:")] + name = "Object with Media references" description = "Matches objects with certain number of items in the gallery" - category = _('General filters') + category = _("General filters") def prepare(self, db, user): # things we want to do just once, not for every handle - if self.list[1] == 'less than': + if self.list[1] == "less than": self.count_type = 0 - elif self.list[1] == 'greater than': + elif self.list[1] == "greater than": self.count_type = 2 else: - self.count_type = 1 # "equal to" + self.count_type = 1 # "equal to" self.userSelectedCount = int(self.list[0]) def apply(self, db, obj): - count = len( obj.get_media_list()) - if self.count_type == 0: # "less than" + count = len(obj.get_media_list()) + if self.count_type == 0: # "less than" return count < self.userSelectedCount - elif self.count_type == 2: # "greater than" + elif self.count_type == 2: # "greater than" return count > self.userSelectedCount # "equal to" return count == self.userSelectedCount diff --git a/gramps/gen/filters/rules/_hasgrampsid.py b/gramps/gen/filters/rules/_hasgrampsid.py index cb2a97ea2c6..fbfb5a8262a 100644 --- a/gramps/gen/filters/rules/_hasgrampsid.py +++ b/gramps/gen/filters/rules/_hasgrampsid.py @@ -19,33 +19,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasGrampsId(Rule): """Rule that checks for an object with a specific Gramps ID.""" - labels = [ _('ID:') ] - name = 'Object with ' + labels = [_("ID:")] + name = "Object with " description = "Matches objects with a specified Gramps ID" - category = _('General filters') + category = _("General filters") def apply(self, db, obj): """ diff --git a/gramps/gen/filters/rules/_hasldsbase.py b/gramps/gen/filters/rules/_hasldsbase.py index d7aa77d7464..8e29ed2c4fa 100644 --- a/gramps/gen/filters/rules/_hasldsbase.py +++ b/gramps/gen/filters/rules/_hasldsbase.py @@ -21,51 +21,53 @@ # # gen.filters.rules/_HasLDSBase.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasLDSBase # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasLDSBase(Rule): """Rule that checks for object with a LDS event""" - labels = [ _('Number of instances:'), _('Number must be:')] - name = 'Objects with LDS events' + labels = [_("Number of instances:"), _("Number must be:")] + name = "Objects with LDS events" description = "Matches objects with LDS events" - category = _('General filters') + category = _("General filters") def prepare(self, db, user): # things we want to do just once, not for every handle - if self.list[1] == 'less than': + if self.list[1] == "less than": self.count_type = 0 - elif self.list[1] == 'greater than': + elif self.list[1] == "greater than": self.count_type = 2 else: - self.count_type = 1 # "equal to" + self.count_type = 1 # "equal to" self.userSelectedCount = int(self.list[0]) def apply(self, db, obj): - count = len( obj.get_lds_ord_list()) - if self.count_type == 0: # "less than" + count = len(obj.get_lds_ord_list()) + if self.count_type == 0: # "less than" return count < self.userSelectedCount - elif self.count_type == 2: # "greater than" + elif self.count_type == 2: # "greater than" return count > self.userSelectedCount # "equal to" return count == self.userSelectedCount diff --git a/gramps/gen/filters/rules/_hasnotebase.py b/gramps/gen/filters/rules/_hasnotebase.py index 8890facf1ff..441bc582e0a 100644 --- a/gramps/gen/filters/rules/_hasnotebase.py +++ b/gramps/gen/filters/rules/_hasnotebase.py @@ -22,57 +22,58 @@ # # gen.filters.rules/_HasNoteBase.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Objects having notes" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteBase(Rule): """Objects having notes""" - labels = [ _('Number of instances:'), _('Number must be:')] - name = 'Object with notes' + labels = [_("Number of instances:"), _("Number must be:")] + name = "Object with notes" description = "Matches objects that have a certain number of notes" - category = _('General filters') + category = _("General filters") def __init__(self, arg, use_regex=False, use_case=False): # Upgrade from pre 3.1 HasNote filter, use defaults that correspond # Previous filter had 0 arguments if len(arg) == 0: - Rule.__init__(self, ["0", 'greater than'], use_regex, use_case) + Rule.__init__(self, ["0", "greater than"], use_regex, use_case) else: Rule.__init__(self, arg, use_regex, use_case) def prepare(self, db, user): # things we want to do just once, not for every handle - if self.list[1] == 'less than': + if self.list[1] == "less than": self.count_type = 0 - elif self.list[1] == 'greater than': + elif self.list[1] == "greater than": self.count_type = 2 else: - self.count_type = 1 # "equal to" + self.count_type = 1 # "equal to" self.userSelectedCount = int(self.list[0]) - def apply(self, db, obj): - count = len( obj.get_note_list()) - if self.count_type == 0: # "less than" + count = len(obj.get_note_list()) + if self.count_type == 0: # "less than" return count < self.userSelectedCount - elif self.count_type == 2: # "greater than" + elif self.count_type == 2: # "greater than" return count > self.userSelectedCount # "equal to" return count == self.userSelectedCount diff --git a/gramps/gen/filters/rules/_hasnoteregexbase.py b/gramps/gen/filters/rules/_hasnoteregexbase.py index 3736a5b55f1..50677efd96a 100644 --- a/gramps/gen/filters/rules/_hasnoteregexbase.py +++ b/gramps/gen/filters/rules/_hasnoteregexbase.py @@ -18,33 +18,37 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import re from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # Objects having notes that contain a substring or match a regular expression -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteRegexBase(Rule): """Objects having notes containing .""" - labels = [ _('Text:')] - name = 'Objects having notes containing ' - description = ("Matches objects whose notes contain a substring " - "or match a regular expression") - category = _('General filters') + labels = [_("Text:")] + name = "Objects having notes containing " + description = ( + "Matches objects whose notes contain a substring " + "or match a regular expression" + ) + category = _("General filters") allow_regex = True def apply(self, db, person): diff --git a/gramps/gen/filters/rules/_hasnotesubstrbase.py b/gramps/gen/filters/rules/_hasnotesubstrbase.py index affe5cb6f7d..25b3c3fc878 100644 --- a/gramps/gen/filters/rules/_hasnotesubstrbase.py +++ b/gramps/gen/filters/rules/_hasnotesubstrbase.py @@ -18,32 +18,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteSubstrBase(Rule): """People having notes containing .""" - labels = [ _('Substring:')] - name = 'Objects having notes containing ' - description = "Matches objects whose notes contain text matching a " \ - "substring" - category = _('General filters') + labels = [_("Substring:")] + name = "Objects having notes containing " + description = "Matches objects whose notes contain text matching a " "substring" + category = _("General filters") def apply(self, db, person): notelist = person.get_note_list() diff --git a/gramps/gen/filters/rules/_hasreferencecountbase.py b/gramps/gen/filters/rules/_hasreferencecountbase.py index 3db48fa9552..c8a6e2977db 100644 --- a/gramps/gen/filters/rules/_hasreferencecountbase.py +++ b/gramps/gen/filters/rules/_hasreferencecountbase.py @@ -18,55 +18,54 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Objects with a certain reference count" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasReferenceCountBase(Rule): """Objects with a reference count of .""" - labels = [ _('Reference count must be:'), _('Reference count:')] - name = 'Objects with a reference count of ' + labels = [_("Reference count must be:"), _("Reference count:")] + name = "Objects with a reference count of " description = "Matches objects with a certain reference count" - category = _('General filters') - + category = _("General filters") def prepare(self, db, user): # things we want to do just once, not for every handle - if self.list[0] == 'less than': + if self.list[0] == "less than": self.count_type = 0 - elif self.list[0] == 'greater than': + elif self.list[0] == "greater than": self.count_type = 2 else: - self.count_type = 1 # "equal to" + self.count_type = 1 # "equal to" self.userSelectedCount = int(self.list[1]) - def apply(self, db, obj): handle = obj.get_handle() count = 0 for item in db.find_backlink_handles(handle): count += 1 - if self.count_type == 0: # "less than" + if self.count_type == 0: # "less than" return count < self.userSelectedCount - elif self.count_type == 2: # "greater than" + elif self.count_type == 2: # "greater than" return count > self.userSelectedCount # "equal to" return count == self.userSelectedCount - diff --git a/gramps/gen/filters/rules/_hassourcebase.py b/gramps/gen/filters/rules/_hassourcebase.py index 8300c20768b..024143571ae 100644 --- a/gramps/gen/filters/rules/_hassourcebase.py +++ b/gramps/gen/filters/rules/_hassourcebase.py @@ -19,50 +19,48 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasSource # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceBase(Rule): """Rule that checks for a source with a particular value""" - - labels = [ 'Title:', - 'Author:', - 'Abbreviation:', - 'Publication:' ] - name = 'Sources matching parameters' + labels = ["Title:", "Author:", "Abbreviation:", "Publication:"] + name = "Sources matching parameters" description = "Matches sources with particular parameters" - category = _('Citation/source filters') + category = _("Citation/source filters") allow_regex = True - def apply(self,db,source): - if not self.match_substring(0,source.get_title()): + def apply(self, db, source): + if not self.match_substring(0, source.get_title()): return False - if not self.match_substring(1,source.get_author()): + if not self.match_substring(1, source.get_author()): return False - if not self.match_substring(2,source.get_abbreviation()): + if not self.match_substring(2, source.get_abbreviation()): return False - if not self.match_substring(3,source.get_publication_info()): + if not self.match_substring(3, source.get_publication_info()): return False return True diff --git a/gramps/gen/filters/rules/_hassourcecountbase.py b/gramps/gen/filters/rules/_hassourcecountbase.py index 943c0866564..8b4aab709bc 100644 --- a/gramps/gen/filters/rules/_hassourcecountbase.py +++ b/gramps/gen/filters/rules/_hassourcecountbase.py @@ -21,49 +21,53 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Objects having sources" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceCountBase(Rule): """Objects having sources""" - labels = [ _('Number of instances:'), _('Number must be:')] - name = 'Objects with sources' - description = "Matches objects that have a certain number of sources " \ - "connected to it (actually citations are counted)" - category = _('Citation/source filters') + labels = [_("Number of instances:"), _("Number must be:")] + name = "Objects with sources" + description = ( + "Matches objects that have a certain number of sources " + "connected to it (actually citations are counted)" + ) + category = _("Citation/source filters") def prepare(self, db, user): # things we want to do just once, not for every handle - if self.list[1] == 'less than': + if self.list[1] == "less than": self.count_type = 0 - elif self.list[1] == 'greater than': + elif self.list[1] == "greater than": self.count_type = 2 else: - self.count_type = 1 # "equal to" + self.count_type = 1 # "equal to" self.userSelectedCount = int(self.list[0]) def apply(self, db, obj): count = len(obj.get_citation_list()) - if self.count_type == 0: # "less than" + if self.count_type == 0: # "less than" return count < self.userSelectedCount - elif self.count_type == 2: # "greater than" + elif self.count_type == 2: # "greater than" return count > self.userSelectedCount # "equal to" return count == self.userSelectedCount diff --git a/gramps/gen/filters/rules/_hassourceofbase.py b/gramps/gen/filters/rules/_hassourceofbase.py index afbd9f2bf0a..4e04be727fa 100644 --- a/gramps/gen/filters/rules/_hassourceofbase.py +++ b/gramps/gen/filters/rules/_hassourceofbase.py @@ -19,44 +19,45 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasSourceOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceOfBase(Rule): """Rule that checks for objects that have a particular source.""" - labels = [ _('Source ID:') ] - name = 'Object with the ' - category = _('Citation/source filters') - description = 'Matches objects who have a particular source' + labels = [_("Source ID:")] + name = "Object with the " + category = _("Citation/source filters") + description = "Matches objects who have a particular source" def prepare(self, db, user): - if self.list[0] == '': + if self.list[0] == "": self.source_handle = None self.nosource = True return self.nosource = False try: - self.source_handle = db.get_source_from_gramps_id( - self.list[0]).get_handle() + self.source_handle = db.get_source_from_gramps_id(self.list[0]).get_handle() except: self.source_handle = None diff --git a/gramps/gen/filters/rules/_hastagbase.py b/gramps/gen/filters/rules/_hastagbase.py index 9a84ac2cafc..9d708776121 100644 --- a/gramps/gen/filters/rules/_hastagbase.py +++ b/gramps/gen/filters/rules/_hastagbase.py @@ -21,35 +21,37 @@ Rule that checks for an object with a particular tag. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTag # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTagBase(Rule): """ Rule that checks for an object with a particular tag. """ - labels = [ 'Tag:' ] - name = 'Objects with the ' + labels = ["Tag:"] + name = "Objects with the " description = "Matches objects with the given tag" - category = _('General filters') + category = _("General filters") def prepare(self, db, user): """ diff --git a/gramps/gen/filters/rules/_hastextmatchingregexpof.py b/gramps/gen/filters/rules/_hastextmatchingregexpof.py index 8ac18ce4490..be6e73f64b6 100644 --- a/gramps/gen/filters/rules/_hastextmatchingregexpof.py +++ b/gramps/gen/filters/rules/_hastextmatchingregexpof.py @@ -18,20 +18,22 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import HasTextMatchingSubstringOf -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "HasTextMatchingRegexOf" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTextMatchingRegexpOf(HasTextMatchingSubstringOf): """ Wrap HasTextMatchingSubstringOf to enable the regex_match parameter. """ + def __init__(self, list, use_regex=False): HasTextMatchingSubstringOf.__init__(self, list, use_regex) diff --git a/gramps/gen/filters/rules/_hastextmatchingsubstringof.py b/gramps/gen/filters/rules/_hastextmatchingsubstringof.py index 5d5d85fe50e..dde86e0768e 100644 --- a/gramps/gen/filters/rules/_hastextmatchingsubstringof.py +++ b/gramps/gen/filters/rules/_hastextmatchingsubstringof.py @@ -18,34 +18,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "HasTextMatchingSubstringOf" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTextMatchingSubstringOf(Rule): """Rule that checks for string matches in any textual information.""" - labels = [ 'Substring:', - 'Case sensitive:', - 'Regular-Expression matching:'] - name = 'Objects with records containing ' - description = "Matches objects whose records contain text " \ - "matching a substring" - category = _('General filters') + labels = ["Substring:", "Case sensitive:", "Regular-Expression matching:"] + name = "Objects with records containing " + description = "Matches objects whose records contain text " "matching a substring" + category = _("General filters") # FIXME: This needs to be written for an arbitrary object # if possible diff --git a/gramps/gen/filters/rules/_isprivate.py b/gramps/gen/filters/rules/_isprivate.py index 807dc85d872..53c2b95a0fa 100644 --- a/gramps/gen/filters/rules/_isprivate.py +++ b/gramps/gen/filters/rules/_isprivate.py @@ -20,26 +20,28 @@ # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People marked private" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsPrivate(Rule): """Objects marked private.""" - name = 'Objects marked private' + name = "Objects marked private" description = "Matches objects that are indicated as private" - category = _('General filters') + category = _("General filters") def apply(self, db, obj): return obj.get_privacy() diff --git a/gramps/gen/filters/rules/_ispublic.py b/gramps/gen/filters/rules/_ispublic.py index c0a99185c91..2ffdf608120 100644 --- a/gramps/gen/filters/rules/_ispublic.py +++ b/gramps/gen/filters/rules/_ispublic.py @@ -19,24 +19,26 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People marked public" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsPublic(Rule): """Objects not marked private.""" - name = 'Objects not marked private' + name = "Objects not marked private" description = "Matches objects that are not indicated as private" - category = _('General filters') + category = _("General filters") def apply(self, db, obj): return not obj.get_privacy() diff --git a/gramps/gen/filters/rules/_matcheseventfilterbase.py b/gramps/gen/filters/rules/_matcheseventfilterbase.py index 56f9f7f1a7e..9e551392f39 100644 --- a/gramps/gen/filters/rules/_matcheseventfilterbase.py +++ b/gramps/gen/filters/rules/_matcheseventfilterbase.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesEventFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesEventFilterBase(MatchesFilterBase): """ Rule that checks against another filter. @@ -47,26 +49,25 @@ class MatchesEventFilterBase(MatchesFilterBase): """ - labels = ['Event filter name:'] - name = 'Objects with events matching the ' - description = "Matches objects who have events that match a certain" \ - " event filter" - category = _('General filters') + labels = ["Event filter name:"] + name = "Objects with events matching the " + description = "Matches objects who have events that match a certain" " event filter" + category = _("General filters") # we want to have this filter show event filters - namespace = 'Event' + namespace = "Event" def prepare(self, db, user): MatchesFilterBase.prepare(self, db, user) self.MEF_filt = self.find_filter() def apply(self, db, object): - if self.MEF_filt is None : + if self.MEF_filt is None: return False eventlist = [x.ref for x in object.get_event_ref_list()] for eventhandle in eventlist: - #check if event in event filter + # check if event in event filter if self.MEF_filt.check(db, eventhandle): return True return False diff --git a/gramps/gen/filters/rules/_matchesfilterbase.py b/gramps/gen/filters/rules/_matchesfilterbase.py index 24876b32403..208b876e75c 100644 --- a/gramps/gen/filters/rules/_matchesfilterbase.py +++ b/gramps/gen/filters/rules/_matchesfilterbase.py @@ -18,31 +18,34 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + LOG = logging.getLogger(".filter") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # we need global variableCustomFilters, so we need to query gramps.gen.filters # when we need this variable, not import it at the start! import gramps.gen.filters from . import Rule from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesFilterBase(Rule): """ Rule that checks against another filter. @@ -51,10 +54,11 @@ class MatchesFilterBase(Rule): Subclasses need to define the namespace class attribute. """ - labels = [_('Filter name:')] - name = 'Objects matching the ' + + labels = [_("Filter name:")] + name = "Objects matching the " description = "Matches objects matched by the specified filter name" - category = _('General filters') + category = _("General filters") def prepare(self, db, user): if gramps.gen.filters.CustomFilters: @@ -64,11 +68,14 @@ def prepare(self, db, user): for rule in filt.flist: rule.requestprepare(db, user) else: - LOG.warning(_("Can't find filter %s in the defined custom filters") - % self.list[0]) + LOG.warning( + _("Can't find filter %s in the defined custom filters") + % self.list[0] + ) else: - LOG.warning(_("Can't find filter %s in the defined custom filters") - % self.list[0]) + LOG.warning( + _("Can't find filter %s in the defined custom filters") % self.list[0] + ) def reset(self): if gramps.gen.filters.CustomFilters: diff --git a/gramps/gen/filters/rules/_matchessourceconfidencebase.py b/gramps/gen/filters/rules/_matchessourceconfidencebase.py index 2b492780065..ccb9e8eb059 100644 --- a/gramps/gen/filters/rules/_matchessourceconfidencebase.py +++ b/gramps/gen/filters/rules/_matchessourceconfidencebase.py @@ -22,32 +22,36 @@ # # gen.filters.rules/_MatchesSourceConfidenceBase.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Confidence level" # Sources of an attribute of an event are ignored -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesSourceConfidenceBase(Rule): """Objects with a specific confidence level on 'direct' Source references""" - labels = ['Confidence level:'] - name = 'Object with at least one direct source >= ' - description = "Matches objects with at least one direct source with confidence level(s)" - category = _('Citation/source filters') + labels = ["Confidence level:"] + name = "Object with at least one direct source >= " + description = ( + "Matches objects with at least one direct source with confidence level(s)" + ) + category = _("Citation/source filters") def apply(self, db, obj): required_conf = int(self.list[0]) diff --git a/gramps/gen/filters/rules/_matchessourcefilterbase.py b/gramps/gen/filters/rules/_matchessourcefilterbase.py index e6173131268..1f9e9801749 100644 --- a/gramps/gen/filters/rules/_matchessourcefilterbase.py +++ b/gramps/gen/filters/rules/_matchessourcefilterbase.py @@ -19,46 +19,49 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesSourceFilterBase(MatchesFilterBase): """ Rule that checks against another filter. """ - labels = [_('Source filter name:')] - name = 'Objects with source matching the ' - description = "Matches objects with sources that match the " \ - "specified source filter name" - category = _('Citation/source filters') + labels = [_("Source filter name:")] + name = "Objects with source matching the " + description = ( + "Matches objects with sources that match the " "specified source filter name" + ) + category = _("Citation/source filters") # we want to have this filter show source filters - namespace = 'Source' + namespace = "Source" def prepare(self, db, user): MatchesFilterBase.prepare(self, db, user) self.MSF_filt = self.find_filter() def apply(self, db, object): - if self.MSF_filt is None : + if self.MSF_filt is None: return False for citation_handle in object.get_citation_list(): diff --git a/gramps/gen/filters/rules/_regexpidbase.py b/gramps/gen/filters/rules/_regexpidbase.py index ab892a32852..14b5c9a687f 100644 --- a/gramps/gen/filters/rules/_regexpidbase.py +++ b/gramps/gen/filters/rules/_regexpidbase.py @@ -18,38 +18,42 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import re from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpIdBase(Rule): """ Objects with a Gramps ID that contains a substring or matches a regular expression. """ - labels = [ _('Text:') ] - name = 'Objects with ' - description = "Matches objects whose Gramps ID contains a substring " \ - "or matches a regular expression" - category = _('General filters') + labels = [_("Text:")] + name = "Objects with " + description = ( + "Matches objects whose Gramps ID contains a substring " + "or matches a regular expression" + ) + category = _("General filters") allow_regex = True def apply(self, db, obj): diff --git a/gramps/gen/filters/rules/_rule.py b/gramps/gen/filters/rules/_rule.py index 34862c8a59b..0d565dfcc87 100644 --- a/gramps/gen/filters/rules/_rule.py +++ b/gramps/gen/filters/rules/_rule.py @@ -23,37 +23,40 @@ Base class for filter rules. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import re from ...errors import FilterError from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # enable logging for error handling # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + LOG = logging.getLogger(".") -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Rule # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Rule: """Base rule class.""" labels = [] - name = '' - category = _('Miscellaneous filters') - description = _('No description') + name = "" + category = _("Miscellaneous filters") + description = _("No description") allow_regex = False def __init__(self, arg, use_regex=False, use_case=False): @@ -81,7 +84,7 @@ def requestprepare(self, db, user): """ if self.nrprepare == 0: if self.use_regex: - self.regex = [None]*len(self.labels) + self.regex = [None] * len(self.labels) for index, label in enumerate(self.labels): if self.list[index]: try: @@ -90,14 +93,18 @@ def requestprepare(self, db, user): else: self.regex[index] = re.compile(self.list[index], re.I) except re.error: - self.regex[index] = re.compile('') + self.regex[index] = re.compile("") self.match_substring = self.match_regex self.prepare(db, user) self.nrprepare += 1 if self.nrprepare > 20: # more references to a filter than expected - raise FilterError(_("The filter definition contains a loop."), - _("One rule references another which eventually" - " references the first.")) + raise FilterError( + _("The filter definition contains a loop."), + _( + "One rule references another which eventually" + " references the first." + ), + ) def prepare(self, db, user): """prepare so the rule can be executed efficiently""" @@ -126,9 +133,13 @@ def set_list(self, arg): """Store the values of this rule.""" assert isinstance(arg, list) or arg is None, "Argument is not a list" if len(arg) != len(self.labels): - LOG.warning(("Number of arguments does not match number of " + - "labels.\n list: %s\n labels: %s") % (arg, - self.labels)) + LOG.warning( + ( + "Number of arguments does not match number of " + + "labels.\n list: %s\n labels: %s" + ) + % (arg, self.labels) + ) self.list = arg def values(self): @@ -145,12 +156,21 @@ def apply(self, dummy_db, dummy_person): def display_values(self): """Return the labels and values of this rule.""" - l_v = ('%s="%s"' % (_(self.labels[index][0] if - isinstance(self.labels[index], tuple) else - self.labels[index]), item) - for index, item in enumerate(self.list) if item) - - return ';'.join(l_v) + l_v = ( + '%s="%s"' + % ( + _( + self.labels[index][0] + if isinstance(self.labels[index], tuple) + else self.labels[index] + ), + item, + ) + for index, item in enumerate(self.list) + if item + ) + + return ";".join(l_v) def __match_substring(self, param_index, str_var): """ @@ -161,8 +181,9 @@ def __match_substring(self, param_index, str_var): # make str_var unicode so that search for ü works # see issue 3188 str_var = str(str_var) - if self.list[param_index] and \ - (str_var.upper().find(self.list[param_index].upper()) == -1): + if self.list[param_index] and ( + str_var.upper().find(self.list[param_index].upper()) == -1 + ): return False else: return True @@ -174,8 +195,7 @@ def match_regex(self, param_index, str_var): expression search. """ str_var = str(str_var) - if (self.list[param_index] and self.regex[param_index].search(str_var) - is None): + if self.list[param_index] and self.regex[param_index].search(str_var) is None: return False else: return True diff --git a/gramps/gen/filters/rules/citation/__init__.py b/gramps/gen/filters/rules/citation/__init__.py index 63185d09fac..228847ea31f 100644 --- a/gramps/gen/filters/rules/citation/__init__.py +++ b/gramps/gen/filters/rules/citation/__init__.py @@ -66,5 +66,5 @@ MatchesSourceFilter, RegExpIdOf, RegExpSourceIdOf, - HasTag + HasTag, ] diff --git a/gramps/gen/filters/rules/citation/_allcitations.py b/gramps/gen/filters/rules/citation/_allcitations.py index 92b74f7ba9a..e325e14b143 100644 --- a/gramps/gen/filters/rules/citation/_allcitations.py +++ b/gramps/gen/filters/rules/citation/_allcitations.py @@ -19,28 +19,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._everything import Everything -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Everyone # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class AllCitations(Everything): """Matches every citation""" - name = _('Every citation') - description = _('Matches every citation in the database') + name = _("Every citation") + description = _("Matches every citation in the database") diff --git a/gramps/gen/filters/rules/citation/_changedsince.py b/gramps/gen/filters/rules/citation/_changedsince.py index b66c7b3758d..c128d8065a2 100644 --- a/gramps/gen/filters/rules/citation/_changedsince.py +++ b/gramps/gen/filters/rules/citation/_changedsince.py @@ -19,31 +19,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._changedsincebase import ChangedSinceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ChangedSince # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChangedSince(ChangedSinceBase): """Rule that checks for citations changed since a specific time.""" - labels = [ _('Changed after:'), _('but before:') ] - name = _('Citations changed after ') - description = _("Matches citation records changed after a specified " - "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " - "date-time is given.") + labels = [_("Changed after:"), _("but before:")] + name = _("Citations changed after ") + description = _( + "Matches citation records changed after a specified " + "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " + "date-time is given." + ) diff --git a/gramps/gen/filters/rules/citation/_citationprivate.py b/gramps/gen/filters/rules/citation/_citationprivate.py index ef6a0c0952a..b11941e7f72 100644 --- a/gramps/gen/filters/rules/citation/_citationprivate.py +++ b/gramps/gen/filters/rules/citation/_citationprivate.py @@ -19,26 +19,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._isprivate import IsPrivate -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Family marked private" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class CitationPrivate(IsPrivate): """Citation marked private""" - name = _('Citations marked private') + name = _("Citations marked private") description = _("Matches citations that are indicated as private") diff --git a/gramps/gen/filters/rules/citation/_hasattribute.py b/gramps/gen/filters/rules/citation/_hasattribute.py index f15c2be642c..57c15a33c33 100644 --- a/gramps/gen/filters/rules/citation/_hasattribute.py +++ b/gramps/gen/filters/rules/citation/_hasattribute.py @@ -25,6 +25,7 @@ # # ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext # ------------------------------------------------------------------------- @@ -43,7 +44,6 @@ class HasAttribute(HasAttributeBase): """Rule that checks for a citation with a particular attribute""" - labels = [_('Citation attribute:'), _('Value:')] - name = _('Citations with the attribute ') - description = _("Matches citations with the attribute " - "of a particular value") + labels = [_("Citation attribute:"), _("Value:")] + name = _("Citations with the attribute ") + description = _("Matches citations with the attribute " "of a particular value") diff --git a/gramps/gen/filters/rules/citation/_hascitation.py b/gramps/gen/filters/rules/citation/_hascitation.py index f20d6e17da6..af08fc5a40c 100644 --- a/gramps/gen/filters/rules/citation/_hascitation.py +++ b/gramps/gen/filters/rules/citation/_hascitation.py @@ -21,35 +21,35 @@ """ Filter rule to match citation data. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....datehandler import parser -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasCitation # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasCitation(Rule): """Rule that checks for a citations with a particular value""" - labels = [ _('Volume/Page:'), - _('Date:'), - _('Confidence level:')] - name = _('Citations matching parameters') - category = _('General filters') + labels = [_("Volume/Page:"), _("Date:"), _("Confidence level:")] + name = _("Citations matching parameters") + category = _("General filters") description = _("Matches citations with particular parameters") allow_regex = True diff --git a/gramps/gen/filters/rules/citation/_hasgallery.py b/gramps/gen/filters/rules/citation/_hasgallery.py index 1774df39541..8c5437c0bf8 100644 --- a/gramps/gen/filters/rules/citation/_hasgallery.py +++ b/gramps/gen/filters/rules/citation/_hasgallery.py @@ -21,26 +21,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasgallerybase import HasGalleryBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Sources who have media object reference" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasGallery(HasGalleryBase): """Rule that checks for citation who has media object reference""" - name = _('Citations with media') + name = _("Citations with media") description = _("Matches citations with a certain number of items in the gallery") diff --git a/gramps/gen/filters/rules/citation/_hasidof.py b/gramps/gen/filters/rules/citation/_hasidof.py index f7923031a15..de69c51ad9f 100644 --- a/gramps/gen/filters/rules/citation/_hasidof.py +++ b/gramps/gen/filters/rules/citation/_hasidof.py @@ -19,28 +19,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import HasGrampsId -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasIdOf(HasGrampsId): """Rule that checks for a citation with a specific Gramps ID""" - name = _('Citation with ') + name = _("Citation with ") description = _("Matches a citation with a specified Gramps ID") diff --git a/gramps/gen/filters/rules/citation/_hasnote.py b/gramps/gen/filters/rules/citation/_hasnote.py index 083138336f2..3e7dea949af 100644 --- a/gramps/gen/filters/rules/citation/_hasnote.py +++ b/gramps/gen/filters/rules/citation/_hasnote.py @@ -22,26 +22,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotebase import HasNoteBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Sources having notes" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNote(HasNoteBase): """Citations having notes""" - name = _('Citations having notes') + name = _("Citations having notes") description = _("Matches citations having a certain number of notes") diff --git a/gramps/gen/filters/rules/citation/_hasnotematchingsubstringof.py b/gramps/gen/filters/rules/citation/_hasnotematchingsubstringof.py index 11e4875cde8..f9a1aa5e0e3 100644 --- a/gramps/gen/filters/rules/citation/_hasnotematchingsubstringof.py +++ b/gramps/gen/filters/rules/citation/_hasnotematchingsubstringof.py @@ -19,28 +19,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotesubstrbase import HasNoteSubstrBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Events having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteMatchingSubstringOf(HasNoteSubstrBase): """Citations having notes containing """ - name = _('Citations having notes containing ') - description = _("Matches citations whose notes contain text " - "matching a substring") - + name = _("Citations having notes containing ") + description = _( + "Matches citations whose notes contain text " "matching a substring" + ) diff --git a/gramps/gen/filters/rules/citation/_hasnoteregexp.py b/gramps/gen/filters/rules/citation/_hasnoteregexp.py index 77e8c5de451..3ffc0c39b76 100644 --- a/gramps/gen/filters/rules/citation/_hasnoteregexp.py +++ b/gramps/gen/filters/rules/citation/_hasnoteregexp.py @@ -19,26 +19,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnoteregexbase import HasNoteRegexBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Sources having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteRegexp(HasNoteRegexBase): - - name = _('Citations having notes containing ') - description = _("Matches citations whose notes contain text " - "matching a regular expression") + name = _("Citations having notes containing ") + description = _( + "Matches citations whose notes contain text " "matching a regular expression" + ) diff --git a/gramps/gen/filters/rules/citation/_hasreferencecountof.py b/gramps/gen/filters/rules/citation/_hasreferencecountof.py index e8eda4fbb25..af5cc04b330 100644 --- a/gramps/gen/filters/rules/citation/_hasreferencecountof.py +++ b/gramps/gen/filters/rules/citation/_hasreferencecountof.py @@ -19,27 +19,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasreferencecountbase import HasReferenceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Source objects with a certain reference count" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasReferenceCountOf(HasReferenceCountBase): """Citation objects with a reference count of """ - name = _('Citations with a reference count of ') + name = _("Citations with a reference count of ") description = _("Matches citations with a certain reference count") - diff --git a/gramps/gen/filters/rules/citation/_hassource.py b/gramps/gen/filters/rules/citation/_hassource.py index 549d00bfff1..1a63bfcaaf9 100644 --- a/gramps/gen/filters/rules/citation/_hassource.py +++ b/gramps/gen/filters/rules/citation/_hassource.py @@ -22,41 +22,38 @@ """ Filter rule to match citation with a particular source. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hassourcebase import HasSourceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasEvent # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSource(HasSourceBase): """Rule that checks for an citation with a particular value""" - labels = [ _('Title:'), - _('Author:'), - _('Abbreviation:'), - _('Publication:') ] - name = _('Sources matching parameters') - description = _("Matches citations with a source of a particular " - "value") - category = _('Source filters') + labels = [_("Title:"), _("Author:"), _("Abbreviation:"), _("Publication:")] + name = _("Sources matching parameters") + description = _("Matches citations with a source of a particular " "value") + category = _("Source filters") def apply(self, dbase, citation): - source = dbase.get_source_from_handle( - citation.get_reference_handle()) + source = dbase.get_source_from_handle(citation.get_reference_handle()) if HasSourceBase.apply(self, dbase, source): return True return False diff --git a/gramps/gen/filters/rules/citation/_hassourceidof.py b/gramps/gen/filters/rules/citation/_hassourceidof.py index 5bc14c2009a..de6e07b765e 100644 --- a/gramps/gen/filters/rules/citation/_hassourceidof.py +++ b/gramps/gen/filters/rules/citation/_hassourceidof.py @@ -19,38 +19,38 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasgrampsid import HasGrampsId -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasSourceIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceIdOf(HasGrampsId): """Rule that checks for a citation with a source which has a specific Gramps ID""" - name = _('Citation with Source ') - description = _("Matches a citation with a source with a specified Gramps " - "ID") - category = _('Source filters') + name = _("Citation with Source ") + description = _("Matches a citation with a source with a specified Gramps " "ID") + category = _("Source filters") def apply(self, dbase, citation): - source = dbase.get_source_from_handle( - citation.get_reference_handle()) + source = dbase.get_source_from_handle(citation.get_reference_handle()) if HasGrampsId.apply(self, dbase, source): return True return False diff --git a/gramps/gen/filters/rules/citation/_hassourcenoteregexp.py b/gramps/gen/filters/rules/citation/_hassourcenoteregexp.py index 41d2f3271a4..82ceeb2d4e1 100644 --- a/gramps/gen/filters/rules/citation/_hassourcenoteregexp.py +++ b/gramps/gen/filters/rules/citation/_hassourcenoteregexp.py @@ -23,36 +23,40 @@ match a regular expression. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnoteregexbase import HasNoteRegexBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasSourceNoteRegexp # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceNoteRegexp(HasNoteRegexBase): """ Rule that checks if a citation has a source note that contains a substring or matches a regular expression. """ - name = _('Citations having source notes containing ') - description = _("Matches citations whose source notes contain a substring " - "or match a regular expression") - category = _('Source filters') + name = _("Citations having source notes containing ") + description = _( + "Matches citations whose source notes contain a substring " + "or match a regular expression" + ) + category = _("Source filters") def apply(self, db, citation): source = db.get_source_from_handle(citation.get_reference_handle()) diff --git a/gramps/gen/filters/rules/citation/_hastag.py b/gramps/gen/filters/rules/citation/_hastag.py index 2396d230b54..efe1a330fb8 100644 --- a/gramps/gen/filters/rules/citation/_hastag.py +++ b/gramps/gen/filters/rules/citation/_hastag.py @@ -21,30 +21,33 @@ Rule that checks for a citation with a particular tag. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hastagbase import HasTagBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTag # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTag(HasTagBase): """ Rule that checks for a citation with a particular tag. """ - labels = [ _('Tag:') ] - name = _('Citations with the ') + + labels = [_("Tag:")] + name = _("Citations with the ") description = _("Matches citations with the particular tag") diff --git a/gramps/gen/filters/rules/citation/_matchesfilter.py b/gramps/gen/filters/rules/citation/_matchesfilter.py index 769e36e8af1..8a0a2139cfa 100644 --- a/gramps/gen/filters/rules/citation/_matchesfilter.py +++ b/gramps/gen/filters/rules/citation/_matchesfilter.py @@ -19,29 +19,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._matchesfilterbase import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesFilter(MatchesFilterBase): """Rule that checks against another filter""" - name = _('Citations matching the ') + name = _("Citations matching the ") description = _("Matches citations matched by the specified filter name") - namespace = 'Citation' + namespace = "Citation" diff --git a/gramps/gen/filters/rules/citation/_matchespagesubstringof.py b/gramps/gen/filters/rules/citation/_matchespagesubstringof.py index 1e74a6ca742..f45abf4650c 100644 --- a/gramps/gen/filters/rules/citation/_matchespagesubstringof.py +++ b/gramps/gen/filters/rules/citation/_matchespagesubstringof.py @@ -18,34 +18,37 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Sources having a title that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesPageSubstringOf(Rule): """Citation Volume/Page title containing """ - labels = [ _('Text:')] - name = _('Citations with Volume/Page containing ') - description = _("Matches citations whose Volume/Page contains a " - "certain substring") - category = _('General filters') + labels = [_("Text:")] + name = _("Citations with Volume/Page containing ") + description = _( + "Matches citations whose Volume/Page contains a " "certain substring" + ) + category = _("General filters") allow_regex = True def apply(self, db, object): - """ Apply the filter """ + """Apply the filter""" return self.match_substring(0, object.get_page()) diff --git a/gramps/gen/filters/rules/citation/_matchesrepositoryfilter.py b/gramps/gen/filters/rules/citation/_matchesrepositoryfilter.py index 308929b720a..a9260647d48 100644 --- a/gramps/gen/filters/rules/citation/_matchesrepositoryfilter.py +++ b/gramps/gen/filters/rules/citation/_matchesrepositoryfilter.py @@ -19,53 +19,59 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + LOG = logging.getLogger(".citation") from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Sources which reference a repository by selection" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesRepositoryFilter(MatchesFilterBase): """Citations which have a source which references the selected repository""" - labels = [ _('Repository filter name:') ] - name = _('Citations with a source with a repository reference ' - 'matching the ') - description = _("Matches citations with sources with a repository " - "reference that match a certain repository filter") - category = _('General filters') + labels = [_("Repository filter name:")] + name = _( + "Citations with a source with a repository reference " + "matching the " + ) + description = _( + "Matches citations with sources with a repository " + "reference that match a certain repository filter" + ) + category = _("General filters") # we want to have this filter show repository filters - namespace = 'Repository' - + namespace = "Repository" def prepare(self, db, user): MatchesFilterBase.prepare(self, db, user) self.MRF_filt = self.find_filter() def apply(self, db, object): - if self.MRF_filt is None : + if self.MRF_filt is None: return False source_handle = object.source_handle source = db.get_source_from_handle(source_handle) repolist = [x.ref for x in source.get_reporef_list()] for repohandle in repolist: - #check if repo in repository filter + # check if repo in repository filter if self.MRF_filt.check(db, repohandle): return True return False diff --git a/gramps/gen/filters/rules/citation/_matchessourcefilter.py b/gramps/gen/filters/rules/citation/_matchessourcefilter.py index 71bc120bba7..0bc9c18fc2c 100644 --- a/gramps/gen/filters/rules/citation/_matchessourcefilter.py +++ b/gramps/gen/filters/rules/citation/_matchessourcefilter.py @@ -20,46 +20,49 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesSourceFilter(MatchesFilterBase): """ Rule that checks against another filter. """ - labels = [_('Source filter name:')] - name = _('Citations with source matching the ') - description = _("Matches citations with sources that match the " - "specified source filter name") - category = _('General filters') + labels = [_("Source filter name:")] + name = _("Citations with source matching the ") + description = _( + "Matches citations with sources that match the " "specified source filter name" + ) + category = _("General filters") # we want to have this filter show source filters - namespace = 'Source' + namespace = "Source" def prepare(self, db, user): MatchesFilterBase.prepare(self, db, user) self.MRF_filt = self.find_filter() def apply(self, db, object): - if self.MRF_filt is None : + if self.MRF_filt is None: return False source_handle = object.source_handle diff --git a/gramps/gen/filters/rules/citation/_regexpidof.py b/gramps/gen/filters/rules/citation/_regexpidof.py index 52b093fad62..80d63715ff0 100644 --- a/gramps/gen/filters/rules/citation/_regexpidof.py +++ b/gramps/gen/filters/rules/citation/_regexpidof.py @@ -19,32 +19,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._regexpidbase import RegExpIdBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpIdOf(RegExpIdBase): """ Rule that checks for a citation whose Gramps ID matches regular expression. """ - name = _('Citations with Id containing ') - description = _("Matches citations whose Gramps ID matches " - "the regular expression") + name = _("Citations with Id containing ") + description = _( + "Matches citations whose Gramps ID matches " "the regular expression" + ) diff --git a/gramps/gen/filters/rules/citation/_regexpsourceidof.py b/gramps/gen/filters/rules/citation/_regexpsourceidof.py index 322d2866094..afa7f2471aa 100644 --- a/gramps/gen/filters/rules/citation/_regexpsourceidof.py +++ b/gramps/gen/filters/rules/citation/_regexpsourceidof.py @@ -19,40 +19,43 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._regexpidbase import RegExpIdBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpSourceIdOf(RegExpIdBase): """ Rule that checks for a citation whose Gramps ID matches regular expression. """ - name = _('Citations with Source Id containing ') - description = _("Matches citations whose source has a Gramps ID that " - "matches the regular expression") - category = _('Source filters') + name = _("Citations with Source Id containing ") + description = _( + "Matches citations whose source has a Gramps ID that " + "matches the regular expression" + ) + category = _("Source filters") def apply(self, dbase, citation): - source = dbase.get_source_from_handle( - citation.get_reference_handle()) + source = dbase.get_source_from_handle(citation.get_reference_handle()) if RegExpIdBase.apply(self, dbase, source): return True return False diff --git a/gramps/gen/filters/rules/event/__init__.py b/gramps/gen/filters/rules/event/__init__.py index 8cfbd1ce742..5f7bec29e09 100644 --- a/gramps/gen/filters/rules/event/__init__.py +++ b/gramps/gen/filters/rules/event/__init__.py @@ -70,5 +70,5 @@ ChangedSince, HasTag, MatchesPlaceFilter, - HasDayOfWeek + HasDayOfWeek, ] diff --git a/gramps/gen/filters/rules/event/_allevents.py b/gramps/gen/filters/rules/event/_allevents.py index 0ffa4e9ba28..12dc31dd864 100644 --- a/gramps/gen/filters/rules/event/_allevents.py +++ b/gramps/gen/filters/rules/event/_allevents.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._everything import Everything -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Everyone # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class AllEvents(Everything): """Matches Everyone""" - name = _('Every event') - description = _('Matches every event in the database') + name = _("Every event") + description = _("Matches every event in the database") diff --git a/gramps/gen/filters/rules/event/_changedsince.py b/gramps/gen/filters/rules/event/_changedsince.py index 3a71fcc1e36..5bcd6ea2ac4 100644 --- a/gramps/gen/filters/rules/event/_changedsince.py +++ b/gramps/gen/filters/rules/event/_changedsince.py @@ -20,31 +20,35 @@ # gen.filters.rules/Event/_ChangedSince.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._changedsincebase import ChangedSinceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ChangedSince # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChangedSince(ChangedSinceBase): """Rule that checks for an event changed since a specific time.""" - labels = [ _('Changed after:'), _('but before:') ] - name = _('Events changed after ') - description = _("Matches event records changed after a specified " - "date/time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " - "date/time is given.") + labels = [_("Changed after:"), _("but before:")] + name = _("Events changed after ") + description = _( + "Matches event records changed after a specified " + "date/time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " + "date/time is given." + ) diff --git a/gramps/gen/filters/rules/event/_eventprivate.py b/gramps/gen/filters/rules/event/_eventprivate.py index 7b985ca9722..5143abb7d91 100644 --- a/gramps/gen/filters/rules/event/_eventprivate.py +++ b/gramps/gen/filters/rules/event/_eventprivate.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._isprivate import IsPrivate -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Family marked private" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class EventPrivate(IsPrivate): """Event marked private""" - name = _('Events marked private') + name = _("Events marked private") description = _("Matches events that are indicated as private") diff --git a/gramps/gen/filters/rules/event/_hasattribute.py b/gramps/gen/filters/rules/event/_hasattribute.py index fb5a11824f9..d69ee64671a 100644 --- a/gramps/gen/filters/rules/event/_hasattribute.py +++ b/gramps/gen/filters/rules/event/_hasattribute.py @@ -18,30 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasattributebase import HasAttributeBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasAttribute # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasAttribute(HasAttributeBase): """Rule that checks for an event with a particular event attribute""" - labels = [ _('Event attribute:'), _('Value:') ] - name = _('Events with the attribute ') - description = _("Matches events with the event attribute " - "of a particular value") + labels = [_("Event attribute:"), _("Value:")] + name = _("Events with the attribute ") + description = _("Matches events with the event attribute " "of a particular value") diff --git a/gramps/gen/filters/rules/event/_hascitation.py b/gramps/gen/filters/rules/event/_hascitation.py index ead645147dc..158b710c4e9 100644 --- a/gramps/gen/filters/rules/event/_hascitation.py +++ b/gramps/gen/filters/rules/event/_hascitation.py @@ -22,32 +22,31 @@ """ Filter rule to match event with a particular citation. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hascitationbase import HasCitationBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasEvent # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasCitation(HasCitationBase): """Rule that checks for an event with a particular value""" - labels = [ _('Volume/Page:'), - _('Date:'), - _('Confidence level:')] - name = _('Events with the ') - description = _("Matches events with a citation of a particular " - "value") + labels = [_("Volume/Page:"), _("Date:"), _("Confidence level:")] + name = _("Events with the ") + description = _("Matches events with a citation of a particular " "value") diff --git a/gramps/gen/filters/rules/event/_hasdata.py b/gramps/gen/filters/rules/event/_hasdata.py index 87f59e75cd0..31dc890e37a 100644 --- a/gramps/gen/filters/rules/event/_hasdata.py +++ b/gramps/gen/filters/rules/event/_hasdata.py @@ -18,37 +18,38 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....datehandler import parser from ....display.place import displayer as place_displayer from ....lib.eventtype import EventType from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasBirth # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasData(Rule): """Rule that checks for an event containing particular values""" - labels = [ _('Event type:'), _('Date:'), _('Place:'), - _('Description:') ] - name = _('Events with ') + labels = [_("Event type:"), _("Date:"), _("Place:"), _("Description:")] + name = _("Events with ") description = _("Matches events with data of a particular value") - category = _('General filters') + category = _("General filters") allow_regex = True def prepare(self, db, user): diff --git a/gramps/gen/filters/rules/event/_hasdayofweek.py b/gramps/gen/filters/rules/event/_hasdayofweek.py index 6c69e0818e5..b4aad3c21e2 100644 --- a/gramps/gen/filters/rules/event/_hasdayofweek.py +++ b/gramps/gen/filters/rules/event/_hasdayofweek.py @@ -18,27 +18,29 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasDayOfWeek # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasDayOfWeek(Rule): """Rule that matches an event occurring on a particular day of the week.""" - labels = [ _('Day of Week:') ] - name = _('Events occurring on a particular day of the week') - description = _('Matches events occurring on a particular day of the week') - category = _('General filters') + labels = [_("Day of Week:")] + name = _("Events occurring on a particular day of the week") + description = _("Matches events occurring on a particular day of the week") + category = _("General filters") def apply(self, db, event): if not self.list[0]: diff --git a/gramps/gen/filters/rules/event/_hasgallery.py b/gramps/gen/filters/rules/event/_hasgallery.py index 6bf351e2b76..9537a806b40 100644 --- a/gramps/gen/filters/rules/event/_hasgallery.py +++ b/gramps/gen/filters/rules/event/_hasgallery.py @@ -21,26 +21,28 @@ # # gen.filters.rules/Event/_HasGallery.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasgallerybase import HasGalleryBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Events who have media object reference" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasGallery(HasGalleryBase): """Rule that checks for event who has media object reference""" - name = _('Events with media') + name = _("Events with media") description = _("Matches events with a certain number of items in the gallery") diff --git a/gramps/gen/filters/rules/event/_hasidof.py b/gramps/gen/filters/rules/event/_hasidof.py index ac8911d52e1..afb58930bbd 100644 --- a/gramps/gen/filters/rules/event/_hasidof.py +++ b/gramps/gen/filters/rules/event/_hasidof.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import HasGrampsId -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasIdOf(HasGrampsId): """Rule that checks for a family with a specific Gramps ID""" - name = _('Event with ') + name = _("Event with ") description = _("Matches an event with a specified Gramps ID") diff --git a/gramps/gen/filters/rules/event/_hasnote.py b/gramps/gen/filters/rules/event/_hasnote.py index 883e6fb474e..4fc84074a66 100644 --- a/gramps/gen/filters/rules/event/_hasnote.py +++ b/gramps/gen/filters/rules/event/_hasnote.py @@ -21,26 +21,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotebase import HasNoteBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Events having notes" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNote(HasNoteBase): """Events having notes""" - name = _('Events having notes') + name = _("Events having notes") description = _("Matches events having a certain number of notes") diff --git a/gramps/gen/filters/rules/event/_hasnotematchingsubstringof.py b/gramps/gen/filters/rules/event/_hasnotematchingsubstringof.py index 1844490cfd6..8f6de969c1f 100644 --- a/gramps/gen/filters/rules/event/_hasnotematchingsubstringof.py +++ b/gramps/gen/filters/rules/event/_hasnotematchingsubstringof.py @@ -18,28 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotesubstrbase import HasNoteSubstrBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Events having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteMatchingSubstringOf(HasNoteSubstrBase): """People having notes containing """ - name = _('Events having notes containing ') - description = _("Matches events whose notes contain text " - "matching a substring") - + name = _("Events having notes containing ") + description = _("Matches events whose notes contain text " "matching a substring") diff --git a/gramps/gen/filters/rules/event/_hasnoteregexp.py b/gramps/gen/filters/rules/event/_hasnoteregexp.py index e9f8acea54f..a5783f7efff 100644 --- a/gramps/gen/filters/rules/event/_hasnoteregexp.py +++ b/gramps/gen/filters/rules/event/_hasnoteregexp.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnoteregexbase import HasNoteRegexBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Events having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteRegexp(HasNoteRegexBase): - - name = _('Events having notes containing ') - description = _("Matches events whose notes contain text " - "matching a regular expression") + name = _("Events having notes containing ") + description = _( + "Matches events whose notes contain text " "matching a regular expression" + ) diff --git a/gramps/gen/filters/rules/event/_hasreferencecountof.py b/gramps/gen/filters/rules/event/_hasreferencecountof.py index 967d61cea6f..0e3af3fee45 100644 --- a/gramps/gen/filters/rules/event/_hasreferencecountof.py +++ b/gramps/gen/filters/rules/event/_hasreferencecountof.py @@ -18,27 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasreferencecountbase import HasReferenceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Events with a certain reference count" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasReferenceCountOf(HasReferenceCountBase): """Events with a reference count of """ - name = _('Events with a reference count of ') + name = _("Events with a reference count of ") description = _("Matches events with a certain reference count") - diff --git a/gramps/gen/filters/rules/event/_hassourcecount.py b/gramps/gen/filters/rules/event/_hassourcecount.py index ca4e200f8c3..6afbba32473 100644 --- a/gramps/gen/filters/rules/event/_hassourcecount.py +++ b/gramps/gen/filters/rules/event/_hassourcecount.py @@ -20,26 +20,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hassourcecountbase import HasSourceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People having sources" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceCount(HasSourceCountBase): """Events with sources""" - name = _('Events with sources') + name = _("Events with sources") description = _("Matches events with a certain number of sources connected to it") diff --git a/gramps/gen/filters/rules/event/_hastag.py b/gramps/gen/filters/rules/event/_hastag.py index c599c5124cd..b2e0ef303c1 100644 --- a/gramps/gen/filters/rules/event/_hastag.py +++ b/gramps/gen/filters/rules/event/_hastag.py @@ -21,30 +21,33 @@ Rule that checks for an event with a particular tag. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hastagbase import HasTagBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTag # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTag(HasTagBase): """ Rule that checks for an event with a particular tag. """ - labels = [ _('Tag:') ] - name = _('Events with the ') + + labels = [_("Tag:")] + name = _("Events with the ") description = _("Matches events with the particular tag") diff --git a/gramps/gen/filters/rules/event/_hastype.py b/gramps/gen/filters/rules/event/_hastype.py index a4d5d0d1683..88e721c2602 100644 --- a/gramps/gen/filters/rules/event/_hastype.py +++ b/gramps/gen/filters/rules/event/_hastype.py @@ -18,34 +18,36 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....lib.eventtype import EventType from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasType # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasType(Rule): """Rule that checks for an event of a particular type.""" - labels = [ _('Event type:') ] - name = _('Events with the particular type') + labels = [_("Event type:")] + name = _("Events with the particular type") description = _("Matches events with the particular type ") - category = _('General filters') + category = _("General filters") def apply(self, db, event): if not self.list[0]: diff --git a/gramps/gen/filters/rules/event/_matchesfilter.py b/gramps/gen/filters/rules/event/_matchesfilter.py index 3f529f99914..91bb3d5c13e 100644 --- a/gramps/gen/filters/rules/event/_matchesfilter.py +++ b/gramps/gen/filters/rules/event/_matchesfilter.py @@ -18,29 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesFilter(MatchesFilterBase): """Rule that checks against another filter.""" - name = _('Events matching the ') + name = _("Events matching the ") description = _("Matches events matched by the specified filter name") - namespace = 'Event' + namespace = "Event" diff --git a/gramps/gen/filters/rules/event/_matchespersonfilter.py b/gramps/gen/filters/rules/event/_matchespersonfilter.py index a4640ff4c44..b82cb22e335 100644 --- a/gramps/gen/filters/rules/event/_matchespersonfilter.py +++ b/gramps/gen/filters/rules/event/_matchespersonfilter.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesPersonFilter(MatchesFilterBase): """ Rule that checks against another filter. @@ -47,19 +49,20 @@ class MatchesPersonFilter(MatchesFilterBase): """ - labels = [_('Person filter name:'), _('Include Family events:')] - name = _('Events of persons matching the ') - description = _("Matches events of persons matched by the specified " - "person filter name") - category = _('General filters') + labels = [_("Person filter name:"), _("Include Family events:")] + name = _("Events of persons matching the ") + description = _( + "Matches events of persons matched by the specified " "person filter name" + ) + category = _("General filters") # we want to have this filter show person filters - namespace = 'Person' + namespace = "Person" def prepare(self, db, user): MatchesFilterBase.prepare(self, db, user) - try : + try: if int(self.list[1]): self.MPF_famevents = True else: @@ -67,24 +70,23 @@ def prepare(self, db, user): except IndexError: self.MPF_famevents = False - def apply(self, db, event): filt = self.find_filter() if filt: - for (classname, handle) in db.find_backlink_handles( - event.get_handle(), ['Person']): + for classname, handle in db.find_backlink_handles( + event.get_handle(), ["Person"] + ): if filt.check(db, handle): return True - if self.MPF_famevents : - #also include if family event of the person - for (classname, handle) in db.find_backlink_handles( - event.get_handle(), ['Family']): + if self.MPF_famevents: + # also include if family event of the person + for classname, handle in db.find_backlink_handles( + event.get_handle(), ["Family"] + ): family = db.get_family_from_handle(handle) - if family.father_handle and filt.check(db, - family.father_handle): + if family.father_handle and filt.check(db, family.father_handle): return True - if family.mother_handle and filt.check(db, - family.mother_handle): + if family.mother_handle and filt.check(db, family.mother_handle): return True return False diff --git a/gramps/gen/filters/rules/event/_matchesplacefilter.py b/gramps/gen/filters/rules/event/_matchesplacefilter.py index 240a904f780..b05924b0fd8 100644 --- a/gramps/gen/filters/rules/event/_matchesplacefilter.py +++ b/gramps/gen/filters/rules/event/_matchesplacefilter.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._matchesfilterbase import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesPlaceFilter(MatchesFilterBase): """ Rule that checks against another filter. @@ -46,13 +48,15 @@ class MatchesPlaceFilter(MatchesFilterBase): Subclasses need to define the namespace class attribute. """ - labels = [_('Place filter name:')] - name = _('Events of places matching the ') - description = _("Matches events that occurred at places that match the " - "specified place filter name") - category = _('General filters') + labels = [_("Place filter name:")] + name = _("Events of places matching the ") + description = _( + "Matches events that occurred at places that match the " + "specified place filter name" + ) + category = _("General filters") # we want to have this filter show place filters - namespace = 'Place' + namespace = "Place" def apply(self, db, event): filt = self.find_filter() diff --git a/gramps/gen/filters/rules/event/_matchessourceconfidence.py b/gramps/gen/filters/rules/event/_matchessourceconfidence.py index f3a163e7b9c..3eb293e0fa3 100644 --- a/gramps/gen/filters/rules/event/_matchessourceconfidence.py +++ b/gramps/gen/filters/rules/event/_matchessourceconfidence.py @@ -19,29 +19,32 @@ # # gen.filters.rules/Event/_MatchesSourceConfidence.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._matchessourceconfidencebase import MatchesSourceConfidenceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Confidence level" # Sources of an attribute of an event are ignored -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesSourceConfidence(MatchesSourceConfidenceBase): """Events matching a specific confidence level on its 'direct' source references""" - labels = [_('Confidence level:')] - name = _('Events with at least one direct source >= ') - description = _("Matches events with at least one direct source with confidence level(s)") - + labels = [_("Confidence level:")] + name = _("Events with at least one direct source >= ") + description = _( + "Matches events with at least one direct source with confidence level(s)" + ) diff --git a/gramps/gen/filters/rules/event/_matchessourcefilter.py b/gramps/gen/filters/rules/event/_matchessourcefilter.py index 3c61ea71936..a6a3d635821 100644 --- a/gramps/gen/filters/rules/event/_matchessourcefilter.py +++ b/gramps/gen/filters/rules/event/_matchessourcefilter.py @@ -20,36 +20,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import MatchesSourceFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesSourceFilter(MatchesSourceFilterBase): """ Rule that checks against another filter. """ - labels = [_('Source filter name:')] - name = _('Events with source matching the ') - description = _("Matches events with sources that match the " - "specified source filter name") - category = _('Citation/source filters') + labels = [_("Source filter name:")] + name = _("Events with source matching the ") + description = _( + "Matches events with sources that match the " "specified source filter name" + ) + category = _("Citation/source filters") # we want to have this filter show source filters - namespace = 'Source' + namespace = "Source" diff --git a/gramps/gen/filters/rules/event/_regexpidof.py b/gramps/gen/filters/rules/event/_regexpidof.py index 129c8db7883..fb1e8010795 100644 --- a/gramps/gen/filters/rules/event/_regexpidof.py +++ b/gramps/gen/filters/rules/event/_regexpidof.py @@ -18,32 +18,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._regexpidbase import RegExpIdBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpIdOf(RegExpIdBase): """ Rule that checks for an event whose Gramps ID matches regular expression. """ - name = _('Events with Id containing ') - description = _("Matches events whose Gramps ID matches " - "the regular expression") + name = _("Events with Id containing ") + description = _("Matches events whose Gramps ID matches " "the regular expression") diff --git a/gramps/gen/filters/rules/family/_allfamilies.py b/gramps/gen/filters/rules/family/_allfamilies.py index ec4321667fc..787933f3d8a 100644 --- a/gramps/gen/filters/rules/family/_allfamilies.py +++ b/gramps/gen/filters/rules/family/_allfamilies.py @@ -18,29 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._everything import Everything -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Everyone # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class AllFamilies(Everything): """Matches Everyone""" - name = _('Every family') - description = _('Matches every family in the database') - + name = _("Every family") + description = _("Matches every family in the database") diff --git a/gramps/gen/filters/rules/family/_changedsince.py b/gramps/gen/filters/rules/family/_changedsince.py index 062a8ea3a0e..9bfbc631e25 100644 --- a/gramps/gen/filters/rules/family/_changedsince.py +++ b/gramps/gen/filters/rules/family/_changedsince.py @@ -20,31 +20,35 @@ # gen.filters.rules/Family/_ChangedSince.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._changedsincebase import ChangedSinceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ChangedSince # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChangedSince(ChangedSinceBase): """Rule that checks for families changed since a specific time.""" - labels = [ _('Changed after:'), _('but before:') ] - name = _('Families changed after ') - description = _("Matches family records changed after a specified " - "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " - "date-time is given.") + labels = [_("Changed after:"), _("but before:")] + name = _("Families changed after ") + description = _( + "Matches family records changed after a specified " + "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " + "date-time is given." + ) diff --git a/gramps/gen/filters/rules/family/_childhasidof.py b/gramps/gen/filters/rules/family/_childhasidof.py index 7f04f172651..ab1b2069244 100644 --- a/gramps/gen/filters/rules/family/_childhasidof.py +++ b/gramps/gen/filters/rules/family/_childhasidof.py @@ -18,34 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import RegExpIdBase from ._memberbase import child_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChildHasIdOf(RegExpIdBase): """Rule that checks for a person with a specific Gramps ID""" - labels = [ _('Person ID:') ] - name = _('Families having child with Id containing ') - description = _("Matches families where child has a specified " - "Gramps ID") - category = _('Child filters') + labels = [_("Person ID:")] + name = _("Families having child with Id containing ") + description = _("Matches families where child has a specified " "Gramps ID") + category = _("Child filters") base_class = RegExpIdBase apply = child_base diff --git a/gramps/gen/filters/rules/family/_childhasnameof.py b/gramps/gen/filters/rules/family/_childhasnameof.py index 547ca27ad92..0da60f54884 100644 --- a/gramps/gen/filters/rules/family/_childhasnameof.py +++ b/gramps/gen/filters/rules/family/_childhasnameof.py @@ -18,33 +18,34 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..person import HasNameOf from ._memberbase import child_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChildHasNameOf(HasNameOf): """Rule that checks for full or partial name matches""" - name = _('Families with child with the ') - description = _("Matches families where child has a specified " - "(partial) name") - category = _('Child filters') + name = _("Families with child with the ") + description = _("Matches families where child has a specified " "(partial) name") + category = _("Child filters") base_class = HasNameOf apply = child_base diff --git a/gramps/gen/filters/rules/family/_familyprivate.py b/gramps/gen/filters/rules/family/_familyprivate.py index 0e26bb350fb..962d92fbc54 100644 --- a/gramps/gen/filters/rules/family/_familyprivate.py +++ b/gramps/gen/filters/rules/family/_familyprivate.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._isprivate import IsPrivate -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Family marked private" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class FamilyPrivate(IsPrivate): """Family marked private""" - name = _('Families marked private') + name = _("Families marked private") description = _("Matches families that are indicated as private") diff --git a/gramps/gen/filters/rules/family/_fatherhasidof.py b/gramps/gen/filters/rules/family/_fatherhasidof.py index faa59efc02d..5b8ccf79bbf 100644 --- a/gramps/gen/filters/rules/family/_fatherhasidof.py +++ b/gramps/gen/filters/rules/family/_fatherhasidof.py @@ -18,34 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import RegExpIdBase from ._memberbase import father_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class FatherHasIdOf(RegExpIdBase): """Rule that checks for a person with a specific Gramps ID""" - labels = [ _('Person ID:') ] - name = _('Families having father with Id containing ') - description = _("Matches families whose father has a specified " - "Gramps ID") - category = _('Father filters') + labels = [_("Person ID:")] + name = _("Families having father with Id containing ") + description = _("Matches families whose father has a specified " "Gramps ID") + category = _("Father filters") base_class = RegExpIdBase apply = father_base diff --git a/gramps/gen/filters/rules/family/_fatherhasnameof.py b/gramps/gen/filters/rules/family/_fatherhasnameof.py index 434dfed8608..c9030f313f9 100644 --- a/gramps/gen/filters/rules/family/_fatherhasnameof.py +++ b/gramps/gen/filters/rules/family/_fatherhasnameof.py @@ -18,33 +18,34 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..person import HasNameOf from ._memberbase import father_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class FatherHasNameOf(HasNameOf): """Rule that checks for full or partial name matches""" - name = _('Families with father with the ') - description = _("Matches families whose father has a specified " - "(partial) name") - category = _('Father filters') + name = _("Families with father with the ") + description = _("Matches families whose father has a specified " "(partial) name") + category = _("Father filters") base_class = HasNameOf apply = father_base diff --git a/gramps/gen/filters/rules/family/_hasattribute.py b/gramps/gen/filters/rules/family/_hasattribute.py index 7c169bd35d7..944aa2d34a1 100644 --- a/gramps/gen/filters/rules/family/_hasattribute.py +++ b/gramps/gen/filters/rules/family/_hasattribute.py @@ -18,30 +18,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasattributebase import HasAttributeBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasAttribute # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasAttribute(HasAttributeBase): """Rule that checks for a family with a particular family attribute""" - labels = [ _('Family attribute:'), _('Value:') ] - name = _('Families with the family ') - description = _("Matches families with the family attribute " - "of a particular value") + labels = [_("Family attribute:"), _("Value:")] + name = _("Families with the family ") + description = _( + "Matches families with the family attribute " "of a particular value" + ) diff --git a/gramps/gen/filters/rules/family/_hascitation.py b/gramps/gen/filters/rules/family/_hascitation.py index f34db9df998..9642e899330 100644 --- a/gramps/gen/filters/rules/family/_hascitation.py +++ b/gramps/gen/filters/rules/family/_hascitation.py @@ -22,32 +22,31 @@ """ Filter rule to match family with a particular citation. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hascitationbase import HasCitationBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasEvent # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasCitation(HasCitationBase): """Rule that checks for a family with a particular value""" - labels = [ _('Volume/Page:'), - _('Date:'), - _('Confidence level:')] - name = _('Families with the ') - description = _("Matches families with a citation of a particular " - "value") + labels = [_("Volume/Page:"), _("Date:"), _("Confidence level:")] + name = _("Families with the ") + description = _("Matches families with a citation of a particular " "value") diff --git a/gramps/gen/filters/rules/family/_hasevent.py b/gramps/gen/filters/rules/family/_hasevent.py index 670d13d7156..0662e546707 100644 --- a/gramps/gen/filters/rules/family/_hasevent.py +++ b/gramps/gen/filters/rules/family/_hasevent.py @@ -21,35 +21,39 @@ """ Filter rule to match families with a particular event. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._haseventbase import HasEventBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasEvent # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasEvent(HasEventBase): """Rule that checks for a family event with a particular value""" - labels = [ _('Family event:'), - _('Date:'), - _('Place:'), - _('Description:'), - _('Main Participants') ] - name = _('Families with the ') + labels = [ + _("Family event:"), + _("Date:"), + _("Place:"), + _("Description:"), + _("Main Participants"), + ] + name = _("Families with the ") description = _("Matches families with an event of a particular value") def apply(self, dbase, family): diff --git a/gramps/gen/filters/rules/family/_hasgallery.py b/gramps/gen/filters/rules/family/_hasgallery.py index 21817ce964e..a5ce3411cfa 100644 --- a/gramps/gen/filters/rules/family/_hasgallery.py +++ b/gramps/gen/filters/rules/family/_hasgallery.py @@ -21,26 +21,28 @@ # # gen.filters.rules/Family/_HasGallery.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasgallerybase import HasGalleryBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Families who have media object reference" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasGallery(HasGalleryBase): """Rule that checks for family who has media object reference""" - name = _('Families with media') + name = _("Families with media") description = _("Matches families with a certain number of items in the gallery") diff --git a/gramps/gen/filters/rules/family/_hasidof.py b/gramps/gen/filters/rules/family/_hasidof.py index ac502dbb837..643f511bb05 100644 --- a/gramps/gen/filters/rules/family/_hasidof.py +++ b/gramps/gen/filters/rules/family/_hasidof.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import HasGrampsId -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasIdOf(HasGrampsId): """Rule that checks for a family with a specific Gramps ID""" - name = _('Family with ') + name = _("Family with ") description = _("Matches a family with a specified Gramps ID") diff --git a/gramps/gen/filters/rules/family/_haslds.py b/gramps/gen/filters/rules/family/_haslds.py index 608e3c23705..804f7589255 100644 --- a/gramps/gen/filters/rules/family/_haslds.py +++ b/gramps/gen/filters/rules/family/_haslds.py @@ -21,29 +21,31 @@ # # gen.filters.rules/Family/_HasLDS.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasldsbase import HasLDSBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasLDS # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasLDS(HasLDSBase): """Rule that checks for family with a LDS event""" - name = _('Families with LDS events') + name = _("Families with LDS events") description = _("Matches families with a certain number of LDS events") diff --git a/gramps/gen/filters/rules/family/_hasnote.py b/gramps/gen/filters/rules/family/_hasnote.py index adb40b25634..5a3c981cd1c 100644 --- a/gramps/gen/filters/rules/family/_hasnote.py +++ b/gramps/gen/filters/rules/family/_hasnote.py @@ -21,26 +21,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotebase import HasNoteBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Families having notes" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNote(HasNoteBase): """Families having notes""" - name = _('Families having notes') + name = _("Families having notes") description = _("Matches families having a certain number notes") diff --git a/gramps/gen/filters/rules/family/_hasnotematchingsubstringof.py b/gramps/gen/filters/rules/family/_hasnotematchingsubstringof.py index f540664fedc..5bd9929bf52 100644 --- a/gramps/gen/filters/rules/family/_hasnotematchingsubstringof.py +++ b/gramps/gen/filters/rules/family/_hasnotematchingsubstringof.py @@ -18,27 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotesubstrbase import HasNoteSubstrBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteMatchingSubstringOf(HasNoteSubstrBase): """People having notes containing """ - name = _('Families having notes containing ') + name = _("Families having notes containing ") description = _("Matches families whose notes contain text matching a substring") - diff --git a/gramps/gen/filters/rules/family/_hasnoteregexp.py b/gramps/gen/filters/rules/family/_hasnoteregexp.py index 8635c323043..6734ea9a977 100644 --- a/gramps/gen/filters/rules/family/_hasnoteregexp.py +++ b/gramps/gen/filters/rules/family/_hasnoteregexp.py @@ -18,27 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnoteregexbase import HasNoteRegexBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteRegexp(HasNoteRegexBase): - - name = _('Families having notes containing ') - description = _("Matches families whose notes contain text " - "matching a regular expression") - + name = _("Families having notes containing ") + description = _( + "Matches families whose notes contain text " "matching a regular expression" + ) diff --git a/gramps/gen/filters/rules/family/_hasreferencecountof.py b/gramps/gen/filters/rules/family/_hasreferencecountof.py index 5fb07db5cec..ded1d66d14e 100644 --- a/gramps/gen/filters/rules/family/_hasreferencecountof.py +++ b/gramps/gen/filters/rules/family/_hasreferencecountof.py @@ -18,27 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasreferencecountbase import HasReferenceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Family objects with a certain reference count" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasReferenceCountOf(HasReferenceCountBase): """Family objects with a reference count of """ - name = _('Families with a reference count of ') + name = _("Families with a reference count of ") description = _("Matches family objects with a certain reference count") - diff --git a/gramps/gen/filters/rules/family/_hasreltype.py b/gramps/gen/filters/rules/family/_hasreltype.py index d42477ee48a..b39284d9fd0 100644 --- a/gramps/gen/filters/rules/family/_hasreltype.py +++ b/gramps/gen/filters/rules/family/_hasreltype.py @@ -18,35 +18,38 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....lib.familyreltype import FamilyRelType from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasAttribute # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasRelType(Rule): """Rule that checks for a person with a particular personal attribute""" - labels = [ _('Relationship type:') ] - name = _('Families with the relationship type') - description = _("Matches families with the relationship type " - "of a particular value") - category = _('General filters') + labels = [_("Relationship type:")] + name = _("Families with the relationship type") + description = _( + "Matches families with the relationship type " "of a particular value" + ) + category = _("General filters") def prepare(self, db, user): if self.list[0]: diff --git a/gramps/gen/filters/rules/family/_hassourcecount.py b/gramps/gen/filters/rules/family/_hassourcecount.py index 949350dd926..d81c7cb19e8 100644 --- a/gramps/gen/filters/rules/family/_hassourcecount.py +++ b/gramps/gen/filters/rules/family/_hassourcecount.py @@ -21,26 +21,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hassourcecountbase import HasSourceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Families having sources" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceCount(HasSourceCountBase): """Families with sources""" - name = _('Families with sources') + name = _("Families with sources") description = _("Matches families with a certain number of sources connected to it") diff --git a/gramps/gen/filters/rules/family/_hassourceof.py b/gramps/gen/filters/rules/family/_hassourceof.py index 221ed0ff125..9157d04b426 100644 --- a/gramps/gen/filters/rules/family/_hassourceof.py +++ b/gramps/gen/filters/rules/family/_hassourceof.py @@ -19,30 +19,32 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hassourceofbase import HasSourceOfBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasSourceOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceOf(HasSourceOfBase): """Rule that checks family that have a particular source.""" - labels = [ _('Source ID:') ] - name = _('Families with the ') - category = _('Citation/source filters') - description = _('Matches families who have a particular source') + labels = [_("Source ID:")] + name = _("Families with the ") + category = _("Citation/source filters") + description = _("Matches families who have a particular source") diff --git a/gramps/gen/filters/rules/family/_hastag.py b/gramps/gen/filters/rules/family/_hastag.py index 9114e1a5507..e559fac2122 100644 --- a/gramps/gen/filters/rules/family/_hastag.py +++ b/gramps/gen/filters/rules/family/_hastag.py @@ -21,30 +21,33 @@ Rule that checks for a family with a particular tag. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hastagbase import HasTagBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTag # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTag(HasTagBase): """ Rule that checks for a family with a particular tag. """ - labels = [ _('Tag:') ] - name = _('Families with the ') + + labels = [_("Tag:")] + name = _("Families with the ") description = _("Matches families with the particular tag") diff --git a/gramps/gen/filters/rules/family/_hastwins.py b/gramps/gen/filters/rules/family/_hastwins.py index a6da6c8216e..fdaa8f19647 100644 --- a/gramps/gen/filters/rules/family/_hastwins.py +++ b/gramps/gen/filters/rules/family/_hastwins.py @@ -18,33 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.childreftype import ChildRefType from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTwins # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTwins(Rule): """Rule that checks for a family with twins""" - name = _('Families with twins') + name = _("Families with twins") description = _("Matches families with twins") - category = _('Child filters') + category = _("Child filters") def apply(self, db, family): date_list = [] diff --git a/gramps/gen/filters/rules/family/_isancestorof.py b/gramps/gen/filters/rules/family/_isancestorof.py index 16a71f4a559..f9d9473b7e0 100644 --- a/gramps/gen/filters/rules/family/_isancestorof.py +++ b/gramps/gen/filters/rules/family/_isancestorof.py @@ -23,28 +23,31 @@ Rule that checks for a family that is an ancestor of a specified family. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsAncestorOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsAncestorOf(Rule): """ Rule that checks for a family that is an ancestor of a specified family. """ - labels = [_('ID:'), _('Inclusive:')] - name = _('Ancestor families of ') - category = _('General filters') - description = _('Matches ancestor families of the specified family') + + labels = [_("ID:"), _("Inclusive:")] + name = _("Ancestor families of ") + category = _("General filters") + description = _("Matches ancestor families of the specified family") def prepare(self, db, user): self.map = set() @@ -69,8 +72,7 @@ def init_list(self, db, family, first): if not first: self.map.add(family.handle) - for parent_handle in [family.get_father_handle(), - family.get_mother_handle()]: + for parent_handle in [family.get_father_handle(), family.get_mother_handle()]: if parent_handle: parent = db.get_person_from_handle(parent_handle) family_handle = parent.get_main_parents_family_handle() diff --git a/gramps/gen/filters/rules/family/_isbookmarked.py b/gramps/gen/filters/rules/family/_isbookmarked.py index 8090f04e2cd..d3cfdf40c26 100644 --- a/gramps/gen/filters/rules/family/_isbookmarked.py +++ b/gramps/gen/filters/rules/family/_isbookmarked.py @@ -18,31 +18,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsBookmarked # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsBookmarked(Rule): """Rule that checks for the bookmark list in the database""" - name = _('Bookmarked families') - category = _('General filters') + name = _("Bookmarked families") + category = _("General filters") description = _("Matches the families on the bookmark list") def prepare(self, db, user): diff --git a/gramps/gen/filters/rules/family/_isdescendantof.py b/gramps/gen/filters/rules/family/_isdescendantof.py index bc2d3f7226f..52b0bc48aca 100644 --- a/gramps/gen/filters/rules/family/_isdescendantof.py +++ b/gramps/gen/filters/rules/family/_isdescendantof.py @@ -23,28 +23,31 @@ Rule that checks for a family that is a descendant of a specified family. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsDescendantOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsDescendantOf(Rule): """ Rule that checks for a family that is a descendant of a specified family. """ - labels = [_('ID:'), _('Inclusive:')] - name = _('Descendant families of ') - category = _('General filters') - description = _('Matches descendant families of the specified family') + + labels = [_("ID:"), _("Inclusive:")] + name = _("Descendant families of ") + category = _("General filters") + description = _("Matches descendant families of the specified family") def prepare(self, db, user): self.map = set() diff --git a/gramps/gen/filters/rules/family/_matchesfilter.py b/gramps/gen/filters/rules/family/_matchesfilter.py index 18776837b57..c0f352aac89 100644 --- a/gramps/gen/filters/rules/family/_matchesfilter.py +++ b/gramps/gen/filters/rules/family/_matchesfilter.py @@ -18,29 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesFilter(MatchesFilterBase): """Rule that checks against another filter.""" - name = _('Families matching the ') + name = _("Families matching the ") description = _("Matches families matched by the specified filter name") - namespace = 'Family' + namespace = "Family" diff --git a/gramps/gen/filters/rules/family/_matchessourceconfidence.py b/gramps/gen/filters/rules/family/_matchessourceconfidence.py index baa70d9cbb1..3ec6240708c 100644 --- a/gramps/gen/filters/rules/family/_matchessourceconfidence.py +++ b/gramps/gen/filters/rules/family/_matchessourceconfidence.py @@ -19,28 +19,31 @@ # # gen.filters.rules/Family/_MatchesSourceConfidence.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._matchessourceconfidencebase import MatchesSourceConfidenceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Confidence level" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesSourceConfidence(MatchesSourceConfidenceBase): """Families matching a specific confidence level on its 'direct' source references""" - labels = [_('Confidence level:')] - name = _('Families with at least one direct source >= ') - description = _("Matches families with at least one direct source with confidence level(s)") - + labels = [_("Confidence level:")] + name = _("Families with at least one direct source >= ") + description = _( + "Matches families with at least one direct source with confidence level(s)" + ) diff --git a/gramps/gen/filters/rules/family/_memberbase.py b/gramps/gen/filters/rules/family/_memberbase.py index db8435a8427..a042484ca2f 100644 --- a/gramps/gen/filters/rules/family/_memberbase.py +++ b/gramps/gen/filters/rules/family/_memberbase.py @@ -31,6 +31,7 @@ > apply = child_base """ + def father_base(self, db, family): father_handle = family.get_father_handle() if father_handle: @@ -40,6 +41,7 @@ def father_base(self, db, family): else: return False + def mother_base(self, db, family): mother_handle = family.get_mother_handle() if mother_handle: @@ -49,6 +51,7 @@ def mother_base(self, db, family): else: return False + def child_base(self, db, family): for child_ref in family.get_child_ref_list(): child = db.get_person_from_handle(child_ref.ref) diff --git a/gramps/gen/filters/rules/family/_motherhasidof.py b/gramps/gen/filters/rules/family/_motherhasidof.py index f7559c2fc2c..0c8ea2f6ede 100644 --- a/gramps/gen/filters/rules/family/_motherhasidof.py +++ b/gramps/gen/filters/rules/family/_motherhasidof.py @@ -18,34 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import RegExpIdBase from ._memberbase import mother_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MotherHasIdOf(RegExpIdBase): """Rule that checks for a person with a specific Gramps ID""" - labels = [ _('Person ID:') ] - name = _('Families having mother with Id containing ') - description = _("Matches families whose mother has a specified " - "Gramps ID") - category = _('Mother filters') + labels = [_("Person ID:")] + name = _("Families having mother with Id containing ") + description = _("Matches families whose mother has a specified " "Gramps ID") + category = _("Mother filters") base_class = RegExpIdBase apply = mother_base diff --git a/gramps/gen/filters/rules/family/_motherhasnameof.py b/gramps/gen/filters/rules/family/_motherhasnameof.py index e2eb613b1ef..1872cd46c3a 100644 --- a/gramps/gen/filters/rules/family/_motherhasnameof.py +++ b/gramps/gen/filters/rules/family/_motherhasnameof.py @@ -18,33 +18,34 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..person import HasNameOf from ._memberbase import mother_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MotherHasNameOf(HasNameOf): """Rule that checks for full or partial name matches""" - name = _('Families with mother with the ') - description = _("Matches families whose mother has a specified " - "(partial) name") - category = _('Mother filters') + name = _("Families with mother with the ") + description = _("Matches families whose mother has a specified " "(partial) name") + category = _("Mother filters") base_class = HasNameOf apply = mother_base diff --git a/gramps/gen/filters/rules/family/_regexpchildname.py b/gramps/gen/filters/rules/family/_regexpchildname.py index 7d34dec921d..f0fb746b1c8 100644 --- a/gramps/gen/filters/rules/family/_regexpchildname.py +++ b/gramps/gen/filters/rules/family/_regexpchildname.py @@ -18,33 +18,37 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..person import RegExpName from ._memberbase import child_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # RegExpChildName # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpChildName(RegExpName): """Rule that checks for full or partial name matches""" - name = _('Families with child matching the ') - description = _("Matches families where some child has a name " - "that matches a specified regular expression") - category = _('Child filters') + name = _("Families with child matching the ") + description = _( + "Matches families where some child has a name " + "that matches a specified regular expression" + ) + category = _("Child filters") base_class = RegExpName apply = child_base diff --git a/gramps/gen/filters/rules/family/_regexpfathername.py b/gramps/gen/filters/rules/family/_regexpfathername.py index 2d0afba6e97..6fe0e9dddef 100644 --- a/gramps/gen/filters/rules/family/_regexpfathername.py +++ b/gramps/gen/filters/rules/family/_regexpfathername.py @@ -18,33 +18,37 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..person import RegExpName from ._memberbase import father_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # RegExpFatherName # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpFatherName(RegExpName): """Rule that checks for full or partial name matches""" - name = _('Families with father matching the ') - description = _("Matches families whose father has a name " - "matching a specified regular expression") - category = _('Father filters') + name = _("Families with father matching the ") + description = _( + "Matches families whose father has a name " + "matching a specified regular expression" + ) + category = _("Father filters") base_class = RegExpName apply = father_base diff --git a/gramps/gen/filters/rules/family/_regexpidof.py b/gramps/gen/filters/rules/family/_regexpidof.py index c47c39a0790..ee739059d06 100644 --- a/gramps/gen/filters/rules/family/_regexpidof.py +++ b/gramps/gen/filters/rules/family/_regexpidof.py @@ -18,32 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._regexpidbase import RegExpIdBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpIdOf(RegExpIdBase): """ Rule that checks for a family whose Gramps ID matches regular expression. """ - name = _('Families with Id containing ') - description = _("Matches families whose Gramps ID matches " - "the regular expression") + name = _("Families with Id containing ") + description = _( + "Matches families whose Gramps ID matches " "the regular expression" + ) diff --git a/gramps/gen/filters/rules/family/_regexpmothername.py b/gramps/gen/filters/rules/family/_regexpmothername.py index 3a092e4169c..24378f10757 100644 --- a/gramps/gen/filters/rules/family/_regexpmothername.py +++ b/gramps/gen/filters/rules/family/_regexpmothername.py @@ -18,33 +18,37 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..person import RegExpName from ._memberbase import mother_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # RegExpMotherName # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpMotherName(RegExpName): """Rule that checks for full or partial name matches""" - name = _('Families with mother matching the ') - description = _("Matches families whose mother has a name " - "matching a specified regular expression") - category = _('Mother filters') + name = _("Families with mother matching the ") + description = _( + "Matches families whose mother has a name " + "matching a specified regular expression" + ) + category = _("Mother filters") base_class = RegExpName apply = mother_base diff --git a/gramps/gen/filters/rules/family/_searchchildname.py b/gramps/gen/filters/rules/family/_searchchildname.py index f82c5dd79d1..2450430a287 100644 --- a/gramps/gen/filters/rules/family/_searchchildname.py +++ b/gramps/gen/filters/rules/family/_searchchildname.py @@ -18,33 +18,36 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..person import SearchName from ._memberbase import child_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SearchChildName(SearchName): """Rule that checks for full or partial name matches""" - name = _('Families with any child matching the ') - description = _("Matches families where any child has a specified " - "(partial) name") - category = _('Child filters') + name = _("Families with any child matching the ") + description = _( + "Matches families where any child has a specified " "(partial) name" + ) + category = _("Child filters") base_class = SearchName apply = child_base diff --git a/gramps/gen/filters/rules/family/_searchfathername.py b/gramps/gen/filters/rules/family/_searchfathername.py index ad2041f9893..431717d8cbe 100644 --- a/gramps/gen/filters/rules/family/_searchfathername.py +++ b/gramps/gen/filters/rules/family/_searchfathername.py @@ -18,33 +18,34 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..person import SearchName from ._memberbase import father_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SearchFatherName(SearchName): """Rule that checks for full or partial name matches""" - name = _('Families with father matching the ') - description = _("Matches families whose father has a specified " - "(partial) name") - category = _('Father filters') + name = _("Families with father matching the ") + description = _("Matches families whose father has a specified " "(partial) name") + category = _("Father filters") base_class = SearchName apply = father_base diff --git a/gramps/gen/filters/rules/family/_searchmothername.py b/gramps/gen/filters/rules/family/_searchmothername.py index 5f32e66d47c..8bbca710488 100644 --- a/gramps/gen/filters/rules/family/_searchmothername.py +++ b/gramps/gen/filters/rules/family/_searchmothername.py @@ -18,33 +18,34 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..person import SearchName from ._memberbase import mother_base -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SearchMotherName(SearchName): """Rule that checks for full or partial name matches""" - name = _('Families with mother matching the ') - description = _("Matches families whose mother has a specified " - "(partial) name") - category = _('Mother filters') + name = _("Families with mother matching the ") + description = _("Matches families whose mother has a specified " "(partial) name") + category = _("Mother filters") base_class = SearchName apply = mother_base diff --git a/gramps/gen/filters/rules/media/_allmedia.py b/gramps/gen/filters/rules/media/_allmedia.py index 6146b2a649e..39523f65ac8 100644 --- a/gramps/gen/filters/rules/media/_allmedia.py +++ b/gramps/gen/filters/rules/media/_allmedia.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._everything import Everything -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Everyone # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class AllMedia(Everything): """Matches Everyone""" - name = _('Every media object') - description = _('Matches every media object in the database') + name = _("Every media object") + description = _("Matches every media object in the database") diff --git a/gramps/gen/filters/rules/media/_changedsince.py b/gramps/gen/filters/rules/media/_changedsince.py index 23b594f51d9..ead680ede01 100644 --- a/gramps/gen/filters/rules/media/_changedsince.py +++ b/gramps/gen/filters/rules/media/_changedsince.py @@ -18,31 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._changedsincebase import ChangedSinceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ChangedSince # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChangedSince(ChangedSinceBase): """Rule that checks for media objects changed since a specific time""" - labels = [ _('Changed after:'), _('but before:') ] - name = _('Media objects changed after ') - description = _("Matches media objects changed after a specified " - "date:time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " - "date:time is given.") + labels = [_("Changed after:"), _("but before:")] + name = _("Media objects changed after ") + description = _( + "Matches media objects changed after a specified " + "date:time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " + "date:time is given." + ) diff --git a/gramps/gen/filters/rules/media/_hasattribute.py b/gramps/gen/filters/rules/media/_hasattribute.py index 0773a7b473a..a380dca60bd 100644 --- a/gramps/gen/filters/rules/media/_hasattribute.py +++ b/gramps/gen/filters/rules/media/_hasattribute.py @@ -18,30 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasattributebase import HasAttributeBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasAttribute # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasAttribute(HasAttributeBase): """Rule that checks for a media object with a particular attribute""" - labels = [ _('Media attribute:'), _('Value:') ] - name = _('Media objects with the attribute ') - description = _("Matches media objects with the attribute " - "of a particular value") + labels = [_("Media attribute:"), _("Value:")] + name = _("Media objects with the attribute ") + description = _("Matches media objects with the attribute " "of a particular value") diff --git a/gramps/gen/filters/rules/media/_hascitation.py b/gramps/gen/filters/rules/media/_hascitation.py index d7112fa63c6..72fff19e6a5 100644 --- a/gramps/gen/filters/rules/media/_hascitation.py +++ b/gramps/gen/filters/rules/media/_hascitation.py @@ -21,32 +21,31 @@ """ Filter rule to match persons with a particular citation. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hascitationbase import HasCitationBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasEvent # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasCitation(HasCitationBase): """Rule that checks for a person with a particular value""" - labels = [ _('Volume/Page:'), - _('Date:'), - _('Confidence level:')] - name = _('Media with the ') - description = _("Matches media with a citation of a particular " - "value") + labels = [_("Volume/Page:"), _("Date:"), _("Confidence level:")] + name = _("Media with the ") + description = _("Matches media with a citation of a particular " "value") diff --git a/gramps/gen/filters/rules/media/_hasidof.py b/gramps/gen/filters/rules/media/_hasidof.py index 6e0b0d97810..597473a7846 100644 --- a/gramps/gen/filters/rules/media/_hasidof.py +++ b/gramps/gen/filters/rules/media/_hasidof.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import HasGrampsId -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasIdOf(HasGrampsId): """Rule that checks for a media object with a specific Gramps ID""" - name = _('Media object with ') + name = _("Media object with ") description = _("Matches a media object with a specified Gramps ID") diff --git a/gramps/gen/filters/rules/media/_hasmedia.py b/gramps/gen/filters/rules/media/_hasmedia.py index 5c61c5911c8..49ffc7f3975 100644 --- a/gramps/gen/filters/rules/media/_hasmedia.py +++ b/gramps/gen/filters/rules/media/_hasmedia.py @@ -18,39 +18,41 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....datehandler import parser from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasMedia # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasMedia(Rule): """Rule that checks for a media with a particular value""" - - labels = [ _('Title:'), - _('Type:'), - _('Path:'), - _('Date:'), - ] - name = _('Media objects matching parameters') + labels = [ + _("Title:"), + _("Type:"), + _("Path:"), + _("Date:"), + ] + name = _("Media objects matching parameters") description = _("Matches media objects with particular parameters") - category = _('General filters') + category = _("General filters") allow_regex = True def prepare(self, db, user): @@ -61,7 +63,7 @@ def prepare(self, db, user): except: pass - def apply(self,db, obj): + def apply(self, db, obj): if not self.match_substring(0, obj.get_description()): return False diff --git a/gramps/gen/filters/rules/media/_hasnotematchingsubstringof.py b/gramps/gen/filters/rules/media/_hasnotematchingsubstringof.py index 7b8338f7152..e51fc7fcf55 100644 --- a/gramps/gen/filters/rules/media/_hasnotematchingsubstringof.py +++ b/gramps/gen/filters/rules/media/_hasnotematchingsubstringof.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotesubstrbase import HasNoteSubstrBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Media having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteMatchingSubstringOf(HasNoteSubstrBase): """Media having notes containing """ - name = _('Media objects having notes containing ') - description = _("Matches media objects whose notes contain text " - "matching a substring") - + name = _("Media objects having notes containing ") + description = _( + "Matches media objects whose notes contain text " "matching a substring" + ) diff --git a/gramps/gen/filters/rules/media/_hasnoteregexp.py b/gramps/gen/filters/rules/media/_hasnoteregexp.py index 3d45ee42106..c6b9577372e 100644 --- a/gramps/gen/filters/rules/media/_hasnoteregexp.py +++ b/gramps/gen/filters/rules/media/_hasnoteregexp.py @@ -18,26 +18,29 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnoteregexbase import HasNoteRegexBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Media having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteRegexp(HasNoteRegexBase): - - name = _('Media objects having notes containing ') - description = _("Matches media objects whose notes contain text " - "matching a regular expression") + name = _("Media objects having notes containing ") + description = _( + "Matches media objects whose notes contain text " + "matching a regular expression" + ) diff --git a/gramps/gen/filters/rules/media/_hasreferencecountof.py b/gramps/gen/filters/rules/media/_hasreferencecountof.py index 553cf4d2148..95a67dcaa0f 100644 --- a/gramps/gen/filters/rules/media/_hasreferencecountof.py +++ b/gramps/gen/filters/rules/media/_hasreferencecountof.py @@ -18,27 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasreferencecountbase import HasReferenceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Media objects with a certain reference count" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasReferenceCountOf(HasReferenceCountBase): """Media objects with a reference count of """ - name = _('Media objects with a reference count of ') + name = _("Media objects with a reference count of ") description = _("Matches media objects with a certain reference count") - diff --git a/gramps/gen/filters/rules/media/_hassourcecount.py b/gramps/gen/filters/rules/media/_hassourcecount.py index 08af90a1963..ce901d14f26 100644 --- a/gramps/gen/filters/rules/media/_hassourcecount.py +++ b/gramps/gen/filters/rules/media/_hassourcecount.py @@ -21,26 +21,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hassourcecountbase import HasSourceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People having sources" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceCount(HasSourceCountBase): """Media with sources""" - name = _('Media with sources') + name = _("Media with sources") description = _("Matches media with a certain number of sources connected to it") diff --git a/gramps/gen/filters/rules/media/_hassourceof.py b/gramps/gen/filters/rules/media/_hassourceof.py index d644b8dd6d7..08b911bd833 100644 --- a/gramps/gen/filters/rules/media/_hassourceof.py +++ b/gramps/gen/filters/rules/media/_hassourceof.py @@ -19,30 +19,32 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hassourceofbase import HasSourceOfBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasSourceOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceOf(HasSourceOfBase): """Rule that checks media that have a particular source.""" - labels = [ _('Source ID:') ] - name = _('Media with the ') - category = _('Citation/source filters') - description = _('Matches media who have a particular source') + labels = [_("Source ID:")] + name = _("Media with the ") + category = _("Citation/source filters") + description = _("Matches media who have a particular source") diff --git a/gramps/gen/filters/rules/media/_hastag.py b/gramps/gen/filters/rules/media/_hastag.py index bf56811b939..4ee499396c0 100644 --- a/gramps/gen/filters/rules/media/_hastag.py +++ b/gramps/gen/filters/rules/media/_hastag.py @@ -21,30 +21,33 @@ Rule that checks for a media object with a particular tag. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hastagbase import HasTagBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTag # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTag(HasTagBase): """ Rule that checks for a media object with a particular tag. """ - labels = [ _('Tag:') ] - name = _('Media objects with the ') + + labels = [_("Tag:")] + name = _("Media objects with the ") description = _("Matches media objects with the particular tag") diff --git a/gramps/gen/filters/rules/media/_matchesfilter.py b/gramps/gen/filters/rules/media/_matchesfilter.py index 8613a4761aa..3876677bc02 100644 --- a/gramps/gen/filters/rules/media/_matchesfilter.py +++ b/gramps/gen/filters/rules/media/_matchesfilter.py @@ -18,30 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesFilter(MatchesFilterBase): """Rule that checks against another filter.""" - name = _('Media objects matching the ') - description = _("Matches media objects matched by the " - "specified filter name") - namespace = 'Media' + name = _("Media objects matching the ") + description = _("Matches media objects matched by the " "specified filter name") + namespace = "Media" diff --git a/gramps/gen/filters/rules/media/_matchessourceconfidence.py b/gramps/gen/filters/rules/media/_matchessourceconfidence.py index 290d02a34d4..93e796284ca 100644 --- a/gramps/gen/filters/rules/media/_matchessourceconfidence.py +++ b/gramps/gen/filters/rules/media/_matchessourceconfidence.py @@ -19,27 +19,31 @@ # # Filters/Rules/Person/_MatchesSourceConfidence.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._matchessourceconfidencebase import MatchesSourceConfidenceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Confidence level" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesSourceConfidence(MatchesSourceConfidenceBase): """Media matching a specific confidence level on its 'direct' source references""" - labels = [_('Confidence level:')] - name = _('Media with a direct source >= ') - description = _("Matches media with at least one direct source with confidence level(s)") + labels = [_("Confidence level:")] + name = _("Media with a direct source >= ") + description = _( + "Matches media with at least one direct source with confidence level(s)" + ) diff --git a/gramps/gen/filters/rules/media/_mediaprivate.py b/gramps/gen/filters/rules/media/_mediaprivate.py index a2699285011..38442edc9ff 100644 --- a/gramps/gen/filters/rules/media/_mediaprivate.py +++ b/gramps/gen/filters/rules/media/_mediaprivate.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._isprivate import IsPrivate -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Media marked private" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MediaPrivate(IsPrivate): """Media marked private""" - name = _('Media objects marked private') + name = _("Media objects marked private") description = _("Matches Media objects that are indicated as private") diff --git a/gramps/gen/filters/rules/media/_regexpidof.py b/gramps/gen/filters/rules/media/_regexpidof.py index 9554a9b089a..c579c428eba 100644 --- a/gramps/gen/filters/rules/media/_regexpidof.py +++ b/gramps/gen/filters/rules/media/_regexpidof.py @@ -18,32 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._regexpidbase import RegExpIdBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpIdOf(RegExpIdBase): """ Rule that checks for a media object whose Gramps ID matches regular expression. """ - name = _('Media objects with Id containing ') - description = _("Matches media objects whose Gramps ID matches " - "the regular expression") + name = _("Media objects with Id containing ") + description = _( + "Matches media objects whose Gramps ID matches " "the regular expression" + ) diff --git a/gramps/gen/filters/rules/note/_allnotes.py b/gramps/gen/filters/rules/note/_allnotes.py index 3ae3712d461..13057152780 100644 --- a/gramps/gen/filters/rules/note/_allnotes.py +++ b/gramps/gen/filters/rules/note/_allnotes.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._everything import Everything -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Everyone # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class AllNotes(Everything): """Matches every note""" - name = _('Every note') - description = _('Matches every note in the database') + name = _("Every note") + description = _("Matches every note in the database") diff --git a/gramps/gen/filters/rules/note/_changedsince.py b/gramps/gen/filters/rules/note/_changedsince.py index 7eb9cb00956..a9e81a5696f 100644 --- a/gramps/gen/filters/rules/note/_changedsince.py +++ b/gramps/gen/filters/rules/note/_changedsince.py @@ -20,31 +20,35 @@ # gen.filters.rules/Note/_ChangedSince.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._changedsincebase import ChangedSinceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ChangedSince # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChangedSince(ChangedSinceBase): """Rule that checks for notes changed since a specific time.""" - labels = [ _('Changed after:'), _('but before:') ] - name = _('Notes changed after ') - description = _("Matches note records changed after a specified " - "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " - "date-time is given.") + labels = [_("Changed after:"), _("but before:")] + name = _("Notes changed after ") + description = _( + "Matches note records changed after a specified " + "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " + "date-time is given." + ) diff --git a/gramps/gen/filters/rules/note/_hasidof.py b/gramps/gen/filters/rules/note/_hasidof.py index 845609ebc09..cc1b1b38b1f 100644 --- a/gramps/gen/filters/rules/note/_hasidof.py +++ b/gramps/gen/filters/rules/note/_hasidof.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import HasGrampsId -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasIdOf(HasGrampsId): """Rule that checks for a note with a specific Gramps ID""" - name = _('Note with ') + name = _("Note with ") description = _("Matches a note with a specified Gramps ID") diff --git a/gramps/gen/filters/rules/note/_hasnote.py b/gramps/gen/filters/rules/note/_hasnote.py index 1f15d4ca46f..303e19f767e 100644 --- a/gramps/gen/filters/rules/note/_hasnote.py +++ b/gramps/gen/filters/rules/note/_hasnote.py @@ -18,37 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....lib.notetype import NoteType from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNote # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNote(Rule): """Rule that checks for a note with a particular value""" - - labels = [ _('Text:'), - _('Note type:'), - ] - name = _('Notes matching parameters') + labels = [ + _("Text:"), + _("Note type:"), + ] + name = _("Notes matching parameters") description = _("Matches Notes with particular parameters") - category = _('General filters') + category = _("General filters") allow_regex = True def prepare(self, db, user): @@ -58,7 +60,7 @@ def prepare(self, db, user): else: self.ntype = None - def apply(self,db, note): + def apply(self, db, note): if not self.match_substring(0, note.get()): return False diff --git a/gramps/gen/filters/rules/note/_hasreferencecountof.py b/gramps/gen/filters/rules/note/_hasreferencecountof.py index 8cfe84de937..9330c2c8e89 100644 --- a/gramps/gen/filters/rules/note/_hasreferencecountof.py +++ b/gramps/gen/filters/rules/note/_hasreferencecountof.py @@ -18,27 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasreferencecountbase import HasReferenceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Notes with a certain reference count" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasReferenceCountOf(HasReferenceCountBase): """Notes with a reference count of """ - name = _('Notes with a reference count of ') + name = _("Notes with a reference count of ") description = _("Matches notes with a certain reference count") - diff --git a/gramps/gen/filters/rules/note/_hastag.py b/gramps/gen/filters/rules/note/_hastag.py index 91114546bce..ec3044dd526 100644 --- a/gramps/gen/filters/rules/note/_hastag.py +++ b/gramps/gen/filters/rules/note/_hastag.py @@ -21,30 +21,33 @@ Rule that checks for a note with a particular tag. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hastagbase import HasTagBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTag # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTag(HasTagBase): """ Rule that checks for a note with a particular tag. """ - labels = [ _('Tag:') ] - name = _('Notes with the ') + + labels = [_("Tag:")] + name = _("Notes with the ") description = _("Matches notes with the particular tag") diff --git a/gramps/gen/filters/rules/note/_hastype.py b/gramps/gen/filters/rules/note/_hastype.py index 02276c3ae36..6f4a8adfc68 100644 --- a/gramps/gen/filters/rules/note/_hastype.py +++ b/gramps/gen/filters/rules/note/_hastype.py @@ -18,34 +18,36 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....lib.notetype import NoteType from .. import Rule from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasType # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasType(Rule): """Rule that checks for a note of a particular type.""" - labels = [ _('Note type:') ] - name = _('Notes with the particular type') + labels = [_("Note type:")] + name = _("Notes with the particular type") description = _("Matches notes with the particular type ") - category = _('General filters') + category = _("General filters") def apply(self, db, note): if not self.list[0]: diff --git a/gramps/gen/filters/rules/note/_matchesfilter.py b/gramps/gen/filters/rules/note/_matchesfilter.py index 958824ac784..2abf305126e 100644 --- a/gramps/gen/filters/rules/note/_matchesfilter.py +++ b/gramps/gen/filters/rules/note/_matchesfilter.py @@ -18,30 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesFilter(MatchesFilterBase): """Rule that checks against another filter.""" - name = _('Notes matching the ') - description = _("Matches notes matched " - "by the specified filter name") - namespace = 'Note' + name = _("Notes matching the ") + description = _("Matches notes matched " "by the specified filter name") + namespace = "Note" diff --git a/gramps/gen/filters/rules/note/_matchesregexpof.py b/gramps/gen/filters/rules/note/_matchesregexpof.py index 68e935ebbab..ad8c5ada03f 100644 --- a/gramps/gen/filters/rules/note/_matchesregexpof.py +++ b/gramps/gen/filters/rules/note/_matchesregexpof.py @@ -19,36 +19,38 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import re from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # Notes that contain a substring or match a regular expression -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesRegexpOf(Rule): - - labels = [ _('Text:')] - name = _('Notes containing ') - description = _("Matches notes that contain a substring " - "or match a regular expression") - category = _('General filters') + labels = [_("Text:")] + name = _("Notes containing ") + description = _( + "Matches notes that contain a substring " "or match a regular expression" + ) + category = _("General filters") allow_regex = True def apply(self, db, note): - """ Apply the filter """ + """Apply the filter""" if self.match_substring(0, note.get()): return True return False diff --git a/gramps/gen/filters/rules/note/_matchessubstringof.py b/gramps/gen/filters/rules/note/_matchessubstringof.py index 0583b230dfb..96cafb9fb0f 100644 --- a/gramps/gen/filters/rules/note/_matchessubstringof.py +++ b/gramps/gen/filters/rules/note/_matchessubstringof.py @@ -19,35 +19,36 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Events having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesSubstringOf(Rule): """Notes having notes containing """ - labels = [ _('Substring:')] - name = _('Notes containing ') - description = _("Matches notes that contain text " - "which matches a substring") - category = _('General filters') + labels = [_("Substring:")] + name = _("Notes containing ") + description = _("Matches notes that contain text " "which matches a substring") + category = _("General filters") def apply(self, db, note): - """ Apply the filter """ + """Apply the filter""" text = note.get() if text.upper().find(self.list[0].upper()) != -1: return True diff --git a/gramps/gen/filters/rules/note/_noteprivate.py b/gramps/gen/filters/rules/note/_noteprivate.py index 1c577898467..ac20bef887d 100644 --- a/gramps/gen/filters/rules/note/_noteprivate.py +++ b/gramps/gen/filters/rules/note/_noteprivate.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._isprivate import IsPrivate -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Repo marked private" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class NotePrivate(IsPrivate): """Note marked private""" - name = _('Notes marked private') + name = _("Notes marked private") description = _("Matches notes that are indicated as private") diff --git a/gramps/gen/filters/rules/note/_regexpidof.py b/gramps/gen/filters/rules/note/_regexpidof.py index 9a0945c965f..ec68b932327 100644 --- a/gramps/gen/filters/rules/note/_regexpidof.py +++ b/gramps/gen/filters/rules/note/_regexpidof.py @@ -18,32 +18,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._regexpidbase import RegExpIdBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpIdOf(RegExpIdBase): """ Rule that checks for a note whose Gramps ID matches regular expression. """ - name = _('Notes with Id containing ') - description = _("Matches notes whose Gramps ID matches " - "the regular expression") + name = _("Notes with Id containing ") + description = _("Matches notes whose Gramps ID matches " "the regular expression") diff --git a/gramps/gen/filters/rules/person/__init__.py b/gramps/gen/filters/rules/person/__init__.py index 7812cec52ed..8f993d8b65b 100644 --- a/gramps/gen/filters/rules/person/__init__.py +++ b/gramps/gen/filters/rules/person/__init__.py @@ -73,19 +73,17 @@ from ._isdescendantoffiltermatch import IsDescendantOfFilterMatch from ._isduplicatedancestorof import IsDuplicatedAncestorOf from ._isfemale import IsFemale -from ._islessthannthgenerationancestorof import \ - IsLessThanNthGenerationAncestorOf -from ._islessthannthgenerationancestorofbookmarked import \ - IsLessThanNthGenerationAncestorOfBookmarked -from ._islessthannthgenerationancestorofdefaultperson import \ - IsLessThanNthGenerationAncestorOfDefaultPerson -from ._islessthannthgenerationdescendantof import \ - IsLessThanNthGenerationDescendantOf +from ._islessthannthgenerationancestorof import IsLessThanNthGenerationAncestorOf +from ._islessthannthgenerationancestorofbookmarked import ( + IsLessThanNthGenerationAncestorOfBookmarked, +) +from ._islessthannthgenerationancestorofdefaultperson import ( + IsLessThanNthGenerationAncestorOfDefaultPerson, +) +from ._islessthannthgenerationdescendantof import IsLessThanNthGenerationDescendantOf from ._ismale import IsMale -from ._ismorethannthgenerationancestorof import \ - IsMoreThanNthGenerationAncestorOf -from ._ismorethannthgenerationdescendantof import \ - IsMoreThanNthGenerationDescendantOf +from ._ismorethannthgenerationancestorof import IsMoreThanNthGenerationAncestorOf +from ._ismorethannthgenerationdescendantof import IsMoreThanNthGenerationDescendantOf from ._isparentoffiltermatch import IsParentOfFilterMatch from ._issiblingoffiltermatch import IsSiblingOfFilterMatch from ._isspouseoffiltermatch import IsSpouseOfFilterMatch @@ -113,11 +111,11 @@ from ._isrelatedwith import IsRelatedWith from ._hassoundexname import HasSoundexName -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # This is used by Custom Filter Editor tool # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- editor_rule_list = [ Everyone, IsFemale, @@ -197,4 +195,3 @@ IsRelatedWith, HasSoundexName, ] - diff --git a/gramps/gen/filters/rules/person/_changedsince.py b/gramps/gen/filters/rules/person/_changedsince.py index 341048b0bc6..0a4a047f00a 100644 --- a/gramps/gen/filters/rules/person/_changedsince.py +++ b/gramps/gen/filters/rules/person/_changedsince.py @@ -20,31 +20,35 @@ # gen.filters.rules/Person/_ChangedSince.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._changedsincebase import ChangedSinceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ChangedSince # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChangedSince(ChangedSinceBase): """Rule that checks for persons changed since a specific time.""" - labels = [ _('Changed after:'), _('but before:') ] - name = _('Persons changed after ') - description = _("Matches person records changed after a specified " - "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " - "date-time is given.") + labels = [_("Changed after:"), _("but before:")] + name = _("Persons changed after ") + description = _( + "Matches person records changed after a specified " + "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " + "date-time is given." + ) diff --git a/gramps/gen/filters/rules/person/_deeprelationshippathbetween.py b/gramps/gen/filters/rules/person/_deeprelationshippathbetween.py index b5951bfe3b7..d617b6e36f7 100644 --- a/gramps/gen/filters/rules/person/_deeprelationshippathbetween.py +++ b/gramps/gen/filters/rules/person/_deeprelationshippathbetween.py @@ -20,27 +20,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from collections import deque -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from . import MatchesFilter from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # DeepRelationshipPathBetween # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- def get_family_handle_people(db, exclude_handle, family_handle): @@ -67,8 +68,7 @@ def get_person_family_people(db, person, person_handle): def add_family_handle_list(fam_list): for family_handle in fam_list: - people.update(get_family_handle_people(db, person_handle, - family_handle)) + people.update(get_family_handle_people(db, person_handle, family_handle)) add_family_handle_list(person.get_family_handle_list()) add_family_handle_list(person.get_parent_family_handle_list()) @@ -77,14 +77,14 @@ def add_family_handle_list(fam_list): def find_deep_relations(db, user, person, target_people): - """ This explores all possible paths between a person and one or more + """This explores all possible paths between a person and one or more targets. The algorithm processes paths in a breadth first wave, one remove at a time. The first path that reaches a target causes the target to be marked complete and the path to be stored in the return_paths set. By processing in wave, the return path should be a shortest path. The function stores to do data and intermediate results in an ordered dict, rather than using a recursive algorithm becasue some trees have been found - that exceed the standard python recursive depth. """ + that exceed the standard python recursive depth.""" return_paths = set() # all people in paths between targets and person if person is None: return return_paths @@ -117,9 +117,9 @@ def find_deep_relations(db, user, person, target_people): people = get_person_family_people(db, person, handle) for p_hndl in people: - if p_hndl in done: # check if we have already been here - continue # and ignore if we have - todo.append(p_hndl) # Add to the todo list + if p_hndl in done: # check if we have already been here + continue # and ignore if we have + todo.append(p_hndl) # Add to the todo list done[p_hndl] = handle # Add to the (almost) done list return return_paths @@ -127,18 +127,20 @@ def find_deep_relations(db, user, person, target_people): class DeepRelationshipPathBetween(Rule): """Checks if there is any familial connection between a person and a - filter match by searching over all connections.""" + filter match by searching over all connections.""" - labels = [_('ID:'), _('Filter name:')] + labels = [_("ID:"), _("Filter name:")] name = _("Relationship path between and people matching ") - category = _('Relationship filters') - description = _("Searches over the database starting from a specified" - " person and returns everyone between that person and" - " a set of target people specified with a filter. " - "This produces a set of relationship paths (including" - " by marriage) between the specified person and the" - " target people. Each path is not necessarily" - " the shortest path.") + category = _("Relationship filters") + description = _( + "Searches over the database starting from a specified" + " person and returns everyone between that person and" + " a set of target people specified with a filter. " + "This produces a set of relationship paths (including" + " by marriage) between the specified person and the" + " target people. Each path is not necessarily" + " the shortest path." + ) def prepare(self, db, user): root_person_id = self.list[0] @@ -149,9 +151,11 @@ def prepare(self, db, user): self.filt.requestprepare(db, user) if user: - user.begin_progress(_('Finding relationship paths'), - _('Retrieving all sub-filter matches'), - db.get_number_of_people()) + user.begin_progress( + _("Finding relationship paths"), + _("Retrieving all sub-filter matches"), + db.get_number_of_people(), + ) target_people = [] for handle in db.iter_person_handles(): person = db.get_person_from_handle(handle) @@ -161,11 +165,12 @@ def prepare(self, db, user): user.step_progress() if user: user.end_progress() - user.begin_progress(_('Finding relationship paths'), - _('Evaluating people'), - db.get_number_of_people()) - self.__matches = find_deep_relations(db, user, root_person, - target_people) + user.begin_progress( + _("Finding relationship paths"), + _("Evaluating people"), + db.get_number_of_people(), + ) + self.__matches = find_deep_relations(db, user, root_person, target_people) if user: user.end_progress() diff --git a/gramps/gen/filters/rules/person/_disconnected.py b/gramps/gen/filters/rules/person/_disconnected.py index 448d62cef7e..66b60c28763 100644 --- a/gramps/gen/filters/rules/person/_disconnected.py +++ b/gramps/gen/filters/rules/person/_disconnected.py @@ -18,34 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Disconnected # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Disconnected(Rule): """Matches disconnected people""" - name = _('Disconnected people') - category = _('General filters') - description = _('Matches people that have no family relationships ' - 'to any other person in the database') + name = _("Disconnected people") + category = _("General filters") + description = _( + "Matches people that have no family relationships " + "to any other person in the database" + ) - def apply(self,db,person): - return not (person.get_parent_family_handle_list() - or person.get_family_handle_list()) + def apply(self, db, person): + return not ( + person.get_parent_family_handle_list() or person.get_family_handle_list() + ) diff --git a/gramps/gen/filters/rules/person/_everyone.py b/gramps/gen/filters/rules/person/_everyone.py index b0af0ed5c86..29832d2d676 100644 --- a/gramps/gen/filters/rules/person/_everyone.py +++ b/gramps/gen/filters/rules/person/_everyone.py @@ -18,35 +18,37 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Everyone # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Everyone(Rule): """Match Everyone.""" - name = _('Everyone') - category = _('General filters') - description = _('Matches everyone in the database') + name = _("Everyone") + category = _("General filters") + description = _("Matches everyone in the database") def is_empty(self): return True - def apply(self,db,person): + def apply(self, db, person): return True diff --git a/gramps/gen/filters/rules/person/_familywithincompleteevent.py b/gramps/gen/filters/rules/person/_familywithincompleteevent.py index 657d7a8cf5c..c5ff2bdb3f8 100644 --- a/gramps/gen/filters/rules/person/_familywithincompleteevent.py +++ b/gramps/gen/filters/rules/person/_familywithincompleteevent.py @@ -18,33 +18,36 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Families with incomplete events" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class FamilyWithIncompleteEvent(Rule): """Families with incomplete events""" - name = _('Families with incomplete events') - description = _("Matches people with missing date or " - "place in an event of the family") - category = _('Event filters') + name = _("Families with incomplete events") + description = _( + "Matches people with missing date or " "place in an event of the family" + ) + category = _("Event filters") - def apply(self,db,person): + def apply(self, db, person): for family_handle in person.get_family_handle_list(): family = db.get_family_from_handle(family_handle) if family: diff --git a/gramps/gen/filters/rules/person/_hasaddress.py b/gramps/gen/filters/rules/person/_hasaddress.py index afe12b0a948..6c8b891aec8 100644 --- a/gramps/gen/filters/rules/person/_hasaddress.py +++ b/gramps/gen/filters/rules/person/_hasaddress.py @@ -21,52 +21,53 @@ # # gen.filters.rules/Person/_HasAddress.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasAddress # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasAddress(Rule): """Rule that checks for a person with a personal address""" - labels = [ _('Number of instances:'), _('Number must be:')] - name = _('People with addresses') + labels = [_("Number of instances:"), _("Number must be:")] + name = _("People with addresses") description = _("Matches people with a certain number of personal addresses") - category = _('General filters') - + category = _("General filters") def prepare(self, db, user): # things we want to do just once, not for every handle - if self.list[1] == 'less than': + if self.list[1] == "less than": self.count_type = 0 - elif self.list[1] == 'greater than': + elif self.list[1] == "greater than": self.count_type = 2 else: - self.count_type = 1 # "equal to" + self.count_type = 1 # "equal to" self.userSelectedCount = int(self.list[0]) def apply(self, db, person): - count = len( person.get_address_list()) - if self.count_type == 0: # "less than" + count = len(person.get_address_list()) + if self.count_type == 0: # "less than" return count < self.userSelectedCount - elif self.count_type == 2: # "greater than" + elif self.count_type == 2: # "greater than" return count > self.userSelectedCount # "equal to" return count == self.userSelectedCount diff --git a/gramps/gen/filters/rules/person/_hasaddresstext.py b/gramps/gen/filters/rules/person/_hasaddresstext.py index 0e236bad3e0..a42b973634e 100644 --- a/gramps/gen/filters/rules/person/_hasaddresstext.py +++ b/gramps/gen/filters/rules/person/_hasaddresstext.py @@ -28,6 +28,7 @@ # ------------------------------------------------------------------------- from .. import Rule from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext @@ -39,11 +40,12 @@ class HasAddressText(Rule): """Rule that checks for text in personal addresses""" - labels = [_('Text:')] - name = _('People with an address containing ') - description = _("Matches people with a personal address containing " - "the given text") - category = _('General filters') + labels = [_("Text:")] + name = _("People with an address containing ") + description = _( + "Matches people with a personal address containing " "the given text" + ) + category = _("General filters") allow_regex = True def apply(self, db, person): diff --git a/gramps/gen/filters/rules/person/_hasalternatename.py b/gramps/gen/filters/rules/person/_hasalternatename.py index 2bd3cf1e922..673111879e6 100644 --- a/gramps/gen/filters/rules/person/_hasalternatename.py +++ b/gramps/gen/filters/rules/person/_hasalternatename.py @@ -19,32 +19,34 @@ # # gen.filters.rules/Person/_HasAlternateName.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasAlternateName # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasAlternateName(Rule): """Rule that checks an alternate name""" - name = _('People with an alternate name') + name = _("People with an alternate name") description = _("Matches people with an alternate name") - category = _('General filters') + category = _("General filters") def apply(self, db, person): if person.get_alternate_names(): diff --git a/gramps/gen/filters/rules/person/_hasassociation.py b/gramps/gen/filters/rules/person/_hasassociation.py index b7dfc433bb8..e1d95f8c310 100644 --- a/gramps/gen/filters/rules/person/_hasassociation.py +++ b/gramps/gen/filters/rules/person/_hasassociation.py @@ -21,51 +21,53 @@ # # gen.filters.rules/Person/_HasAssociation.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasAssociation # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasAssociation(Rule): """Rule that checks for a person with a personal association""" - labels = [ _('Number of instances:'), _('Number must be:')] - name = _('People with associations') + labels = [_("Number of instances:"), _("Number must be:")] + name = _("People with associations") description = _("Matches people with a certain number of associations") - category = _('General filters') + category = _("General filters") def prepare(self, db, user): # things we want to do just once, not for every handle - if self.list[1] == 'less than': + if self.list[1] == "less than": self.count_type = 0 - elif self.list[1] == 'greater than': + elif self.list[1] == "greater than": self.count_type = 2 else: - self.count_type = 1 # "equal to" + self.count_type = 1 # "equal to" self.selected_count = int(self.list[0]) def apply(self, db, person): count = len(person.get_person_ref_list()) - if self.count_type == 0: # "less than" + if self.count_type == 0: # "less than" return count < self.selected_count - elif self.count_type == 2: # "greater than" + elif self.count_type == 2: # "greater than" return count > self.selected_count # "equal to" return count == self.selected_count diff --git a/gramps/gen/filters/rules/person/_hasattribute.py b/gramps/gen/filters/rules/person/_hasattribute.py index 2673a1e0d86..b4b4ef77c70 100644 --- a/gramps/gen/filters/rules/person/_hasattribute.py +++ b/gramps/gen/filters/rules/person/_hasattribute.py @@ -18,30 +18,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasattributebase import HasAttributeBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasAttribute # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasAttribute(HasAttributeBase): """Rule that checks for a person with a particular personal attribute""" - labels = [ _('Personal attribute:'), _('Value:') ] - name = _('People with the personal ') - description = _("Matches people with the personal attribute " - "of a particular value") + labels = [_("Personal attribute:"), _("Value:")] + name = _("People with the personal ") + description = _( + "Matches people with the personal attribute " "of a particular value" + ) diff --git a/gramps/gen/filters/rules/person/_hasbirth.py b/gramps/gen/filters/rules/person/_hasbirth.py index adaee24d708..511a61fa829 100644 --- a/gramps/gen/filters/rules/person/_hasbirth.py +++ b/gramps/gen/filters/rules/person/_hasbirth.py @@ -18,37 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....datehandler import parser from ....display.place import displayer as place_displayer from ....lib.eventtype import EventType from ....lib.eventroletype import EventRoleType from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasBirth # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasBirth(Rule): """Rule that checks for a person with a birth of a particular value""" - labels = [ _('Date:'), _('Place:'), _('Description:') ] - name = _('People with the ') + labels = [_("Date:"), _("Place:"), _("Description:")] + name = _("People with the ") description = _("Matches people with birth data of a particular value") - category = _('Event filters') + category = _("Event filters") allow_regex = True def prepare(self, db, user): @@ -57,7 +59,7 @@ def prepare(self, db, user): else: self.date = None - def apply(self,db,person): + def apply(self, db, person): for event_ref in person.get_event_ref_list(): if not event_ref: continue diff --git a/gramps/gen/filters/rules/person/_hascitation.py b/gramps/gen/filters/rules/person/_hascitation.py index d6417aa04cd..ae32d0090ae 100644 --- a/gramps/gen/filters/rules/person/_hascitation.py +++ b/gramps/gen/filters/rules/person/_hascitation.py @@ -21,32 +21,31 @@ """ Filter rule to match persons with a particular citation. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hascitationbase import HasCitationBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasEvent # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasCitation(HasCitationBase): """Rule that checks for a person with a particular value""" - labels = [ _('Volume/Page:'), - _('Date:'), - _('Confidence level:')] - name = _('People with the ') - description = _("Matches people with a citation of a particular " - "value") + labels = [_("Volume/Page:"), _("Date:"), _("Confidence level:")] + name = _("People with the ") + description = _("Matches people with a citation of a particular " "value") diff --git a/gramps/gen/filters/rules/person/_hascommonancestorwith.py b/gramps/gen/filters/rules/person/_hascommonancestorwith.py index ec2eaa7bf4c..cba92f5df10 100644 --- a/gramps/gen/filters/rules/person/_hascommonancestorwith.py +++ b/gramps/gen/filters/rules/person/_hascommonancestorwith.py @@ -18,35 +18,38 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....utils.db import for_each_ancestor from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasCommonAncestorWith # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasCommonAncestorWith(Rule): """Rule that checks for a person that has a common ancestor with a specified person""" - labels = [ _('ID:') ] - name = _('People with a common ancestor with ') + labels = [_("ID:")] + name = _("People with a common ancestor with ") category = _("Ancestral filters") - description = _("Matches people that have a common ancestor " - "with a specified person") + description = _( + "Matches people that have a common ancestor " "with a specified person" + ) def prepare(self, db, user): self.db = db @@ -84,7 +87,9 @@ def add_ancs(self, db, person): if par and par.handle not in self.ancestor_cache: self.add_ancs(db, par) if par: - self.ancestor_cache[person.handle] |= self.ancestor_cache[par.handle] + self.ancestor_cache[person.handle] |= self.ancestor_cache[ + par.handle + ] if parentless_fam: self.ancestor_cache[person.handle].add(fam_handle) @@ -93,10 +98,11 @@ def reset(self): def has_common_ancestor(self, other): for handle in self.with_people: - if ((handle in self.ancestor_cache and - self.ancestor_cache[handle]) & - (other and other.handle in self.ancestor_cache and - self.ancestor_cache[other.handle])): + if (handle in self.ancestor_cache and self.ancestor_cache[handle]) & ( + other + and other.handle in self.ancestor_cache + and self.ancestor_cache[other.handle] + ): return True return False diff --git a/gramps/gen/filters/rules/person/_hascommonancestorwithfiltermatch.py b/gramps/gen/filters/rules/person/_hascommonancestorwithfiltermatch.py index 923792c2306..ec521077b94 100644 --- a/gramps/gen/filters/rules/person/_hascommonancestorwithfiltermatch.py +++ b/gramps/gen/filters/rules/person/_hascommonancestorwithfiltermatch.py @@ -18,36 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....utils.db import for_each_ancestor from ._hascommonancestorwith import HasCommonAncestorWith from ._matchesfilter import MatchesFilter -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasCommonAncestorWithFilterMatch # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasCommonAncestorWithFilterMatch(HasCommonAncestorWith): """Rule that checks for a person that has a common ancestor with someone matching a filter""" - labels = [ _('Filter name:') ] - name = _('People with a common ancestor with match') - description = _("Matches people that have a common ancestor " - "with anybody matched by a filter") + labels = [_("Filter name:")] + name = _("People with a common ancestor with match") + description = _( + "Matches people that have a common ancestor " "with anybody matched by a filter" + ) category = _("Ancestral filters") def __init__(self, list, use_regex=False): @@ -65,17 +68,19 @@ def prepare(self, db, user): self.filt = MatchesFilter(self.list) self.filt.requestprepare(db, user) if user: - user.begin_progress(self.category, - _('Retrieving all sub-filter matches'), - db.get_number_of_people()) + user.begin_progress( + self.category, + _("Retrieving all sub-filter matches"), + db.get_number_of_people(), + ) for handle in db.iter_person_handles(): person = db.get_person_from_handle(handle) if user: user.step_progress() if person and self.filt.apply(db, person): - #store all people in the filter so as to compare later + # store all people in the filter so as to compare later self.with_people.append(person.handle) - #fill list of ancestor of person if not present yet + # fill list of ancestor of person if not present yet if handle not in self.ancestor_cache: self.add_ancs(db, person) if user: diff --git a/gramps/gen/filters/rules/person/_hasdeath.py b/gramps/gen/filters/rules/person/_hasdeath.py index bb04a9c3c66..d22ba288812 100644 --- a/gramps/gen/filters/rules/person/_hasdeath.py +++ b/gramps/gen/filters/rules/person/_hasdeath.py @@ -18,37 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....datehandler import parser from ....display.place import displayer as place_displayer from ....lib.eventroletype import EventRoleType from ....lib.eventtype import EventType from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasDeath # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasDeath(Rule): """Rule that checks for a person with a death of a particular value""" - labels = [ _('Date:'), _('Place:'), _('Description:') ] - name = _('People with the ') + labels = [_("Date:"), _("Place:"), _("Description:")] + name = _("People with the ") description = _("Matches people with death data of a particular value") - category = _('Event filters') + category = _("Event filters") allow_regex = True def prepare(self, db, user): @@ -57,7 +59,7 @@ def prepare(self, db, user): else: self.date = None - def apply(self,db,person): + def apply(self, db, person): for event_ref in person.get_event_ref_list(): if not event_ref: continue diff --git a/gramps/gen/filters/rules/person/_hasevent.py b/gramps/gen/filters/rules/person/_hasevent.py index 23ad3e9b35e..7ac1fad4f67 100644 --- a/gramps/gen/filters/rules/person/_hasevent.py +++ b/gramps/gen/filters/rules/person/_hasevent.py @@ -21,39 +21,42 @@ """ Filter rule to match persons with a particular event. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....lib.eventroletype import EventRoleType from .._haseventbase import HasEventBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasEvent # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasEvent(HasEventBase): """Rule that checks for a person with a particular value""" - labels = [ _('Personal event:'), - _('Date:'), - _('Place:'), - _('Description:'), - _('Main Participants:'), - _('Primary Role:') ] - name = _('People with the personal ') - description = _("Matches people with a personal event of a particular " - "value") + labels = [ + _("Personal event:"), + _("Date:"), + _("Place:"), + _("Description:"), + _("Main Participants:"), + _("Primary Role:"), + ] + name = _("People with the personal ") + description = _("Matches people with a personal event of a particular " "value") def apply(self, dbase, person): for event_ref in person.get_event_ref_list(): diff --git a/gramps/gen/filters/rules/person/_hasfamilyattribute.py b/gramps/gen/filters/rules/person/_hasfamilyattribute.py index a1edd500ce4..e8707b392d7 100644 --- a/gramps/gen/filters/rules/person/_hasfamilyattribute.py +++ b/gramps/gen/filters/rules/person/_hasfamilyattribute.py @@ -18,37 +18,38 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasFamilyAttribute # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasFamilyAttribute(Rule): """Rule that checks for a person with a particular family attribute""" - labels = [ _('Family attribute:'), _('Value:') ] - name = _('People with the family ') - description = _("Matches people with the family attribute " - "of a particular value") - category = _('General filters') + labels = [_("Family attribute:"), _("Value:")] + name = _("People with the family ") + description = _("Matches people with the family attribute " "of a particular value") + category = _("General filters") allow_regex = True - def apply(self,db,person): + def apply(self, db, person): if not self.list[0]: return False for f_id in person.get_family_handle_list(): diff --git a/gramps/gen/filters/rules/person/_hasfamilyevent.py b/gramps/gen/filters/rules/person/_hasfamilyevent.py index 09b4a76c9b5..ff370394f07 100644 --- a/gramps/gen/filters/rules/person/_hasfamilyevent.py +++ b/gramps/gen/filters/rules/person/_hasfamilyevent.py @@ -18,40 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....datehandler import parser from ....display.place import displayer as place_displayer from ....lib.eventtype import EventType from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasFamilyEvent # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasFamilyEvent(Rule): """Rule that checks for a person who has a relationship event with a particular value""" - labels = [ _('Family event:'), - _('Date:'), - _('Place:'), - _('Description:') ] - name = _('People with the family ') + labels = [_("Family event:"), _("Date:"), _("Place:"), _("Description:")] + name = _("People with the family ") description = _("Matches people with a family event of a particular value") - category = _('Event filters') + category = _("Event filters") allow_regex = True def prepare(self, db, user): @@ -62,7 +61,7 @@ def prepare(self, db, user): except: pass - def apply(self,db,person): + def apply(self, db, person): for f_id in person.get_family_handle_list(): f = db.get_family_from_handle(f_id) if not f: diff --git a/gramps/gen/filters/rules/person/_hasgallery.py b/gramps/gen/filters/rules/person/_hasgallery.py index 42a746de2a9..0fadcac073f 100644 --- a/gramps/gen/filters/rules/person/_hasgallery.py +++ b/gramps/gen/filters/rules/person/_hasgallery.py @@ -18,34 +18,36 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasgallerybase import HasGalleryBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People with media object reference " -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HavePhotos(HasGalleryBase): """Rule that checks for person who has media object reference""" - name = _('People with media') + name = _("People with media") description = _("Matches people with a certain number of items in the gallery") def __init__(self, arg, use_regex=False): # Upgrade from pre 3.1 HasPhotos filter, use defaults that correspond # Previous filter had 0 arguments if len(arg) == 0: - HasGalleryBase.__init__(self, ["0", 'greater than'], use_regex) + HasGalleryBase.__init__(self, ["0", "greater than"], use_regex) else: HasGalleryBase.__init__(self, arg, use_regex) diff --git a/gramps/gen/filters/rules/person/_hasidof.py b/gramps/gen/filters/rules/person/_hasidof.py index d34a8c7dc88..ebe5addf6ee 100644 --- a/gramps/gen/filters/rules/person/_hasidof.py +++ b/gramps/gen/filters/rules/person/_hasidof.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import HasGrampsId -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasIdOf(HasGrampsId): """Rule that checks for a person with a specific Gramps ID""" - name = _('Person with ') + name = _("Person with ") description = _("Matches person with a specified Gramps ID") diff --git a/gramps/gen/filters/rules/person/_haslds.py b/gramps/gen/filters/rules/person/_haslds.py index ebb410de9c9..a00636c0cae 100644 --- a/gramps/gen/filters/rules/person/_haslds.py +++ b/gramps/gen/filters/rules/person/_haslds.py @@ -21,29 +21,31 @@ # # gen.filters.rules/Person/_HasLDS.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasldsbase import HasLDSBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasLDS # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasLDS(HasLDSBase): """Rule that checks for a person with a LDS event""" - name = _('People with LDS events') + name = _("People with LDS events") description = _("Matches people with a certain number of LDS events") diff --git a/gramps/gen/filters/rules/person/_hasnameof.py b/gramps/gen/filters/rules/person/_hasnameof.py index 0eb881fe661..2ef2c10dc40 100644 --- a/gramps/gen/filters/rules/person/_hasnameof.py +++ b/gramps/gen/filters/rules/person/_hasnameof.py @@ -19,44 +19,48 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.nameorigintype import NameOriginType -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNameOf(Rule): """Rule that checks for full or partial name matches""" - labels = [_('Given name:'), - _('Full Family name:'), - _('Title:', 'person'), - _('Suffix:'), - _('Call Name:'), - _('Nick Name:'), - _('Prefix:'), - _('Single Surname:'), - _('Connector'), - _('Patronymic:'), - _('Family Nick Name:')] - name = _('People with the ') + labels = [ + _("Given name:"), + _("Full Family name:"), + _("Title:", "person"), + _("Suffix:"), + _("Call Name:"), + _("Nick Name:"), + _("Prefix:"), + _("Single Surname:"), + _("Connector"), + _("Patronymic:"), + _("Family Nick Name:"), + ] + name = _("People with the ") description = _("Matches people with a specified (partial) name") - category = _('General filters') + category = _("General filters") allow_regex = True def apply(self, db, person): @@ -78,7 +82,9 @@ def match_name(self, name): return False elif self.list[5] and not self.match_substring(5, name.get_nick_name()): return False - elif self.list[10] and not self.match_substring(10, name.get_family_nick_name()): + elif self.list[10] and not self.match_substring( + 10, name.get_family_nick_name() + ): return False else: for surn in name.get_surname_list(): diff --git a/gramps/gen/filters/rules/person/_hasnameorigintype.py b/gramps/gen/filters/rules/person/_hasnameorigintype.py index 276356363b1..a56ac932289 100644 --- a/gramps/gen/filters/rules/person/_hasnameorigintype.py +++ b/gramps/gen/filters/rules/person/_hasnameorigintype.py @@ -19,34 +19,36 @@ # # gen.filters.rules/Person/_HasNameOriginType.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.nameorigintype import NameOriginType -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOriginType # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNameOriginType(Rule): """Rule that checks the type of Surname origin""" - labels = [ _('Surname origin type:')] - name = _('People with the ') + labels = [_("Surname origin type:")] + name = _("People with the ") description = _("Matches people with a surname origin") - category = _('General filters') + category = _("General filters") def apply(self, db, person): if not self.list[0]: diff --git a/gramps/gen/filters/rules/person/_hasnametype.py b/gramps/gen/filters/rules/person/_hasnametype.py index a8e50c2e1a9..95738c54020 100644 --- a/gramps/gen/filters/rules/person/_hasnametype.py +++ b/gramps/gen/filters/rules/person/_hasnametype.py @@ -19,34 +19,36 @@ # # gen.filters.rules/Person/_HasNameType.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.nametype import NameType -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameType # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNameType(Rule): """Rule that checks the type of name""" - labels = [ _('Name type:')] - name = _('People with the ') + labels = [_("Name type:")] + name = _("People with the ") description = _("Matches people with a type of name") - category = _('General filters') + category = _("General filters") def apply(self, db, person): if not self.list[0]: diff --git a/gramps/gen/filters/rules/person/_hasnickname.py b/gramps/gen/filters/rules/person/_hasnickname.py index fb90eae022b..48f7da04057 100644 --- a/gramps/gen/filters/rules/person/_hasnickname.py +++ b/gramps/gen/filters/rules/person/_hasnickname.py @@ -19,32 +19,34 @@ # # gen.filters.rules/Person/_HasNickname.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNickname # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNickname(Rule): """Rule that checks a nickname""" - name = _('People with a nickname') + name = _("People with a nickname") description = _("Matches people with a nickname") - category = _('General filters') + category = _("General filters") def apply(self, db, person): if person.get_nick_name(): diff --git a/gramps/gen/filters/rules/person/_hasnote.py b/gramps/gen/filters/rules/person/_hasnote.py index bb2c66f4274..2f1659e68f4 100644 --- a/gramps/gen/filters/rules/person/_hasnote.py +++ b/gramps/gen/filters/rules/person/_hasnote.py @@ -21,26 +21,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotebase import HasNoteBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People having notes" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNote(HasNoteBase): """People having notes""" - name = _('People having notes') + name = _("People having notes") description = _("Matches people having a certain number of notes") diff --git a/gramps/gen/filters/rules/person/_hasnotematchingsubstringof.py b/gramps/gen/filters/rules/person/_hasnotematchingsubstringof.py index 8f2852bb0e0..ead24509a75 100644 --- a/gramps/gen/filters/rules/person/_hasnotematchingsubstringof.py +++ b/gramps/gen/filters/rules/person/_hasnotematchingsubstringof.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotesubstrbase import HasNoteSubstrBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteMatchingSubstringOf(HasNoteSubstrBase): """People having notes containing """ - name = _('People having notes containing ') + name = _("People having notes containing ") description = _("Matches people whose notes contain text matching a substring") diff --git a/gramps/gen/filters/rules/person/_hasnoteregexp.py b/gramps/gen/filters/rules/person/_hasnoteregexp.py index 70fafffeb6d..855872ac65d 100644 --- a/gramps/gen/filters/rules/person/_hasnoteregexp.py +++ b/gramps/gen/filters/rules/person/_hasnoteregexp.py @@ -18,27 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnoteregexbase import HasNoteRegexBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteRegexp(HasNoteRegexBase): - - name = _('People having notes containing ') - description = _("Matches people whose notes contain text " - "matching a regular expression") - + name = _("People having notes containing ") + description = _( + "Matches people whose notes contain text " "matching a regular expression" + ) diff --git a/gramps/gen/filters/rules/person/_hasothergender.py b/gramps/gen/filters/rules/person/_hasothergender.py index eba966bf08a..1d8533f03be 100644 --- a/gramps/gen/filters/rules/person/_hasothergender.py +++ b/gramps/gen/filters/rules/person/_hasothergender.py @@ -18,33 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.person import Person -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasOtherGender # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasOtherGender(Rule): """Rule that checks for a person that has other gender""" - name = _('People who are neither male nor female') - category = _('General filters') - description = _('Matches all people with other gender') + name = _("People who are neither male nor female") + category = _("General filters") + description = _("Matches all people with other gender") def apply(self, db, person): return person.gender == Person.OTHER diff --git a/gramps/gen/filters/rules/person/_hasrelationship.py b/gramps/gen/filters/rules/person/_hasrelationship.py index fd376cd70f8..79ae775f9f9 100644 --- a/gramps/gen/filters/rules/person/_hasrelationship.py +++ b/gramps/gen/filters/rules/person/_hasrelationship.py @@ -18,38 +18,42 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.familyreltype import FamilyRelType -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasRelationship # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasRelationship(Rule): """Rule that checks for a person who has a particular relationship""" - labels = [ _('Number of relationships:'), - _('Relationship type:'), - _('Number of children:') ] - name = _('People with the ') + labels = [ + _("Number of relationships:"), + _("Relationship type:"), + _("Number of children:"), + ] + name = _("People with the ") description = _("Matches people with a particular relationship") - category = _('Family filters') + category = _("Family filters") - def apply(self,db,person): + def apply(self, db, person): rel_type = 0 cnt = 0 num_rel = len(person.get_family_handle_list()) diff --git a/gramps/gen/filters/rules/person/_hassoundexname.py b/gramps/gen/filters/rules/person/_hassoundexname.py index 09634e321f5..199c2401cdb 100644 --- a/gramps/gen/filters/rules/person/_hassoundexname.py +++ b/gramps/gen/filters/rules/person/_hassoundexname.py @@ -18,32 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.nameorigintype import NameOriginType from ....soundex import soundex from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSoundexName(Rule): """Rule that checks for full or partial name matches""" - labels = [_('Name:')] - name = _('Soundex match of People with the ') - description = _("Soundex Match of people with a specified name. First " - "name, Surname, Call name, and Nickname are searched in " - "primary and alternate names.") - category = _('General filters') + labels = [_("Name:")] + name = _("Soundex match of People with the ") + description = _( + "Soundex Match of people with a specified name. First " + "name, Surname, Call name, and Nickname are searched in " + "primary and alternate names." + ) + category = _("General filters") allow_regex = False def apply(self, db, person): diff --git a/gramps/gen/filters/rules/person/_hassourcecount.py b/gramps/gen/filters/rules/person/_hassourcecount.py index 97a655d1f02..b880c3a2f68 100644 --- a/gramps/gen/filters/rules/person/_hassourcecount.py +++ b/gramps/gen/filters/rules/person/_hassourcecount.py @@ -21,26 +21,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hassourcecountbase import HasSourceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People having sources" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceCount(HasSourceCountBase): """People with sources""" - name = _('People with sources') + name = _("People with sources") description = _("Matches people with a certain number of sources connected to it") diff --git a/gramps/gen/filters/rules/person/_hassourceof.py b/gramps/gen/filters/rules/person/_hassourceof.py index 057725b9058..420bb0bf710 100644 --- a/gramps/gen/filters/rules/person/_hassourceof.py +++ b/gramps/gen/filters/rules/person/_hassourceof.py @@ -19,30 +19,32 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hassourceofbase import HasSourceOfBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasSourceOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceOf(HasSourceOfBase): """Rule that checks people that have a particular source.""" - labels = [ _('Source ID:') ] - name = _('People with the ') - category = _('Citation/source filters') - description = _('Matches people who have a particular source') + labels = [_("Source ID:")] + name = _("People with the ") + category = _("Citation/source filters") + description = _("Matches people who have a particular source") diff --git a/gramps/gen/filters/rules/person/_hastag.py b/gramps/gen/filters/rules/person/_hastag.py index b1f9a7b2148..2378b9a9f0d 100644 --- a/gramps/gen/filters/rules/person/_hastag.py +++ b/gramps/gen/filters/rules/person/_hastag.py @@ -21,30 +21,33 @@ Rule that checks for a person with a particular tag. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hastagbase import HasTagBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTag # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTag(HasTagBase): """ Rule that checks for a person with a particular tag. """ - labels = [ _('Tag:') ] - name = _('People with the ') + + labels = [_("Tag:")] + name = _("People with the ") description = _("Matches people with the particular tag") diff --git a/gramps/gen/filters/rules/person/_hastextmatchingregexpof.py b/gramps/gen/filters/rules/person/_hastextmatchingregexpof.py index 3eda27fb0f7..46c3177038a 100644 --- a/gramps/gen/filters/rules/person/_hastextmatchingregexpof.py +++ b/gramps/gen/filters/rules/person/_hastextmatchingregexpof.py @@ -18,27 +18,29 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ._hastextmatchingsubstringof import HasTextMatchingSubstringOf -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "HasTextMatchingRegexOf" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTextMatchingRegexpOf(HasTextMatchingSubstringOf): """This is wrapping HasTextMatchingSubstringOf to enable the regex_match parameter. """ + def __init__(self, list, use_regex=False): HasTextMatchingSubstringOf.__init__(self, list, use_regex) diff --git a/gramps/gen/filters/rules/person/_hastextmatchingsubstringof.py b/gramps/gen/filters/rules/person/_hastextmatchingsubstringof.py index fd3387eba47..7aa4c2aaa78 100644 --- a/gramps/gen/filters/rules/person/_hastextmatchingsubstringof.py +++ b/gramps/gen/filters/rules/person/_hastextmatchingsubstringof.py @@ -19,36 +19,37 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext import logging + LOG = logging.getLogger(".citationfilter") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....utils.db import get_source_and_citation_referents from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "HasTextMatchingSubstringOf" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTextMatchingSubstringOf(Rule): """Rule that checks for string matches in any textual information""" - labels = [ _('Substring:'), - _('Case sensitive:')] - name = _('People with records containing ') - description = _("Matches people whose records contain text " - "matching a substring") - category = _('General filters') + labels = [_("Substring:"), _("Case sensitive:")] + name = _("People with records containing ") + description = _("Matches people whose records contain text " "matching a substring") + category = _("General filters") allow_regex = True def prepare(self, db, user): @@ -79,29 +80,35 @@ def reset(self): self.place_map.clear() self.media_map.clear() - def apply(self,db,person): - if person.handle in self.person_map: # Cached by matching Source? + def apply(self, db, person): + if person.handle in self.person_map: # Cached by matching Source? return True - if self.match_object(person): # first match the person itself + if self.match_object(person): # first match the person itself return True # Look for matching events - if any(self.search_event(event_ref.ref) - for event_ref in person.get_event_ref_list()): - return True + if any( + self.search_event(event_ref.ref) + for event_ref in person.get_event_ref_list() + ): + return True # Look for matching families - if any(self.search_family(family_handle) - for family_handle in person.get_family_handle_list()): - return True + if any( + self.search_family(family_handle) + for family_handle in person.get_family_handle_list() + ): + return True # Look for matching media objects - if any(self.search_media(media_ref.get_reference_handle()) - for media_ref in person.get_media_list()): - return True + if any( + self.search_media(media_ref.get_reference_handle()) + for media_ref in person.get_media_list() + ): + return True return False - def search_family(self,family_handle): + def search_family(self, family_handle): if not family_handle: return False # search inside the family and cache the result to not search a family twice @@ -111,17 +118,21 @@ def search_family(self,family_handle): if self.match_object(family): match = 1 else: - if any(self.search_event(event_ref.ref) - for event_ref in family.get_event_ref_list()): - match = 1 - if any(self.search_media(media_ref.get_reference_handle()) - for media_ref in family.get_media_list()): - return True + if any( + self.search_event(event_ref.ref) + for event_ref in family.get_event_ref_list() + ): + match = 1 + if any( + self.search_media(media_ref.get_reference_handle()) + for media_ref in family.get_media_list() + ): + return True if match: self.family_map.add(family_handle) return family_handle in self.family_map - def search_event(self,event_handle): + def search_event(self, event_handle): if not event_handle: return False # search inside the event and cache the result (event sharing) @@ -134,14 +145,16 @@ def search_event(self,event_handle): place_handle = event.get_place_handle() if place_handle and self.search_place(place_handle): match = 1 - if any(self.search_media(media_ref.get_reference_handle()) - for media_ref in event.get_media_list()): - return True + if any( + self.search_media(media_ref.get_reference_handle()) + for media_ref in event.get_media_list() + ): + return True if match: self.event_map.add(event_handle) return event_handle in self.event_map - def search_place(self,place_handle): + def search_place(self, place_handle): if not place_handle: return False # search inside the place and cache the result @@ -151,7 +164,7 @@ def search_place(self,place_handle): self.place_map.add(place_handle) return place_handle in self.place_map - def search_media(self,media_handle): + def search_media(self, media_handle): if not media_handle: return False # search inside the media object and cache the result @@ -164,40 +177,58 @@ def search_media(self,media_handle): def cache_repos(self): # search all matching repositories self.repo_map.update( - - repo.handle for repo in self.db.iter_repositories() - if repo and self.match_object(repo) - - ) + repo.handle + for repo in self.db.iter_repositories() + if repo and self.match_object(repo) + ) def cache_sources(self): # search all sources and match all referents of a matching source for source in self.db.iter_sources(): match = self.match_object(source) - LOG.debug("cache_sources match %s string %s source %s" % - (match, self.list[0], source.gramps_id)) + LOG.debug( + "cache_sources match %s string %s source %s" + % (match, self.list[0], source.gramps_id) + ) if not match: - if any(reporef.get_reference_handle() in self.repo_map - for reporef in source.get_reporef_list() - ): + if any( + reporef.get_reference_handle() in self.repo_map + for reporef in source.get_reporef_list() + ): match = True - LOG.debug("cache_sources repomatch %s string %s source %s" % - (match, self.list[0], source.gramps_id)) - (citation_list, citation_referents_list) = \ - get_source_and_citation_referents(source.handle, self.db) - LOG.debug("the_lists %s %s" % - (citation_list, citation_referents_list)) - for (citation_handle, refs) in citation_referents_list: + LOG.debug( + "cache_sources repomatch %s string %s source %s" + % (match, self.list[0], source.gramps_id) + ) + ( + citation_list, + citation_referents_list, + ) = get_source_and_citation_referents(source.handle, self.db) + LOG.debug("the_lists %s %s" % (citation_list, citation_referents_list)) + for citation_handle, refs in citation_referents_list: citation = self.db.get_citation_from_handle(citation_handle) - LOG.debug("cache_sources match %s matchcitation %s string %s" - " source %s citation %s" % - (match, self.match_object(citation), - self.list[0], source.gramps_id, - citation.gramps_id)) + LOG.debug( + "cache_sources match %s matchcitation %s string %s" + " source %s citation %s" + % ( + match, + self.match_object(citation), + self.list[0], + source.gramps_id, + citation.gramps_id, + ) + ) if match or self.match_object(citation): # Update the maps to reflect the reference - (person_list, family_list, event_list, place_list, - source_list, media_list, repo_list) = refs + ( + person_list, + family_list, + event_list, + place_list, + source_list, + media_list, + repo_list, + ) = refs self.person_map.update(person_list) self.family_map.update(family_list) self.event_map.update(event_list) @@ -209,5 +240,5 @@ def match_object(self, obj): if not obj: return False if self.use_regex: - return obj.matches_regexp(self.list[0],self.case_sensitive) - return obj.matches_string(self.list[0],self.case_sensitive) + return obj.matches_regexp(self.list[0], self.case_sensitive) + return obj.matches_string(self.list[0], self.case_sensitive) diff --git a/gramps/gen/filters/rules/person/_hasunknowngender.py b/gramps/gen/filters/rules/person/_hasunknowngender.py index 61cb2e94005..5c25eb8995e 100644 --- a/gramps/gen/filters/rules/person/_hasunknowngender.py +++ b/gramps/gen/filters/rules/person/_hasunknowngender.py @@ -18,33 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.person import Person -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasUnknownGender # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasUnknownGender(Rule): """Rule that checks for a person that has unknown gender""" - name = _('People with unknown gender') - category = _('General filters') - description = _('Matches all people with unknown gender') + name = _("People with unknown gender") + category = _("General filters") + description = _("Matches all people with unknown gender") - def apply(self,db,person): + def apply(self, db, person): return person.gender == Person.UNKNOWN diff --git a/gramps/gen/filters/rules/person/_havealtfamilies.py b/gramps/gen/filters/rules/person/_havealtfamilies.py index 80c1c96b575..41c6b468273 100644 --- a/gramps/gen/filters/rules/person/_havealtfamilies.py +++ b/gramps/gen/filters/rules/person/_havealtfamilies.py @@ -18,39 +18,46 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.childreftype import ChildRefType -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People who were adopted" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HaveAltFamilies(Rule): """People who were adopted""" - name = _('Adopted people') + name = _("Adopted people") description = _("Matches people who were adopted") - category = _('Family filters') + category = _("Family filters") - def apply(self,db,person): + def apply(self, db, person): for fhandle in person.get_parent_family_handle_list(): family = db.get_family_from_handle(fhandle) if family: - ref = [ ref for ref in family.get_child_ref_list() \ - if ref.ref == person.handle] - if ref[0].get_father_relation() == ChildRefType.ADOPTED \ - or ref[0].get_mother_relation() == ChildRefType.ADOPTED: + ref = [ + ref + for ref in family.get_child_ref_list() + if ref.ref == person.handle + ] + if ( + ref[0].get_father_relation() == ChildRefType.ADOPTED + or ref[0].get_mother_relation() == ChildRefType.ADOPTED + ): return True return False diff --git a/gramps/gen/filters/rules/person/_havechildren.py b/gramps/gen/filters/rules/person/_havechildren.py index 24b823cfd9c..3753d7a8a3a 100644 --- a/gramps/gen/filters/rules/person/_havechildren.py +++ b/gramps/gen/filters/rules/person/_havechildren.py @@ -19,33 +19,34 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # "People with children" # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HaveChildren(Rule): """People with children""" - name = _('People with children') + name = _("People with children") description = _("Matches people who have children") - category = _('Family filters') + category = _("Family filters") def apply(self, db, person): for family_handle in person.get_family_handle_list(): diff --git a/gramps/gen/filters/rules/person/_incompletenames.py b/gramps/gen/filters/rules/person/_incompletenames.py index c0a86b4eb1b..3e11c52b760 100644 --- a/gramps/gen/filters/rules/person/_incompletenames.py +++ b/gramps/gen/filters/rules/person/_incompletenames.py @@ -18,34 +18,36 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IncompleteNames # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IncompleteNames(Rule): """People with incomplete names""" - name = _('People with incomplete names') + name = _("People with incomplete names") description = _("Matches people with firstname or lastname missing") - category = _('General filters') + category = _("General filters") - def apply(self,db,person): + def apply(self, db, person): for name in [person.get_primary_name()] + person.get_alternate_names(): if name.get_first_name().strip() == "": return True diff --git a/gramps/gen/filters/rules/person/_isancestorof.py b/gramps/gen/filters/rules/person/_isancestorof.py index 5785783bfbf..ac2668b4a66 100644 --- a/gramps/gen/filters/rules/person/_isancestorof.py +++ b/gramps/gen/filters/rules/person/_isancestorof.py @@ -18,31 +18,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsAncestorOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsAncestorOf(Rule): """Rule that checks for a person that is an ancestor of a specified person""" - labels = [ _('ID:'), _('Inclusive:') ] - name = _('Ancestors of ') + labels = [_("ID:"), _("Inclusive:")] + name = _("Ancestors of ") category = _("Ancestral filters") description = _("Matches people that are ancestors of a specified person") @@ -56,7 +58,7 @@ def prepare(self, db, user): first = 1 try: root_person = db.get_person_from_gramps_id(self.list[0]) - self.init_ancestor_list(db,root_person,first) + self.init_ancestor_list(db, root_person, first) except: pass @@ -66,7 +68,7 @@ def reset(self): def apply(self, db, person): return person.handle in self.map - def init_ancestor_list(self, db, person,first): + def init_ancestor_list(self, db, person, first): if not person: return if person.handle in self.map: @@ -81,6 +83,6 @@ def init_ancestor_list(self, db, person,first): m_id = fam.get_mother_handle() if f_id: - self.init_ancestor_list(db,db.get_person_from_handle(f_id),0) + self.init_ancestor_list(db, db.get_person_from_handle(f_id), 0) if m_id: - self.init_ancestor_list(db,db.get_person_from_handle(m_id),0) + self.init_ancestor_list(db, db.get_person_from_handle(m_id), 0) diff --git a/gramps/gen/filters/rules/person/_isancestoroffiltermatch.py b/gramps/gen/filters/rules/person/_isancestoroffiltermatch.py index 119fe9de584..ff7b6ea5bc2 100644 --- a/gramps/gen/filters/rules/person/_isancestoroffiltermatch.py +++ b/gramps/gen/filters/rules/person/_isancestoroffiltermatch.py @@ -18,36 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ._isancestorof import IsAncestorOf from ._matchesfilter import MatchesFilter -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsAncestorOfFilterMatch # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsAncestorOfFilterMatch(IsAncestorOf): """Rule that checks for a person that is an ancestor of someone matched by a filter""" - labels = [ _('Filter name:') ] - name = _('Ancestors of match') + labels = [_("Filter name:")] + name = _("Ancestors of match") category = _("Ancestral filters") - description = _("Matches people that are ancestors " - "of anybody matched by a filter") + description = _( + "Matches people that are ancestors " "of anybody matched by a filter" + ) def prepare(self, db, user): self.db = db @@ -63,9 +66,11 @@ def prepare(self, db, user): self.filt = MatchesFilter(self.list[0:1]) self.filt.requestprepare(db, user) if user: - user.begin_progress(self.category, - _('Retrieving all sub-filter matches'), - db.get_number_of_people()) + user.begin_progress( + self.category, + _("Retrieving all sub-filter matches"), + db.get_number_of_people(), + ) for person in db.iter_people(): if user: user.step_progress() @@ -78,5 +83,5 @@ def reset(self): self.filt.requestreset() self.map.clear() - def apply(self,db,person): + def apply(self, db, person): return person.handle in self.map diff --git a/gramps/gen/filters/rules/person/_isbookmarked.py b/gramps/gen/filters/rules/person/_isbookmarked.py index e7763b67cd3..715cefcca3f 100644 --- a/gramps/gen/filters/rules/person/_isbookmarked.py +++ b/gramps/gen/filters/rules/person/_isbookmarked.py @@ -19,35 +19,37 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsBookmarked # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsBookmarked(Rule): """Rule that checks for the bookmark list in the database""" - name = _('Bookmarked people') - category = _('General filters') + name = _("Bookmarked people") + category = _("General filters") description = _("Matches the people on the bookmark list") def prepare(self, db, user): self.bookmarks = db.get_bookmarks().get() - def apply(self,db,person): + def apply(self, db, person): return person.handle in self.bookmarks diff --git a/gramps/gen/filters/rules/person/_ischildoffiltermatch.py b/gramps/gen/filters/rules/person/_ischildoffiltermatch.py index bdb29550e76..fa737f26522 100644 --- a/gramps/gen/filters/rules/person/_ischildoffiltermatch.py +++ b/gramps/gen/filters/rules/person/_ischildoffiltermatch.py @@ -18,34 +18,36 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ._matchesfilter import MatchesFilter -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsChildOfFilterMatch # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsChildOfFilterMatch(Rule): """Rule that checks for a person that is a child of someone matched by a filter""" - labels = [ _('Filter name:') ] - name = _('Children of match') - category = _('Family filters') + labels = [_("Filter name:")] + name = _("Children of match") + category = _("Family filters") description = _("Matches children of anybody matched by a filter") def prepare(self, db, user): @@ -54,9 +56,11 @@ def prepare(self, db, user): self.filt = MatchesFilter(self.list) self.filt.requestprepare(db, user) if user: - user.begin_progress(self.category, - _('Retrieving all sub-filter matches'), - db.get_number_of_people()) + user.begin_progress( + self.category, + _("Retrieving all sub-filter matches"), + db.get_number_of_people(), + ) for person in db.iter_people(): if user: user.step_progress() @@ -69,14 +73,13 @@ def reset(self): self.filt.requestreset() self.map.clear() - def apply(self,db,person): + def apply(self, db, person): return person.handle in self.map - def init_list(self,person): + def init_list(self, person): if not person: return for fam_id in person.get_family_handle_list(): fam = self.db.get_family_from_handle(fam_id) if fam: - self.map.update(child_ref.ref - for child_ref in fam.get_child_ref_list()) + self.map.update(child_ref.ref for child_ref in fam.get_child_ref_list()) diff --git a/gramps/gen/filters/rules/person/_isdefaultperson.py b/gramps/gen/filters/rules/person/_isdefaultperson.py index 30fd3dd39cd..2b58ed43d41 100644 --- a/gramps/gen/filters/rules/person/_isdefaultperson.py +++ b/gramps/gen/filters/rules/person/_isdefaultperson.py @@ -18,31 +18,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsDefaultPerson # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsDefaultPerson(Rule): """Rule that checks for a default person in the database""" - name = _('Home Person') - category = _('General filters') + name = _("Home Person") + category = _("General filters") description = _("Matches the Home Person") def prepare(self, db, user): @@ -51,7 +53,7 @@ def prepare(self, db, user): self.def_handle = p.get_handle() self.apply = self.apply_real else: - self.apply = lambda db,p: False + self.apply = lambda db, p: False - def apply_real(self,db,person): + def apply_real(self, db, person): return person.handle == self.def_handle diff --git a/gramps/gen/filters/rules/person/_isdescendantfamilyof.py b/gramps/gen/filters/rules/person/_isdescendantfamilyof.py index 43fa79615d3..bc288b289e8 100644 --- a/gramps/gen/filters/rules/person/_isdescendantfamilyof.py +++ b/gramps/gen/filters/rules/person/_isdescendantfamilyof.py @@ -18,39 +18,43 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext try: set() except NameError: from sets import Set as set -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsDescendantFamilyOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsDescendantFamilyOf(Rule): """Rule that checks for a person that is a descendant or the spouse of a descendant of a specified person""" - labels = [ _('ID:'), _('Inclusive:') ] - name = _('Descendant family members of ') - category = _('Descendant filters') - description = _("Matches people that are descendants or the spouse " - "of a descendant of a specified person") + labels = [_("ID:"), _("Inclusive:")] + name = _("Descendant family members of ") + category = _("Descendant filters") + description = _( + "Matches people that are descendants or the spouse " + "of a descendant of a specified person" + ) def prepare(self, db, user): self.db = db @@ -70,10 +74,10 @@ def prepare(self, db, user): def reset(self): self.matches = set() - def apply(self,db,person): + def apply(self, db, person): return person.handle in self.matches - def add_matches(self,person): + def add_matches(self, person): if not person: return @@ -102,7 +106,8 @@ def add_matches(self,person): def exclude(self): # This removes root person and his/her spouses from the matches set - if not self.root_person: return + if not self.root_person: + return self.matches.remove(self.root_person.handle) for family_handle in self.root_person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) diff --git a/gramps/gen/filters/rules/person/_isdescendantfamilyoffiltermatch.py b/gramps/gen/filters/rules/person/_isdescendantfamilyoffiltermatch.py index 36f27abc737..25634a1bc14 100644 --- a/gramps/gen/filters/rules/person/_isdescendantfamilyoffiltermatch.py +++ b/gramps/gen/filters/rules/person/_isdescendantfamilyoffiltermatch.py @@ -18,36 +18,40 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ._isdescendantfamilyof import IsDescendantFamilyOf from ._matchesfilter import MatchesFilter -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsDescendantFamilyOfFilterMatch # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsDescendantFamilyOfFilterMatch(IsDescendantFamilyOf): """Rule that checks for a person that is a descendant of someone matched by a filter""" - labels = [_('Filter name:')] - name = _('Descendant family members of match') - category = _('Descendant filters') - description = _("Matches people that are descendants or the spouse " - "of anybody matched by a filter") + labels = [_("Filter name:")] + name = _("Descendant family members of match") + category = _("Descendant filters") + description = _( + "Matches people that are descendants or the spouse " + "of anybody matched by a filter" + ) def prepare(self, db, user): self.db = db @@ -56,9 +60,11 @@ def prepare(self, db, user): self.matchfilt = MatchesFilter(self.list[0:1]) self.matchfilt.requestprepare(db, user) if user: - user.begin_progress(self.category, - _('Retrieving all sub-filter matches'), - db.get_number_of_people()) + user.begin_progress( + self.category, + _("Retrieving all sub-filter matches"), + db.get_number_of_people(), + ) for person in db.iter_people(): if user: user.step_progress() diff --git a/gramps/gen/filters/rules/person/_isdescendantof.py b/gramps/gen/filters/rules/person/_isdescendantof.py index 1ed33ecc1b1..52cea65c8f9 100644 --- a/gramps/gen/filters/rules/person/_isdescendantof.py +++ b/gramps/gen/filters/rules/person/_isdescendantof.py @@ -18,34 +18,36 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsDescendantOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsDescendantOf(Rule): """Rule that checks for a person that is a descendant of a specified person""" - labels = [ _('ID:'), _('Inclusive:') ] - name = _('Descendants of ') - category = _('Descendant filters') - description = _('Matches all descendants for the specified person') + labels = [_("ID:"), _("Inclusive:")] + name = _("Descendants of ") + category = _("Descendant filters") + description = _("Matches all descendants for the specified person") def prepare(self, db, user): self.db = db @@ -56,7 +58,7 @@ def prepare(self, db, user): first = True try: root_person = db.get_person_from_gramps_id(self.list[0]) - self.init_list(root_person,first) + self.init_list(root_person, first) except: pass @@ -77,5 +79,4 @@ def init_list(self, person, first): fam = self.db.get_family_from_handle(fam_id) if fam: for child_ref in fam.get_child_ref_list(): - self.init_list( - self.db.get_person_from_handle(child_ref.ref), 0) + self.init_list(self.db.get_person_from_handle(child_ref.ref), 0) diff --git a/gramps/gen/filters/rules/person/_isdescendantoffiltermatch.py b/gramps/gen/filters/rules/person/_isdescendantoffiltermatch.py index d265540ca3a..dbb864b4b44 100644 --- a/gramps/gen/filters/rules/person/_isdescendantoffiltermatch.py +++ b/gramps/gen/filters/rules/person/_isdescendantoffiltermatch.py @@ -18,36 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ._isdescendantof import IsDescendantOf from ._matchesfilter import MatchesFilter -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsDescendantOfFilterMatch # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsDescendantOfFilterMatch(IsDescendantOf): """Rule that checks for a person that is a descendant of someone matched by a filter""" - labels = [ _('Filter name:') ] - name = _('Descendants of match') - category = _('Descendant filters') - description = _("Matches people that are descendants " - "of anybody matched by a filter") + labels = [_("Filter name:")] + name = _("Descendants of match") + category = _("Descendant filters") + description = _( + "Matches people that are descendants " "of anybody matched by a filter" + ) def prepare(self, db, user): self.db = db @@ -63,9 +66,11 @@ def prepare(self, db, user): self.filt = MatchesFilter(self.list[0:1]) self.filt.requestprepare(db, user) if user: - user.begin_progress(self.category, - _('Retrieving all sub-filter matches'), - db.get_number_of_people()) + user.begin_progress( + self.category, + _("Retrieving all sub-filter matches"), + db.get_number_of_people(), + ) for person in db.iter_people(): if user: user.step_progress() @@ -78,5 +83,5 @@ def reset(self): self.filt.requestreset() self.map.clear() - def apply(self,db,person): + def apply(self, db, person): return person.handle in self.map diff --git a/gramps/gen/filters/rules/person/_isduplicatedancestorof.py b/gramps/gen/filters/rules/person/_isduplicatedancestorof.py index 206c13b69ce..9d31ca2e200 100644 --- a/gramps/gen/filters/rules/person/_isduplicatedancestorof.py +++ b/gramps/gen/filters/rules/person/_isduplicatedancestorof.py @@ -19,35 +19,38 @@ # # gen.filters.rules/Person/_IsDuplicatedAncestorOf.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsDuplicatedAncestorOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsDuplicatedAncestorOf(Rule): """Rule that checks for a person that is a duplicated ancestor of a specified person""" - labels = [ _('ID:')] - name = _('Duplicated ancestors of ') + labels = [_("ID:")] + name = _("Duplicated ancestors of ") category = _("Ancestral filters") - description = _("Matches people that are ancestors twice or more " - "of a specified person") + description = _( + "Matches people that are ancestors twice or more " "of a specified person" + ) def prepare(self, db, user): self.db = db @@ -55,7 +58,7 @@ def prepare(self, db, user): self.map2 = set() root_person = db.get_person_from_gramps_id(self.list[0]) if root_person: - self.init_ancestor_list(db,root_person) + self.init_ancestor_list(db, root_person) def reset(self): self.map.clear() diff --git a/gramps/gen/filters/rules/person/_isfemale.py b/gramps/gen/filters/rules/person/_isfemale.py index 821f4f4bf04..2fa21e6e004 100644 --- a/gramps/gen/filters/rules/person/_isfemale.py +++ b/gramps/gen/filters/rules/person/_isfemale.py @@ -18,33 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.person import Person -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsFemale # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsFemale(Rule): """Rule that checks for a person that is a female""" - name = _('Females') - category = _('General filters') - description = _('Matches all females') + name = _("Females") + category = _("General filters") + description = _("Matches all females") - def apply(self,db,person): + def apply(self, db, person): return person.gender == Person.FEMALE diff --git a/gramps/gen/filters/rules/person/_islessthannthgenerationancestorof.py b/gramps/gen/filters/rules/person/_islessthannthgenerationancestorof.py index 4fe8067d31f..c88f8c332fa 100644 --- a/gramps/gen/filters/rules/person/_islessthannthgenerationancestorof.py +++ b/gramps/gen/filters/rules/person/_islessthannthgenerationancestorof.py @@ -18,35 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsLessThanNthGenerationAncestorOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsLessThanNthGenerationAncestorOf(Rule): """Rule that checks for a person that is an ancestor of a specified person not more than N generations away""" - labels = [ _('ID:'), _('Number of generations:') ] - name = _('Ancestors of not more than generations away') + labels = [_("ID:"), _("Number of generations:")] + name = _("Ancestors of not more than generations away") category = _("Ancestral filters") - description = _("Matches people that are ancestors " - "of a specified person not more than N generations away") + description = _( + "Matches people that are ancestors " + "of a specified person not more than N generations away" + ) def prepare(self, db, user): self.db = db @@ -58,9 +62,9 @@ def prepare(self, db, user): self.init_ancestor_list(root_handle) def init_ancestor_list(self, root_handle): - queue = [(root_handle, 1)] # generation 1 is root + queue = [(root_handle, 1)] # generation 1 is root while queue: - handle, gen = queue.pop(0) # pop off front of queue + handle, gen = queue.pop(0) # pop off front of queue if handle in self.map: # if we have been here before, skip continue @@ -83,5 +87,5 @@ def init_ancestor_list(self, root_handle): def reset(self): self.map.clear() - def apply(self,db,person): + def apply(self, db, person): return person.handle in self.map diff --git a/gramps/gen/filters/rules/person/_islessthannthgenerationancestorofbookmarked.py b/gramps/gen/filters/rules/person/_islessthannthgenerationancestorofbookmarked.py index 0be87dad2b5..bbdda54b480 100644 --- a/gramps/gen/filters/rules/person/_islessthannthgenerationancestorofbookmarked.py +++ b/gramps/gen/filters/rules/person/_islessthannthgenerationancestorofbookmarked.py @@ -18,12 +18,13 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext try: @@ -31,46 +32,47 @@ except: from sets import Set as set -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsLessThanNthGenerationAncestorOfBookmarked # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsLessThanNthGenerationAncestorOfBookmarked(Rule): # Submitted by Wayne Bergeron """Rule that checks for a person that is an ancestor of bookmarked persons not more than N generations away""" - labels = [ _('Number of generations:') ] - name = _('Ancestors of bookmarked people not more ' - 'than generations away') - category = _('Ancestral filters') - description = _("Matches ancestors of the people on the bookmark list " - "not more than N generations away") + labels = [_("Number of generations:")] + name = _("Ancestors of bookmarked people not more " "than generations away") + category = _("Ancestral filters") + description = _( + "Matches ancestors of the people on the bookmark list " + "not more than N generations away" + ) def prepare(self, db, user): self.db = db bookmarks = db.get_bookmarks().get() self.map = set() if len(bookmarks) == 0: - self.apply = lambda db,p : False + self.apply = lambda db, p: False else: self.bookmarks = set(bookmarks) self.apply = self.apply_real for self.bookmarkhandle in self.bookmarks: self.init_ancestor_list(self.bookmarkhandle, 1) - def init_ancestor_list(self, handle, gen): -# if p.get_handle() in self.map: -# loop_error(self.orig,p) + # if p.get_handle() in self.map: + # loop_error(self.orig,p) if not handle or handle in self.map: # if been here already, skip return @@ -89,9 +91,9 @@ def init_ancestor_list(self, handle, gen): m_id = fam.get_mother_handle() if f_id: - self.init_ancestor_list(f_id, gen+1) + self.init_ancestor_list(f_id, gen + 1) if m_id: - self.init_ancestor_list(m_id, gen+1) + self.init_ancestor_list(m_id, gen + 1) def apply_real(self, db, person): return person.handle in self.map diff --git a/gramps/gen/filters/rules/person/_islessthannthgenerationancestorofdefaultperson.py b/gramps/gen/filters/rules/person/_islessthannthgenerationancestorofdefaultperson.py index 48150b5f473..8afef235388 100644 --- a/gramps/gen/filters/rules/person/_islessthannthgenerationancestorofdefaultperson.py +++ b/gramps/gen/filters/rules/person/_islessthannthgenerationancestorofdefaultperson.py @@ -18,37 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsLessThanNthGenerationAncestorOfDefaultPerson # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsLessThanNthGenerationAncestorOfDefaultPerson(Rule): # Submitted by Wayne Bergeron """Rule that checks for a person that is an ancestor of the default person not more than N generations away""" - labels = [ _('Number of generations:') ] - name = _('Ancestors of the Home Person ' - 'not more than generations away') - category = _('Ancestral filters') - description = _("Matches ancestors of the Home Person " - "not more than N generations away") + labels = [_("Number of generations:")] + name = _("Ancestors of the Home Person " "not more than generations away") + category = _("Ancestral filters") + description = _( + "Matches ancestors of the Home Person " "not more than N generations away" + ) def prepare(self, db, user): self.db = db @@ -59,11 +61,11 @@ def prepare(self, db, user): self.apply = self.apply_real self.init_ancestor_list(self.def_handle, 1) else: - self.apply = lambda db,p: False + self.apply = lambda db, p: False def init_ancestor_list(self, handle, gen): -# if p.get_handle() in self.map: -# loop_error(self.orig,p) + # if p.get_handle() in self.map: + # loop_error(self.orig,p) if not handle or handle in self.map: # if we have been here before, skip return @@ -82,11 +84,11 @@ def init_ancestor_list(self, handle, gen): m_id = fam.get_mother_handle() if f_id: - self.init_ancestor_list(f_id, gen+1) + self.init_ancestor_list(f_id, gen + 1) if m_id: - self.init_ancestor_list(m_id, gen+1) + self.init_ancestor_list(m_id, gen + 1) - def apply_real(self,db,person): + def apply_real(self, db, person): return person.handle in self.map def reset(self): diff --git a/gramps/gen/filters/rules/person/_islessthannthgenerationdescendantof.py b/gramps/gen/filters/rules/person/_islessthannthgenerationdescendantof.py index 2ccc768cd89..d6429edbc0e 100644 --- a/gramps/gen/filters/rules/person/_islessthannthgenerationdescendantof.py +++ b/gramps/gen/filters/rules/person/_islessthannthgenerationdescendantof.py @@ -18,36 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsLessThanNthGenerationDescendantOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsLessThanNthGenerationDescendantOf(Rule): """Rule that checks for a person that is a descendant of a specified person not more than N generations away""" - labels = [ _('ID:'), _('Number of generations:') ] - name = _('Descendants of not more than ' - ' generations away') - category = _('Descendant filters') - description = _("Matches people that are descendants of a " - "specified person not more than N generations away") + labels = [_("ID:"), _("Number of generations:")] + name = _("Descendants of not more than " " generations away") + category = _("Descendant filters") + description = _( + "Matches people that are descendants of a " + "specified person not more than N generations away" + ) def prepare(self, db, user): self.db = db @@ -64,7 +67,7 @@ def reset(self): def apply(self, db, person): return person.handle in self.map - def init_list(self,person,gen): + def init_list(self, person, gen): if not person or person.handle in self.map: # if we have been here before, skip return @@ -78,4 +81,5 @@ def init_list(self,person,gen): if fam: for child_ref in fam.get_child_ref_list(): self.init_list( - self.db.get_person_from_handle(child_ref.ref), gen+1) + self.db.get_person_from_handle(child_ref.ref), gen + 1 + ) diff --git a/gramps/gen/filters/rules/person/_ismale.py b/gramps/gen/filters/rules/person/_ismale.py index 7951f08320a..1349ea18c9a 100644 --- a/gramps/gen/filters/rules/person/_ismale.py +++ b/gramps/gen/filters/rules/person/_ismale.py @@ -18,33 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.person import Person -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsMale # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsMale(Rule): """Rule that checks for a person that is a male""" - name = _('Males') - category = _('General filters') - description = _('Matches all males') + name = _("Males") + category = _("General filters") + description = _("Matches all males") - def apply(self,db,person): + def apply(self, db, person): return person.gender == Person.MALE diff --git a/gramps/gen/filters/rules/person/_ismorethannthgenerationancestorof.py b/gramps/gen/filters/rules/person/_ismorethannthgenerationancestorof.py index b6d65f73ac4..0391d9bafba 100644 --- a/gramps/gen/filters/rules/person/_ismorethannthgenerationancestorof.py +++ b/gramps/gen/filters/rules/person/_ismorethannthgenerationancestorof.py @@ -18,35 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsMoreThanNthGenerationAncestorOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsMoreThanNthGenerationAncestorOf(Rule): """Rule that checks for a person that is an ancestor of a specified person at least N generations away""" - labels = [ _('ID:'), _('Number of generations:') ] - name = _('Ancestors of at least generations away') + labels = [_("ID:"), _("Number of generations:")] + name = _("Ancestors of at least generations away") category = _("Ancestral filters") - description = _("Matches people that are ancestors " - "of a specified person at least N generations away") + description = _( + "Matches people that are ancestors " + "of a specified person at least N generations away" + ) def prepare(self, db, user): self.db = db @@ -58,9 +62,9 @@ def prepare(self, db, user): self.init_ancestor_list(root_handle) def init_ancestor_list(self, root_handle): - queue = [(root_handle, 1)] # generation 1 is root + queue = [(root_handle, 1)] # generation 1 is root while queue: - handle, gen = queue.pop(0) # pop off front of queue + handle, gen = queue.pop(0) # pop off front of queue if gen > int(self.list[1]): self.map.add(handle) gen += 1 @@ -80,5 +84,5 @@ def init_ancestor_list(self, root_handle): def reset(self): self.map.clear() - def apply(self,db,person): + def apply(self, db, person): return person.handle in self.map diff --git a/gramps/gen/filters/rules/person/_ismorethannthgenerationdescendantof.py b/gramps/gen/filters/rules/person/_ismorethannthgenerationdescendantof.py index 30e2f01d361..6869df63142 100644 --- a/gramps/gen/filters/rules/person/_ismorethannthgenerationdescendantof.py +++ b/gramps/gen/filters/rules/person/_ismorethannthgenerationdescendantof.py @@ -18,36 +18,39 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsMoreThanNthGenerationDescendantOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsMoreThanNthGenerationDescendantOf(Rule): """Rule that checks for a person that is a descendant of a specified person at least N generations away""" - labels = [ _('ID:'), _('Number of generations:') ] - name = _('Descendants of at least generations away') + labels = [_("ID:"), _("Number of generations:")] + name = _("Descendants of at least generations away") category = _("Descendant filters") - description = _("Matches people that are descendants of a specified " - "person at least N generations away") - + description = _( + "Matches people that are descendants of a specified " + "person at least N generations away" + ) def prepare(self, db, user): self.db = db @@ -61,7 +64,7 @@ def prepare(self, db, user): def reset(self): self.map.clear() - def apply(self,db,person): + def apply(self, db, person): return person.handle in self.map def init_list(self, person, gen): @@ -75,4 +78,5 @@ def init_list(self, person, gen): if fam: for child_ref in fam.get_child_ref_list(): self.init_list( - self.db.get_person_from_handle(child_ref.ref), gen+1) + self.db.get_person_from_handle(child_ref.ref), gen + 1 + ) diff --git a/gramps/gen/filters/rules/person/_isparentoffiltermatch.py b/gramps/gen/filters/rules/person/_isparentoffiltermatch.py index ab7a5ef8143..a262ac23e31 100644 --- a/gramps/gen/filters/rules/person/_isparentoffiltermatch.py +++ b/gramps/gen/filters/rules/person/_isparentoffiltermatch.py @@ -18,34 +18,36 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ._matchesfilter import MatchesFilter -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsParentOfFilterMatch # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsParentOfFilterMatch(Rule): """Rule that checks for a person that is a parent of someone matched by a filter""" - labels = [ _('Filter name:') ] - name = _('Parents of match') - category = _('Family filters') + labels = [_("Filter name:")] + name = _("Parents of match") + category = _("Family filters") description = _("Matches parents of anybody matched by a filter") def prepare(self, db, user): @@ -54,9 +56,11 @@ def prepare(self, db, user): self.filt = MatchesFilter(self.list) self.filt.requestprepare(db, user) if user: - user.begin_progress(self.category, - _('Retrieving all sub-filter matches'), - db.get_number_of_people()) + user.begin_progress( + self.category, + _("Retrieving all sub-filter matches"), + db.get_number_of_people(), + ) for person in db.iter_people(): if user: user.step_progress() @@ -69,15 +73,15 @@ def reset(self): self.filt.requestreset() self.map.clear() - def apply(self,db,person): + def apply(self, db, person): return person.handle in self.map - def init_list(self,person): + def init_list(self, person): for fam_id in person.get_parent_family_handle_list(): fam = self.db.get_family_from_handle(fam_id) if fam: - self.map.update(parent_id - for parent_id in [fam.get_father_handle(), - fam.get_mother_handle()] - if parent_id) - + self.map.update( + parent_id + for parent_id in [fam.get_father_handle(), fam.get_mother_handle()] + if parent_id + ) diff --git a/gramps/gen/filters/rules/person/_isrelatedwith.py b/gramps/gen/filters/rules/person/_isrelatedwith.py index f0a7bd6e698..c478257ff43 100644 --- a/gramps/gen/filters/rules/person/_isrelatedwith.py +++ b/gramps/gen/filters/rules/person/_isrelatedwith.py @@ -18,38 +18,40 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # RelatedWith # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsRelatedWith(Rule): """Rule that checks if a person is related to a specified person""" - labels = [ _('ID:') ] - name = _('People related to ') + labels = [_("ID:")] + name = _("People related to ") category = _("Relationship filters") description = _("Matches people related to a specified person") def prepare(self, db, user): """prepare so the rule can be executed efficiently - we build the list of people related to here, - so that apply is only a check into this list + we build the list of people related to here, + so that apply is only a check into this list """ self.db = db @@ -62,10 +64,9 @@ def reset(self): def apply(self, db, person): return person.handle in self.relatives - def add_relative(self, start): """Non-recursive function that scans relatives and add them to self.relatives""" - if not(start): + if not (start): return expand = [start] @@ -81,22 +82,28 @@ def add_relative(self, start): for family_handle in person.get_parent_family_handle_list(): family = self.db.get_family_from_handle(family_handle) if family: - # Check Parents - for parent_handle in (family.get_father_handle(), family.get_mother_handle()): + # Check Parents + for parent_handle in ( + family.get_father_handle(), + family.get_mother_handle(), + ): if parent_handle: expand.append(self.db.get_person_from_handle(parent_handle)) - # Check Sibilings + # Check Sibilings for child_ref in family.get_child_ref_list(): expand.append(self.db.get_person_from_handle(child_ref.ref)) for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle(family_handle) if family: - # Check Spouse - for parent_handle in (family.get_father_handle(), family.get_mother_handle()): + # Check Spouse + for parent_handle in ( + family.get_father_handle(), + family.get_mother_handle(), + ): if parent_handle: expand.append(self.db.get_person_from_handle(parent_handle)) - # Check Children + # Check Children for child_ref in family.get_child_ref_list(): expand.append(self.db.get_person_from_handle(child_ref.ref)) diff --git a/gramps/gen/filters/rules/person/_issiblingoffiltermatch.py b/gramps/gen/filters/rules/person/_issiblingoffiltermatch.py index 766214a7b77..d6974d2d0fd 100644 --- a/gramps/gen/filters/rules/person/_issiblingoffiltermatch.py +++ b/gramps/gen/filters/rules/person/_issiblingoffiltermatch.py @@ -18,33 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ._matchesfilter import MatchesFilter -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsSiblingOfFilterMatch # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsSiblingOfFilterMatch(Rule): """Rule that checks for siblings of someone matched by a filter""" - labels = [ _('Filter name:') ] - name = _('Siblings of match') - category = _('Family filters') + labels = [_("Filter name:")] + name = _("Siblings of match") + category = _("Family filters") description = _("Matches siblings of anybody matched by a filter") def prepare(self, db, user): @@ -53,9 +55,11 @@ def prepare(self, db, user): self.matchfilt = MatchesFilter(self.list) self.matchfilt.requestprepare(db, user) if user: - user.begin_progress(self.category, - _('Retrieving all sub-filter matches'), - db.get_number_of_people()) + user.begin_progress( + self.category, + _("Retrieving all sub-filter matches"), + db.get_number_of_people(), + ) for person in db.iter_people(): if user: user.step_progress() @@ -68,10 +72,10 @@ def reset(self): self.matchfilt.requestreset() self.map.clear() - def apply(self,db,person): + def apply(self, db, person): return person.handle in self.map - def init_list(self,person): + def init_list(self, person): if not person: return fam_id = person.get_main_parents_family_handle() @@ -79,5 +83,7 @@ def init_list(self,person): fam = self.db.get_family_from_handle(fam_id) if fam: self.map.update( - child_ref.ref for child_ref in fam.get_child_ref_list() - if child_ref and child_ref.ref != person.handle) + child_ref.ref + for child_ref in fam.get_child_ref_list() + if child_ref and child_ref.ref != person.handle + ) diff --git a/gramps/gen/filters/rules/person/_isspouseoffiltermatch.py b/gramps/gen/filters/rules/person/_isspouseoffiltermatch.py index 1eedbf0ebe7..c96f88a6acd 100644 --- a/gramps/gen/filters/rules/person/_isspouseoffiltermatch.py +++ b/gramps/gen/filters/rules/person/_isspouseoffiltermatch.py @@ -18,51 +18,55 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ._matchesfilter import MatchesFilter -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsSpouseOfFilterMatch # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsSpouseOfFilterMatch(Rule): """Rule that checks for a person married to someone matching a filter""" - labels = [_('Filter name:')] - name = _('Spouses of match') + labels = [_("Filter name:")] + name = _("Spouses of match") description = _("Matches people married to anybody matching a filter") - category = _('Family filters') + category = _("Family filters") def prepare(self, db, user): - self.filt = MatchesFilter (self.list) + self.filt = MatchesFilter(self.list) self.filt.requestprepare(db, user) - def apply(self,db,person): - for family_handle in person.get_family_handle_list (): + def apply(self, db, person): + for family_handle in person.get_family_handle_list(): family = db.get_family_from_handle(family_handle) if family: - for spouse_id in [family.get_father_handle(), - family.get_mother_handle()]: + for spouse_id in [ + family.get_father_handle(), + family.get_mother_handle(), + ]: if not spouse_id: continue if spouse_id == person.handle: continue - if self.filt.apply (db, db.get_person_from_handle( spouse_id)): + if self.filt.apply(db, db.get_person_from_handle(spouse_id)): return True return False diff --git a/gramps/gen/filters/rules/person/_iswitness.py b/gramps/gen/filters/rules/person/_iswitness.py index 99f82d547ac..9a755c62910 100644 --- a/gramps/gen/filters/rules/person/_iswitness.py +++ b/gramps/gen/filters/rules/person/_iswitness.py @@ -18,35 +18,37 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib.eventroletype import EventRoleType from ....lib.eventtype import EventType -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Witnesses" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsWitness(Rule): """Witnesses""" - labels = [_('Event type:')] - name = _('Witnesses') + labels = [_("Event type:")] + name = _("Witnesses") description = _("Matches people who are witnesses in any event") - category = _('Event filters') + category = _("Event filters") - def apply(self,db,person): + def apply(self, db, person): for event_ref in person.event_ref_list: if event_ref and event_ref.role == EventRoleType.WITNESS: # This is the witness. diff --git a/gramps/gen/filters/rules/person/_matcheseventfilter.py b/gramps/gen/filters/rules/person/_matcheseventfilter.py index b352a2acf6d..2dd97c359cb 100644 --- a/gramps/gen/filters/rules/person/_matcheseventfilter.py +++ b/gramps/gen/filters/rules/person/_matcheseventfilter.py @@ -19,26 +19,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import MatchesEventFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesEventFilter(MatchesEventFilterBase): """ Rule that checks against another filter. @@ -48,11 +50,12 @@ class MatchesEventFilter(MatchesEventFilterBase): """ - labels = [_('Event filter name:')] - name = _('Persons with events matching the ') - description = _("Matches persons who have events that match a certain" - " event filter") - category = _('Event filters') + labels = [_("Event filter name:")] + name = _("Persons with events matching the ") + description = _( + "Matches persons who have events that match a certain" " event filter" + ) + category = _("Event filters") # we want to have this filter show event filters - namespace = 'Event' + namespace = "Event" diff --git a/gramps/gen/filters/rules/person/_matchesfilter.py b/gramps/gen/filters/rules/person/_matchesfilter.py index 2eb9c1dc71a..78e035d0208 100644 --- a/gramps/gen/filters/rules/person/_matchesfilter.py +++ b/gramps/gen/filters/rules/person/_matchesfilter.py @@ -18,29 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesFilter(MatchesFilterBase): """Rule that checks against another filter.""" - name = _('People matching the ') + name = _("People matching the ") description = _("Matches people matched by the specified filter name") - namespace = 'Person' + namespace = "Person" diff --git a/gramps/gen/filters/rules/person/_matchessourceconfidence.py b/gramps/gen/filters/rules/person/_matchessourceconfidence.py index 3fc5636645a..01f6d38b0ed 100644 --- a/gramps/gen/filters/rules/person/_matchessourceconfidence.py +++ b/gramps/gen/filters/rules/person/_matchessourceconfidence.py @@ -19,28 +19,31 @@ # # gen.filters.rules/Person/_MatchesSourceConfidence.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._matchessourceconfidencebase import MatchesSourceConfidenceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Confidence level" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesSourceConfidence(MatchesSourceConfidenceBase): """Persons matching a specific confidence level on its 'direct' source references""" - labels = [_('Confidence level:')] - name = _('Persons with at least one direct source >= ') - description = _("Matches persons with at least one direct source with confidence level(s)") - + labels = [_("Confidence level:")] + name = _("Persons with at least one direct source >= ") + description = _( + "Matches persons with at least one direct source with confidence level(s)" + ) diff --git a/gramps/gen/filters/rules/person/_matchidof.py b/gramps/gen/filters/rules/person/_matchidof.py index b1f8e972c54..52aca2709ca 100644 --- a/gramps/gen/filters/rules/person/_matchidof.py +++ b/gramps/gen/filters/rules/person/_matchidof.py @@ -18,33 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchIdOf(Rule): """Rule that checks for a person with a specific Gramps ID""" - labels = [ _('ID:') ] - name = _('Person with ') + labels = [_("ID:")] + name = _("Person with ") description = _("Matches person with a specified Gramps ID") - category = _('General filters') + category = _("General filters") - def apply(self,db,person): - return person.gramps_id.find(self.list[0]) !=-1 + def apply(self, db, person): + return person.gramps_id.find(self.list[0]) != -1 diff --git a/gramps/gen/filters/rules/person/_missingparent.py b/gramps/gen/filters/rules/person/_missingparent.py index 919fbcfaf16..2ee7aea8530 100644 --- a/gramps/gen/filters/rules/person/_missingparent.py +++ b/gramps/gen/filters/rules/person/_missingparent.py @@ -19,34 +19,38 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People with less than 2 parents" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MissingParent(Rule): """People with less than two parents""" - name = _('People missing parents') - description = _("Matches people that are children" - " in a family with less than two parents" - " or are not children in any family.") - category = _('Family filters') + name = _("People missing parents") + description = _( + "Matches people that are children" + " in a family with less than two parents" + " or are not children in any family." + ) + category = _("Family filters") - def apply(self,db,person): + def apply(self, db, person): families = person.get_parent_family_handle_list() if families == []: return True diff --git a/gramps/gen/filters/rules/person/_multiplemarriages.py b/gramps/gen/filters/rules/person/_multiplemarriages.py index a2f845af211..30532b2d504 100644 --- a/gramps/gen/filters/rules/person/_multiplemarriages.py +++ b/gramps/gen/filters/rules/person/_multiplemarriages.py @@ -18,30 +18,32 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People with multiple marriage records" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MultipleMarriages(Rule): """People with multiple marriage records""" - name = _('People with multiple marriage records') + name = _("People with multiple marriage records") description = _("Matches people who have more than one spouse") - category = _('Family filters') + category = _("Family filters") - def apply(self,db,person): + def apply(self, db, person): return len(person.get_family_handle_list()) > 1 diff --git a/gramps/gen/filters/rules/person/_nevermarried.py b/gramps/gen/filters/rules/person/_nevermarried.py index b81f49fc47a..66a9634d2c8 100644 --- a/gramps/gen/filters/rules/person/_nevermarried.py +++ b/gramps/gen/filters/rules/person/_nevermarried.py @@ -18,30 +18,32 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People with no marriage records" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class NeverMarried(Rule): """People with no marriage records""" - name = _('People with no marriage records') + name = _("People with no marriage records") description = _("Matches people who have no spouse") - category = _('Family filters') + category = _("Family filters") - def apply(self,db,person): + def apply(self, db, person): return len(person.get_family_handle_list()) == 0 diff --git a/gramps/gen/filters/rules/person/_nobirthdate.py b/gramps/gen/filters/rules/person/_nobirthdate.py index 92e65b53ccd..22e979a15b5 100644 --- a/gramps/gen/filters/rules/person/_nobirthdate.py +++ b/gramps/gen/filters/rules/person/_nobirthdate.py @@ -18,32 +18,34 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People without a birth date" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class NoBirthdate(Rule): """People without a birth date""" - name = _('People without a known birth date') + name = _("People without a known birth date") description = _("Matches people without a known birthdate") - category = _('General filters') + category = _("General filters") - def apply(self,db,person): + def apply(self, db, person): birth_ref = person.get_birth_ref() if not birth_ref: return True diff --git a/gramps/gen/filters/rules/person/_nodeathdate.py b/gramps/gen/filters/rules/person/_nodeathdate.py index 40b344ba6e8..6884d69d9e4 100644 --- a/gramps/gen/filters/rules/person/_nodeathdate.py +++ b/gramps/gen/filters/rules/person/_nodeathdate.py @@ -18,32 +18,34 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People without a death date" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class NoDeathdate(Rule): """People without a death date""" - name = _('People without a known death date') + name = _("People without a known death date") description = _("Matches people without a known deathdate") - category = _('General filters') + category = _("General filters") - def apply(self,db,person): + def apply(self, db, person): death_ref = person.get_death_ref() if not death_ref: return True diff --git a/gramps/gen/filters/rules/person/_peopleprivate.py b/gramps/gen/filters/rules/person/_peopleprivate.py index 9052846dd33..26f67d146ac 100644 --- a/gramps/gen/filters/rules/person/_peopleprivate.py +++ b/gramps/gen/filters/rules/person/_peopleprivate.py @@ -18,27 +18,29 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._isprivate import IsPrivate -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People marked private" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PeoplePrivate(IsPrivate): """People marked private""" - name = _('People marked private') + name = _("People marked private") description = _("Matches people that are indicated as private") - category = _('General filters') + category = _("General filters") diff --git a/gramps/gen/filters/rules/person/_peoplepublic.py b/gramps/gen/filters/rules/person/_peoplepublic.py index 5b0db3d8c7d..acb633e8d35 100644 --- a/gramps/gen/filters/rules/person/_peoplepublic.py +++ b/gramps/gen/filters/rules/person/_peoplepublic.py @@ -19,27 +19,29 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._ispublic import IsPublic -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People marked private" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PeoplePublic(IsPublic): """People not marked private""" - name = _('People not marked private') + name = _("People not marked private") description = _("Matches people that are not indicated as private") - category = _('General filters') + category = _("General filters") diff --git a/gramps/gen/filters/rules/person/_personwithincompleteevent.py b/gramps/gen/filters/rules/person/_personwithincompleteevent.py index e331f060fa9..58ce20d7b31 100644 --- a/gramps/gen/filters/rules/person/_personwithincompleteevent.py +++ b/gramps/gen/filters/rules/person/_personwithincompleteevent.py @@ -18,32 +18,34 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People with incomplete events" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PersonWithIncompleteEvent(Rule): """People with incomplete events""" - name = _('People with incomplete events') + name = _("People with incomplete events") description = _("Matches people with missing date or place in an event") - category = _('Event filters') + category = _("Event filters") - def apply(self,db,person): + def apply(self, db, person): for event_ref in person.get_event_ref_list(): if event_ref: event = db.get_event_from_handle(event_ref.ref) diff --git a/gramps/gen/filters/rules/person/_probablyalive.py b/gramps/gen/filters/rules/person/_probablyalive.py index b07f1199437..91d9e80b690 100644 --- a/gramps/gen/filters/rules/person/_probablyalive.py +++ b/gramps/gen/filters/rules/person/_probablyalive.py @@ -18,33 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....utils.alive import probably_alive from .. import Rule from ....datehandler import parser -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People probably alive" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ProbablyAlive(Rule): """People probably alive""" labels = [_("On date:")] - name = _('People probably alive') + name = _("People probably alive") description = _("Matches people without indications of death that are not too old") - category = _('General filters') + category = _("General filters") def prepare(self, db, user): try: @@ -52,5 +54,5 @@ def prepare(self, db, user): except: self.current_date = None - def apply(self,db,person): - return probably_alive(person,db,self.current_date) + def apply(self, db, person): + return probably_alive(person, db, self.current_date) diff --git a/gramps/gen/filters/rules/person/_regexpidof.py b/gramps/gen/filters/rules/person/_regexpidof.py index 17b4e383853..4a1156c48fa 100644 --- a/gramps/gen/filters/rules/person/_regexpidof.py +++ b/gramps/gen/filters/rules/person/_regexpidof.py @@ -18,31 +18,32 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._regexpidbase import RegExpIdBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpIdOf(RegExpIdBase): """Rule that checks for a person whose Gramps ID matches regular expression. """ - name = _('People with Id containing ') - description = _("Matches people whose Gramps ID matches " - "the regular expression") + name = _("People with Id containing ") + description = _("Matches people whose Gramps ID matches " "the regular expression") diff --git a/gramps/gen/filters/rules/person/_regexpname.py b/gramps/gen/filters/rules/person/_regexpname.py index 3bb5e005682..95aa6dc2740 100644 --- a/gramps/gen/filters/rules/person/_regexpname.py +++ b/gramps/gen/filters/rules/person/_regexpname.py @@ -19,40 +19,51 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpName(Rule): """Rule that checks for full or partial name matches""" - labels = [_('Text:')] - name = _('People with a name matching ') - description = _("Matches people's names containing a substring or " - "matching a regular expression") - category = _('General filters') + labels = [_("Text:")] + name = _("People with a name matching ") + description = _( + "Matches people's names containing a substring or " + "matching a regular expression" + ) + category = _("General filters") allow_regex = True - def apply(self,db,person): + def apply(self, db, person): for name in [person.get_primary_name()] + person.get_alternate_names(): - for field in [name.first_name, name.get_surname(), name.suffix, - name.title, name.nick, name.famnick, name.call]: + for field in [ + name.first_name, + name.get_surname(), + name.suffix, + name.title, + name.nick, + name.famnick, + name.call, + ]: if self.match_substring(0, field): return True return False diff --git a/gramps/gen/filters/rules/person/_relationshippathbetween.py b/gramps/gen/filters/rules/person/_relationshippathbetween.py index 8263780a175..39b786afd45 100644 --- a/gramps/gen/filters/rules/person/_relationshippathbetween.py +++ b/gramps/gen/filters/rules/person/_relationshippathbetween.py @@ -18,36 +18,40 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # RelationshipPathBetween # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RelationshipPathBetween(Rule): """Rule that checks for a person that is a descendant of a specified person not more than N generations away""" - labels = [ _('ID:'), _('ID:') ] + labels = [_("ID:"), _("ID:")] name = _("Relationship path between ") - category = _('Relationship filters') - description = _("Matches the ancestors of two persons back " - "to a common ancestor, producing the relationship " - "path between two persons.") + category = _("Relationship filters") + description = _( + "Matches the ancestors of two persons back " + "to a common ancestor, producing the relationship " + "path between two persons." + ) def prepare(self, db, user): self.db = db @@ -88,8 +92,8 @@ def apply_filter(self, rank, handle, plist, pmap): return family = self.db.get_family_from_handle(fam_id) if family is not None: - self.apply_filter(rank+1, family.get_father_handle(), plist, pmap) - self.apply_filter(rank+1, family.get_mother_handle(), plist, pmap) + self.apply_filter(rank + 1, family.get_father_handle(), plist, pmap) + self.apply_filter(rank + 1, family.get_mother_handle(), plist, pmap) def apply(self, db, person): return person.handle in self.map @@ -103,7 +107,7 @@ def init_list(self, p1_handle, p2_handle): rank = 9999999 self.apply_filter(0, p1_handle, firstList, firstMap) - self.apply_filter(0, p2_handle ,secondList, secondMap) + self.apply_filter(0, p2_handle, secondList, secondMap) for person_handle in firstList & secondList: new_rank = firstMap[person_handle] diff --git a/gramps/gen/filters/rules/person/_relationshippathbetweenbookmarks.py b/gramps/gen/filters/rules/person/_relationshippathbetweenbookmarks.py index 46241306cd3..9c4619523a3 100644 --- a/gramps/gen/filters/rules/person/_relationshippathbetweenbookmarks.py +++ b/gramps/gen/filters/rules/person/_relationshippathbetweenbookmarks.py @@ -18,29 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext try: set() except NameError: from sets import Set as set -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # RelationshipPathBetween # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RelationshipPathBetweenBookmarks(Rule): """ Rule that matches the ancestors of bookmarked individuals back to @@ -49,17 +51,19 @@ class RelationshipPathBetweenBookmarks(Rule): """ name = _("Relationship path between bookmarked persons") - category = _('Relationship filters') - description = _("Matches the ancestors of bookmarked individuals " - "back to common ancestors, producing the relationship " - "path(s) between bookmarked persons.") + category = _("Relationship filters") + description = _( + "Matches the ancestors of bookmarked individuals " + "back to common ancestors, producing the relationship " + "path(s) between bookmarked persons." + ) def prepare(self, db, user): self.db = db self.map = set() bookmarks = db.get_bookmarks().get() if len(bookmarks) == 0: - self.apply = lambda db,p : False + self.apply = lambda db, p: False else: self.bookmarks = set(bookmarks) try: @@ -90,7 +94,8 @@ def hnm(self, handle): # The value keyed by the individual handles is the path from # the original person up, like generation[gfather]= [son,father,gfather] def parents(self, generation): - if len(generation) < 1: return None + if len(generation) < 1: + return None prev_generation = {} for handle in generation: try: @@ -115,31 +120,33 @@ def parents(self, generation): # Given two handles for individuals, a list of all individuals # in the relationship path between the two. def rel_path_for_two(self, handle1, handle2): - #print "rel_path_for_two (", handle1, self.hnm(handle1), ",", handle2, self.hnm(handle2), ")" - rel_path = {} # Result map - gmap1 = { handle1 : [ handle1 ] } # Key is ancestor, value is the path - gmap2 = { handle2 : [ handle2 ] } + # print "rel_path_for_two (", handle1, self.hnm(handle1), ",", handle2, self.hnm(handle2), ")" + rel_path = {} # Result map + gmap1 = {handle1: [handle1]} # Key is ancestor, value is the path + gmap2 = {handle2: [handle2]} map1 = {} map2 = {} - overlap = set( {} ) - for rank in range(1, 50): # Limit depth of search + overlap = set({}) + for rank in range(1, 50): # Limit depth of search try: - gmap1 = self.parents(gmap1) # Get previous generation into map - gmap2 = self.parents(gmap2) # Get previous generation into map - map1.update(gmap1) # Merge previous generation into map - map2.update(gmap2) # Merge previous generation into map - overlap = set(map1).intersection(set(map2)) # Any common ancestors? - if len(overlap) > 0: break # If so, stop walking through generations - except: pass - if len(overlap) < 1: # No common ancestor found - rel_path[handle1] = handle1 # Results for degenerate case + gmap1 = self.parents(gmap1) # Get previous generation into map + gmap2 = self.parents(gmap2) # Get previous generation into map + map1.update(gmap1) # Merge previous generation into map + map2.update(gmap2) # Merge previous generation into map + overlap = set(map1).intersection(set(map2)) # Any common ancestors? + if len(overlap) > 0: + break # If so, stop walking through generations + except: + pass + if len(overlap) < 1: # No common ancestor found + rel_path[handle1] = handle1 # Results for degenerate case rel_path[handle2] = handle2 - #print " In rel_path_for_two, returning rel_path = ", rel_path + # print " In rel_path_for_two, returning rel_path = ", rel_path return rel_path - for handle in overlap: # Handle of common ancestor(s) + for handle in overlap: # Handle of common ancestor(s) for phandle in map1[handle] + map2[handle]: rel_path[phandle] = phandle - #print " In rel_path_for_two, returning rel_path = ", rel_path + # print " In rel_path_for_two, returning rel_path = ", rel_path return rel_path def init_list(self): @@ -151,15 +158,13 @@ def init_list(self): # Go through all bookmarked individuals, and mark all # of the people in each of the paths betweent them. lb = len(bmarks) - for i in range(lb-1): - for j in range(i+1, lb): + for i in range(lb - 1): + for j in range(i + 1, lb): try: pathmap = self.rel_path_for_two(bmarks[i], bmarks[j]) self.map.update(pathmap) except: pass - def apply(self,db,person): + def apply(self, db, person): return person.handle in self.map - - diff --git a/gramps/gen/filters/rules/person/_searchname.py b/gramps/gen/filters/rules/person/_searchname.py index 7b5ad736250..f6b62be8d5b 100644 --- a/gramps/gen/filters/rules/person/_searchname.py +++ b/gramps/gen/filters/rules/person/_searchname.py @@ -19,33 +19,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNameOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SearchName(Rule): """Rule that checks for full or partial name matches""" - labels = [_('Substring:')] - name = _('People matching the ') + labels = [_("Substring:")] + name = _("People matching the ") description = _("Matches people with a specified (partial) name") - category = _('General filters') + category = _("General filters") def apply(self, db, person): src = self.list[0].upper() @@ -53,8 +55,15 @@ def apply(self, db, person): return False for name in [person.get_primary_name()] + person.get_alternate_names(): - for field in [name.first_name, name.get_surname(), name.suffix, - name.title, name.nick, name.famnick, name.call]: + for field in [ + name.first_name, + name.get_surname(), + name.suffix, + name.title, + name.nick, + name.famnick, + name.call, + ]: if src and field.upper().find(src) != -1: return True return False diff --git a/gramps/gen/filters/rules/place/__init__.py b/gramps/gen/filters/rules/place/__init__.py index 793cf3ad8ac..73d406f6c19 100644 --- a/gramps/gen/filters/rules/place/__init__.py +++ b/gramps/gen/filters/rules/place/__init__.py @@ -71,5 +71,5 @@ HasTag, HasTitle, WithinArea, - IsEnclosedBy + IsEnclosedBy, ] diff --git a/gramps/gen/filters/rules/place/_allplaces.py b/gramps/gen/filters/rules/place/_allplaces.py index 993b0c2318c..b3e5f7c22f3 100644 --- a/gramps/gen/filters/rules/place/_allplaces.py +++ b/gramps/gen/filters/rules/place/_allplaces.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._everything import Everything -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Everyone # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class AllPlaces(Everything): """Matches Everyone""" - name = _('Every place') - description = _('Matches every place in the database') + name = _("Every place") + description = _("Matches every place in the database") diff --git a/gramps/gen/filters/rules/place/_changedsince.py b/gramps/gen/filters/rules/place/_changedsince.py index 3bddbc09753..02f8650cd59 100644 --- a/gramps/gen/filters/rules/place/_changedsince.py +++ b/gramps/gen/filters/rules/place/_changedsince.py @@ -20,31 +20,35 @@ # gen.filters.rules/Place/_ChangedSince.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._changedsincebase import ChangedSinceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ChangedSince # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChangedSince(ChangedSinceBase): """Rules that checks for places changed since a specific time.""" - labels = [ _('Changed after:'), _('but before:') ] - name = _('Places changed after ') - description = _("Matches place records changed after a specified " - "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " - "date-time is given.") + labels = [_("Changed after:"), _("but before:")] + name = _("Places changed after ") + description = _( + "Matches place records changed after a specified " + "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " + "date-time is given." + ) diff --git a/gramps/gen/filters/rules/place/_hascitation.py b/gramps/gen/filters/rules/place/_hascitation.py index 92ea0dd1100..7310a05d842 100644 --- a/gramps/gen/filters/rules/place/_hascitation.py +++ b/gramps/gen/filters/rules/place/_hascitation.py @@ -22,32 +22,31 @@ """ Filter rule to match family with a particular citation. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hascitationbase import HasCitationBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasEvent # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasCitation(HasCitationBase): """Rule that checks for a family with a particular value""" - labels = [ _('Volume/Page:'), - _('Date:'), - _('Confidence level:')] - name = _('Place with the ') - description = _("Matches places with a citation of a particular " - "value") + labels = [_("Volume/Page:"), _("Date:"), _("Confidence level:")] + name = _("Place with the ") + description = _("Matches places with a citation of a particular " "value") diff --git a/gramps/gen/filters/rules/place/_hasdata.py b/gramps/gen/filters/rules/place/_hasdata.py index 0eba40fabf5..63ac33a5fdb 100644 --- a/gramps/gen/filters/rules/place/_hasdata.py +++ b/gramps/gen/filters/rules/place/_hasdata.py @@ -19,39 +19,42 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib import PlaceType -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasData # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasData(Rule): """ Rule that checks for a place with a particular value """ - labels = [ _('Name:', 'place'), - _('Place type:'), - _('Code:'), - ] - name = _('Places matching parameters') - description = _('Matches places with particular parameters') - category = _('General filters') + labels = [ + _("Name:", "place"), + _("Place type:"), + _("Code:"), + ] + name = _("Places matching parameters") + description = _("Matches places with particular parameters") + category = _("General filters") allow_regex = True def prepare(self, db, user): diff --git a/gramps/gen/filters/rules/place/_hasgallery.py b/gramps/gen/filters/rules/place/_hasgallery.py index 67ca449798e..842ebc91eb6 100644 --- a/gramps/gen/filters/rules/place/_hasgallery.py +++ b/gramps/gen/filters/rules/place/_hasgallery.py @@ -21,26 +21,28 @@ # # gen.filters.rules/Place/_HasGallery.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasgallerybase import HasGalleryBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Places who have media object reference" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasGallery(HasGalleryBase): """Rule that checks for place who has media object reference""" - name = _('Places with media') + name = _("Places with media") description = _("Matches places with a certain number of items in the gallery") diff --git a/gramps/gen/filters/rules/place/_hasidof.py b/gramps/gen/filters/rules/place/_hasidof.py index 404c467a017..cc01ce3a741 100644 --- a/gramps/gen/filters/rules/place/_hasidof.py +++ b/gramps/gen/filters/rules/place/_hasidof.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import HasGrampsId -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasIdOf(HasGrampsId): """Rule that checks for a place with a specific Gramps ID""" - name = _('Place with ') + name = _("Place with ") description = _("Matches a place with a specified Gramps ID") diff --git a/gramps/gen/filters/rules/place/_hasnolatorlon.py b/gramps/gen/filters/rules/place/_hasnolatorlon.py index ec226bfec7c..768592d3c5a 100644 --- a/gramps/gen/filters/rules/place/_hasnolatorlon.py +++ b/gramps/gen/filters/rules/place/_hasnolatorlon.py @@ -20,36 +20,37 @@ # gen.filters.rules/Place/_HasNoLatOrLon.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasNoLatOrLon # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoLatOrLon(Rule): """Rule that checks if Latitude or Longitude are not given""" - labels = [] - name = _('Places with no latitude or longitude given') + name = _("Places with no latitude or longitude given") description = _("Matches places with empty latitude or longitude") - category = _('Position filters') + category = _("Position filters") - def apply(self,db,place): + def apply(self, db, place): if place.get_latitude().strip and place.get_longitude().strip(): return False return True diff --git a/gramps/gen/filters/rules/place/_hasnote.py b/gramps/gen/filters/rules/place/_hasnote.py index 5a675ed9284..14ad6c0b04a 100644 --- a/gramps/gen/filters/rules/place/_hasnote.py +++ b/gramps/gen/filters/rules/place/_hasnote.py @@ -21,26 +21,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotebase import HasNoteBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Places having notes" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNote(HasNoteBase): """Places having notes""" - name = _('Places having notes') + name = _("Places having notes") description = _("Matches places having a certain number of notes") diff --git a/gramps/gen/filters/rules/place/_hasnotematchingsubstringof.py b/gramps/gen/filters/rules/place/_hasnotematchingsubstringof.py index 4ea8b4078cb..8f899758a12 100644 --- a/gramps/gen/filters/rules/place/_hasnotematchingsubstringof.py +++ b/gramps/gen/filters/rules/place/_hasnotematchingsubstringof.py @@ -18,28 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotesubstrbase import HasNoteSubstrBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Events having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteMatchingSubstringOf(HasNoteSubstrBase): """Places having notes containing """ - name = _('Places having notes containing ') - description = _("Matches places whose notes contain text " - "matching a substring") - + name = _("Places having notes containing ") + description = _("Matches places whose notes contain text " "matching a substring") diff --git a/gramps/gen/filters/rules/place/_hasnoteregexp.py b/gramps/gen/filters/rules/place/_hasnoteregexp.py index 633b5eded43..1d8e2db81a2 100644 --- a/gramps/gen/filters/rules/place/_hasnoteregexp.py +++ b/gramps/gen/filters/rules/place/_hasnoteregexp.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnoteregexbase import HasNoteRegexBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Places having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteRegexp(HasNoteRegexBase): - - name = _('Places having notes containing ') - description = _("Matches places whose notes contain text " - "matching a regular expression") + name = _("Places having notes containing ") + description = _( + "Matches places whose notes contain text " "matching a regular expression" + ) diff --git a/gramps/gen/filters/rules/place/_hasplace.py b/gramps/gen/filters/rules/place/_hasplace.py index 9510bd940af..544a1cc8f2a 100644 --- a/gramps/gen/filters/rules/place/_hasplace.py +++ b/gramps/gen/filters/rules/place/_hasplace.py @@ -20,53 +20,58 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....lib import PlaceType from ....utils.location import get_locations -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasPlace # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasPlace(Rule): """Rule that checks for a place with a particular value""" - labels = [ _('Title:'), - _('Street:'), - _('Locality:'), - _('City:'), - _('County:'), - _('State:'), - _('Country:'), - _('ZIP/Postal Code:'), - _('Church Parish:'), - ] - name = _('Places matching parameters') + labels = [ + _("Title:"), + _("Street:"), + _("Locality:"), + _("City:"), + _("County:"), + _("State:"), + _("Country:"), + _("ZIP/Postal Code:"), + _("Church Parish:"), + ] + name = _("Places matching parameters") description = _("Matches places with particular parameters") - category = _('General filters') + category = _("General filters") allow_regex = True - TYPE2FIELD = {PlaceType.STREET: 1, - PlaceType.LOCALITY: 2, - PlaceType.CITY: 3, - PlaceType.COUNTY: 4, - PlaceType.STATE: 5, - PlaceType.COUNTRY: 6, - PlaceType.PARISH: 8} + TYPE2FIELD = { + PlaceType.STREET: 1, + PlaceType.LOCALITY: 2, + PlaceType.CITY: 3, + PlaceType.COUNTY: 4, + PlaceType.STATE: 5, + PlaceType.COUNTRY: 6, + PlaceType.PARISH: 8, + } def apply(self, db, place): if not self.match_substring(0, place.get_title()): @@ -90,7 +95,7 @@ def check(self, location): Check each location for a match. """ for place_type, field in self.TYPE2FIELD.items(): - name_list = location.get(place_type, ['']) + name_list = location.get(place_type, [""]) if not self.match_name(field, name_list): return False return True diff --git a/gramps/gen/filters/rules/place/_hasreferencecountof.py b/gramps/gen/filters/rules/place/_hasreferencecountof.py index 289cf78fc2f..3776e584828 100644 --- a/gramps/gen/filters/rules/place/_hasreferencecountof.py +++ b/gramps/gen/filters/rules/place/_hasreferencecountof.py @@ -18,27 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasreferencecountbase import HasReferenceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Place objects with a certain reference count" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasReferenceCountOf(HasReferenceCountBase): """Place objects with a reference count of """ - name = _('Places with a reference count of ') + name = _("Places with a reference count of ") description = _("Matches places with a certain reference count") - diff --git a/gramps/gen/filters/rules/place/_hassourcecount.py b/gramps/gen/filters/rules/place/_hassourcecount.py index 6b15362235c..a62a9e5585d 100644 --- a/gramps/gen/filters/rules/place/_hassourcecount.py +++ b/gramps/gen/filters/rules/place/_hassourcecount.py @@ -21,26 +21,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hassourcecountbase import HasSourceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People having sources" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceCount(HasSourceCountBase): """Place with sources""" - name = _('Place with sources') + name = _("Place with sources") description = _("Matches places with a certain number of sources connected to it") diff --git a/gramps/gen/filters/rules/place/_hassourceof.py b/gramps/gen/filters/rules/place/_hassourceof.py index a0ca8feda71..949e82e73f1 100644 --- a/gramps/gen/filters/rules/place/_hassourceof.py +++ b/gramps/gen/filters/rules/place/_hassourceof.py @@ -19,30 +19,32 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hassourceofbase import HasSourceOfBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasSourceOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasSourceOf(HasSourceOfBase): """Rule that checks family that have a particular source.""" - labels = [ _('Source ID:') ] - name = _('Places with the ') - category = _('Citation/source filters') - description = _('Matches places who have a particular source') + labels = [_("Source ID:")] + name = _("Places with the ") + category = _("Citation/source filters") + description = _("Matches places who have a particular source") diff --git a/gramps/gen/filters/rules/place/_hastag.py b/gramps/gen/filters/rules/place/_hastag.py index 2b38e7f1457..21cfb90aa73 100644 --- a/gramps/gen/filters/rules/place/_hastag.py +++ b/gramps/gen/filters/rules/place/_hastag.py @@ -21,30 +21,33 @@ Rule that checks for a place with a particular tag. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hastagbase import HasTagBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTag # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTag(HasTagBase): """ Rule that checks for a place with a particular tag. """ - labels = [ _('Tag:') ] - name = _('Places with the ') + + labels = [_("Tag:")] + name = _("Places with the ") description = _("Matches places with the particular tag") diff --git a/gramps/gen/filters/rules/place/_hastitle.py b/gramps/gen/filters/rules/place/_hastitle.py index 6c5f3ba5f7f..6820e480e81 100644 --- a/gramps/gen/filters/rules/place/_hastitle.py +++ b/gramps/gen/filters/rules/place/_hastitle.py @@ -19,36 +19,38 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....display.place import displayer -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTitle # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTitle(Rule): """ Rule that checks for a place with a title """ - labels = [_('Title:')] - name = _('Places matching a title') - description = _('Matches places with a particular title') - category = _('General filters') + labels = [_("Title:")] + name = _("Places matching a title") + description = _("Matches places with a particular title") + category = _("General filters") allow_regex = True def apply(self, db, place): diff --git a/gramps/gen/filters/rules/place/_inlatlonneighborhood.py b/gramps/gen/filters/rules/place/_inlatlonneighborhood.py index 15e6760946d..c3c6bfa0b40 100644 --- a/gramps/gen/filters/rules/place/_inlatlonneighborhood.py +++ b/gramps/gen/filters/rules/place/_inlatlonneighborhood.py @@ -20,142 +20,154 @@ # gen.filters.rules/Place/_InLatLonNeighborhood.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....utils.place import conv_lat_lon -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # InLatLonNeighborhood # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class InLatLonNeighborhood(Rule): """Rule that checks if a place is in the neighborhood of a given - Latitude or Longitude or""" - - - labels = [_('Latitude:'), _('Longitude:'), - _('Rectangle height:'), _('Rectangle width:')] - name = _('Places in neighborhood of given position') - description = _("Matches places with latitude or longitude positioned in " - "a rectangle of given height and width (in degrees), and " - "with middlepoint the given latitude and longitude." - ) - category = _('Position filters') + Latitude or Longitude or""" + + labels = [ + _("Latitude:"), + _("Longitude:"), + _("Rectangle height:"), + _("Rectangle width:"), + ] + name = _("Places in neighborhood of given position") + description = _( + "Matches places with latitude or longitude positioned in " + "a rectangle of given height and width (in degrees), and " + "with middlepoint the given latitude and longitude." + ) + category = _("Position filters") def prepare(self, db, user): - if self.list[0] : + if self.list[0]: try: - self.halfheight = float(self.list[2])/2. - except ValueError : + self.halfheight = float(self.list[2]) / 2.0 + except ValueError: self.halfheight = None - if self.halfheight is not None and self.halfheight<= 0. : + if self.halfheight is not None and self.halfheight <= 0.0: self.halfheight = None - else : + else: self.halfheight = -1 - #give dummy value - self.list[0] = '0.0' + # give dummy value + self.list[0] = "0.0" - if self.list[1] : + if self.list[1]: try: - self.halfwidth = float(self.list[3])/2. - except ValueError : + self.halfwidth = float(self.list[3]) / 2.0 + except ValueError: self.halfwidth = None - if self.halfwidth is not None and self.halfwidth<= 0. : + if self.halfwidth is not None and self.halfwidth <= 0.0: self.halfwidth = None - else : + else: self.halfwidth = -1 - #give dummy value - self.list[1] = '0.0' + # give dummy value + self.list[1] = "0.0" - #we allow a band instead of a triangle - self.lat, self.lon = conv_lat_lon(self.list[0],self.list[1],"D.D8") - if self.lat is not None and self.lon is not None : + # we allow a band instead of a triangle + self.lat, self.lon = conv_lat_lon(self.list[0], self.list[1], "D.D8") + if self.lat is not None and self.lon is not None: self.lat = float(self.lat) self.lon = float(self.lon) - else : - self.lat = None; self.lon = None + else: + self.lat = None + self.lon = None - #we define the two squares we must look in + # we define the two squares we must look in # can be 0, so check on None - if self.lat is not None and self.halfheight is not None and self.halfheight != -1 : + if ( + self.lat is not None + and self.halfheight is not None + and self.halfheight != -1 + ): self.S = self.lat + self.halfheight - if self.S > 90. : self.S = 90. + if self.S > 90.0: + self.S = 90.0 self.N = self.lat - self.halfheight - if self.N < -90. : self.N = -90. + if self.N < -90.0: + self.N = -90.0 self.doublesquares = False - if self.lon is not None and self.halfwidth is not None and self.halfwidth != -1 : - if self.halfwidth >= 180. : - #the entire longitude is allowed, reset values - self.lon = 0. - self.E = 180. - self.W = -180. - else : - self.E = self.lon +self.halfwidth - self.W = self.lon -self.halfwidth - if self.E > 180. : - #we need to check in two squares: + if self.lon is not None and self.halfwidth is not None and self.halfwidth != -1: + if self.halfwidth >= 180.0: + # the entire longitude is allowed, reset values + self.lon = 0.0 + self.E = 180.0 + self.W = -180.0 + else: + self.E = self.lon + self.halfwidth + self.W = self.lon - self.halfwidth + if self.E > 180.0: + # we need to check in two squares: self.doublesquares = True - self.E2 = self.E -360. - self.W2 = -180. + self.E2 = self.E - 360.0 + self.W2 = -180.0 self.E = 180 - if self.W < -180. : - #we need to check in two squares: + if self.W < -180.0: + # we need to check in two squares: self.doublesquares = True - self.W2 = self.W + 360. - self.E2 = 180. + self.W2 = self.W + 360.0 + self.E2 = 180.0 self.W = -180 - - def apply(self,db,place): - if self.halfheight == -1 and self.halfwidth ==-1 : + def apply(self, db, place): + if self.halfheight == -1 and self.halfwidth == -1: return False # when given, must be valid - if self.lat is None or self.lon is None : + if self.lat is None or self.lon is None: return False # if height/width given, they must be valid - if self.halfheight is None or self.halfwidth is None : + if self.halfheight is None or self.halfwidth is None: return False - #now we know at least one is given in the filter and is valid + # now we know at least one is given in the filter and is valid # the place we look at must have lat AND lon entered - if not ( place.get_latitude().strip and place.get_longitude().strip() ): + if not (place.get_latitude().strip and place.get_longitude().strip()): return False - latpl, lonpl = conv_lat_lon(place.get_latitude(), - place.get_longitude(), "D.D8") - if latpl and lonpl : + latpl, lonpl = conv_lat_lon(place.get_latitude(), place.get_longitude(), "D.D8") + if latpl and lonpl: latpl = float(latpl) lonpl = float(lonpl) - if self.halfheight != -1 : + if self.halfheight != -1: # check lat - if latpl < self.N or latpl > self.S : + if latpl < self.N or latpl > self.S: return False - if self.halfwidth != -1 : - #check lon: more difficult, we may cross the 180/-180 boundary + if self.halfwidth != -1: + # check lon: more difficult, we may cross the 180/-180 boundary # and must keep counting - if self.doublesquares : - #two squares to look in : - if (lonpl self.E) and \ - (lonpl self.E2): + if self.doublesquares: + # two squares to look in : + if (lonpl < self.W or lonpl > self.E) and ( + lonpl < self.W2 or lonpl > self.E2 + ): return False - elif (lonpl self.E): + elif lonpl < self.W or lonpl > self.E: return False return True diff --git a/gramps/gen/filters/rules/place/_isenclosedby.py b/gramps/gen/filters/rules/place/_isenclosedby.py index 0e0d158d049..7be1b88465f 100644 --- a/gramps/gen/filters/rules/place/_isenclosedby.py +++ b/gramps/gen/filters/rules/place/_isenclosedby.py @@ -19,36 +19,38 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule from ....utils.location import located_in -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # IsEnclosedBy # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class IsEnclosedBy(Rule): """ Rule that checks for a place enclosed by another place """ - labels = [_('ID:'), _('Inclusive:')] - name = _('Places enclosed by another place') - description = _('Matches a place enclosed by a particular place') - category = _('General filters') + labels = [_("ID:"), _("Inclusive:")] + name = _("Places enclosed by another place") + description = _("Matches a place enclosed by a particular place") + category = _("General filters") def prepare(self, db, user): self.handle = None @@ -59,7 +61,7 @@ def prepare(self, db, user): def apply(self, db, place): if self.handle is None: return False - if self.list[1] == '1' and place.handle == self.handle: + if self.list[1] == "1" and place.handle == self.handle: return True if located_in(db, place.handle, self.handle): return True diff --git a/gramps/gen/filters/rules/place/_matcheseventfilter.py b/gramps/gen/filters/rules/place/_matcheseventfilter.py index 98332e6acdc..b5a8745d250 100644 --- a/gramps/gen/filters/rules/place/_matcheseventfilter.py +++ b/gramps/gen/filters/rules/place/_matcheseventfilter.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._matchesfilterbase import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesEventFilter(MatchesFilterBase): """ Rule that checks against another filter. @@ -46,19 +48,22 @@ class MatchesEventFilter(MatchesFilterBase): Subclasses need to define the namespace class attribute. """ - labels = [_('Event filter name:')] - name = _('Places of events matching the ') - description = _("Matches places where events happened that match the " - "specified event filter name") - category = _('General filters') + labels = [_("Event filter name:")] + name = _("Places of events matching the ") + description = _( + "Matches places where events happened that match the " + "specified event filter name" + ) + category = _("General filters") # we want to have this filter show event filters - namespace = 'Event' - + namespace = "Event" - def apply(self,db,event): + def apply(self, db, event): filt = self.find_filter() if filt: - for (classname, handle) in db.find_backlink_handles(event.get_handle(), ['Event']): + for classname, handle in db.find_backlink_handles( + event.get_handle(), ["Event"] + ): if filt.check(db, handle): return True return False diff --git a/gramps/gen/filters/rules/place/_matchesfilter.py b/gramps/gen/filters/rules/place/_matchesfilter.py index c78988a97cf..b807549a56a 100644 --- a/gramps/gen/filters/rules/place/_matchesfilter.py +++ b/gramps/gen/filters/rules/place/_matchesfilter.py @@ -18,29 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._matchesfilterbase import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesFilter(MatchesFilterBase): """Rule that checks against another filter""" - name = _('Places matching the ') + name = _("Places matching the ") description = _("Matches places matched by the specified filter name") - namespace = 'Place' + namespace = "Place" diff --git a/gramps/gen/filters/rules/place/_matchessourceconfidence.py b/gramps/gen/filters/rules/place/_matchessourceconfidence.py index 25a2cf7db71..90146904267 100644 --- a/gramps/gen/filters/rules/place/_matchessourceconfidence.py +++ b/gramps/gen/filters/rules/place/_matchessourceconfidence.py @@ -19,27 +19,31 @@ # # Filters/Rules/Person/_MatchesSourceConfidence.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._matchessourceconfidencebase import MatchesSourceConfidenceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Confidence level" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesSourceConfidence(MatchesSourceConfidenceBase): """Media matching a specific confidence level on its 'direct' source references""" - labels = [_('Confidence level:')] - name = _('Place with a direct source >= ') - description = _("Matches places with at least one direct source with confidence level(s)") + labels = [_("Confidence level:")] + name = _("Place with a direct source >= ") + description = _( + "Matches places with at least one direct source with confidence level(s)" + ) diff --git a/gramps/gen/filters/rules/place/_placeprivate.py b/gramps/gen/filters/rules/place/_placeprivate.py index be144470a23..a55162cb609 100644 --- a/gramps/gen/filters/rules/place/_placeprivate.py +++ b/gramps/gen/filters/rules/place/_placeprivate.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._isprivate import IsPrivate -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Family marked private" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PlacePrivate(IsPrivate): """Place marked private""" - name = _('Places marked private') + name = _("Places marked private") description = _("Matches places that are indicated as private") diff --git a/gramps/gen/filters/rules/place/_regexpidof.py b/gramps/gen/filters/rules/place/_regexpidof.py index 4fd00d5e4a3..a1f7dcaca20 100644 --- a/gramps/gen/filters/rules/place/_regexpidof.py +++ b/gramps/gen/filters/rules/place/_regexpidof.py @@ -18,32 +18,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._regexpidbase import RegExpIdBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpIdOf(RegExpIdBase): """ Rule that checks for a place whose Gramps ID matches regular expression. """ - name = _('Places with Id containing ') - description = _("Matches places whose Gramps ID matches " - "the regular expression") + name = _("Places with Id containing ") + description = _("Matches places whose Gramps ID matches " "the regular expression") diff --git a/gramps/gen/filters/rules/place/_withinarea.py b/gramps/gen/filters/rules/place/_withinarea.py index c0cac8eb336..582c8646c1e 100644 --- a/gramps/gen/filters/rules/place/_withinarea.py +++ b/gramps/gen/filters/rules/place/_withinarea.py @@ -23,20 +23,20 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from math import pi, cos, hypot import re -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from gramps.gen.errors import FilterError from ....const import GRAMPS_LOCALE as glocale from .. import Rule @@ -44,20 +44,21 @@ _ = glocale.translation.sgettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # WithinArea # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class WithinArea(Rule): """ Rule that checks for a place within an area """ - labels = [_('ID:'), _('Value:'), _('Units:')] - name = _('Places within an area') - description = _('Matches places within a given distance of another place') - category = _('Position filters') + labels = [_("ID:"), _("Value:"), _("Units:")] + name = _("Places within an area") + description = _("Matches places within a given distance of another place") + category = _("Position filters") handle = None radius = None latitude = None @@ -76,31 +77,33 @@ def prepare(self, db, user): latitude = None return longitude = ref_place.get_longitude() - self.latitude, self.longitude = conv_lat_lon(latitude, - longitude, - "D.D8") + self.latitude, self.longitude = conv_lat_lon(latitude, longitude, "D.D8") if self.latitude is None or self.longitude is None: - raise FilterError(_("Cannot use the filter 'within area'"), - _("The place you selected contains bad" - " coordinates. Please, run the tool " - "'clean input data'")) + raise FilterError( + _("Cannot use the filter 'within area'"), + _( + "The place you selected contains bad" + " coordinates. Please, run the tool " + "'clean input data'" + ), + ) val = self.list[1] if isinstance(val, str): - val = re.sub(r"\D", "", val) # suppress all alpha characters + val = re.sub(r"\D", "", val) # suppress all alpha characters value = int(val) unit = int(self.list[2]) # earth perimeter in kilometers for latitude # 2 * pi * (6371 * cos(latitude/180*pi)) # so 1 degree correspond to the result above / 360 - earth_perimeter = 2*pi*(6371*cos(float(self.latitude)/180*pi)) - if unit == 0: # kilometers - self.radius = float(value / (earth_perimeter/360)) - elif unit == 1: # miles - self.radius = float((value / (earth_perimeter/360))/0.62138) - else: # degrees + earth_perimeter = 2 * pi * (6371 * cos(float(self.latitude) / 180 * pi)) + if unit == 0: # kilometers + self.radius = float(value / (earth_perimeter / 360)) + elif unit == 1: # miles + self.radius = float((value / (earth_perimeter / 360)) / 0.62138) + else: # degrees self.radius = float(value) - self.radius = self.radius/2 + self.radius = self.radius / 2 def apply(self, dummy_db, place): if self.handle is None: @@ -116,8 +119,12 @@ def apply(self, dummy_db, place): latit, longit = conv_lat_lon(lat, lon, "D.D8") if latit is None or longit is None: return False - if (hypot(float(self.latitude)-float(latit), - float(self.longitude)-float(longit)) - <= self.radius): + if ( + hypot( + float(self.latitude) - float(latit), + float(self.longitude) - float(longit), + ) + <= self.radius + ): return True return False diff --git a/gramps/gen/filters/rules/repository/__init__.py b/gramps/gen/filters/rules/repository/__init__.py index 8e3a3c536df..0c8cd3f8b68 100644 --- a/gramps/gen/filters/rules/repository/__init__.py +++ b/gramps/gen/filters/rules/repository/__init__.py @@ -47,5 +47,5 @@ MatchesFilter, ChangedSince, MatchesNameSubstringOf, - HasTag + HasTag, ] diff --git a/gramps/gen/filters/rules/repository/_allrepos.py b/gramps/gen/filters/rules/repository/_allrepos.py index cb6ed4dcd34..c8f312c9382 100644 --- a/gramps/gen/filters/rules/repository/_allrepos.py +++ b/gramps/gen/filters/rules/repository/_allrepos.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._everything import Everything -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Everyone # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class AllRepos(Everything): """Matches Everyone""" - name = _('Every repository') - description = _('Matches every repository in the database') + name = _("Every repository") + description = _("Matches every repository in the database") diff --git a/gramps/gen/filters/rules/repository/_changedsince.py b/gramps/gen/filters/rules/repository/_changedsince.py index 2339d57108e..ae01f32d242 100644 --- a/gramps/gen/filters/rules/repository/_changedsince.py +++ b/gramps/gen/filters/rules/repository/_changedsince.py @@ -20,31 +20,35 @@ # gen.filters.rules/Repository/_ChangedSince.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._changedsincebase import ChangedSinceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ChangedSince # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChangedSince(ChangedSinceBase): """Rule that checks for repositories changed since a specific time.""" - labels = [ _('Changed after:'), _('but before:') ] - name = _('Repositories changed after ') - description = _("Matches repository records changed after a specified " - "date/time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " - "date/time is given.") + labels = [_("Changed after:"), _("but before:")] + name = _("Repositories changed after ") + description = _( + "Matches repository records changed after a specified " + "date/time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " + "date/time is given." + ) diff --git a/gramps/gen/filters/rules/repository/_hasattribute.py b/gramps/gen/filters/rules/repository/_hasattribute.py index 875356c6b5b..013cdb2631f 100644 --- a/gramps/gen/filters/rules/repository/_hasattribute.py +++ b/gramps/gen/filters/rules/repository/_hasattribute.py @@ -25,6 +25,7 @@ # # ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext # ------------------------------------------------------------------------- @@ -43,7 +44,6 @@ class HasAttribute(HasAttributeBase): """Rule that checks for a repository with a particular attribute""" - labels = [_('Repository attribute:'), _('Value:')] - name = _('Repositories with the attribute ') - description = _("Matches repositories with the attribute " - "of a particular value") + labels = [_("Repository attribute:"), _("Value:")] + name = _("Repositories with the attribute ") + description = _("Matches repositories with the attribute " "of a particular value") diff --git a/gramps/gen/filters/rules/repository/_hasidof.py b/gramps/gen/filters/rules/repository/_hasidof.py index f1d750ad596..2c7e1f7c901 100644 --- a/gramps/gen/filters/rules/repository/_hasidof.py +++ b/gramps/gen/filters/rules/repository/_hasidof.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import HasGrampsId -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasIdOf(HasGrampsId): """Rule that checks for a repo with a specific Gramps ID""" - name = _('Repository with ') + name = _("Repository with ") description = _("Matches a repository with a specified Gramps ID") diff --git a/gramps/gen/filters/rules/repository/_hasnotematchingsubstringof.py b/gramps/gen/filters/rules/repository/_hasnotematchingsubstringof.py index aca952e394d..dcb0ac1ce96 100644 --- a/gramps/gen/filters/rules/repository/_hasnotematchingsubstringof.py +++ b/gramps/gen/filters/rules/repository/_hasnotematchingsubstringof.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotesubstrbase import HasNoteSubstrBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Events having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteMatchingSubstringOf(HasNoteSubstrBase): """Repos having notes containing """ - name = _('Repositories having notes containing ') - description = _("Matches repositories whose notes contain text " - "matching a substring") - + name = _("Repositories having notes containing ") + description = _( + "Matches repositories whose notes contain text " "matching a substring" + ) diff --git a/gramps/gen/filters/rules/repository/_hasnoteregexp.py b/gramps/gen/filters/rules/repository/_hasnoteregexp.py index 68cb53eddb6..3f1bacdfb2f 100644 --- a/gramps/gen/filters/rules/repository/_hasnoteregexp.py +++ b/gramps/gen/filters/rules/repository/_hasnoteregexp.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnoteregexbase import HasNoteRegexBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Repos having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteRegexp(HasNoteRegexBase): - - name = _('Repositories having notes containing ') - description = _("Matches repositories whose notes contain text " - "matching a regular expression") + name = _("Repositories having notes containing ") + description = _( + "Matches repositories whose notes contain text " "matching a regular expression" + ) diff --git a/gramps/gen/filters/rules/repository/_hasreferencecountof.py b/gramps/gen/filters/rules/repository/_hasreferencecountof.py index 99eeee71a35..b817fe0ba17 100644 --- a/gramps/gen/filters/rules/repository/_hasreferencecountof.py +++ b/gramps/gen/filters/rules/repository/_hasreferencecountof.py @@ -18,27 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasreferencecountbase import HasReferenceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Repositories with a certain reference count" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasReferenceCountOf(HasReferenceCountBase): """Repositories with a reference count of """ - name = _('Repositories with a reference count of ') + name = _("Repositories with a reference count of ") description = _("Matches repositories with a certain reference count") - diff --git a/gramps/gen/filters/rules/repository/_hasrepo.py b/gramps/gen/filters/rules/repository/_hasrepo.py index 67b169580a2..795bd20c6a8 100644 --- a/gramps/gen/filters/rules/repository/_hasrepo.py +++ b/gramps/gen/filters/rules/repository/_hasrepo.py @@ -18,39 +18,41 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....lib.repotype import RepositoryType from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasRepo # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasRepo(Rule): """Rule that checks for a repo with a particular value""" - - labels = [ _('Name:', 'repo'), - _('Type:'), - _('Address:'), - _('URL:'), - ] - name = _('Repositories matching parameters') + labels = [ + _("Name:", "repo"), + _("Type:"), + _("Address:"), + _("URL:"), + ] + name = _("Repositories matching parameters") description = _("Matches Repositories with particular parameters") - category = _('General filters') + category = _("General filters") allow_regex = True def prepare(self, db, user): @@ -75,7 +77,7 @@ def apply(self, db, repo): addr_match = False for addr in repo.address_list: # TODO for Arabic, should the next line's comma be translated? - addr_text = ', '.join(addr.get_text_data_list()) + addr_text = ", ".join(addr.get_text_data_list()) if self.match_substring(2, addr_text): addr_match = True break @@ -86,7 +88,7 @@ def apply(self, db, repo): url_match = False for url in repo.urls: # TODO for Arabic, should the next line's comma be translated? - url_text = ', '.join(url.get_text_data_list()) + url_text = ", ".join(url.get_text_data_list()) if self.match_substring(3, url_text): url_match = True break diff --git a/gramps/gen/filters/rules/repository/_hastag.py b/gramps/gen/filters/rules/repository/_hastag.py index c8d5c833e94..e1c81a3a179 100644 --- a/gramps/gen/filters/rules/repository/_hastag.py +++ b/gramps/gen/filters/rules/repository/_hastag.py @@ -21,30 +21,33 @@ Rule that checks for a repository with a particular tag. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hastagbase import HasTagBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTag # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTag(HasTagBase): """ Rule that checks for a repository with a particular tag. """ - labels = [ _('Tag:') ] - name = _('Repositories with the ') + + labels = [_("Tag:")] + name = _("Repositories with the ") description = _("Matches repositories with the particular tag") diff --git a/gramps/gen/filters/rules/repository/_matchesfilter.py b/gramps/gen/filters/rules/repository/_matchesfilter.py index 7de4b90dfbb..f4cb3e23184 100644 --- a/gramps/gen/filters/rules/repository/_matchesfilter.py +++ b/gramps/gen/filters/rules/repository/_matchesfilter.py @@ -18,30 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._matchesfilterbase import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesFilter(MatchesFilterBase): """Rule that checks against another filter""" - name = _('Repositories matching the ') - description = _("Matches repositories matched " - "by the specified filter name") - namespace = 'Repository' + name = _("Repositories matching the ") + description = _("Matches repositories matched " "by the specified filter name") + namespace = "Repository" diff --git a/gramps/gen/filters/rules/repository/_matchesnamesubstringof.py b/gramps/gen/filters/rules/repository/_matchesnamesubstringof.py index f2076204a36..8ae45db63c4 100644 --- a/gramps/gen/filters/rules/repository/_matchesnamesubstringof.py +++ b/gramps/gen/filters/rules/repository/_matchesnamesubstringof.py @@ -18,33 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Repositories having a name that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesNameSubstringOf(Rule): """Repository name containing """ - labels = [ _('Text:')] - name = _('Repositories with name containing ') + labels = [_("Text:")] + name = _("Repositories with name containing ") description = _("Matches repositories whose name contains a certain substring") - category = _('General filters') + category = _("General filters") allow_regex = True def apply(self, db, repository): - """ Apply the filter """ + """Apply the filter""" return self.match_substring(0, repository.get_name()) diff --git a/gramps/gen/filters/rules/repository/_regexpidof.py b/gramps/gen/filters/rules/repository/_regexpidof.py index 73e724862c8..7f6b7185bcb 100644 --- a/gramps/gen/filters/rules/repository/_regexpidof.py +++ b/gramps/gen/filters/rules/repository/_regexpidof.py @@ -18,32 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._regexpidbase import RegExpIdBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpIdOf(RegExpIdBase): """ Rule that checks for a repo whose Gramps ID matches regular expression. """ - name = _('Repositories with Id containing ') - description = _("Matches repositories whose Gramps ID matches " - "the regular expression") + name = _("Repositories with Id containing ") + description = _( + "Matches repositories whose Gramps ID matches " "the regular expression" + ) diff --git a/gramps/gen/filters/rules/repository/_repoprivate.py b/gramps/gen/filters/rules/repository/_repoprivate.py index da88aeb2f7b..b4bb52396ec 100644 --- a/gramps/gen/filters/rules/repository/_repoprivate.py +++ b/gramps/gen/filters/rules/repository/_repoprivate.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._isprivate import IsPrivate -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Repo marked private" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RepoPrivate(IsPrivate): """Repo marked private""" - name = _('Repositories marked private') + name = _("Repositories marked private") description = _("Matches repositories that are indicated as private") diff --git a/gramps/gen/filters/rules/source/__init__.py b/gramps/gen/filters/rules/source/__init__.py index 83184cccd0c..27df1c6ecb0 100644 --- a/gramps/gen/filters/rules/source/__init__.py +++ b/gramps/gen/filters/rules/source/__init__.py @@ -60,5 +60,5 @@ MatchesTitleSubstringOf, HasRepositoryCallNumberRef, MatchesRepositoryFilter, - HasTag + HasTag, ] diff --git a/gramps/gen/filters/rules/source/_allsources.py b/gramps/gen/filters/rules/source/_allsources.py index 118868d104a..d884fe2fa04 100644 --- a/gramps/gen/filters/rules/source/_allsources.py +++ b/gramps/gen/filters/rules/source/_allsources.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._everything import Everything -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Everyone # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class AllSources(Everything): """Matches Everyone""" - name = _('Every source') - description = _('Matches every source in the database') + name = _("Every source") + description = _("Matches every source in the database") diff --git a/gramps/gen/filters/rules/source/_changedsince.py b/gramps/gen/filters/rules/source/_changedsince.py index 320e4be8d94..31e7c6239a1 100644 --- a/gramps/gen/filters/rules/source/_changedsince.py +++ b/gramps/gen/filters/rules/source/_changedsince.py @@ -20,31 +20,35 @@ # gen.filters.rules/Source/_ChangedSince.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._changedsincebase import ChangedSinceBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ChangedSince # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChangedSince(ChangedSinceBase): """Rule that checks for sources changed since a specific time.""" - labels = [ _('Changed after:'), _('but before:') ] - name = _('Sources changed after ') - description = _("Matches source records changed after a specified " - "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " - "date-time is given.") + labels = [_("Changed after:"), _("but before:")] + name = _("Sources changed after ") + description = _( + "Matches source records changed after a specified " + "date-time (yyyy-mm-dd hh:mm:ss) or in the range, if a second " + "date-time is given." + ) diff --git a/gramps/gen/filters/rules/source/_hasattribute.py b/gramps/gen/filters/rules/source/_hasattribute.py index f9bb0c675b1..c4090f4b873 100644 --- a/gramps/gen/filters/rules/source/_hasattribute.py +++ b/gramps/gen/filters/rules/source/_hasattribute.py @@ -25,6 +25,7 @@ # # ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext # ------------------------------------------------------------------------- @@ -43,7 +44,6 @@ class HasAttribute(HasAttributeBase): """Rule that checks for a source with a particular attribute""" - labels = [_('Source attribute:'), _('Value:')] - name = _('Sources with the attribute ') - description = _("Matches sources with the attribute " - "of a particular value") + labels = [_("Source attribute:"), _("Value:")] + name = _("Sources with the attribute ") + description = _("Matches sources with the attribute " "of a particular value") diff --git a/gramps/gen/filters/rules/source/_hasgallery.py b/gramps/gen/filters/rules/source/_hasgallery.py index 497c730dd6d..ccdf2c23706 100644 --- a/gramps/gen/filters/rules/source/_hasgallery.py +++ b/gramps/gen/filters/rules/source/_hasgallery.py @@ -21,26 +21,28 @@ # # gen.filters.rules/Source/_HasGallery.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasgallerybase import HasGalleryBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Sources who have media object reference" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasGallery(HasGalleryBase): """Rule that checks for source who has media object reference""" - name = _('Sources with media') + name = _("Sources with media") description = _("Matches sources with a certain number of items in the gallery") diff --git a/gramps/gen/filters/rules/source/_hasidof.py b/gramps/gen/filters/rules/source/_hasidof.py index bd88111e82d..ec7a69e1e13 100644 --- a/gramps/gen/filters/rules/source/_hasidof.py +++ b/gramps/gen/filters/rules/source/_hasidof.py @@ -18,28 +18,30 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import HasGrampsId -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasIdOf(HasGrampsId): """Rule that checks for a source with a specific Gramps ID""" - name = _('Source with ') + name = _("Source with ") description = _("Matches a source with a specified Gramps ID") diff --git a/gramps/gen/filters/rules/source/_hasnote.py b/gramps/gen/filters/rules/source/_hasnote.py index 8b4a06ebc38..a4edfe84b35 100644 --- a/gramps/gen/filters/rules/source/_hasnote.py +++ b/gramps/gen/filters/rules/source/_hasnote.py @@ -21,26 +21,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotebase import HasNoteBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Sources having notes" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNote(HasNoteBase): """Sources having notes""" - name = _('Sources having notes') + name = _("Sources having notes") description = _("Matches sources having a certain number of notes") diff --git a/gramps/gen/filters/rules/source/_hasnotematchingsubstringof.py b/gramps/gen/filters/rules/source/_hasnotematchingsubstringof.py index 05267719470..1b38ee8a7da 100644 --- a/gramps/gen/filters/rules/source/_hasnotematchingsubstringof.py +++ b/gramps/gen/filters/rules/source/_hasnotematchingsubstringof.py @@ -18,28 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnotesubstrbase import HasNoteSubstrBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Events having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteMatchingSubstringOf(HasNoteSubstrBase): """Sources having notes containing """ - name = _('Sources having notes containing ') - description = _("Matches sources whose notes contain text " - "matching a substring") - + name = _("Sources having notes containing ") + description = _("Matches sources whose notes contain text " "matching a substring") diff --git a/gramps/gen/filters/rules/source/_hasnoteregexp.py b/gramps/gen/filters/rules/source/_hasnoteregexp.py index 1ebfd11c9ca..acc6a22a972 100644 --- a/gramps/gen/filters/rules/source/_hasnoteregexp.py +++ b/gramps/gen/filters/rules/source/_hasnoteregexp.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasnoteregexbase import HasNoteRegexBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Sources having notes that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasNoteRegexp(HasNoteRegexBase): - - name = _('Sources having notes containing ') - description = _("Matches sources whose notes contain text " - "matching a regular expression") + name = _("Sources having notes containing ") + description = _( + "Matches sources whose notes contain text " "matching a regular expression" + ) diff --git a/gramps/gen/filters/rules/source/_hasreferencecountof.py b/gramps/gen/filters/rules/source/_hasreferencecountof.py index df33d42adc6..5b44f27c60d 100644 --- a/gramps/gen/filters/rules/source/_hasreferencecountof.py +++ b/gramps/gen/filters/rules/source/_hasreferencecountof.py @@ -18,27 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hasreferencecountbase import HasReferenceCountBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Source objects with a certain reference count" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasReferenceCountOf(HasReferenceCountBase): """Source objects with a reference count of """ - name = _('Sources with a reference count of ') + name = _("Sources with a reference count of ") description = _("Matches sources with a certain reference count") - diff --git a/gramps/gen/filters/rules/source/_hasrepository.py b/gramps/gen/filters/rules/source/_hasrepository.py index b14bff2286e..e1c9c8e626a 100644 --- a/gramps/gen/filters/rules/source/_hasrepository.py +++ b/gramps/gen/filters/rules/source/_hasrepository.py @@ -22,48 +22,50 @@ # # gen.filters.rules/Source/_HasRepository.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "People who have images" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasRepository(Rule): """Objects which reference repositories""" - labels = [ _('Number of instances:'), _('Number must be:')] - name = _('Sources with Repository references') + labels = [_("Number of instances:"), _("Number must be:")] + name = _("Sources with Repository references") description = _("Matches sources with a certain number of repository references") - category = _('General filters') + category = _("General filters") def prepare(self, db, user): # things we want to do just once, not for every handle - if self.list[1] == 'less than': + if self.list[1] == "less than": self.count_type = 0 - elif self.list[1] == 'greater than': + elif self.list[1] == "greater than": self.count_type = 2 else: - self.count_type = 1 # "equal to" + self.count_type = 1 # "equal to" self.userSelectedCount = int(self.list[0]) def apply(self, db, obj): count = len(obj.get_reporef_list()) - if self.count_type == 0: # "less than" + if self.count_type == 0: # "less than" return count < self.userSelectedCount - elif self.count_type == 2: # "greater than" + elif self.count_type == 2: # "greater than" return count > self.userSelectedCount # "equal to" return count == self.userSelectedCount diff --git a/gramps/gen/filters/rules/source/_hasrepositorycallnumberref.py b/gramps/gen/filters/rules/source/_hasrepositorycallnumberref.py index 625d264f936..090172cf654 100644 --- a/gramps/gen/filters/rules/source/_hasrepositorycallnumberref.py +++ b/gramps/gen/filters/rules/source/_hasrepositorycallnumberref.py @@ -19,32 +19,36 @@ # # gen.filters.rules/Source/_HasRepositoryCallNumberRef.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Sources which reference repositories by a special Call Name" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasRepositoryCallNumberRef(Rule): """Sources which reference repositories by a special Call Number""" - labels = [ _('Text:')] + labels = [_("Text:")] name = _('Sources with repository reference containing in "Call Number"') - description = _("Matches sources with a repository reference\n" - "containing a substring in \"Call Number\"") - category = _('General filters') + description = _( + "Matches sources with a repository reference\n" + 'containing a substring in "Call Number"' + ) + category = _("General filters") allow_regex = True def apply(self, db, obj): diff --git a/gramps/gen/filters/rules/source/_hastag.py b/gramps/gen/filters/rules/source/_hastag.py index b67f34904d1..70047d906bd 100644 --- a/gramps/gen/filters/rules/source/_hastag.py +++ b/gramps/gen/filters/rules/source/_hastag.py @@ -21,30 +21,33 @@ Rule that checks for a source with a particular tag. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._hastagbase import HasTagBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasTag # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class HasTag(HasTagBase): """ Rule that checks for a source with a particular tag. """ - labels = [ _('Tag:') ] - name = _('Sources with the ') + + labels = [_("Tag:")] + name = _("Sources with the ") description = _("Matches sources with the particular tag") diff --git a/gramps/gen/filters/rules/source/_matchesfilter.py b/gramps/gen/filters/rules/source/_matchesfilter.py index 8d2c2d3574c..1b5bc79cdbb 100644 --- a/gramps/gen/filters/rules/source/_matchesfilter.py +++ b/gramps/gen/filters/rules/source/_matchesfilter.py @@ -18,29 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._matchesfilterbase import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MatchesFilter # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesFilter(MatchesFilterBase): """Rule that checks against another filter""" - name = _('Sources matching the ') + name = _("Sources matching the ") description = _("Matches sources matched by the specified filter name") - namespace = 'Source' + namespace = "Source" diff --git a/gramps/gen/filters/rules/source/_matchesrepositoryfilter.py b/gramps/gen/filters/rules/source/_matchesrepositoryfilter.py index 17cecadc4b0..2c0e8f18222 100644 --- a/gramps/gen/filters/rules/source/_matchesrepositoryfilter.py +++ b/gramps/gen/filters/rules/source/_matchesrepositoryfilter.py @@ -19,48 +19,51 @@ # # gen.filters.rules/Source/_MatchesRepositoryFilter.py -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import MatchesFilterBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Sources which reference a repository by selection" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesRepositoryFilter(MatchesFilterBase): """Sources which reference the selected repository""" - labels = [ _('Repository filter name:') ] - name = _('Sources with repository reference matching the ') - description = _("Matches sources with a repository reference that match a certain\n" - "repository filter") - category = _('General filters') + labels = [_("Repository filter name:")] + name = _("Sources with repository reference matching the ") + description = _( + "Matches sources with a repository reference that match a certain\n" + "repository filter" + ) + category = _("General filters") # we want to have this filter show repository filters - namespace = 'Repository' - + namespace = "Repository" def prepare(self, db, user): MatchesFilterBase.prepare(self, db, user) self.MRF_filt = self.find_filter() def apply(self, db, object): - if self.MRF_filt is None : + if self.MRF_filt is None: return False repolist = [x.ref for x in object.get_reporef_list()] for repohandle in repolist: - #check if repo in repository filter + # check if repo in repository filter if self.MRF_filt.check(db, repohandle): return True return False diff --git a/gramps/gen/filters/rules/source/_matchestitlesubstringof.py b/gramps/gen/filters/rules/source/_matchestitlesubstringof.py index 0c5c31bd2e4..e88e70c7362 100644 --- a/gramps/gen/filters/rules/source/_matchestitlesubstringof.py +++ b/gramps/gen/filters/rules/source/_matchestitlesubstringof.py @@ -18,34 +18,35 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .. import Rule -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Sources having a title that contain a substring" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MatchesTitleSubstringOf(Rule): """Source title containing """ - labels = [ _('Text:')] - name = _('Sources with title containing ') - description = _("Matches sources whose title contains a " - "certain substring") - category = _('General filters') + labels = [_("Text:")] + name = _("Sources with title containing ") + description = _("Matches sources whose title contains a " "certain substring") + category = _("General filters") allow_regex = True def apply(self, db, source): - """ Apply the filter """ + """Apply the filter""" return self.match_substring(0, source.get_title()) diff --git a/gramps/gen/filters/rules/source/_regexpidof.py b/gramps/gen/filters/rules/source/_regexpidof.py index 0ffba1e520d..df7f49c8741 100644 --- a/gramps/gen/filters/rules/source/_regexpidof.py +++ b/gramps/gen/filters/rules/source/_regexpidof.py @@ -18,32 +18,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._regexpidbase import RegExpIdBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # HasIdOf # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RegExpIdOf(RegExpIdBase): """ Rule that checks for a source whose Gramps ID matches regular expression. """ - name = _('Sources with Id containing ') - description = _("Matches sources whose Gramps ID matches " - "the regular expression") + name = _("Sources with Id containing ") + description = _("Matches sources whose Gramps ID matches " "the regular expression") diff --git a/gramps/gen/filters/rules/source/_sourceprivate.py b/gramps/gen/filters/rules/source/_sourceprivate.py index 173534dc7f7..4b960441fdf 100644 --- a/gramps/gen/filters/rules/source/_sourceprivate.py +++ b/gramps/gen/filters/rules/source/_sourceprivate.py @@ -18,26 +18,28 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ....const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .._isprivate import IsPrivate -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # "Family marked private" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SourcePrivate(IsPrivate): """Source marked private""" - name = _('Sources marked private') + name = _("Sources marked private") description = _("Matches sources that are indicated as private") diff --git a/gramps/gen/filters/rules/test/event_rules_test.py b/gramps/gen/filters/rules/test/event_rules_test.py index 98dd227df36..380e15cdec1 100644 --- a/gramps/gen/filters/rules/test/event_rules_test.py +++ b/gramps/gen/filters/rules/test/event_rules_test.py @@ -31,14 +31,29 @@ from ....utils.unittest import localize_date from ..event import ( - AllEvents, HasType, HasIdOf, HasGallery, RegExpIdOf, HasCitation, HasNote, - HasNoteRegexp, HasReferenceCountOf, HasSourceCount, EventPrivate, - MatchesSourceConfidence, HasAttribute, HasData, ChangedSince, HasTag, - HasDayOfWeek) + AllEvents, + HasType, + HasIdOf, + HasGallery, + RegExpIdOf, + HasCitation, + HasNote, + HasNoteRegexp, + HasReferenceCountOf, + HasSourceCount, + EventPrivate, + MatchesSourceConfidence, + HasAttribute, + HasData, + ChangedSince, + HasTag, + HasDayOfWeek, +) TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests")) EXAMPLE = os.path.join(TEST_DIR, "example.gramps") -GenericEventFilter = GenericFilterFactory('Event') +GenericEventFilter = GenericFilterFactory("Event") + class BaseTest(unittest.TestCase): """ @@ -66,84 +81,91 @@ def test_allevents(self): Test AllEvents rule. """ rule = AllEvents([]) - self.assertEqual(len(self.filter_with_rule(rule)), - self.db.get_number_of_events()) + self.assertEqual( + len(self.filter_with_rule(rule)), self.db.get_number_of_events() + ) def test_hastype(self): """ Test HasType rule. """ - rule = HasType(['Burial']) + rule = HasType(["Burial"]) self.assertEqual(len(self.filter_with_rule(rule)), 296) def test_hasidof(self): """ Test HasIdOf rule. """ - rule = HasIdOf(['E0001']) - self.assertEqual(self.filter_with_rule(rule), - set(['a5af0eb696917232725'])) + rule = HasIdOf(["E0001"]) + self.assertEqual(self.filter_with_rule(rule), set(["a5af0eb696917232725"])) def test_hasgallery(self): """ Test HasGallery rule. """ - rule = HasGallery(['0', 'greater than']) - self.assertEqual(self.filter_with_rule(rule), - set(['a5af0ecb107303354a0'])) + rule = HasGallery(["0", "greater than"]) + self.assertEqual(self.filter_with_rule(rule), set(["a5af0ecb107303354a0"])) def test_regexpidof(self): """ Test RegExpIdOf rule. """ - rule = RegExpIdOf(['E000.'], use_regex=True) - self.assertEqual(self.filter_with_rule(rule), set([ - 'a5af0eb69cf2d3fb615', 'a5af0eb667015e355db', - 'a5af0eb6a016da2d6d1', 'a5af0eb6a405acb126c', - 'a5af0eb698f29568502', 'a5af0eb69b82a6cdc5a', - 'a5af0eb69f41bfb5a6a', 'a5af0eb69c40c179441', - 'a5af0eb6a3229544ba2', 'a5af0eb696917232725'])) + rule = RegExpIdOf(["E000."], use_regex=True) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "a5af0eb69cf2d3fb615", + "a5af0eb667015e355db", + "a5af0eb6a016da2d6d1", + "a5af0eb6a405acb126c", + "a5af0eb698f29568502", + "a5af0eb69b82a6cdc5a", + "a5af0eb69f41bfb5a6a", + "a5af0eb69c40c179441", + "a5af0eb6a3229544ba2", + "a5af0eb696917232725", + ] + ), + ) def test_hascitation(self): """ Test HasCitation rule. """ - rule = HasCitation(['page 1', '', '']) - self.assertEqual(self.filter_with_rule(rule), - set(['a5af0ecb107303354a0'])) + rule = HasCitation(["page 1", "", ""]) + self.assertEqual(self.filter_with_rule(rule), set(["a5af0ecb107303354a0"])) def test_hasnote(self): """ Test HasNote rule. """ rule = HasNote([]) - self.assertEqual(self.filter_with_rule(rule), - set(['a5af0ecb11f5ac3110e'])) + self.assertEqual(self.filter_with_rule(rule), set(["a5af0ecb11f5ac3110e"])) def test_hasnoteregexp(self): """ Test HasNoteRegexp rule. """ - rule = HasNoteRegexp(['.'], use_regex=True) - self.assertEqual(self.filter_with_rule(rule), - set(['a5af0ecb11f5ac3110e'])) + rule = HasNoteRegexp(["."], use_regex=True) + self.assertEqual(self.filter_with_rule(rule), set(["a5af0ecb11f5ac3110e"])) def test_hasreferencecountof(self): """ Test HasReferenceCountOf rule. """ - rule = HasReferenceCountOf(['greater than', '1']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'cc8205d86fc4e9706a5', 'a5af0ed60de7a612b9e', - 'cc820604ef05cb67907'])) + rule = HasReferenceCountOf(["greater than", "1"]) + self.assertEqual( + self.filter_with_rule(rule), + set(["cc8205d86fc4e9706a5", "a5af0ed60de7a612b9e", "cc820604ef05cb67907"]), + ) def test_hassourcecount(self): """ Test HasSourceCount rule. """ - rule = HasSourceCount(['1', 'greater than']) - self.assertEqual(self.filter_with_rule(rule), - set(['a5af0ecb107303354a0'])) + rule = HasSourceCount(["1", "greater than"]) + self.assertEqual(self.filter_with_rule(rule), set(["a5af0ecb107303354a0"])) def test_eventprivate(self): """ @@ -156,49 +178,49 @@ def test_matchessourceconfidence(self): """ Test MatchesSourceConfidence rule. """ - rule = MatchesSourceConfidence(['2']) - self.assertEqual(self.filter_with_rule(rule), - set(['a5af0ecb107303354a0'])) + rule = MatchesSourceConfidence(["2"]) + self.assertEqual(self.filter_with_rule(rule), set(["a5af0ecb107303354a0"])) def test_hasattribute(self): """ Test HasAttribute rule. """ - rule = HasAttribute(['Cause', '']) - self.assertEqual(self.filter_with_rule(rule), - set(['a5af0ecb11f5ac3110e'])) + rule = HasAttribute(["Cause", ""]) + self.assertEqual(self.filter_with_rule(rule), set(["a5af0ecb11f5ac3110e"])) def test_hasdata(self): """ Test HasData rule. """ - date_str = localize_date('before 1800') - rule = HasData(['Burial', date_str, 'USA', '']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'a5af0ed4211095487d2', 'a5af0ed36793c1d3e05', - 'a5af0ecfcc16ce7a96a'])) + date_str = localize_date("before 1800") + rule = HasData(["Burial", date_str, "USA", ""]) + self.assertEqual( + self.filter_with_rule(rule), + set(["a5af0ed4211095487d2", "a5af0ed36793c1d3e05", "a5af0ecfcc16ce7a96a"]), + ) def test_changedsince(self): """ Test ChangedSince rule. """ - rule = ChangedSince(['2011-01-01', '2014-01-01']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'a5af0ecb107303354a0', 'a5af0ecb11f5ac3110e', - 'a5af0ed5df832ee65c1'])) + rule = ChangedSince(["2011-01-01", "2014-01-01"]) + self.assertEqual( + self.filter_with_rule(rule), + set(["a5af0ecb107303354a0", "a5af0ecb11f5ac3110e", "a5af0ed5df832ee65c1"]), + ) def test_hastag(self): """ Test HasTag rule. """ - rule = HasTag(['ToDo']) + rule = HasTag(["ToDo"]) self.assertEqual(self.filter_with_rule(rule), set([])) def test_hasdayofweek(self): """ Test HasDayOfWeek rule. """ - rule = HasDayOfWeek(['2']) + rule = HasDayOfWeek(["2"]) self.assertEqual(len(self.filter_with_rule(rule)), 185) diff --git a/gramps/gen/filters/rules/test/family_rules_test.py b/gramps/gen/filters/rules/test/family_rules_test.py index 7ff0b6e8d1e..f9afa9b7b39 100644 --- a/gramps/gen/filters/rules/test/family_rules_test.py +++ b/gramps/gen/filters/rules/test/family_rules_test.py @@ -31,16 +31,40 @@ from ....utils.unittest import localize_date from ..family import ( - AllFamilies, HasRelType, HasGallery, HasIdOf, HasLDS, HasNote, RegExpIdOf, - HasNoteRegexp, HasReferenceCountOf, HasSourceCount, HasSourceOf, - HasCitation, FamilyPrivate, HasEvent, HasAttribute, IsBookmarked, - MatchesSourceConfidence, FatherHasNameOf, FatherHasIdOf, MotherHasNameOf, - MotherHasIdOf, ChildHasNameOf, ChildHasIdOf, ChangedSince, HasTag, - HasTwins, IsAncestorOf, IsDescendantOf) + AllFamilies, + HasRelType, + HasGallery, + HasIdOf, + HasLDS, + HasNote, + RegExpIdOf, + HasNoteRegexp, + HasReferenceCountOf, + HasSourceCount, + HasSourceOf, + HasCitation, + FamilyPrivate, + HasEvent, + HasAttribute, + IsBookmarked, + MatchesSourceConfidence, + FatherHasNameOf, + FatherHasIdOf, + MotherHasNameOf, + MotherHasIdOf, + ChildHasNameOf, + ChildHasIdOf, + ChangedSince, + HasTag, + HasTwins, + IsAncestorOf, + IsDescendantOf, +) TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests")) EXAMPLE = os.path.join(TEST_DIR, "example.gramps") -GenericFamilyFilter = GenericFilterFactory('Family') +GenericFamilyFilter = GenericFilterFactory("Family") + class BaseTest(unittest.TestCase): """ @@ -68,103 +92,118 @@ def test_allfamilies(self): Test AllFamilies rule. """ rule = AllFamilies([]) - self.assertEqual(len(self.filter_with_rule(rule)), - self.db.get_number_of_families()) + self.assertEqual( + len(self.filter_with_rule(rule)), self.db.get_number_of_families() + ) def test_hasreltype(self): """ Test HasRelType rule. """ - rule = HasRelType(['Married']) + rule = HasRelType(["Married"]) self.assertEqual(len(self.filter_with_rule(rule)), 750) def test_hasgallery(self): """ Test HasGallery rule. """ - rule = HasGallery(['0', 'greater than']) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + rule = HasGallery(["0", "greater than"]) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_hasidof(self): """ Test HasIdOf rule. """ - rule = HasIdOf(['F0001']) - self.assertEqual(self.filter_with_rule(rule), - set(['48TJQCGNNIR5SJRCAK'])) + rule = HasIdOf(["F0001"]) + self.assertEqual(self.filter_with_rule(rule), set(["48TJQCGNNIR5SJRCAK"])) def test_haslds(self): """ Test HasLDS rule. """ - rule = HasLDS(['0', 'greater than']) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + rule = HasLDS(["0", "greater than"]) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_hasnote(self): """ Test HasNote rule. """ rule = HasNote([]) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_regexpidof(self): """ Test RegExpIdOf rule. """ - rule = RegExpIdOf(['F000.'], use_regex=True) - self.assertEqual(self.filter_with_rule(rule), set([ - 'LOTJQC78O5B4WQGJRP', 'UPTJQC4VPCABZUDB75', - 'NBTJQCIX49EKOCIHBP', 'C9UJQCF6ETBTV2MRRV', - '74UJQCKV8R4NBNHCB', '4BTJQCL4CHNA5OUTKF', - '48TJQCGNNIR5SJRCAK', '4YTJQCTEH7PQUU4AD', - 'MTTJQC05LKVFFLN01A', 'd5839c123c034ef82ab', - ])) + rule = RegExpIdOf(["F000."], use_regex=True) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "LOTJQC78O5B4WQGJRP", + "UPTJQC4VPCABZUDB75", + "NBTJQCIX49EKOCIHBP", + "C9UJQCF6ETBTV2MRRV", + "74UJQCKV8R4NBNHCB", + "4BTJQCL4CHNA5OUTKF", + "48TJQCGNNIR5SJRCAK", + "4YTJQCTEH7PQUU4AD", + "MTTJQC05LKVFFLN01A", + "d5839c123c034ef82ab", + ] + ), + ) def test_hasnoteregexp(self): """ Test HasNoteRegexp rule. """ - rule = HasNoteRegexp(['.'], use_regex=True) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + rule = HasNoteRegexp(["."], use_regex=True) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_hasreferencecountof(self): """ Test HasReferenceCountOf rule. """ - rule = HasReferenceCountOf(['greater than', '12']) - self.assertEqual(self.filter_with_rule(rule), set([ - '29IKQCMUNFTIBV653N', '8OUJQCUVZ0XML7BQLF', 'UPTJQC4VPCABZUDB75', - '9NWJQCJGLXUR3AQSFJ', '5G2KQCGBTS86UVSRG5', 'WG2KQCSY9LEFDFQHMN', - 'MTTJQC05LKVFFLN01A', 'C2VJQC71TNHO7RBBMX', 'QIDKQCJQ37SIUQ3UFU', - 'DV4KQCX9OBVQ74H77F'])) + rule = HasReferenceCountOf(["greater than", "12"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "29IKQCMUNFTIBV653N", + "8OUJQCUVZ0XML7BQLF", + "UPTJQC4VPCABZUDB75", + "9NWJQCJGLXUR3AQSFJ", + "5G2KQCGBTS86UVSRG5", + "WG2KQCSY9LEFDFQHMN", + "MTTJQC05LKVFFLN01A", + "C2VJQC71TNHO7RBBMX", + "QIDKQCJQ37SIUQ3UFU", + "DV4KQCX9OBVQ74H77F", + ] + ), + ) def test_hassourcecount(self): """ Test HasSourceCount rule. """ - rule = HasSourceCount(['1', 'greater than']) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + rule = HasSourceCount(["1", "greater than"]) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_hassourceof(self): """ Test HasSourceOf rule. """ - rule = HasSourceOf(['S0001']) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + rule = HasSourceOf(["S0001"]) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_hascitation(self): """ Test HasCitation rule. """ - rule = HasCitation(['page 10', '', '2']) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + rule = HasCitation(["page 10", "", "2"]) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_familyprivate(self): """ @@ -177,139 +216,192 @@ def test_hasevent(self): """ Test HasEvent rule. """ - date_str = localize_date('before 1900') - rule = HasEvent(['Marriage', date_str, 'USA', '', 'Garner']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'KSFKQCP4V0YXGM1LR9', '8ZFKQC3FRSHACOJBOU', '3XFKQCE7QUDJ99AVNV', - 'OVFKQC51DX0OQUV3JB', '9OUJQCBOHW9UEK9CNV'])) + date_str = localize_date("before 1900") + rule = HasEvent(["Marriage", date_str, "USA", "", "Garner"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "KSFKQCP4V0YXGM1LR9", + "8ZFKQC3FRSHACOJBOU", + "3XFKQCE7QUDJ99AVNV", + "OVFKQC51DX0OQUV3JB", + "9OUJQCBOHW9UEK9CNV", + ] + ), + ) def test_hasattribute(self): """ Test HasAttribute rule. """ - rule = HasAttribute(['Number of Children', '']) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + rule = HasAttribute(["Number of Children", ""]) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_isbookmarked(self): """ Test IsBookmarked rule. """ rule = IsBookmarked([]) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_matchessourceconfidence(self): """ Test MatchesSourceConfidence rule. """ - rule = MatchesSourceConfidence(['0']) + rule = MatchesSourceConfidence(["0"]) self.assertEqual(len(self.filter_with_rule(rule)), 734) def test_fatherhasnameof(self): """ Test FatherHasNameOf rule. """ - rule = FatherHasNameOf(['', '', 'Dr.', '', '', '', '', '', '', '', - '']) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + rule = FatherHasNameOf(["", "", "Dr.", "", "", "", "", "", "", "", ""]) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_fatherhasidof(self): """ Test FatherHasIdOf rule. """ - rule = FatherHasIdOf(['I0106']) - self.assertEqual(self.filter_with_rule(rule), - set(['8OUJQCUVZ0XML7BQLF'])) + rule = FatherHasIdOf(["I0106"]) + self.assertEqual(self.filter_with_rule(rule), set(["8OUJQCUVZ0XML7BQLF"])) def test_motherhasnameof(self): """ Test MotherHasNameOf rule. """ - rule = MotherHasNameOf(['', 'Alvarado', '', '', '', '', '', '', '', '', - '']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'EM3KQC48HFLA02TF8D', 'K9NKQCBG105ECXZ48D', - '2QMKQC5YWNAWZMG6VO', '6JUJQCCAXGENRX990K'])) + rule = MotherHasNameOf(["", "Alvarado", "", "", "", "", "", "", "", "", ""]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "EM3KQC48HFLA02TF8D", + "K9NKQCBG105ECXZ48D", + "2QMKQC5YWNAWZMG6VO", + "6JUJQCCAXGENRX990K", + ] + ), + ) def test_motherhasidof(self): """ Test MotherHasIdOf rule. """ - rule = MotherHasIdOf(['I0107']) - self.assertEqual(self.filter_with_rule(rule), - set(['8OUJQCUVZ0XML7BQLF'])) + rule = MotherHasIdOf(["I0107"]) + self.assertEqual(self.filter_with_rule(rule), set(["8OUJQCUVZ0XML7BQLF"])) def test_childhasnameof(self): """ Test ChildHasNameOf rule. """ - rule = ChildHasNameOf(['Eugene', '', '', '', '', '', '', '', '', '', - '']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'D1YJQCGLEIBPPLNL4B', '5GTJQCXVYVAIQTBVKA', 'I42KQCM3S926FMJ91O', - '7CTJQCFJVBQSY076A6', '9OUJQCBOHW9UEK9CNV', '9IXJQCX18AHUFPQHEZ', - '9NWJQCJGLXUR3AQSFJ'])) + rule = ChildHasNameOf(["Eugene", "", "", "", "", "", "", "", "", "", ""]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "D1YJQCGLEIBPPLNL4B", + "5GTJQCXVYVAIQTBVKA", + "I42KQCM3S926FMJ91O", + "7CTJQCFJVBQSY076A6", + "9OUJQCBOHW9UEK9CNV", + "9IXJQCX18AHUFPQHEZ", + "9NWJQCJGLXUR3AQSFJ", + ] + ), + ) def test_childhasidof(self): """ Test ChildHasIdOf rule. """ - rule = ChildHasIdOf(['I0001']) - self.assertEqual(self.filter_with_rule(rule), - set(['48TJQCGNNIR5SJRCAK'])) + rule = ChildHasIdOf(["I0001"]) + self.assertEqual(self.filter_with_rule(rule), set(["48TJQCGNNIR5SJRCAK"])) def test_changedsince(self): """ Test ChangedSince rule. """ - rule = ChangedSince(['2008-01-01', '2014-01-01']) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + rule = ChangedSince(["2008-01-01", "2014-01-01"]) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_hastag(self): """ Test HasTag rule. """ - rule = HasTag(['ToDo']) - self.assertEqual(self.filter_with_rule(rule), - set(['9OUJQCBOHW9UEK9CNV'])) + rule = HasTag(["ToDo"]) + self.assertEqual(self.filter_with_rule(rule), set(["9OUJQCBOHW9UEK9CNV"])) def test_hastwins(self): """ Test HasTwins rule. """ rule = HasTwins([]) - self.assertEqual(self.filter_with_rule(rule), set([ - 'SD6KQC7LB8MYGA7F5W', '8OUJQCUVZ0XML7BQLF', '1BVJQCNTFAGS8273LJ', - '5IUJQCRJY47YQ8PU7N', 'ZLUJQCPDV93OR8KHB7', '4U2KQCBXG2VTPH6U1F', - ])) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "SD6KQC7LB8MYGA7F5W", + "8OUJQCUVZ0XML7BQLF", + "1BVJQCNTFAGS8273LJ", + "5IUJQCRJY47YQ8PU7N", + "ZLUJQCPDV93OR8KHB7", + "4U2KQCBXG2VTPH6U1F", + ] + ), + ) def test_isancestorof(self): """ Test IsAncestorOf rule. """ - rule = IsAncestorOf(['F0031', '0']) - self.assertEqual(self.filter_with_rule(rule), set([ - '4AXJQC96KTN3WGPTVE', '1RUJQCYX9QL1V45YLD', '5GTJQCXVYVAIQTBVKA', - 'X3WJQCSF48F6809142', 'NSVJQC89IHEEBIPDP2', '9OUJQCBOHW9UEK9CNV', - '1RUJQCCL9MVRYLMTBO', 'RRVJQC5A8DDHQFPRDL', '0SUJQCOS78AXGWP8QR', - '57WJQCTBJKR5QYPS6K', '8OUJQCUVZ0XML7BQLF', '7PUJQC4PPS4EDIVMYE' - ])) + rule = IsAncestorOf(["F0031", "0"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "4AXJQC96KTN3WGPTVE", + "1RUJQCYX9QL1V45YLD", + "5GTJQCXVYVAIQTBVKA", + "X3WJQCSF48F6809142", + "NSVJQC89IHEEBIPDP2", + "9OUJQCBOHW9UEK9CNV", + "1RUJQCCL9MVRYLMTBO", + "RRVJQC5A8DDHQFPRDL", + "0SUJQCOS78AXGWP8QR", + "57WJQCTBJKR5QYPS6K", + "8OUJQCUVZ0XML7BQLF", + "7PUJQC4PPS4EDIVMYE", + ] + ), + ) def test_isdescendantof(self): """ Test IsDescendantOf rule. """ - rule = IsDescendantOf(['F0031', '0']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'SFXJQCLE8PIG7PH38J', 'UCXJQCC5HS8VXDKWBM', 'IIEKQCRX89WYBHKB7R', - 'XDXJQCMWU5EIV8XCRF', '7BXJQCU22OCA4HN38A', '3FXJQCR749H2H7G321', - 'IEXJQCFUN95VENI6BO', '4FXJQC7656WDQ3HJGW', 'FLEKQCRVG3O1UA9YUB', - 'BCXJQC9AQ0DBXCVLEQ', '9SEKQCAAWRUCIO7A0M', 'DDXJQCVT5X72TOXP0C', - 'CGXJQC515QL9RLPQTU', 'XGXJQCNVZH2PWRMVAH', 'RBXJQCUYMQR2KRMDFY' - ])) + rule = IsDescendantOf(["F0031", "0"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "SFXJQCLE8PIG7PH38J", + "UCXJQCC5HS8VXDKWBM", + "IIEKQCRX89WYBHKB7R", + "XDXJQCMWU5EIV8XCRF", + "7BXJQCU22OCA4HN38A", + "3FXJQCR749H2H7G321", + "IEXJQCFUN95VENI6BO", + "4FXJQC7656WDQ3HJGW", + "FLEKQCRVG3O1UA9YUB", + "BCXJQC9AQ0DBXCVLEQ", + "9SEKQCAAWRUCIO7A0M", + "DDXJQCVT5X72TOXP0C", + "CGXJQC515QL9RLPQTU", + "XGXJQCNVZH2PWRMVAH", + "RBXJQCUYMQR2KRMDFY", + ] + ), + ) if __name__ == "__main__": diff --git a/gramps/gen/filters/rules/test/media_rules_test.py b/gramps/gen/filters/rules/test/media_rules_test.py index 5d2ddd338a5..10f6111df6a 100644 --- a/gramps/gen/filters/rules/test/media_rules_test.py +++ b/gramps/gen/filters/rules/test/media_rules_test.py @@ -30,14 +30,27 @@ from ....user import User from ..media import ( - AllMedia, HasIdOf, RegExpIdOf, HasCitation, HasNoteRegexp, - HasNoteMatchingSubstringOf, HasReferenceCountOf, HasSourceCount, - HasSourceOf, MediaPrivate, MatchesSourceConfidence, HasMedia, - HasAttribute, ChangedSince, HasTag) + AllMedia, + HasIdOf, + RegExpIdOf, + HasCitation, + HasNoteRegexp, + HasNoteMatchingSubstringOf, + HasReferenceCountOf, + HasSourceCount, + HasSourceOf, + MediaPrivate, + MatchesSourceConfidence, + HasMedia, + HasAttribute, + ChangedSince, + HasTag, +) TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests")) EXAMPLE = os.path.join(TEST_DIR, "example.gramps") -GenericMediaFilter = GenericFilterFactory('Media') +GenericMediaFilter = GenericFilterFactory("Media") + class BaseTest(unittest.TestCase): """ @@ -65,73 +78,79 @@ def test_allmedia(self): Test AllMedia rule. """ rule = AllMedia([]) - self.assertEqual(len(self.filter_with_rule(rule)), - self.db.get_number_of_media()) + self.assertEqual( + len(self.filter_with_rule(rule)), self.db.get_number_of_media() + ) def test_hasidof(self): """ Test HasIdOf rule. """ - rule = HasIdOf(['O0000']) - self.assertEqual(self.filter_with_rule(rule), - set(['b39fe1cfc1305ac4a21'])) + rule = HasIdOf(["O0000"]) + self.assertEqual(self.filter_with_rule(rule), set(["b39fe1cfc1305ac4a21"])) def test_regexpidof(self): """ Test RegExpIdOf rule. """ - rule = RegExpIdOf(['O000.'], use_regex=True) - self.assertEqual(self.filter_with_rule(rule), set([ - 'F0QIGQFT275JFJ75E8', '78V2GQX2FKNSYQ3OHE', - 'b39fe1cfc1305ac4a21', 'F8JYGQFL2PKLSYH79X', - 'B1AUFQV7H8R9NR4SZM'])) + rule = RegExpIdOf(["O000."], use_regex=True) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "F0QIGQFT275JFJ75E8", + "78V2GQX2FKNSYQ3OHE", + "b39fe1cfc1305ac4a21", + "F8JYGQFL2PKLSYH79X", + "B1AUFQV7H8R9NR4SZM", + ] + ), + ) def test_hascitation(self): """ Test HasCitation rule. """ - rule = HasCitation(['page 21', '', '']) - self.assertEqual(self.filter_with_rule(rule), - set(['B1AUFQV7H8R9NR4SZM'])) + rule = HasCitation(["page 21", "", ""]) + self.assertEqual(self.filter_with_rule(rule), set(["B1AUFQV7H8R9NR4SZM"])) def test_hasnoteregexp(self): """ Test HasNoteRegexp rule. """ - rule = HasNoteRegexp(['.'], use_regex=True) + rule = HasNoteRegexp(["."], use_regex=True) self.assertEqual(self.filter_with_rule(rule), set([])) def test_hasnotematchingsubstringof(self): """ Test HasNoteMatchingSubstringOf rule. """ - rule = HasNoteMatchingSubstringOf(['some text']) + rule = HasNoteMatchingSubstringOf(["some text"]) self.assertEqual(self.filter_with_rule(rule), set([])) def test_hasreferencecountof(self): """ Test HasReferenceCountOf rule. """ - rule = HasReferenceCountOf(['greater than', '1']) - self.assertEqual(self.filter_with_rule(rule), set([ - '238CGQ939HG18SS5MG', 'b39fe1cfc1305ac4a21', - 'Y3ARGQWE088EQRTTDH'])) + rule = HasReferenceCountOf(["greater than", "1"]) + self.assertEqual( + self.filter_with_rule(rule), + set(["238CGQ939HG18SS5MG", "b39fe1cfc1305ac4a21", "Y3ARGQWE088EQRTTDH"]), + ) def test_hassourcecount(self): """ Test HasSourceCount rule. """ - rule = HasSourceCount(['1', 'equal to']) - self.assertEqual(self.filter_with_rule(rule), - set(['B1AUFQV7H8R9NR4SZM'])) + rule = HasSourceCount(["1", "equal to"]) + self.assertEqual(self.filter_with_rule(rule), set(["B1AUFQV7H8R9NR4SZM"])) def test_hassourceof(self): """ Test HasSourceOf rule. """ - rule = HasSourceOf(['S0001']) - self.assertEqual(self.filter_with_rule(rule), - set(['B1AUFQV7H8R9NR4SZM'])) + rule = HasSourceOf(["S0001"]) + self.assertEqual(self.filter_with_rule(rule), set(["B1AUFQV7H8R9NR4SZM"])) def test_mediaprivate(self): """ @@ -144,42 +163,46 @@ def test_matchessourceconfidence(self): """ Test MatchesSourceConfidence rule. """ - rule = MatchesSourceConfidence(['2']) - self.assertEqual(self.filter_with_rule(rule), - set(['B1AUFQV7H8R9NR4SZM'])) + rule = MatchesSourceConfidence(["2"]) + self.assertEqual(self.filter_with_rule(rule), set(["B1AUFQV7H8R9NR4SZM"])) def test_hasmedia(self): """ Test HasMedia rule. """ - rule = HasMedia(['mannschaft', 'image/jpeg', '.jpg', '1897']) - self.assertEqual(self.filter_with_rule(rule), - set(['238CGQ939HG18SS5MG'])) + rule = HasMedia(["mannschaft", "image/jpeg", ".jpg", "1897"]) + self.assertEqual(self.filter_with_rule(rule), set(["238CGQ939HG18SS5MG"])) def test_hasattribute(self): """ Test HasAttribute rule. """ - rule = HasAttribute(['Description', '']) - self.assertEqual(self.filter_with_rule(rule), - set(['B1AUFQV7H8R9NR4SZM'])) + rule = HasAttribute(["Description", ""]) + self.assertEqual(self.filter_with_rule(rule), set(["B1AUFQV7H8R9NR4SZM"])) def test_changedsince(self): """ Test ChangedSince rule. """ - rule = ChangedSince(['2010-01-01', '2016-01-01']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'b39fe1cfc1305ac4a21', 'B1AUFQV7H8R9NR4SZM', - '238CGQ939HG18SS5MG', 'F0QIGQFT275JFJ75E8'])) + rule = ChangedSince(["2010-01-01", "2016-01-01"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "b39fe1cfc1305ac4a21", + "B1AUFQV7H8R9NR4SZM", + "238CGQ939HG18SS5MG", + "F0QIGQFT275JFJ75E8", + ] + ), + ) def test_hastag(self): """ Test HasTag rule. """ - rule = HasTag(['ToDo']) - self.assertEqual(self.filter_with_rule(rule), - set(['238CGQ939HG18SS5MG'])) + rule = HasTag(["ToDo"]) + self.assertEqual(self.filter_with_rule(rule), set(["238CGQ939HG18SS5MG"])) if __name__ == "__main__": diff --git a/gramps/gen/filters/rules/test/note_rules_test.py b/gramps/gen/filters/rules/test/note_rules_test.py index c8a4292014a..ab29ccce9be 100644 --- a/gramps/gen/filters/rules/test/note_rules_test.py +++ b/gramps/gen/filters/rules/test/note_rules_test.py @@ -30,12 +30,22 @@ from ....user import User from ..note import ( - AllNotes, HasIdOf, RegExpIdOf, HasNote, MatchesRegexpOf, - HasReferenceCountOf, NotePrivate, ChangedSince, HasTag, HasType) + AllNotes, + HasIdOf, + RegExpIdOf, + HasNote, + MatchesRegexpOf, + HasReferenceCountOf, + NotePrivate, + ChangedSince, + HasTag, + HasType, +) TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests")) EXAMPLE = os.path.join(TEST_DIR, "example.gramps") -GenericNoteFilter = GenericFilterFactory('Note') +GenericNoteFilter = GenericFilterFactory("Note") + class BaseTest(unittest.TestCase): """ @@ -63,53 +73,66 @@ def test_allnotes(self): Test AllNotes rule. """ rule = AllNotes([]) - self.assertEqual(len(self.filter_with_rule(rule)), - self.db.get_number_of_notes()) + self.assertEqual( + len(self.filter_with_rule(rule)), self.db.get_number_of_notes() + ) def test_hasidof(self): """ Test HasIdOf rule. """ - rule = HasIdOf(['N0001']) - self.assertEqual(self.filter_with_rule(rule), - set(['ac380498bac48eedee8'])) + rule = HasIdOf(["N0001"]) + self.assertEqual(self.filter_with_rule(rule), set(["ac380498bac48eedee8"])) def test_regexpidof(self): """ Test RegExpIdOf rule. """ - rule = RegExpIdOf(['N000.'], use_regex=True) - self.assertEqual(self.filter_with_rule(rule), set([ - 'ac380498c020c7bcdc7', 'ac3804a842b21358c97', - 'ae13613d581506d040892f88a21', 'ac3804a8405171ef666', - 'ac3804a1d747a39822c', 'ac3804aac6b762b75a5', - 'ac380498bac48eedee8', 'ac3804a1d66258b8e13', - 'ac380498bc46102e1e8', 'b39fe2e143d1e599450'])) + rule = RegExpIdOf(["N000."], use_regex=True) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "ac380498c020c7bcdc7", + "ac3804a842b21358c97", + "ae13613d581506d040892f88a21", + "ac3804a8405171ef666", + "ac3804a1d747a39822c", + "ac3804aac6b762b75a5", + "ac380498bac48eedee8", + "ac3804a1d66258b8e13", + "ac380498bc46102e1e8", + "b39fe2e143d1e599450", + ] + ), + ) def test_hasnote(self): """ Test HasNote rule. """ - rule = HasNote(['note', 'Person Note']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'b39ff11d8912173cded', 'b39ff01f75c1f76859a'])) + rule = HasNote(["note", "Person Note"]) + self.assertEqual( + self.filter_with_rule(rule), + set(["b39ff11d8912173cded", "b39ff01f75c1f76859a"]), + ) def test_matchesregexpof(self): """ Test MatchesRegexpOf rule. """ - rule = MatchesRegexpOf(['^This'], use_regex=True) - self.assertEqual(self.filter_with_rule(rule), set([ - 'b39ff11d8912173cded', 'c140d4c29520c92055c', - 'b39ff01f75c1f76859a'])) + rule = MatchesRegexpOf(["^This"], use_regex=True) + self.assertEqual( + self.filter_with_rule(rule), + set(["b39ff11d8912173cded", "c140d4c29520c92055c", "b39ff01f75c1f76859a"]), + ) def test_hasreferencecountof(self): """ Test HasReferenceCountOf rule. """ - rule = HasReferenceCountOf(['greater than', '1']) - self.assertEqual(self.filter_with_rule(rule), - set(['c140d4c29520c92055c'])) + rule = HasReferenceCountOf(["greater than", "1"]) + self.assertEqual(self.filter_with_rule(rule), set(["c140d4c29520c92055c"])) def test_noteprivate(self): """ @@ -122,28 +145,39 @@ def test_changedsince(self): """ Test ChangedSince rule. """ - rule = ChangedSince(['2010-01-01', '2016-01-01']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'c140d4c29520c92055c', 'd0436bcc69d6bba278bff5bc7db', - 'b39fe2e143d1e599450', 'd0436bba4ec328d3b631259a4ee', - 'd0436be64ac277b615b79b34e72'])) + rule = ChangedSince(["2010-01-01", "2016-01-01"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "c140d4c29520c92055c", + "d0436bcc69d6bba278bff5bc7db", + "b39fe2e143d1e599450", + "d0436bba4ec328d3b631259a4ee", + "d0436be64ac277b615b79b34e72", + ] + ), + ) def test_hastag(self): """ Test HasTag rule. """ - rule = HasTag(['ToDo']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'b39ff01f75c1f76859a', 'b39fe2e143d1e599450'])) + rule = HasTag(["ToDo"]) + self.assertEqual( + self.filter_with_rule(rule), + set(["b39ff01f75c1f76859a", "b39fe2e143d1e599450"]), + ) def test_hastype(self): """ Test HasType rule. """ - rule = HasType(['Person Note']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'ac380498c020c7bcdc7', 'b39ff11d8912173cded', - 'b39ff01f75c1f76859a'])) + rule = HasType(["Person Note"]) + self.assertEqual( + self.filter_with_rule(rule), + set(["ac380498c020c7bcdc7", "b39ff11d8912173cded", "b39ff01f75c1f76859a"]), + ) if __name__ == "__main__": diff --git a/gramps/gen/filters/rules/test/person_rules_test.py b/gramps/gen/filters/rules/test/person_rules_test.py index 84f7725791d..a62beb8940d 100644 --- a/gramps/gen/filters/rules/test/person_rules_test.py +++ b/gramps/gen/filters/rules/test/person_rules_test.py @@ -27,6 +27,7 @@ import inspect from ....filters import reload_custom_filters + reload_custom_filters() from ....db.utils import import_as_dict from ....filters import GenericFilter, CustomFilters @@ -35,31 +36,72 @@ from ....utils.unittest import localize_date from ..person import ( - Disconnected, Everyone, FamilyWithIncompleteEvent, HasAddress, - HasAlternateName, HasAssociation, HasBirth, HasDeath, HasEvent, - HasCommonAncestorWith, HasCommonAncestorWithFilterMatch, - HasFamilyAttribute, HasFamilyEvent, HasIdOf, HasLDS, - HasNameOf, HasNameOriginType, HasNameType, HasNickname, HasRelationship, - HasSoundexName, HasSourceOf, HasTextMatchingRegexpOf, HasUnknownGender, - HaveAltFamilies, HaveChildren, HavePhotos, IncompleteNames, - IsAncestorOfFilterMatch, IsBookmarked, IsChildOfFilterMatch, - IsDescendantFamilyOf, IsDescendantFamilyOfFilterMatch, - IsDescendantOfFilterMatch, IsDefaultPerson, IsDescendantOf, - IsDuplicatedAncestorOf, IsFemale, + Disconnected, + Everyone, + FamilyWithIncompleteEvent, + HasAddress, + HasAlternateName, + HasAssociation, + HasBirth, + HasDeath, + HasEvent, + HasCommonAncestorWith, + HasCommonAncestorWithFilterMatch, + HasFamilyAttribute, + HasFamilyEvent, + HasIdOf, + HasLDS, + HasNameOf, + HasNameOriginType, + HasNameType, + HasNickname, + HasRelationship, + HasSoundexName, + HasSourceOf, + HasTextMatchingRegexpOf, + HasUnknownGender, + HaveAltFamilies, + HaveChildren, + HavePhotos, + IncompleteNames, + IsAncestorOfFilterMatch, + IsBookmarked, + IsChildOfFilterMatch, + IsDescendantFamilyOf, + IsDescendantFamilyOfFilterMatch, + IsDescendantOfFilterMatch, + IsDefaultPerson, + IsDescendantOf, + IsDuplicatedAncestorOf, + IsFemale, IsLessThanNthGenerationAncestorOf, IsLessThanNthGenerationAncestorOfDefaultPerson, - IsLessThanNthGenerationAncestorOfBookmarked, IsMale, - IsMoreThanNthGenerationAncestorOf, IsMoreThanNthGenerationDescendantOf, - IsParentOfFilterMatch, IsRelatedWith, IsSiblingOfFilterMatch, - IsSpouseOfFilterMatch, IsWitness, MissingParent, MultipleMarriages, - NeverMarried, NoBirthdate, NoDeathdate, PeoplePrivate, PeoplePublic, - PersonWithIncompleteEvent, ProbablyAlive, RegExpName, + IsLessThanNthGenerationAncestorOfBookmarked, + IsMale, + IsMoreThanNthGenerationAncestorOf, + IsMoreThanNthGenerationDescendantOf, + IsParentOfFilterMatch, + IsRelatedWith, + IsSiblingOfFilterMatch, + IsSpouseOfFilterMatch, + IsWitness, + MissingParent, + MultipleMarriages, + NeverMarried, + NoBirthdate, + NoDeathdate, + PeoplePrivate, + PeoplePublic, + PersonWithIncompleteEvent, + ProbablyAlive, + RegExpName, RelationshipPathBetweenBookmarks, ) TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests")) EXAMPLE = os.path.join(TEST_DIR, "example.gramps") + class BaseTest(unittest.TestCase): """ Person rule tests. @@ -72,9 +114,16 @@ def setUpClass(cls): """ cls.db = import_as_dict(EXAMPLE, User()) - def filter_with_rule(self, rule, l_op='and', invert=False, - baserule=None, base_l_op='and', base_invert=False, - base_name='Base'): + def filter_with_rule( + self, + rule, + l_op="and", + invert=False, + baserule=None, + base_l_op="and", + base_invert=False, + base_name="Base", + ): """ Apply a filter with the given rule. 'baserule' can be used to stack filters when using filters that are of 'offiltermatch' type. @@ -88,7 +137,7 @@ def filter_with_rule(self, rule, l_op='and', invert=False, filter_.set_logical_op(base_l_op) filter_.set_invert(base_invert) filter_.set_name(base_name) - filters = CustomFilters.get_filters_dict('Person') + filters = CustomFilters.get_filters_dict("Person") filters[base_name] = filter_ filter_ = GenericFilter() if isinstance(rule, list): @@ -100,130 +149,123 @@ def filter_with_rule(self, rule, l_op='and', invert=False, stime = perf_counter() results = filter_.apply(self.db) # if __debug__: - # frame = inspect.currentframe() - # rulename = frame.f_back.f_code.co_name - # print("%s: %.2f\n" % (rulename, perf_counter() - stime)) + # frame = inspect.currentframe() + # rulename = frame.f_back.f_code.co_name + # print("%s: %.2f\n" % (rulename, perf_counter() - stime)) return set(results) def test_Complex_1(self): - """ Test with two ancestor trees in base filter, and a complex - 'or' of a descendent tree, sibling of, """ - rule1 = IsLessThanNthGenerationAncestorOf(['I0005', 10]) - rule2 = IsLessThanNthGenerationAncestorOf(['I0006', 10]) - ruleA = IsDescendantOfFilterMatch(['Base']) - ruleB = IsSiblingOfFilterMatch(['Base']) - ruleC = IsSpouseOfFilterMatch(['Base']) - res = self.filter_with_rule([ruleA, ruleB, ruleC], l_op='or', - baserule=[rule1, rule2], base_l_op='or') + """Test with two ancestor trees in base filter, and a complex + 'or' of a descendent tree, sibling of,""" + rule1 = IsLessThanNthGenerationAncestorOf(["I0005", 10]) + rule2 = IsLessThanNthGenerationAncestorOf(["I0006", 10]) + ruleA = IsDescendantOfFilterMatch(["Base"]) + ruleB = IsSiblingOfFilterMatch(["Base"]) + ruleC = IsSpouseOfFilterMatch(["Base"]) + res = self.filter_with_rule( + [ruleA, ruleB, ruleC], l_op="or", baserule=[rule1, rule2], base_l_op="or" + ) self.assertEqual(len(res), 1277) def test_IsDescendantOfFilterMatch(self): - """ Test the rule with two persons in base filter """ - rule1 = HasIdOf(['I0610']) - rule2 = HasIdOf(['I1804']) - rule = IsDescendantOfFilterMatch(['Base']) - res = self.filter_with_rule(rule, baserule=[rule1, rule2], - base_l_op='or') + """Test the rule with two persons in base filter""" + rule1 = HasIdOf(["I0610"]) + rule2 = HasIdOf(["I1804"]) + rule = IsDescendantOfFilterMatch(["Base"]) + res = self.filter_with_rule(rule, baserule=[rule1, rule2], base_l_op="or") self.assertEqual(len(res), 120) def test_IsDescendantFamilyOfFilterMatch(self): - """ Test the rule with two persons in base filter """ - rule1 = HasIdOf(['I0610']) - rule2 = HasIdOf(['I1804']) - rule = IsDescendantFamilyOfFilterMatch(['Base']) - res = self.filter_with_rule(rule, baserule=[rule1, rule2], - base_l_op='or') + """Test the rule with two persons in base filter""" + rule1 = HasIdOf(["I0610"]) + rule2 = HasIdOf(["I1804"]) + rule = IsDescendantFamilyOfFilterMatch(["Base"]) + res = self.filter_with_rule(rule, baserule=[rule1, rule2], base_l_op="or") self.assertEqual(len(res), 171) def test_IsDescendantFamilyOf(self): - """ Test the rule """ - rule = IsDescendantFamilyOf(['I0610', 1]) + """Test the rule""" + rule = IsDescendantFamilyOf(["I0610", 1]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 118) def test_IsDescendantOf(self): - """ Test the rule """ - rule = IsDescendantOf(['I0610', 0]) + """Test the rule""" + rule = IsDescendantOf(["I0610", 0]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 85) def test_IsMoreThanNthGenerationDescendantOf(self): - """ Test the rule """ - rule = IsMoreThanNthGenerationDescendantOf(['I0610', 3]) + """Test the rule""" + rule = IsMoreThanNthGenerationDescendantOf(["I0610", 3]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 83) def test_IsLessThanNthGenerationAncestorOfDefaultPerson(self): - """ Test the rule """ + """Test the rule""" rule = IsLessThanNthGenerationAncestorOfDefaultPerson([5]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 7) def test_IsLessThanNthGenerationAncestorOfBookmarked(self): - """ Test the rule """ + """Test the rule""" rule = IsLessThanNthGenerationAncestorOfBookmarked([5]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 8) def test_IsParentOfFilterMatch(self): - """ Test the rule with two persons in base filter """ - rule1 = HasIdOf(['I0006']) - rule2 = HasIdOf(['I0010']) - rule = IsParentOfFilterMatch(['Base']) - res = self.filter_with_rule(rule, baserule=[rule1, rule2], - base_l_op='or') + """Test the rule with two persons in base filter""" + rule1 = HasIdOf(["I0006"]) + rule2 = HasIdOf(["I0010"]) + rule = IsParentOfFilterMatch(["Base"]) + res = self.filter_with_rule(rule, baserule=[rule1, rule2], base_l_op="or") self.assertEqual(len(res), 4) def test_IsSiblingOfFilterMatch(self): - """ Test the rule with two persons in base filter """ - rule1 = HasIdOf(['I0006']) - rule2 = HasIdOf(['I0010']) - rule = IsSiblingOfFilterMatch(['Base']) - res = self.filter_with_rule(rule, baserule=[rule1, rule2], - base_l_op='or') + """Test the rule with two persons in base filter""" + rule1 = HasIdOf(["I0006"]) + rule2 = HasIdOf(["I0010"]) + rule = IsSiblingOfFilterMatch(["Base"]) + res = self.filter_with_rule(rule, baserule=[rule1, rule2], base_l_op="or") self.assertEqual(len(res), 7) def test_IsSpouseOfFilterMatch(self): - """ Test the rule with two persons in base filter """ - rule1 = HasIdOf(['I0006']) - rule2 = HasIdOf(['I0010']) - rule = IsSpouseOfFilterMatch(['Base']) - res = self.filter_with_rule(rule, baserule=[rule1, rule2], - base_l_op='or') + """Test the rule with two persons in base filter""" + rule1 = HasIdOf(["I0006"]) + rule2 = HasIdOf(["I0010"]) + rule = IsSpouseOfFilterMatch(["Base"]) + res = self.filter_with_rule(rule, baserule=[rule1, rule2], base_l_op="or") self.assertEqual(len(res), 2) def test_isancestoroffiltermatch(self): - """ Test the rule with two persons in base filter """ - rule1 = HasIdOf(['I0006']) - rule2 = HasIdOf(['I0005']) - rule = IsAncestorOfFilterMatch(['Base']) - res = self.filter_with_rule(rule, baserule=[rule1, rule2], - base_l_op='or') + """Test the rule with two persons in base filter""" + rule1 = HasIdOf(["I0006"]) + rule2 = HasIdOf(["I0005"]) + rule = IsAncestorOfFilterMatch(["Base"]) + res = self.filter_with_rule(rule, baserule=[rule1, rule2], base_l_op="or") self.assertEqual(len(res), 431) def test_HasCommonAncestorWithFilterMatch(self): - """ Test the rule with two persons in base filter """ - rule1 = HasIdOf(['I0006']) - rule2 = HasIdOf(['I0005']) - rule = HasCommonAncestorWithFilterMatch(['Base']) - res = self.filter_with_rule(rule, baserule=[rule1, rule2], - base_l_op='or') + """Test the rule with two persons in base filter""" + rule1 = HasIdOf(["I0006"]) + rule2 = HasIdOf(["I0005"]) + rule = HasCommonAncestorWithFilterMatch(["Base"]) + res = self.filter_with_rule(rule, baserule=[rule1, rule2], base_l_op="or") self.assertEqual(len(res), 1415) def test_IsChildOfFilterMatch(self): - """ Test the rule with two persons in base filter """ - rule1 = HasIdOf(['I0006']) - rule2 = HasIdOf(['I0010']) - rule = IsChildOfFilterMatch(['Base']) - res = self.filter_with_rule(rule, baserule=[rule1, rule2], - base_l_op='or') + """Test the rule with two persons in base filter""" + rule1 = HasIdOf(["I0006"]) + rule2 = HasIdOf(["I0010"]) + rule = IsChildOfFilterMatch(["Base"]) + res = self.filter_with_rule(rule, baserule=[rule1, rule2], base_l_op="or") self.assertEqual(len(res), 11) def test_HasAddress(self): """ Test HasAddress rule. """ - rule = HasAddress([0, 'greater than']) + rule = HasAddress([0, "greater than"]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 1) @@ -231,7 +273,7 @@ def test_HasAssociation(self): """ Test rule. """ - rule = HasAssociation([0, 'greater than']) + rule = HasAssociation([0, "greater than"]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 2) @@ -239,8 +281,8 @@ def test_HasBirth(self): """ Test rule. """ - date_str = localize_date('between 1600 and 1700') - rule = HasBirth([date_str, 'akron', '']) + date_str = localize_date("between 1600 and 1700") + rule = HasBirth([date_str, "akron", ""]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 2) @@ -248,8 +290,8 @@ def test_HasDeath(self): """ Test HasDeath rule. """ - date_str = localize_date('between 1600 and 1700') - rule = HasDeath([date_str, 'ashtabula', '']) + date_str = localize_date("between 1600 and 1700") + rule = HasDeath([date_str, "ashtabula", ""]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 2) @@ -257,8 +299,8 @@ def test_HasEvent(self): """ Test rule. """ - date_str = localize_date('between 1600 and 1700') - rule = HasEvent(['Birth', date_str, 'akron', '', '', 1]) + date_str = localize_date("between 1600 and 1700") + rule = HasEvent(["Birth", date_str, "akron", "", "", 1]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 2) @@ -266,7 +308,7 @@ def test_HasFamilyAttribute(self): """ Test rule. """ - rule = HasFamilyAttribute([5, '8']) + rule = HasFamilyAttribute([5, "8"]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 2) @@ -274,8 +316,8 @@ def test_HasFamilyEvent(self): """ Test rule. """ - date_str = localize_date('after 1900') - rule = HasFamilyEvent(['Marriage', date_str, 'craw', '']) + date_str = localize_date("after 1900") + rule = HasFamilyEvent(["Marriage", date_str, "craw", ""]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 4) @@ -283,7 +325,7 @@ def test_HavePhotos(self): """ Test rule. """ - rule = HavePhotos([0, 'greater than']) + rule = HavePhotos([0, "greater than"]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 5) @@ -291,7 +333,7 @@ def test_HasLDS(self): """ Test rule. """ - rule = HasLDS([0, 'greater than']) + rule = HasLDS([0, "greater than"]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 1) @@ -299,7 +341,7 @@ def test_HasNameOriginType(self): """ Test rule. """ - rule = HasNameOriginType(['Patrilineal']) + rule = HasNameOriginType(["Patrilineal"]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 9) @@ -307,7 +349,7 @@ def test_HasNameType(self): """ Test rule. """ - rule = HasNameType(['Married Name']) + rule = HasNameType(["Married Name"]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 1) @@ -315,7 +357,7 @@ def test_HasRelationship(self): """ Test rule. """ - rule = HasRelationship([0, 'Married', 0]) + rule = HasRelationship([0, "Married", 0]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 1377) @@ -323,9 +365,9 @@ def test_HasTextMatchingRegexpOf(self): """ Test rule. """ - rule = HasTextMatchingRegexpOf(['.*(Dahl|Akron|Smith|Attic|' - 'of Lessard).*', False], - use_regex=True) + rule = HasTextMatchingRegexpOf( + [".*(Dahl|Akron|Smith|Attic|" "of Lessard).*", False], use_regex=True + ) res = self.filter_with_rule(rule) self.assertEqual(len(res), 28) @@ -333,7 +375,7 @@ def test_IsMoreThanNthGenerationAncestorOf(self): """ Test rule. """ - rule = IsMoreThanNthGenerationAncestorOf(['I0005', 3]) + rule = IsMoreThanNthGenerationAncestorOf(["I0005", 3]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 322) @@ -341,7 +383,7 @@ def test_IsWitness(self): """ Test rule. """ - rule = IsWitness(['Marriage']) + rule = IsWitness(["Marriage"]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 1) @@ -349,7 +391,7 @@ def test_ProbablyAlive(self): """ Test rule. """ - rule = ProbablyAlive(['1900']) + rule = ProbablyAlive(["1900"]) res = self.filter_with_rule(rule) self.assertEqual(len(res), 733) @@ -357,51 +399,104 @@ def test_RegExpName(self): """ Test rule. """ - rule = RegExpName(['.*(Garc|Amy).*'], use_regex=True) + rule = RegExpName([".*(Garc|Amy).*"], use_regex=True) res = self.filter_with_rule(rule) self.assertEqual(len(res), 3) - def test_disconnected(self): """ Test Disconnected rule. """ rule = Disconnected([]) - self.assertEqual(self.filter_with_rule(rule), set([ - '0PBKQCXHLAEIB46ZIA', 'QEVJQC04YO01UAWJ2N', 'UT0KQCMN7PC9XURRXJ', - 'MZAKQCKAQLIQYWP5IW', 'Y7BKQC9CUXWQLGLPQM', 'OBBKQC8NJM5UYBO849', - 'NPBKQCKEF0G7T4H312', '423KQCGLT8UISDUM1Q', '8S0KQCNORIWDL0X8SB', - 'AP5KQC0LBXPM727OWB', 'AREKQC0VPBHNZ5R3IO', 'KU0KQCJ0RUTJTIUKSA', - 'VC4KQC7L7KKH9RLHXN', '0P3KQCRSIVL1A4VJ19', 'PK6KQCGEL4PTE720BL', - 'YIKKQCSD2Z85UHJ8LX', 'KY8KQCMIH2HUUGLA3R', 'RD7KQCQ24B1N3OEC5X', - 'NV0KQC7SIEH3SVDPP1', 'KIKKQCU2CJ543TLM5J', 'AT0KQC4P3MMUCHI3BK', - 'J6BKQC1PMNBAYSLM9U', 'IXXJQCLKOUAJ5RSQY4', 'U4ZJQC5VR0QBIE8DU', - 'F7BKQC4NXO9R7XOG2W', '7U0KQC6PGZBNQATNOT', '78AKQCI05U36T3E82O', - 'H1GKQCWOUJHFSHXABA', 'ZWGKQCRFZAPC5PYJZ1', 'EZ0KQCF3LSM9PRSG0K', - 'FHKKQC963NGSY18ZDZ', 'FJ9KQCRJ3RGHNBWW4S', 'S2EKQC9F4UR4R71IC3', - '1XBKQCX019BKJ0M9IH', 'Z62KQC706L0B0WTN3Q', 'O7EKQCEVZ7FBEWMNWE', - 'XY8KQCULFPN4SR915Q', 'WQDKQCEULSD5G9XNFI', '2Z0KQCSWKVFG7RPFD8', - '26BKQC0SJIJOH02H2A', '262KQCH2RQKN0CBRLF', 'P5ZJQCMKO7EYV4HFCL', - 'KXBKQC52JO3AP4GMLF', '9IFKQC60JTDBV57N6S', 'TQ0KQCZ8LA7X9DIEAN', - 'BAXJQCORQA5Q46FCDG', 'VR0KQC7LVANO83AL35', '75CKQC4T617U2E5T5Y', - 'LCTKQCZU3F94CEFSOM', 'WJYJQCPNJJI5JN07SD', '3N6KQC6BE5EIXTRMDL', - 'CM5KQCD57I15GKLAMB', 'cccbffffd3e69819cd8', - 'BJKKQCVDA66528PDAU', 'QS0KQCLMIZFI8ZDLM3', 'UW0KQCRHBIYMA8LPZD', - 'GJ7KQC7APJSAMHEK5Q', '711KQCDXOQWB3KDWEP', 'PY0KQC77AJ3457A6C2', - 'WZ0KQCYVMEJHDR4MV2', '28EKQCQGM6NLLWFRG7', 'E33KQCRREJALRA715H', - '8HKKQCTEJAOBVH410L', 'IO6KQC70PMBQUDNB3L', '1YBKQCWRBNB433NEMH', - 'M01KQCF7KUWCDY67JD', 'CR0KQCOMV2QPPC90IF', '85ZJQCMG38N7Q2WKIK', - 'I9GKQCERACL8UZF2PY', 'BY0KQCOZUK47R2JZDE', '7W0KQCYDMD4LTSY5JL', - 'A0YJQC3HONEKD1JCPK', 'd5839c13b0541b7b8e6', - ])) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "0PBKQCXHLAEIB46ZIA", + "QEVJQC04YO01UAWJ2N", + "UT0KQCMN7PC9XURRXJ", + "MZAKQCKAQLIQYWP5IW", + "Y7BKQC9CUXWQLGLPQM", + "OBBKQC8NJM5UYBO849", + "NPBKQCKEF0G7T4H312", + "423KQCGLT8UISDUM1Q", + "8S0KQCNORIWDL0X8SB", + "AP5KQC0LBXPM727OWB", + "AREKQC0VPBHNZ5R3IO", + "KU0KQCJ0RUTJTIUKSA", + "VC4KQC7L7KKH9RLHXN", + "0P3KQCRSIVL1A4VJ19", + "PK6KQCGEL4PTE720BL", + "YIKKQCSD2Z85UHJ8LX", + "KY8KQCMIH2HUUGLA3R", + "RD7KQCQ24B1N3OEC5X", + "NV0KQC7SIEH3SVDPP1", + "KIKKQCU2CJ543TLM5J", + "AT0KQC4P3MMUCHI3BK", + "J6BKQC1PMNBAYSLM9U", + "IXXJQCLKOUAJ5RSQY4", + "U4ZJQC5VR0QBIE8DU", + "F7BKQC4NXO9R7XOG2W", + "7U0KQC6PGZBNQATNOT", + "78AKQCI05U36T3E82O", + "H1GKQCWOUJHFSHXABA", + "ZWGKQCRFZAPC5PYJZ1", + "EZ0KQCF3LSM9PRSG0K", + "FHKKQC963NGSY18ZDZ", + "FJ9KQCRJ3RGHNBWW4S", + "S2EKQC9F4UR4R71IC3", + "1XBKQCX019BKJ0M9IH", + "Z62KQC706L0B0WTN3Q", + "O7EKQCEVZ7FBEWMNWE", + "XY8KQCULFPN4SR915Q", + "WQDKQCEULSD5G9XNFI", + "2Z0KQCSWKVFG7RPFD8", + "26BKQC0SJIJOH02H2A", + "262KQCH2RQKN0CBRLF", + "P5ZJQCMKO7EYV4HFCL", + "KXBKQC52JO3AP4GMLF", + "9IFKQC60JTDBV57N6S", + "TQ0KQCZ8LA7X9DIEAN", + "BAXJQCORQA5Q46FCDG", + "VR0KQC7LVANO83AL35", + "75CKQC4T617U2E5T5Y", + "LCTKQCZU3F94CEFSOM", + "WJYJQCPNJJI5JN07SD", + "3N6KQC6BE5EIXTRMDL", + "CM5KQCD57I15GKLAMB", + "cccbffffd3e69819cd8", + "BJKKQCVDA66528PDAU", + "QS0KQCLMIZFI8ZDLM3", + "UW0KQCRHBIYMA8LPZD", + "GJ7KQC7APJSAMHEK5Q", + "711KQCDXOQWB3KDWEP", + "PY0KQC77AJ3457A6C2", + "WZ0KQCYVMEJHDR4MV2", + "28EKQCQGM6NLLWFRG7", + "E33KQCRREJALRA715H", + "8HKKQCTEJAOBVH410L", + "IO6KQC70PMBQUDNB3L", + "1YBKQCWRBNB433NEMH", + "M01KQCF7KUWCDY67JD", + "CR0KQCOMV2QPPC90IF", + "85ZJQCMG38N7Q2WKIK", + "I9GKQCERACL8UZF2PY", + "BY0KQCOZUK47R2JZDE", + "7W0KQCYDMD4LTSY5JL", + "A0YJQC3HONEKD1JCPK", + "d5839c13b0541b7b8e6", + ] + ), + ) def test_everyone(self): """ Test Everyone rule. """ rule = Everyone([]) - self.assertEqual(len(self.filter_with_rule(rule)), - self.db.get_number_of_people()) + self.assertEqual( + len(self.filter_with_rule(rule)), self.db.get_number_of_people() + ) def test_familywithincompleteevent(self): """ @@ -416,163 +511,290 @@ def test_hasalternatename(self): Test HasAlternateName rule. """ rule = HasAlternateName([]) - self.assertEqual(self.filter_with_rule(rule), set([ - '46WJQCIOLQ0KOX2XCC', 'GNUJQCL9MD64AM56OH', - ])) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "46WJQCIOLQ0KOX2XCC", + "GNUJQCL9MD64AM56OH", + ] + ), + ) def test_commonancestor_empty(self): """ Test empty HasCommonAncestorWith rule. """ - rule = HasCommonAncestorWith(['']) - self.assertEqual(self.filter_with_rule(rule), set([ - ])) + rule = HasCommonAncestorWith([""]) + self.assertEqual(self.filter_with_rule(rule), set([])) def test_commonancestor_nonmatching(self): """ Test non-matching HasCommonAncestorWith rule. """ - rule = HasCommonAncestorWith(['I0000']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'd5839c1237765987724' - ])) + rule = HasCommonAncestorWith(["I0000"]) + self.assertEqual(self.filter_with_rule(rule), set(["d5839c1237765987724"])) def test_commonancestor_irregular(self): """ Test irregular HasCommonAncestorWith rule. """ - rule = HasCommonAncestorWith(['ABCDEFG']) - self.assertEqual(self.filter_with_rule(rule), set([ - ])) + rule = HasCommonAncestorWith(["ABCDEFG"]) + self.assertEqual(self.filter_with_rule(rule), set([])) def test_commonancestor_matching(self): """ Test matching HasCommonAncestorWith rule. """ - rule = HasCommonAncestorWith(['I0044']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'GNUJQCL9MD64AM56OH', 'SOFKQCBYAO18OWC0CS', 'EMEKQC02EOUF8H0SHM', - '3EXJQCVWOSQFGLYB6H', 'EMTJQCQU6TL4WAVSE4', 'QUEKQCZL61S8BJJ388', - 'MKEKQCSBQGAVHAPCQT', 'MUFKQCMXUJ07MCDUNI', 'DBXJQCJCEZMO17WZ89', - 'ORFKQC4KLWEGTGR19L', 'MG5KQC6ZKSVO4A63G2', 'N26KQCF3ASHMZ0HEW6', - 'GNWJQC9NLVF2MZLHU9', 'ZFXJQCHAD8SLZZ7KRP', '44WJQCLCQIPZUB0UH', - 'B8TJQC53HJXOGXK8F7', 'D3WJQCCGV58IP8PNHZ', '3LEKQCRF3FD2E1H73I', - 'F06KQCZY1I4H4IFZM', 'VMTJQC49IGKLG2EQ5', '9BXKQC1PVLPYFMD6IX', - 'H1DKQC4YGZ5A61FGS', '1GWJQCGOOZ8FJW3YK9', 'S16KQCX8XUO3EEL85N', - 'OREKQCF34YE89RL8S6', 'RU5KQCQTPC9SJ5Q1JN', 'GYFKQCPH8Q0JDN94GR', - '9QFKQC54ET79K2SD57', 'MLEKQCH64557K610VR', 'AWFKQCJELLUWDY2PD3', - 'ZDWJQC7TMS2AWAVF2Y', 'VJFKQCFO7WESWPNKHE', 'LV5KQCJCCR0S3DN5WW', - 'CDTJQCVTVX7CNMY9YU', 'OX5KQCKE3I94MEPDC', 'JF5KQC2L6ABI0MVD3E', - 'CH5KQCIEXSN1J5UEHB', '4JEKQC22K5UTH9QHCU', 'EPFKQCETTDTEL3PYIR', - 'D16KQCIZS56HVPW6DA', '2TEKQCTSCRL4Z2AUHE', '3WEKQCHXRH61E3CIKB', - 'TDTJQCGYRS2RCCGQN3', 'SMWJQCXQ6I2GEXSPK9', 'PXFKQCXEHJX3W1Q1IV', - 'Q9TJQCXDL1599L2B2Z', 'BFXJQCF1JBOXPRW2OS', '6TFKQCUTO94WB2NHN', - 'FNEKQCO239QSNK0R78', '3RFKQCNKMX9HVLNSLW', 'W2DKQCV4H3EZUJ35DX', - '5IEKQCN37EFBK9EBUD', 'LW5KQCXSXRC2XV3T3D', 'ZNEKQCULV911DIXBK3', - '35WJQC1B7T7NPV8OLV', 'MPEKQC6TIP3SP1YF7I', 'DMFKQC5MHGYC6503F2', - '3KEKQC45RL87D4ZG86', 'KLTJQC70XVZJSPQ43U', 'LVEKQCP09W7JNFDAFC', - 'DPUJQCUYKKDPT78JJV', 'JDXJQCR5L0NTR21SQA', 'UAXJQC6HC354V7Q6JA', - 'XBXJQCS4QY316ZGHRN', 'HCXJQCRKB4K65V1C07', '66TJQC6CC7ZWL9YZ64', - 'XNFKQC6DN59LACS9IU', 'LL5KQCG687Y165GL5P', '7X5KQC9ABK4T6AW7QF', - 'HKTJQCIJD8RK9RJFO1', '1LTJQCYQI1DXBLG6Z', '0FWJQCLYEP736P3YZK', - '0DXJQC1T8P3CQKZIUO', 'ISEKQC97YI74A9VKWC', 'KGXJQCBQ39ON9VB37T', - 'BZ5KQCD4KFI3BTIMZU', '0HEKQCLINMQS4RB7B8', 'BBTJQCNT6N1H4X6TL4', - 'COFKQCUXC2H4G3QBYT', 'DI5KQC3CLKWQI3I0CC', 'T8TJQCWWI8RY57YNTQ', - '46WJQCIOLQ0KOX2XCC', 'OEXJQCQJHF2BLSAAIS', 'GNFKQCH8AFJRJO9V4Y', - '8LFKQCQWXTJQJR4CXV', 'IGWJQCSVT8NXTFXOFJ', '3PEKQC8ZDCYTSSIKZ9', - '5UEKQC8N8NEPSWU1QQ', 'NK5KQC1MAOU2BP35ZV', 'UZFKQCIHVT44DC9KGH', - 'JJ5KQC83DT7VDMUYRQ', '626KQC7C08H3UTM38E', 'XIFKQCLQOY645QTGP7', - 'HEWJQCWQQ3K4BNRLIO', 'HDWJQCT361VOV2PQLP', 'XFKKQCGA4DVECEB48E', - 'KWEKQCTNIIV9BROFFG', - ])) + rule = HasCommonAncestorWith(["I0044"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "GNUJQCL9MD64AM56OH", + "SOFKQCBYAO18OWC0CS", + "EMEKQC02EOUF8H0SHM", + "3EXJQCVWOSQFGLYB6H", + "EMTJQCQU6TL4WAVSE4", + "QUEKQCZL61S8BJJ388", + "MKEKQCSBQGAVHAPCQT", + "MUFKQCMXUJ07MCDUNI", + "DBXJQCJCEZMO17WZ89", + "ORFKQC4KLWEGTGR19L", + "MG5KQC6ZKSVO4A63G2", + "N26KQCF3ASHMZ0HEW6", + "GNWJQC9NLVF2MZLHU9", + "ZFXJQCHAD8SLZZ7KRP", + "44WJQCLCQIPZUB0UH", + "B8TJQC53HJXOGXK8F7", + "D3WJQCCGV58IP8PNHZ", + "3LEKQCRF3FD2E1H73I", + "F06KQCZY1I4H4IFZM", + "VMTJQC49IGKLG2EQ5", + "9BXKQC1PVLPYFMD6IX", + "H1DKQC4YGZ5A61FGS", + "1GWJQCGOOZ8FJW3YK9", + "S16KQCX8XUO3EEL85N", + "OREKQCF34YE89RL8S6", + "RU5KQCQTPC9SJ5Q1JN", + "GYFKQCPH8Q0JDN94GR", + "9QFKQC54ET79K2SD57", + "MLEKQCH64557K610VR", + "AWFKQCJELLUWDY2PD3", + "ZDWJQC7TMS2AWAVF2Y", + "VJFKQCFO7WESWPNKHE", + "LV5KQCJCCR0S3DN5WW", + "CDTJQCVTVX7CNMY9YU", + "OX5KQCKE3I94MEPDC", + "JF5KQC2L6ABI0MVD3E", + "CH5KQCIEXSN1J5UEHB", + "4JEKQC22K5UTH9QHCU", + "EPFKQCETTDTEL3PYIR", + "D16KQCIZS56HVPW6DA", + "2TEKQCTSCRL4Z2AUHE", + "3WEKQCHXRH61E3CIKB", + "TDTJQCGYRS2RCCGQN3", + "SMWJQCXQ6I2GEXSPK9", + "PXFKQCXEHJX3W1Q1IV", + "Q9TJQCXDL1599L2B2Z", + "BFXJQCF1JBOXPRW2OS", + "6TFKQCUTO94WB2NHN", + "FNEKQCO239QSNK0R78", + "3RFKQCNKMX9HVLNSLW", + "W2DKQCV4H3EZUJ35DX", + "5IEKQCN37EFBK9EBUD", + "LW5KQCXSXRC2XV3T3D", + "ZNEKQCULV911DIXBK3", + "35WJQC1B7T7NPV8OLV", + "MPEKQC6TIP3SP1YF7I", + "DMFKQC5MHGYC6503F2", + "3KEKQC45RL87D4ZG86", + "KLTJQC70XVZJSPQ43U", + "LVEKQCP09W7JNFDAFC", + "DPUJQCUYKKDPT78JJV", + "JDXJQCR5L0NTR21SQA", + "UAXJQC6HC354V7Q6JA", + "XBXJQCS4QY316ZGHRN", + "HCXJQCRKB4K65V1C07", + "66TJQC6CC7ZWL9YZ64", + "XNFKQC6DN59LACS9IU", + "LL5KQCG687Y165GL5P", + "7X5KQC9ABK4T6AW7QF", + "HKTJQCIJD8RK9RJFO1", + "1LTJQCYQI1DXBLG6Z", + "0FWJQCLYEP736P3YZK", + "0DXJQC1T8P3CQKZIUO", + "ISEKQC97YI74A9VKWC", + "KGXJQCBQ39ON9VB37T", + "BZ5KQCD4KFI3BTIMZU", + "0HEKQCLINMQS4RB7B8", + "BBTJQCNT6N1H4X6TL4", + "COFKQCUXC2H4G3QBYT", + "DI5KQC3CLKWQI3I0CC", + "T8TJQCWWI8RY57YNTQ", + "46WJQCIOLQ0KOX2XCC", + "OEXJQCQJHF2BLSAAIS", + "GNFKQCH8AFJRJO9V4Y", + "8LFKQCQWXTJQJR4CXV", + "IGWJQCSVT8NXTFXOFJ", + "3PEKQC8ZDCYTSSIKZ9", + "5UEKQC8N8NEPSWU1QQ", + "NK5KQC1MAOU2BP35ZV", + "UZFKQCIHVT44DC9KGH", + "JJ5KQC83DT7VDMUYRQ", + "626KQC7C08H3UTM38E", + "XIFKQCLQOY645QTGP7", + "HEWJQCWQQ3K4BNRLIO", + "HDWJQCT361VOV2PQLP", + "XFKKQCGA4DVECEB48E", + "KWEKQCTNIIV9BROFFG", + ] + ), + ) def test_hasnickname(self): """ Test HasNickname rule. """ rule = HasNickname([]) - self.assertEqual(self.filter_with_rule(rule), set([ - 'cc8205d883763f02abd', 'GNUJQCL9MD64AM56OH', - 'Q8HKQC3VMRM1M6M7ES', - ])) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "cc8205d883763f02abd", + "GNUJQCL9MD64AM56OH", + "Q8HKQC3VMRM1M6M7ES", + ] + ), + ) def test_hasunknowngender(self): """ Test HasUnknownGender rule. """ rule = HasUnknownGender([]) - self.assertEqual(self.filter_with_rule(rule), set([ - 'OJOKQC83Y1EDBIMLJ6', '8BHKQCFK9UZFRJYC2Y', 'PGFKQC1TUQMXFAMLMB', - 'IHOKQCECRZYQDKW6KF', '8HKKQCTEJAOBVH410L', 'AGFKQCO358R18LNJYV', - '1ENKQCBPFZTAQJSP4O', 'NUWKQCO7TVAOH0CHLV', 'P5IKQC88STY3FNTFZ3', - '7GXKQCMVFU8WR1LKZL', 'LGXKQCJ5OP6MKF9QLN', 'XNFKQC6DN59LACS9IU', - '7IOKQC1NVGUI1E55CQ', '57PKQCFAWY7AM3JS4M', 'BNXKQCEBXC1RCOGJNF', - 'TFFKQC1RMG8RRADKDH', 'FHKKQC963NGSY18ZDZ', 'WMXKQCDUJ4JKQQYCR7', - 'PBHKQCHOAGTECRKT9L', 'OFXKQC8W0N3N6JP6YQ', - ])) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "OJOKQC83Y1EDBIMLJ6", + "8BHKQCFK9UZFRJYC2Y", + "PGFKQC1TUQMXFAMLMB", + "IHOKQCECRZYQDKW6KF", + "8HKKQCTEJAOBVH410L", + "AGFKQCO358R18LNJYV", + "1ENKQCBPFZTAQJSP4O", + "NUWKQCO7TVAOH0CHLV", + "P5IKQC88STY3FNTFZ3", + "7GXKQCMVFU8WR1LKZL", + "LGXKQCJ5OP6MKF9QLN", + "XNFKQC6DN59LACS9IU", + "7IOKQC1NVGUI1E55CQ", + "57PKQCFAWY7AM3JS4M", + "BNXKQCEBXC1RCOGJNF", + "TFFKQC1RMG8RRADKDH", + "FHKKQC963NGSY18ZDZ", + "WMXKQCDUJ4JKQQYCR7", + "PBHKQCHOAGTECRKT9L", + "OFXKQC8W0N3N6JP6YQ", + ] + ), + ) def test_hassourceof_empty(self): """ Test empty HasSourceOf rule. """ # when run with an empty string finds people with no sourc citations - rule = HasSourceOf(['']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'cc82060512042f67e2c', 'cc8205d87831c772e87', - 'cc82060516c6c141500', 'cc8205d87fd529000ff', - 'cc82060504445ab6deb', 'cc8205d887376aacba2', - 'cccbffffd3e69819cd8', 'cc8205d87c20350420b', - 'cc8206050e541f79f92', 'cc8205d883763f02abd', - 'cc8206050980ea622d0', 'cc8205d872f532ab14e', - 'd5839c132b11d9e3632', 'd583a5ba0d50afbbaaf', - 'd5839c1352c64b924d9', 'd583a5b9fc864e3bf4e', - 'd583a5ba1bd083ce4c2', 'd583a5b9df71bceb48c', - 'd583a5b9ced473a7e6a', 'd583a5ba2bc7b9d1388', - 'd5839c12fec09785f6a', 'd5839c1237765987724', - 'd5839c137b3640ad776', 'd5839c126d11a754f46', - 'd5839c12d3b4d5e619b', 'd5839c13380462b246f', - 'd5839c12e9e08301ce2', 'd5839c1366b21411fb4', - 'd5839c13a282b51dd0d', 'd5839c12ac91650a72b', - 'd583a5b9edf6cb5d8d5', 'd583a5ba4be3acdd312', - 'd5839c131d560e06bac', 'd5839c13b0541b7b8e6', - 'd5839c1388e3ab6c87c', 'd583a5ba5ca6b698463', - 'd583a5ba3bc48c2002c', 'd583a5b90777391ea9a', - ])) + rule = HasSourceOf([""]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "cc82060512042f67e2c", + "cc8205d87831c772e87", + "cc82060516c6c141500", + "cc8205d87fd529000ff", + "cc82060504445ab6deb", + "cc8205d887376aacba2", + "cccbffffd3e69819cd8", + "cc8205d87c20350420b", + "cc8206050e541f79f92", + "cc8205d883763f02abd", + "cc8206050980ea622d0", + "cc8205d872f532ab14e", + "d5839c132b11d9e3632", + "d583a5ba0d50afbbaaf", + "d5839c1352c64b924d9", + "d583a5b9fc864e3bf4e", + "d583a5ba1bd083ce4c2", + "d583a5b9df71bceb48c", + "d583a5b9ced473a7e6a", + "d583a5ba2bc7b9d1388", + "d5839c12fec09785f6a", + "d5839c1237765987724", + "d5839c137b3640ad776", + "d5839c126d11a754f46", + "d5839c12d3b4d5e619b", + "d5839c13380462b246f", + "d5839c12e9e08301ce2", + "d5839c1366b21411fb4", + "d5839c13a282b51dd0d", + "d5839c12ac91650a72b", + "d583a5b9edf6cb5d8d5", + "d583a5ba4be3acdd312", + "d5839c131d560e06bac", + "d5839c13b0541b7b8e6", + "d5839c1388e3ab6c87c", + "d583a5ba5ca6b698463", + "d583a5ba3bc48c2002c", + "d583a5b90777391ea9a", + ] + ), + ) def test_hassourceof_nonmatching(self): """ Test non-matching HasSourceOf rule. """ - rule = HasSourceOf(['S0004']) - self.assertEqual(self.filter_with_rule(rule), set([ - ])) + rule = HasSourceOf(["S0004"]) + self.assertEqual(self.filter_with_rule(rule), set([])) def test_hassourceof_irregular(self): """ Test irregular HasSourceOf rule. """ - rule = HasSourceOf(['ABCDEFG']) - self.assertEqual(self.filter_with_rule(rule), set([ - ])) + rule = HasSourceOf(["ABCDEFG"]) + self.assertEqual(self.filter_with_rule(rule), set([])) def test_hassourceof_matching(self): """ Test matching HasSourceOf rule. """ - rule = HasSourceOf(['S0000']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'GNUJQCL9MD64AM56OH', - ])) - + rule = HasSourceOf(["S0000"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "GNUJQCL9MD64AM56OH", + ] + ), + ) def test_havealtfamilies(self): """ Test HaveAltFamilies rule. """ rule = HaveAltFamilies([]) - self.assertEqual(self.filter_with_rule(rule), set([ - 'CH5KQCIEXSN1J5UEHB', 'MG5KQC6ZKSVO4A63G2', - ])) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "CH5KQCIEXSN1J5UEHB", + "MG5KQC6ZKSVO4A63G2", + ] + ), + ) def test_havechildren(self): """ @@ -587,174 +809,285 @@ def test_incompletenames(self): Test IncompleteNames rule. """ rule = IncompleteNames([]) - self.assertEqual(self.filter_with_rule(rule), set([ - 'IHOKQCECRZYQDKW6KF', 'cc82060504445ab6deb', - 'LCXKQCQZH5EH56NTCD', 'cc8205d87831c772e87', - '3RFKQCNKMX9HVLNSLW', 'cc8205d87fd529000ff', - 'B1UKQCBR49WB3134PN', '0TTKQCXXY59OCDPLV3', - 'F3UKQC7ZV3EYVWTZ8O', '1MXKQCJ2BR43910ZYX', - 'cc8206050e541f79f92', 'FHKKQC963NGSY18ZDZ', - 'R5HKQCIEPOY1DMQOWX', 'ZHMKQC50PFVAPI8PZ6', 'T4UKQCYGECXGVNBWMY', - 'cc82060516c6c141500', 'UPWKQCYVFH7RZOSZ29', - '2AMKQCE67YOH3TBVYI', '2CUKQCFDVN3EZE2E4C', '7IOKQC1NVGUI1E55CQ', - 'KSTKQC018GNA7HDCAS', 'WIVKQC4Q4FCQJT5M63', 'A4YKQCRYSI5FT5T38', - 'BUNKQCO4HZHZP70F3K', 'YRTKQCNDP343OD5OQJ', '7VEKQCV05EDK0625KI', - 'cc8205d872f532ab14e', 'TPXKQCEGL04KHGMO2X', - 'L9LKQCQ8KJRKHM4D2E', '8QXKQCHJ2EUC7OV8EQ', 'W0XKQCKSFWWJWQ2OSN', - 'I6QKQCFRDTV2LDC8M2', 'XTUKQC7WCIVA5F0NC4', 'F4UKQCPK572VWU2YZQ', - 'JKDKQCF4ND92A088J2', 'COFKQCUXC2H4G3QBYT', 'BNXKQCEBXC1RCOGJNF', - 'Q42KQCKJZGS4IZWHF5', 'P5IKQC88STY3FNTFZ3', '7CXKQC59NSZFXIG1UE', - 'cc8205d87c20350420b', 'FQUKQCWEHOAWUP4QWS', - '3YTKQCK2W63W0MQBJE', '8HKKQCTEJAOBVH410L', 'HLQKQC0BJIZL0V4EK4', - 'B0UKQC9A54F1GUB7NR', 'EPXKQCQRZP2PNPN7BE', - 'cc82060512042f67e2c', 'XZLKQCRQA9EHPBNZPT', - 'OQXKQC2Y5FVH9PK0JL', 'AXLKQC0YTFAWQ234YD', 'OFXKQC8W0N3N6JP6YQ', - 'MWUKQCD2ZSCECQOCLG', '1ENKQCBPFZTAQJSP4O', 'N7XKQCYD3VSCSZREGJ', - '2LQKQC62GJUQCJIOK8', 'QXXKQC9PT5FWNT140K', 'VAXKQC19HIFPX61J28', - '0PXKQCJ9S1M3NNASET', 'K8XKQCDSVLSK422A3K', '52UKQCFYXMFTKIGNBS', - '7GXKQCMVFU8WR1LKZL', '4UMKQCF07KL2K92CI5', 'LGXKQCJ5OP6MKF9QLN', - 'FZTKQCSTPIQ3C9JC46', 'WMXKQCDUJ4JKQQYCR7', 'R6UKQC939L9FV62UGE', - 'OIUKQCBHUWDGL7DNTI', 'FRTKQC3G6JBJAR2ZPX', 'PIEKQCKUL6OAMS8Q9R', - 'cc8205d887376aacba2', 'LGMKQCQP5M5L18FVTN', - '8HUKQCRV8B3J2LLQ3B', 'LOUKQC45HUN532HOOM', - 'cc8205d883763f02abd', 'TBXKQC7OHIN28PVCS3', - ])) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "IHOKQCECRZYQDKW6KF", + "cc82060504445ab6deb", + "LCXKQCQZH5EH56NTCD", + "cc8205d87831c772e87", + "3RFKQCNKMX9HVLNSLW", + "cc8205d87fd529000ff", + "B1UKQCBR49WB3134PN", + "0TTKQCXXY59OCDPLV3", + "F3UKQC7ZV3EYVWTZ8O", + "1MXKQCJ2BR43910ZYX", + "cc8206050e541f79f92", + "FHKKQC963NGSY18ZDZ", + "R5HKQCIEPOY1DMQOWX", + "ZHMKQC50PFVAPI8PZ6", + "T4UKQCYGECXGVNBWMY", + "cc82060516c6c141500", + "UPWKQCYVFH7RZOSZ29", + "2AMKQCE67YOH3TBVYI", + "2CUKQCFDVN3EZE2E4C", + "7IOKQC1NVGUI1E55CQ", + "KSTKQC018GNA7HDCAS", + "WIVKQC4Q4FCQJT5M63", + "A4YKQCRYSI5FT5T38", + "BUNKQCO4HZHZP70F3K", + "YRTKQCNDP343OD5OQJ", + "7VEKQCV05EDK0625KI", + "cc8205d872f532ab14e", + "TPXKQCEGL04KHGMO2X", + "L9LKQCQ8KJRKHM4D2E", + "8QXKQCHJ2EUC7OV8EQ", + "W0XKQCKSFWWJWQ2OSN", + "I6QKQCFRDTV2LDC8M2", + "XTUKQC7WCIVA5F0NC4", + "F4UKQCPK572VWU2YZQ", + "JKDKQCF4ND92A088J2", + "COFKQCUXC2H4G3QBYT", + "BNXKQCEBXC1RCOGJNF", + "Q42KQCKJZGS4IZWHF5", + "P5IKQC88STY3FNTFZ3", + "7CXKQC59NSZFXIG1UE", + "cc8205d87c20350420b", + "FQUKQCWEHOAWUP4QWS", + "3YTKQCK2W63W0MQBJE", + "8HKKQCTEJAOBVH410L", + "HLQKQC0BJIZL0V4EK4", + "B0UKQC9A54F1GUB7NR", + "EPXKQCQRZP2PNPN7BE", + "cc82060512042f67e2c", + "XZLKQCRQA9EHPBNZPT", + "OQXKQC2Y5FVH9PK0JL", + "AXLKQC0YTFAWQ234YD", + "OFXKQC8W0N3N6JP6YQ", + "MWUKQCD2ZSCECQOCLG", + "1ENKQCBPFZTAQJSP4O", + "N7XKQCYD3VSCSZREGJ", + "2LQKQC62GJUQCJIOK8", + "QXXKQC9PT5FWNT140K", + "VAXKQC19HIFPX61J28", + "0PXKQCJ9S1M3NNASET", + "K8XKQCDSVLSK422A3K", + "52UKQCFYXMFTKIGNBS", + "7GXKQCMVFU8WR1LKZL", + "4UMKQCF07KL2K92CI5", + "LGXKQCJ5OP6MKF9QLN", + "FZTKQCSTPIQ3C9JC46", + "WMXKQCDUJ4JKQQYCR7", + "R6UKQC939L9FV62UGE", + "OIUKQCBHUWDGL7DNTI", + "FRTKQC3G6JBJAR2ZPX", + "PIEKQCKUL6OAMS8Q9R", + "cc8205d887376aacba2", + "LGMKQCQP5M5L18FVTN", + "8HUKQCRV8B3J2LLQ3B", + "LOUKQC45HUN532HOOM", + "cc8205d883763f02abd", + "TBXKQC7OHIN28PVCS3", + ] + ), + ) def test_isbookmarked(self): """ Test IsBookmarked rule. """ rule = IsBookmarked([]) - self.assertEqual(self.filter_with_rule(rule), set([ - '35WJQC1B7T7NPV8OLV', 'AWFKQCJELLUWDY2PD3', 'Q8HKQC3VMRM1M6M7ES', - ])) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "35WJQC1B7T7NPV8OLV", + "AWFKQCJELLUWDY2PD3", + "Q8HKQC3VMRM1M6M7ES", + ] + ), + ) def test_dupancestor_empty(self): """ Test empty IsDuplicatedAncestorOf rule. """ - rule = IsDuplicatedAncestorOf(['']) - self.assertEqual(self.filter_with_rule(rule), set([ - ])) + rule = IsDuplicatedAncestorOf([""]) + self.assertEqual(self.filter_with_rule(rule), set([])) def test_dupancestor_nonmatching(self): """ Test non-matching IsDuplicatedAncestorOf rule. """ - rule = IsDuplicatedAncestorOf(['I0000']) - self.assertEqual(self.filter_with_rule(rule), set([ - ])) + rule = IsDuplicatedAncestorOf(["I0000"]) + self.assertEqual(self.filter_with_rule(rule), set([])) def test_dupancestor_irregular(self): """ Test irregular IsDuplicatedAncestorOf rule. """ - rule = IsDuplicatedAncestorOf(['ABCDEFG']) - self.assertEqual(self.filter_with_rule(rule), set([ - ])) + rule = IsDuplicatedAncestorOf(["ABCDEFG"]) + self.assertEqual(self.filter_with_rule(rule), set([])) def test_dupancestor_matching(self): """ Test matching IsDuplicatedAncestorOf rule. """ - rule = IsDuplicatedAncestorOf(['I1631']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'I3VJQCUY5I6UR92507', 'D4VJQC09STQCWD393E', - ])) + rule = IsDuplicatedAncestorOf(["I1631"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "I3VJQCUY5I6UR92507", + "D4VJQC09STQCWD393E", + ] + ), + ) def test_isrelatedwith_empty(self): """ Test empty IsRelatedWith rule. """ - rule = IsRelatedWith(['']) - self.assertEqual(self.filter_with_rule(rule), set([ - ])) + rule = IsRelatedWith([""]) + self.assertEqual(self.filter_with_rule(rule), set([])) def test_isrelatedwith_nonmatching(self): """ Test non-matching IsRelatedWith rule. """ - rule = IsRelatedWith(['I0000']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'd5839c1237765987724', 'd5839c126d11a754f46', - ])) + rule = IsRelatedWith(["I0000"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "d5839c1237765987724", + "d5839c126d11a754f46", + ] + ), + ) def test_isrelatedwith_irregular(self): """ Test irregular IsRelatedWith rule. """ - rule = IsRelatedWith(['ABCDEFG']) - self.assertEqual(self.filter_with_rule(rule), set([ - ])) + rule = IsRelatedWith(["ABCDEFG"]) + self.assertEqual(self.filter_with_rule(rule), set([])) def test_isrelatedwith_matching(self): """ Test matching IsRelatedWith rule. """ - rule = IsRelatedWith(['I1844']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'HWTKQCSM28EI6WFDHP', 'T4UKQCYGECXGVNBWMY', 'YOTKQCEX2PLG03LZQS', - 'X8UKQCIDY21QIQBDVI', 'F3UKQC7ZV3EYVWTZ8O', '0TTKQCXXY59OCDPLV3', - 'EVTKQCHV2E2PODFD7C', 'BBUKQC5GPRPDJHJAWU', 'FRTKQC3G6JBJAR2ZPX', - 'NDTKQCN95VFLGJ21L', 'SFTKQC26EJ2BYQCRIA', 'MYTKQCVCFOFM32H9GB', - 'B0UKQC9A54F1GUB7NR', 'PTTKQCYN0JR3ZZJNWR', 'F4UKQCPK572VWU2YZQ', - 'LLTKQCX39KCXFSX0U4', 'IXTKQC1BAU1F1WNXKB', '3YTKQCK2W63W0MQBJE', - 'TQTKQCO897BNA1H93B', 'DOTKQCP1MG3VC8D7V2', '3NTKQCZKLMIM6HYFE1', - 'WUTKQCVQCUPFFOGUT8', 'GETKQCPRC2W5YDUYM6', 'YRTKQCNDP343OD5OQJ', - 'U0UKQCBZS0R6WW7LBS', 'J2UKQC897I42M9VHDD', '7MTKQC1QNE4H5RF35S', - '5FTKQCKT9SDZ8TB03C', 'O1UKQCJD5YHDRW887V', 'EUTKQCFATXRU431YY6', - 'UHTKQCORH3NTZ0FYL3', '2CUKQCFDVN3EZE2E4C', 'RNTKQCMLGRRKQVKDPR', - 'CGTKQC4WO8W3WSQRCX', 'WAUKQCOQ91QCJZWQ9U', 'FZTKQCSTPIQ3C9JC46', - 'AHTKQCM2YFRW3AGSRL', 'WBTKQCC775IAAGIWZD', '8KTKQC407A8CN5O68H', - '8QTKQCN8ZKY5OWWJZF', 'UKTKQCSL3AUJIWTD2A', 'HAUKQCM3GYGVTREGZS', - '52UKQCFYXMFTKIGNBS', 'U3UKQCO30PWAK6JQBA', 'R6UKQC939L9FV62UGE', - 'TZTKQCR39A060AQ63C', 'X9UKQCFELSDAQ2TDP1', 'B1UKQCBR49WB3134PN', - 'KSTKQC018GNA7HDCAS', 'FJTKQCJCMAHJOA9NHI', 'HITKQCWJSCZX2AN6NP', - 'WVTKQCZC91I63LHEE7', '0DTKQC6KBOS69LQJ35', - ])) + rule = IsRelatedWith(["I1844"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "HWTKQCSM28EI6WFDHP", + "T4UKQCYGECXGVNBWMY", + "YOTKQCEX2PLG03LZQS", + "X8UKQCIDY21QIQBDVI", + "F3UKQC7ZV3EYVWTZ8O", + "0TTKQCXXY59OCDPLV3", + "EVTKQCHV2E2PODFD7C", + "BBUKQC5GPRPDJHJAWU", + "FRTKQC3G6JBJAR2ZPX", + "NDTKQCN95VFLGJ21L", + "SFTKQC26EJ2BYQCRIA", + "MYTKQCVCFOFM32H9GB", + "B0UKQC9A54F1GUB7NR", + "PTTKQCYN0JR3ZZJNWR", + "F4UKQCPK572VWU2YZQ", + "LLTKQCX39KCXFSX0U4", + "IXTKQC1BAU1F1WNXKB", + "3YTKQCK2W63W0MQBJE", + "TQTKQCO897BNA1H93B", + "DOTKQCP1MG3VC8D7V2", + "3NTKQCZKLMIM6HYFE1", + "WUTKQCVQCUPFFOGUT8", + "GETKQCPRC2W5YDUYM6", + "YRTKQCNDP343OD5OQJ", + "U0UKQCBZS0R6WW7LBS", + "J2UKQC897I42M9VHDD", + "7MTKQC1QNE4H5RF35S", + "5FTKQCKT9SDZ8TB03C", + "O1UKQCJD5YHDRW887V", + "EUTKQCFATXRU431YY6", + "UHTKQCORH3NTZ0FYL3", + "2CUKQCFDVN3EZE2E4C", + "RNTKQCMLGRRKQVKDPR", + "CGTKQC4WO8W3WSQRCX", + "WAUKQCOQ91QCJZWQ9U", + "FZTKQCSTPIQ3C9JC46", + "AHTKQCM2YFRW3AGSRL", + "WBTKQCC775IAAGIWZD", + "8KTKQC407A8CN5O68H", + "8QTKQCN8ZKY5OWWJZF", + "UKTKQCSL3AUJIWTD2A", + "HAUKQCM3GYGVTREGZS", + "52UKQCFYXMFTKIGNBS", + "U3UKQCO30PWAK6JQBA", + "R6UKQC939L9FV62UGE", + "TZTKQCR39A060AQ63C", + "X9UKQCFELSDAQ2TDP1", + "B1UKQCBR49WB3134PN", + "KSTKQC018GNA7HDCAS", + "FJTKQCJCMAHJOA9NHI", + "HITKQCWJSCZX2AN6NP", + "WVTKQCZC91I63LHEE7", + "0DTKQC6KBOS69LQJ35", + ] + ), + ) def test_hasidof_empty(self): """ Test empty HasIdOf rule. """ - rule = HasIdOf(['']) - self.assertEqual(self.filter_with_rule(rule), set([ - ])) + rule = HasIdOf([""]) + self.assertEqual(self.filter_with_rule(rule), set([])) def test_hasidof_nonmatching(self): """ Test non-matching HasIdOf rule. """ - rule = HasIdOf(['I0000']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'd5839c1237765987724' - ])) + rule = HasIdOf(["I0000"]) + self.assertEqual(self.filter_with_rule(rule), set(["d5839c1237765987724"])) def test_hasidof_irregular(self): """ Test irregular HasIdOf rule. """ - rule = HasIdOf(['ABCDEFG']) - self.assertEqual(self.filter_with_rule(rule), set([ - ])) + rule = HasIdOf(["ABCDEFG"]) + self.assertEqual(self.filter_with_rule(rule), set([])) def test_hasidof_matching(self): """ Test matching HasIdOf rule. """ - rule = HasIdOf(['I0044']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'GNUJQCL9MD64AM56OH', - ])) + rule = HasIdOf(["I0044"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "GNUJQCL9MD64AM56OH", + ] + ), + ) def test_isdefaultperson(self): """ Test IsDefaultPerson rule. """ rule = IsDefaultPerson([]) - self.assertEqual(self.filter_with_rule(rule), set([ - 'GNUJQCL9MD64AM56OH', - ])) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "GNUJQCL9MD64AM56OH", + ] + ), + ) def test_isfemale(self): """ @@ -785,26 +1118,63 @@ def test_multiplemarriages(self): Test MultipleMarriages rule. """ rule = MultipleMarriages([]) - self.assertEqual(self.filter_with_rule(rule), set([ - 'R1VKQCJWNP24VN7BO', 'ZTVJQCTSMI85EGMXFM', 'ENTJQCZXQV1IRKJXUL', - '44WJQCLCQIPZUB0UH', 'SMWJQCXQ6I2GEXSPK9', 'DN3KQC1URTED410L3R', - '5FYJQC86G8EZ0L4E4B', '5F4KQCJRU8ZKL6SILT', '0YNKQC5U4EQGVNUZD8', - 'YRYJQCE3RF4U8A59UB', 'APWKQCI6YXAXBLC33I', 'XSKKQC6GGKLAYANWAF', - '0FQKQCOQD0VRVJPTSD', 'B3UJQCZHDXII99AWW4', - 'cc8205d872f532ab14e', 'SS1KQCWWF9488Q330U', - 'OCYJQCS8YT7JO8KIMO', 'I6HKQCQF72V2N56JQ5', '6YWJQC86FBVN0J6JS', - 'KYNKQCVA6FE65ONFIQ', 'SHAKQCNY5IXO30GUAB', 'O5XKQC3V6BPJI13J24', - 'ZN7KQC3RLB82EXF1QF', 'CIYJQCF3UK12DL0S2Y', 'H3XJQCFJ4FP4U2WGZC', - 'cc82060504445ab6deb', '4E4KQC1K4XUEX29IJO', - '0XVJQCJUNJY40WDSMA', '1WUJQCHNH76G6YD3A', 'IH3KQCM1VZPRKLBLK7', - '242KQCBALBOD8ZK5VI', '8G4KQCS6C1AOM6ZGR3', 'I1EKQCGGDSUD8ILUW4', - 'X8BKQCSFF4AET5MY23', 'RJWJQCN1XKXRN5KMCP', 'ZWNKQC9DAZ3C6UHUAV', - '9QUJQCCSWRZNSAPCR', 'HI0KQCG9TGT5AAIPU', 'DI4KQC3S1AO27VWOLN', - 'QBDKQCH2IU6N8IXMFE', 'DK2KQCJYW14VXUJ85', '117KQCBB32RMTTV4G6', - '0QLKQCFTQMNVGCV4GM', 'D2OKQCGDNPT3BH4WH', 'CAYJQCKOL49OF7XWB3', - 'ZQGKQCGHS67Q4IMHEG', 'OEXJQCQJHF2BLSAAIS', 'UKYJQC70LIZQ11BP89', - 'FF2KQCRBSPCG1QY97', 'L6EKQCO8QYL2UO2MQO', - ])) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "R1VKQCJWNP24VN7BO", + "ZTVJQCTSMI85EGMXFM", + "ENTJQCZXQV1IRKJXUL", + "44WJQCLCQIPZUB0UH", + "SMWJQCXQ6I2GEXSPK9", + "DN3KQC1URTED410L3R", + "5FYJQC86G8EZ0L4E4B", + "5F4KQCJRU8ZKL6SILT", + "0YNKQC5U4EQGVNUZD8", + "YRYJQCE3RF4U8A59UB", + "APWKQCI6YXAXBLC33I", + "XSKKQC6GGKLAYANWAF", + "0FQKQCOQD0VRVJPTSD", + "B3UJQCZHDXII99AWW4", + "cc8205d872f532ab14e", + "SS1KQCWWF9488Q330U", + "OCYJQCS8YT7JO8KIMO", + "I6HKQCQF72V2N56JQ5", + "6YWJQC86FBVN0J6JS", + "KYNKQCVA6FE65ONFIQ", + "SHAKQCNY5IXO30GUAB", + "O5XKQC3V6BPJI13J24", + "ZN7KQC3RLB82EXF1QF", + "CIYJQCF3UK12DL0S2Y", + "H3XJQCFJ4FP4U2WGZC", + "cc82060504445ab6deb", + "4E4KQC1K4XUEX29IJO", + "0XVJQCJUNJY40WDSMA", + "1WUJQCHNH76G6YD3A", + "IH3KQCM1VZPRKLBLK7", + "242KQCBALBOD8ZK5VI", + "8G4KQCS6C1AOM6ZGR3", + "I1EKQCGGDSUD8ILUW4", + "X8BKQCSFF4AET5MY23", + "RJWJQCN1XKXRN5KMCP", + "ZWNKQC9DAZ3C6UHUAV", + "9QUJQCCSWRZNSAPCR", + "HI0KQCG9TGT5AAIPU", + "DI4KQC3S1AO27VWOLN", + "QBDKQCH2IU6N8IXMFE", + "DK2KQCJYW14VXUJ85", + "117KQCBB32RMTTV4G6", + "0QLKQCFTQMNVGCV4GM", + "D2OKQCGDNPT3BH4WH", + "CAYJQCKOL49OF7XWB3", + "ZQGKQCGHS67Q4IMHEG", + "OEXJQCQJHF2BLSAAIS", + "UKYJQC70LIZQ11BP89", + "FF2KQCRBSPCG1QY97", + "L6EKQCO8QYL2UO2MQO", + ] + ), + ) def test_nevermarried(self): """ @@ -859,26 +1229,46 @@ def test_relationshipbookmarks(self): Test RelationshipPathBetweenBookmarks rule. """ rule = RelationshipPathBetweenBookmarks([]) - self.assertEqual(self.filter_with_rule(rule), set([ - '44WJQCLCQIPZUB0UH', '35WJQC1B7T7NPV8OLV', 'AWFKQCJELLUWDY2PD3', - 'D3WJQCCGV58IP8PNHZ', 'Q8HKQC3VMRM1M6M7ES', - ])) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "44WJQCLCQIPZUB0UH", + "35WJQC1B7T7NPV8OLV", + "AWFKQCJELLUWDY2PD3", + "D3WJQCCGV58IP8PNHZ", + "Q8HKQC3VMRM1M6M7ES", + ] + ), + ) def test_hassoundexname(self): """ Test HasSoundexName rule. """ - rule = HasSoundexName(['garner']) + rule = HasSoundexName(["garner"]) self.assertEqual(len(self.filter_with_rule(rule)), 73) def test_hasnameof(self): """ Test HasNameOf rule. """ - rule = HasNameOf(['Lewis', 'Garner', 'Dr.', 'Sr', 'Anderson', - 'Big Louie', 'von', 'Zieliński', None, None, None]) - self.assertEqual(self.filter_with_rule(rule), set([ - 'GNUJQCL9MD64AM56OH'])) + rule = HasNameOf( + [ + "Lewis", + "Garner", + "Dr.", + "Sr", + "Anderson", + "Big Louie", + "von", + "Zieliński", + None, + None, + None, + ] + ) + self.assertEqual(self.filter_with_rule(rule), set(["GNUJQCL9MD64AM56OH"])) if __name__ == "__main__": diff --git a/gramps/gen/filters/rules/test/place_rules_test.py b/gramps/gen/filters/rules/test/place_rules_test.py index c850d5ecf1b..b027cfadce2 100644 --- a/gramps/gen/filters/rules/test/place_rules_test.py +++ b/gramps/gen/filters/rules/test/place_rules_test.py @@ -31,16 +31,32 @@ from ....user import User from ..place import ( - AllPlaces, HasCitation, HasGallery, HasIdOf, RegExpIdOf, HasNote, - HasNoteRegexp, HasReferenceCountOf, HasSourceCount, HasSourceOf, - PlacePrivate, MatchesSourceConfidence, HasData, HasNoLatOrLon, - InLatLonNeighborhood, ChangedSince, HasTag, HasTitle, IsEnclosedBy, - WithinArea - ) + AllPlaces, + HasCitation, + HasGallery, + HasIdOf, + RegExpIdOf, + HasNote, + HasNoteRegexp, + HasReferenceCountOf, + HasSourceCount, + HasSourceOf, + PlacePrivate, + MatchesSourceConfidence, + HasData, + HasNoLatOrLon, + InLatLonNeighborhood, + ChangedSince, + HasTag, + HasTitle, + IsEnclosedBy, + WithinArea, +) TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests")) EXAMPLE = os.path.join(TEST_DIR, "example.gramps") -GenericPlaceFilter = GenericFilterFactory('Place') +GenericPlaceFilter = GenericFilterFactory("Place") + class BaseTest(unittest.TestCase): """ @@ -68,45 +84,55 @@ def test_allplaces(self): Test AllPlaces rule. """ rule = AllPlaces([]) - self.assertEqual(len(self.filter_with_rule(rule)), - self.db.get_number_of_places()) + self.assertEqual( + len(self.filter_with_rule(rule)), self.db.get_number_of_places() + ) def test_hascitation(self): """ Test HasCitation rule. """ - rule = HasCitation(['page 23', '', '']) - self.assertEqual(self.filter_with_rule(rule), - set(['YNUJQC8YM5EGRG868J'])) + rule = HasCitation(["page 23", "", ""]) + self.assertEqual(self.filter_with_rule(rule), set(["YNUJQC8YM5EGRG868J"])) def test_hasgallery(self): """ Test HasGallery rule. """ - rule = HasGallery(['0', 'greater than']) - self.assertEqual(self.filter_with_rule(rule), - set(['YNUJQC8YM5EGRG868J'])) + rule = HasGallery(["0", "greater than"]) + self.assertEqual(self.filter_with_rule(rule), set(["YNUJQC8YM5EGRG868J"])) def test_hasidof(self): """ Test HasIdOf rule. """ - rule = HasIdOf(['P0001']) - self.assertEqual(self.filter_with_rule(rule), - set(['c96587262e91149933fcea5f20a'])) + rule = HasIdOf(["P0001"]) + self.assertEqual( + self.filter_with_rule(rule), set(["c96587262e91149933fcea5f20a"]) + ) def test_regexpidof(self): """ Test RegExpIdOf rule. """ - rule = RegExpIdOf(['P000.'], use_regex=True) - self.assertEqual(self.filter_with_rule(rule), set([ - 'c96587262e91149933fcea5f20a', 'c96587262ff262aaac31f6db7af', - 'c96587262f24c33ab2420276737', 'c96587262e566596a225682bf53', - 'c9658726302661576894508202d', 'c96587262f8329d37b252e1b9e5', - 'c965872630664f33485fc18e75', 'c96587262fb7dbb954077cb1286', - 'c96587262f4a44183c65ff1e52', 'c96587262ed43fdb37bf04bdb7f', - ])) + rule = RegExpIdOf(["P000."], use_regex=True) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "c96587262e91149933fcea5f20a", + "c96587262ff262aaac31f6db7af", + "c96587262f24c33ab2420276737", + "c96587262e566596a225682bf53", + "c9658726302661576894508202d", + "c96587262f8329d37b252e1b9e5", + "c965872630664f33485fc18e75", + "c96587262fb7dbb954077cb1286", + "c96587262f4a44183c65ff1e52", + "c96587262ed43fdb37bf04bdb7f", + ] + ), + ) def test_hasnote(self): """ @@ -119,34 +145,40 @@ def test_hasnoteregexp(self): """ Test HasNoteRegexp rule. """ - rule = HasNoteRegexp(['.'], use_regex=True) + rule = HasNoteRegexp(["."], use_regex=True) self.assertEqual(self.filter_with_rule(rule), set([])) def test_hasreferencecountof(self): """ Test HasReferenceCountOf rule. """ - rule = HasReferenceCountOf(['greater than', '35']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'c96587262e566596a225682bf53', 'MATJQCJYH8ULRIRYTH', - '5HTJQCSB91P69HY731', '4ECKQCWCLO5YIHXEXC', - 'c965872630a68ebd32322c4a30a'])) + rule = HasReferenceCountOf(["greater than", "35"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "c96587262e566596a225682bf53", + "MATJQCJYH8ULRIRYTH", + "5HTJQCSB91P69HY731", + "4ECKQCWCLO5YIHXEXC", + "c965872630a68ebd32322c4a30a", + ] + ), + ) def test_hassourcecount(self): """ Test HasSourceCount rule. """ - rule = HasSourceCount(['1', 'equal to']) - self.assertEqual(self.filter_with_rule(rule), - set(['YNUJQC8YM5EGRG868J'])) + rule = HasSourceCount(["1", "equal to"]) + self.assertEqual(self.filter_with_rule(rule), set(["YNUJQC8YM5EGRG868J"])) def test_hassourceof(self): """ Test HasSourceOf rule. """ - rule = HasSourceOf(['S0001']) - self.assertEqual(self.filter_with_rule(rule), - set(['YNUJQC8YM5EGRG868J'])) + rule = HasSourceOf(["S0001"]) + self.assertEqual(self.filter_with_rule(rule), set(["YNUJQC8YM5EGRG868J"])) def test_placeprivate(self): """ @@ -159,17 +191,17 @@ def test_matchessourceconfidence(self): """ Test MatchesSourceConfidence rule. """ - rule = MatchesSourceConfidence(['2']) - self.assertEqual(self.filter_with_rule(rule), - set(['YNUJQC8YM5EGRG868J'])) + rule = MatchesSourceConfidence(["2"]) + self.assertEqual(self.filter_with_rule(rule), set(["YNUJQC8YM5EGRG868J"])) def test_hasdata(self): """ Test HasData rule. """ - rule = HasData(['Albany', 'County', '']) - self.assertEqual(self.filter_with_rule(rule), - set(['c9658726d602acadb74e330116a'])) + rule = HasData(["Albany", "County", ""]) + self.assertEqual( + self.filter_with_rule(rule), set(["c9658726d602acadb74e330116a"]) + ) def test_hasnolatorlon(self): """ @@ -182,63 +214,109 @@ def test_inlatlonneighborhood(self): """ Test InLatLonNeighborhood rule. """ - rule = InLatLonNeighborhood(['30N', '90W', '2', '2']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'C6WJQC0GDYP3HZDPR3', 'N88LQCRB363ES5WJ83', - '03EKQCC2KTNLHFLDRJ', 'M9VKQCJV91X0M12J8'])) + rule = InLatLonNeighborhood(["30N", "90W", "2", "2"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "C6WJQC0GDYP3HZDPR3", + "N88LQCRB363ES5WJ83", + "03EKQCC2KTNLHFLDRJ", + "M9VKQCJV91X0M12J8", + ] + ), + ) def test_changedsince(self): """ Test ChangedSince rule. """ - rule = ChangedSince(['2013-01-01', '2014-01-01']) + rule = ChangedSince(["2013-01-01", "2014-01-01"]) self.assertEqual(len(self.filter_with_rule(rule)), 419) def test_hastag(self): """ Test HasTag rule. """ - rule = HasTag(['ToDo']) + rule = HasTag(["ToDo"]) self.assertEqual(self.filter_with_rule(rule), set([])) def test_hastitle(self): """ Test HasTitle rule. """ - rule = HasTitle(['Albany']) - self.assertEqual(self.filter_with_rule(rule), set([ - '51VJQCXUP61H9JRL66', '9XBKQCE1LZ7PMJE56G', - 'c9658726d602acadb74e330116a', 'P9MKQCT08Z3YBJV5UB'])) + rule = HasTitle(["Albany"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "51VJQCXUP61H9JRL66", + "9XBKQCE1LZ7PMJE56G", + "c9658726d602acadb74e330116a", + "P9MKQCT08Z3YBJV5UB", + ] + ), + ) def test_isenclosedby(self): """ Test IsEnclosedBy rule. """ - rule = IsEnclosedBy(['P0001', '0']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'EAFKQCR0ED5QWL87EO', 'S22LQCLUZM135LVKRL', 'VDUJQCFP24ZV3O4ID2', - 'V6ALQCZZFN996CO4D', 'OC6LQCXMKP6NUVYQD8', 'CUUKQC6BY5LAZXLXC6', - 'PTFKQCKPHO2VC5SYKS', 'PHUJQCJ9R4XQO5Y0WS'])) + rule = IsEnclosedBy(["P0001", "0"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "EAFKQCR0ED5QWL87EO", + "S22LQCLUZM135LVKRL", + "VDUJQCFP24ZV3O4ID2", + "V6ALQCZZFN996CO4D", + "OC6LQCXMKP6NUVYQD8", + "CUUKQC6BY5LAZXLXC6", + "PTFKQCKPHO2VC5SYKS", + "PHUJQCJ9R4XQO5Y0WS", + ] + ), + ) def test_withinarea(self): """ Test within area rule. """ - rule = WithinArea(['P1339', 100, 0]) - self.assertEqual(self.filter_with_rule(rule), set([ - 'KJUJQCY580EB77WIVO', 'TLVJQC4FD2CD9OYAXU', 'TE4KQCL9FDYA4PB6VW', - 'W9GLQCSRJIQ9N2TGDF'])) + rule = WithinArea(["P1339", 100, 0]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "KJUJQCY580EB77WIVO", + "TLVJQC4FD2CD9OYAXU", + "TE4KQCL9FDYA4PB6VW", + "W9GLQCSRJIQ9N2TGDF", + ] + ), + ) def test_isenclosedby_inclusive(self): """ Test IsEnclosedBy rule with inclusive option. """ - rule = IsEnclosedBy(['P0001', '1']) - self.assertEqual(self.filter_with_rule(rule), set([ - 'c96587262e91149933fcea5f20a', 'EAFKQCR0ED5QWL87EO', - 'S22LQCLUZM135LVKRL', 'VDUJQCFP24ZV3O4ID2', 'V6ALQCZZFN996CO4D', - 'OC6LQCXMKP6NUVYQD8', 'CUUKQC6BY5LAZXLXC6', 'PTFKQCKPHO2VC5SYKS', - 'PHUJQCJ9R4XQO5Y0WS'])) + rule = IsEnclosedBy(["P0001", "1"]) + self.assertEqual( + self.filter_with_rule(rule), + set( + [ + "c96587262e91149933fcea5f20a", + "EAFKQCR0ED5QWL87EO", + "S22LQCLUZM135LVKRL", + "VDUJQCFP24ZV3O4ID2", + "V6ALQCZZFN996CO4D", + "OC6LQCXMKP6NUVYQD8", + "CUUKQC6BY5LAZXLXC6", + "PTFKQCKPHO2VC5SYKS", + "PHUJQCJ9R4XQO5Y0WS", + ] + ), + ) if __name__ == "__main__": diff --git a/gramps/gen/filters/rules/test/repository_rules_test.py b/gramps/gen/filters/rules/test/repository_rules_test.py index 11e9d75c098..fa4495afb70 100644 --- a/gramps/gen/filters/rules/test/repository_rules_test.py +++ b/gramps/gen/filters/rules/test/repository_rules_test.py @@ -30,12 +30,21 @@ from ....user import User from ..repository import ( - AllRepos, HasIdOf, RegExpIdOf, HasNoteRegexp, HasReferenceCountOf, - RepoPrivate, ChangedSince, MatchesNameSubstringOf, HasTag) + AllRepos, + HasIdOf, + RegExpIdOf, + HasNoteRegexp, + HasReferenceCountOf, + RepoPrivate, + ChangedSince, + MatchesNameSubstringOf, + HasTag, +) TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests")) EXAMPLE = os.path.join(TEST_DIR, "example.gramps") -GenericRepositoryFilter = GenericFilterFactory('Repository') +GenericRepositoryFilter = GenericFilterFactory("Repository") + class BaseTest(unittest.TestCase): """ @@ -63,41 +72,43 @@ def test_allrepos(self): Test AllRepos rule. """ rule = AllRepos([]) - self.assertEqual(len(self.filter_with_rule(rule)), - self.db.get_number_of_repositories()) + self.assertEqual( + len(self.filter_with_rule(rule)), self.db.get_number_of_repositories() + ) def test_hasidof(self): """ Test HasIdOf rule. """ - rule = HasIdOf(['R0000']) - self.assertEqual(self.filter_with_rule(rule), - set(['b39fe38593f3f8c4f12'])) + rule = HasIdOf(["R0000"]) + self.assertEqual(self.filter_with_rule(rule), set(["b39fe38593f3f8c4f12"])) def test_regexpidof(self): """ Test RegExpIdOf rule. """ - rule = RegExpIdOf(['R000.'], use_regex=True) - self.assertEqual(self.filter_with_rule(rule), set([ - 'a701ead12841521cd4d', 'a701e99f93e5434f6f3', - 'b39fe38593f3f8c4f12'])) + rule = RegExpIdOf(["R000."], use_regex=True) + self.assertEqual( + self.filter_with_rule(rule), + set(["a701ead12841521cd4d", "a701e99f93e5434f6f3", "b39fe38593f3f8c4f12"]), + ) def test_hasnoteregexp(self): """ Test HasNoteRegexp rule. """ - rule = HasNoteRegexp(['.'], use_regex=True) - self.assertEqual(self.filter_with_rule(rule), set([ - 'a701ead12841521cd4d', 'b39fe38593f3f8c4f12'])) + rule = HasNoteRegexp(["."], use_regex=True) + self.assertEqual( + self.filter_with_rule(rule), + set(["a701ead12841521cd4d", "b39fe38593f3f8c4f12"]), + ) def test_hasreferencecountof(self): """ Test HasReferenceCountOf rule. """ - rule = HasReferenceCountOf(['greater than', '1']) - self.assertEqual(self.filter_with_rule(rule), - set(['a701e99f93e5434f6f3'])) + rule = HasReferenceCountOf(["greater than", "1"]) + self.assertEqual(self.filter_with_rule(rule), set(["a701e99f93e5434f6f3"])) def test_repoprivate(self): """ @@ -110,25 +121,22 @@ def test_changedsince(self): """ Test ChangedSince rule. """ - rule = ChangedSince(['2010-01-01', '2016-01-01']) - self.assertEqual(self.filter_with_rule(rule), - set(['a701e99f93e5434f6f3'])) + rule = ChangedSince(["2010-01-01", "2016-01-01"]) + self.assertEqual(self.filter_with_rule(rule), set(["a701e99f93e5434f6f3"])) def test_matchesnamesubstringof(self): """ Test MatchesNameSubstringOf rule. """ - rule = MatchesNameSubstringOf(['Martha']) - self.assertEqual(self.filter_with_rule(rule), - set(['a701ead12841521cd4d'])) + rule = MatchesNameSubstringOf(["Martha"]) + self.assertEqual(self.filter_with_rule(rule), set(["a701ead12841521cd4d"])) def test_hastag(self): """ Test HasTag rule. """ - rule = HasTag(['ToDo']) - self.assertEqual(self.filter_with_rule(rule), - set()) + rule = HasTag(["ToDo"]) + self.assertEqual(self.filter_with_rule(rule), set()) if __name__ == "__main__": diff --git a/gramps/gen/git_revision.py b/gramps/gen/git_revision.py index 87720455b5b..b24fdc45fd1 100644 --- a/gramps/gen/git_revision.py +++ b/gramps/gen/git_revision.py @@ -25,25 +25,24 @@ import subprocess + def get_git_revision(path=""): """ Return the short commit hash of the latest commit. """ stdout = "" - command = ['git', 'log', '-1', '--format=%h', path] + command = ["git", "log", "-1", "--format=%h", path] try: - proc = subprocess.Popen(command, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdout, stderr) = proc.communicate() except OSError: - return "" # subprocess failed + return "" # subprocess failed # subprocess worked - if stdout and len(stdout) > 0: # has output + if stdout and len(stdout) > 0: # has output try: - stdout = stdout.decode("utf-8", errors='replace') + stdout = stdout.decode("utf-8", errors="replace") except UnicodeDecodeError: pass return "-" + stdout if stdout else "" - else: # no output from git log + else: # no output from git log return "" diff --git a/gramps/gen/lib/address.py b/gramps/gen/lib/address.py index 2a30a6215bd..72b36fef69f 100644 --- a/gramps/gen/lib/address.py +++ b/gramps/gen/lib/address.py @@ -26,11 +26,11 @@ Address class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .privacybase import PrivacyBase from .citationbase import CitationBase @@ -39,15 +39,18 @@ from .locationbase import LocationBase from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Address for Person/Repository # -#------------------------------------------------------------------------- -class Address(SecondaryObject, PrivacyBase, CitationBase, NoteBase, DateBase, - LocationBase): +# ------------------------------------------------------------------------- +class Address( + SecondaryObject, PrivacyBase, CitationBase, NoteBase, DateBase, LocationBase +): """Provide address information.""" def __init__(self, source=None): @@ -64,11 +67,13 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (PrivacyBase.serialize(self), - CitationBase.serialize(self), - NoteBase.serialize(self), - DateBase.serialize(self), - LocationBase.serialize(self)) + return ( + PrivacyBase.serialize(self), + CitationBase.serialize(self), + NoteBase.serialize(self), + DateBase.serialize(self), + LocationBase.serialize(self), + ) def unserialize(self, data): """ @@ -92,40 +97,36 @@ def get_schema(cls): :rtype: dict """ from .date import Date + return { "type": "object", "title": _("Address"), "properties": { "_class": {"enum": [cls.__name__]}, - "private": {"type": "boolean", - "title": _("Private")}, - "citation_list": {"type": "array", - "title": _("Citations"), - "items": {"type": "string", - "maxLength": 50}}, - "note_list": {"type": "array", - "title": _("Notes"), - "items": {"type": "string", - "maxLength": 50}}, - "date": {"oneOf": [{"type": "null"}, Date.get_schema()], - "title": _("Date")}, - "street": {"type": "string", - "title": _("Street")}, - "locality": {"type": "string", - "title": _("Locality")}, - "city": {"type": "string", - "title": _("City")}, - "county": {"type": "string", - "title": _("County")}, - "state": {"type": "string", - "title": _("State")}, - "country": {"type": "string", - "title": _("Country")}, - "postal": {"type": "string", - "title": _("Postal Code")}, - "phone": {"type": "string", - "title": _("Phone")} - } + "private": {"type": "boolean", "title": _("Private")}, + "citation_list": { + "type": "array", + "title": _("Citations"), + "items": {"type": "string", "maxLength": 50}, + }, + "note_list": { + "type": "array", + "title": _("Notes"), + "items": {"type": "string", "maxLength": 50}, + }, + "date": { + "oneOf": [{"type": "null"}, Date.get_schema()], + "title": _("Date"), + }, + "street": {"type": "string", "title": _("Street")}, + "locality": {"type": "string", "title": _("Locality")}, + "city": {"type": "string", "title": _("City")}, + "county": {"type": "string", "title": _("County")}, + "state": {"type": "string", "title": _("State")}, + "country": {"type": "string", "title": _("Country")}, + "postal": {"type": "string", "title": _("Postal Code")}, + "phone": {"type": "string", "title": _("Phone")}, + }, } def get_text_data_list(self): @@ -174,8 +175,9 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - return self.get_referenced_note_handles() + \ - self.get_referenced_citation_handles() + return ( + self.get_referenced_note_handles() + self.get_referenced_citation_handles() + ) def is_equivalent(self, other): """ @@ -187,8 +189,10 @@ def is_equivalent(self, other): :returns: Constant indicating degree of equivalence. :rtype: int """ - if self.get_text_data_list() != other.get_text_data_list() or \ - self.get_date_object() != other.get_date_object(): + if ( + self.get_text_data_list() != other.get_text_data_list() + or self.get_date_object() != other.get_date_object() + ): return DIFFERENT else: if self.is_equal(other): diff --git a/gramps/gen/lib/addressbase.py b/gramps/gen/lib/addressbase.py index ad9c3ac9371..805feddcea1 100644 --- a/gramps/gen/lib/addressbase.py +++ b/gramps/gen/lib/addressbase.py @@ -23,19 +23,20 @@ AddressBase class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .address import Address from .const import IDENTICAL, EQUAL -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # AddressBase classes # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class AddressBase: """ Base class for address-aware objects. diff --git a/gramps/gen/lib/attrbase.py b/gramps/gen/lib/attrbase.py index 1e88269d722..a6a8d2d1206 100644 --- a/gramps/gen/lib/attrbase.py +++ b/gramps/gen/lib/attrbase.py @@ -23,24 +23,26 @@ AttributeRootBase class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .attribute import Attribute, AttributeRoot from .srcattribute import SrcAttribute from .const import IDENTICAL, EQUAL -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # AttributeRootBase class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class AttributeRootBase: """ Base class for attribute-aware objects. """ + _CLASS = AttributeRoot def __init__(self, source=None): @@ -54,8 +56,9 @@ def __init__(self, source=None): :type source: AttributeBase """ if source: - self.attribute_list = [self._CLASS(attribute) - for attribute in source.attribute_list] + self.attribute_list = [ + self._CLASS(attribute) for attribute in source.attribute_list + ] else: self.attribute_list = [] @@ -145,8 +148,10 @@ def _merge_attribute_list(self, acquisition): else: self.attribute_list.append(addendum) + class AttributeBase(AttributeRootBase): _CLASS = Attribute + class SrcAttributeBase(AttributeRootBase): _CLASS = SrcAttribute diff --git a/gramps/gen/lib/attribute.py b/gramps/gen/lib/attribute.py index 169c13d95a6..fc881077202 100644 --- a/gramps/gen/lib/attribute.py +++ b/gramps/gen/lib/attribute.py @@ -25,11 +25,11 @@ Attribute class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .privacybase import PrivacyBase from .citationbase import CitationBase @@ -37,13 +37,15 @@ from .attrtype import AttributeType from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Root object for Attribute # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class AttributeRoot(SecondaryObject, PrivacyBase): """ Provide a simple key/value pair for describing properties. @@ -66,7 +68,7 @@ def __init__(self, source=None): """ PrivacyBase.__init__(self, source) - #type structure depends on inheriting classes + # type structure depends on inheriting classes self.type = None self.value = None @@ -77,8 +79,7 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (PrivacyBase.serialize(self), - self.type.serialize(), self.value) + return (PrivacyBase.serialize(self), self.type.serialize(), self.value) def unserialize(self, data): """ @@ -182,13 +183,13 @@ def get_value(self): """Return the value of the Attribute instance.""" return self.value -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Attribute for Person/Family/Media/MediaRef # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Attribute(AttributeRoot, CitationBase, NoteBase): - def __init__(self, source=None): """ Create a new Attribute object, copying from the source if provided. @@ -203,14 +204,18 @@ def __init__(self, source=None): else: self.type = AttributeType() self.value = "" + def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (PrivacyBase.serialize(self), - CitationBase.serialize(self), - NoteBase.serialize(self), - self.type.serialize(), self.value) + return ( + PrivacyBase.serialize(self), + CitationBase.serialize(self), + NoteBase.serialize(self), + self.type.serialize(), + self.value, + ) def unserialize(self, data): """ @@ -236,20 +241,20 @@ def get_schema(cls): "title": _("Attribute"), "properties": { "_class": {"enum": [cls.__name__]}, - "private": {"type": "boolean", - "title": _("Private")}, - "citation_list": {"type": "array", - "title": _("Citations"), - "items": {"type": "string", - "maxLength": 50}}, - "note_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Notes")}, + "private": {"type": "boolean", "title": _("Private")}, + "citation_list": { + "type": "array", + "title": _("Citations"), + "items": {"type": "string", "maxLength": 50}, + }, + "note_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Notes"), + }, "type": AttributeType.get_schema(), - "value": {"type": "string", - "title": _("Value")} - } + "value": {"type": "string", "title": _("Value")}, + }, } def get_referenced_handles(self): @@ -260,8 +265,9 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - return self.get_referenced_note_handles() + \ - self.get_referenced_citation_handles() + return ( + self.get_referenced_note_handles() + self.get_referenced_citation_handles() + ) def merge(self, acquisition): """ diff --git a/gramps/gen/lib/attrtype.py b/gramps/gen/lib/attrtype.py index e469f1e920b..af162a1c8b5 100644 --- a/gramps/gen/lib/attrtype.py +++ b/gramps/gen/lib/attrtype.py @@ -23,21 +23,23 @@ Provide the different Attribute Types for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext + # _T_ is a gramps-defined keyword -- see po/update_po.py and po/genpot.sh -def _T_(value, context=''): # enable deferred translations +def _T_(value, context=""): # enable deferred translations return "%s\x04%s" % (context, value) if context else value -class AttributeType(GrampsType): +class AttributeType(GrampsType): UNKNOWN = -1 CUSTOM = 0 CASTE = 1 @@ -59,7 +61,7 @@ class AttributeType(GrampsType): _CUSTOM = CUSTOM _DEFAULT = ID - _BASEMAP = [ # allow deferred translation of attribute UI strings + _BASEMAP = [ # allow deferred translation of attribute UI strings (UNKNOWN, _T_("Unknown"), "Unknown"), (CUSTOM, _T_("Custom"), "Custom"), (CASTE, _T_("Caste"), "Caste"), @@ -77,7 +79,7 @@ class AttributeType(GrampsType): (WITNESS, _T_("Witness"), "Witness"), (TIME, _T_("Time"), "Time"), (OCCUPATION, _T_("Occupation"), "Occupation"), - ] + ] _DATAMAP = [(base[0], _(base[1]), base[2]) for base in _BASEMAP] @@ -90,7 +92,7 @@ def type2base(self): """ if self.value == self.CUSTOM: return str(self) - elif self._BASEMAP[self.value+1]: # UNKNOWN is before CUSTOM, sigh - return self._BASEMAP[self.value+1][1] + elif self._BASEMAP[self.value + 1]: # UNKNOWN is before CUSTOM, sigh + return self._BASEMAP[self.value + 1][1] else: return self.UNKNOWN diff --git a/gramps/gen/lib/baseobj.py b/gramps/gen/lib/baseobj.py index 631b777c2ca..b4dc274a5f0 100644 --- a/gramps/gen/lib/baseobj.py +++ b/gramps/gen/lib/baseobj.py @@ -22,19 +22,20 @@ Base Object class for Gramps """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from abc import ABCMeta, abstractmethod import re -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Base Object # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class BaseObject(metaclass=ABCMeta): """ The BaseObject is the base class for all data objects in Gramps, diff --git a/gramps/gen/lib/childref.py b/gramps/gen/lib/childref.py index 10f770150f8..a53b53d7b25 100644 --- a/gramps/gen/lib/childref.py +++ b/gramps/gen/lib/childref.py @@ -25,11 +25,11 @@ """ Child Reference class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .privacybase import PrivacyBase from .citationbase import CitationBase @@ -38,13 +38,15 @@ from .childreftype import ChildRefType from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Person References for Person/Family # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ChildRef(SecondaryObject, PrivacyBase, CitationBase, NoteBase, RefBase): """ Person reference class. @@ -70,12 +72,14 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (PrivacyBase.serialize(self), - CitationBase.serialize(self), - NoteBase.serialize(self), - RefBase.serialize(self), - self.frel.serialize(), - self.mrel.serialize()) + return ( + PrivacyBase.serialize(self), + CitationBase.serialize(self), + NoteBase.serialize(self), + RefBase.serialize(self), + self.frel.serialize(), + self.mrel.serialize(), + ) def unserialize(self, data): """ @@ -105,22 +109,21 @@ def get_schema(cls): "title": _("Child Reference"), "properties": { "_class": {"enum": [cls.__name__]}, - "private": {"type": "boolean", - "title": _("Private")}, - "citation_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Citations")}, - "note_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Notes")}, - "ref": {"type": "string", - "maxLength": 50, - "title": _("Handle")}, + "private": {"type": "boolean", "title": _("Private")}, + "citation_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Citations"), + }, + "note_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Notes"), + }, + "ref": {"type": "string", "maxLength": 50, "title": _("Handle")}, "frel": ChildRefType.get_schema(), - "mrel": ChildRefType.get_schema() - } + "mrel": ChildRefType.get_schema(), + }, } def get_text_data_list(self): @@ -159,10 +162,11 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - ret = self.get_referenced_note_handles() + \ - self.get_referenced_citation_handles() + ret = ( + self.get_referenced_note_handles() + self.get_referenced_citation_handles() + ) if self.ref: - ret += [('Person', self.ref)] + ret += [("Person", self.ref)] return ret def get_handle_referents(self): diff --git a/gramps/gen/lib/childreftype.py b/gramps/gen/lib/childreftype.py index 8feec0ba57c..fdf7539b89b 100644 --- a/gramps/gen/lib/childreftype.py +++ b/gramps/gen/lib/childreftype.py @@ -22,15 +22,17 @@ Provide the different child reference types. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext + class ChildRefType(GrampsType): """ Provide the different ChildRef types. @@ -65,14 +67,14 @@ class ChildRefType(GrampsType): _DATAMAP = [ (NONE, _("None"), "None"), - (BIRTH, _("Birth", 'relationship'), "Birth"), - (ADOPTED, _("Adopted", 'relationship'), "Adopted"), + (BIRTH, _("Birth", "relationship"), "Birth"), + (ADOPTED, _("Adopted", "relationship"), "Adopted"), (STEPCHILD, _("Stepchild"), "Stepchild"), (SPONSORED, _("Sponsored"), "Sponsored"), (FOSTER, _("Foster"), "Foster"), (UNKNOWN, _("Unknown"), "Unknown"), (CUSTOM, _("Custom"), "Custom"), - ] + ] def __init__(self, value=None): GrampsType.__init__(self, value) diff --git a/gramps/gen/lib/citation.py b/gramps/gen/lib/citation.py index 09b3661a976..4982cfa9277 100644 --- a/gramps/gen/lib/citation.py +++ b/gramps/gen/lib/citation.py @@ -25,18 +25,18 @@ Citation object for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .primaryobj import PrimaryObject from .mediabase import MediaBase from .notebase import NoteBase @@ -45,17 +45,20 @@ from .attrbase import SrcAttributeBase from .citationbase import IndirectCitationBase from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext LOG = logging.getLogger(".citation") -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Citation class # -#------------------------------------------------------------------------- -class Citation(MediaBase, NoteBase, SrcAttributeBase, IndirectCitationBase, - DateBase, PrimaryObject): +# ------------------------------------------------------------------------- +class Citation( + MediaBase, NoteBase, SrcAttributeBase, IndirectCitationBase, DateBase, PrimaryObject +): """ A record of a citation of a source of information. @@ -73,13 +76,13 @@ class Citation(MediaBase, NoteBase, SrcAttributeBase, IndirectCitationBase, def __init__(self): """Create a new Citation instance.""" PrimaryObject.__init__(self) - MediaBase.__init__(self) # 7 - NoteBase.__init__(self) # 6 - DateBase.__init__(self) # 2 - self.source_handle = None # 5 - self.page = "" # 3 - self.confidence = Citation.CONF_NORMAL # 4 - SrcAttributeBase.__init__(self) # 8 + MediaBase.__init__(self) # 7 + NoteBase.__init__(self) # 6 + DateBase.__init__(self) # 2 + self.source_handle = None # 5 + self.page = "" # 3 + self.confidence = Citation.CONF_NORMAL # 4 + SrcAttributeBase.__init__(self) # 8 @classmethod def get_schema(cls): @@ -92,82 +95,92 @@ def get_schema(cls): from .srcattribute import SrcAttribute from .mediaref import MediaRef from .date import Date + return { "type": "object", "title": _("Citation"), "properties": { "_class": {"enum": [cls.__name__]}, - "handle": {"type": "string", - "maxLength": 50, - "title": _("Handle")}, - "gramps_id": {"type": "string", - "title": _("Gramps ID")}, - "date": {"oneOf": [{"type": "null"}, Date.get_schema()], - "title": _("Date")}, - "page": {"type": "string", - "title": _("Page")}, - "confidence": {"type": "integer", - "minimum": 0, - "maximum": 4, - "title": _("Confidence")}, - "source_handle": {"type": "string", - "maxLength": 50, - "title": _("Source")}, - "note_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Notes")}, - "media_list": {"type": "array", - "items": MediaRef.get_schema(), - "title": _("Media")}, - "attribute_list": {"type": "array", - "items": SrcAttribute.get_schema(), - "title": _("Source Attributes")}, - "change": {"type": "integer", - "title": _("Last changed")}, - "tag_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Tags")}, - "private": {"type": "boolean", - "title": _("Private")} - } + "handle": {"type": "string", "maxLength": 50, "title": _("Handle")}, + "gramps_id": {"type": "string", "title": _("Gramps ID")}, + "date": { + "oneOf": [{"type": "null"}, Date.get_schema()], + "title": _("Date"), + }, + "page": {"type": "string", "title": _("Page")}, + "confidence": { + "type": "integer", + "minimum": 0, + "maximum": 4, + "title": _("Confidence"), + }, + "source_handle": { + "type": "string", + "maxLength": 50, + "title": _("Source"), + }, + "note_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Notes"), + }, + "media_list": { + "type": "array", + "items": MediaRef.get_schema(), + "title": _("Media"), + }, + "attribute_list": { + "type": "array", + "items": SrcAttribute.get_schema(), + "title": _("Source Attributes"), + }, + "change": {"type": "integer", "title": _("Last changed")}, + "tag_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Tags"), + }, + "private": {"type": "boolean", "title": _("Private")}, + }, } def serialize(self, no_text_date=False): """ Convert the object to a serialized tuple of data. """ - return (self.handle, # 0 - self.gramps_id, # 1 - DateBase.serialize(self, no_text_date),# 2 - str(self.page), # 3 - self.confidence, # 4 - self.source_handle, # 5 - NoteBase.serialize(self), # 6 - MediaBase.serialize(self), # 7 - SrcAttributeBase.serialize(self), # 8 - self.change, # 9 - TagBase.serialize(self), # 10 - self.private) # 11 + return ( + self.handle, # 0 + self.gramps_id, # 1 + DateBase.serialize(self, no_text_date), # 2 + str(self.page), # 3 + self.confidence, # 4 + self.source_handle, # 5 + NoteBase.serialize(self), # 6 + MediaBase.serialize(self), # 7 + SrcAttributeBase.serialize(self), # 8 + self.change, # 9 + TagBase.serialize(self), # 10 + self.private, + ) # 11 def unserialize(self, data): """ Convert the data held in a tuple created by the serialize method back into the data in a Citation structure. """ - (self.handle, # 0 - self.gramps_id, # 1 - date, # 2 - self.page, # 3 - self.confidence, # 4 - self.source_handle, # 5 - note_list, # 6 - media_list, # 7 - srcattr_list, # 8 - self.change, # 9 - tag_list, # 10 - self.private # 11 + ( + self.handle, # 0 + self.gramps_id, # 1 + date, # 2 + self.page, # 3 + self.confidence, # 4 + self.source_handle, # 5 + note_list, # 6 + media_list, # 7 + srcattr_list, # 8 + self.change, # 9 + tag_list, # 10 + self.private, # 11 ) = data DateBase.unserialize(self, date) @@ -190,11 +203,11 @@ def _has_handle_reference(self, classname, handle): this object type. :rtype: bool """ - if classname == 'Note': + if classname == "Note": return handle in [ref.ref for ref in self.note_list] - elif classname == 'Media': + elif classname == "Media": return handle in [ref.ref for ref in self.media_list] - elif classname == 'Source': + elif classname == "Source": return handle == self.get_reference_handle() return False @@ -207,8 +220,7 @@ def _remove_handle_references(self, classname, handle_list): :param handle_list: The list of handles to be removed. :type handle_list: str """ - if classname == 'Source' and \ - self.get_reference_handle() in handle_list: + if classname == "Source" and self.get_reference_handle() in handle_list: self.set_reference_handle(None) def _replace_handle_reference(self, classname, old_handle, new_handle): @@ -222,8 +234,7 @@ def _replace_handle_reference(self, classname, old_handle, new_handle): :param new_handle: The handle to replace the old one with. :type new_handle: str """ - if classname == 'Source' and \ - self.get_reference_handle() == old_handle: + if classname == "Source" and self.get_reference_handle() == old_handle: self.set_reference_handle(new_handle) def get_citation_child_list(self): @@ -282,10 +293,9 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - ret = (self.get_referenced_note_handles() + - self.get_referenced_tag_handles()) + ret = self.get_referenced_note_handles() + self.get_referenced_tag_handles() if self.get_reference_handle(): - ret += [('Source', self.get_reference_handle())] + ret += [("Source", self.get_reference_handle())] return ret def merge(self, acquisition): @@ -301,8 +311,10 @@ def merge(self, acquisition): self._merge_tag_list(acquisition) # merge confidence level_priority = [0, 4, 1, 3, 2] - idx = min(level_priority.index(self.confidence), - level_priority.index(acquisition.confidence)) + idx = min( + level_priority.index(self.confidence), + level_priority.index(acquisition.confidence), + ) self.confidence = level_priority[idx] self._merge_attribute_list(acquisition) # N.B. a Citation can refer to only one 'Source', so the diff --git a/gramps/gen/lib/citationbase.py b/gramps/gen/lib/citationbase.py index f69d5111e19..eaa6d009207 100644 --- a/gramps/gen/lib/citationbase.py +++ b/gramps/gen/lib/citationbase.py @@ -24,20 +24,21 @@ CitationBase class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging LOG = logging.getLogger(".citation") -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # CitationBase class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class CitationBase: """ Base class for storing citations. @@ -53,6 +54,7 @@ class CitationBase: This class, together with the Citation class, replaces the old SourceRef class. I.e. SourceRef = CitationBase + Citation """ + def __init__(self, source=None): """ Create a new CitationBase, copying from source if not None. @@ -100,14 +102,19 @@ def remove_citation_references(self, citation_handle_list): :param citation_handle_list: The list of citation handles to be removed :type handle: list """ - LOG.debug('enter remove_citation handle: %s self: %s citation_list: %s', - citation_handle_list, self, self.citation_list) + LOG.debug( + "enter remove_citation handle: %s self: %s citation_list: %s", + citation_handle_list, + self, + self.citation_list, + ) for handle in citation_handle_list: if handle in self.citation_list: - LOG.debug('remove handle %s from citation_list %s', - handle, self.citation_list) + LOG.debug( + "remove handle %s from citation_list %s", handle, self.citation_list + ) self.citation_list.remove(handle) - LOG.debug('get_citation_child_list %s', self.get_citation_child_list()) + LOG.debug("get_citation_child_list %s", self.get_citation_child_list()) for item in self.get_citation_child_list(): item.remove_citation_references(citation_handle_list) @@ -215,7 +222,7 @@ def get_referenced_citation_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - return [('Citation', handle) for handle in self.citation_list] + return [("Citation", handle) for handle in self.citation_list] def replace_citation_references(self, old_handle, new_handle): """ @@ -243,6 +250,7 @@ def replace_citation_references(self, old_handle, new_handle): for item in self.get_citation_child_list(): item.replace_citation_references(old_handle, new_handle) + class IndirectCitationBase: """ Citation management logic for objects that don't have citations @@ -256,6 +264,7 @@ class IndirectCitationBase: :class:`CitationBase`, which checks both the object and the child objects. """ + def has_citation_reference(self, citation_handle): """ Return True if any of the child objects has reference to this citation diff --git a/gramps/gen/lib/date.py b/gramps/gen/lib/date.py index 496dc2df07a..b38542a354e 100644 --- a/gramps/gen/lib/date.py +++ b/gramps/gen/lib/date.py @@ -2074,7 +2074,7 @@ def anniversary(self, year): month = self.dateval[Date._POS_MON] day = self.dateval[Date._POS_DAY] if month == 2 and day == 29 and not calendar.isleap(year): - day_show = config.get('preferences.february-29') + day_show = config.get("preferences.february-29") if day_show == 0: day = 28 elif day_show == 1: diff --git a/gramps/gen/lib/datebase.py b/gramps/gen/lib/datebase.py index da3fe242c6e..0dfd0b89817 100644 --- a/gramps/gen/lib/datebase.py +++ b/gramps/gen/lib/datebase.py @@ -22,18 +22,19 @@ DateBase class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .date import Date -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # DateBase classes # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class DateBase: """ Base class for storing date information. diff --git a/gramps/gen/lib/event.py b/gramps/gen/lib/event.py index c436c78415d..6c40c5698c3 100644 --- a/gramps/gen/lib/event.py +++ b/gramps/gen/lib/event.py @@ -25,18 +25,18 @@ Event object for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .primaryobj import PrimaryObject from .citationbase import CitationBase from .notebase import NoteBase @@ -47,17 +47,20 @@ from .tagbase import TagBase from .eventtype import EventType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext LOG = logging.getLogger(".citation") -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Event class # -#------------------------------------------------------------------------- -class Event(CitationBase, NoteBase, MediaBase, AttributeBase, - DateBase, PlaceBase, PrimaryObject): +# ------------------------------------------------------------------------- +class Event( + CitationBase, NoteBase, MediaBase, AttributeBase, DateBase, PlaceBase, PrimaryObject +): """ The Event record is used to store information about some type of action that occurred at a particular place at a particular time, @@ -111,14 +114,21 @@ def serialize(self, no_text_date=False): be considered persistent. :rtype: tuple """ - return (self.handle, self.gramps_id, self.__type.serialize(), - DateBase.serialize(self, no_text_date), - self.__description, self.place, - CitationBase.serialize(self), - NoteBase.serialize(self), - MediaBase.serialize(self), - AttributeBase.serialize(self), - self.change, TagBase.serialize(self), self.private) + return ( + self.handle, + self.gramps_id, + self.__type.serialize(), + DateBase.serialize(self, no_text_date), + self.__description, + self.place, + CitationBase.serialize(self), + NoteBase.serialize(self), + MediaBase.serialize(self), + AttributeBase.serialize(self), + self.change, + TagBase.serialize(self), + self.private, + ) @classmethod def get_schema(cls): @@ -131,47 +141,53 @@ def get_schema(cls): from .attribute import Attribute from .date import Date from .mediaref import MediaRef + return { "type": "object", "title": _("Event"), "properties": { "_class": {"enum": [cls.__name__]}, - "handle": {"type": "string", - "maxLength": 50, - "title": _("Handle")}, - "gramps_id": {"type": "string", - "title": _("Gramps ID")}, + "handle": {"type": "string", "maxLength": 50, "title": _("Handle")}, + "gramps_id": {"type": "string", "title": _("Gramps ID")}, "type": EventType.get_schema(), - "date": {"oneOf": [{"type": "null"}, Date.get_schema()], - "title": _("Date")}, - "description": {"type": "string", - "title": _("Description")}, - "place": {"type": ["string", "null"], - "maxLength": 50, - "title": _("Place")}, - "citation_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Citations")}, - "note_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Notes")}, - "media_list": {"type": "array", - "items": MediaRef.get_schema(), - "title": _("Media")}, - "attribute_list": {"type": "array", - "items": Attribute.get_schema(), - "title": _("Attributes")}, - "change": {"type": "integer", - "title": _("Last changed")}, - "tag_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Tags")}, - "private": {"type": "boolean", - "title": _("Private")}, - } + "date": { + "oneOf": [{"type": "null"}, Date.get_schema()], + "title": _("Date"), + }, + "description": {"type": "string", "title": _("Description")}, + "place": { + "type": ["string", "null"], + "maxLength": 50, + "title": _("Place"), + }, + "citation_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Citations"), + }, + "note_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Notes"), + }, + "media_list": { + "type": "array", + "items": MediaRef.get_schema(), + "title": _("Media"), + }, + "attribute_list": { + "type": "array", + "items": Attribute.get_schema(), + "title": _("Attributes"), + }, + "change": {"type": "integer", "title": _("Last changed")}, + "tag_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Tags"), + }, + "private": {"type": "boolean", "title": _("Private")}, + }, } def unserialize(self, data): @@ -183,10 +199,21 @@ def unserialize(self, data): Event object :type data: tuple """ - (self.handle, self.gramps_id, the_type, date, - self.__description, self.place, - citation_list, note_list, media_list, attribute_list, - self.change, tag_list, self.private) = data + ( + self.handle, + self.gramps_id, + the_type, + date, + self.__description, + self.place, + citation_list, + note_list, + media_list, + attribute_list, + self.change, + tag_list, + self.private, + ) = data self.__type = EventType() self.__type.unserialize(the_type) @@ -211,7 +238,7 @@ def _has_handle_reference(self, classname, handle): this object type. :rtype: bool """ - if classname == 'Place': + if classname == "Place": return self.place == handle return False @@ -224,7 +251,7 @@ def _remove_handle_references(self, classname, handle_list): :param handle_list: The list of handles to be removed. :type handle_list: str """ - if classname == 'Place' and self.place in handle_list: + if classname == "Place" and self.place in handle_list: self.place = "" def _replace_handle_reference(self, classname, old_handle, new_handle): @@ -238,7 +265,7 @@ def _replace_handle_reference(self, classname, old_handle, new_handle): :param new_handle: The handle to replace the old one with. :type new_handle: str """ - if classname == 'Place' and self.place == old_handle: + if classname == "Place" and self.place == old_handle: self.place = new_handle def get_text_data_list(self): @@ -287,11 +314,13 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - ret = (self.get_referenced_note_handles() + - self.get_referenced_citation_handles() + - self.get_referenced_tag_handles()) + ret = ( + self.get_referenced_note_handles() + + self.get_referenced_citation_handles() + + self.get_referenced_tag_handles() + ) if self.place: - ret.append(('Place', self.place)) + ret.append(("Place", self.place)) return ret def get_handle_referents(self): @@ -315,8 +344,12 @@ def is_empty(self): place = self.get_place_handle() description = self.__description the_type = self.__type - return (the_type == EventType.CUSTOM and date.is_empty() - and not place and not description) + return ( + the_type == EventType.CUSTOM + and date.is_empty() + and not place + and not description + ) def are_equal(self, other): """ @@ -330,13 +363,14 @@ def are_equal(self, other): if other is None: other = Event(None) - if self.__type != other.type or \ - ((self.place or other.place) and (self.place != other.place)) or \ - self.__description != other.description \ - or self.private != other.private or \ - (not self.get_date_object().is_equal(other.get_date_object())) or \ - len(self.get_citation_list()) != \ - len(other.get_citation_list()): + if ( + self.__type != other.type + or ((self.place or other.place) and (self.place != other.place)) + or self.__description != other.description + or self.private != other.private + or (not self.get_date_object().is_equal(other.get_date_object())) + or len(self.get_citation_list()) != len(other.get_citation_list()) + ): return False index = 0 @@ -382,8 +416,8 @@ def get_type(self): :rtype: tuple """ return self.__type - type = property(get_type, set_type, None, - 'Returns or sets type of the event') + + type = property(get_type, set_type, None, "Returns or sets type of the event") def set_description(self, description): """ @@ -404,6 +438,10 @@ def get_description(self): :rtype: str """ return self.__description - description = property(get_description, set_description, None, - 'Returns or sets description of the event') + description = property( + get_description, + set_description, + None, + "Returns or sets description of the event", + ) diff --git a/gramps/gen/lib/eventref.py b/gramps/gen/lib/eventref.py index 12dba5bce36..b580f6d33cd 100644 --- a/gramps/gen/lib/eventref.py +++ b/gramps/gen/lib/eventref.py @@ -26,11 +26,11 @@ Event Reference class for Gramps """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .privacybase import PrivacyBase from .notebase import NoteBase @@ -40,15 +40,18 @@ from .const import IDENTICAL, EQUAL, DIFFERENT from .citationbase import CitationBase from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Event References for Person/Family # -#------------------------------------------------------------------------- -class EventRef(PrivacyBase, NoteBase, AttributeBase, RefBase, - CitationBase, SecondaryObject): +# ------------------------------------------------------------------------- +class EventRef( + PrivacyBase, NoteBase, AttributeBase, RefBase, CitationBase, SecondaryObject +): """ Event reference class. @@ -80,8 +83,8 @@ def serialize(self): NoteBase.serialize(self), AttributeBase.serialize(self), RefBase.serialize(self), - self.__role.serialize() - ) + self.__role.serialize(), + ) @classmethod def get_schema(cls): @@ -92,29 +95,31 @@ def get_schema(cls): :rtype: dict """ from .attribute import Attribute + return { "type": "object", "title": _("Event reference"), "properties": { "_class": {"enum": [cls.__name__]}, - "private": {"type": "boolean", - "title": _("Private")}, - "citation_list": {"type": "array", - "title": _("Citations"), - "items": {"type": "string", - "maxLength": 50}}, - "note_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Notes")}, - "attribute_list": {"type": "array", - "items": Attribute.get_schema(), - "title": _("Attributes")}, - "ref": {"type": "string", - "maxLength": 50, - "title": _("Event")}, + "private": {"type": "boolean", "title": _("Private")}, + "citation_list": { + "type": "array", + "title": _("Citations"), + "items": {"type": "string", "maxLength": 50}, + }, + "note_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Notes"), + }, + "attribute_list": { + "type": "array", + "items": Attribute.get_schema(), + "title": _("Attributes"), + }, + "ref": {"type": "string", "maxLength": 50, "title": _("Event")}, "role": EventRoleType.get_schema(), - } + }, } def unserialize(self, data): @@ -147,7 +152,7 @@ def get_text_data_child_list(self): :returns: Returns the list of child objects that may carry textual data. :rtype: list """ - return self.attribute_list + return self.attribute_list def get_citation_child_list(self): """ @@ -178,10 +183,11 @@ def get_referenced_handles(self): objects. :rtype: list """ - ret = self.get_referenced_citation_handles() + \ - self.get_referenced_note_handles() + ret = ( + self.get_referenced_citation_handles() + self.get_referenced_note_handles() + ) if self.ref: - ret += [('Event', self.ref)] + ret += [("Event", self.ref)] return ret def get_handle_referents(self): @@ -237,4 +243,5 @@ def set_role(self, role): Set the role according to the given argument. """ self.__role.set(role) - role = property(get_role, set_role, None, 'Returns or sets role property') + + role = property(get_role, set_role, None, "Returns or sets role property") diff --git a/gramps/gen/lib/eventroletype.py b/gramps/gen/lib/eventroletype.py index 5a97fe9f046..f8b5bc852f0 100644 --- a/gramps/gen/lib/eventroletype.py +++ b/gramps/gen/lib/eventroletype.py @@ -22,17 +22,18 @@ Provide the different event roles. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -class EventRoleType(GrampsType): +class EventRoleType(GrampsType): UNKNOWN = -1 CUSTOM = 0 PRIMARY = 1 @@ -62,7 +63,7 @@ class EventRoleType(GrampsType): (FAMILY, _("Family", "Role"), "Family"), (INFORMANT, _("Informant"), "Informant"), (GODPARENT, _("Godparent"), "Godparent"), - ] + ] def __init__(self, value=None): GrampsType.__init__(self, value) diff --git a/gramps/gen/lib/eventtype.py b/gramps/gen/lib/eventtype.py index 15f3a0762d0..d8b3d1b34bc 100644 --- a/gramps/gen/lib/eventtype.py +++ b/gramps/gen/lib/eventtype.py @@ -23,15 +23,17 @@ Provide the different event types """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext + class EventType(GrampsType): """ Event types. @@ -84,6 +86,7 @@ class EventType(GrampsType): .. attribute MARR_ALT: Alternate Marriage .. attribute STILLBIRTH: Stillbirth """ + UNKNOWN = -1 CUSTOM = 0 MARRIAGE = 1 @@ -133,29 +136,52 @@ class EventType(GrampsType): STILLBIRTH = 45 # _T_ is a gramps-defined keyword -- see po/update_po.py and po/genpot.sh - def _T_(value, context=''): # enable deferred translations + def _T_(value, context=""): # enable deferred translations return "%s\x04%s" % (context, value) if context else value - _MENU = [[_T_('Life Events'), - [BIRTH, BAPTISM, DEATH, STILLBIRTH, BURIAL, CREMATION, ADOPT]], - [_T_('Family'), - [ENGAGEMENT, MARRIAGE, DIVORCE, ANNULMENT, MARR_SETTL, MARR_LIC, - MARR_CONTR, MARR_BANNS, DIV_FILING, MARR_ALT]], - [_T_('Religious'), - [CHRISTEN, ADULT_CHRISTEN, CONFIRMATION, FIRST_COMMUN, BLESS, - BAR_MITZVAH, BAS_MITZVAH, RELIGION]], - [_T_('Vocational'), - [OCCUPATION, RETIREMENT, ELECTED, MILITARY_SERV, ORDINATION]], - [_T_('Academic'), - [EDUCATION, DEGREE, GRADUATION]], - [_T_('Travel'), - [EMIGRATION, IMMIGRATION, NATURALIZATION]], - [_T_('Legal'), - [PROBATE, WILL]], - [_T_('Residence'), - [RESIDENCE, CENSUS, PROPERTY]], - [_T_('Other'), - [CAUSE_DEATH, MED_INFO, NOB_TITLE, NUM_MARRIAGES]]] + _MENU = [ + [ + _T_("Life Events"), + [BIRTH, BAPTISM, DEATH, STILLBIRTH, BURIAL, CREMATION, ADOPT], + ], + [ + _T_("Family"), + [ + ENGAGEMENT, + MARRIAGE, + DIVORCE, + ANNULMENT, + MARR_SETTL, + MARR_LIC, + MARR_CONTR, + MARR_BANNS, + DIV_FILING, + MARR_ALT, + ], + ], + [ + _T_("Religious"), + [ + CHRISTEN, + ADULT_CHRISTEN, + CONFIRMATION, + FIRST_COMMUN, + BLESS, + BAR_MITZVAH, + BAS_MITZVAH, + RELIGION, + ], + ], + [ + _T_("Vocational"), + [OCCUPATION, RETIREMENT, ELECTED, MILITARY_SERV, ORDINATION], + ], + [_T_("Academic"), [EDUCATION, DEGREE, GRADUATION]], + [_T_("Travel"), [EMIGRATION, IMMIGRATION, NATURALIZATION]], + [_T_("Legal"), [PROBATE, WILL]], + [_T_("Residence"), [RESIDENCE, CENSUS, PROPERTY]], + [_T_("Other"), [CAUSE_DEATH, MED_INFO, NOB_TITLE, NUM_MARRIAGES]], + ] _CUSTOM = CUSTOM _DEFAULT = BIRTH @@ -208,7 +234,7 @@ def _T_(value, context=''): # enable deferred translations (ANNULMENT, _("Annulment"), "Annulment"), (MARR_ALT, _("Alternate Marriage"), "Alternate Marriage"), (STILLBIRTH, _("Stillbirth"), "Stillbirth"), - ] + ] _ABBREVIATIONS = { BIRTH: _T_("b.", "birth abbreviation"), @@ -217,13 +243,13 @@ def _T_(value, context=''): # enable deferred translations UNKNOWN: _T_("unkn.", "Unknown abbreviation"), CUSTOM: _T_("cust.", "Custom abbreviation"), ADOPT: _T_("adop.", "Adopted abbreviation"), - ADULT_CHRISTEN : _T_("a.chr.", "Adult Christening abbreviation"), + ADULT_CHRISTEN: _T_("a.chr.", "Adult Christening abbreviation"), BAPTISM: _T_("bap.", "Baptism abbreviation"), - BAR_MITZVAH : _T_("bar.", "Bar Mitzvah abbreviation"), - BAS_MITZVAH : _T_("bat.", "Bat Mitzvah abbreviation"), + BAR_MITZVAH: _T_("bar.", "Bar Mitzvah abbreviation"), + BAS_MITZVAH: _T_("bat.", "Bat Mitzvah abbreviation"), BLESS: _T_("bles.", "Blessing abbreviation"), BURIAL: _T_("bur.", "Burial abbreviation"), - CAUSE_DEATH : _T_("d.cau.", "Cause Of Death abbreviation"), + CAUSE_DEATH: _T_("d.cau.", "Cause Of Death abbreviation"), CENSUS: _T_("cens.", "Census abbreviation"), CHRISTEN: _T_("chr.", "Christening abbreviation"), CONFIRMATION: _T_("conf.", "Confirmation abbreviation"), @@ -257,8 +283,8 @@ def _T_(value, context=''): # enable deferred translations DIVORCE: _T_("div.", "Divorce abbreviation"), DIV_FILING: _T_("div.f.", "Divorce Filing abbreviation"), ANNULMENT: _T_("annul.", "Annulment abbreviation"), - STILLBIRTH: _T_("still.", "Stillbirth abbreviation") - } + STILLBIRTH: _T_("still.", "Stillbirth abbreviation"), + } def __init__(self, value=None): GrampsType.__init__(self, value) @@ -296,19 +322,19 @@ def is_birth_fallback(self): Returns True if EventType is a birth fallback, False otherwise. """ - return self.value in [self.STILLBIRTH, - self.BAPTISM, - self.CHRISTEN] + return self.value in [self.STILLBIRTH, self.BAPTISM, self.CHRISTEN] def is_death_fallback(self): """ Returns True if EventType is a death fallback, False otherwise. """ - return self.value in [self.STILLBIRTH, - self.BURIAL, - self.CREMATION, - self.CAUSE_DEATH] + return self.value in [ + self.STILLBIRTH, + self.BURIAL, + self.CREMATION, + self.CAUSE_DEATH, + ] def is_marriage(self): """ @@ -321,8 +347,7 @@ def is_marriage_fallback(self): Returns True if EventType is a marriage fallback, False otherwise. """ - return self.value in [self.ENGAGEMENT, - self.MARR_ALT] + return self.value in [self.ENGAGEMENT, self.MARR_ALT] def is_divorce(self): """ @@ -335,8 +360,7 @@ def is_divorce_fallback(self): Returns True if EventType is a divorce fallback, False otherwise. """ - return self.value in [self.ANNULMENT, - self.DIV_FILING] + return self.value in [self.ANNULMENT, self.DIV_FILING] def is_relationship_event(self): """ @@ -350,7 +374,7 @@ def is_type(self, event_name): """ event_type = [tup for tup in self._DATAMAP if tup[2] == event_name] if len(event_type) > 0: - return self.value == event_type[0][0] # first one, the code + return self.value == event_type[0][0] # first one, the code return False def get_abbreviation(self, trans_text=glocale.translation.sgettext): @@ -368,7 +392,6 @@ def get_abbreviation(self, trans_text=glocale.translation.sgettext): else: abbrev = str(self) if " " in abbrev: - return ".".join([letter[0].lower() - for letter in abbrev.split()]) + "." + return ".".join([letter[0].lower() for letter in abbrev.split()]) + "." else: return abbrev[:3].lower() + "." diff --git a/gramps/gen/lib/family.py b/gramps/gen/lib/family.py index 9557dfaf0d6..ea028bc564c 100644 --- a/gramps/gen/lib/family.py +++ b/gramps/gen/lib/family.py @@ -25,19 +25,19 @@ Family object for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from warnings import warn import logging -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .primaryobj import PrimaryObject from .citationbase import CitationBase from .notebase import NoteBase @@ -50,17 +50,20 @@ from .familyreltype import FamilyRelType from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext LOG = logging.getLogger(".citation") -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Family class # -#------------------------------------------------------------------------- -class Family(CitationBase, NoteBase, MediaBase, AttributeBase, LdsOrdBase, - PrimaryObject): +# ------------------------------------------------------------------------- +class Family( + CitationBase, NoteBase, MediaBase, AttributeBase, LdsOrdBase, PrimaryObject +): """ The Family record is the Gramps in-memory representation of the relationships between people. It contains all the information @@ -116,17 +119,23 @@ def serialize(self): be considered persistent. :rtype: tuple """ - return (self.handle, self.gramps_id, self.father_handle, - self.mother_handle, - [cr.serialize() for cr in self.child_ref_list], - self.type.serialize(), - [er.serialize() for er in self.event_ref_list], - MediaBase.serialize(self), - AttributeBase.serialize(self), - LdsOrdBase.serialize(self), - CitationBase.serialize(self), - NoteBase.serialize(self), - self.change, TagBase.serialize(self), self.private) + return ( + self.handle, + self.gramps_id, + self.father_handle, + self.mother_handle, + [cr.serialize() for cr in self.child_ref_list], + self.type.serialize(), + [er.serialize() for er in self.event_ref_list], + MediaBase.serialize(self), + AttributeBase.serialize(self), + LdsOrdBase.serialize(self), + CitationBase.serialize(self), + NoteBase.serialize(self), + self.change, + TagBase.serialize(self), + self.private, + ) @classmethod def get_schema(cls): @@ -140,55 +149,68 @@ def get_schema(cls): from .ldsord import LdsOrd from .childref import ChildRef from .attribute import Attribute + return { "type": "object", "title": _("Family"), "properties": { "_class": {"enum": [cls.__name__]}, - "handle": {"type": "string", - "maxLength": 50, - "title": _("Handle")}, - "gramps_id": {"type": "string", - "title": _("Gramps ID")}, - "father_handle": {"type": ["string", "null"], - "maxLength": 50, - "title": _("Father")}, - "mother_handle": {"type": ["string", "null"], - "maxLength": 50, - "title": _("Mother")}, - "child_ref_list": {"type": "array", - "items": ChildRef.get_schema(), - "title": _("Children")}, + "handle": {"type": "string", "maxLength": 50, "title": _("Handle")}, + "gramps_id": {"type": "string", "title": _("Gramps ID")}, + "father_handle": { + "type": ["string", "null"], + "maxLength": 50, + "title": _("Father"), + }, + "mother_handle": { + "type": ["string", "null"], + "maxLength": 50, + "title": _("Mother"), + }, + "child_ref_list": { + "type": "array", + "items": ChildRef.get_schema(), + "title": _("Children"), + }, "type": FamilyRelType.get_schema(), - "event_ref_list": {"type": "array", - "items": EventRef.get_schema(), - "title": _("Events")}, - "media_list": {"type": "array", - "items": MediaRef.get_schema(), - "title": _("Media")}, - "attribute_list": {"type": "array", - "items": Attribute.get_schema(), - "title": _("Attributes")}, - "lds_ord_list": {"type": "array", - "items": LdsOrd.get_schema(), - "title": _("LDS ordinances")}, - "citation_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Citations")}, - "note_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Notes")}, - "change": {"type": "integer", - "title": _("Last changed")}, - "tag_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Tags")}, - "private": {"type": "boolean", - "title": _("Private")} - } + "event_ref_list": { + "type": "array", + "items": EventRef.get_schema(), + "title": _("Events"), + }, + "media_list": { + "type": "array", + "items": MediaRef.get_schema(), + "title": _("Media"), + }, + "attribute_list": { + "type": "array", + "items": Attribute.get_schema(), + "title": _("Attributes"), + }, + "lds_ord_list": { + "type": "array", + "items": LdsOrd.get_schema(), + "title": _("LDS ordinances"), + }, + "citation_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Citations"), + }, + "note_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Notes"), + }, + "change": {"type": "integer", "title": _("Last changed")}, + "tag_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Tags"), + }, + "private": {"type": "boolean", "title": _("Private")}, + }, } def unserialize(self, data): @@ -196,17 +218,28 @@ def unserialize(self, data): Convert the data held in a tuple created by the serialize method back into the data in a Family structure. """ - (self.handle, self.gramps_id, self.father_handle, self.mother_handle, - child_ref_list, the_type, event_ref_list, media_list, - attribute_list, lds_seal_list, citation_list, note_list, - self.change, tag_list, self.private) = data + ( + self.handle, + self.gramps_id, + self.father_handle, + self.mother_handle, + child_ref_list, + the_type, + event_ref_list, + media_list, + attribute_list, + lds_seal_list, + citation_list, + note_list, + self.change, + tag_list, + self.private, + ) = data self.type = FamilyRelType() self.type.unserialize(the_type) - self.event_ref_list = [EventRef().unserialize(er) - for er in event_ref_list] - self.child_ref_list = [ChildRef().unserialize(cr) - for cr in child_ref_list] + self.event_ref_list = [EventRef().unserialize(er) for er in event_ref_list] + self.child_ref_list = [ChildRef().unserialize(cr) for cr in child_ref_list] MediaBase.unserialize(self, media_list) AttributeBase.unserialize(self, attribute_list) CitationBase.unserialize(self, citation_list) @@ -228,12 +261,14 @@ def _has_handle_reference(self, classname, handle): this object type. :rtype: bool """ - if classname == 'Event': + if classname == "Event": return handle in [ref.ref for ref in self.event_ref_list] - elif classname == 'Person': - return handle in ([ref.ref for ref in self.child_ref_list] - + [self.father_handle, self.mother_handle]) - elif classname == 'Place': + elif classname == "Person": + return handle in ( + [ref.ref for ref in self.child_ref_list] + + [self.father_handle, self.mother_handle] + ) + elif classname == "Place": return handle in [x.place for x in self.lds_ord_list] return False @@ -246,19 +281,21 @@ def _remove_handle_references(self, classname, handle_list): :param handle_list: The list of handles to be removed. :type handle_list: str """ - if classname == 'Event': - new_list = [ref for ref in self.event_ref_list - if ref.ref not in handle_list] + if classname == "Event": + new_list = [ + ref for ref in self.event_ref_list if ref.ref not in handle_list + ] self.event_ref_list = new_list - elif classname == 'Person': - new_list = [ref for ref in self.child_ref_list - if ref.ref not in handle_list] + elif classname == "Person": + new_list = [ + ref for ref in self.child_ref_list if ref.ref not in handle_list + ] self.child_ref_list = new_list if self.father_handle in handle_list: self.father_handle = None if self.mother_handle in handle_list: self.mother_handle = None - elif classname == 'Place': + elif classname == "Place": for lds_ord in self.lds_ord_list: if lds_ord.place in handle_list: lds_ord.place = None @@ -274,7 +311,7 @@ def _replace_handle_reference(self, classname, old_handle, new_handle): :param new_handle: The handle to replace the old one with. :type new_handle: str """ - if classname == 'Event': + if classname == "Event": refs_list = [ref.ref for ref in self.event_ref_list] new_ref = None if new_handle in refs_list: @@ -292,7 +329,7 @@ def _replace_handle_reference(self, classname, old_handle, new_handle): new_ref.merge(evt_ref) self.event_ref_list.pop(idx) refs_list.pop(idx) - elif classname == 'Person': + elif classname == "Person": refs_list = [ref.ref for ref in self.child_ref_list] new_ref = None if new_handle in refs_list: @@ -314,7 +351,7 @@ def _replace_handle_reference(self, classname, old_handle, new_handle): self.father_handle = new_handle if self.mother_handle == old_handle: self.mother_handle = new_handle - elif classname == 'Place': + elif classname == "Place": for lds_ord in self.lds_ord_list: if lds_ord.place == old_handle: lds_ord.place = new_handle @@ -346,8 +383,13 @@ def get_citation_child_list(self): refer citations. :rtype: list """ - check_list = self.media_list + self.attribute_list + \ - self.lds_ord_list + self.child_ref_list + self.event_ref_list + check_list = ( + self.media_list + + self.attribute_list + + self.lds_ord_list + + self.child_ref_list + + self.event_ref_list + ) return check_list def get_note_child_list(self): @@ -358,9 +400,13 @@ def get_note_child_list(self): refer notes. :rtype: list """ - check_list = self.media_list + self.attribute_list + \ - self.lds_ord_list + self.child_ref_list + \ - self.event_ref_list + check_list = ( + self.media_list + + self.attribute_list + + self.lds_ord_list + + self.child_ref_list + + self.event_ref_list + ) return check_list def get_referenced_handles(self): @@ -371,12 +417,17 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - ret = self.get_referenced_note_handles() + \ - self.get_referenced_citation_handles() - ret += [('Person', handle) for handle - in ([ref.ref for ref in self.child_ref_list] + - [self.father_handle, self.mother_handle]) - if handle] + ret = ( + self.get_referenced_note_handles() + self.get_referenced_citation_handles() + ) + ret += [ + ("Person", handle) + for handle in ( + [ref.ref for ref in self.child_ref_list] + + [self.father_handle, self.mother_handle] + ) + if handle + ] ret += self.get_referenced_tag_handles() return ret @@ -388,8 +439,13 @@ def get_handle_referents(self): :returns: Returns the list of objects referencing primary objects. :rtype: list """ - return self.media_list + self.attribute_list + \ - self.lds_ord_list + self.child_ref_list + self.event_ref_list + return ( + self.media_list + + self.attribute_list + + self.lds_ord_list + + self.child_ref_list + + self.event_ref_list + ) def merge(self, acquisition): """ @@ -524,8 +580,7 @@ def remove_child_ref(self, child_ref): """ if not isinstance(child_ref, ChildRef): raise ValueError("expecting ChildRef instance") - new_list = [ref for ref in self.child_ref_list - if ref.ref != child_ref.ref] + new_list = [ref for ref in self.child_ref_list if ref.ref != child_ref.ref] self.child_ref_list = new_list def remove_child_handle(self, child_handle): @@ -539,8 +594,7 @@ def remove_child_handle(self, child_handle): in the list. :rtype: bool """ - new_list = [ref for ref in self.child_ref_list - if ref.ref != child_handle] + new_list = [ref for ref in self.child_ref_list if ref.ref != child_handle] self.child_ref_list = new_list def get_child_ref_list(self): @@ -601,8 +655,7 @@ def add_event_ref(self, event_ref): self.event_ref_list.append(event_ref) def get_event_list(self): - warn("Use get_event_ref_list instead of get_event_list", - DeprecationWarning, 2) + warn("Use get_event_ref_list instead of get_event_list", DeprecationWarning, 2) # Wrapper for old API # remove when transitition done. event_handle_list = [] diff --git a/gramps/gen/lib/familyreltype.py b/gramps/gen/lib/familyreltype.py index 0e6192b1f2e..b40a3261385 100644 --- a/gramps/gen/lib/familyreltype.py +++ b/gramps/gen/lib/familyreltype.py @@ -22,18 +22,19 @@ Provide the different family reference types. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..config import config from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -class FamilyRelType(GrampsType): +class FamilyRelType(GrampsType): MARRIED = 0 UNMARRIED = 1 CIVIL_UNION = 2 @@ -49,7 +50,7 @@ class FamilyRelType(GrampsType): (CIVIL_UNION, _("Civil Union"), "Civil Union"), (UNKNOWN, _("Unknown"), "Unknown"), (CUSTOM, _("Custom"), "Custom"), - ] + ] def __init__(self, value=None): if value is None: diff --git a/gramps/gen/lib/gcalendar.py b/gramps/gen/lib/gcalendar.py index bb95f9f7fa6..75c2fb538a7 100644 --- a/gramps/gen/lib/gcalendar.py +++ b/gramps/gen/lib/gcalendar.py @@ -22,18 +22,18 @@ Provide calendar to sdn (serial date number) conversion. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import math -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Constants # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- _GRG_SDN_OFFSET = 32045 _GRG_DAYS_PER_5_MONTHS = 153 _GRG_DAYS_PER_4_YEARS = 1461 @@ -60,14 +60,48 @@ _HBR_FRIDAY = 5 _HBR_MONTHS_PER_YEAR = [ - 12, 12, 13, 12, 12, 13, 12, 13, 12, 12, - 13, 12, 12, 13, 12, 12, 13, 12, 13 - ] + 12, + 12, + 13, + 12, + 12, + 13, + 12, + 13, + 12, + 12, + 13, + 12, + 12, + 13, + 12, + 12, + 13, + 12, + 13, +] _HBR_YEAR_OFFSET = [ - 0, 12, 24, 37, 49, 61, 74, 86, 99, 111, 123, - 136, 148, 160, 173, 185, 197, 210, 222 - ] + 0, + 12, + 24, + 37, + 49, + 61, + 74, + 86, + 99, + 111, + 123, + 136, + 148, + 160, + 173, + 185, + 197, + 210, + 222, +] _FR_SDN_OFFSET = 2375474 _FR_DAYS_PER_4_YEARS = 1461 @@ -75,19 +109,23 @@ _PRS_EPOCH = 1948320.5 _ISM_EPOCH = 1948439.5 -def _tishri1(metonic_year, molad_day, molad_halakim): +def _tishri1(metonic_year, molad_day, molad_halakim): tishri1 = molad_day dow = tishri1 % 7 leap_year = metonic_year in [2, 5, 7, 10, 13, 16, 18] last_was_leap_year = metonic_year in [3, 6, 8, 11, 14, 17, 0] # Apply rules 2, 3 and 4. - if ((molad_halakim >= _HBR_NOON) or - ((not leap_year) and dow == _HBR_TUESDAY and - molad_halakim >= _HBR_AM3_11_20) or - (last_was_leap_year and dow == _HBR_MONDAY - and molad_halakim >= _HBR_AM9_32_43)): + if ( + (molad_halakim >= _HBR_NOON) + or ((not leap_year) and dow == _HBR_TUESDAY and molad_halakim >= _HBR_AM3_11_20) + or ( + last_was_leap_year + and dow == _HBR_MONDAY + and molad_halakim >= _HBR_AM9_32_43 + ) + ): tishri1 += 1 dow += 1 if dow == 7: @@ -100,6 +138,7 @@ def _tishri1(metonic_year, molad_day, molad_halakim): return tishri1 + def _tishri_molad(input_day): """ Estimate the metonic cycle number. @@ -132,13 +171,15 @@ def _tishri_molad(input_day): if molad_day > input_day - 74: break - molad_halakim += (_HBR_HALAKIM_PER_LUNAR_CYCLE - * _HBR_MONTHS_PER_YEAR[metonic_year]) + molad_halakim += ( + _HBR_HALAKIM_PER_LUNAR_CYCLE * _HBR_MONTHS_PER_YEAR[metonic_year] + ) molad_day += molad_halakim // _HBR_HALAKIM_PER_DAY molad_halakim = molad_halakim % _HBR_HALAKIM_PER_DAY return (metonic_cycle, metonic_year, molad_day, molad_halakim) + def _molad_of_metonic_cycle(metonic_cycle): """ Start with the time of the first molad after creation. @@ -152,7 +193,7 @@ def _molad_of_metonic_cycle(metonic_cycle): r1 = r1 + (metonic_cycle * (_HBR_HALAKIM_PER_METONIC_CYCLE & 0xFFFF)) r2 = r1 >> 16 - r2 = r2 + (metonic_cycle * ((_HBR_HALAKIM_PER_METONIC_CYCLE >> 16)&0xFFFF)) + r2 = r2 + (metonic_cycle * ((_HBR_HALAKIM_PER_METONIC_CYCLE >> 16) & 0xFFFF)) # Calculate r2r1 / HALAKIM_PER_DAY. The remainder will be in r1, the # upper 16 bits of the quotient will be in d2 and the lower 16 bits @@ -169,6 +210,7 @@ def _molad_of_metonic_cycle(metonic_cycle): return (molad_day, molad_halakim) + def _start_of_year(year): """ Calculate the start of the year. @@ -177,8 +219,9 @@ def _start_of_year(year): metonic_year = (year - 1) % 19 (molad_day, molad_halakim) = _molad_of_metonic_cycle(metonic_cycle) - molad_halakim = molad_halakim + (_HBR_HALAKIM_PER_LUNAR_CYCLE - * _HBR_YEAR_OFFSET[metonic_year]) + molad_halakim = molad_halakim + ( + _HBR_HALAKIM_PER_LUNAR_CYCLE * _HBR_YEAR_OFFSET[metonic_year] + ) molad_day = molad_day + (molad_halakim // _HBR_HALAKIM_PER_DAY) molad_halakim = molad_halakim % _HBR_HALAKIM_PER_DAY @@ -186,13 +229,19 @@ def _start_of_year(year): return (metonic_cycle, metonic_year, molad_day, molad_halakim, ptishri1) + def hebrew_sdn(year, month, day): """Convert a Jewish calendar date to an SDN number.""" if month == 1 or month == 2: # It is Tishri or Heshvan - don't need the year length. - (metonic_cycle, metonic_year, - molad_day, molad_halakim, tishri1) = _start_of_year(year) + ( + metonic_cycle, + metonic_year, + molad_day, + molad_halakim, + tishri1, + ) = _start_of_year(year) if month == 1: sdn = tishri1 + day - 1 else: @@ -201,16 +250,21 @@ def hebrew_sdn(year, month, day): # It is Kislev - must find the year length. # Find the start of the year. - (metonic_cycle, metonic_year, - molad_day, molad_halakim, tishri1) = _start_of_year(year) + ( + metonic_cycle, + metonic_year, + molad_day, + molad_halakim, + tishri1, + ) = _start_of_year(year) # Find the end of the year. - molad_halakim = molad_halakim + (_HBR_HALAKIM_PER_LUNAR_CYCLE - *_HBR_MONTHS_PER_YEAR[metonic_year]) + molad_halakim = molad_halakim + ( + _HBR_HALAKIM_PER_LUNAR_CYCLE * _HBR_MONTHS_PER_YEAR[metonic_year] + ) molad_day = molad_day + (molad_halakim // _HBR_HALAKIM_PER_DAY) molad_halakim = molad_halakim % _HBR_HALAKIM_PER_DAY - tishri1_after = _tishri1((metonic_year + 1) - % 19, molad_day, molad_halakim) + tishri1_after = _tishri1((metonic_year + 1) % 19, molad_day, molad_halakim) year_length = tishri1_after - tishri1 @@ -221,8 +275,13 @@ def hebrew_sdn(year, month, day): elif month == 4 or month == 5 or month == 6: # It is Tevet, Shevat or Adar I - don't need the year length - (metonic_cycle, metonic_year, - molad_day, molad_halakim, tishri1_after) = _start_of_year(year+1) + ( + metonic_cycle, + metonic_year, + molad_day, + molad_halakim, + tishri1_after, + ) = _start_of_year(year + 1) if _HBR_MONTHS_PER_YEAR[(year - 1) % 19] == 12: length_of_adar_1and2 = 29 @@ -237,8 +296,13 @@ def hebrew_sdn(year, month, day): sdn = tishri1_after + day - length_of_adar_1and2 - 178 else: # It is Adar II or later - don't need the year length. - (metonic_cycle, metonic_year, - molad_day, molad_halakim, tishri1_after) = _start_of_year(year+1) + ( + metonic_cycle, + metonic_year, + molad_day, + molad_halakim, + tishri1_after, + ) = _start_of_year(year + 1) if month == 7: sdn = tishri1_after + day - 207 @@ -258,6 +322,7 @@ def hebrew_sdn(year, month, day): return 0 return sdn + _HBR_SDN_OFFSET + def hebrew_ymd(sdn): """Convert an SDN number to a Hebrew calendar date.""" @@ -283,8 +348,7 @@ def hebrew_ymd(sdn): # We need the length of the year to figure this out, so find # Tishri 1 of the next year. - halakim += (_HBR_HALAKIM_PER_LUNAR_CYCLE - * _HBR_MONTHS_PER_YEAR[metonic_year]) + halakim += _HBR_HALAKIM_PER_LUNAR_CYCLE * _HBR_MONTHS_PER_YEAR[metonic_year] day1 += halakim // _HBR_HALAKIM_PER_DAY halakim = halakim % _HBR_HALAKIM_PER_DAY tishri1_after = _tishri1((metonic_year + 1) % 19, day1, halakim) @@ -343,7 +407,7 @@ def hebrew_ymd(sdn): # We need the length of the year to figure this out, so find # Tishri 1 of this year tishri1_after = tishri1 - (metonic_cycle, metonic_year, day1, halakim) = _tishri_molad(day1-365) + (metonic_cycle, metonic_year, day1, halakim) = _tishri_molad(day1 - 365) tishri1 = _tishri1(metonic_year, day1, halakim) year_length = tishri1_after - tishri1 @@ -365,6 +429,7 @@ def hebrew_ymd(sdn): # It has to be Kislev return (year, 3, day) + def julian_sdn(year, month, day): """Convert a Julian calendar date to an SDN number.""" @@ -380,9 +445,13 @@ def julian_sdn(year, month, day): month += 9 year -= 1 - return (year * _JLN_DAYS_PER_4_YEARS) // 4 \ - + (month * _JLN_DAYS_PER_5_MONTHS + 2) // 5 \ - + day - _JLN_SDN_OFFSET + return ( + (year * _JLN_DAYS_PER_4_YEARS) // 4 + + (month * _JLN_DAYS_PER_5_MONTHS + 2) // 5 + + day + - _JLN_SDN_OFFSET + ) + def julian_ymd(sdn): """Convert an SDN number to a Julian date.""" @@ -411,6 +480,7 @@ def julian_ymd(sdn): return (year, month, day) + def gregorian_sdn(year, month, day): """Convert a gregorian date to an SDN number.""" if year < 0: @@ -425,11 +495,14 @@ def gregorian_sdn(year, month, day): month += 9 year -= 1 - return(((year // 100) * _GRG_DAYS_PER_400_YEARS) // 4 - + ((year % 100) * _GRG_DAYS_PER_4_YEARS) // 4 - + (month * _GRG_DAYS_PER_5_MONTHS + 2) // 5 - + day - - _GRG_SDN_OFFSET) + return ( + ((year // 100) * _GRG_DAYS_PER_400_YEARS) // 4 + + ((year % 100) * _GRG_DAYS_PER_4_YEARS) // 4 + + (month * _GRG_DAYS_PER_5_MONTHS + 2) // 5 + + day + - _GRG_SDN_OFFSET + ) + def gregorian_ymd(sdn): """Convert an SDN number to a gregorian date.""" @@ -461,29 +534,36 @@ def gregorian_ymd(sdn): year = year - 1 return (year, month, day) + def _check_republican_period(sdn, restrict_period): # French Republican calendar wasn't in use before 22.9.1792 or after 1.1.1806 if restrict_period and (sdn < 2375840 or sdn > 2380688): raise ValueError("Outside of the French Republican period") + def french_sdn(year, month, day, restrict_period=False): """Convert a French Republican Calendar date to an SDN number.""" - sdn = (year*_FR_DAYS_PER_4_YEARS) // 4 + \ - (month-1)*_FR_DAYS_PER_MONTH + \ - day + _FR_SDN_OFFSET + sdn = ( + (year * _FR_DAYS_PER_4_YEARS) // 4 + + (month - 1) * _FR_DAYS_PER_MONTH + + day + + _FR_SDN_OFFSET + ) _check_republican_period(sdn, restrict_period) return sdn + def french_ymd(sdn, restrict_period=False): """Convert an SDN number to a French Republican Calendar date.""" _check_republican_period(sdn, restrict_period) - temp = (sdn-_FR_SDN_OFFSET)*4 - 1 + temp = (sdn - _FR_SDN_OFFSET) * 4 - 1 year = temp // _FR_DAYS_PER_4_YEARS day_of_year = (temp % _FR_DAYS_PER_4_YEARS) // 4 month = (day_of_year // _FR_DAYS_PER_MONTH) + 1 day = (day_of_year % _FR_DAYS_PER_MONTH) + 1 return (year, month, day) + def persian_sdn(year, month, day): """Convert a Persian date to an SDN number.""" if year >= 0: @@ -503,26 +583,27 @@ def persian_sdn(year, month, day): return int(math.ceil(v1 + v2 + v3 + v4 + _PRS_EPOCH - 1)) + def persian_ymd(sdn): """Convert an SDN number to a Persian calendar date.""" # The following is commented out and is related to bug 12576 # sdn = math.floor(sdn) + 0.5 # float - depoch = sdn - 2121446 #float - cycle = math.floor(depoch / 1029983) #int - cyear = depoch % 1029983 #int + depoch = sdn - 2121446 # float + cycle = math.floor(depoch / 1029983) # int + cyear = depoch % 1029983 # int if cyear == 1029982: ycycle = 2820 else: - aux1 = cyear // 366 #int - aux2 = cyear % 366 #int - ycycle = (((2134*aux1)+(2816*aux2)+2815) // 1028522) + aux1 + 1 + aux1 = cyear // 366 # int + aux2 = cyear % 366 # int + ycycle = (((2134 * aux1) + (2816 * aux2) + 2815) // 1028522) + aux1 + 1 year = ycycle + (2820 * cycle) + 474 if year <= 0: year = year - 1 - yday = sdn - persian_sdn(year, 1, 1) + 1 #float ! + yday = sdn - persian_sdn(year, 1, 1) + 1 # float ! if yday < 186: month = math.ceil(yday / 31) else: @@ -530,41 +611,45 @@ def persian_ymd(sdn): day = (sdn - persian_sdn(year, month, 1)) + 1 return (int(year), int(month), int(day)) + def islamic_sdn(year, month, day): """Convert an Islamic date to an SDN number.""" v1 = math.ceil(29.5 * (month - 1)) v2 = (year - 1) * 354 - v3 = math.floor((3 + (11 *year)) // 30) + v3 = math.floor((3 + (11 * year)) // 30) return int(math.ceil((day + v1 + v2 + v3 + _ISM_EPOCH) - 1)) + def islamic_ymd(sdn): """Convert an SDN number to an Islamic calendar date.""" sdn = math.floor(sdn) + 0.5 - year = int(math.floor(((30*(sdn-_ISM_EPOCH))+10646) / 10631)) - month = int(min(12, math.ceil((sdn-(29+islamic_sdn(year, 1, 1))) / 29.5) + 1)) + year = int(math.floor(((30 * (sdn - _ISM_EPOCH)) + 10646) / 10631)) + month = int(min(12, math.ceil((sdn - (29 + islamic_sdn(year, 1, 1))) / 29.5) + 1)) day = int((sdn - islamic_sdn(year, month, 1)) + 1) return (year, month, day) + def swedish_sdn(year, month, day): """Convert a Swedish date to an SDN number.""" datum = (year, month, day) # Swedish Calendar if (1700, 3, 1) <= datum <= (1712, 2, 30): - return julian_sdn(year, month, day) -1 + return julian_sdn(year, month, day) - 1 # Gregorian Calendar (1753-03-01) elif (1753, 3, 1) <= datum: return gregorian_sdn(year, month, day) else: return julian_sdn(year, month, day) + def swedish_ymd(sdn): """Convert an SDN number to a Swedish calendar date.""" if sdn == 2346425: return (1712, 2, 30) # Swedish Calendar elif 2342042 <= sdn < 2346425: - return julian_ymd(sdn+1) + return julian_ymd(sdn + 1) # Gregorian Calendar (1753-03-01) elif sdn >= 2361390: return gregorian_ymd(sdn) diff --git a/gramps/gen/lib/genderstats.py b/gramps/gen/lib/genderstats.py index 271c922e8c7..74412b90393 100644 --- a/gramps/gen/lib/genderstats.py +++ b/gramps/gen/lib/genderstats.py @@ -23,18 +23,19 @@ Gender statistics kept in Gramps database. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .person import Person -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class GenderStats: """ Class for keeping track of statistics related to Given Name vs. Gender. @@ -42,6 +43,7 @@ class GenderStats: This allows the tracking of the liklihood of a person's given name indicating the gender of the person. """ + def __init__(self, stats=None): if stats is None: self.stats = {} @@ -128,9 +130,11 @@ def guess_gender(self, name): return Person.UNKNOWN + def _get_key(person): name = person.get_primary_name().get_first_name() return _get_key_from_name(name) + def _get_key_from_name(name): - return name.split(' ')[0].replace('?', '') + return name.split(" ")[0].replace("?", "") diff --git a/gramps/gen/lib/grampstype.py b/gramps/gen/lib/grampstype.py index f27cf65d4b7..bbd1944ed92 100644 --- a/gramps/gen/lib/grampstype.py +++ b/gramps/gen/lib/grampstype.py @@ -23,29 +23,31 @@ Base type for all gramps types. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -_UNKNOWN = _('Unknown') +_UNKNOWN = _("Unknown") + -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # GrampsTypeMeta class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class GrampsTypeMeta(type): """ Metaclass for :class:`~.grampstype.GrampsType`. Create the class-specific integer/string maps. """ - def __init__(cls, name, bases, namespace): + def __init__(cls, name, bases, namespace): # Helper function to create the maps def init_map(data, key_col, data_col, blacklist=None): """ @@ -53,8 +55,13 @@ def init_map(data, key_col, data_col, blacklist=None): columns. """ if blacklist: - return dict([(item[key_col], item[data_col]) - for item in data if item[0] not in blacklist]) + return dict( + [ + (item[key_col], item[data_col]) + for item in data + if item[0] not in blacklist + ] + ) else: return dict([(item[key_col], item[data_col]) for item in data]) @@ -62,18 +69,18 @@ def init_map(data, key_col, data_col, blacklist=None): type.__init__(cls, name, bases, namespace) # Build the integer/string maps - if hasattr(cls, '_DATAMAP'): + if hasattr(cls, "_DATAMAP"): cls._I2SMAP = init_map(cls._DATAMAP, 0, 1, cls._BLACKLIST) cls._S2IMAP = init_map(cls._DATAMAP, 1, 0, cls._BLACKLIST) cls._I2EMAP = init_map(cls._DATAMAP, 0, 2, cls._BLACKLIST) cls._E2IMAP = init_map(cls._DATAMAP, 2, 0, cls._BLACKLIST) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # GrampsType class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class GrampsType(object, metaclass=GrampsTypeMeta): """Base class for all Gramps object types. @@ -97,6 +104,7 @@ class GrampsType(object, metaclass=GrampsTypeMeta): :attribute value: (int) Returns or sets integer value :attribute string: (str) Returns or sets string value """ + (POS_VALUE, POS_STRING) = list(range(2)) _CUSTOM = 0 @@ -109,17 +117,17 @@ class GrampsType(object, metaclass=GrampsTypeMeta): _I2EMAP = {} _E2IMAP = {} _MENU = [] - __slots__ = ('__value', '__string') + __slots__ = ("__value", "__string") def __getstate__(self): - return {'__value': self.__value, '__string': self.__string} + return {"__value": self.__value, "__string": self.__string} def __setstate__(self, dict_): - self.__value = dict_['__value'] + self.__value = dict_["__value"] if self.__value == self._CUSTOM: - self.__string = dict_['__string'] + self.__string = dict_["__string"] else: - self.__string = '' + self.__string = "" def __init__(self, value=None): """ @@ -127,13 +135,13 @@ def __init__(self, value=None): states. """ self.__value = self._DEFAULT - self.__string = '' + self.__string = "" if value is not None: self.set(value) def __set_tuple(self, value): "Set the value/string properties from a tuple." - val, strg = self._DEFAULT, '' + val, strg = self._DEFAULT, "" if value: val = value[0] if len(value) > 1 and val == self._CUSTOM: @@ -144,7 +152,7 @@ def __set_tuple(self, value): def __set_int(self, value): "Set the value/string properties from an integer." self.__value = value - self.__string = '' + self.__string = "" def __set_instance(self, value): "Set the value/string properties from another grampstype." @@ -152,7 +160,7 @@ def __set_instance(self, value): if self.__value == self._CUSTOM: self.__string = value.string else: - self.__string = '' + self.__string = "" def __set_str(self, value): "Set the value/string properties from a string." @@ -160,7 +168,7 @@ def __set_str(self, value): if self.__value == self._CUSTOM: self.__string = value else: - self.__string = '' + self.__string = "" def set(self, value): "Set the value/string properties from the passed in value." @@ -174,7 +182,7 @@ def set(self, value): self.__set_str(value) else: self.__value = self._DEFAULT - self.__string = '' + self.__string = "" def set_from_xml_str(self, value): """ @@ -183,9 +191,9 @@ def set_from_xml_str(self, value): """ if value in self._E2IMAP: self.__value = self._E2IMAP[value] - self.__string = '' + self.__string = "" if self.__value == self._CUSTOM: - #if the custom event is actually 'Custom' then we should save it + # if the custom event is actually 'Custom' then we should save it # with that string value. That is, 'Custom' is in _E2IMAP self.__string = value else: @@ -205,7 +213,7 @@ def xml_str(self): return _UNKNOWN def serialize(self): - """Convert the object to a serialized tuple of data. """ + """Convert the object to a serialized tuple of data.""" return (self.__value, self.__string) @classmethod @@ -221,16 +229,15 @@ def get_schema(cls): "title": _("Type"), "properties": { "_class": {"enum": [cls.__name__]}, - "string": {"type": "string", - "title": _("Type")}, - } + "string": {"type": "string", "title": _("Type")}, + }, } def unserialize(self, data): """Convert a serialized tuple of data to an object.""" self.__value, self.__string = data if self.__value != self._CUSTOM: - self.__string = '' + self.__string = "" return self def __str__(self): @@ -247,13 +254,19 @@ def get_map(self): def get_standard_names(self): """Return the list of localized names for all standard types.""" - return [s for (i, s) in list(self._I2SMAP.items()) - if (i != self._CUSTOM) and s.strip()] + return [ + s + for (i, s) in list(self._I2SMAP.items()) + if (i != self._CUSTOM) and s.strip() + ] def get_standard_xml(self): """Return the list of XML (english) names for all standard types.""" - return [s for (i, s) in list(self._I2EMAP.items()) - if (i != self._CUSTOM) and s.strip()] + return [ + s + for (i, s) in list(self._I2EMAP.items()) + if (i != self._CUSTOM) and s.strip() + ] def is_custom(self): return self.__value == self._CUSTOM diff --git a/gramps/gen/lib/ldsord.py b/gramps/gen/lib/ldsord.py index e5c8fec0726..0c3a1e50f68 100644 --- a/gramps/gen/lib/ldsord.py +++ b/gramps/gen/lib/ldsord.py @@ -26,18 +26,18 @@ LDS Ordinance class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from warnings import warn -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .citationbase import CitationBase from .notebase import NoteBase @@ -46,15 +46,16 @@ from .privacybase import PrivacyBase from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # LDS Ordinance class # -#------------------------------------------------------------------------- -class LdsOrd(SecondaryObject, CitationBase, NoteBase, - DateBase, PlaceBase, PrivacyBase): +# ------------------------------------------------------------------------- +class LdsOrd(SecondaryObject, CitationBase, NoteBase, DateBase, PlaceBase, PrivacyBase): """ Class that contains information about LDS Ordinances. @@ -72,7 +73,6 @@ class LdsOrd(SecondaryObject, CitationBase, NoteBase, DEFAULT_TYPE = BAPTISM - STATUS_NONE = 0 STATUS_BIC = 1 STATUS_CANCELED = 2 @@ -90,13 +90,12 @@ class LdsOrd(SecondaryObject, CitationBase, NoteBase, DEFAULT_STATUS = STATUS_NONE - _TYPE_MAP = [ - (BAPTISM, _('Baptism'), 'baptism'), - (ENDOWMENT, _('Endowment'), 'endowment'), - (CONFIRMATION, _('Confirmation'), 'confirmation'), - (SEAL_TO_PARENTS, _('Sealed to Parents'), 'sealed_to_parents'), - (SEAL_TO_SPOUSE, _('Sealed to Spouse'), 'sealed_to_spouse'), + (BAPTISM, _("Baptism"), "baptism"), + (ENDOWMENT, _("Endowment"), "endowment"), + (CONFIRMATION, _("Confirmation"), "confirmation"), + (SEAL_TO_PARENTS, _("Sealed to Parents"), "sealed_to_parents"), + (SEAL_TO_SPOUSE, _("Sealed to Spouse"), "sealed_to_spouse"), ] _STATUS_MAP = [ @@ -114,7 +113,7 @@ class LdsOrd(SecondaryObject, CitationBase, NoteBase, (STATUS_STILLBORN, _("Stillborn"), "Stillborn"), (STATUS_SUBMITTED, _("Submitted"), "Submitted"), (STATUS_UNCLEARED, _("Uncleared"), "Uncleared"), - ] + ] def __init__(self, source=None): """Create a LDS Ordinance instance.""" @@ -139,18 +138,33 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (CitationBase.serialize(self), - NoteBase.serialize(self), - DateBase.serialize(self), - self.type, self.place, - self.famc, self.temple, self.status, self.private) + return ( + CitationBase.serialize(self), + NoteBase.serialize(self), + DateBase.serialize(self), + self.type, + self.place, + self.famc, + self.temple, + self.status, + self.private, + ) def unserialize(self, data): """ Convert a serialized tuple of data to an object. """ - (citation_list, note_list, date, self.type, self.place, - self.famc, self.temple, self.status, self.private) = data + ( + citation_list, + note_list, + date, + self.type, + self.place, + self.famc, + self.temple, + self.status, + self.private, + ) = data CitationBase.unserialize(self, citation_list) NoteBase.unserialize(self, note_list) DateBase.unserialize(self, date) @@ -165,34 +179,33 @@ def get_schema(cls): :rtype: dict """ from .date import Date + return { "type": "object", "title": _("LDS Ordinance"), "properties": { "_class": {"enum": [cls.__name__]}, - "citation_list": {"type": "array", - "title": _("Citations"), - "items": {"type": "string", - "maxLength": 50}}, - "note_list": {"type": "array", - "title": _("Notes"), - "items": {"type": "string", - "maxLength": 50}}, - "date": {"oneOf": [{"type": "null"}, Date.get_schema()], - "title": _("Date")}, - "type": {"type": "integer", - "title": _("Type")}, - "place": {"type": "string", - "title": _("Place")}, - "famc": {"type": ["null", "string"], - "title": _("Family")}, - "temple": {"type": "string", - "title": _("Temple")}, - "status": {"type": "integer", - "title": _("Status")}, - "private": {"type": "boolean", - "title": _("Private")} - } + "citation_list": { + "type": "array", + "title": _("Citations"), + "items": {"type": "string", "maxLength": 50}, + }, + "note_list": { + "type": "array", + "title": _("Notes"), + "items": {"type": "string", "maxLength": 50}, + }, + "date": { + "oneOf": [{"type": "null"}, Date.get_schema()], + "title": _("Date"), + }, + "type": {"type": "integer", "title": _("Type")}, + "place": {"type": "string", "title": _("Place")}, + "famc": {"type": ["null", "string"], "title": _("Family")}, + "temple": {"type": "string", "title": _("Temple")}, + "status": {"type": "integer", "title": _("Status")}, + "private": {"type": "boolean", "title": _("Private")}, + }, } def get_text_data_list(self): @@ -203,7 +216,7 @@ def get_text_data_list(self): :rtype: list """ return [self.temple] - #return [self.temple,self.get_date()] + # return [self.temple,self.get_date()] def get_text_data_child_list(self): """ @@ -232,12 +245,13 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - ret = self.get_referenced_note_handles() + \ - self.get_referenced_citation_handles() + ret = ( + self.get_referenced_note_handles() + self.get_referenced_citation_handles() + ) if self.place: - ret += [('Place', self.place)] + ret += [("Place", self.place)] if self.famc: - ret += [('Family', self.famc)] + ret += [("Family", self.famc)] return ret def get_handle_referents(self): @@ -260,11 +274,13 @@ def is_equivalent(self, other): :returns: Constant indicating degree of equivalence. :rtype: int """ - if self.type != other.type or \ - self.get_date_object() != other.get_date_object() or \ - self.temple != other.temple or \ - self.status != other.status or \ - self.famc != other.famc: + if ( + self.type != other.type + or self.get_date_object() != other.get_date_object() + or self.temple != other.temple + or self.status != other.status + or self.famc != other.famc + ): return DIFFERENT else: if self.is_equal(other): @@ -333,11 +349,13 @@ def get_temple(self): def is_empty(self): """Return 1 if the ordinance is actually empty.""" - if (self.famc or - (self.date and not self.date.is_empty()) or - self.temple or - self.status or - self.place): + if ( + self.famc + or (self.date and not self.date.is_empty()) + or self.temple + or self.status + or self.place + ): return False else: return True diff --git a/gramps/gen/lib/ldsordbase.py b/gramps/gen/lib/ldsordbase.py index b24abac0f19..9d62a0c6736 100644 --- a/gramps/gen/lib/ldsordbase.py +++ b/gramps/gen/lib/ldsordbase.py @@ -23,19 +23,20 @@ LdsOrdBase class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .ldsord import LdsOrd from .const import IDENTICAL, EQUAL -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # LdsOrdBase classes # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class LdsOrdBase: """ Base class for lds_ord-aware objects. @@ -53,8 +54,7 @@ def __init__(self, source=None): """ if source: - self.lds_ord_list = [LdsOrd(lds_ord) - for lds_ord in source.lds_ord_list] + self.lds_ord_list = [LdsOrd(lds_ord) for lds_ord in source.lds_ord_list] else: self.lds_ord_list = [] diff --git a/gramps/gen/lib/location.py b/gramps/gen/lib/location.py index d7341fdb8c1..d462c1f4109 100644 --- a/gramps/gen/lib/location.py +++ b/gramps/gen/lib/location.py @@ -25,22 +25,24 @@ Location class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .locationbase import LocationBase from .const import IDENTICAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Location class for Places # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Location(SecondaryObject, LocationBase): """ Provide information about a place. @@ -87,25 +89,16 @@ def get_schema(cls): "title": _("Location"), "properties": { "_class": {"enum": [cls.__name__]}, - "street": {"type": "string", - "title": _("Street")}, - "locality": {"type": "string", - "title": _("Locality")}, - "city": {"type": "string", - "title": _("City")}, - "county": {"type": "string", - "title": _("County")}, - "state": {"type": "string", - "title": _("State")}, - "country": {"type": "string", - "title": _("Country")}, - "postal": {"type": "string", - "title": _("Postal Code")}, - "phone": {"type": "string", - "title": _("Phone")}, - "parish": {"type": "string", - "title": _("Parish")} - } + "street": {"type": "string", "title": _("Street")}, + "locality": {"type": "string", "title": _("Locality")}, + "city": {"type": "string", "title": _("City")}, + "county": {"type": "string", "title": _("County")}, + "state": {"type": "string", "title": _("State")}, + "country": {"type": "string", "title": _("Country")}, + "postal": {"type": "string", "title": _("Postal Code")}, + "phone": {"type": "string", "title": _("Phone")}, + "parish": {"type": "string", "title": _("Parish")}, + }, } def get_text_data_list(self): @@ -143,9 +136,16 @@ def merge(self, acquisition): pass def is_empty(self): - return not self.street and not self.locality and not self.city and \ - not self.county and not self.state and not self.country and \ - not self.postal and not self.phone + return ( + not self.street + and not self.locality + and not self.city + and not self.county + and not self.state + and not self.country + and not self.postal + and not self.phone + ) def set_parish(self, data): """Set the religious parish name.""" diff --git a/gramps/gen/lib/locationbase.py b/gramps/gen/lib/locationbase.py index 304e24df082..b10d4d42d10 100644 --- a/gramps/gen/lib/locationbase.py +++ b/gramps/gen/lib/locationbase.py @@ -23,11 +23,12 @@ LocationBase class for Gramps. """ -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # LocationBase class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class LocationBase: """ Base class for all things Address. @@ -61,15 +62,31 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (self.street, self.locality, self.city, self.county, self.state, - self.country, self.postal, self.phone) + return ( + self.street, + self.locality, + self.city, + self.county, + self.state, + self.country, + self.postal, + self.phone, + ) def unserialize(self, data): """ Convert a serialized tuple of data to an object. """ - (self.street, self.locality, self.city, self.county, self.state, - self.country, self.postal, self.phone) = data + ( + self.street, + self.locality, + self.city, + self.county, + self.state, + self.country, + self.postal, + self.phone, + ) = data return self def get_text_data_list(self): @@ -79,8 +96,16 @@ def get_text_data_list(self): :returns: Returns the list of all textual attributes of the object. :rtype: list """ - return [self.street, self.locality, self.city, self.county, - self.state, self.country, self.postal, self.phone] + return [ + self.street, + self.locality, + self.city, + self.county, + self.state, + self.country, + self.postal, + self.phone, + ] def set_street(self, val): """Set the street portion of the Location.""" diff --git a/gramps/gen/lib/markertype.py b/gramps/gen/lib/markertype.py index bb11824cc16..e0e31e7a686 100644 --- a/gramps/gen/lib/markertype.py +++ b/gramps/gen/lib/markertype.py @@ -25,15 +25,17 @@ when loading old database files. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext + class MarkerType(GrampsType): """ Class for handling data markers. @@ -52,7 +54,7 @@ class MarkerType(GrampsType): (CUSTOM, _("Custom"), "Custom"), (COMPLETE, _("Complete"), "Complete"), (TODO_TYPE, _("ToDo"), "ToDo"), - ] + ] def __init__(self, value=None): GrampsType.__init__(self, value) diff --git a/gramps/gen/lib/media.py b/gramps/gen/lib/media.py index 4040ca17c7f..d347a928ad0 100644 --- a/gramps/gen/lib/media.py +++ b/gramps/gen/lib/media.py @@ -25,20 +25,20 @@ Media object for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import os from urllib.parse import urlparse import logging -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .primaryobj import PrimaryObject from .citationbase import CitationBase from .notebase import NoteBase @@ -46,17 +46,18 @@ from .attrbase import AttributeBase from .tagbase import TagBase from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext LOG = logging.getLogger(".citation") -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Media class # -#------------------------------------------------------------------------- -class Media(CitationBase, NoteBase, DateBase, AttributeBase, - PrimaryObject): +# ------------------------------------------------------------------------- +class Media(CitationBase, NoteBase, DateBase, AttributeBase, PrimaryObject): """ Container for information about an image file, including location, description and privacy. @@ -109,15 +110,21 @@ def serialize(self, no_text_date=False): be considered persistent. :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), - self.change, - DateBase.serialize(self, no_text_date), - TagBase.serialize(self), - self.private) + return ( + self.handle, + self.gramps_id, + self.path, + self.mime, + self.desc, + self.checksum, + AttributeBase.serialize(self), + CitationBase.serialize(self), + NoteBase.serialize(self), + self.change, + DateBase.serialize(self, no_text_date), + TagBase.serialize(self), + self.private, + ) @classmethod def get_schema(cls): @@ -129,45 +136,45 @@ def get_schema(cls): """ from .attribute import Attribute from .date import Date + return { "type": "object", "title": _("Media"), "properties": { "_class": {"enum": [cls.__name__]}, - "handle": {"type": "string", - "maxLength": 50, - "title": _("Handle")}, - "gramps_id": {"type": "string", - "title": _("Gramps ID")}, - "path": {"type": "string", - "title": _("Path")}, - "mime": {"type": "string", - "title": _("MIME")}, - "desc": {"type": "string", - "title": _("Description")}, - "checksum": {"type": "string", - "title": _("Checksum")}, - "attribute_list": {"type": "array", - "items": Attribute.get_schema(), - "title": _("Attributes")}, - "citation_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Citations")}, - "note_list": {"type": "array", - "items": {"type": "string"}, - "title": _("Notes")}, - "change": {"type": "integer", - "title": _("Last changed")}, - "date": {"oneOf": [{"type": "null"}, Date.get_schema()], - "title": _("Date")}, - "tag_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Tags")}, - "private": {"type": "boolean", - "title": _("Private")} - } + "handle": {"type": "string", "maxLength": 50, "title": _("Handle")}, + "gramps_id": {"type": "string", "title": _("Gramps ID")}, + "path": {"type": "string", "title": _("Path")}, + "mime": {"type": "string", "title": _("MIME")}, + "desc": {"type": "string", "title": _("Description")}, + "checksum": {"type": "string", "title": _("Checksum")}, + "attribute_list": { + "type": "array", + "items": Attribute.get_schema(), + "title": _("Attributes"), + }, + "citation_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Citations"), + }, + "note_list": { + "type": "array", + "items": {"type": "string"}, + "title": _("Notes"), + }, + "change": {"type": "integer", "title": _("Last changed")}, + "date": { + "oneOf": [{"type": "null"}, Date.get_schema()], + "title": _("Date"), + }, + "tag_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Tags"), + }, + "private": {"type": "boolean", "title": _("Private")}, + }, } def unserialize(self, data): @@ -178,9 +185,21 @@ def unserialize(self, data): :param data: tuple containing the persistent data associated the object :type data: tuple """ - (self.handle, self.gramps_id, self.path, self.mime, self.desc, - self.checksum, attribute_list, citation_list, note_list, self.change, - date, tag_list, self.private) = data + ( + self.handle, + self.gramps_id, + self.path, + self.mime, + self.desc, + self.checksum, + attribute_list, + citation_list, + note_list, + self.change, + date, + tag_list, + self.private, + ) = data AttributeBase.unserialize(self, attribute_list) CitationBase.unserialize(self, citation_list) @@ -235,9 +254,11 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - return self.get_referenced_note_handles() + \ - self.get_referenced_tag_handles() + \ - self.get_referenced_citation_handles() + return ( + self.get_referenced_note_handles() + + self.get_referenced_tag_handles() + + self.get_referenced_citation_handles() + ) def get_handle_referents(self): """ @@ -285,7 +306,7 @@ def get_mime_type(self): def set_path(self, path): """Set the file path to the passed path.""" res = urlparse(path) - if res.scheme == '' or res.scheme == 'file': + if res.scheme == "" or res.scheme == "file": self.path = os.path.normpath(path) else: # The principal case this path caters for is where the scheme is diff --git a/gramps/gen/lib/mediabase.py b/gramps/gen/lib/mediabase.py index 5205e84b221..62ac020a5a6 100644 --- a/gramps/gen/lib/mediabase.py +++ b/gramps/gen/lib/mediabase.py @@ -23,19 +23,20 @@ MediaBase class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .mediaref import MediaRef from .const import IDENTICAL, EQUAL, DIFFERENT -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MediaBase class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MediaBase: """ Base class for storing media references. @@ -135,8 +136,11 @@ def remove_media_references(self, obj_handle_list): :param obj_handle_list: The list of media handles to be removed. :type obj_handle_list: list """ - new_media_list = [media_ref for media_ref in self.media_list - if media_ref.ref not in obj_handle_list] + new_media_list = [ + media_ref + for media_ref in self.media_list + if media_ref.ref not in obj_handle_list + ] self.media_list = new_media_list def replace_media_references(self, old_handle, new_handle): diff --git a/gramps/gen/lib/mediaref.py b/gramps/gen/lib/mediaref.py index 0f088380de9..d2bc51d2185 100644 --- a/gramps/gen/lib/mediaref.py +++ b/gramps/gen/lib/mediaref.py @@ -26,11 +26,11 @@ Media Reference class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .privacybase import PrivacyBase from .citationbase import CitationBase @@ -39,16 +39,20 @@ from .attrbase import AttributeBase from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Media References for Person/Place/Source # -#------------------------------------------------------------------------- -class MediaRef(SecondaryObject, PrivacyBase, CitationBase, NoteBase, RefBase, - AttributeBase): +# ------------------------------------------------------------------------- +class MediaRef( + SecondaryObject, PrivacyBase, CitationBase, NoteBase, RefBase, AttributeBase +): """Media reference class.""" + def __init__(self, source=None): PrivacyBase.__init__(self, source) CitationBase.__init__(self, source) @@ -65,12 +69,14 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (PrivacyBase.serialize(self), - CitationBase.serialize(self), - NoteBase.serialize(self), - AttributeBase.serialize(self), - RefBase.serialize(self), - self.rect) + return ( + PrivacyBase.serialize(self), + CitationBase.serialize(self), + NoteBase.serialize(self), + AttributeBase.serialize(self), + RefBase.serialize(self), + self.rect, + ) @classmethod def get_schema(cls): @@ -81,42 +87,49 @@ def get_schema(cls): :rtype: dict """ from .attribute import Attribute + return { "type": "object", "title": _("Media ref"), "properties": { "_class": {"enum": [cls.__name__]}, - "private": {"type": "boolean", - "title": _("Private")}, - "citation_list": {"type": "array", - "title": _("Citations"), - "items": {"type": "string", - "maxLength": 50}}, - "note_list": {"type": "array", - "title": _("Notes"), - "items": {"type": "string", - "maxLength": 50}}, - "attribute_list": {"type": "array", - "title": _("Attributes"), - "items": Attribute.get_schema()}, - "ref": {"type": "string", - "title": _("Handle"), - "maxLength": 50}, - "rect": {"oneOf": [{"type": "null"}, - {"type": "array", - "items": {"type": "integer"}, - "minItems": 4, - "maxItems": 4}], - "title": _("Region")} - } + "private": {"type": "boolean", "title": _("Private")}, + "citation_list": { + "type": "array", + "title": _("Citations"), + "items": {"type": "string", "maxLength": 50}, + }, + "note_list": { + "type": "array", + "title": _("Notes"), + "items": {"type": "string", "maxLength": 50}, + }, + "attribute_list": { + "type": "array", + "title": _("Attributes"), + "items": Attribute.get_schema(), + }, + "ref": {"type": "string", "title": _("Handle"), "maxLength": 50}, + "rect": { + "oneOf": [ + {"type": "null"}, + { + "type": "array", + "items": {"type": "integer"}, + "minItems": 4, + "maxItems": 4, + }, + ], + "title": _("Region"), + }, + }, } def unserialize(self, data): """ Convert a serialized tuple of data to an object. """ - (privacy, citation_list, note_list, attribute_list, ref, - self.rect) = data + (privacy, citation_list, note_list, attribute_list, ref, self.rect) = data PrivacyBase.unserialize(self, privacy) CitationBase.unserialize(self, citation_list) NoteBase.unserialize(self, note_list) @@ -161,10 +174,11 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - ret = self.get_referenced_note_handles() + \ - self.get_referenced_citation_handles() + ret = ( + self.get_referenced_note_handles() + self.get_referenced_citation_handles() + ) if self.ref: - ret += [('Media', self.ref)] + ret += [("Media", self.ref)] return ret def get_handle_referents(self): diff --git a/gramps/gen/lib/name.py b/gramps/gen/lib/name.py index 10cb7f89f10..04dfcaff262 100644 --- a/gramps/gen/lib/name.py +++ b/gramps/gen/lib/name.py @@ -26,11 +26,11 @@ Name class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .privacybase import PrivacyBase from .citationbase import CitationBase @@ -41,15 +41,16 @@ from .const import IDENTICAL, EQUAL, DIFFERENT from .date import Date from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Personal Name # -#------------------------------------------------------------------------- -class Name(SecondaryObject, PrivacyBase, SurnameBase, CitationBase, NoteBase, - DateBase): +# ------------------------------------------------------------------------- +class Name(SecondaryObject, PrivacyBase, SurnameBase, CitationBase, NoteBase, DateBase): """ Provide name information about a person. @@ -57,14 +58,14 @@ class Name(SecondaryObject, PrivacyBase, SurnameBase, CitationBase, NoteBase, object stores one of them """ - DEF = 0 # Default format (determined by gramps-wide prefs) - LNFN = 1 # last name first name - FNLN = 2 # first name last name - FN = 4 # first name + DEF = 0 # Default format (determined by gramps-wide prefs) + LNFN = 1 # last name first name + FNLN = 2 # first name last name + FN = 4 # first name LNFNP = 5 # primary name primconnector rest, given pa/ma suffix, primprefix NAMEFORMATS = (DEF, LNFN, FNLN, FN, LNFNP) - #deprecated : + # deprecated : PTFN = 3 # patronymic first name def __init__(self, source=None, data=None): @@ -81,10 +82,23 @@ def __init__(self, source=None, data=None): NoteBase.__init__(self, source) DateBase.__init__(self, source) if data: - (privacy, citation_list, note, date, - self.first_name, surname_list, self.suffix, self.title, name_type, - self.group_as, self.sort_as, self.display_as, self.call, - self.nick, self.famnick) = data + ( + privacy, + citation_list, + note, + date, + self.first_name, + surname_list, + self.suffix, + self.title, + name_type, + self.group_as, + self.sort_as, + self.display_as, + self.call, + self.nick, + self.famnick, + ) = data self.type = NameType(name_type) SurnameBase.unserialize(self, surname_list) PrivacyBase.unserialize(self, privacy) @@ -118,16 +132,23 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (PrivacyBase.serialize(self), - CitationBase.serialize(self), - NoteBase.serialize(self), - DateBase.serialize(self), - self.first_name, - SurnameBase.serialize(self), - self.suffix, self.title, - self.type.serialize(), - self.group_as, self.sort_as, self.display_as, self.call, - self.nick, self.famnick) + return ( + PrivacyBase.serialize(self), + CitationBase.serialize(self), + NoteBase.serialize(self), + DateBase.serialize(self), + self.first_name, + SurnameBase.serialize(self), + self.suffix, + self.title, + self.type.serialize(), + self.group_as, + self.sort_as, + self.display_as, + self.call, + self.nick, + self.famnick, + ) @classmethod def get_schema(cls): @@ -138,69 +159,82 @@ def get_schema(cls): :rtype: dict """ from .surname import Surname + return { "type": "object", "title": _("Name"), "properties": { "_class": {"enum": [cls.__name__]}, - "private": {"type": "boolean", - "title": _("Private")}, - "citation_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Citations")}, - "note_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Notes")}, - "date": {"oneOf": [{"type": "null"}, Date.get_schema()], - "title": _("Date")}, - "first_name": {"type": "string", - "title": _("Given name")}, - "surname_list": {"type": "array", - "items": Surname.get_schema(), - "title": _("Surnames")}, - "suffix": {"type": "string", - "title": _("Suffix")}, - "title": {"type": "string", - "title": _("Title")}, + "private": {"type": "boolean", "title": _("Private")}, + "citation_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Citations"), + }, + "note_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Notes"), + }, + "date": { + "oneOf": [{"type": "null"}, Date.get_schema()], + "title": _("Date"), + }, + "first_name": {"type": "string", "title": _("Given name")}, + "surname_list": { + "type": "array", + "items": Surname.get_schema(), + "title": _("Surnames"), + }, + "suffix": {"type": "string", "title": _("Suffix")}, + "title": {"type": "string", "title": _("Title")}, "type": NameType.get_schema(), - "group_as": {"type": "string", - "title": _("Group as")}, - "sort_as": {"type": "integer", - "title": _("Sort as")}, - "display_as": {"type": "integer", - "title": _("Display as")}, - "call": {"type": "string", - "title": _("Call name")}, - "nick": {"type": "string", - "title": _("Nick name")}, - "famnick": {"type": "string", - "title": _("Family nick name")} - } + "group_as": {"type": "string", "title": _("Group as")}, + "sort_as": {"type": "integer", "title": _("Sort as")}, + "display_as": {"type": "integer", "title": _("Display as")}, + "call": {"type": "string", "title": _("Call name")}, + "nick": {"type": "string", "title": _("Nick name")}, + "famnick": {"type": "string", "title": _("Family nick name")}, + }, } def is_empty(self): """ Indicate if the name is empty. """ - namefieldsempty = (self.first_name == "" and - self.suffix == "" and - self.title == "" and - self.nick == "" and - self.famnick == "") - surnamefieldsempty = False not in [surn.is_empty() - for surn in self.surname_list] + namefieldsempty = ( + self.first_name == "" + and self.suffix == "" + and self.title == "" + and self.nick == "" + and self.famnick == "" + ) + surnamefieldsempty = False not in [ + surn.is_empty() for surn in self.surname_list + ] return namefieldsempty and surnamefieldsempty def unserialize(self, data): """ Convert a serialized tuple of data to an object. """ - (privacy, citation_list, note_list, date, - self.first_name, surname_list, self.suffix, self.title, name_type, - self.group_as, self.sort_as, self.display_as, self.call, - self.nick, self.famnick) = data + ( + privacy, + citation_list, + note_list, + date, + self.first_name, + surname_list, + self.suffix, + self.title, + name_type, + self.group_as, + self.sort_as, + self.display_as, + self.call, + self.nick, + self.famnick, + ) = data self.type = NameType(name_type) PrivacyBase.unserialize(self, privacy) SurnameBase.unserialize(self, surname_list) @@ -216,8 +250,15 @@ def get_text_data_list(self): :returns: Returns the list of all textual attributes of the object. :rtype: list """ - return [self.first_name, self.suffix, self.title, - str(self.type), self.call, self.nick, self.famnick] + return [ + self.first_name, + self.suffix, + self.title, + str(self.type), + self.call, + self.nick, + self.famnick, + ] def get_text_data_child_list(self): """ @@ -256,8 +297,9 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - return self.get_referenced_note_handles() + \ - self.get_referenced_citation_handles() + return ( + self.get_referenced_note_handles() + self.get_referenced_citation_handles() + ) def is_equivalent(self, other): """ @@ -270,9 +312,11 @@ def is_equivalent(self, other): :rtype: int """ # TODO what to do with sort and display? - if self.get_text_data_list() != other.get_text_data_list() or \ - self.get_date_object() != other.get_date_object() or \ - SurnameBase.serialize(self) != SurnameBase.serialize(other): + if ( + self.get_text_data_list() != other.get_text_data_list() + or self.get_date_object() != other.get_date_object() + or SurnameBase.serialize(self) != SurnameBase.serialize(other) + ): return DIFFERENT else: if self.is_equal(other): @@ -458,11 +502,14 @@ def get_name(self): surname = self.get_surname() if self.suffix: # Translators: needed for Arabic, ignore otherwise - return _("%(surname)s, %(first)s %(suffix)s" - ) % {'surname':surname, 'first':first, 'suffix':self.suffix} + return _("%(surname)s, %(first)s %(suffix)s") % { + "surname": surname, + "first": first, + "suffix": self.suffix, + } else: # Translators: needed for Arabic, ignore otherwise - return _("%(str1)s, %(str2)s") % {'str1':surname, 'str2':first} + return _("%(str1)s, %(str2)s") % {"str1": surname, "str2": first} def get_upper_name(self): """ @@ -473,11 +520,14 @@ def get_upper_name(self): surname = self.get_surname().upper() if self.suffix: # Translators: needed for Arabic, ignore otherwise - return _("%(surname)s, %(first)s %(suffix)s" - ) % {'surname':surname, 'first':first, 'suffix':self.suffix} + return _("%(surname)s, %(first)s %(suffix)s") % { + "surname": surname, + "first": first, + "suffix": self.suffix, + } else: # Translators: needed for Arabic, ignore otherwise - return _("%(str1)s, %(str2)s") % {'str1':surname, 'str2':first} + return _("%(str1)s, %(str2)s") % {"str1": surname, "str2": first} def get_regular_name(self): """ @@ -490,8 +540,11 @@ def get_regular_name(self): return "%s %s" % (first, surname) else: # Translators: needed for Arabic, ignore otherwise - return _("%(first)s %(surname)s, %(suffix)s" - ) % {'surname':surname, 'first':first, 'suffix':self.suffix} + return _("%(first)s %(surname)s, %(suffix)s") % { + "surname": surname, + "first": first, + "suffix": self.suffix, + } def get_gedcom_parts(self): """ @@ -501,15 +554,15 @@ def get_gedcom_parts(self): surname list, added. """ retval = {} - retval['given'] = self.first_name.strip() - retval['surname'] = self.get_surname().replace('/', '?') - retval['suffix'] = self.suffix - retval['title'] = self.title - retval['surnamelist'] = self.get_surnames() - retval['prefixes'] = self.get_prefixes() - retval['connectors'] = self.get_connectors() - retval['nick'] = self.nick - retval['famnick'] = self.famnick + retval["given"] = self.first_name.strip() + retval["surname"] = self.get_surname().replace("/", "?") + retval["suffix"] = self.suffix + retval["title"] = self.title + retval["surnamelist"] = self.get_surnames() + retval["prefixes"] = self.get_prefixes() + retval["connectors"] = self.get_connectors() + retval["nick"] = self.nick + retval["famnick"] = self.famnick return retval def get_gedcom_name(self): @@ -517,9 +570,9 @@ def get_gedcom_name(self): Returns a GEDCOM-formatted name. """ firstname = self.first_name.strip() - surname = self.get_surname().replace('/', '?') + surname = self.get_surname().replace("/", "?") suffix = self.suffix if suffix == "": - return '%s /%s/' % (firstname, surname) + return "%s /%s/" % (firstname, surname) else: - return '%s /%s/ %s' % (firstname, surname, suffix) + return "%s /%s/ %s" % (firstname, surname, suffix) diff --git a/gramps/gen/lib/nameorigintype.py b/gramps/gen/lib/nameorigintype.py index 6e36b5a939a..ff244eca14b 100644 --- a/gramps/gen/lib/nameorigintype.py +++ b/gramps/gen/lib/nameorigintype.py @@ -22,15 +22,17 @@ Name types. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext + class NameOriginType(GrampsType): """ Name Origin Types @@ -84,7 +86,7 @@ class NameOriginType(GrampsType): (MATRILINEAL, _("Matrilineal"), "Matrilineal"), (OCCUPATION, _("Occupation"), "Occupation"), (LOCATION, _("Location"), "Location"), - ] + ] def __init__(self, value=None): GrampsType.__init__(self, value) diff --git a/gramps/gen/lib/nametype.py b/gramps/gen/lib/nametype.py index 76776d58f5c..3903bb1d24a 100644 --- a/gramps/gen/lib/nametype.py +++ b/gramps/gen/lib/nametype.py @@ -22,17 +22,18 @@ Name types. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -class NameType(GrampsType): +class NameType(GrampsType): UNKNOWN = -1 CUSTOM = 0 AKA = 1 @@ -48,7 +49,7 @@ class NameType(GrampsType): (AKA, _("Also Known As"), "Also Known As"), (BIRTH, _("Birth Name"), "Birth Name"), (MARRIED, _("Married Name"), "Married Name"), - ] + ] def __init__(self, value=None): GrampsType.__init__(self, value) diff --git a/gramps/gen/lib/note.py b/gramps/gen/lib/note.py index 9f1ae33a656..05a91d4fbc6 100644 --- a/gramps/gen/lib/note.py +++ b/gramps/gen/lib/note.py @@ -24,24 +24,26 @@ Note class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .primaryobj import BasicPrimaryObject from .tagbase import TagBase from .notetype import NoteType from .styledtext import StyledText from .styledtexttagtype import StyledTextTagType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Class for notes used throughout the majority of Gramps objects # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Note(BasicPrimaryObject): """Define a text note. @@ -67,16 +69,19 @@ class Note(BasicPrimaryObject): they have to be updated in case the data structure or the :meth:`serialize` method changes! """ + (FLOWED, FORMATTED) = list(range(2)) - (POS_HANDLE, - POS_ID, - POS_TEXT, - POS_FORMAT, - POS_TYPE, - POS_CHANGE, - POS_TAGS, - POS_PRIVATE,) = list(range(8)) + ( + POS_HANDLE, + POS_ID, + POS_TEXT, + POS_FORMAT, + POS_TYPE, + POS_CHANGE, + POS_TAGS, + POS_PRIVATE, + ) = list(range(8)) def __init__(self, text=""): """Create a new Note object, initializing from the passed string.""" @@ -92,9 +97,16 @@ def serialize(self): :rtype: tuple """ - return (self.handle, self.gramps_id, self.text.serialize(), self.format, - self.type.serialize(), self.change, TagBase.serialize(self), - self.private) + return ( + self.handle, + self.gramps_id, + self.text.serialize(), + self.format, + self.type.serialize(), + self.change, + TagBase.serialize(self), + self.private, + ) @classmethod def get_schema(cls): @@ -109,24 +121,19 @@ def get_schema(cls): "title": _("Note"), "properties": { "_class": {"enum": [cls.__name__]}, - "handle": {"type": "string", - "maxLength": 50, - "title": _("Handle")}, - "gramps_id": {"type": "string", - "title": _("Gramps ID")}, + "handle": {"type": "string", "maxLength": 50, "title": _("Handle")}, + "gramps_id": {"type": "string", "title": _("Gramps ID")}, "text": StyledText.get_schema(), - "format": {"type": "integer", - "title": _("Format")}, + "format": {"type": "integer", "title": _("Format")}, "type": NoteType.get_schema(), - "change": {"type": "integer", - "title": _("Last changed")}, - "tag_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Tags")}, - "private": {"type": "boolean", - "title": _("Private")} - } + "change": {"type": "integer", "title": _("Last changed")}, + "tag_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Tags"), + }, + "private": {"type": "boolean", "title": _("Private")}, + }, } def unserialize(self, data): @@ -135,8 +142,16 @@ def unserialize(self, data): :param data: The serialized format of a Note. :type: data: tuple """ - (self.handle, self.gramps_id, the_text, self.format, - the_type, self.change, tag_list, self.private) = data + ( + self.handle, + self.gramps_id, + the_text, + self.format, + the_type, + self.change, + tag_list, + self.private, + ) = data self.text = StyledText() self.text.unserialize(the_text) @@ -187,8 +202,12 @@ def has_handle_reference(self, classname, handle): :rtype: bool """ for dom, obj, prop, hndl in self.get_links(): - if dom == "gramps" and prop == "handle" and \ - obj == classname and hndl == handle: + if ( + dom == "gramps" + and prop == "handle" + and obj == classname + and hndl == handle + ): return True return False @@ -206,11 +225,12 @@ def remove_handle_references(self, classname, handle_list): """ tags = [] for styledtext_tag in self.text.get_tags(): - if(styledtext_tag.name == StyledTextTagType.LINK and - styledtext_tag.value.startswith("gramps://")): + if ( + styledtext_tag.name == StyledTextTagType.LINK + and styledtext_tag.value.startswith("gramps://") + ): obj, prop, value = styledtext_tag.value[9:].split("/", 2) - if obj == classname and prop == 'handle' and \ - value in handle_list: + if obj == classname and prop == "handle" and value in handle_list: continue tags.append(styledtext_tag) self.text.set_tags(tags) @@ -227,13 +247,15 @@ def replace_handle_reference(self, classname, old_handle, new_handle): :type new_handle: str """ for styledtext_tag in self.text.get_tags(): - if(styledtext_tag.name == StyledTextTagType.LINK and - styledtext_tag.value.startswith("gramps://")): + if ( + styledtext_tag.name == StyledTextTagType.LINK + and styledtext_tag.value.startswith("gramps://") + ): obj, prop, value = styledtext_tag.value[9:].split("/", 2) - if(obj == classname and prop == 'handle' and - value == old_handle): + if obj == classname and prop == "handle" and value == old_handle: styledtext_tag.value = styledtext_tag.value.replace( - old_handle, new_handle) + old_handle, new_handle + ) def merge(self, acquisition): """ diff --git a/gramps/gen/lib/notebase.py b/gramps/gen/lib/notebase.py index e9fe54b48a3..fe30af1c965 100644 --- a/gramps/gen/lib/notebase.py +++ b/gramps/gen/lib/notebase.py @@ -22,21 +22,21 @@ """ NoteBase class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging LOG = logging.getLogger(".note") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # NoteBase class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class NoteBase: """ Base class for storing notes. @@ -45,6 +45,7 @@ class NoteBase: Internally, this class maintains a list of Note handles, as a note_list attribute of the NoteBase object. """ + def __init__(self, source=None): """ Create a new NoteBase, copying from source if not None. @@ -149,14 +150,17 @@ def remove_note_references(self, handle_list): :param citation_handle_list: The list of note handles to be removed :type handle: list """ - LOG.debug('enter remove_note handle: %s self: %s note_list: %s', - handle_list, self, self.note_list) + LOG.debug( + "enter remove_note handle: %s self: %s note_list: %s", + handle_list, + self, + self.note_list, + ) for handle in handle_list: if handle in self.note_list: - LOG.debug('remove handle %s from note_list %s', - handle, self.note_list) + LOG.debug("remove handle %s from note_list %s", handle, self.note_list) self.note_list.remove(handle) - LOG.debug('get_note_child_list %s', self.get_note_child_list()) + LOG.debug("get_note_child_list %s", self.get_note_child_list()) for item in self.get_note_child_list(): item.remove_note_references(handle_list) @@ -192,7 +196,7 @@ def get_referenced_note_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - return [('Note', handle) for handle in self.note_list] + return [("Note", handle) for handle in self.note_list] def replace_note_references(self, old_handle, new_handle): """ diff --git a/gramps/gen/lib/notetype.py b/gramps/gen/lib/notetype.py index 12422ad11e3..c5cc146b4b9 100644 --- a/gramps/gen/lib/notetype.py +++ b/gramps/gen/lib/notetype.py @@ -22,23 +22,24 @@ Note types. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -class NoteType(GrampsType): +class NoteType(GrampsType): UNKNOWN = -1 CUSTOM = 0 GENERAL = 1 RESEARCH = 2 TRANSCRIPT = 3 - #per object with notes a Type to distinguish the notes + # per object with notes a Type to distinguish the notes PERSON = 4 ATTRIBUTE = 5 ADDRESS = 6 @@ -57,9 +58,9 @@ class NoteType(GrampsType): CHILDREF = 19 PERSONNAME = 20 # other common types - SOURCE_TEXT = 21 # this is used for verbatim source text in SourceRef + SOURCE_TEXT = 21 # this is used for verbatim source text in SourceRef CITATION = 22 - REPORT_TEXT = 23 # this is used for notes used for reports + REPORT_TEXT = 23 # this is used for notes used for reports # indicate a note is html code HTML_CODE = 24 TODO = 25 @@ -78,12 +79,12 @@ class NoteType(GrampsType): (ANALYSIS, _("Analysis"), "Analysis"), (TRANSCRIPT, _("Transcript"), "Transcript"), (SOURCE_TEXT, _("Source text"), "Source text"), - (CITATION, _('Citation'), "Citation"), + (CITATION, _("Citation"), "Citation"), (REPORT_TEXT, _("Report"), "Report"), (HTML_CODE, _("Html code"), "Html code"), (TODO, _("To Do", "notetype"), "To Do"), (LINK, _("Link", "notetype"), "Link"), - ] + ] _DATAMAPIGNORE = [ (PERSON, _("Person Note"), "Person Note"), @@ -103,7 +104,7 @@ class NoteType(GrampsType): (MEDIA, _("Media Note"), "Media Note"), (MEDIAREF, _("Media Reference Note"), "Media Reference Note"), (CHILDREF, _("Child Reference Note"), "Child Reference Note"), - ] + ] _DATAMAP = _DATAMAPREAL + _DATAMAPIGNORE diff --git a/gramps/gen/lib/person.py b/gramps/gen/lib/person.py index 4c9c2d5d271..10008f1adcf 100644 --- a/gramps/gen/lib/person.py +++ b/gramps/gen/lib/person.py @@ -25,11 +25,11 @@ Person object for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .primaryobj import PrimaryObject from .citationbase import CitationBase from .notebase import NoteBase @@ -47,15 +47,25 @@ from .attribute import Attribute from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Person class # -#------------------------------------------------------------------------- -class Person(CitationBase, NoteBase, AttributeBase, MediaBase, - AddressBase, UrlBase, LdsOrdBase, PrimaryObject): +# ------------------------------------------------------------------------- +class Person( + CitationBase, + NoteBase, + AttributeBase, + MediaBase, + AddressBase, + UrlBase, + LdsOrdBase, + PrimaryObject, +): """ The Person record is the Gramps in-memory representation of an individual person. It contains all the information related to @@ -134,28 +144,28 @@ def serialize(self): :rtype: tuple """ return ( - self.handle, # 0 - self.gramps_id, # 1 - self.__gender, # 2 - self.primary_name.serialize(), # 3 - [name.serialize() for name in self.alternate_names], # 4 - self.death_ref_index, # 5 - self.birth_ref_index, # 6 - [er.serialize() for er in self.event_ref_list], # 7 - self.family_list, # 8 - self.parent_family_list, # 9 - MediaBase.serialize(self), # 10 - AddressBase.serialize(self), # 11 - AttributeBase.serialize(self), # 12 - UrlBase.serialize(self), # 13 - LdsOrdBase.serialize(self), # 14 - CitationBase.serialize(self), # 15 - NoteBase.serialize(self), # 16 - self.change, # 17 - TagBase.serialize(self), # 18 - self.private, # 19 - [pr.serialize() for pr in self.person_ref_list] # 20 - ) + self.handle, # 0 + self.gramps_id, # 1 + self.__gender, # 2 + self.primary_name.serialize(), # 3 + [name.serialize() for name in self.alternate_names], # 4 + self.death_ref_index, # 5 + self.birth_ref_index, # 6 + [er.serialize() for er in self.event_ref_list], # 7 + self.family_list, # 8 + self.parent_family_list, # 9 + MediaBase.serialize(self), # 10 + AddressBase.serialize(self), # 11 + AttributeBase.serialize(self), # 12 + UrlBase.serialize(self), # 13 + LdsOrdBase.serialize(self), # 14 + CitationBase.serialize(self), # 15 + NoteBase.serialize(self), # 16 + self.change, # 17 + TagBase.serialize(self), # 18 + self.private, # 19 + [pr.serialize() for pr in self.person_ref_list], # 20 + ) @classmethod def get_schema(cls): @@ -169,74 +179,97 @@ def get_schema(cls): from .address import Address from .url import Url from .ldsord import LdsOrd + return { "type": "object", "title": _("Person"), "properties": { "_class": {"enum": [cls.__name__]}, - "handle": {"type": "string", - "maxLength": 50, - "title": _("Handle")}, - "gramps_id": {"type": "string", - "title": _("Gramps ID")}, - "gender": {"type": "integer", - "minimum": 0, - "maximum": 2, - "title": _("Gender")}, + "handle": {"type": "string", "maxLength": 50, "title": _("Handle")}, + "gramps_id": {"type": "string", "title": _("Gramps ID")}, + "gender": { + "type": "integer", + "minimum": 0, + "maximum": 2, + "title": _("Gender"), + }, "primary_name": Name.get_schema(), - "alternate_names": {"type": "array", - "items": Name.get_schema(), - "title": _("Alternate names")}, - "death_ref_index": {"type": "integer", - "title": _("Death reference index")}, - "birth_ref_index": {"type": "integer", - "title": _("Birth reference index")}, - "event_ref_list": {"type": "array", - "items": EventRef.get_schema(), - "title": _("Event references")}, - "family_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Families")}, - "parent_family_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Parent families")}, - "media_list": {"type": "array", - "items": MediaRef.get_schema(), - "title": _("Media")}, - "address_list": {"type": "array", - "items": Address.get_schema(), - "title": _("Addresses")}, - "attribute_list": {"type": "array", - "items": Attribute.get_schema(), - "title": _("Attributes")}, - "urls": {"type": "array", - "items": Url.get_schema(), - "title": _("Urls")}, - "lds_ord_list": {"type": "array", - "items": LdsOrd.get_schema(), - "title": _("LDS ordinances")}, - "citation_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Citations")}, - "note_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Notes")}, - "change": {"type": "integer", - "title": _("Last changed")}, - "tag_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Tags")}, - "private": {"type": "boolean", - "title": _("Private")}, - "person_ref_list": {"type": "array", - "items": PersonRef.get_schema(), - "title": _("Person references")} - } + "alternate_names": { + "type": "array", + "items": Name.get_schema(), + "title": _("Alternate names"), + }, + "death_ref_index": { + "type": "integer", + "title": _("Death reference index"), + }, + "birth_ref_index": { + "type": "integer", + "title": _("Birth reference index"), + }, + "event_ref_list": { + "type": "array", + "items": EventRef.get_schema(), + "title": _("Event references"), + }, + "family_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Families"), + }, + "parent_family_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Parent families"), + }, + "media_list": { + "type": "array", + "items": MediaRef.get_schema(), + "title": _("Media"), + }, + "address_list": { + "type": "array", + "items": Address.get_schema(), + "title": _("Addresses"), + }, + "attribute_list": { + "type": "array", + "items": Attribute.get_schema(), + "title": _("Attributes"), + }, + "urls": { + "type": "array", + "items": Url.get_schema(), + "title": _("Urls"), + }, + "lds_ord_list": { + "type": "array", + "items": LdsOrd.get_schema(), + "title": _("LDS ordinances"), + }, + "citation_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Citations"), + }, + "note_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Notes"), + }, + "change": {"type": "integer", "title": _("Last changed")}, + "tag_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Tags"), + }, + "private": {"type": "boolean", "title": _("Private")}, + "person_ref_list": { + "type": "array", + "items": PersonRef.get_schema(), + "title": _("Person references"), + }, + }, } def unserialize(self, data): @@ -248,37 +281,35 @@ def unserialize(self, data): Person object :type data: tuple """ - (self.handle, # 0 - self.gramps_id, # 1 - self.__gender, # 2 - primary_name, # 3 - alternate_names, # 4 - self.death_ref_index, # 5 - self.birth_ref_index, # 6 - event_ref_list, # 7 - self.family_list, # 8 - self.parent_family_list, # 9 - media_list, # 10 - address_list, # 11 - attribute_list, # 12 - urls, # 13 - lds_ord_list, # 14 - citation_list, # 15 - note_list, # 16 - self.change, # 17 - tag_list, # 18 - self.private, # 19 - person_ref_list, # 20 + ( + self.handle, # 0 + self.gramps_id, # 1 + self.__gender, # 2 + primary_name, # 3 + alternate_names, # 4 + self.death_ref_index, # 5 + self.birth_ref_index, # 6 + event_ref_list, # 7 + self.family_list, # 8 + self.parent_family_list, # 9 + media_list, # 10 + address_list, # 11 + attribute_list, # 12 + urls, # 13 + lds_ord_list, # 14 + citation_list, # 15 + note_list, # 16 + self.change, # 17 + tag_list, # 18 + self.private, # 19 + person_ref_list, # 20 ) = data self.primary_name = Name() self.primary_name.unserialize(primary_name) - self.alternate_names = [Name().unserialize(name) - for name in alternate_names] - self.event_ref_list = [EventRef().unserialize(er) - for er in event_ref_list] - self.person_ref_list = [PersonRef().unserialize(pr) - for pr in person_ref_list] + self.alternate_names = [Name().unserialize(name) for name in alternate_names] + self.event_ref_list = [EventRef().unserialize(er) for er in event_ref_list] + self.person_ref_list = [PersonRef().unserialize(pr) for pr in person_ref_list] MediaBase.unserialize(self, media_list) LdsOrdBase.unserialize(self, lds_ord_list) AddressBase.unserialize(self, address_list) @@ -302,36 +333,41 @@ def _has_handle_reference(self, classname, handle): this object type. :rtype: bool """ - if classname == 'Event': + if classname == "Event": return any(ref.ref == handle for ref in self.event_ref_list) - elif classname == 'Person': + elif classname == "Person": return any(ref.ref == handle for ref in self.person_ref_list) - elif classname == 'Family': - return any(ref == handle - for ref in self.family_list + self.parent_family_list + - [ordinance.famc for ordinance in self.lds_ord_list]) - elif classname == 'Place': - return any(ordinance.place == handle - for ordinance in self.lds_ord_list) + elif classname == "Family": + return any( + ref == handle + for ref in self.family_list + + self.parent_family_list + + [ordinance.famc for ordinance in self.lds_ord_list] + ) + elif classname == "Place": + return any(ordinance.place == handle for ordinance in self.lds_ord_list) return False def _remove_handle_references(self, classname, handle_list): - if classname == 'Event': + if classname == "Event": # Keep a copy of the birth and death references birth_ref = self.get_birth_ref() death_ref = self.get_death_ref() - new_list = [ref for ref in self.event_ref_list - if ref.ref not in handle_list] + new_list = [ + ref for ref in self.event_ref_list if ref.ref not in handle_list + ] # If deleting removing the reference to the event # to which birth or death ref_index points, unset the index - if (self.birth_ref_index != -1 - and self.event_ref_list[self.birth_ref_index].ref - in handle_list): + if ( + self.birth_ref_index != -1 + and self.event_ref_list[self.birth_ref_index].ref in handle_list + ): self.set_birth_ref(None) - if (self.death_ref_index != -1 - and self.event_ref_list[self.death_ref_index].ref - in handle_list): + if ( + self.death_ref_index != -1 + and self.event_ref_list[self.death_ref_index].ref in handle_list + ): self.set_death_ref(None) self.event_ref_list = new_list @@ -340,27 +376,32 @@ def _remove_handle_references(self, classname, handle_list): self.set_birth_ref(birth_ref) if self.death_ref_index != -1: self.set_death_ref(death_ref) - elif classname == 'Person': - new_list = [ref for ref in self.person_ref_list - if ref.ref not in handle_list] + elif classname == "Person": + new_list = [ + ref for ref in self.person_ref_list if ref.ref not in handle_list + ] self.person_ref_list = new_list - elif classname == 'Family': - new_list = [handle for handle in self.family_list - if handle not in handle_list] + elif classname == "Family": + new_list = [ + handle for handle in self.family_list if handle not in handle_list + ] self.family_list = new_list - new_list = [handle for handle in self.parent_family_list - if handle not in handle_list] + new_list = [ + handle + for handle in self.parent_family_list + if handle not in handle_list + ] self.parent_family_list = new_list for ordinance in self.lds_ord_list: if ordinance.famc in handle_list: ordinance.famc = None - elif classname == 'Place': + elif classname == "Place": for ordinance in self.lds_ord_list: if ordinance.place in handle_list: ordinance.place = None def _replace_handle_reference(self, classname, old_handle, new_handle): - if classname == 'Event': + if classname == "Event": refs_list = [ref.ref for ref in self.event_ref_list] new_ref = None if new_handle in refs_list: @@ -390,7 +431,7 @@ def _replace_handle_reference(self, classname, old_handle, new_handle): self.death_ref_index = -1 # death_ref_index should be recalculated which # needs database access! - elif classname == 'Person': + elif classname == "Person": refs_list = [ref.ref for ref in self.person_ref_list] new_ref = None if new_handle in refs_list: @@ -408,7 +449,7 @@ def _replace_handle_reference(self, classname, old_handle, new_handle): new_ref.merge(person_ref) self.person_ref_list.pop(idx) refs_list.pop(idx) - elif classname == 'Family': + elif classname == "Family": while old_handle in self.family_list: ix = self.family_list.index(old_handle) self.family_list[ix] = new_handle @@ -419,13 +460,13 @@ def _replace_handle_reference(self, classname, old_handle, new_handle): while old_handle in handle_list: ix = handle_list.index(old_handle) self.lds_ord_list[ix].famc = new_handle - handle_list[ix] = '' + handle_list[ix] = "" elif classname == "Place": handle_list = [ordinance.place for ordinance in self.lds_ord_list] while old_handle in handle_list: ix = handle_list.index(old_handle) self.lds_ord_list[ix].place = new_handle - handle_list[ix] = '' + handle_list[ix] = "" def get_text_data_list(self): """ @@ -445,16 +486,17 @@ def get_text_data_child_list(self): """ check_list = self.lds_ord_list add_list = [_f for _f in check_list if _f] - return ([self.primary_name] + - self.media_list + - self.alternate_names + - self.address_list + - self.attribute_list + - self.urls + - self.event_ref_list + - add_list + - self.person_ref_list - ) + return ( + [self.primary_name] + + self.media_list + + self.alternate_names + + self.address_list + + self.attribute_list + + self.urls + + self.event_ref_list + + add_list + + self.person_ref_list + ) def get_citation_child_list(self): """ @@ -464,15 +506,16 @@ def get_citation_child_list(self): refer citations. :rtype: list """ - return ([self.primary_name] + - self.media_list + - self.alternate_names + - self.address_list + - self.attribute_list + - self.lds_ord_list + - self.person_ref_list + - self.event_ref_list - ) + return ( + [self.primary_name] + + self.media_list + + self.alternate_names + + self.address_list + + self.attribute_list + + self.lds_ord_list + + self.person_ref_list + + self.event_ref_list + ) def get_note_child_list(self): """ @@ -482,15 +525,16 @@ def get_note_child_list(self): refer notes. :rtype: list """ - return ([self.primary_name] + - self.media_list + - self.alternate_names + - self.address_list + - self.attribute_list + - self.lds_ord_list + - self.person_ref_list + - self.event_ref_list - ) + return ( + [self.primary_name] + + self.media_list + + self.alternate_names + + self.address_list + + self.attribute_list + + self.lds_ord_list + + self.person_ref_list + + self.event_ref_list + ) def get_referenced_handles(self): """ @@ -500,12 +544,14 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - return [('Family', handle) for handle in - (self.family_list + self.parent_family_list)] + ( - self.get_referenced_note_handles() + - self.get_referenced_citation_handles() + - self.get_referenced_tag_handles() - ) + return [ + ("Family", handle) + for handle in (self.family_list + self.parent_family_list) + ] + ( + self.get_referenced_note_handles() + + self.get_referenced_citation_handles() + + self.get_referenced_tag_handles() + ) def get_handle_referents(self): """ @@ -515,15 +561,16 @@ def get_handle_referents(self): :returns: Returns the list of objects referencing primary objects. :rtype: list """ - return ([self.primary_name] + - self.media_list + - self.alternate_names + - self.address_list + - self.attribute_list + - self.lds_ord_list + - self.person_ref_list + - self.event_ref_list - ) + return ( + [self.primary_name] + + self.media_list + + self.alternate_names + + self.address_list + + self.attribute_list + + self.lds_ord_list + + self.person_ref_list + + self.event_ref_list + ) def merge(self, acquisition): """ @@ -553,8 +600,12 @@ def merge(self, acquisition): self._merge_citation_list(acquisition) self._merge_tag_list(acquisition) - list(map(self.add_parent_family_handle, - acquisition.get_parent_family_handle_list())) + list( + map( + self.add_parent_family_handle, + acquisition.get_parent_family_handle_list(), + ) + ) list(map(self.add_family_handle, acquisition.get_family_handle_list())) def set_primary_name(self, name): @@ -634,7 +685,7 @@ def get_nick_name(self): for attr in self.attribute_list: if int(attr.type) == AttributeType.NICKNAME: return attr.get_value() - return '' + return "" def set_gender(self, gender): """ @@ -649,9 +700,8 @@ def set_gender(self, gender): - Person.UNKNOWN :type gender: int """ - if gender not in (Person.MALE, Person.FEMALE, Person.OTHER, - Person.UNKNOWN): - raise ValueError('Attempt to assign invalid gender') + if gender not in (Person.MALE, Person.FEMALE, Person.OTHER, Person.UNKNOWN): + raise ValueError("Attempt to assign invalid gender") self.__gender = gender def get_gender(self): @@ -668,8 +718,9 @@ def get_gender(self): """ return self.__gender - gender = property(get_gender, set_gender, None, - 'Returns or sets the gender of the person') + gender = property( + get_gender, set_gender, None, "Returns or sets the gender of the person" + ) def set_birth_ref(self, event_ref): """ @@ -691,10 +742,10 @@ def set_birth_ref(self, event_ref): # check whether we already have this ref in the list for self.birth_ref_index, ref in enumerate(self.event_ref_list): if event_ref.is_equal(ref): - return # Note: self.birth_ref_index already set + return # Note: self.birth_ref_index already set self.event_ref_list.append(event_ref) - self.birth_ref_index = len(self.event_ref_list)-1 + self.birth_ref_index = len(self.event_ref_list) - 1 def set_death_ref(self, event_ref): """ @@ -716,10 +767,10 @@ def set_death_ref(self, event_ref): # check whether we already have this ref in the list for self.death_ref_index, ref in enumerate(self.event_ref_list): if event_ref.is_equal(ref): - return # Note: self.death_ref_index already set + return # Note: self.death_ref_index already set self.event_ref_list.append(event_ref) - self.death_ref_index = len(self.event_ref_list)-1 + self.death_ref_index = len(self.event_ref_list) - 1 def get_birth_ref(self): """ @@ -795,9 +846,11 @@ def get_primary_event_ref_list(self): associated with the Person instance. :rtype: generator """ - return (ref for ref in self.event_ref_list - if ref.get_role() == EventRoleType.PRIMARY - ) + return ( + ref + for ref in self.event_ref_list + if ref.get_role() == EventRoleType.PRIMARY + ) def set_event_ref_list(self, event_ref_list): """ @@ -829,11 +882,9 @@ def _merge_event_ref_list(self, acquisition): break else: self.event_ref_list.append(addendum) - if (self.birth_ref_index == -1 and - idx == acquisition.birth_ref_index): + if self.birth_ref_index == -1 and idx == acquisition.birth_ref_index: self.birth_ref_index = len(self.event_ref_list) - 1 - if (self.death_ref_index == -1 and - idx == acquisition.death_ref_index): + if self.death_ref_index == -1 and idx == acquisition.death_ref_index: self.death_ref_index = len(self.event_ref_list) - 1 def add_family_handle(self, family_handle): diff --git a/gramps/gen/lib/personref.py b/gramps/gen/lib/personref.py index 743d0a408ba..0a1619c9f34 100644 --- a/gramps/gen/lib/personref.py +++ b/gramps/gen/lib/personref.py @@ -26,11 +26,11 @@ Person Reference class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .privacybase import PrivacyBase from .citationbase import CitationBase @@ -38,13 +38,15 @@ from .refbase import RefBase from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Person References for Person/Family # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PersonRef(SecondaryObject, PrivacyBase, CitationBase, NoteBase, RefBase): """ Person reference class. @@ -62,17 +64,19 @@ def __init__(self, source=None): if source: self.rel = source.rel else: - self.rel = '' + self.rel = "" def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (PrivacyBase.serialize(self), - CitationBase.serialize(self), - NoteBase.serialize(self), - RefBase.serialize(self), - self.rel) + return ( + PrivacyBase.serialize(self), + CitationBase.serialize(self), + NoteBase.serialize(self), + RefBase.serialize(self), + self.rel, + ) def unserialize(self, data): """ @@ -98,22 +102,20 @@ def get_schema(cls): "title": _("Person ref"), "properties": { "_class": {"enum": [cls.__name__]}, - "private": {"type": "boolean", - "title": _("Private")}, - "citation_list": {"type": "array", - "title": _("Citations"), - "items": {"type": "string", - "maxLength": 50}}, - "note_list": {"type": "array", - "title": _("Notes"), - "items": {"type": "string", - "maxLength": 50}}, - "ref": {"type": "string", - "title": _("Handle"), - "maxLength": 50}, - "rel": {"type": "string", - "title": _("Association")} - } + "private": {"type": "boolean", "title": _("Private")}, + "citation_list": { + "type": "array", + "title": _("Citations"), + "items": {"type": "string", "maxLength": 50}, + }, + "note_list": { + "type": "array", + "title": _("Notes"), + "items": {"type": "string", "maxLength": 50}, + }, + "ref": {"type": "string", "title": _("Handle"), "maxLength": 50}, + "rel": {"type": "string", "title": _("Association")}, + }, } def get_text_data_list(self): @@ -152,10 +154,11 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - ret = self.get_referenced_note_handles() + \ - self.get_referenced_citation_handles() + ret = ( + self.get_referenced_note_handles() + self.get_referenced_citation_handles() + ) if self.ref: - ret += [('Person', self.ref)] + ret += [("Person", self.ref)] return ret def get_handle_referents(self): @@ -178,8 +181,10 @@ def is_equivalent(self, other): :returns: Constant indicating degree of equivalence. :rtype: int """ - if self.ref != other.ref or \ - self.get_text_data_list() != other.get_text_data_list(): + if ( + self.ref != other.ref + or self.get_text_data_list() != other.get_text_data_list() + ): return DIFFERENT else: if self.is_equal(other): diff --git a/gramps/gen/lib/place.py b/gramps/gen/lib/place.py index e3227587379..08517a2b46f 100644 --- a/gramps/gen/lib/place.py +++ b/gramps/gen/lib/place.py @@ -26,11 +26,11 @@ Place object for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .primaryobj import PrimaryObject from .placeref import PlaceRef from .placename import PlaceName @@ -42,13 +42,15 @@ from .tagbase import TagBase from .location import Location from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Place class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject): """ Contains information related to a place, including multiple address @@ -107,17 +109,26 @@ def serialize(self): be considered persistent. :rtype: tuple """ - return (self.handle, self.gramps_id, self.title, self.long, self.lat, - [pr.serialize() for pr in self.placeref_list], - self.name.serialize(), - [an.serialize() for an in self.alt_names], - self.place_type.serialize(), self.code, - [al.serialize() for al in self.alt_loc], - UrlBase.serialize(self), - MediaBase.serialize(self), - CitationBase.serialize(self), - NoteBase.serialize(self), - self.change, TagBase.serialize(self), self.private) + return ( + self.handle, + self.gramps_id, + self.title, + self.long, + self.lat, + [pr.serialize() for pr in self.placeref_list], + self.name.serialize(), + [an.serialize() for an in self.alt_names], + self.place_type.serialize(), + self.code, + [al.serialize() for al in self.alt_loc], + UrlBase.serialize(self), + MediaBase.serialize(self), + CitationBase.serialize(self), + NoteBase.serialize(self), + self.change, + TagBase.serialize(self), + self.private, + ) @classmethod def get_schema(cls): @@ -129,58 +140,63 @@ def get_schema(cls): """ from .url import Url from .mediaref import MediaRef + return { "type": "object", "title": _("Place"), "properties": { "_class": {"enum": [cls.__name__]}, - "handle": {"type": "string", - "maxLength": 50, - "title": _("Handle")}, - "gramps_id": {"type": "string", - "title": _("Gramps ID")}, - "title": {"type": "string", - "title": _("Title")}, - "long": {"type": "string", - "title": _("Longitude")}, - "lat": {"type": "string", - "title": _("Latitude")}, - "placeref_list": {"type": "array", - "items": PlaceRef.get_schema(), - "title": _("Places")}, + "handle": {"type": "string", "maxLength": 50, "title": _("Handle")}, + "gramps_id": {"type": "string", "title": _("Gramps ID")}, + "title": {"type": "string", "title": _("Title")}, + "long": {"type": "string", "title": _("Longitude")}, + "lat": {"type": "string", "title": _("Latitude")}, + "placeref_list": { + "type": "array", + "items": PlaceRef.get_schema(), + "title": _("Places"), + }, "name": PlaceName.get_schema(), - "alt_names": {"type": "array", - "items": PlaceName.get_schema(), - "title": _("Alternate Names")}, + "alt_names": { + "type": "array", + "items": PlaceName.get_schema(), + "title": _("Alternate Names"), + }, "place_type": PlaceType.get_schema(), - "code": {"type": "string", - "title": _("Code")}, - "alt_loc": {"type": "array", - "items": Location.get_schema(), - "title": _("Alternate Locations")}, - "urls": {"type": "array", - "items": Url.get_schema(), - "title": _("URLs")}, - "media_list": {"type": "array", - "items": MediaRef.get_schema(), - "title": _("Media")}, - "citation_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Citations")}, - "note_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Notes")}, - "change": {"type": "integer", - "title": _("Last changed")}, - "tag_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Tags")}, - "private": {"type": "boolean", - "title": _("Private")} - } + "code": {"type": "string", "title": _("Code")}, + "alt_loc": { + "type": "array", + "items": Location.get_schema(), + "title": _("Alternate Locations"), + }, + "urls": { + "type": "array", + "items": Url.get_schema(), + "title": _("URLs"), + }, + "media_list": { + "type": "array", + "items": MediaRef.get_schema(), + "title": _("Media"), + }, + "citation_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Citations"), + }, + "note_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Notes"), + }, + "change": {"type": "integer", "title": _("Last changed")}, + "tag_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Tags"), + }, + "private": {"type": "boolean", "title": _("Private")}, + }, } def unserialize(self, data): @@ -192,10 +208,26 @@ def unserialize(self, data): Place object :type data: tuple """ - (self.handle, self.gramps_id, self.title, self.long, self.lat, - placeref_list, name, alt_names, the_type, self.code, - alt_loc, urls, media_list, citation_list, note_list, - self.change, tag_list, self.private) = data + ( + self.handle, + self.gramps_id, + self.title, + self.long, + self.lat, + placeref_list, + name, + alt_names, + the_type, + self.code, + alt_loc, + urls, + media_list, + citation_list, + note_list, + self.change, + tag_list, + self.private, + ) = data self.place_type = PlaceType() self.place_type.unserialize(the_type) @@ -227,8 +259,7 @@ def get_text_data_child_list(self): :rtype: list """ - ret = (self.media_list + self.alt_loc + self.urls + - [self.name] + self.alt_names) + ret = self.media_list + self.alt_loc + self.urls + [self.name] + self.alt_names return ret def get_citation_child_list(self): @@ -268,12 +299,14 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - return (self.get_referenced_note_handles() + - self.get_referenced_citation_handles() + - self.get_referenced_tag_handles()) + return ( + self.get_referenced_note_handles() + + self.get_referenced_citation_handles() + + self.get_referenced_tag_handles() + ) def merge(self, acquisition): - """ Merge the content of acquisition into this place. + """Merge the content of acquisition into this place. :param acquisition: The place to merge with the present place. :type acquisition: Place @@ -464,7 +497,7 @@ def _has_handle_reference(self, classname, handle): this object type. :rtype: bool """ - if classname == 'Place': + if classname == "Place": for placeref in self.placeref_list: if placeref.ref == handle: return True @@ -481,7 +514,7 @@ def _replace_handle_reference(self, classname, old_handle, new_handle): :param new_handle: The handle to replace the old one with. :type new_handle: str """ - if classname == 'Place': + if classname == "Place": for placeref in self.placeref_list: if placeref.ref == old_handle: placeref.ref = new_handle diff --git a/gramps/gen/lib/placebase.py b/gramps/gen/lib/placebase.py index 5423e014d32..e3e82fb94f6 100644 --- a/gramps/gen/lib/placebase.py +++ b/gramps/gen/lib/placebase.py @@ -22,15 +22,17 @@ PlaceBase class for Gramps. """ -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # PlaceBase class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PlaceBase: """ Base class for place-aware objects. """ + def __init__(self, source=None): """ Initialize a PlaceBase. diff --git a/gramps/gen/lib/placename.py b/gramps/gen/lib/placename.py index 41881bd68f8..032adeb0429 100644 --- a/gramps/gen/lib/placename.py +++ b/gramps/gen/lib/placename.py @@ -23,22 +23,24 @@ Place name class for Gramps """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .datebase import DateBase from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Place Name # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PlaceName(SecondaryObject, DateBase): """ Place name class. @@ -55,8 +57,8 @@ def __init__(self, source=None, **kwargs): self.value = source.value self.lang = source.lang else: - self.value = '' - self.lang = '' + self.value = "" + self.lang = "" for key in kwargs: if key in ["value", "lang"]: setattr(self, key, kwargs[key]) @@ -67,11 +69,7 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return ( - self.value, - DateBase.serialize(self), - self.lang - ) + return (self.value, DateBase.serialize(self), self.lang) def unserialize(self, data): """ @@ -90,18 +88,19 @@ def get_schema(cls): :rtype: dict """ from .date import Date + return { "type": "object", "title": _("Place Name"), "properties": { "_class": {"enum": [cls.__name__]}, - "value": {"type": "string", - "title": _("Text")}, - "date": {"oneOf": [{"type": "null"}, Date.get_schema()], - "title": _("Date")}, - "lang": {"type": "string", - "title": _("Language")} - } + "value": {"type": "string", "title": _("Text")}, + "date": { + "oneOf": [{"type": "null"}, Date.get_schema()], + "title": _("Date"), + }, + "lang": {"type": "string", "title": _("Language")}, + }, } def get_text_data_list(self): @@ -173,9 +172,11 @@ def is_equivalent(self, other): :returns: Constant indicating degree of equivalence. :rtype: int """ - if (self.value != other.value or - self.date != other.date or - self.lang != other.lang): + if ( + self.value != other.value + or self.date != other.date + or self.lang != other.lang + ): return DIFFERENT else: if self.is_equal(other): diff --git a/gramps/gen/lib/placeref.py b/gramps/gen/lib/placeref.py index 6197f3f570c..727a6123a91 100644 --- a/gramps/gen/lib/placeref.py +++ b/gramps/gen/lib/placeref.py @@ -23,23 +23,25 @@ Place Reference class for Gramps """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .refbase import RefBase from .datebase import DateBase from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Place References # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PlaceRef(RefBase, DateBase, SecondaryObject): """ Place reference class. @@ -59,10 +61,7 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return ( - RefBase.serialize(self), - DateBase.serialize(self) - ) + return (RefBase.serialize(self), DateBase.serialize(self)) def unserialize(self, data): """ @@ -82,17 +81,18 @@ def get_schema(cls): :rtype: dict """ from .date import Date + return { "type": "object", "title": _("Place ref"), "properties": { "_class": {"enum": [cls.__name__]}, - "ref": {"type": "string", - "title": _("Handle"), - "maxLength": 50}, - "date": {"oneOf": [{"type": "null"}, Date.get_schema()], - "title": _("Date")} - } + "ref": {"type": "string", "title": _("Handle"), "maxLength": 50}, + "date": { + "oneOf": [{"type": "null"}, Date.get_schema()], + "title": _("Date"), + }, + }, } def get_text_data_list(self): @@ -142,7 +142,7 @@ def get_referenced_handles(self): objects. :rtype: list """ - return [('Place', self.ref)] + return [("Place", self.ref)] def get_handle_referents(self): """ diff --git a/gramps/gen/lib/placetype.py b/gramps/gen/lib/placetype.py index b0c7120e145..fd1789d9174 100644 --- a/gramps/gen/lib/placetype.py +++ b/gramps/gen/lib/placetype.py @@ -22,17 +22,18 @@ Provide the different place types. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -class PlaceType(GrampsType): +class PlaceType(GrampsType): UNKNOWN = -1 CUSTOM = 0 COUNTRY = 1 @@ -82,7 +83,7 @@ class PlaceType(GrampsType): (FARM, _("Farm"), "Farm"), (BUILDING, _("Building"), "Building"), (NUMBER, _("Number"), "Number"), - ] + ] def __init__(self, value=None): GrampsType.__init__(self, value) diff --git a/gramps/gen/lib/primaryobj.py b/gramps/gen/lib/primaryobj.py index 863f8939d65..5c5bc8eb11d 100644 --- a/gramps/gen/lib/primaryobj.py +++ b/gramps/gen/lib/primaryobj.py @@ -23,18 +23,18 @@ Basic Primary Object class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from abc import abstractmethod -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .tableobj import TableObject from .privacybase import PrivacyBase from .citationbase import CitationBase @@ -43,11 +43,11 @@ from .tagbase import TagBase -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Basic Primary Object class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class BasicPrimaryObject(TableObject, PrivacyBase, TagBase): """ The BasicPrimaryObject is the base class for :class:`~.note.Note` objects. @@ -202,11 +202,12 @@ def replace_media_references(self, old_handle, new_handle): """ pass -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Primary Object class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PrimaryObject(BasicPrimaryObject): """ The PrimaryObject is the base class for all primary objects in the @@ -256,9 +257,9 @@ def has_handle_reference(self, classname, handle): of this object type. :rtype: bool """ - if classname == 'Citation' and isinstance(self, CitationBase): + if classname == "Citation" and isinstance(self, CitationBase): return self.has_citation_reference(handle) - elif classname == 'Media' and isinstance(self, MediaBase): + elif classname == "Media" and isinstance(self, MediaBase): return self.has_media_reference(handle) else: return self._has_handle_reference(classname, handle) @@ -272,11 +273,11 @@ def remove_handle_references(self, classname, handle_list): :param handle_list: The list of handles to be removed. :type handle_list: str """ - if classname == 'Citation' and isinstance(self, CitationBase): + if classname == "Citation" and isinstance(self, CitationBase): self.remove_citation_references(handle_list) - elif classname == 'Media' and isinstance(self, MediaBase): + elif classname == "Media" and isinstance(self, MediaBase): self.remove_media_references(handle_list) - elif classname == 'Note' and isinstance(self, NoteBase): + elif classname == "Note" and isinstance(self, NoteBase): self.remove_note_references(handle_list) else: self._remove_handle_references(classname, handle_list) @@ -292,9 +293,9 @@ def replace_handle_reference(self, classname, old_handle, new_handle): :param new_handle: The handle to replace the old one with. :type new_handle: str """ - if classname == 'Citation' and isinstance(self, CitationBase): + if classname == "Citation" and isinstance(self, CitationBase): self.replace_citation_references(old_handle, new_handle) - elif classname == 'Media' and isinstance(self, MediaBase): + elif classname == "Media" and isinstance(self, MediaBase): self.replace_media_references(old_handle, new_handle) else: self._replace_handle_reference(classname, old_handle, new_handle) diff --git a/gramps/gen/lib/privacybase.py b/gramps/gen/lib/privacybase.py index 872531c4a14..89653f32816 100644 --- a/gramps/gen/lib/privacybase.py +++ b/gramps/gen/lib/privacybase.py @@ -23,11 +23,12 @@ PrivacyBase Object class for Gramps. """ -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # PrivacyBase Object # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PrivacyBase: """ Base class for privacy-aware objects. diff --git a/gramps/gen/lib/refbase.py b/gramps/gen/lib/refbase.py index 8ca742bf4c2..7408ef6abcb 100644 --- a/gramps/gen/lib/refbase.py +++ b/gramps/gen/lib/refbase.py @@ -22,18 +22,19 @@ Base Reference class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from abc import ABCMeta, abstractmethod -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # RefBase class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RefBase(metaclass=ABCMeta): """ Base reference class to manage references to other objects. diff --git a/gramps/gen/lib/repo.py b/gramps/gen/lib/repo.py index 59f4f805edf..263b4b37352 100644 --- a/gramps/gen/lib/repo.py +++ b/gramps/gen/lib/repo.py @@ -25,11 +25,11 @@ Repository object for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .primaryobj import PrimaryObject from .notebase import NoteBase from .addressbase import AddressBase @@ -38,15 +38,16 @@ from .repotype import RepositoryType from .citationbase import IndirectCitationBase from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Repository class # -#------------------------------------------------------------------------- -class Repository(NoteBase, AddressBase, UrlBase, IndirectCitationBase, - PrimaryObject): +# ------------------------------------------------------------------------- +class Repository(NoteBase, AddressBase, UrlBase, IndirectCitationBase, PrimaryObject): """A location where collections of Sources are found.""" def __init__(self): @@ -64,12 +65,18 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (self.handle, self.gramps_id, self.type.serialize(), - str(self.name), - NoteBase.serialize(self), - AddressBase.serialize(self), - UrlBase.serialize(self), - self.change, TagBase.serialize(self), self.private) + return ( + self.handle, + self.gramps_id, + self.type.serialize(), + str(self.name), + NoteBase.serialize(self), + AddressBase.serialize(self), + UrlBase.serialize(self), + self.change, + TagBase.serialize(self), + self.private, + ) @classmethod def get_schema(cls): @@ -81,38 +88,39 @@ def get_schema(cls): """ from .address import Address from .url import Url + return { "type": "object", "title": _("Repository"), "properties": { "_class": {"enum": [cls.__name__]}, - "handle": {"type": "string", - "maxLength": 50, - "title": _("Handle")}, - "gramps_id": {"type": "string", - "title": _("Gramps ID")}, + "handle": {"type": "string", "maxLength": 50, "title": _("Handle")}, + "gramps_id": {"type": "string", "title": _("Gramps ID")}, "type": RepositoryType.get_schema(), - "name": {"type": "string", - "title": _("Name")}, - "note_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Notes")}, - "address_list": {"type": "array", - "items": Address.get_schema(), - "title": _("Addresses")}, - "urls": {"type": "array", - "items": Url.get_schema(), - "title": _("URLs")}, - "change": {"type": "integer", - "title": _("Last changed")}, - "tag_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Tags")}, - "private": {"type": "boolean", - "title": _("Private")} - } + "name": {"type": "string", "title": _("Name")}, + "note_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Notes"), + }, + "address_list": { + "type": "array", + "items": Address.get_schema(), + "title": _("Addresses"), + }, + "urls": { + "type": "array", + "items": Url.get_schema(), + "title": _("URLs"), + }, + "change": {"type": "integer", "title": _("Last changed")}, + "tag_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Tags"), + }, + "private": {"type": "boolean", "title": _("Private")}, + }, } def unserialize(self, data): @@ -120,8 +128,18 @@ def unserialize(self, data): Convert the data held in a tuple created by the serialize method back into the data in a Repository structure. """ - (self.handle, self.gramps_id, the_type, self.name, note_list, - address_list, urls, self.change, tag_list, self.private) = data + ( + self.handle, + self.gramps_id, + the_type, + self.name, + note_list, + address_list, + urls, + self.change, + tag_list, + self.private, + ) = data self.type = RepositoryType() self.type.unserialize(the_type) @@ -187,8 +205,7 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - return (self.get_referenced_note_handles() + - self.get_referenced_tag_handles()) + return self.get_referenced_note_handles() + self.get_referenced_tag_handles() def merge(self, acquisition): """ diff --git a/gramps/gen/lib/reporef.py b/gramps/gen/lib/reporef.py index a4a98231301..4f5711b62ab 100644 --- a/gramps/gen/lib/reporef.py +++ b/gramps/gen/lib/reporef.py @@ -25,11 +25,11 @@ Repository Reference class for Gramps """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .privacybase import PrivacyBase from .notebase import NoteBase @@ -37,13 +37,15 @@ from .srcmediatype import SourceMediaType from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Repository Reference for Sources # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RepoRef(SecondaryObject, PrivacyBase, NoteBase, RefBase): """ Repository reference class. @@ -67,9 +69,10 @@ def serialize(self): return ( NoteBase.serialize(self), RefBase.serialize(self), - self.call_number, self.media_type.serialize(), + self.call_number, + self.media_type.serialize(), PrivacyBase.serialize(self), - ) + ) def unserialize(self, data): """ @@ -96,19 +99,16 @@ def get_schema(cls): "title": _("Repository ref"), "properties": { "_class": {"enum": [cls.__name__]}, - "note_list": {"type": "array", - "title": _("Notes"), - "items": {"type": "string", - "maxLength": 50}}, - "ref": {"type": "string", - "title": _("Handle"), - "maxLength": 50}, - "call_number": {"type": "string", - "title": _("Call Number")}, + "note_list": { + "type": "array", + "title": _("Notes"), + "items": {"type": "string", "maxLength": 50}, + }, + "ref": {"type": "string", "title": _("Handle"), "maxLength": 50}, + "call_number": {"type": "string", "title": _("Call Number")}, "media_type": SourceMediaType.get_schema(), - "private": {"type": "boolean", - "title": _("Private")} - } + "private": {"type": "boolean", "title": _("Private")}, + }, } def get_text_data_list(self): @@ -130,7 +130,7 @@ def get_referenced_handles(self): """ ret = self.get_referenced_note_handles() if self.ref: - ret += [('Repository', self.ref)] + ret += [("Repository", self.ref)] return ret def is_equivalent(self, other): @@ -143,8 +143,10 @@ def is_equivalent(self, other): :returns: Constant indicating degree of equivalence. :rtype: int """ - if self.ref != other.ref or \ - self.get_text_data_list() != other.get_text_data_list(): + if ( + self.ref != other.ref + or self.get_text_data_list() != other.get_text_data_list() + ): return DIFFERENT else: if self.is_equal(other): diff --git a/gramps/gen/lib/repotype.py b/gramps/gen/lib/repotype.py index ccdac97462a..bb0ada3574a 100644 --- a/gramps/gen/lib/repotype.py +++ b/gramps/gen/lib/repotype.py @@ -22,17 +22,18 @@ Repository types. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -class RepositoryType(GrampsType): +class RepositoryType(GrampsType): UNKNOWN = -1 CUSTOM = 0 LIBRARY = 1 @@ -60,7 +61,7 @@ class RepositoryType(GrampsType): (BOOKSTORE, _("Bookstore"), "Bookstore"), (COLLECTION, _("Collection"), "Collection"), (SAFE, _("Safe"), "Safe"), - ] + ] def __init__(self, value=None): GrampsType.__init__(self, value) diff --git a/gramps/gen/lib/researcher.py b/gramps/gen/lib/researcher.py index 5a8caf27056..7b591504118 100644 --- a/gramps/gen/lib/researcher.py +++ b/gramps/gen/lib/researcher.py @@ -23,18 +23,19 @@ Researcher information for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .locationbase import LocationBase -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Researcher(LocationBase): """Contains the information about the owner of the database.""" @@ -57,8 +58,7 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (LocationBase.serialize(self), - self.name, self.addr, self.email) + return (LocationBase.serialize(self), self.name, self.addr, self.email) def unserialize(self, data): """ @@ -86,7 +86,7 @@ def get_address(self): return self.addr def set_email(self, data): - """ Set the database owner's email.""" + """Set the database owner's email.""" self.email = data def get_email(self): @@ -109,14 +109,33 @@ def set_from(self, other_researcher): self.email = other_researcher.email def get(self): - return [getattr(self, value) for value in - ['name', 'addr', 'locality', 'city', 'state', - 'country', 'postal', 'phone', 'email'] - ] + return [ + getattr(self, value) + for value in [ + "name", + "addr", + "locality", + "city", + "state", + "country", + "postal", + "phone", + "email", + ] + ] def is_empty(self): - for attr in ['name', 'addr', 'locality', 'city', 'state', - 'country', 'postal', 'phone', 'email']: + for attr in [ + "name", + "addr", + "locality", + "city", + "state", + "country", + "postal", + "phone", + "email", + ]: if getattr(self, attr) != "": return False return True diff --git a/gramps/gen/lib/secondaryobj.py b/gramps/gen/lib/secondaryobj.py index bc34bba4747..0408816507f 100644 --- a/gramps/gen/lib/secondaryobj.py +++ b/gramps/gen/lib/secondaryobj.py @@ -22,25 +22,26 @@ Secondary Object class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from abc import abstractmethod -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .baseobj import BaseObject -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Secondary Object class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SecondaryObject(BaseObject): """ The SecondaryObject is the base class for all secondary objects in the diff --git a/gramps/gen/lib/serialize.py b/gramps/gen/lib/serialize.py index 6059e14f9ff..df0c323bd7a 100644 --- a/gramps/gen/lib/serialize.py +++ b/gramps/gen/lib/serialize.py @@ -22,50 +22,53 @@ Serialization utilities for Gramps. """ -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Python modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ import json -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Gramps modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ import gramps.gen.lib as lib + def __default(obj): - obj_dict = {'_class': obj.__class__.__name__} + obj_dict = {"_class": obj.__class__.__name__} if isinstance(obj, lib.GrampsType): - obj_dict['string'] = getattr(obj, 'string') + obj_dict["string"] = getattr(obj, "string") if isinstance(obj, lib.Date): if obj.is_empty() and not obj.text: return None for key, value in obj.__dict__.items(): - if not key.startswith('_'): + if not key.startswith("_"): obj_dict[key] = value for key, value in obj.__class__.__dict__.items(): if isinstance(value, property): - if key != 'year': + if key != "year": obj_dict[key] = getattr(obj, key) return obj_dict + def __object_hook(obj_dict): - obj = getattr(lib, obj_dict['_class'])() + obj = getattr(lib, obj_dict["_class"])() for key, value in obj_dict.items(): - if key != '_class': - if key in ('dateval', 'rect') and value is not None: + if key != "_class": + if key in ("dateval", "rect") and value is not None: value = tuple(value) - if key == 'ranges': + if key == "ranges": value = [tuple(item) for item in value] setattr(obj, key, value) - if obj_dict['_class'] == 'Date': + if obj_dict["_class"] == "Date": if obj.is_empty() and not obj.text: return None return obj + def to_json(obj): """ Encode a Gramps object in JSON format. @@ -77,6 +80,7 @@ def to_json(obj): """ return json.dumps(obj, default=__default, ensure_ascii=False) + def from_json(data): """ Decode JSON data into a Gramps object hierarchy. diff --git a/gramps/gen/lib/src.py b/gramps/gen/lib/src.py index 1cebc9fad61..c96ab2818ff 100644 --- a/gramps/gen/lib/src.py +++ b/gramps/gen/lib/src.py @@ -26,11 +26,11 @@ Source object for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .primaryobj import PrimaryObject from .mediabase import MediaBase from .notebase import NoteBase @@ -40,15 +40,18 @@ from .const import DIFFERENT, EQUAL, IDENTICAL from .citationbase import IndirectCitationBase from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Source class # -#------------------------------------------------------------------------- -class Source(MediaBase, NoteBase, SrcAttributeBase, IndirectCitationBase, - PrimaryObject): +# ------------------------------------------------------------------------- +class Source( + MediaBase, NoteBase, SrcAttributeBase, IndirectCitationBase, PrimaryObject +): """A record of a source of information.""" def __init__(self): @@ -67,19 +70,21 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (self.handle, # 0 - self.gramps_id, # 1 - str(self.title), # 2 - str(self.author), # 3 - str(self.pubinfo), # 4 - NoteBase.serialize(self), # 5 - MediaBase.serialize(self), # 6 - str(self.abbrev), # 7 - self.change, # 8 - SrcAttributeBase.serialize(self), # 9 - [rr.serialize() for rr in self.reporef_list], # 10 - TagBase.serialize(self), # 11 - self.private) # 12 + return ( + self.handle, # 0 + self.gramps_id, # 1 + str(self.title), # 2 + str(self.author), # 3 + str(self.pubinfo), # 4 + NoteBase.serialize(self), # 5 + MediaBase.serialize(self), # 6 + str(self.abbrev), # 7 + self.change, # 8 + SrcAttributeBase.serialize(self), # 9 + [rr.serialize() for rr in self.reporef_list], # 10 + TagBase.serialize(self), # 11 + self.private, + ) # 12 @classmethod def get_schema(cls): @@ -92,46 +97,46 @@ def get_schema(cls): from .srcattribute import SrcAttribute from .reporef import RepoRef from .mediaref import MediaRef + return { "type": "object", "title": _("Source"), "properties": { "_class": {"enum": [cls.__name__]}, - "handle": {"type": "string", - "maxLength": 50, - "title": _("Handle")}, - "gramps_id": {"type": "string", - "title": _("Gramps ID")}, - "title": {"type": "string", - "title": _("Title")}, - "author": {"type": "string", - "title": _("Author")}, - "pubinfo": {"type": "string", - "title": _("Publication info")}, - "note_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Notes")}, - "media_list": {"type": "array", - "items": MediaRef.get_schema(), - "title": _("Media")}, - "abbrev": {"type": "string", - "title": _("Abbreviation")}, - "change": {"type": "integer", - "title": _("Last changed")}, - "attribute_list": {"type": "array", - "items": SrcAttribute.get_schema(), - "title": _("Source Attributes")}, - "reporef_list": {"type": "array", - "items": RepoRef.get_schema(), - "title": _("Repositories")}, - "tag_list": {"type": "array", - "items": {"type": "string", - "maxLength": 50}, - "title": _("Tags")}, - "private": {"type": "boolean", - "title": _("Private")} - } + "handle": {"type": "string", "maxLength": 50, "title": _("Handle")}, + "gramps_id": {"type": "string", "title": _("Gramps ID")}, + "title": {"type": "string", "title": _("Title")}, + "author": {"type": "string", "title": _("Author")}, + "pubinfo": {"type": "string", "title": _("Publication info")}, + "note_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Notes"), + }, + "media_list": { + "type": "array", + "items": MediaRef.get_schema(), + "title": _("Media"), + }, + "abbrev": {"type": "string", "title": _("Abbreviation")}, + "change": {"type": "integer", "title": _("Last changed")}, + "attribute_list": { + "type": "array", + "items": SrcAttribute.get_schema(), + "title": _("Source Attributes"), + }, + "reporef_list": { + "type": "array", + "items": RepoRef.get_schema(), + "title": _("Repositories"), + }, + "tag_list": { + "type": "array", + "items": {"type": "string", "maxLength": 50}, + "title": _("Tags"), + }, + "private": {"type": "boolean", "title": _("Private")}, + }, } def unserialize(self, data): @@ -139,19 +144,20 @@ def unserialize(self, data): Convert the data held in a tuple created by the serialize method back into the data in a Source structure. """ - (self.handle, # 0 - self.gramps_id, # 1 - self.title, # 2 - self.author, # 3 - self.pubinfo, # 4 - note_list, # 5 - media_list, # 6 - self.abbrev, # 7 - self.change, # 8 - srcattr_list, # 9 - reporef_list, # 10 - tag_list, # 11 - self.private # 12 + ( + self.handle, # 0 + self.gramps_id, # 1 + self.title, # 2 + self.author, # 3 + self.pubinfo, # 4 + note_list, # 5 + media_list, # 6 + self.abbrev, # 7 + self.change, # 8 + srcattr_list, # 9 + reporef_list, # 10 + tag_list, # 11 + self.private, # 12 ) = data NoteBase.unserialize(self, note_list) @@ -174,7 +180,7 @@ def _has_handle_reference(self, classname, handle): this object type. :rtype: bool """ - if classname == 'Repository': + if classname == "Repository": return handle in [ref.ref for ref in self.reporef_list] return False @@ -187,9 +193,8 @@ def _remove_handle_references(self, classname, handle_list): :param handle_list: The list of handles to be removed. :type handle_list: str """ - if classname == 'Repository': - new_list = [ref for ref in self.reporef_list - if ref.ref not in handle_list] + if classname == "Repository": + new_list = [ref for ref in self.reporef_list if ref.ref not in handle_list] self.reporef_list = new_list def _replace_handle_reference(self, classname, old_handle, new_handle): @@ -203,12 +208,12 @@ def _replace_handle_reference(self, classname, old_handle, new_handle): :param new_handle: The handle to replace the old one with. :type new_handle: str """ - if classname == 'Repository': + if classname == "Repository": handle_list = [ref.ref for ref in self.reporef_list] while old_handle in handle_list: idx = handle_list.index(old_handle) self.reporef_list[idx].ref = new_handle - handle_list[idx] = '' + handle_list[idx] = "" def get_text_data_list(self): """ @@ -217,8 +222,7 @@ def get_text_data_list(self): :returns: Returns the list of all textual attributes of the object. :rtype: list """ - return [self.title, self.author, self.pubinfo, self.abbrev, - self.gramps_id] + return [self.title, self.author, self.pubinfo, self.abbrev, self.gramps_id] def get_text_data_child_list(self): """ @@ -267,8 +271,7 @@ def get_referenced_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - return (self.get_referenced_note_handles() + - self.get_referenced_tag_handles()) + return self.get_referenced_note_handles() + self.get_referenced_tag_handles() def merge(self, acquisition): """ @@ -398,8 +401,11 @@ def remove_repo_references(self, repo_handle_list): :param repo_handle_list: The list of Repository handles to be removed. :type repo_handle_list: list """ - new_reporef_list = [repo_ref for repo_ref in self.reporef_list - if repo_ref.ref not in repo_handle_list] + new_reporef_list = [ + repo_ref + for repo_ref in self.reporef_list + if repo_ref.ref not in repo_handle_list + ] self.reporef_list = new_reporef_list def replace_repo_references(self, old_handle, new_handle): diff --git a/gramps/gen/lib/srcattribute.py b/gramps/gen/lib/srcattribute.py index b98625efda3..59eaf9f73f4 100644 --- a/gramps/gen/lib/srcattribute.py +++ b/gramps/gen/lib/srcattribute.py @@ -23,21 +23,23 @@ Source Attribute class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .attribute import AttributeRoot from .srcattrtype import SrcAttributeType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Attribute for Source/Citation # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SrcAttribute(AttributeRoot): """ Provide a simple key/value pair for describing properties. @@ -70,10 +72,8 @@ def get_schema(cls): "title": _("Attribute"), "properties": { "_class": {"enum": [cls.__name__]}, - "private": {"type": "boolean", - "title": _("Private")}, + "private": {"type": "boolean", "title": _("Private")}, "type": SrcAttributeType.get_schema(), - "value": {"type": "string", - "title": _("Value")} - } + "value": {"type": "string", "title": _("Value")}, + }, } diff --git a/gramps/gen/lib/srcattrtype.py b/gramps/gen/lib/srcattrtype.py index f82e4a18cde..db2067e27b5 100644 --- a/gramps/gen/lib/srcattrtype.py +++ b/gramps/gen/lib/srcattrtype.py @@ -22,17 +22,18 @@ Provide the different Source Attribute Types for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -class SrcAttributeType(GrampsType): +class SrcAttributeType(GrampsType): UNKNOWN = -1 CUSTOM = 0 @@ -42,7 +43,7 @@ class SrcAttributeType(GrampsType): _DATAMAP = [ (UNKNOWN, _("Unknown"), "Unknown"), (CUSTOM, _("Custom"), "Custom"), - ] + ] def __init__(self, value=None): GrampsType.__init__(self, value) diff --git a/gramps/gen/lib/srcmediatype.py b/gramps/gen/lib/srcmediatype.py index 4f121efdb2e..5395fe0a9c5 100644 --- a/gramps/gen/lib/srcmediatype.py +++ b/gramps/gen/lib/srcmediatype.py @@ -22,17 +22,18 @@ SourceMedia types. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -class SourceMediaType(GrampsType): +class SourceMediaType(GrampsType): UNKNOWN = -1 CUSTOM = 0 AUDIO = 1 @@ -68,7 +69,7 @@ class SourceMediaType(GrampsType): (PHOTO, _("Photo"), "Photo"), (TOMBSTONE, _("Tombstone"), "Tombstone"), (VIDEO, _("Video"), "Video"), - ] + ] def __init__(self, value=None): GrampsType.__init__(self, value) diff --git a/gramps/gen/lib/styledtext.py b/gramps/gen/lib/styledtext.py index 0b6800f1dec..89b66cd0c6f 100644 --- a/gramps/gen/lib/styledtext.py +++ b/gramps/gen/lib/styledtext.py @@ -22,21 +22,23 @@ "Handling formatted ('rich text') strings" -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from copy import copy from .styledtexttag import StyledTextTag from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # StyledText class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class StyledText: """Helper class to enable character based text formatting. @@ -81,6 +83,7 @@ class StyledText: 3. Warning: Some of these operations modify the source tag ranges in place so if you intend to use a source tag more than once, copy it for use. """ + (POS_TEXT, POS_TAGS) = list(range(2)) def __init__(self, text="", tags=None): @@ -114,17 +117,18 @@ def __add__(self, other): if isinstance(other, StyledText): # need to join strings and merge tags for tag in other.tags: - tag.ranges = [(start + offset, end + offset) - for (start, end) in tag.ranges] + tag.ranges = [ + (start + offset, end + offset) for (start, end) in tag.ranges + ] - return self.__class__("".join([self._string, other.string]), - self._tags + other.tags) + return self.__class__( + "".join([self._string, other.string]), self._tags + other.tags + ) elif isinstance(other, str): # tags remain the same, only text becomes longer return self.__class__("".join([self._string, other]), self._tags) else: - return self.__class__("".join([self._string, str(other)]), - self._tags) + return self.__class__("".join([self._string, str(other)]), self._tags) def __eq__(self, other): return self._string == other.string and self._tags == other.tags @@ -154,18 +158,18 @@ def __mod__(self, other): start = 0 while True: - idx1 = result.string.find('%', start) + idx1 = result.string.find("%", start) if idx1 < 0: break - if result.string[idx1+1] == '(': - idx2 = result.string.find(')', idx1+3) - param_name = result.string[idx1+2:idx2] + if result.string[idx1 + 1] == "(": + idx2 = result.string.find(")", idx1 + 3) + param_name = result.string[idx1 + 2 : idx2] else: idx2 = idx1 param_name = None end = idx2 + 1 - for end in range(idx2+1, len(result.string)): - if result.string[end] in 'diouxXeEfFgGcrs%': + for end in range(idx2 + 1, len(result.string)): + if result.string[end] in "diouxXeEfFgGcrs%": break if param_name is not None: param = other[param_name] @@ -175,9 +179,9 @@ def __mod__(self, other): else: param = other if not isinstance(param, StyledText): - param_type = '%' + result.string[idx2+1:end+1] + param_type = "%" + result.string[idx2 + 1 : end + 1] param = StyledText(param_type % param) - parts = result.split(result.string[idx1:end+1], 1) + parts = result.split(result.string[idx1 : end + 1], 1) if len(parts) == 2: result = parts[0] + param + parts[1] start = end + 1 @@ -186,7 +190,6 @@ def __mod__(self, other): # private methods - # string methods in alphabetical order: def join(self, seq): @@ -210,15 +213,17 @@ def join(self, seq): # put the joined element tag(s) into place for tag in self.tags: ntag = copy(tag) - ntag.ranges = [(start + offset, end + offset) - for (start, end) in tag.ranges] + ntag.ranges = [ + (start + offset, end + offset) for (start, end) in tag.ranges + ] new_tags += [ntag] offset += self_len if isinstance(text, StyledText): for tag in text.tags: ntag = copy(tag) - ntag.ranges = [(start + offset, end + offset) - for (start, end) in tag.ranges] + ntag.ranges = [ + (start + offset, end + offset) for (start, end) in tag.ranges + ] new_tags += [ntag] offset += len(str(text)) not_first = True @@ -273,13 +278,14 @@ def split(self, sep=None, maxsplit=-1): for tag in self._tags: new_tag = StyledTextTag(int(tag.name), tag.value) - for (start_tag, end_tag) in tag.ranges: + for start_tag, end_tag in tag.ranges: start = max(start_string, start_tag) end = min(end_string, end_tag) if start < end: - new_tag.ranges.append((start - start_string, - end - start_string)) + new_tag.ranges.append( + (start - start_string, end - start_string) + ) if new_tag.ranges: new_tags.append(new_tag) @@ -318,12 +324,13 @@ def get_schema(cls): "title": _("Styled Text"), "properties": { "_class": {"enum": [cls.__name__]}, - "string": {"type": "string", - "title": _("Text")}, - "tags": {"type": "array", - "items": StyledTextTag.get_schema(), - "title": _("Styled Text Tags")} - } + "string": {"type": "string", "title": _("Text")}, + "tags": { + "type": "array", + "items": StyledTextTag.get_schema(), + "title": _("Styled Text Tags"), + }, + }, } def unserialize(self, data): @@ -336,7 +343,7 @@ def unserialize(self, data): (self._string, the_tags) = data # I really wonder why this doesn't work... it does for all other types - #self._tags = [StyledTextTag().unserialize(tag) for tag in the_tags] + # self._tags = [StyledTextTag().unserialize(tag) for tag in the_tags] for tag in the_tags: stt = StyledTextTag() stt.unserialize(tag) @@ -376,22 +383,24 @@ def set_string(self, string): tags = property(get_tags, set_tags) string = property(get_string, set_string) -if __name__ == '__main__': + +if __name__ == "__main__": from .styledtexttagtype import StyledTextTagType - T1 = StyledTextTag(StyledTextTagType(1), 'v1', [(0, 2), (2, 4), (4, 6)]) - T2 = StyledTextTag(StyledTextTagType(2), 'v2', [(1, 3), (3, 5), (0, 7)]) - T3 = StyledTextTag(StyledTextTagType(0), 'v3', [(0, 1)]) - A = StyledText('123X456', [T1]) + T1 = StyledTextTag(StyledTextTagType(1), "v1", [(0, 2), (2, 4), (4, 6)]) + T2 = StyledTextTag(StyledTextTagType(2), "v2", [(1, 3), (3, 5), (0, 7)]) + T3 = StyledTextTag(StyledTextTagType(0), "v3", [(0, 1)]) + + A = StyledText("123X456", [T1]) B = StyledText("abcXdef", [T2]) - C = StyledText('\n') + C = StyledText("\n") - S = 'cleartext' + S = "cleartext" C = C.join([A, S, B]) L = C.split() - C = C.replace('X', StyledText('_', [T3])) + C = C.replace("X", StyledText("_", [T3])) A = A + B print(A) diff --git a/gramps/gen/lib/styledtexttag.py b/gramps/gen/lib/styledtexttag.py index 56ba7043eec..fe0b23dea39 100644 --- a/gramps/gen/lib/styledtexttag.py +++ b/gramps/gen/lib/styledtexttag.py @@ -22,20 +22,22 @@ "Provide formatting tag definition for StyledText." -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .styledtexttagtype import StyledTextTagType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # StyledTextTag class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class StyledTextTag: """Hold formatting information for :py:class:`.StyledText`. @@ -50,6 +52,7 @@ class StyledTextTag: :type ranges: list of (int(start), int(end)) tuples. """ + def __init__(self, name=None, value=None, ranges=None): """Setup initial instance variable values. @@ -102,13 +105,16 @@ def get_schema(cls): "properties": { "_class": {"enum": [cls.__name__]}, "name": StyledTextTagType.get_schema(), - "value": {"type": ["null", "string", "integer"], - "title": _("Value")}, - "ranges": {"type": "array", - "items": {"type": "array", - "items": {"type": "integer"}, - "minItems": 2, - "maxItems": 2}, - "title": _("Ranges")} - } + "value": {"type": ["null", "string", "integer"], "title": _("Value")}, + "ranges": { + "type": "array", + "items": { + "type": "array", + "items": {"type": "integer"}, + "minItems": 2, + "maxItems": 2, + }, + "title": _("Ranges"), + }, + }, } diff --git a/gramps/gen/lib/styledtexttagtype.py b/gramps/gen/lib/styledtexttagtype.py index 587768ba476..74286579d04 100644 --- a/gramps/gen/lib/styledtexttagtype.py +++ b/gramps/gen/lib/styledtexttagtype.py @@ -22,20 +22,22 @@ Define text formatting tag types. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # StyledTextTagType class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class StyledTextTagType(GrampsType): """ Text formatting tag type definition. @@ -43,6 +45,7 @@ class StyledTextTagType(GrampsType): Here we only define new class variables. For details see :class:`~gen.lib.grampstype.GrampsType`. """ + NONE_TYPE = -1 BOLD = 0 ITALIC = 1 @@ -91,12 +94,12 @@ class StyledTextTagType(GrampsType): BOLD: False, ITALIC: False, UNDERLINE: False, - FONTCOLOR: '#000000', - HIGHLIGHT: '#FFFFFF', - FONTFACE: 'Sans', + FONTCOLOR: "#000000", + HIGHLIGHT: "#FFFFFF", + FONTFACE: "Sans", FONTSIZE: 10, SUPERSCRIPT: False, - LINK: '', + LINK: "", STRIKETHROUGH: False, SUBSCRIPT: False, } diff --git a/gramps/gen/lib/surname.py b/gramps/gen/lib/surname.py index ad45dff7002..df106fbe049 100644 --- a/gramps/gen/lib/surname.py +++ b/gramps/gen/lib/surname.py @@ -24,22 +24,24 @@ Surname class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .nameorigintype import NameOriginType from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Personal Name # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Surname(SecondaryObject): """ Provide surname information of a name. @@ -71,8 +73,13 @@ def serialize(self): """ Convert the object to a serialized tuple of data. """ - return (self.surname, self.prefix, self.primary, - self.origintype.serialize(), self.connector) + return ( + self.surname, + self.prefix, + self.primary, + self.origintype.serialize(), + self.connector, + ) @classmethod def get_schema(cls): @@ -87,31 +94,25 @@ def get_schema(cls): "title": _("Surname"), "properties": { "_class": {"enum": [cls.__name__]}, - "surname": {"type": "string", - "title": _("Surname")}, - "prefix": {"type": "string", - "title": _("Prefix")}, - "primary": {"type": "boolean", - "title": _("Primary")}, + "surname": {"type": "string", "title": _("Surname")}, + "prefix": {"type": "string", "title": _("Prefix")}, + "primary": {"type": "boolean", "title": _("Primary")}, "origintype": NameOriginType.get_schema(), - "connector": {"type": "string", - "title": _("Connector")} - } + "connector": {"type": "string", "title": _("Connector")}, + }, } def is_empty(self): """ Indicate if the surname is empty. """ - return (self.surname == "" and self.prefix == "" and - self.connector == "") + return self.surname == "" and self.prefix == "" and self.connector == "" def unserialize(self, data): """ Convert a serialized tuple of data to an object. """ - (self.surname, self.prefix, self.primary, origin_type, - self.connector) = data + (self.surname, self.prefix, self.primary, origin_type, self.connector) = data self.origintype = NameOriginType(origin_type) return self @@ -122,8 +123,7 @@ def get_text_data_list(self): :returns: Returns the list of all textual attributes of the object. :rtype: list """ - return [self.surname, self.prefix, self.connector, - str(self.origintype)] + return [self.surname, self.prefix, self.connector, str(self.origintype)] def is_equivalent(self, other): """ @@ -136,8 +136,10 @@ def is_equivalent(self, other): :rtype: int """ # TODO what to do with sort and display? - if self.get_text_data_list() != other.get_text_data_list() or \ - self.primary != other.primary: + if ( + self.get_text_data_list() != other.get_text_data_list() + or self.primary != other.primary + ): return DIFFERENT else: if self.is_equal(other): @@ -156,7 +158,6 @@ def merge(self, acquisition): """ pass - def get_surname(self): """ Return the surname. diff --git a/gramps/gen/lib/surnamebase.py b/gramps/gen/lib/surnamebase.py index 1fc807f0bd8..9cbaaa777f6 100644 --- a/gramps/gen/lib/surnamebase.py +++ b/gramps/gen/lib/surnamebase.py @@ -22,21 +22,23 @@ SurnameBase class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .surname import Surname from .const import IDENTICAL, EQUAL from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # SurnameBase classes # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SurnameBase: """ Base class for surname-aware objects. @@ -135,7 +137,7 @@ def get_primary_surname(self): if self.surname_list: return self.surname_list[0] else: - #self healing, add a surname to this object and return it + # self healing, add a surname to this object and return it self.set_surname_list([Surname()]) return self.surname_list[0] @@ -144,7 +146,9 @@ def set_primary_surname(self, surnamenr=0): Set the surname with surnamenr in the surname list as primary surname Counting starts at 0 """ - assert isinstance(surnamenr, int), "Surname.set_primary_surname requires integer" + assert isinstance( + surnamenr, int + ), "Surname.set_primary_surname requires integer" if surnamenr >= len(self.surname_list): return for surname in self.surname_list: @@ -169,7 +173,7 @@ def _merge_surname_list(self, acquisition): if equi == IDENTICAL: break elif equi == EQUAL: - #This should normally never happen, an alternate name + # This should normally never happen, an alternate name # should be added surname.merge(addendum) break @@ -184,17 +188,23 @@ def get_surname(self): for surn in self.surname_list: partsurn = surn.get_surname() if surn.get_prefix(): - fsurn = _('%(first)s %(second)s') % {'first': surn.get_prefix(), - 'second': partsurn} + fsurn = _("%(first)s %(second)s") % { + "first": surn.get_prefix(), + "second": partsurn, + } else: fsurn = partsurn fsurn = fsurn.strip() if surn.get_connector(): - fsurn = _('%(first)s %(second)s') % {'first': fsurn, - 'second': surn.get_connector()} + fsurn = _("%(first)s %(second)s") % { + "first": fsurn, + "second": surn.get_connector(), + } fsurn = fsurn.strip() - totalsurn = _('%(first)s %(second)s') % {'first': totalsurn, - 'second': fsurn} + totalsurn = _("%(first)s %(second)s") % { + "first": totalsurn, + "second": fsurn, + } return totalsurn.strip() def get_primary(self): @@ -204,8 +214,10 @@ def get_primary(self): primary = self.get_primary_surname() partsurn = primary.get_surname() if primary.get_prefix(): - fsurn = _('%(first)s %(second)s') % {'first': primary.get_prefix(), - 'second': partsurn} + fsurn = _("%(first)s %(second)s") % { + "first": primary.get_prefix(), + "second": partsurn, + } else: fsurn = partsurn return fsurn.strip() diff --git a/gramps/gen/lib/tableobj.py b/gramps/gen/lib/tableobj.py index c40e4da1a1b..bc944798689 100644 --- a/gramps/gen/lib/tableobj.py +++ b/gramps/gen/lib/tableobj.py @@ -23,34 +23,37 @@ Table Object class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from abc import abstractmethod import time -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .baseobj import BaseObject from ..errors import HandleError -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Localized constants # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..const import GRAMPS_LOCALE as glocale + CODESET = glocale.encoding -#------------------------------------------------------------------------- + + +# ------------------------------------------------------------------------- # # Table Object class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class TableObject(BaseObject): """ The TableObject is the base class for all objects that are stored in a @@ -125,10 +128,9 @@ def get_change_display(self): """ if self.change: - return str(time.strftime('%x %X', time.localtime(self.change)), - CODESET) + return str(time.strftime("%x %X", time.localtime(self.change)), CODESET) else: - return '' + return "" def set_handle(self, handle): """ @@ -161,7 +163,7 @@ def get_secondary_fields(cls): Return all secondary fields and their types """ result = [] - for (key, value) in cls.get_schema()["properties"].items(): + for key, value in cls.get_schema()["properties"].items(): schema_type = value.get("type") if isinstance(schema_type, list): schema_type.remove("null") @@ -169,7 +171,5 @@ def get_secondary_fields(cls): elif isinstance(schema_type, dict): schema_type = None if schema_type in ("string", "integer", "number", "boolean"): - result.append((key.lower(), - schema_type, - value.get("maxLength"))) + result.append((key.lower(), schema_type, value.get("maxLength"))) return result diff --git a/gramps/gen/lib/tag.py b/gramps/gen/lib/tag.py index 3f00b3c37f8..c8b937130a1 100644 --- a/gramps/gen/lib/tag.py +++ b/gramps/gen/lib/tag.py @@ -23,20 +23,22 @@ Tag object for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .tableobj import TableObject from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Tag class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Tag(TableObject): """ The Tag record is used to store information about a tag that can be @@ -59,7 +61,7 @@ def __init__(self, source=None): self.__priority = source.priority else: self.__name = "" - self.__color = "#000000000000" # Black + self.__color = "#000000000000" # Black self.__priority = 0 def serialize(self): @@ -80,11 +82,7 @@ def serialize(self): be considered persistent. :rtype: tuple """ - return (self.handle, - self.__name, - self.__color, - self.__priority, - self.change) + return (self.handle, self.__name, self.__color, self.__priority, self.change) def unserialize(self, data): """ @@ -95,11 +93,7 @@ def unserialize(self, data): object :type data: tuple """ - (self.handle, - self.__name, - self.__color, - self.__priority, - self.change) = data + (self.handle, self.__name, self.__color, self.__priority, self.change) = data return self @classmethod @@ -115,20 +109,12 @@ def get_schema(cls): "title": _("Tag"), "properties": { "_class": {"enum": [cls.__name__]}, - "handle": {"type": "string", - "maxLength": 50, - "title": _("Handle")}, - "name": {"type": "string", - "title": _("Name")}, - "color": {"type": "string", - "maxLength": 13, - "title": _("Color")}, - "priority": {"type": "integer", - "minimum": 0, - "title": _("Priority")}, - "change": {"type": "integer", - "title": _("Last changed")} - } + "handle": {"type": "string", "maxLength": 50, "title": _("Handle")}, + "name": {"type": "string", "title": _("Name")}, + "color": {"type": "string", "maxLength": 13, "title": _("Color")}, + "priority": {"type": "integer", "minimum": 0, "title": _("Priority")}, + "change": {"type": "integer", "title": _("Last changed")}, + }, } def get_text_data_list(self): @@ -161,9 +147,11 @@ def are_equal(self, other): if other is None: other = Tag() - if (self.__name != other.name or - self.__color != other.color or - self.__priority != other.priority): + if ( + self.__name != other.name + or self.__color != other.color + or self.__priority != other.priority + ): return False return True @@ -184,8 +172,8 @@ def get_name(self): :rtype: str """ return self.__name - name = property(get_name, set_name, None, - 'Returns or sets name of the tag') + + name = property(get_name, set_name, None, "Returns or sets name of the tag") def set_color(self, color): """ @@ -206,8 +194,8 @@ def get_color(self): :rtype: str """ return self.__color - color = property(get_color, set_color, None, - 'Returns or sets color of the tag') + + color = property(get_color, set_color, None, "Returns or sets color of the tag") def set_priority(self, priority): """ @@ -229,5 +217,6 @@ def get_priority(self): """ return self.__priority - priority = property(get_priority, set_priority, None, - 'Returns or sets priority of the tag') + priority = property( + get_priority, set_priority, None, "Returns or sets priority of the tag" + ) diff --git a/gramps/gen/lib/tagbase.py b/gramps/gen/lib/tagbase.py index 69346732554..eb0d90347c4 100644 --- a/gramps/gen/lib/tagbase.py +++ b/gramps/gen/lib/tagbase.py @@ -22,11 +22,12 @@ TagBase class for Gramps. """ -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # TagBase class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class TagBase: """ Base class for tag-aware objects. @@ -116,7 +117,7 @@ def get_referenced_tag_handles(self): :returns: List of (classname, handle) tuples for referenced objects. :rtype: list """ - return [('Tag', handle) for handle in self.tag_list] + return [("Tag", handle) for handle in self.tag_list] def _merge_tag_list(self, acquisition): """ @@ -151,4 +152,3 @@ def replace_tag_references(self, old_handle, new_handle): refs_list.pop(idx) else: self.tag_list[idx] = new_handle - diff --git a/gramps/gen/lib/test/date_test.py b/gramps/gen/lib/test/date_test.py index fe608ca57ac..af92a81e67d 100644 --- a/gramps/gen/lib/test/date_test.py +++ b/gramps/gen/lib/test/date_test.py @@ -280,6 +280,7 @@ ) dates.append(d) + # CAL_SWEDISH - Swedish calendar 1700-03-01 -> 1712-02-30! class Context: def __init__(self, retval): @@ -345,6 +346,7 @@ def __exit__(self, *args, **kwargs): d.set(quality, modifier, calendar, (4, month, year, False), "Text comment") swedish_dates.append(d) + # ------------------------------------------------------------------------- # # BaseDateTest @@ -1232,6 +1234,7 @@ def test_span_empty(self): d.set(value=(1, 1, 1900, False, 1, 1, 1910, False), modifier=Date.MOD_SPAN) self.assertFalse(d.is_empty()) + # ------------------------------------------------------------------------- # # AnniversaryDateTest @@ -1243,27 +1246,27 @@ class AnniversaryDateTest(BaseDateTest): """ def test_leapyear_1(self): - config.set('preferences.february-29', 0) + config.set("preferences.february-29", 0) d = Date(1904, 2, 29) self.assertEqual(d.anniversary(1908), (2, 29)) def test_leapyear_2(self): - config.set('preferences.february-29', 1) + config.set("preferences.february-29", 1) d = Date(1904, 2, 29) self.assertEqual(d.anniversary(1908), (2, 29)) def test_nonleapyear_before(self): - config.set('preferences.february-29', 0) + config.set("preferences.february-29", 0) d = Date(1904, 2, 29) self.assertEqual(d.anniversary(1910), (2, 28)) def test_nonleapyear_after(self): - config.set('preferences.february-29', 1) + config.set("preferences.february-29", 1) d = Date(1904, 2, 29) self.assertEqual(d.anniversary(1910), (3, 1)) def test_nonleapyear_keep(self): - config.set('preferences.february-29', 2) + config.set("preferences.february-29", 2) d = Date(1904, 2, 29) self.assertEqual(d.anniversary(1910), (2, 29)) diff --git a/gramps/gen/lib/test/grampstype_test.py b/gramps/gen/lib/test/grampstype_test.py index d54eda8d86f..c20192538fc 100644 --- a/gramps/gen/lib/test/grampstype_test.py +++ b/gramps/gen/lib/test/grampstype_test.py @@ -27,14 +27,16 @@ # some simple map items to test with vals = "zz ab cd ef".split() keys = list(range(len(vals))) -MAP = [(k, v*2, v) for (k, v) in zip(keys, vals)] -BLIST= [1,3] +MAP = [(k, v * 2, v) for (k, v) in zip(keys, vals)] +BLIST = [1, 3] + class GT0(GrampsType): - _DEFAULT = 1 # just avoiding the pre-coded 0 - _CUSTOM = 3 # just avoiding the pre-coded 0 + _DEFAULT = 1 # just avoiding the pre-coded 0 + _CUSTOM = 3 # just avoiding the pre-coded 0 _DATAMAP = MAP + # NOTE: this type of code might be used in a migration utility # to allow conversions or other handling of retired type-values # A migration utility might instantiate several of these with @@ -42,9 +44,11 @@ class GT0(GrampsType): class GT1(GT0): _BLACKLIST = BLIST + class GT2(GT1): _BLACKLIST = None + class Test1(unittest.TestCase): # some basic tests def test_basic(self): @@ -61,23 +65,24 @@ def test_basic(self): # NB: tuple tests w/ lengths < 2 fail before release 10403 def test_init_value(self): for i, v, u in ( - (None, 1, 'abab'), # all DEFAULT - (0, 0, 'zzzz'), - (1, 1, 'abab'), - ('efef', 3, 'efef'), # matches CUSTOM - ('zzzz', 0, 'zzzz'), - ('x', 3, 'x'), # nomatch gives CUSTOM - ('', 3, ''), # nomatch gives CUSTOM - ((0,'zero'), 0, 'zzzz'), # normal behavior - ((2,), 2, 'cdcd'), # DEFAULT-string, just like int - ((), 1, 'abab'), # DEFAULT-pair - ): + (None, 1, "abab"), # all DEFAULT + (0, 0, "zzzz"), + (1, 1, "abab"), + ("efef", 3, "efef"), # matches CUSTOM + ("zzzz", 0, "zzzz"), + ("x", 3, "x"), # nomatch gives CUSTOM + ("", 3, ""), # nomatch gives CUSTOM + ((0, "zero"), 0, "zzzz"), # normal behavior + ((2,), 2, "cdcd"), # DEFAULT-string, just like int + ((), 1, "abab"), # DEFAULT-pair + ): self.gt = GT0(i) g = self.gt.value self.assertEqual(g, v) g = self.gt.string self.assertEqual(g, u) + # test blacklist functionality added to enable fix of bug #1680 class Test2(unittest.TestCase): def test_blacklist(self): @@ -87,11 +92,12 @@ def test_blacklist(self): g = len(self.gt._E2IMAP) self.assertEqual(g, e) - self.ub=GT2() + self.ub = GT2() # check that these MAPS are now un-blacklisted e = len(keys) g = len(self.ub._E2IMAP) self.assertEqual(g, e) + if __name__ == "__main__": unittest.main() diff --git a/gramps/gen/lib/test/merge_test.py b/gramps/gen/lib/test/merge_test.py index ff6faf89dbb..82dd8b6c1c8 100644 --- a/gramps/gen/lib/test/merge_test.py +++ b/gramps/gen/lib/test/merge_test.py @@ -22,14 +22,48 @@ import unittest -from .. import (Person, Surname, Name, NameType, Family, FamilyRelType, - Event, EventType, Source, Place, PlaceName, Citation, Date, - Repository, RepositoryType, Media, Note, NoteType, - StyledText, StyledTextTag, StyledTextTagType, Tag, - ChildRef, ChildRefType, Attribute, MediaRef, AttributeType, - Url, UrlType, Address, EventRef, EventRoleType, RepoRef, - FamilyRelType, LdsOrd, MediaRef, PersonRef, PlaceType, - SrcAttribute, SrcAttributeType) +from .. import ( + Person, + Surname, + Name, + NameType, + Family, + FamilyRelType, + Event, + EventType, + Source, + Place, + PlaceName, + Citation, + Date, + Repository, + RepositoryType, + Media, + Note, + NoteType, + StyledText, + StyledTextTag, + StyledTextTagType, + Tag, + ChildRef, + ChildRefType, + Attribute, + MediaRef, + AttributeType, + Url, + UrlType, + Address, + EventRef, + EventRoleType, + RepoRef, + FamilyRelType, + LdsOrd, + MediaRef, + PersonRef, + PlaceType, + SrcAttribute, + SrcAttributeType, +) from ..privacybase import PrivacyBase from ..urlbase import UrlBase from ..addressbase import AddressBase @@ -42,6 +76,7 @@ from ..tagbase import TagBase from ..const import IDENTICAL, EQUAL, DIFFERENT + class PrivacyBaseTest: def test_privacy_merge(self): self.assertEqual(self.phoenix.serialize(), self.titanic.serialize()) @@ -50,33 +85,37 @@ def test_privacy_merge(self): self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) + class NoteBaseTest: def test_note_merge(self): - note_handle = '123456' + note_handle = "123456" self.titanic.add_note(note_handle) self.ref_obj.add_note(note_handle) self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) + class CitationBaseTest: def test_citation_merge(self): citation = Citation() - citation.set_reference_handle('123456') - citation.set_page('p.10') + citation.set_reference_handle("123456") + citation.set_page("p.10") self.titanic.add_citation(citation.handle) self.ref_obj.add_citation(citation.handle) self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) + class MediaBaseTest: def test_media_merge(self): mediaref = MediaRef() - mediaref.set_reference_handle('123456') + mediaref.set_reference_handle("123456") self.titanic.add_media_reference(mediaref) self.ref_obj.add_media_reference(mediaref) self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) + class AttrBaseTest: def test_attribute_merge(self): attr = Attribute() @@ -87,22 +126,28 @@ def test_attribute_merge(self): self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) + class UrlBaseTest: def test_url_merge(self): url = Url() - url.set_path('http://example.com') + url.set_path("http://example.com") self.titanic.add_url(url) self.ref_obj.add_url(url) self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) -#=========================================================== + + +# =========================================================== + class PrivacyCheck(unittest.TestCase): def test_privacy(self): - known_values = ( (False, False, False), - (True, False, True), - (False, True, True), - (True, True, True) ) + known_values = ( + (False, False, False), + (True, False, True), + (False, True, True), + (True, True, True), + ) phoenix = PrivacyBase() titanic = PrivacyBase() for value1, value2, value_merge in known_values: @@ -111,18 +156,19 @@ def test_privacy(self): phoenix._merge_privacy(titanic) self.assertEqual(phoenix.get_privacy(), value_merge) + class UrlCheck(unittest.TestCase, PrivacyBaseTest): def setUp(self): self.phoenix = Url() - self.phoenix.set_path('http://example1.com') - self.phoenix.set_description('hello world') + self.phoenix.set_path("http://example1.com") + self.phoenix.set_description("hello world") self.phoenix.set_type(UrlType.WEB_HOME) self.titanic = Url(self.phoenix) self.ref_obj = Url(self.phoenix) def test_path_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), IDENTICAL) - self.titanic.set_path('http://example2.com') + self.titanic.set_path("http://example2.com") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_type_equivalence(self): @@ -130,7 +176,7 @@ def test_type_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_desc_equivalence(self): - self.titanic.set_description('goodby') + self.titanic.set_description("goodby") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_privacy_equivalence(self): @@ -138,22 +184,23 @@ def test_privacy_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), EQUAL) def test_merge_path(self): - self.titanic.set_path('example2.com') + self.titanic.set_path("example2.com") self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.is_equal(self.ref_obj), True) + class UrlBaseCheck(unittest.TestCase): def setUp(self): self.phoenix = UrlBase() self.titanic = UrlBase() url = Url() - url.set_path('example.com') + url.set_path("example.com") self.phoenix.add_url(url) def test_identical(self): ref_url_list = UrlBase(self.phoenix) url = Url() - url.set_path('example.com') + url.set_path("example.com") self.titanic.add_url(url) self.phoenix._merge_url_list(self.titanic) self.assertEqual(self.phoenix.serialize(), ref_url_list.serialize()) @@ -163,7 +210,7 @@ def test_equal(self): ref_url = ref_url_list.get_url_list()[0] ref_url.set_privacy(True) url = Url() - url.set_path('example.com') + url.set_path("example.com") url.set_privacy(True) self.titanic.add_url(url) self.phoenix._merge_url_list(self.titanic) @@ -172,28 +219,28 @@ def test_equal(self): def test_different(self): ref_url_list = UrlBase(self.phoenix) url = Url() - url.set_path('other.com') + url.set_path("other.com") ref_url_list.add_url(url) self.titanic.add_url(url) self.phoenix._merge_url_list(self.titanic) self.assertEqual(self.phoenix.serialize(), ref_url_list.serialize()) -class AddressCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, - CitationBaseTest): + +class AddressCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, CitationBaseTest): def setUp(self): self.phoenix = Address() - self.phoenix.set_city('Amsterdam') + self.phoenix.set_city("Amsterdam") self.titanic = Address(self.phoenix) self.ref_obj = Address(self.phoenix) def test_location_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), IDENTICAL) - self.titanic.set_city('Rotterdam') + self.titanic.set_city("Rotterdam") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_date_equivalence(self): date = Date() - date.set_yr_mon_day(1999,12,5) + date.set_yr_mon_day(1999, 12, 5) self.titanic.set_date_object(date) self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) @@ -202,31 +249,32 @@ def test_privacy_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), EQUAL) def test_location_merge(self): - self.titanic.set_city('Rotterdam') + self.titanic.set_city("Rotterdam") self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.is_equal(self.ref_obj), True) + class AddressBaseCheck(unittest.TestCase): def setUp(self): self.phoenix = AddressBase() self.titanic = AddressBase() self.ref_list = AddressBase() address = Address() - address.set_city('Amsterdam') + address.set_city("Amsterdam") self.phoenix.add_address(address) def test_identical(self): address = Address() - address.set_city('Amsterdam') + address.set_city("Amsterdam") self.ref_list.add_address(address) self.titanic.add_address(address) self.phoenix._merge_address_list(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) def test_equal(self): - note_handle = '123456' + note_handle = "123456" address = Address() - address.set_city('Amsterdam') + address.set_city("Amsterdam") address.add_note(note_handle) self.titanic.add_address(address) self.ref_list.add_address(address) @@ -235,15 +283,17 @@ def test_equal(self): def test_different(self): address = Address() - address.set_country('Netherlands') + address.set_country("Netherlands") self.titanic.add_address(address) self.ref_list = AddressBase(self.phoenix) self.ref_list.add_address(address) self.phoenix._merge_address_list(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) -class AttributeCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, - CitationBaseTest): + +class AttributeCheck( + unittest.TestCase, PrivacyBaseTest, NoteBaseTest, CitationBaseTest +): def setUp(self): self.phoenix = Attribute() self.phoenix.set_type(AttributeType.AGE) @@ -269,6 +319,7 @@ def test_value_merge(self): self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.is_equal(self.ref_obj), True) + class AttributeBaseCheck(unittest.TestCase): def setUp(self): self.phoenix = AttributeBase() @@ -289,7 +340,7 @@ def test_identical(self): self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) def test_equal(self): - note_handle = '123456' + note_handle = "123456" attr = Attribute() attr.set_type(AttributeType.AGE) attr.set_value(10) @@ -309,25 +360,25 @@ def test_different(self): self.phoenix._merge_attribute_list(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) -class ChildRefCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, - CitationBaseTest): + +class ChildRefCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, CitationBaseTest): def setUp(self): self.phoenix = ChildRef() - self.phoenix.set_reference_handle('123456') + self.phoenix.set_reference_handle("123456") self.phoenix.set_father_relation(ChildRefType.UNKNOWN) self.phoenix.set_mother_relation(ChildRefType.UNKNOWN) self.titanic = ChildRef() - self.titanic.set_reference_handle('123456') + self.titanic.set_reference_handle("123456") self.titanic.set_father_relation(ChildRefType.UNKNOWN) self.titanic.set_mother_relation(ChildRefType.UNKNOWN) self.ref_obj = ChildRef() - self.ref_obj.set_reference_handle('123456') + self.ref_obj.set_reference_handle("123456") self.ref_obj.set_father_relation(ChildRefType.UNKNOWN) self.ref_obj.set_mother_relation(ChildRefType.UNKNOWN) def test_handle_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), IDENTICAL) - self.titanic.set_reference_handle('654321') + self.titanic.set_reference_handle("654321") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_privacy_equivalence(self): @@ -346,25 +397,32 @@ def test_frel_merge(self): self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.is_equal(self.ref_obj), True) -class EventCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, - CitationBaseTest, MediaBaseTest, AttrBaseTest): + +class EventCheck( + unittest.TestCase, + PrivacyBaseTest, + NoteBaseTest, + CitationBaseTest, + MediaBaseTest, + AttrBaseTest, +): def setUp(self): self.phoenix = Event() self.phoenix.set_description("hello world") self.titanic = Event(self.phoenix) self.ref_obj = Event(self.phoenix) -class EventRefCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, - AttrBaseTest): + +class EventRefCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, AttrBaseTest): def setUp(self): self.phoenix = EventRef() - self.phoenix.set_reference_handle('123456') + self.phoenix.set_reference_handle("123456") self.titanic = EventRef(self.phoenix) self.ref_obj = EventRef(self.phoenix) def test_handle_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), IDENTICAL) - self.titanic.set_reference_handle('654321') + self.titanic.set_reference_handle("654321") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_role_equivalence(self): @@ -380,43 +438,50 @@ def test_replace(self): attr1.set_type(AttributeType.AGE) attr1.set_value(10) citation1 = Citation() - citation1.set_reference_handle('123456') - citation1.set_page('p.10') + citation1.set_reference_handle("123456") + citation1.set_page("p.10") citation2 = Citation() - citation2.set_reference_handle('234567') - citation2.set_page('p.20') + citation2.set_reference_handle("234567") + citation2.set_page("p.20") attr1.add_citation(citation1.handle) attr1.add_citation(citation2.handle) attr2 = Attribute() attr2.set_type(AttributeType.AGE) attr2.set_value(10) citation3 = Citation() - citation3.set_reference_handle('123456') - citation3.set_page('p.10') + citation3.set_reference_handle("123456") + citation3.set_page("p.10") citation4 = Citation() - citation4.set_reference_handle('654321') - citation4.set_page('p.20') + citation4.set_reference_handle("654321") + citation4.set_page("p.20") attr2.add_citation(citation3.handle) attr2.add_citation(citation4.handle) self.phoenix.add_attribute(attr1) self.ref_obj.add_attribute(attr2) - self.phoenix.replace_citation_references('234567','654321') + self.phoenix.replace_citation_references("234567", "654321") self.assertTrue(self.phoenix.is_equal(self.ref_obj)) -class FamilyCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, - CitationBaseTest, MediaBaseTest, AttrBaseTest): + +class FamilyCheck( + unittest.TestCase, + PrivacyBaseTest, + NoteBaseTest, + CitationBaseTest, + MediaBaseTest, + AttrBaseTest, +): def setUp(self): self.phoenix = Family() - self.phoenix.set_father_handle('123456') - self.phoenix.set_mother_handle('654321') + self.phoenix.set_father_handle("123456") + self.phoenix.set_mother_handle("654321") self.phoenix.set_relationship(FamilyRelType.MARRIED) self.titanic = Family() - self.titanic.set_father_handle('123456') - self.titanic.set_mother_handle('654321') + self.titanic.set_father_handle("123456") + self.titanic.set_mother_handle("654321") self.titanic.set_relationship(FamilyRelType.MARRIED) self.ref_obj = Family() - self.ref_obj.set_father_handle('123456') - self.ref_obj.set_mother_handle('654321') + self.ref_obj.set_father_handle("123456") + self.ref_obj.set_mother_handle("654321") self.ref_obj.set_relationship(FamilyRelType.MARRIED) def test_relation_merge(self): @@ -436,7 +501,7 @@ def test_eventref_merge(self): def test_ldsord_merge(self): ldsord = LdsOrd() - ldsord.set_temple('London') + ldsord.set_temple("London") self.titanic.add_lds_ord(ldsord) self.ref_obj.add_lds_ord(ldsord) self.phoenix.merge(self.titanic) @@ -444,7 +509,7 @@ def test_ldsord_merge(self): def test_childref_merge(self): childref = ChildRef() - childref.set_reference_handle('123456') + childref.set_reference_handle("123456") self.titanic.add_child_ref(childref) self.ref_obj.add_child_ref(childref) self.phoenix.merge(self.titanic) @@ -452,11 +517,11 @@ def test_childref_merge(self): def test_mergechildref_identical(self): childref1 = ChildRef() - childref1.set_reference_handle('123456') + childref1.set_reference_handle("123456") childref2 = ChildRef() - childref2.set_reference_handle('123456') + childref2.set_reference_handle("123456") childref3 = ChildRef() - childref3.set_reference_handle('123456') + childref3.set_reference_handle("123456") self.phoenix.add_child_ref(childref1) self.titanic.add_child_ref(childref2) self.ref_obj.add_child_ref(childref3) @@ -465,13 +530,13 @@ def test_mergechildref_identical(self): def test_mergechildref_equal(self): childref1 = ChildRef() - childref1.set_reference_handle('123456') + childref1.set_reference_handle("123456") childref2 = ChildRef() - childref2.set_reference_handle('123456') - childref2.add_note('N1') + childref2.set_reference_handle("123456") + childref2.add_note("N1") childref3 = ChildRef() - childref3.set_reference_handle('123456') - childref3.add_note('N1') + childref3.set_reference_handle("123456") + childref3.add_note("N1") self.phoenix.add_child_ref(childref1) self.titanic.add_child_ref(childref2) self.ref_obj.add_child_ref(childref3) @@ -480,13 +545,13 @@ def test_mergechildref_equal(self): def test_mergechildref_different(self): childref1 = ChildRef() - childref1.set_reference_handle('123456') + childref1.set_reference_handle("123456") childref2 = ChildRef() - childref2.set_reference_handle('654321') + childref2.set_reference_handle("654321") childref3 = ChildRef() - childref3.set_reference_handle('123456') + childref3.set_reference_handle("123456") childref4 = ChildRef() - childref4.set_reference_handle('654321') + childref4.set_reference_handle("654321") self.phoenix.add_child_ref(childref1) self.titanic.add_child_ref(childref2) self.ref_obj.add_child_ref(childref3) @@ -496,61 +561,61 @@ def test_mergechildref_different(self): def test_replace_childref_absent(self): childref1 = ChildRef() - childref1.set_reference_handle('234567') + childref1.set_reference_handle("234567") childref2 = ChildRef() - childref2.set_reference_handle('345678') + childref2.set_reference_handle("345678") childref3 = ChildRef() - childref3.set_reference_handle('765432') + childref3.set_reference_handle("765432") childref4 = ChildRef() - childref4.set_reference_handle('345678') + childref4.set_reference_handle("345678") self.phoenix.add_child_ref(childref1) self.phoenix.add_child_ref(childref2) self.ref_obj.add_child_ref(childref3) self.ref_obj.add_child_ref(childref4) - self.phoenix.replace_handle_reference('Person', '234567', '765432') + self.phoenix.replace_handle_reference("Person", "234567", "765432") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_childref_identical(self): childref1 = ChildRef() - childref1.set_reference_handle('234567') + childref1.set_reference_handle("234567") childref2 = ChildRef() - childref2.set_reference_handle('765432') + childref2.set_reference_handle("765432") childref3 = ChildRef() - childref3.set_reference_handle('765432') + childref3.set_reference_handle("765432") self.phoenix.add_child_ref(childref1) self.phoenix.add_child_ref(childref2) self.ref_obj.add_child_ref(childref3) - self.phoenix.replace_handle_reference('Person', '234567', '765432') + self.phoenix.replace_handle_reference("Person", "234567", "765432") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_childref_equal(self): childref1 = ChildRef() - childref1.set_reference_handle('234567') + childref1.set_reference_handle("234567") childref1.set_privacy(True) childref2 = ChildRef() - childref2.set_reference_handle('765432') + childref2.set_reference_handle("765432") childref3 = ChildRef() - childref3.set_reference_handle('765432') + childref3.set_reference_handle("765432") childref3.set_privacy(True) self.phoenix.add_child_ref(childref1) self.phoenix.add_child_ref(childref2) self.ref_obj.add_child_ref(childref3) - self.phoenix.replace_handle_reference('Person', '234567', '765432') + self.phoenix.replace_handle_reference("Person", "234567", "765432") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_childref_different(self): # impossible, is_equivalent is only DIFFERENT if handles differ. childref1 = ChildRef() - childref1.set_reference_handle('234567') - childref1.set_mother_relation('Adopted') + childref1.set_reference_handle("234567") + childref1.set_mother_relation("Adopted") childref2 = ChildRef() - childref2.set_reference_handle('765432') + childref2.set_reference_handle("765432") childref3 = ChildRef() - childref3.set_reference_handle('765432') + childref3.set_reference_handle("765432") self.phoenix.add_child_ref(childref1) self.phoenix.add_child_ref(childref2) self.ref_obj.add_child_ref(childref3) - self.phoenix.replace_handle_reference('Person', '234567', '765432') + self.phoenix.replace_handle_reference("Person", "234567", "765432") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_mergeeventref_identical(self): @@ -571,10 +636,10 @@ def test_mergeeventref_equal(self): eventref1.set_role(EventRoleType.WITNESS) eventref2 = EventRef() eventref2.set_role(EventRoleType.WITNESS) - eventref2.add_note('N1') + eventref2.add_note("N1") eventref3 = EventRef() eventref3.set_role(EventRoleType.WITNESS) - eventref3.add_note('N1') + eventref3.add_note("N1") self.phoenix.add_event_ref(eventref1) self.titanic.add_event_ref(eventref2) self.ref_obj.add_event_ref(eventref3) @@ -599,110 +664,109 @@ def test_mergeeventref_different(self): def test_replace_event_absent(self): eventref1 = EventRef() - eventref1.set_reference_handle('123456') + eventref1.set_reference_handle("123456") eventref2 = EventRef() - eventref2.set_reference_handle('234567') + eventref2.set_reference_handle("234567") eventref3 = EventRef() - eventref3.set_reference_handle('654321') + eventref3.set_reference_handle("654321") eventref4 = EventRef() - eventref4.set_reference_handle('234567') + eventref4.set_reference_handle("234567") self.phoenix.add_event_ref(eventref1) self.phoenix.add_event_ref(eventref2) self.ref_obj.add_event_ref(eventref3) self.ref_obj.add_event_ref(eventref4) - self.phoenix.replace_handle_reference('Event', '123456', '654321') + self.phoenix.replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_event_identical(self): eventref1 = EventRef() - eventref1.set_reference_handle('123456') + eventref1.set_reference_handle("123456") eventref2 = EventRef() - eventref2.set_reference_handle('654321') + eventref2.set_reference_handle("654321") eventref3 = EventRef() - eventref3.set_reference_handle('654321') + eventref3.set_reference_handle("654321") self.phoenix.add_event_ref(eventref1) self.phoenix.add_event_ref(eventref2) self.ref_obj.add_event_ref(eventref3) - self.phoenix.replace_handle_reference('Event', '123456', '654321') + self.phoenix.replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_event_equal(self): eventref1 = EventRef() - eventref1.set_reference_handle('123456') + eventref1.set_reference_handle("123456") eventref1.set_privacy(True) eventref2 = EventRef() - eventref2.set_reference_handle('654321') + eventref2.set_reference_handle("654321") eventref3 = EventRef() - eventref3.set_reference_handle('654321') + eventref3.set_reference_handle("654321") eventref3.set_privacy(True) self.phoenix.add_event_ref(eventref1) self.phoenix.add_event_ref(eventref2) self.ref_obj.add_event_ref(eventref3) - self.phoenix.replace_handle_reference('Event', '123456', '654321') + self.phoenix.replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_event_different(self): eventref1 = EventRef() - eventref1.set_reference_handle('123456') + eventref1.set_reference_handle("123456") eventref1.set_role(EventRoleType.WITNESS) eventref2 = EventRef() - eventref2.set_reference_handle('654321') + eventref2.set_reference_handle("654321") eventref3 = EventRef() - eventref3.set_reference_handle('654321') + eventref3.set_reference_handle("654321") eventref3.set_role(EventRoleType.WITNESS) eventref4 = EventRef() - eventref4.set_reference_handle('654321') + eventref4.set_reference_handle("654321") self.phoenix.add_event_ref(eventref1) self.phoenix.add_event_ref(eventref2) self.ref_obj.add_event_ref(eventref3) self.ref_obj.add_event_ref(eventref4) - self.phoenix.replace_handle_reference('Event', '123456', '654321') + self.phoenix.replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_event_order_first(self): eventref1 = EventRef() - eventref1.set_reference_handle('123456') + eventref1.set_reference_handle("123456") eventref2 = EventRef() - eventref2.set_reference_handle('234567') + eventref2.set_reference_handle("234567") eventref3 = EventRef() - eventref3.set_reference_handle('654321') + eventref3.set_reference_handle("654321") eventref4 = EventRef() - eventref4.set_reference_handle('123456') + eventref4.set_reference_handle("123456") eventref5 = EventRef() - eventref5.set_reference_handle('234567') + eventref5.set_reference_handle("234567") self.phoenix.add_event_ref(eventref1) self.phoenix.add_event_ref(eventref2) self.phoenix.add_event_ref(eventref3) self.ref_obj.add_event_ref(eventref4) self.ref_obj.add_event_ref(eventref5) - self.phoenix.replace_handle_reference('Event', '654321', '123456') + self.phoenix.replace_handle_reference("Event", "654321", "123456") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_event_order_last(self): eventref1 = EventRef() - eventref1.set_reference_handle('123456') + eventref1.set_reference_handle("123456") eventref2 = EventRef() - eventref2.set_reference_handle('234567') + eventref2.set_reference_handle("234567") eventref3 = EventRef() - eventref3.set_reference_handle('654321') + eventref3.set_reference_handle("654321") eventref4 = EventRef() - eventref4.set_reference_handle('234567') + eventref4.set_reference_handle("234567") eventref5 = EventRef() - eventref5.set_reference_handle('654321') + eventref5.set_reference_handle("654321") self.phoenix.add_event_ref(eventref1) self.phoenix.add_event_ref(eventref2) self.phoenix.add_event_ref(eventref3) self.ref_obj.add_event_ref(eventref4) self.ref_obj.add_event_ref(eventref5) - self.phoenix.replace_handle_reference('Event', '123456', '654321') + self.phoenix.replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) -class LdsordCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, - CitationBaseTest): +class LdsordCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, CitationBaseTest): def setUp(self): self.phoenix = LdsOrd() - self.phoenix.set_temple('London, England') + self.phoenix.set_temple("London, England") self.titanic = LdsOrd(self.phoenix) self.ref_obj = LdsOrd(self.phoenix) @@ -713,12 +777,12 @@ def test_type_equivalence(self): def test_date_equivalence(self): date = Date() - date.set_yr_mon_day(1999,12,5) + date.set_yr_mon_day(1999, 12, 5) self.titanic.set_date_object(date) self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_temple_equivalence(self): - self.titanic.set_temple('Baton Rouge, Louisiana') + self.titanic.set_temple("Baton Rouge, Louisiana") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_status_equivalence(self): @@ -726,25 +790,26 @@ def test_status_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_famc_equivalence(self): - self.titanic.set_family_handle('F1') + self.titanic.set_family_handle("F1") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_privacy_equivalence(self): self.titanic.set_privacy(True) self.assertEqual(self.phoenix.is_equivalent(self.titanic), EQUAL) + class LdsordBaseCheck(unittest.TestCase): def setUp(self): self.phoenix = LdsOrdBase() self.titanic = LdsOrdBase() self.ref_list = LdsOrdBase() ldsord = LdsOrd() - ldsord.set_temple('London, England') + ldsord.set_temple("London, England") self.phoenix.add_lds_ord(ldsord) def test_identical(self): ldsord = LdsOrd() - ldsord.set_temple('London, England') + ldsord.set_temple("London, England") self.titanic.add_lds_ord(ldsord) self.ref_list.add_lds_ord(ldsord) self.phoenix._merge_lds_ord_list(self.titanic) @@ -752,7 +817,7 @@ def test_identical(self): def test_equal(self): ldsord = LdsOrd() - ldsord.set_temple('London, England') + ldsord.set_temple("London, England") ldsord.set_privacy(True) self.titanic.add_lds_ord(ldsord) self.ref_list.add_lds_ord(ldsord) @@ -761,27 +826,28 @@ def test_equal(self): def test_different(self): ldsord = LdsOrd() - ldsord.set_temple('Baton Rouge, Louisiana') + ldsord.set_temple("Baton Rouge, Louisiana") self.titanic.add_lds_ord(ldsord) self.ref_list = LdsOrdBase(self.phoenix) self.ref_list.add_lds_ord(ldsord) self.phoenix._merge_lds_ord_list(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) + class MediaBaseCheck(unittest.TestCase): def setUp(self): self.phoenix = MediaBase() self.titanic = MediaBase() self.ref_list = MediaBase() mediaref = MediaRef() - mediaref.set_reference_handle('123456') - mediaref.set_rectangle('10 10 90 90') + mediaref.set_reference_handle("123456") + mediaref.set_rectangle("10 10 90 90") self.phoenix.add_media_reference(mediaref) def test_merge_identical(self): mediaref = MediaRef() - mediaref.set_reference_handle('123456') - mediaref.set_rectangle('10 10 90 90') + mediaref.set_reference_handle("123456") + mediaref.set_rectangle("10 10 90 90") self.titanic.add_media_reference(mediaref) self.ref_list.add_media_reference(mediaref) self.phoenix._merge_media_list(self.titanic) @@ -789,8 +855,8 @@ def test_merge_identical(self): def test_merge_equal(self): mediaref = MediaRef() - mediaref.set_reference_handle('123456') - mediaref.set_rectangle('10 10 90 90') + mediaref.set_reference_handle("123456") + mediaref.set_rectangle("10 10 90 90") mediaref.set_privacy(True) self.titanic.add_media_reference(mediaref) self.ref_list.add_media_reference(mediaref) @@ -799,11 +865,11 @@ def test_merge_equal(self): def test_merge_different(self): mediaref1 = MediaRef() - mediaref1.set_reference_handle('123456') - mediaref1.set_rectangle('10 10 90 90') + mediaref1.set_reference_handle("123456") + mediaref1.set_rectangle("10 10 90 90") mediaref2 = MediaRef() - mediaref2.set_reference_handle('123456') - mediaref2.set_rectangle('20 10 90 90') + mediaref2.set_reference_handle("123456") + mediaref2.set_rectangle("20 10 90 90") self.titanic.add_media_reference(mediaref2) self.ref_list.add_media_reference(mediaref1) self.ref_list.add_media_reference(mediaref2) @@ -812,104 +878,108 @@ def test_merge_different(self): def test_replace_absent(self): mediaref1 = MediaRef() - mediaref1.set_reference_handle('654321') - mediaref1.set_rectangle('10 10 90 90') + mediaref1.set_reference_handle("654321") + mediaref1.set_rectangle("10 10 90 90") self.ref_list.add_media_reference(mediaref1) - self.phoenix.replace_media_references('123456','654321') + self.phoenix.replace_media_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) def test_replace_identical(self): mediaref1 = MediaRef() - mediaref1.set_reference_handle('654321') - mediaref1.set_rectangle('10 10 90 90') + mediaref1.set_reference_handle("654321") + mediaref1.set_rectangle("10 10 90 90") mediaref2 = MediaRef() - mediaref2.set_reference_handle('654321') - mediaref2.set_rectangle('10 10 90 90') + mediaref2.set_reference_handle("654321") + mediaref2.set_rectangle("10 10 90 90") self.phoenix.add_media_reference(mediaref1) self.ref_list.add_media_reference(mediaref2) - self.phoenix.replace_media_references('123456','654321') + self.phoenix.replace_media_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) def test_replace_equal(self): mediaref1 = MediaRef() - mediaref1.set_reference_handle('654321') - mediaref1.set_rectangle('10 10 90 90') + mediaref1.set_reference_handle("654321") + mediaref1.set_rectangle("10 10 90 90") mediaref1.set_privacy(True) mediaref2 = MediaRef() - mediaref2.set_reference_handle('654321') - mediaref2.set_rectangle('10 10 90 90') + mediaref2.set_reference_handle("654321") + mediaref2.set_rectangle("10 10 90 90") mediaref2.set_privacy(True) self.phoenix.add_media_reference(mediaref1) self.ref_list.add_media_reference(mediaref2) - self.phoenix.replace_media_references('123456','654321') + self.phoenix.replace_media_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) def test_replace_different(self): mediaref1 = MediaRef() - mediaref1.set_reference_handle('654321') - mediaref1.set_rectangle('20 20 90 90') + mediaref1.set_reference_handle("654321") + mediaref1.set_rectangle("20 20 90 90") mediaref2 = MediaRef() - mediaref2.set_reference_handle('654321') - mediaref2.set_rectangle('10 10 90 90') + mediaref2.set_reference_handle("654321") + mediaref2.set_rectangle("10 10 90 90") mediaref3 = MediaRef() - mediaref3.set_reference_handle('654321') - mediaref3.set_rectangle('20 20 90 90') + mediaref3.set_reference_handle("654321") + mediaref3.set_rectangle("20 20 90 90") self.phoenix.add_media_reference(mediaref1) self.ref_list.add_media_reference(mediaref2) self.ref_list.add_media_reference(mediaref3) - self.phoenix.replace_media_references('123456','654321') + self.phoenix.replace_media_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) def test_replace_order_first(self): mediaref1 = MediaRef() - mediaref1.set_reference_handle('234567') - mediaref1.set_rectangle('10 10 90 90') + mediaref1.set_reference_handle("234567") + mediaref1.set_rectangle("10 10 90 90") mediaref2 = MediaRef() - mediaref2.set_reference_handle('654321') - mediaref2.set_rectangle('10 10 90 90') + mediaref2.set_reference_handle("654321") + mediaref2.set_rectangle("10 10 90 90") mediaref3 = MediaRef() - mediaref3.set_reference_handle('123456') - mediaref3.set_rectangle('10 10 90 90') + mediaref3.set_reference_handle("123456") + mediaref3.set_rectangle("10 10 90 90") mediaref4 = MediaRef() - mediaref4.set_reference_handle('234567') - mediaref4.set_rectangle('10 10 90 90') + mediaref4.set_reference_handle("234567") + mediaref4.set_rectangle("10 10 90 90") self.phoenix.add_media_reference(mediaref1) self.phoenix.add_media_reference(mediaref2) self.ref_list.add_media_reference(mediaref3) self.ref_list.add_media_reference(mediaref4) - self.phoenix.replace_media_references('654321','123456') + self.phoenix.replace_media_references("654321", "123456") self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) def test_replace_order_last(self): mediaref1 = MediaRef() - mediaref1.set_reference_handle('234567') - mediaref1.set_rectangle('10 10 90 90') + mediaref1.set_reference_handle("234567") + mediaref1.set_rectangle("10 10 90 90") mediaref2 = MediaRef() - mediaref2.set_reference_handle('654321') - mediaref2.set_rectangle('10 10 90 90') + mediaref2.set_reference_handle("654321") + mediaref2.set_rectangle("10 10 90 90") mediaref3 = MediaRef() - mediaref3.set_reference_handle('234567') - mediaref3.set_rectangle('10 10 90 90') + mediaref3.set_reference_handle("234567") + mediaref3.set_rectangle("10 10 90 90") mediaref4 = MediaRef() - mediaref4.set_reference_handle('654321') - mediaref4.set_rectangle('10 10 90 90') + mediaref4.set_reference_handle("654321") + mediaref4.set_rectangle("10 10 90 90") self.phoenix.add_media_reference(mediaref1) self.phoenix.add_media_reference(mediaref2) self.ref_list.add_media_reference(mediaref3) self.ref_list.add_media_reference(mediaref4) - self.phoenix.replace_media_references('123456','654321') + self.phoenix.replace_media_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) -class MediaCheck(unittest.TestCase, PrivacyBaseTest, AttrBaseTest, - NoteBaseTest, CitationBaseTest): + +class MediaCheck( + unittest.TestCase, PrivacyBaseTest, AttrBaseTest, NoteBaseTest, CitationBaseTest +): def setUp(self): self.phoenix = Media() - self.phoenix.set_path('example.png') + self.phoenix.set_path("example.png") self.titanic = Media(self.phoenix) self.ref_obj = Media(self.phoenix) -class MediaRefCheck(unittest.TestCase, PrivacyBaseTest, AttrBaseTest, - CitationBaseTest, NoteBaseTest): + +class MediaRefCheck( + unittest.TestCase, PrivacyBaseTest, AttrBaseTest, CitationBaseTest, NoteBaseTest +): def setUp(self): self.phoenix = MediaRef() self.phoenix.set_rectangle("10 10 90 90") @@ -918,7 +988,7 @@ def setUp(self): def test_ref_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), IDENTICAL) - self.titanic.set_reference_handle('123456') + self.titanic.set_reference_handle("123456") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_rect_equivalence(self): @@ -929,11 +999,11 @@ def test_privacy_equivalence(self): self.titanic.set_privacy(True) self.assertEqual(self.phoenix.is_equivalent(self.titanic), EQUAL) -class NameCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, - CitationBaseTest): + +class NameCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, CitationBaseTest): def setUp(self): self.phoenix = Name() - self.phoenix.set_first_name('Willem') + self.phoenix.set_first_name("Willem") surname = Surname() surname.set_surname("Oranje") self.phoenix.add_surname(surname) @@ -942,12 +1012,12 @@ def setUp(self): def test_datalist_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), IDENTICAL) - self.titanic.set_first_name('Maurits') + self.titanic.set_first_name("Maurits") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_date_equivalence(self): date = Date() - date.set_yr_mon_day(1999,12,5) + date.set_yr_mon_day(1999, 12, 5) self.titanic.set_date_object(date) self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) @@ -961,6 +1031,7 @@ def test_privacy_equivalence(self): self.titanic.set_privacy(True) self.assertEqual(self.phoenix.is_equivalent(self.titanic), EQUAL) + class NoteCheck(unittest.TestCase, PrivacyBaseTest): def setUp(self): self.phoenix = Note("hello world") @@ -968,45 +1039,58 @@ def setUp(self): self.ref_obj = Note("hello world") def test_note_replace_handle_reference(self): - ptag = StyledTextTag(name=StyledTextTagType.LINK, - value="gramps://Event/handle/e0000", - ranges=[0, 3]) + ptag = StyledTextTag( + name=StyledTextTagType.LINK, + value="gramps://Event/handle/e0000", + ranges=[0, 3], + ) self.phoenix.text.set_tags([ptag]) - rtag = StyledTextTag(name=StyledTextTagType.LINK, - value="gramps://Event/handle/e0001", - ranges=[0, 3]) + rtag = StyledTextTag( + name=StyledTextTagType.LINK, + value="gramps://Event/handle/e0001", + ranges=[0, 3], + ) self.ref_obj.text.set_tags([rtag]) - self.phoenix.replace_handle_reference('Event', 'e0000', 'e0001') + self.phoenix.replace_handle_reference("Event", "e0000", "e0001") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_note_has_handle_reference(self): - ptag = StyledTextTag(name=StyledTextTagType.LINK, - value="gramps://Event/handle/e0000", - ranges=[0, 3]) + ptag = StyledTextTag( + name=StyledTextTagType.LINK, + value="gramps://Event/handle/e0000", + ranges=[0, 3], + ) self.phoenix.text.set_tags([ptag]) - self.assertTrue(self.phoenix.has_handle_reference('Event', 'e0000')) - self.assertFalse(self.phoenix.has_handle_reference('Event', 'e0001')) + self.assertTrue(self.phoenix.has_handle_reference("Event", "e0000")) + self.assertFalse(self.phoenix.has_handle_reference("Event", "e0001")) def test_note_get_referenced_handles(self): - tag0 = StyledTextTag(name=StyledTextTagType.LINK, - value="gramps://Event/handle/e0000", - ranges=[0, 2]) - tag1 = StyledTextTag(name=StyledTextTagType.LINK, - value="gramps://Person/handle/i0001", - ranges=[2, 3]) + tag0 = StyledTextTag( + name=StyledTextTagType.LINK, + value="gramps://Event/handle/e0000", + ranges=[0, 2], + ) + tag1 = StyledTextTag( + name=StyledTextTagType.LINK, + value="gramps://Person/handle/i0001", + ranges=[2, 3], + ) self.phoenix.text.set_tags([tag0, tag1]) self.phoenix.add_tag("t1234") tag_list = self.phoenix.get_referenced_handles() - self.assertEqual(tag_list, [('Event', 'e0000'), ('Person', 'i0001'), - ('Tag', 't1234')]) - self.assertFalse(self.phoenix.has_handle_reference('Event', 'e0001')) + self.assertEqual( + tag_list, [("Event", "e0000"), ("Person", "i0001"), ("Tag", "t1234")] + ) + self.assertFalse(self.phoenix.has_handle_reference("Event", "e0001")) def test_note_remove_handle_references(self): - ptag = StyledTextTag(name=StyledTextTagType.LINK, - value="gramps://Event/handle/e0000", - ranges=[0, 3]) + ptag = StyledTextTag( + name=StyledTextTagType.LINK, + value="gramps://Event/handle/e0000", + ranges=[0, 3], + ) self.phoenix.text.set_tags([ptag]) - self.phoenix.remove_handle_references('Event', ['e0000']) + self.phoenix.remove_handle_references("Event", ["e0000"]) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) @@ -1015,7 +1099,7 @@ def setUp(self): self.phoenix = NoteBase() self.titanic = NoteBase() note = Note("hello world") - note.set_handle('123456') + note.set_handle("123456") self.phoenix.add_note(note.get_handle()) def test_identical(self): @@ -1027,7 +1111,7 @@ def test_identical(self): def test_different(self): ref_note_list = NoteBase(self.phoenix) note = Note("note other") - note.set_handle('654321') + note.set_handle("654321") self.titanic.add_note(note.get_handle()) ref_note_list.add_note(note.get_handle()) self.phoenix._merge_note_list(self.titanic) @@ -1035,47 +1119,54 @@ def test_different(self): def test_replace_nonew(self): note = Note("note other") - note.set_handle('654321') + note.set_handle("654321") ref_note_list = NoteBase() ref_note_list.add_note(note.get_handle()) - self.phoenix.replace_note_references('123456','654321') + self.phoenix.replace_note_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), ref_note_list.serialize()) def test_replace_newpresent(self): note = Note("note other") - note.set_handle('654321') + note.set_handle("654321") note2 = Note("yet another note") - note2.set_handle('234567') + note2.set_handle("234567") self.phoenix.add_note(note2.get_handle()) self.phoenix.add_note(note.get_handle()) ref_note_list = NoteBase() ref_note_list.add_note(note2.get_handle()) ref_note_list.add_note(note.get_handle()) - self.phoenix.replace_note_references('123456','654321') + self.phoenix.replace_note_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), ref_note_list.serialize()) def test_replace_child(self): ref_note_list = NoteBase() note = Note("") - note.set_handle('123456') + note.set_handle("123456") ref_note_list.add_note(note.get_handle()) - self.phoenix.replace_note_references('','') + self.phoenix.replace_note_references("", "") self.assertEqual(self.phoenix.serialize(), ref_note_list.serialize()) def test_remove_note_references(self): note = Note("note other") - note.set_handle('654321') + note.set_handle("654321") self.phoenix.add_note(note.get_handle()) - self.phoenix.remove_note_references(['123456', '654321']) + self.phoenix.remove_note_references(["123456", "654321"]) ref_note_list = NoteBase() self.assertEqual(self.phoenix.serialize(), ref_note_list.serialize()) -class PersonCheck(unittest.TestCase, PrivacyBaseTest, MediaBaseTest, - AttrBaseTest, NoteBaseTest, CitationBaseTest): + +class PersonCheck( + unittest.TestCase, + PrivacyBaseTest, + MediaBaseTest, + AttrBaseTest, + NoteBaseTest, + CitationBaseTest, +): def setUp(self): self.phoenix = Person() name = Name() - name.set_first_name('Adam') + name.set_first_name("Adam") self.phoenix.set_primary_name(name) self.titanic = Person() self.titanic.set_primary_name(name) @@ -1084,172 +1175,172 @@ def setUp(self): def test_replace_eventhandle_nonew(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") evtref2 = EventRef() - evtref2.set_reference_handle('654321') + evtref2.set_reference_handle("654321") self.phoenix.add_event_ref(evtref) self.ref_obj.add_event_ref(evtref2) - self.phoenix._replace_handle_reference('Event', '123456', '654321') + self.phoenix._replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_eventhandle_identical(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") evtref2 = EventRef() - evtref2.set_reference_handle('234567') + evtref2.set_reference_handle("234567") evtref3 = EventRef() - evtref3.set_reference_handle('654321') + evtref3.set_reference_handle("654321") self.phoenix.add_event_ref(evtref) self.phoenix.add_event_ref(evtref2) self.phoenix.add_event_ref(evtref3) self.ref_obj.add_event_ref(evtref2) self.ref_obj.add_event_ref(evtref3) - self.phoenix._replace_handle_reference('Event', '123456', '654321') + self.phoenix._replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_eventhandle_equal(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") evtref2 = EventRef() - evtref2.set_reference_handle('234567') + evtref2.set_reference_handle("234567") evtref3 = EventRef() - evtref3.set_reference_handle('654321') + evtref3.set_reference_handle("654321") evtref3.set_privacy(True) self.phoenix.add_event_ref(evtref) self.phoenix.add_event_ref(evtref2) self.phoenix.add_event_ref(evtref3) self.ref_obj.add_event_ref(evtref2) self.ref_obj.add_event_ref(evtref3) - self.phoenix._replace_handle_reference('Event', '123456', '654321') + self.phoenix._replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_eventhandle_different(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") evtref2 = EventRef() - evtref2.set_reference_handle('234567') + evtref2.set_reference_handle("234567") evtref3 = EventRef() - evtref3.set_reference_handle('654321') + evtref3.set_reference_handle("654321") self.phoenix.add_event_ref(evtref) self.phoenix.add_event_ref(evtref2) self.ref_obj.add_event_ref(evtref3) self.ref_obj.add_event_ref(evtref2) - self.phoenix._replace_handle_reference('Event', '123456', '654321') + self.phoenix._replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_birth_lower(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") evtref2 = EventRef() - evtref2.set_reference_handle('654321') + evtref2.set_reference_handle("654321") self.phoenix.add_event_ref(evtref) self.phoenix.add_event_ref(evtref2) self.phoenix.birth_ref_index = 2 self.ref_obj.add_event_ref(evtref2) self.ref_obj.birth_ref_index = 1 - self.phoenix._replace_handle_reference('Event', '123456', '654321') + self.phoenix._replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_birth_minusone(self): evtref = EventRef() - evtref.set_reference_handle('654321') + evtref.set_reference_handle("654321") evtref2 = EventRef() - evtref2.set_reference_handle('123456') + evtref2.set_reference_handle("123456") self.phoenix.add_event_ref(evtref) self.phoenix.add_event_ref(evtref2) self.phoenix.birth_ref_index = 1 self.ref_obj.add_event_ref(evtref2) self.ref_obj.birth_ref_index = -1 - self.phoenix._replace_handle_reference('Event', '123456', '654321') + self.phoenix._replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_death_lower(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") evtref2 = EventRef() - evtref2.set_reference_handle('654321') + evtref2.set_reference_handle("654321") self.phoenix.add_event_ref(evtref) self.phoenix.add_event_ref(evtref2) self.phoenix.death_ref_index = 2 self.ref_obj.add_event_ref(evtref2) self.ref_obj.death_ref_index = 1 - self.phoenix._replace_handle_reference('Event', '123456', '654321') + self.phoenix._replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_death_minusone(self): evtref = EventRef() - evtref.set_reference_handle('654321') + evtref.set_reference_handle("654321") evtref2 = EventRef() - evtref2.set_reference_handle('123456') + evtref2.set_reference_handle("123456") self.phoenix.add_event_ref(evtref) self.phoenix.add_event_ref(evtref2) self.phoenix.death_ref_index = 1 self.ref_obj.add_event_ref(evtref2) self.ref_obj.death_ref_index = -1 - self.phoenix._replace_handle_reference('Event', '123456', '654321') + self.phoenix._replace_handle_reference("Event", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_personhandle_nonew(self): personref = PersonRef() - personref.set_reference_handle('123456') + personref.set_reference_handle("123456") self.phoenix.add_person_ref(personref) personref2 = PersonRef() - personref2.set_reference_handle('654321') + personref2.set_reference_handle("654321") self.ref_obj.add_person_ref(personref2) - self.phoenix._replace_handle_reference('Person', '123456', '654321') + self.phoenix._replace_handle_reference("Person", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_personhandle_identical(self): personref = PersonRef() - personref.set_reference_handle('123456') + personref.set_reference_handle("123456") personref2 = PersonRef() - personref2.set_reference_handle('234567') + personref2.set_reference_handle("234567") personref3 = PersonRef() - personref3.set_reference_handle('654321') + personref3.set_reference_handle("654321") self.phoenix.add_person_ref(personref) self.phoenix.add_person_ref(personref2) self.phoenix.add_person_ref(personref3) self.ref_obj.add_person_ref(personref2) self.ref_obj.add_person_ref(personref3) - self.phoenix._replace_handle_reference('Person', '123456', '654321') + self.phoenix._replace_handle_reference("Person", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_personhandle_equal(self): personref = PersonRef() - personref.set_reference_handle('123456') + personref.set_reference_handle("123456") personref.set_privacy(True) personref2 = PersonRef() - personref2.set_reference_handle('234567') + personref2.set_reference_handle("234567") personref3 = PersonRef() - personref3.set_reference_handle('654321') + personref3.set_reference_handle("654321") personref4 = PersonRef() - personref4.set_reference_handle('654321') + personref4.set_reference_handle("654321") personref4.set_privacy(True) self.phoenix.add_person_ref(personref) self.phoenix.add_person_ref(personref2) self.phoenix.add_person_ref(personref3) self.ref_obj.add_person_ref(personref2) self.ref_obj.add_person_ref(personref4) - self.phoenix._replace_handle_reference('Person', '123456', '654321') + self.phoenix._replace_handle_reference("Person", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_personhandle_different(self): personref = PersonRef() - personref.set_reference_handle('123456') + personref.set_reference_handle("123456") personref2 = PersonRef() - personref2.set_reference_handle('234567') + personref2.set_reference_handle("234567") personref3 = PersonRef() - personref3.set_reference_handle('654321') + personref3.set_reference_handle("654321") self.phoenix.add_person_ref(personref) self.phoenix.add_person_ref(personref2) self.ref_obj.add_person_ref(personref3) self.ref_obj.add_person_ref(personref2) - self.phoenix._replace_handle_reference('Person', '123456', '654321') + self.phoenix._replace_handle_reference("Person", "123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_merge_person_primaryname(self): name = Name() - name.set_first_name('Abel') + name.set_first_name("Abel") self.titanic.set_primary_name(name) self.ref_obj.add_alternate_name(name) self.phoenix.merge(self.titanic) @@ -1257,7 +1348,7 @@ def test_merge_person_primaryname(self): def test_merge_person_altname(self): name = Name() - name.set_first_name('Abel') + name.set_first_name("Abel") self.titanic.add_alternate_name(name) self.ref_obj.add_alternate_name(name) self.phoenix.merge(self.titanic) @@ -1265,7 +1356,7 @@ def test_merge_person_altname(self): def test_merge_person_eventref(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") self.titanic.add_event_ref(evtref) self.ref_obj.add_event_ref(evtref) self.phoenix.merge(self.titanic) @@ -1281,7 +1372,7 @@ def test_merge_person_ldsord(self): def test_merge_person_address(self): address = Address() - address.set_city('The Hague') + address.set_city("The Hague") self.titanic.add_address(address) self.ref_obj.add_address(address) self.phoenix.merge(self.titanic) @@ -1289,23 +1380,23 @@ def test_merge_person_address(self): def test_merge_person_personref(self): personref = PersonRef() - personref.set_reference_handle('123456') + personref.set_reference_handle("123456") self.titanic.add_person_ref(personref) self.ref_obj.add_person_ref(personref) self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) - #def todo_test_merge_person_aschild(self): - #pass + # def todo_test_merge_person_aschild(self): + # pass - #def todo_test_merge_person_asparent(self): - #pass + # def todo_test_merge_person_asparent(self): + # pass def test_altname_identical(self): name = Name() - name.set_first_name('Abel') + name.set_first_name("Abel") name2 = Name() - name2.set_first_name('Abel') + name2.set_first_name("Abel") self.phoenix.add_alternate_name(name) self.titanic.add_alternate_name(name2) self.ref_obj.add_alternate_name(name) @@ -1314,9 +1405,9 @@ def test_altname_identical(self): def test_altname_equal(self): name = Name() - name.set_first_name('Abel') + name.set_first_name("Abel") name2 = Name() - name2.set_first_name('Abel') + name2.set_first_name("Abel") name2.set_privacy(True) self.phoenix.add_alternate_name(name) self.titanic.add_alternate_name(name2) @@ -1326,9 +1417,9 @@ def test_altname_equal(self): def test_altname_different(self): name = Name() - name.set_first_name('Abel') + name.set_first_name("Abel") name2 = Name() - name2.set_first_name('Cain') + name2.set_first_name("Cain") self.phoenix.add_alternate_name(name) self.titanic.add_alternate_name(name2) self.ref_obj.add_alternate_name(name) @@ -1338,9 +1429,9 @@ def test_altname_different(self): def test_eventrefs_identical(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") evtref2 = EventRef() - evtref2.set_reference_handle('123456') + evtref2.set_reference_handle("123456") self.phoenix.add_event_ref(evtref) self.titanic.add_event_ref(evtref2) self.ref_obj.add_event_ref(evtref) @@ -1349,9 +1440,9 @@ def test_eventrefs_identical(self): def test_eventrefs_equal(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") evtref2 = EventRef() - evtref2.set_reference_handle('123456') + evtref2.set_reference_handle("123456") evtref2.set_privacy(True) self.phoenix.add_event_ref(evtref) self.titanic.add_event_ref(evtref2) @@ -1361,9 +1452,9 @@ def test_eventrefs_equal(self): def test_eventrefs_different(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") evtref2 = EventRef() - evtref2.set_reference_handle('234567') + evtref2.set_reference_handle("234567") self.phoenix.add_event_ref(evtref) self.titanic.add_event_ref(evtref2) self.ref_obj.add_event_ref(evtref) @@ -1373,11 +1464,11 @@ def test_eventrefs_different(self): def test_eventrefs_birthref(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") evtref2 = EventRef() - evtref2.set_reference_handle('234567') + evtref2.set_reference_handle("234567") evtref3 = EventRef() - evtref3.set_reference_handle('123456') + evtref3.set_reference_handle("123456") self.phoenix.add_event_ref(evtref2) self.titanic.add_event_ref(evtref) self.titanic.birth_ref_index = 0 @@ -1389,11 +1480,11 @@ def test_eventrefs_birthref(self): def test_eventrefs_deathref(self): evtref = EventRef() - evtref.set_reference_handle('123456') + evtref.set_reference_handle("123456") evtref2 = EventRef() - evtref2.set_reference_handle('234567') + evtref2.set_reference_handle("234567") evtref3 = EventRef() - evtref3.set_reference_handle('123456') + evtref3.set_reference_handle("123456") self.phoenix.add_event_ref(evtref2) self.titanic.add_event_ref(evtref) self.titanic.death_ref_index = 0 @@ -1405,7 +1496,7 @@ def test_eventrefs_deathref(self): def test_merge_personrefs_identical(self): personref = PersonRef() - personref.set_reference_handle('123456') + personref.set_reference_handle("123456") self.phoenix.add_person_ref(personref) self.titanic.add_person_ref(personref) self.ref_obj.add_person_ref(personref) @@ -1414,9 +1505,9 @@ def test_merge_personrefs_identical(self): def test_merge_personrefs_equal(self): personref = PersonRef() - personref.set_reference_handle('123456') + personref.set_reference_handle("123456") personref2 = PersonRef() - personref2.set_reference_handle('123456') + personref2.set_reference_handle("123456") personref2.set_privacy(True) self.phoenix.add_person_ref(personref) self.titanic.add_person_ref(personref2) @@ -1426,9 +1517,9 @@ def test_merge_personrefs_equal(self): def test_merge_personrefs_different(self): personref = PersonRef() - personref.set_reference_handle('123456') + personref.set_reference_handle("123456") personref2 = PersonRef() - personref2.set_reference_handle('234567') + personref2.set_reference_handle("234567") self.phoenix.add_person_ref(personref) self.titanic.add_person_ref(personref2) self.ref_obj.add_person_ref(personref) @@ -1436,32 +1527,39 @@ def test_merge_personrefs_different(self): self.phoenix._merge_person_ref_list(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) -class PlaceCheck(unittest.TestCase, PrivacyBaseTest, MediaBaseTest, - UrlBaseTest, NoteBaseTest, CitationBaseTest): + +class PlaceCheck( + unittest.TestCase, + PrivacyBaseTest, + MediaBaseTest, + UrlBaseTest, + NoteBaseTest, + CitationBaseTest, +): def setUp(self): self.phoenix = Place() - self.phoenix.set_title('Place 1') + self.phoenix.set_title("Place 1") # __init__ copy has bad side effects, don't use it # self.titanic = Place(self.phoenix) self.titanic = Place() - self.titanic.set_title('Place 1') + self.titanic.set_title("Place 1") # __init__ copy has bad side effects, don't use it # self.ref_obj = Place(self.phoenix) self.ref_obj = Place() - self.ref_obj.set_title('Place 1') + self.ref_obj.set_title("Place 1") self.amsterdam = PlaceName() - self.amsterdam.set_value('Amsterdam') + self.amsterdam.set_value("Amsterdam") self.rotterdam = PlaceName() - self.rotterdam.set_value('Rotterdam') + self.rotterdam.set_value("Rotterdam") self.utrecht = PlaceName() - self.utrecht.set_value('Utrecht') + self.utrecht.set_value("Utrecht") self.leiden = PlaceName() - self.leiden.set_value('Leiden') + self.leiden.set_value("Leiden") def test_merge_primary_identical(self): self.phoenix.set_name(self.amsterdam) self.phoenix.set_type(PlaceType.CITY) - self.titanic.set_title('Place 2') + self.titanic.set_title("Place 2") self.titanic.set_name(self.amsterdam) self.titanic.set_type(PlaceType.CITY) self.ref_obj.set_name(self.amsterdam) @@ -1472,7 +1570,7 @@ def test_merge_primary_identical(self): def test_merge_primary_different(self): self.phoenix.set_name(self.amsterdam) self.phoenix.set_type(PlaceType.CITY) - self.titanic.set_title('Place 2') + self.titanic.set_title("Place 2") self.titanic.set_name(self.rotterdam) self.titanic.set_type(PlaceType.CITY) self.ref_obj.set_name(self.amsterdam) @@ -1485,7 +1583,7 @@ def test_merge_both_different(self): self.phoenix.set_name(self.amsterdam) self.phoenix.set_type(PlaceType.CITY) self.phoenix.add_alternative_name(self.utrecht) - self.titanic.set_title('Place 2') + self.titanic.set_title("Place 2") self.titanic.set_name(self.rotterdam) self.titanic.set_type(PlaceType.CITY) self.titanic.add_alternative_name(self.leiden) @@ -1504,7 +1602,7 @@ def test_merge_alternative_identical(self): self.phoenix.set_name(self.amsterdam) self.phoenix.set_type(PlaceType.CITY) self.phoenix.add_alternative_name(self.rotterdam) - self.titanic.set_title('Place 2') + self.titanic.set_title("Place 2") self.titanic.set_name(self.amsterdam) self.titanic.set_type(PlaceType.CITY) self.titanic.add_alternative_name(self.rotterdam) @@ -1518,7 +1616,7 @@ def test_merge_alternative_different(self): self.phoenix.set_name(self.amsterdam) self.phoenix.set_type(PlaceType.CITY) self.phoenix.add_alternative_name(self.rotterdam) - self.titanic.set_title('Place 2') + self.titanic.set_title("Place 2") self.titanic.set_name(self.amsterdam) self.titanic.set_type(PlaceType.CITY) self.titanic.add_alternative_name(self.utrecht) @@ -1533,7 +1631,7 @@ def test_merge_prialt_identical(self): self.phoenix.set_name(self.amsterdam) self.phoenix.set_type(PlaceType.CITY) self.phoenix.add_alternative_name(self.rotterdam) - self.titanic.set_title('Place 2') + self.titanic.set_title("Place 2") self.titanic.set_name(self.rotterdam) self.titanic.set_type(PlaceType.CITY) self.ref_obj.set_name(self.amsterdam) @@ -1546,7 +1644,7 @@ def test_merge_prialt2(self): self.phoenix.set_name(self.amsterdam) self.phoenix.set_type(PlaceType.CITY) self.phoenix.add_alternative_name(self.rotterdam) - self.titanic.set_title('Place 2') + self.titanic.set_title("Place 2") self.titanic.set_name(self.rotterdam) self.titanic.set_type(PlaceType.CITY) self.titanic.add_alternative_name(self.amsterdam) @@ -1560,7 +1658,7 @@ def test_merge_empty(self): self.phoenix.set_name(self.amsterdam) self.phoenix.set_type(PlaceType.CITY) self.phoenix.add_alternative_name(self.rotterdam) - self.titanic.set_title('Place 2') + self.titanic.set_title("Place 2") # titanic gets empty name self.titanic.set_type(PlaceType.CITY) self.titanic.add_alternative_name(self.utrecht) @@ -1572,21 +1670,22 @@ def test_merge_empty(self): self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) + class RepoCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, UrlBaseTest): def setUp(self): self.phoenix = Repository() - self.phoenix.set_name('Repo 1') + self.phoenix.set_name("Repo 1") self.phoenix.set_type(RepositoryType.LIBRARY) self.titanic = Repository() - self.titanic.set_name('Repo 1') + self.titanic.set_name("Repo 1") self.titanic.set_type(RepositoryType.LIBRARY) self.ref_obj = Repository() - self.ref_obj.set_name('Repo 1') + self.ref_obj.set_name("Repo 1") self.ref_obj.set_type(RepositoryType.LIBRARY) def test_address(self): address = Address() - address.set_city('Amsterdam') + address.set_city("Amsterdam") self.titanic.add_address(address) self.ref_obj.add_address(address) self.phoenix.merge(self.titanic) @@ -1594,42 +1693,43 @@ def test_address(self): def test_replace(self): address = Address() - address.set_city('Utrecht') + address.set_city("Utrecht") citation = Citation() - citation.set_reference_handle('123456') + citation.set_reference_handle("123456") address.add_citation(citation.handle) self.phoenix.add_address(address) address2 = Address() - address2.set_city('Utrecht') + address2.set_city("Utrecht") citation2 = Citation() - citation2.set_reference_handle('654321') + citation2.set_reference_handle("654321") address2.add_citation(citation2.handle) self.ref_obj.add_address(address2) - self.phoenix.replace_citation_references('123456','654321') + self.phoenix.replace_citation_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) + class RepoRefCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest): def setUp(self): self.phoenix = RepoRef() - self.phoenix.set_reference_handle('123456') + self.phoenix.set_reference_handle("123456") self.titanic = RepoRef(self.phoenix) self.ref_obj = RepoRef(self.phoenix) def test_handle_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), IDENTICAL) - self.titanic.set_reference_handle('654321') + self.titanic.set_reference_handle("654321") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_callnr_equivalence(self): - self.titanic.set_call_number('10') + self.titanic.set_call_number("10") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_privacy_equivalence(self): self.titanic.set_privacy(True) self.assertEqual(self.phoenix.is_equivalent(self.titanic), EQUAL) -class SourceCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, - MediaBaseTest): + +class SourceCheck(unittest.TestCase, PrivacyBaseTest, NoteBaseTest, MediaBaseTest): def setUp(self): self.phoenix = Source() self.phoenix.set_title("Source 1") @@ -1638,22 +1738,22 @@ def setUp(self): self.ref_obj = Source() self.ref_obj.set_title("Source 1") - #def todo_test_replace(self): - #pass + # def todo_test_replace(self): + # pass def test_merge_datamap(self): attr1 = SrcAttribute() - attr1.set_type('A') - attr1.set_value('a') + attr1.set_type("A") + attr1.set_value("a") attr2 = SrcAttribute() - attr2.set_type('B') - attr2.set_value('b') + attr2.set_type("B") + attr2.set_value("b") attr3 = SrcAttribute() - attr3.set_type('B') - attr3.set_value('bb') + attr3.set_type("B") + attr3.set_value("bb") attr4 = SrcAttribute() - attr4.set_type('C') - attr4.set_value('c') + attr4.set_type("C") + attr4.set_value("c") self.phoenix.set_attribute_list([attr1, attr2]) self.titanic.set_attribute_list([attr3, attr4]) self.ref_obj.set_attribute_list([attr1, attr2, attr3, attr4]) @@ -1662,7 +1762,7 @@ def test_merge_datamap(self): def test_merge_reporef(self): reporef = RepoRef() - reporef.set_reference_handle('123456') + reporef.set_reference_handle("123456") self.titanic.add_repo_reference(reporef) self.ref_obj.add_repo_reference(reporef) self.phoenix.merge(self.titanic) @@ -1670,7 +1770,7 @@ def test_merge_reporef(self): def test_merge_reporef_identical(self): reporef = RepoRef() - reporef.set_reference_handle('123456') + reporef.set_reference_handle("123456") self.phoenix.add_repo_reference(reporef) self.titanic.add_repo_reference(reporef) self.ref_obj.add_repo_reference(reporef) @@ -1679,9 +1779,9 @@ def test_merge_reporef_identical(self): def test_merge_reporef_equal(self): reporef = RepoRef() - reporef.set_reference_handle('123456') + reporef.set_reference_handle("123456") reporef2 = RepoRef() - reporef2.set_reference_handle('123456') + reporef2.set_reference_handle("123456") reporef2.set_privacy(True) self.phoenix.add_repo_reference(reporef) self.titanic.add_repo_reference(reporef2) @@ -1689,12 +1789,11 @@ def test_merge_reporef_equal(self): self.phoenix._merge_reporef_list(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) - def test_merge_reporef_different(self): reporef = RepoRef() - reporef.set_reference_handle('123456') + reporef.set_reference_handle("123456") reporef2 = RepoRef() - reporef2.set_reference_handle('234567') + reporef2.set_reference_handle("234567") self.phoenix.add_repo_reference(reporef) self.titanic.add_repo_reference(reporef2) self.ref_obj.add_repo_reference(reporef) @@ -1704,99 +1803,100 @@ def test_merge_reporef_different(self): def test_replace_reporef_nonew(self): reporef = RepoRef() - reporef.set_reference_handle('123456') + reporef.set_reference_handle("123456") reporef2 = RepoRef() - reporef2.set_reference_handle('654321') + reporef2.set_reference_handle("654321") self.phoenix.add_repo_reference(reporef) self.ref_obj.add_repo_reference(reporef2) - self.phoenix.replace_repo_references('123456','654321') + self.phoenix.replace_repo_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_reporef_identical(self): reporef = RepoRef() - reporef.set_reference_handle('123456') + reporef.set_reference_handle("123456") reporef2 = RepoRef() - reporef2.set_reference_handle('234567') + reporef2.set_reference_handle("234567") reporef3 = RepoRef() - reporef3.set_reference_handle('654321') + reporef3.set_reference_handle("654321") self.phoenix.add_repo_reference(reporef) self.phoenix.add_repo_reference(reporef2) self.phoenix.add_repo_reference(reporef3) self.ref_obj.add_repo_reference(reporef2) self.ref_obj.add_repo_reference(reporef3) - self.phoenix.replace_repo_references('123456','654321') + self.phoenix.replace_repo_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_reporef_equal(self): reporef = RepoRef() - reporef.set_reference_handle('123456') + reporef.set_reference_handle("123456") reporef2 = RepoRef() - reporef2.set_reference_handle('234567') + reporef2.set_reference_handle("234567") reporef3 = RepoRef() - reporef3.set_reference_handle('654321') + reporef3.set_reference_handle("654321") reporef3.set_privacy(True) self.phoenix.add_repo_reference(reporef) self.phoenix.add_repo_reference(reporef2) self.phoenix.add_repo_reference(reporef3) self.ref_obj.add_repo_reference(reporef2) self.ref_obj.add_repo_reference(reporef3) - self.phoenix.replace_repo_references('123456','654321') + self.phoenix.replace_repo_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) def test_replace_reporef_different(self): reporef = RepoRef() - reporef.set_reference_handle('123456') + reporef.set_reference_handle("123456") reporef2 = RepoRef() - reporef2.set_reference_handle('234567') + reporef2.set_reference_handle("234567") reporef3 = RepoRef() - reporef3.set_reference_handle('654321') - reporef3.set_call_number('100') + reporef3.set_reference_handle("654321") + reporef3.set_call_number("100") reporef4 = RepoRef() - reporef4.set_reference_handle('654321') + reporef4.set_reference_handle("654321") self.phoenix.add_repo_reference(reporef) self.phoenix.add_repo_reference(reporef2) self.phoenix.add_repo_reference(reporef3) self.ref_obj.add_repo_reference(reporef4) self.ref_obj.add_repo_reference(reporef2) self.ref_obj.add_repo_reference(reporef3) - self.phoenix.replace_repo_references('123456','654321') + self.phoenix.replace_repo_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) + class CitationBaseCheck(unittest.TestCase): def setUp(self): self.phoenix = CitationBase() citation = Citation() - citation.set_reference_handle('123456') + citation.set_reference_handle("123456") self.phoenix.add_citation(citation.handle) self.titanic = CitationBase() self.obj_list = CitationBase() def test_replace_nonew(self): citation = Citation() - citation.set_reference_handle('654321') + citation.set_reference_handle("654321") self.obj_list.add_citation(citation.handle) - self.phoenix.replace_citation_references('123456','654321') + self.phoenix.replace_citation_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.obj_list.serialize()) def test_replace_newpresent(self): citation = Citation() - citation.set_reference_handle('654321') - citation.set_page('p.10') + citation.set_reference_handle("654321") + citation.set_page("p.10") citation2 = Citation() - citation2.set_reference_handle('234567') + citation2.set_reference_handle("234567") self.phoenix.add_citation(citation.handle) self.phoenix.add_citation(citation2.handle) self.obj_list.add_citation(citation2.handle) self.obj_list.add_citation(citation.handle) - self.phoenix.replace_citation_references('123456','654321') + self.phoenix.replace_citation_references("123456", "654321") self.assertEqual(self.phoenix.serialize(), self.obj_list.serialize()) - #def todo_test_replace_child(self): - #pass + # def todo_test_replace_child(self): + # pass def test_merge_identical(self): citation = Citation() - citation.set_reference_handle('123456') + citation.set_reference_handle("123456") self.titanic.add_citation(citation.handle) self.obj_list.add_citation(citation.handle) self.phoenix._merge_citation_list(self.titanic) @@ -1804,34 +1904,56 @@ def test_merge_identical(self): def test_merge_different(self): citation = Citation() - citation.set_reference_handle('234567') + citation.set_reference_handle("234567") citation2 = Citation() - citation2.set_reference_handle('123456') + citation2.set_reference_handle("123456") self.titanic.add_citation(citation.handle) self.obj_list.add_citation(citation2.handle) self.obj_list.add_citation(citation.handle) self.phoenix._merge_citation_list(self.titanic) self.assertEqual(self.phoenix.serialize(), self.obj_list.serialize()) -class CitationCheck(unittest.TestCase, PrivacyBaseTest, MediaBaseTest, - NoteBaseTest): + +class CitationCheck(unittest.TestCase, PrivacyBaseTest, MediaBaseTest, NoteBaseTest): def setUp(self): self.phoenix = Citation() - self.phoenix.set_reference_handle('123456') - self.phoenix.set_page('p.10') + self.phoenix.set_reference_handle("123456") + self.phoenix.set_page("p.10") self.titanic = Citation() - self.titanic.set_reference_handle('123456') - self.titanic.set_page('p.10') + self.titanic.set_reference_handle("123456") + self.titanic.set_page("p.10") self.ref_obj = Citation() - self.ref_obj.set_reference_handle('123456') - self.ref_obj.set_page('p.10') + self.ref_obj.set_reference_handle("123456") + self.ref_obj.set_page("p.10") def test_merge_confidence(self): - known_values = ( (0, 0, 0), (0, 1, 0), (0, 2, 0), (0, 3, 0), (0, 4, 0), - (1, 0, 0), (1, 1, 1), (1, 2, 1), (1, 3, 1), (1, 4, 4), - (2, 0, 0), (2, 1, 1), (2, 2, 2), (2, 3, 3), (2, 4, 4), - (3, 0, 0), (3, 1, 1), (3, 2, 3), (3, 3, 3), (3, 4, 4), - (4, 0, 0), (4, 1, 4), (4, 2, 4), (4, 3, 4), (4, 4, 4)) + known_values = ( + (0, 0, 0), + (0, 1, 0), + (0, 2, 0), + (0, 3, 0), + (0, 4, 0), + (1, 0, 0), + (1, 1, 1), + (1, 2, 1), + (1, 3, 1), + (1, 4, 4), + (2, 0, 0), + (2, 1, 1), + (2, 2, 2), + (2, 3, 3), + (2, 4, 4), + (3, 0, 0), + (3, 1, 1), + (3, 2, 3), + (3, 3, 3), + (3, 4, 4), + (4, 0, 0), + (4, 1, 4), + (4, 2, 4), + (4, 3, 4), + (4, 4, 4), + ) for val1, val2, val_merge in known_values: self.phoenix.set_confidence_level(val1) self.titanic.set_confidence_level(val2) @@ -1841,32 +1963,33 @@ def test_merge_confidence(self): def test_merge_datamap(self): attr1 = SrcAttribute() - attr1.set_type('A') - attr1.set_value('a') + attr1.set_type("A") + attr1.set_value("a") attr2 = SrcAttribute() - attr2.set_type('B') - attr2.set_value('b') + attr2.set_type("B") + attr2.set_value("b") attr3 = SrcAttribute() - attr3.set_type('B') - attr3.set_value('bb') + attr3.set_type("B") + attr3.set_value("bb") attr4 = SrcAttribute() - attr4.set_type('C') - attr4.set_value('c') + attr4.set_type("C") + attr4.set_value("c") self.phoenix.set_attribute_list([attr1, attr2]) self.titanic.set_attribute_list([attr3, attr4]) self.ref_obj.set_attribute_list([attr1, attr2, attr3, attr4]) self.phoenix.merge(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_obj.serialize()) + class SurnameCheck(unittest.TestCase): def setUp(self): self.phoenix = Surname() - self.phoenix.set_prefix('van') + self.phoenix.set_prefix("van") self.titanic = Surname(self.phoenix) def test_datalist_equivalence(self): self.assertEqual(self.phoenix.is_equivalent(self.titanic), IDENTICAL) - self.titanic.set_prefix('von') + self.titanic.set_prefix("von") self.assertEqual(self.phoenix.is_equivalent(self.titanic), DIFFERENT) def test_primary_equivalence(self): @@ -1877,6 +2000,7 @@ def test_primary_equivalence(self): # There is no merge method to check. + class SurnameBaseCheck(unittest.TestCase): def setUp(self): self.phoenix = SurnameBase() @@ -1903,10 +2027,11 @@ def test_different(self): self.phoenix._merge_surname_list(self.titanic) self.assertEqual(self.phoenix.serialize(), self.ref_list.serialize()) + class TagBaseCheck(unittest.TestCase): def setUp(self): self.phoenix = TagBase() - tag_handle = '123456' + tag_handle = "123456" self.phoenix.add_tag(tag_handle) self.titanic = TagBase() @@ -1918,7 +2043,7 @@ def test_identical(self): def test_different(self): self.titanic.set_tag_list([]) - tag_handle = '654321' + tag_handle = "654321" self.titanic.add_tag(tag_handle) self.ref_list = TagBase(self.phoenix) self.ref_list.add_tag(tag_handle) diff --git a/gramps/gen/lib/test/schema_test.py b/gramps/gen/lib/test/schema_test.py index fb73eb0c71a..132a87cf33e 100644 --- a/gramps/gen/lib/test/schema_test.py +++ b/gramps/gen/lib/test/schema_test.py @@ -25,8 +25,18 @@ import json import jsonschema -from .. import (Person, Family, Event, Place, Repository, Source, Citation, - Media, Note, Tag) +from .. import ( + Person, + Family, + Event, + Place, + Repository, + Source, + Citation, + Media, + Note, + Tag, +) from ..serialize import to_json from ...db.utils import import_as_dict from ...const import DATA_DIR @@ -35,6 +45,7 @@ TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests")) EXAMPLE = os.path.join(TEST_DIR, "example.gramps") + class BaseTest(unittest.TestCase): def _schema_test(self, obj): instance = json.loads(to_json(obj)) @@ -43,65 +54,79 @@ def _schema_test(self, obj): except jsonschema.exceptions.ValidationError: self.fail("JSON Schema validation error") + class PersonTest(BaseTest): @classmethod def setUpClass(cls): cls.schema = Person.get_schema() + class FamilyTest(BaseTest): @classmethod def setUpClass(cls): cls.schema = Family.get_schema() + class EventTest(BaseTest): @classmethod def setUpClass(cls): cls.schema = Event.get_schema() + class PlaceTest(BaseTest): @classmethod def setUpClass(cls): cls.schema = Place.get_schema() + class RepositoryTest(BaseTest): @classmethod def setUpClass(cls): cls.schema = Repository.get_schema() + class SourceTest(BaseTest): @classmethod def setUpClass(cls): cls.schema = Source.get_schema() + class CitationTest(BaseTest): @classmethod def setUpClass(cls): cls.schema = Citation.get_schema() + class MediaTest(BaseTest): @classmethod def setUpClass(cls): cls.schema = Media.get_schema() + class NoteTest(BaseTest): @classmethod def setUpClass(cls): cls.schema = Note.get_schema() + class TagTest(BaseTest): @classmethod def setUpClass(cls): cls.schema = Tag.get_schema() + def generate_case(obj, test_class): """ Dynamically generate tests. """ + def test(self): self._schema_test(obj) + name = "test_schema_%s_%s" % (obj.__class__.__name__, obj.handle) setattr(test_class, name, test) + db = import_as_dict(EXAMPLE, User()) for obj in db.iter_people(): generate_case(obj, PersonTest) diff --git a/gramps/gen/lib/test/serialize_test.py b/gramps/gen/lib/test/serialize_test.py index 6b618880288..9022e876606 100644 --- a/gramps/gen/lib/test/serialize_test.py +++ b/gramps/gen/lib/test/serialize_test.py @@ -23,8 +23,18 @@ import unittest import os -from .. import (Person, Family, Event, Source, Place, Citation, - Repository, Media, Note, Tag) +from .. import ( + Person, + Family, + Event, + Source, + Place, + Citation, + Repository, + Media, + Note, + Tag, +) from ..serialize import to_json, from_json from ...db.utils import import_as_dict from ...const import DATA_DIR @@ -33,6 +43,7 @@ TEST_DIR = os.path.abspath(os.path.join(DATA_DIR, "tests")) EXAMPLE = os.path.join(TEST_DIR, "example.gramps") + class BaseCheck: def test_from_json(self): data = to_json(self.object) @@ -44,80 +55,104 @@ def test_from_empty_json(self): obj = from_json(data) self.assertEqual(self.object.serialize(), obj.serialize()) + class PersonCheck(unittest.TestCase, BaseCheck): def setUp(self): self.cls = Person self.object = self.cls() + class FamilyCheck(unittest.TestCase, BaseCheck): def setUp(self): self.cls = Family self.object = self.cls() + class EventCheck(unittest.TestCase, BaseCheck): def setUp(self): self.cls = Event self.object = self.cls() + class SourceCheck(unittest.TestCase, BaseCheck): def setUp(self): self.cls = Source self.object = self.cls() + class PlaceCheck(unittest.TestCase, BaseCheck): def setUp(self): self.cls = Place self.object = self.cls() + class CitationCheck(unittest.TestCase, BaseCheck): def setUp(self): self.cls = Citation self.object = self.cls() + class RepositoryCheck(unittest.TestCase, BaseCheck): def setUp(self): self.cls = Repository self.object = self.cls() + class MediaCheck(unittest.TestCase, BaseCheck): def setUp(self): self.cls = Media self.object = self.cls() + class NoteCheck(unittest.TestCase, BaseCheck): def setUp(self): self.cls = Note self.object = self.cls() + class TagCheck(unittest.TestCase, BaseCheck): def setUp(self): self.cls = Tag self.object = self.cls() + class DatabaseCheck(unittest.TestCase): maxDiff = None + def generate_case(obj): """ Dynamically generate tests and attach to DatabaseCheck. """ data = to_json(obj) obj2 = from_json(data) + def test(self): self.assertEqual(obj.serialize(), obj2.serialize()) + name = "test_serialize_%s_%s" % (obj.__class__.__name__, obj.handle) setattr(DatabaseCheck, name, test) #### - #def test2(self): + # def test2(self): # self.assertEqual(obj.serialize(), from_struct(struct).serialize()) - #name = "test_create_%s_%s" % (obj.__class__.__name__, obj.handle) - #setattr(DatabaseCheck, name, test2) + # name = "test_create_%s_%s" % (obj.__class__.__name__, obj.handle) + # setattr(DatabaseCheck, name, test2) + db = import_as_dict(EXAMPLE, User()) -for obj_class in ('Person', 'Family', 'Event', 'Place', 'Repository', 'Source', - 'Citation', 'Media', 'Note'): - for handle in db.method('get_%s_handles', obj_class)(): - obj = db.method('get_%s_from_handle', obj_class)(handle) +for obj_class in ( + "Person", + "Family", + "Event", + "Place", + "Repository", + "Source", + "Citation", + "Media", + "Note", +): + for handle in db.method("get_%s_handles", obj_class)(): + obj = db.method("get_%s_from_handle", obj_class)(handle) generate_case(obj) if __name__ == "__main__": diff --git a/gramps/gen/lib/test/styledtext_test.py b/gramps/gen/lib/test/styledtext_test.py index cb17b4c4b5a..7a6542b8a61 100644 --- a/gramps/gen/lib/test/styledtext_test.py +++ b/gramps/gen/lib/test/styledtext_test.py @@ -28,20 +28,18 @@ class Test1(unittest.TestCase): - T1 = StyledTextTag(StyledTextTagType(1), 'v1', [(0, 2), (2, 4), (4, 6)]) - T2 = StyledTextTag(StyledTextTagType(2), 'v2', [(1, 3), (3, 5), (0, 7)]) - T3 = StyledTextTag(StyledTextTagType(0), 'v3', [(0, 1)]) - T4 = StyledTextTag(StyledTextTagType(2), 'v2', - [(8, 10), (10, 12), (7, 14)]) - T5 = StyledTextTag(StyledTextTagType(2), 'v2', - [(19, 21), (21, 23), (18, 25)]) + T1 = StyledTextTag(StyledTextTagType(1), "v1", [(0, 2), (2, 4), (4, 6)]) + T2 = StyledTextTag(StyledTextTagType(2), "v2", [(1, 3), (3, 5), (0, 7)]) + T3 = StyledTextTag(StyledTextTagType(0), "v3", [(0, 1)]) + T4 = StyledTextTag(StyledTextTagType(2), "v2", [(8, 10), (10, 12), (7, 14)]) + T5 = StyledTextTag(StyledTextTagType(2), "v2", [(19, 21), (21, 23), (18, 25)]) - A = StyledText('123X456', [T1]) + A = StyledText("123X456", [T1]) B = StyledText("abcXdef", [T2]) - C = StyledText('\n') + C = StyledText("\n") - S = 'cleartext' + S = "cleartext" # some basic tests # because the StyledText.__eq__ method doesn't work very well (tags don't @@ -49,7 +47,7 @@ class Test1(unittest.TestCase): # serialize for comparisons. def test_join(self): C = self.C.join([self.A, self.S, deepcopy(self.B)]) - _C = StyledText('123X456\ncleartext\nabcXdef', [self.T1, self.T5]) + _C = StyledText("123X456\ncleartext\nabcXdef", [self.T1, self.T5]) self.assertEqual(C.serialize(), _C.serialize()) def test_split(self): @@ -62,19 +60,23 @@ def test_split(self): def test_replace(self): C = self.C.join([self.A, self.S, deepcopy(self.B)]) - C = C.replace('X', StyledText('_', [self.T3])) - _C = ('123_456\ncleartext\nabc_def', - [((0, ''), 'v3', [(3, 4)]), - ((0, ''), 'v3', [(21, 22)]), - ((1, ''), 'v1', [(0, 2), (2, 3)]), - ((1, ''), 'v1', [(4, 6)]), - ((2, ''), 'v2', [(19, 21), (18, 21)]), - ((2, ''), 'v2', [(22, 23), (22, 25)])]) + C = C.replace("X", StyledText("_", [self.T3])) + _C = ( + "123_456\ncleartext\nabc_def", + [ + ((0, ""), "v3", [(3, 4)]), + ((0, ""), "v3", [(21, 22)]), + ((1, ""), "v1", [(0, 2), (2, 3)]), + ((1, ""), "v1", [(4, 6)]), + ((2, ""), "v2", [(19, 21), (18, 21)]), + ((2, ""), "v2", [(22, 23), (22, 25)]), + ], + ) self.assertEqual(C.serialize(), _C) def test_add(self): A = deepcopy(self.A) + deepcopy(self.B) - _A = StyledText('123X456abcXdef', [self.T1, self.T4]) + _A = StyledText("123X456abcXdef", [self.T1, self.T4]) self.assertEqual(A.serialize(), _A.serialize()) diff --git a/gramps/gen/lib/url.py b/gramps/gen/lib/url.py index b3d4543e034..cfed190e607 100644 --- a/gramps/gen/lib/url.py +++ b/gramps/gen/lib/url.py @@ -24,31 +24,33 @@ Url class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from warnings import warn from urllib.parse import urlparse -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .secondaryobj import SecondaryObject from .privacybase import PrivacyBase from .urltype import UrlType from .const import IDENTICAL, EQUAL, DIFFERENT from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Url for Person/Place/Repository # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Url(SecondaryObject, PrivacyBase): """ Contains information related to internet Uniform Resource Locators, @@ -88,14 +90,11 @@ def get_schema(cls): "title": _("Url"), "properties": { "_class": {"enum": [cls.__name__]}, - "private": {"type": "boolean", - "title": _("Private")}, - "path": {"type": "string", - "title": _("Path")}, - "desc": {"type": "string", - "title": _("Description")}, - "type": UrlType.get_schema() - } + "private": {"type": "boolean", "title": _("Private")}, + "path": {"type": "string", "title": _("Path")}, + "desc": {"type": "string", "title": _("Description")}, + "type": UrlType.get_schema(), + }, } def get_text_data_list(self): @@ -117,9 +116,11 @@ def is_equivalent(self, other): :returns: Constant indicating degree of equivalence. :rtype: int """ - if self.type != other.type or \ - self.get_full_path() != other.get_full_path() or \ - self.desc != other.desc: + if ( + self.type != other.type + or self.get_full_path() != other.get_full_path() + or self.desc != other.desc + ): return DIFFERENT else: if self.get_privacy() != other.get_privacy(): @@ -197,7 +198,7 @@ def get_full_path(self): return "mailto:" + self.path elif self.type == UrlType.WEB_FTP and not self.path.startswith("ftp://"): return "ftp://" + self.path - elif self.parse_path().scheme == '': + elif self.parse_path().scheme == "": return "http://" + self.path else: return self.path diff --git a/gramps/gen/lib/urlbase.py b/gramps/gen/lib/urlbase.py index 3bc59fad6b1..01019789c84 100644 --- a/gramps/gen/lib/urlbase.py +++ b/gramps/gen/lib/urlbase.py @@ -22,19 +22,20 @@ UrlBase class for Gramps. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .url import Url from .const import IDENTICAL, EQUAL -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # UrlBase classes # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class UrlBase: """ Base class for url-aware objects. diff --git a/gramps/gen/lib/urltype.py b/gramps/gen/lib/urltype.py index 5bd2a66688b..604a9a9f606 100644 --- a/gramps/gen/lib/urltype.py +++ b/gramps/gen/lib/urltype.py @@ -22,17 +22,18 @@ URL types """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .grampstype import GrampsType from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -class UrlType(GrampsType): +class UrlType(GrampsType): UNKNOWN = -1 CUSTOM = 0 EMAIL = 1 @@ -50,7 +51,7 @@ class UrlType(GrampsType): (WEB_HOME, _("Web Home"), "Web Home"), (WEB_SEARCH, _("Web Search"), "Web Search"), (WEB_FTP, _("FTP"), "FTP"), - ] + ] def __init__(self, value=None): GrampsType.__init__(self, value) diff --git a/gramps/gen/merge/diff.py b/gramps/gen/merge/diff.py index 5fed59304dc..2950470cff1 100644 --- a/gramps/gen/merge/diff.py +++ b/gramps/gen/merge/diff.py @@ -27,20 +27,23 @@ from ..db.utils import import_as_dict from ..lib.serialize import to_json from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext + def to_struct(obj): """ Convert an object into a struct. """ return json.loads(to_json(obj)) + def diff_dates(json1, json2): """ Compare two json date objects. Returns True if different. """ - if json1 == json2: # if same, then Not Different - return False # else, they still might be Not Different + if json1 == json2: # if same, then Not Different + return False # else, they still might be Not Different elif isinstance(json1, dict) and isinstance(json2, dict): if json1["dateval"] == json2["dateval"] and json2["dateval"] != 0: return False @@ -51,6 +54,7 @@ def diff_dates(json1, json2): else: return True + def diff_items(path, json1, json2): """ Compare two json objects. Returns True if different. @@ -71,13 +75,13 @@ def diff_items(path, json1, json2): elif isinstance(json1, dict) and isinstance(json2, dict): for key in json1.keys(): if key == "change": - continue # don't care about time differences, only data changes + continue # don't care about time differences, only data changes elif key == "date": result = diff_dates(json1["date"], json2["date"]) if result: - #print("different dates", path) - #print(" old:", json1["date"]) - #print(" new:", json2["date"]) + # print("different dates", path) + # print(" old:", json1["date"]) + # print(" new:", json2["date"]) return True else: result = diff_items(path + "." + key, json1[key], json2[key]) @@ -85,11 +89,12 @@ def diff_items(path, json1, json2): return True return False else: - #print("different values", path) - #print(" old:", json1) - #print(" new:", json2) + # print("different values", path) + # print(" old:", json1) + # print(" new:", json2) return True + def diff_dbs(db1, db2, user): """ 1. new objects => mark for insert @@ -103,23 +108,32 @@ def diff_dbs(db1, db2, user): missing_from_old = [] missing_from_new = [] diffs = [] - with user.progress(_('Family Tree Differences'), - _('Searching...'), 10) as step: - for item in ['Person', 'Family', 'Source', 'Citation', 'Event', 'Media', - 'Place', 'Repository', 'Note', 'Tag']: + with user.progress(_("Family Tree Differences"), _("Searching..."), 10) as step: + for item in [ + "Person", + "Family", + "Source", + "Citation", + "Event", + "Media", + "Place", + "Repository", + "Note", + "Tag", + ]: step() - handles_func1 = db1.method('get_%s_handles', item) - handles_func2 = db2.method('get_%s_handles', item) - handle_func1 = db1.method('get_%s_from_handle', item) - handle_func2 = db2.method('get_%s_from_handle', item) + handles_func1 = db1.method("get_%s_handles", item) + handles_func2 = db2.method("get_%s_handles", item) + handle_func1 = db1.method("get_%s_from_handle", item) + handle_func2 = db2.method("get_%s_from_handle", item) handles1 = sorted([handle for handle in handles_func1()]) handles2 = sorted([handle for handle in handles_func2()]) p1 = 0 p2 = 0 while p1 < len(handles1) and p2 < len(handles2): - if handles1[p1] == handles2[p2]: # in both + if handles1[p1] == handles2[p2]: # in both item1 = handle_func1(handles1[p1]) item2 = handle_func2(handles2[p2]) diff = diff_items(item, to_struct(item1), to_struct(item2)) @@ -128,11 +142,11 @@ def diff_dbs(db1, db2, user): # else same! p1 += 1 p2 += 1 - elif handles1[p1] < handles2[p2]: # p1 is mssing in p2 + elif handles1[p1] < handles2[p2]: # p1 is mssing in p2 item1 = handle_func1(handles1[p1]) missing_from_new += [(item, item1)] p1 += 1 - elif handles1[p1] > handles2[p2]: # p2 is mssing in p1 + elif handles1[p1] > handles2[p2]: # p2 is mssing in p1 item2 = handle_func2(handles2[p2]) missing_from_old += [(item, item2)] p2 += 1 @@ -146,6 +160,7 @@ def diff_dbs(db1, db2, user): p2 += 1 return diffs, missing_from_old, missing_from_new + def diff_db_to_file(old_db, filename, user): # First, get data as a InMemoryDB new_db = import_as_dict(filename, user, user) @@ -153,4 +168,3 @@ def diff_db_to_file(old_db, filename, user): # Next get differences: diffs, m_old, m_new = diff_dbs(old_db, new_db, user) return diffs, m_old, m_new - diff --git a/gramps/gen/merge/mergecitationquery.py b/gramps/gen/merge/mergecitationquery.py index 3e04af79bac..b777d8893ea 100644 --- a/gramps/gen/merge/mergecitationquery.py +++ b/gramps/gen/merge/mergecitationquery.py @@ -23,27 +23,39 @@ Provide merge capabilities for citations. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- -from ..lib import (Person, Family, Event, Place, Media, Repository, - Citation, Source, Note) +# ------------------------------------------------------------------------- +from ..lib import ( + Person, + Family, + Event, + Place, + Media, + Repository, + Citation, + Source, + Note, +) from ..db import DbTxn from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext from ..errors import MergeError -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MergeCitationQuery # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MergeCitationQuery: """ Create database query to merge two citations. """ + def __init__(self, dbstate, phoenix, titanic): self.database = dbstate.db self.phoenix = phoenix @@ -60,58 +72,55 @@ def execute(self): with DbTxn(_("Merge Citation"), self.database) as trans: self.database.commit_citation(self.phoenix, trans) - for (class_name, handle) in self.database.find_backlink_handles( - old_handle): + for class_name, handle in self.database.find_backlink_handles(old_handle): if class_name == Person.__name__: person = self.database.get_person_from_handle(handle) - assert(person.has_citation_reference(old_handle)) + assert person.has_citation_reference(old_handle) person.replace_citation_references(old_handle, new_handle) self.database.commit_person(person, trans) elif class_name == Family.__name__: family = self.database.get_family_from_handle(handle) - assert(family.has_citation_reference(old_handle)) + assert family.has_citation_reference(old_handle) family.replace_citation_references(old_handle, new_handle) self.database.commit_family(family, trans) elif class_name == Event.__name__: event = self.database.get_event_from_handle(handle) - assert(event.has_citation_reference(old_handle)) + assert event.has_citation_reference(old_handle) event.replace_citation_references(old_handle, new_handle) self.database.commit_event(event, trans) elif class_name == Place.__name__: place = self.database.get_place_from_handle(handle) - assert(place.has_citation_reference(old_handle)) + assert place.has_citation_reference(old_handle) place.replace_citation_references(old_handle, new_handle) self.database.commit_place(place, trans) elif class_name == Media.__name__: obj = self.database.get_media_from_handle(handle) - assert(obj.has_citation_reference(old_handle)) + assert obj.has_citation_reference(old_handle) obj.replace_citation_references(old_handle, new_handle) self.database.commit_media(obj, trans) elif class_name == Repository.__name__: repository = self.database.get_repository_from_handle(handle) - assert(repository.has_citation_reference(old_handle)) - repository.replace_citation_references(old_handle, - new_handle) + assert repository.has_citation_reference(old_handle) + repository.replace_citation_references(old_handle, new_handle) self.database.commit_repository(repository, trans) elif class_name == Citation.__name__: citation = self.database.get_citation_from_handle(handle) - assert(citation.has_citation_reference(old_handle)) - citation.replace_citation_references(old_handle, - new_handle) + assert citation.has_citation_reference(old_handle) + citation.replace_citation_references(old_handle, new_handle) self.database.commit_citation(citation, trans) elif class_name == Source.__name__: source = self.database.get_source_from_handle(handle) - assert(source.has_citation_reference(old_handle)) - source.replace_citation_references(old_handle, - new_handle) + assert source.has_citation_reference(old_handle) + source.replace_citation_references(old_handle, new_handle) self.database.commit_source(source, trans) elif class_name == Note.__name__: note = self.database.get_note_from_handle(handle) - assert(note.has_handle_reference('Citation', old_handle)) - note.replace_handle_reference( - 'Citation', old_handle, new_handle) + assert note.has_handle_reference("Citation", old_handle) + note.replace_handle_reference("Citation", old_handle, new_handle) self.database.commit_note(note, trans) else: - raise MergeError("Encounter an object of type %s that has " - "a citation reference." % class_name) + raise MergeError( + "Encounter an object of type %s that has " + "a citation reference." % class_name + ) self.database.remove_citation(old_handle, trans) diff --git a/gramps/gen/merge/mergeeventquery.py b/gramps/gen/merge/mergeeventquery.py index ba32f64f2c8..d94db1d65dc 100644 --- a/gramps/gen/merge/mergeeventquery.py +++ b/gramps/gen/merge/mergeeventquery.py @@ -22,26 +22,29 @@ Provide merge capabilities for events. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..lib import Person, Family, Note from ..db import DbTxn from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext from ..errors import MergeError -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MergeEventQuery # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MergeEventQuery: """ Create database query to merge two events. """ + def __init__(self, dbstate, phoenix, titanic): self.database = dbstate.db self.phoenix = phoenix @@ -58,24 +61,20 @@ def execute(self): with DbTxn(_("Merge Event Objects"), self.database) as trans: self.database.commit_event(self.phoenix, trans) - for (class_name, handle) in self.database.find_backlink_handles( - old_handle): + for class_name, handle in self.database.find_backlink_handles(old_handle): if class_name == Person.__name__: person = self.database.get_person_from_handle(handle) - assert(person.has_handle_reference("Event", old_handle)) + assert person.has_handle_reference("Event", old_handle) bri = person.birth_ref_index dri = person.death_ref_index - person.replace_handle_reference("Event", old_handle, - new_handle) - if person.birth_ref_index != bri and \ - person.birth_ref_index == -1: + person.replace_handle_reference("Event", old_handle, new_handle) + if person.birth_ref_index != bri and person.birth_ref_index == -1: for index, ref in enumerate(person.get_event_ref_list()): event = self.database.get_event_from_handle(ref.ref) if event.type.is_birth() and ref.role.is_primary(): person.birth_ref_index = index break - if person.death_ref_index != dri and \ - person.death_ref_index == -1: + if person.death_ref_index != dri and person.death_ref_index == -1: for index, ref in enumerate(person.get_event_ref_list()): event = self.database.get_event_from_handle(ref.ref) if event.type.is_death() and ref.role.is_primary(): @@ -84,17 +83,17 @@ def execute(self): self.database.commit_person(person, trans) elif class_name == Family.__name__: family = self.database.get_family_from_handle(handle) - assert(family.has_handle_reference("Event", old_handle)) - family.replace_handle_reference("Event", old_handle, - new_handle) + assert family.has_handle_reference("Event", old_handle) + family.replace_handle_reference("Event", old_handle, new_handle) self.database.commit_family(family, trans) elif class_name == Note.__name__: note = self.database.get_note_from_handle(handle) - assert(note.has_handle_reference('Event', old_handle)) - note.replace_handle_reference( - 'Event', old_handle, new_handle) + assert note.has_handle_reference("Event", old_handle) + note.replace_handle_reference("Event", old_handle, new_handle) self.database.commit_note(note, trans) else: - raise MergeError("Encounter an object of type %s that has " - "an event reference." % class_name) + raise MergeError( + "Encounter an object of type %s that has " + "an event reference." % class_name + ) self.database.remove_event(old_handle, trans) diff --git a/gramps/gen/merge/mergefamilyquery.py b/gramps/gen/merge/mergefamilyquery.py index 7659c92d9f8..f0c6db51131 100644 --- a/gramps/gen/merge/mergefamilyquery.py +++ b/gramps/gen/merge/mergefamilyquery.py @@ -22,28 +22,30 @@ Provide merge capabilities for families. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..db import DbTxn from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext from ..errors import MergeError from . import MergePersonQuery -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MergeFamilyQuery # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MergeFamilyQuery: """ Create database query to merge two families. """ - def __init__(self, database, phoenix, titanic, phoenix_fh=None, - phoenix_mh=None): + + def __init__(self, database, phoenix, titanic, phoenix_fh=None, phoenix_mh=None): self.database = database self.phoenix = phoenix self.titanic = titanic @@ -78,42 +80,56 @@ def merge_person(self, phoenix_person, titanic_person, parent, trans): new_handle = self.phoenix.get_handle() old_handle = self.titanic.get_handle() - if parent == 'father': + if parent == "father": swapped = self.father_swapped family_add_person_handle = ( - (self.phoenix if swapped else self.titanic).set_father_handle) - elif parent == 'mother': + self.phoenix if swapped else self.titanic + ).set_father_handle + elif parent == "mother": swapped = self.mother_swapped family_add_person_handle = ( - (self.phoenix if swapped else self.titanic).set_mother_handle) + self.phoenix if swapped else self.titanic + ).set_mother_handle else: raise ValueError(_("A parent should be a father or mother.")) if phoenix_person is None: if titanic_person is not None: - raise MergeError("""When merging people where one person """ + raise MergeError( + """When merging people where one person """ """doesn't exist, that "person" must be the person that """ - """will be deleted from the database.""") + """will be deleted from the database.""" + ) return elif titanic_person is None: if swapped: - if any(childref.get_reference_handle() == phoenix_person.get_handle() - for childref in self.phoenix.get_child_ref_list()): - - raise MergeError(_("A parent and child cannot be merged. " - "To merge these people, you must first break the " - "relationship between them.")) + if any( + childref.get_reference_handle() == phoenix_person.get_handle() + for childref in self.phoenix.get_child_ref_list() + ): + raise MergeError( + _( + "A parent and child cannot be merged. " + "To merge these people, you must first break the " + "relationship between them." + ) + ) phoenix_person.add_family_handle(new_handle) family_add_person_handle(phoenix_person.get_handle()) self.database.commit_family(self.phoenix, trans) else: - if any(childref.get_reference_handle() == phoenix_person.get_handle() - for childref in self.titanic.get_child_ref_list()): - - raise MergeError(_("A parent and child cannot be merged. " - "To merge these people, you must first break the " - "relationship between them.")) + if any( + childref.get_reference_handle() == phoenix_person.get_handle() + for childref in self.titanic.get_child_ref_list() + ): + raise MergeError( + _( + "A parent and child cannot be merged. " + "To merge these people, you must first break the " + "relationship between them." + ) + ) phoenix_person.add_family_handle(old_handle) family_add_person_handle(phoenix_person.get_handle()) @@ -121,8 +137,7 @@ def merge_person(self, phoenix_person, titanic_person, parent, trans): self.database.commit_person(phoenix_person, trans) else: - query = MergePersonQuery(self.database, phoenix_person, - titanic_person) + query = MergePersonQuery(self.database, phoenix_person, titanic_person) query.execute(family_merger=False, trans=trans) def execute(self): @@ -132,61 +147,61 @@ def execute(self): new_handle = self.phoenix.get_handle() old_handle = self.titanic.get_handle() - with DbTxn(_('Merge Family'), self.database) as trans: + with DbTxn(_("Merge Family"), self.database) as trans: # commit family in case Phoenix GrampsID, relationship has changed self.database.commit_family(self.phoenix, trans) if self.phoenix_fh != self.titanic_fh: if self.phoenix_fh: phoenix_father = self.database.get_person_from_handle( - self.phoenix_fh) + self.phoenix_fh + ) else: phoenix_father = None if self.titanic_fh: titanic_father = self.database.get_person_from_handle( - self.titanic_fh) + self.titanic_fh + ) else: titanic_father = None - self.merge_person(phoenix_father, titanic_father, - 'father', trans) + self.merge_person(phoenix_father, titanic_father, "father", trans) if self.phoenix_mh != self.titanic_mh: if self.phoenix_mh: phoenix_mother = self.database.get_person_from_handle( - self.phoenix_mh) + self.phoenix_mh + ) else: phoenix_mother = None if self.titanic_mh: titanic_mother = self.database.get_person_from_handle( - self.titanic_mh) + self.titanic_mh + ) else: titanic_mother = None - self.merge_person(phoenix_mother, titanic_mother, - 'mother', trans) + self.merge_person(phoenix_mother, titanic_mother, "mother", trans) # Reload families from db in case the merge_person above changed # them self.phoenix = self.database.get_family_from_handle(new_handle) self.titanic = self.database.get_family_from_handle(old_handle) if self.phoenix_fh: - phoenix_father = self.database.get_person_from_handle( - self.phoenix_fh) + phoenix_father = self.database.get_person_from_handle(self.phoenix_fh) else: phoenix_father = None if self.phoenix_mh: - phoenix_mother = self.database.get_person_from_handle( - self.phoenix_mh) + phoenix_mother = self.database.get_person_from_handle(self.phoenix_mh) else: phoenix_mother = None self.phoenix.merge(self.titanic) self.database.commit_family(self.phoenix, trans) for childref in self.titanic.get_child_ref_list(): child = self.database.get_person_from_handle( - childref.get_reference_handle()) + childref.get_reference_handle() + ) if new_handle in child.parent_family_list: - child.remove_handle_references('Family', [old_handle]) + child.remove_handle_references("Family", [old_handle]) else: - child.replace_handle_reference('Family', old_handle, - new_handle) + child.replace_handle_reference("Family", old_handle, new_handle) self.database.commit_person(child, trans) if phoenix_father: phoenix_father.remove_family_handle(old_handle) @@ -195,15 +210,14 @@ def execute(self): phoenix_mother.remove_family_handle(old_handle) self.database.commit_person(phoenix_mother, trans) # replace the family in lds ordinances and notes - for (ref_obj, ref_handle) in self.database.find_backlink_handles( - old_handle, ['Person', 'Note']): + for ref_obj, ref_handle in self.database.find_backlink_handles( + old_handle, ["Person", "Note"] + ): if ref_handle in (self.titanic_fh, self.titanic_mh): continue - obj = self.database.method( - "get_%s_from_handle", ref_obj)(ref_handle) - assert obj.has_handle_reference('Family', old_handle) - obj.replace_handle_reference( - 'Family', old_handle, new_handle) + obj = self.database.method("get_%s_from_handle", ref_obj)(ref_handle) + assert obj.has_handle_reference("Family", old_handle) + obj.replace_handle_reference("Family", old_handle, new_handle) if ref_handle != old_handle: self.database.method("commit_%s", ref_obj)(obj, trans) diff --git a/gramps/gen/merge/mergemediaquery.py b/gramps/gen/merge/mergemediaquery.py index e153c784ef8..08e30e3b9b9 100644 --- a/gramps/gen/merge/mergemediaquery.py +++ b/gramps/gen/merge/mergemediaquery.py @@ -22,26 +22,29 @@ Provide merge capabilities for media objects. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..lib import Person, Family, Event, Source, Citation, Place, Note from ..db import DbTxn from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext from ..errors import MergeError -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MergeMediaQuery # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MergeMediaQuery: """ Create datqabase query to merge two media objects. """ + def __init__(self, dbstate, phoenix, titanic): self.database = dbstate.db self.phoenix = phoenix @@ -58,45 +61,45 @@ def execute(self): with DbTxn(_("Merge Media Objects"), self.database) as trans: self.database.commit_media(self.phoenix, trans) - for (class_name, handle) in self.database.find_backlink_handles( - old_handle): + for class_name, handle in self.database.find_backlink_handles(old_handle): if class_name == Person.__name__: person = self.database.get_person_from_handle(handle) - assert(person.has_media_reference(old_handle)) + assert person.has_media_reference(old_handle) person.replace_media_references(old_handle, new_handle) self.database.commit_person(person, trans) elif class_name == Family.__name__: family = self.database.get_family_from_handle(handle) - assert(family.has_media_reference(old_handle)) + assert family.has_media_reference(old_handle) family.replace_media_references(old_handle, new_handle) self.database.commit_family(family, trans) elif class_name == Event.__name__: event = self.database.get_event_from_handle(handle) - assert(event.has_media_reference(old_handle)) + assert event.has_media_reference(old_handle) event.replace_media_references(old_handle, new_handle) self.database.commit_event(event, trans) elif class_name == Source.__name__: source = self.database.get_source_from_handle(handle) - assert(source.has_media_reference(old_handle)) + assert source.has_media_reference(old_handle) source.replace_media_references(old_handle, new_handle) self.database.commit_source(source, trans) elif class_name == Citation.__name__: citation = self.database.get_citation_from_handle(handle) - assert(citation.has_media_reference(old_handle)) + assert citation.has_media_reference(old_handle) citation.replace_media_references(old_handle, new_handle) self.database.commit_citation(citation, trans) elif class_name == Place.__name__: place = self.database.get_place_from_handle(handle) - assert(place.has_media_reference(old_handle)) + assert place.has_media_reference(old_handle) place.replace_media_references(old_handle, new_handle) self.database.commit_place(place, trans) elif class_name == Note.__name__: note = self.database.get_note_from_handle(handle) - assert(note.has_handle_reference('Media', old_handle)) - note.replace_handle_reference( - 'Media', old_handle, new_handle) + assert note.has_handle_reference("Media", old_handle) + note.replace_handle_reference("Media", old_handle, new_handle) self.database.commit_note(note, trans) else: - raise MergeError("Encounter an object of type % s that has " - "a media object reference." % class_name) + raise MergeError( + "Encounter an object of type % s that has " + "a media object reference." % class_name + ) self.database.remove_media(old_handle, trans) diff --git a/gramps/gen/merge/mergenotequery.py b/gramps/gen/merge/mergenotequery.py index 86e097ce8ae..927e977ae39 100644 --- a/gramps/gen/merge/mergenotequery.py +++ b/gramps/gen/merge/mergenotequery.py @@ -22,27 +22,39 @@ Provide merge capabilities for notes. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- -from ..lib import (Person, Family, Event, Place, Source, Citation, Repository, - Media, Note) +# ------------------------------------------------------------------------- +from ..lib import ( + Person, + Family, + Event, + Place, + Source, + Citation, + Repository, + Media, + Note, +) from ..db import DbTxn from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext from ..errors import MergeError -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MergeNoteQuery # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MergeNoteQuery: """ Create database query to merge two notes. """ + def __init__(self, dbstate, phoenix, titanic): self.database = dbstate.db self.phoenix = phoenix @@ -57,55 +69,55 @@ def execute(self): self.phoenix.merge(self.titanic) with DbTxn(_("Merge Notes"), self.database) as trans: self.database.commit_note(self.phoenix, trans) - for (class_name, handle) in self.database.find_backlink_handles( - old_handle): + for class_name, handle in self.database.find_backlink_handles(old_handle): if class_name == Person.__name__: person = self.database.get_person_from_handle(handle) - assert(person.has_note_reference(old_handle)) + assert person.has_note_reference(old_handle) person.replace_note_references(old_handle, new_handle) self.database.commit_person(person, trans) elif class_name == Family.__name__: family = self.database.get_family_from_handle(handle) - assert(family.has_note_reference(old_handle)) + assert family.has_note_reference(old_handle) family.replace_note_references(old_handle, new_handle) self.database.commit_family(family, trans) elif class_name == Event.__name__: event = self.database.get_event_from_handle(handle) - assert(event.has_note_reference(old_handle)) + assert event.has_note_reference(old_handle) event.replace_note_references(old_handle, new_handle) self.database.commit_event(event, trans) elif class_name == Source.__name__: source = self.database.get_source_from_handle(handle) - assert(source.has_note_reference(old_handle)) + assert source.has_note_reference(old_handle) source.replace_note_references(old_handle, new_handle) self.database.commit_source(source, trans) elif class_name == Citation.__name__: citation = self.database.get_citation_from_handle(handle) - assert(citation.has_note_reference(old_handle)) + assert citation.has_note_reference(old_handle) citation.replace_note_references(old_handle, new_handle) self.database.commit_citation(citation, trans) elif class_name == Place.__name__: place = self.database.get_place_from_handle(handle) - assert(place.has_note_reference(old_handle)) + assert place.has_note_reference(old_handle) place.replace_note_references(old_handle, new_handle) self.database.commit_place(place, trans) elif class_name == Media.__name__: obj = self.database.get_media_from_handle(handle) - assert(obj.has_note_reference(old_handle)) + assert obj.has_note_reference(old_handle) obj.replace_note_references(old_handle, new_handle) self.database.commit_media(obj, trans) elif class_name == Repository.__name__: repo = self.database.get_repository_from_handle(handle) - assert(repo.has_note_reference(old_handle)) + assert repo.has_note_reference(old_handle) repo.replace_note_references(old_handle, new_handle) self.database.commit_repository(repo, trans) elif class_name == Note.__name__: note = self.database.get_note_from_handle(handle) - assert(note.has_handle_reference('Note', old_handle)) - note.replace_handle_reference( - 'Note', old_handle, new_handle) + assert note.has_handle_reference("Note", old_handle) + note.replace_handle_reference("Note", old_handle, new_handle) self.database.commit_note(note, trans) else: - raise MergeError("Encounter object of type %s that has " - "a note reference." % class_name) + raise MergeError( + "Encounter object of type %s that has " + "a note reference." % class_name + ) self.database.remove_note(old_handle, trans) diff --git a/gramps/gen/merge/mergepersonquery.py b/gramps/gen/merge/mergepersonquery.py index dfb0b8028de..9020eef416d 100644 --- a/gramps/gen/merge/mergepersonquery.py +++ b/gramps/gen/merge/mergepersonquery.py @@ -24,37 +24,48 @@ Provide merge capabilities for persons. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..db import DbTxn from ..const import GRAMPS_LOCALE as glocale from ..errors import MergeError + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MergePersonQuery # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MergePersonQuery: """ Create database query to merge two persons. """ + def __init__(self, database, phoenix, titanic): self.database = database self.phoenix = phoenix self.titanic = titanic if self.check_for_spouse(self.phoenix, self.titanic): - raise MergeError(_("Spouses cannot be merged. To merge these " - "people, you must first break the relationship" - " between them.")) + raise MergeError( + _( + "Spouses cannot be merged. To merge these " + "people, you must first break the relationship" + " between them." + ) + ) if self.check_for_child(self.phoenix, self.titanic): - raise MergeError(_("A parent and child cannot be merged. To merge " - "these people, you must first break the relatio" - "nship between them.")) + raise MergeError( + _( + "A parent and child cannot be merged. To merge " + "these people, you must first break the relatio" + "nship between them." + ) + ) def check_for_spouse(self, person1, person2): """Return if person1 and person2 are spouses of eachother.""" @@ -81,34 +92,38 @@ def merge_families(self, main_family_handle, family, trans): main_family.merge(family) for childref in family.get_child_ref_list(): child = self.database.get_person_from_handle( - childref.get_reference_handle()) + childref.get_reference_handle() + ) if main_family_handle in child.parent_family_list: - child.remove_handle_references('Family', [family_handle]) + child.remove_handle_references("Family", [family_handle]) else: - child.replace_handle_reference('Family', family_handle, - main_family_handle) + child.replace_handle_reference( + "Family", family_handle, main_family_handle + ) self.database.commit_person(child, trans) if self.phoenix: self.phoenix.remove_family_handle(family_handle) self.database.commit_person(self.phoenix, trans) family_father_handle = family.get_father_handle() - spouse_handle = family.get_mother_handle() if \ - new_handle == family_father_handle else family_father_handle + spouse_handle = ( + family.get_mother_handle() + if new_handle == family_father_handle + else family_father_handle + ) if spouse_handle: spouse = self.database.get_person_from_handle(spouse_handle) if spouse: spouse.remove_family_handle(family_handle) self.database.commit_person(spouse, trans) # replace the family in lds ordinances - for (ref_obj, ref_handle) in self.database.find_backlink_handles( - family_handle, ['Person', 'Note']): + for ref_obj, ref_handle in self.database.find_backlink_handles( + family_handle, ["Person", "Note"] + ): if ref_handle == old_handle: continue - obj = self.database.method( - "get_%s_from_handle", ref_obj)(ref_handle) - assert obj.has_handle_reference('Family', family_handle) - obj.replace_handle_reference('Family', family_handle, - main_family_handle) + obj = self.database.method("get_%s_from_handle", ref_obj)(ref_handle) + assert obj.has_handle_reference("Family", family_handle) + obj.replace_handle_reference("Family", family_handle, main_family_handle) self.database.method("commit_%s", ref_obj)(obj, trans) self.database.remove_family(family_handle, trans) self.database.commit_family(main_family, trans) @@ -118,7 +133,7 @@ def execute(self, family_merger=True, trans=None): Merges two persons into a single person. """ if trans is None: - with DbTxn(_('Merge Person'), self.database) as trans: + with DbTxn(_("Merge Person"), self.database) as trans: return self.__execute(family_merger, trans) else: return self.__execute(family_merger, trans) @@ -135,21 +150,19 @@ def __execute(self, family_merger, trans): self.phoenix.merge(self.titanic) self.database.commit_person(self.phoenix, trans) - for (ref_obj, handle) in self.database.find_backlink_handles( - old_handle, ['Person', 'Note']): - obj = self.database.method( - "get_%s_from_handle", ref_obj)(handle) - assert obj.has_handle_reference('Person', old_handle) - obj.replace_handle_reference( - 'Person', old_handle, new_handle) + for ref_obj, handle in self.database.find_backlink_handles( + old_handle, ["Person", "Note"] + ): + obj = self.database.method("get_%s_from_handle", ref_obj)(handle) + assert obj.has_handle_reference("Person", old_handle) + obj.replace_handle_reference("Person", old_handle, new_handle) if handle != old_handle: self.database.method("commit_%s", ref_obj)(obj, trans) for family_handle in self.phoenix.get_parent_family_handle_list(): family = self.database.get_family_from_handle(family_handle) - if family.has_handle_reference('Person', old_handle): - family.replace_handle_reference('Person', old_handle, - new_handle) + if family.has_handle_reference("Person", old_handle): + family.replace_handle_reference("Person", old_handle, new_handle) self.database.commit_family(family, trans) family_merge_guard = False @@ -161,19 +174,16 @@ def __execute(self, family_merger, trans): family = self.database.get_family_from_handle(family_handle) parents = (family.get_father_handle(), family.get_mother_handle()) parent_list_orig.append(parents) - if family.has_handle_reference('Person', old_handle): - family.replace_handle_reference('Person', old_handle, - new_handle) + if family.has_handle_reference("Person", old_handle): + family.replace_handle_reference("Person", old_handle, new_handle) if family_merger and parent_list_orig.count(parents) > 1: # A person with multiple relations with the same spouse is # about to be merged. This is beyond the capabilities of # the merge routine. The family merge is skipped. family_merge_ok = False - parents = (family.get_father_handle(), - family.get_mother_handle()) + parents = (family.get_father_handle(), family.get_mother_handle()) # prune means merging families in this case. - if (family_merger and parents in parent_list and - family_merge_ok): + if family_merger and parents in parent_list and family_merge_ok: # also merge when father_handle or mother_handle == None! if family_merge_guard: # Multiple families get merged. @@ -189,8 +199,10 @@ def __execute(self, family_merger, trans): parent_list.append(parents) hp_hdl = self.database.get_default_handle() - if (hp_hdl in (self.phoenix.get_handle(), self.titanic.get_handle()) - and hp_hdl != self.phoenix.get_handle()): + if ( + hp_hdl in (self.phoenix.get_handle(), self.titanic.get_handle()) + and hp_hdl != self.phoenix.get_handle() + ): self.database.set_default_person_handle(self.phoenix.get_handle()) self.database.remove_person(old_handle, trans) diff --git a/gramps/gen/merge/mergeplacequery.py b/gramps/gen/merge/mergeplacequery.py index c168b58b69b..11b49732473 100644 --- a/gramps/gen/merge/mergeplacequery.py +++ b/gramps/gen/merge/mergeplacequery.py @@ -23,26 +23,29 @@ Provide merge capabilities for places. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..lib import Person, Family, Event, Place, Note from ..db import DbTxn from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext from ..errors import MergeError -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MergePlaceQuery # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MergePlaceQuery: """ Create database query to merge two places. """ + def __init__(self, dbstate, phoenix, titanic): self.database = dbstate.db self.phoenix = phoenix @@ -59,39 +62,35 @@ def execute(self): with DbTxn(_("Merge Places"), self.database) as trans: self.database.commit_place(self.phoenix, trans) - for (class_name, handle) in self.database.find_backlink_handles( - old_handle): + for class_name, handle in self.database.find_backlink_handles(old_handle): if class_name == Person.__name__: person = self.database.get_person_from_handle(handle) - assert(person.has_handle_reference('Place', old_handle)) - person.replace_handle_reference('Place', old_handle, - new_handle) + assert person.has_handle_reference("Place", old_handle) + person.replace_handle_reference("Place", old_handle, new_handle) self.database.commit_person(person, trans) elif class_name == Family.__name__: family = self.database.get_family_from_handle(handle) - assert(family.has_handle_reference('Place', old_handle)) - family.replace_handle_reference('Place', old_handle, - new_handle) + assert family.has_handle_reference("Place", old_handle) + family.replace_handle_reference("Place", old_handle, new_handle) self.database.commit_family(family, trans) elif class_name == Event.__name__: event = self.database.get_event_from_handle(handle) - assert(event.has_handle_reference('Place', old_handle)) - event.replace_handle_reference('Place', old_handle, - new_handle) + assert event.has_handle_reference("Place", old_handle) + event.replace_handle_reference("Place", old_handle, new_handle) self.database.commit_event(event, trans) elif class_name == Place.__name__: place = self.database.get_place_from_handle(handle) - assert(place.has_handle_reference('Place', old_handle)) - place.replace_handle_reference('Place', old_handle, - new_handle) + assert place.has_handle_reference("Place", old_handle) + place.replace_handle_reference("Place", old_handle, new_handle) self.database.commit_place(place, trans) elif class_name == Note.__name__: note = self.database.get_note_from_handle(handle) - assert(note.has_handle_reference('Place', old_handle)) - note.replace_handle_reference('Place', old_handle, - new_handle) + assert note.has_handle_reference("Place", old_handle) + note.replace_handle_reference("Place", old_handle, new_handle) self.database.commit_note(note, trans) else: - raise MergeError("Encounter an object of type %s that has " - "a place reference." % class_name) + raise MergeError( + "Encounter an object of type %s that has " + "a place reference." % class_name + ) self.database.remove_place(old_handle, trans) diff --git a/gramps/gen/merge/mergerepositoryquery.py b/gramps/gen/merge/mergerepositoryquery.py index 57a6f6b6d89..f861905daee 100644 --- a/gramps/gen/merge/mergerepositoryquery.py +++ b/gramps/gen/merge/mergerepositoryquery.py @@ -22,26 +22,29 @@ Provide merge capabilities for repositories. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..lib import Source, Note from ..db import DbTxn from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext from ..errors import MergeError -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MergeRepoQuery # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MergeRepositoryQuery: """ Create database query to merge two repositories. """ + def __init__(self, dbstate, phoenix, titanic): self.database = dbstate.db self.phoenix = phoenix @@ -58,20 +61,20 @@ def execute(self): with DbTxn(_("Merge Repositories"), self.database) as trans: self.database.commit_repository(self.phoenix, trans) - for (class_name, handle) in self.database.find_backlink_handles( - old_handle): + for class_name, handle in self.database.find_backlink_handles(old_handle): if class_name == Source.__name__: source = self.database.get_source_from_handle(handle) - assert source.has_handle_reference('Repository', old_handle) + assert source.has_handle_reference("Repository", old_handle) source.replace_repo_references(old_handle, new_handle) self.database.commit_source(source, trans) elif class_name == Note.__name__: note = self.database.get_note_from_handle(handle) - assert(note.has_handle_reference('Repository', old_handle)) - note.replace_handle_reference( - 'Repository', old_handle, new_handle) + assert note.has_handle_reference("Repository", old_handle) + note.replace_handle_reference("Repository", old_handle, new_handle) self.database.commit_note(note, trans) else: - raise MergeError("Encounter an object of type %s that has " - "a repository reference." % class_name) + raise MergeError( + "Encounter an object of type %s that has " + "a repository reference." % class_name + ) self.database.remove_repository(old_handle, trans) diff --git a/gramps/gen/merge/mergesourcequery.py b/gramps/gen/merge/mergesourcequery.py index fb6c4085b60..9d73ad8c1f8 100644 --- a/gramps/gen/merge/mergesourcequery.py +++ b/gramps/gen/merge/mergesourcequery.py @@ -24,26 +24,29 @@ Provide merge capabilities for sources. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- -from ..lib import (Citation, Note) +# ------------------------------------------------------------------------- +from ..lib import Citation, Note from ..db import DbTxn from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext from ..errors import MergeError -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MergeSourceQuery # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MergeSourceQuery: """ Create database query to merge two sources. """ + def __init__(self, dbstate, phoenix, titanic): self.database = dbstate.db self.phoenix = phoenix @@ -60,20 +63,20 @@ def execute(self): with DbTxn(_("Merge Source"), self.database) as trans: self.database.commit_source(self.phoenix, trans) - for (class_name, handle) in self.database.find_backlink_handles( - old_handle): + for class_name, handle in self.database.find_backlink_handles(old_handle): if class_name == Citation.__name__: citation = self.database.get_citation_from_handle(handle) - assert(citation.get_reference_handle() == old_handle) + assert citation.get_reference_handle() == old_handle citation.set_reference_handle(new_handle) self.database.commit_citation(citation, trans) elif class_name == Note.__name__: note = self.database.get_note_from_handle(handle) - assert(note.has_handle_reference('Source', old_handle)) - note.replace_handle_reference( - 'Source', old_handle, new_handle) + assert note.has_handle_reference("Source", old_handle) + note.replace_handle_reference("Source", old_handle, new_handle) self.database.commit_note(note, trans) else: - raise MergeError("Encounter an object of type %s that has " - "a source reference." % class_name) + raise MergeError( + "Encounter an object of type %s that has " + "a source reference." % class_name + ) self.database.remove_source(old_handle, trans) diff --git a/gramps/gen/merge/test/merge_ref_test.py b/gramps/gen/merge/test/merge_ref_test.py index c26188144f2..5c3677230ef 100644 --- a/gramps/gen/merge/test/merge_ref_test.py +++ b/gramps/gen/merge/test/merge_ref_test.py @@ -38,26 +38,30 @@ from gramps.version import VERSION from gramps.gen.lib import Name, Surname from gramps.gen.const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -HAS_CLIMERGE = os.path.isdir(os.path.join(USER_PLUGINS, 'CliMerge')) -HAS_EXPORTRAW = os.path.isdir(os.path.join(USER_PLUGINS, 'ExportRaw')) -NS_G = 'http://gramps-project.org/xml/%s/' % GRAMPS_XML_VERSION +HAS_CLIMERGE = os.path.isdir(os.path.join(USER_PLUGINS, "CliMerge")) +HAS_EXPORTRAW = os.path.isdir(os.path.join(USER_PLUGINS, "ExportRaw")) +NS_G = "http://gramps-project.org/xml/%s/" % GRAMPS_XML_VERSION NSP = "{%s}" % NS_G -@unittest.skipUnless(HAS_CLIMERGE and HAS_EXPORTRAW, - 'These tests need the 3rd-party plugins "CliMerge" ' - 'and "ExportRaw".') +@unittest.skipUnless( + HAS_CLIMERGE and HAS_EXPORTRAW, + 'These tests need the 3rd-party plugins "CliMerge" ' 'and "ExportRaw".', +) class BaseMergeCheck(unittest.TestCase): - """ Base class for the merge tests """ + """Base class for the merge tests""" + def base_setup(self): """Set up code needed by all tests.""" date = time.localtime(time.time()) # libxml2.keepBlanksDefault(0) self.parser = ET.XMLParser(remove_blank_text=True) - styledoc = ET.parse(os.path.join(DATA_DIR, "gramps_canonicalize.xsl"), - parser=self.parser) + styledoc = ET.parse( + os.path.join(DATA_DIR, "gramps_canonicalize.xsl"), parser=self.parser + ) self.transform = ET.XSLT(styledoc) self.basedoc = None self.base_str = """ @@ -68,8 +72,15 @@ def base_setup(self): \n - """ % (GRAMPS_XML_VERSION, GRAMPS_XML_VERSION, GRAMPS_XML_VERSION, - date[0], date[1], date[2], VERSION) + """ % ( + GRAMPS_XML_VERSION, + GRAMPS_XML_VERSION, + GRAMPS_XML_VERSION, + date[0], + date[1], + date[2], + VERSION, + ) def canonicalize(self, doctxt): """ @@ -88,23 +99,36 @@ def canonicalize(self, doctxt): raise TypeError canonical_doc = self.transform(doc) result = ET.tostring(canonical_doc, pretty_print=True) - #print(str(result, 'utf-8')) + # print(str(result, 'utf-8')) return result - def do_case(self, phoenix_id, titanic_id, input_doc, expect_doc, - test_error_str=''): + def do_case(self, phoenix_id, titanic_id, input_doc, expect_doc, test_error_str=""): """Do the merge and "assert" the result.""" gramps = Gramps(user=User()) result_str, err_str = gramps.run( - '-d', '.ImportXML', '--config=preferences.eprefix:DEFAULT', - '-i', '-', '-f', 'gramps', '-a', 'tool', '-p', + "-d", + ".ImportXML", + "--config=preferences.eprefix:DEFAULT", + "-i", + "-", + "-f", + "gramps", + "-a", + "tool", + "-p", "name=climerge,primary=%s,secondary=%s" % (phoenix_id, titanic_id), - '-e', '-', '-f', 'gramps', stdin=BytesIO(input_doc), bytesio=True) - self.check_results(input_doc, expect_doc, result_str, err_str, - test_error_str) - - def check_results(self, input_doc, expect_doc, result_str, err_str, - test_error_str=''): + "-e", + "-", + "-f", + "gramps", + stdin=BytesIO(input_doc), + bytesio=True, + ) + self.check_results(input_doc, expect_doc, result_str, err_str, test_error_str) + + def check_results( + self, input_doc, expect_doc, result_str, err_str, test_error_str="" + ): with tempfile.TemporaryDirectory() as tmpdirname: input_file = os.path.join(tmpdirname, "merge_test_input.gramps") @@ -115,7 +139,7 @@ def check_results(self, input_doc, expect_doc, result_str, err_str, else: if "Traceback (most recent call last):" in err_str: inp = self.canonicalize(input_doc) - inpt = open(input_file, mode='wb') + inpt = open(input_file, mode="wb") inpt.write(inp) inpt.close() raise Exception(err_str) @@ -125,68 +149,104 @@ def check_results(self, input_doc, expect_doc, result_str, err_str, expect_file = os.path.join(tmpdirname, "merge_test_expected.gramps") if result != expect: - res = open(result_file, mode='wb') + res = open(result_file, mode="wb") res.write(result) res.close() - eres = open(expect_file, mode='wb') + eres = open(expect_file, mode="wb") eres.write(expect) eres.close() inp = self.canonicalize(input_doc) - inpt = open(input_file, mode='wb') + inpt = open(input_file, mode="wb") inpt.write(inp) inpt.close() - result = result.decode('utf-8') - expect = expect.decode('utf-8') + result = result.decode("utf-8") + expect = expect.decode("utf-8") diff = difflib.ndiff(result, expect) msg = "" for line in diff: msg += line self.fail(msg) - def do_family_case(self, phoenix_id, titanic_id, father_h, mother_h, - input_doc, expect_doc, test_error_str=''): + def do_family_case( + self, + phoenix_id, + titanic_id, + father_h, + mother_h, + input_doc, + expect_doc, + test_error_str="", + ): gramps = Gramps(user=User()) result_str, err_str = gramps.run( - '-d', '.ImportXML', '--config=preferences.eprefix:DEFAULT', - '-i', '-', '-f', 'gramps', '-a', 'tool', '-p', - "name=climerge,primary=%s,secondary=%s,father_h=%s,mother_h=%s" % - (phoenix_id, titanic_id, father_h, mother_h), - '-e', '-', '-f', 'gramps', stdin=BytesIO(input_doc), bytesio=True) - self.check_results(input_doc, expect_doc, result_str, err_str, - test_error_str) - - def raw_contains(self, phoenix_id, titanic_id, input_doc, expect_str, - test_error_str=''): + "-d", + ".ImportXML", + "--config=preferences.eprefix:DEFAULT", + "-i", + "-", + "-f", + "gramps", + "-a", + "tool", + "-p", + "name=climerge,primary=%s,secondary=%s,father_h=%s,mother_h=%s" + % (phoenix_id, titanic_id, father_h, mother_h), + "-e", + "-", + "-f", + "gramps", + stdin=BytesIO(input_doc), + bytesio=True, + ) + self.check_results(input_doc, expect_doc, result_str, err_str, test_error_str) + + def raw_contains( + self, phoenix_id, titanic_id, input_doc, expect_str, test_error_str="" + ): gramps = Gramps(user=User()) result_str, err_str = gramps.run( - '-d', '.ImportXML', '--config=preferences.eprefix:DEFAULT', - '-i', '-', '-f', 'gramps', '-a', 'tool', '-p', + "-d", + ".ImportXML", + "--config=preferences.eprefix:DEFAULT", + "-i", + "-", + "-f", + "gramps", + "-a", + "tool", + "-p", "name=climerge,primary=%s,secondary=%s" % (phoenix_id, titanic_id), - '-e', '-', '-f', 'raw', stdin=BytesIO(input_doc), bytesio=False) + "-e", + "-", + "-f", + "raw", + stdin=BytesIO(input_doc), + bytesio=False, + ) if err_str: if test_error_str: self.assertIn(test_error_str, err_str) return if expect_str not in result_str: - msg = '\n***** result:\n' + result_str + \ - '\n***** expect:\n' + expect_str + msg = "\n***** result:\n" + result_str + "\n***** expect:\n" + expect_str inp = self.canonicalize(input_doc) with tempfile.TemporaryDirectory() as tmpdirname: input_file = os.path.join(tmpdirname, "merge_test_input.gramps") - inpt = open(input_file, mode='wb') + inpt = open(input_file, mode="wb") inpt.write(inp) inpt.close() self.fail(msg) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # PersonCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PersonCheck(BaseMergeCheck): """Class that checks what the influence is of merger of other primary objects on persons.""" + def setUp(self): self.base_setup() base_str = """ @@ -307,101 +367,109 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) def test_event_merge(self): - """Merge two events. Also checks that Event link in note is updated. - """ + """Merge two events. Also checks that Event link in note is updated.""" expect = ET.fromstring(self.basedoc, parser=self.parser) - eventref = expect.xpath("//g:person[@handle='_i0001']/g:eventref", - namespaces={"g": NS_G})[0] - eventref.attrib['hlink'] = '_e0000' - event = expect.xpath("//g:event[@handle='_e0001']", - namespaces={"g": NS_G})[0] + eventref = expect.xpath( + "//g:person[@handle='_i0001']/g:eventref", namespaces={"g": NS_G} + )[0] + eventref.attrib["hlink"] = "_e0000" + event = expect.xpath("//g:event[@handle='_e0001']", namespaces={"g": NS_G})[0] event.getparent().remove(event) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[1] - notetag.attrib['value'] = "gramps://Event/handle/e0000" - self.do_case('E0000', 'E0001', self.basedoc, expect) - #print(str(ET.tostring(expect, pretty_print=True), 'utf-8')) + notetag.attrib["value"] = "gramps://Event/handle/e0000" + self.do_case("E0000", "E0001", self.basedoc, expect) + # print(str(ET.tostring(expect, pretty_print=True), 'utf-8')) def test_place_merge(self): """Merge two places""" expect = ET.fromstring(self.basedoc, parser=self.parser) - place = expect.xpath("//g:person[@handle='_i0001']/g:lds_ord/g:place", - namespaces={"g": NS_G})[0] - place.attrib['hlink'] = '_p0000' - placeobj = expect.xpath("//g:placeobj[@handle='_p0001']", - namespaces={"g": NS_G})[0] + place = expect.xpath( + "//g:person[@handle='_i0001']/g:lds_ord/g:place", namespaces={"g": NS_G} + )[0] + place.attrib["hlink"] = "_p0000" + placeobj = expect.xpath( + "//g:placeobj[@handle='_p0001']", namespaces={"g": NS_G} + )[0] placeobj.getparent().remove(placeobj) - placeobj = expect.xpath("//g:placeobj[@handle='_p0000']", - namespaces={"g": NS_G})[0] + placeobj = expect.xpath( + "//g:placeobj[@handle='_p0000']", namespaces={"g": NS_G} + )[0] notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[4] - notetag.attrib['value'] = "gramps://Place/handle/p0000" - ET.SubElement(placeobj, NSP + 'pname', value='Place 1') - self.do_case('P0000', 'P0001', self.basedoc, expect) + notetag.attrib["value"] = "gramps://Place/handle/p0000" + ET.SubElement(placeobj, NSP + "pname", value="Place 1") + self.do_case("P0000", "P0001", self.basedoc, expect) def test_citation_merge(self): """Merge two citations""" expect = ET.fromstring(self.basedoc, parser=self.parser) - srcref = expect.xpath("//g:person[@handle='_i0001']/g:citationref", - namespaces={"g": NS_G})[0] - srcref.attrib['hlink'] = '_c0000' - citation = expect.xpath("//g:citation[@handle='_c0001']", - namespaces={"g": NS_G})[0] + srcref = expect.xpath( + "//g:person[@handle='_i0001']/g:citationref", namespaces={"g": NS_G} + )[0] + srcref.attrib["hlink"] = "_c0000" + citation = expect.xpath( + "//g:citation[@handle='_c0001']", namespaces={"g": NS_G} + )[0] citation.getparent().remove(citation) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Citation/handle/c0000" - self.do_case('C0000', 'C0001', self.basedoc, expect) + notetag.attrib["value"] = "gramps://Citation/handle/c0000" + self.do_case("C0000", "C0001", self.basedoc, expect) def test_media_merge(self): """Merge two media objects""" expect = ET.fromstring(self.basedoc, parser=self.parser) - objref = expect.xpath("//g:person[@handle='_i0001']/g:objref", - namespaces={"g": NS_G})[0] - objref.attrib['hlink'] = '_o0000' - object_ = expect.xpath("//g:object[@handle='_o0001']", - namespaces={"g": NS_G})[0] + objref = expect.xpath( + "//g:person[@handle='_i0001']/g:objref", namespaces={"g": NS_G} + )[0] + objref.attrib["hlink"] = "_o0000" + object_ = expect.xpath("//g:object[@handle='_o0001']", namespaces={"g": NS_G})[ + 0 + ] object_.getparent().remove(object_) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[2] - notetag.attrib['value'] = "gramps://Media/handle/o0000" - self.do_case('O0000', 'O0001', self.basedoc, expect) + notetag.attrib["value"] = "gramps://Media/handle/o0000" + self.do_case("O0000", "O0001", self.basedoc, expect) def test_note_merge(self): """Merge two notes""" expect = ET.fromstring(self.basedoc, parser=self.parser) - noteref = expect.xpath("//g:person[@handle='_i0001']/g:noteref", - namespaces={"g": NS_G})[0] - noteref.attrib['hlink'] = '_n0000' - note = expect.xpath("//g:note[@handle='_n0001']", - namespaces={"g": NS_G})[0] + noteref = expect.xpath( + "//g:person[@handle='_i0001']/g:noteref", namespaces={"g": NS_G} + )[0] + noteref.attrib["hlink"] = "_n0000" + note = expect.xpath("//g:note[@handle='_n0001']", namespaces={"g": NS_G})[0] notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[3] - notetag.attrib['value'] = "gramps://Note/handle/n0000" + notetag.attrib["value"] = "gramps://Note/handle/n0000" note.getparent().remove(note) - self.do_case('N0000', 'N0001', self.basedoc, expect) + self.do_case("N0000", "N0001", self.basedoc, expect) def test_repository_merge(self): """Merge two repository objects""" expect = ET.fromstring(self.basedoc, parser=self.parser) - reporef = expect.xpath("//g:source[@handle='_s0001']/g:reporef", - namespaces={"g": NS_G})[0] - reporef.attrib['hlink'] = '_r0000' - object_ = expect.xpath("//g:repository[@handle='_r0001']", - namespaces={"g": NS_G})[0] + reporef = expect.xpath( + "//g:source[@handle='_s0001']/g:reporef", namespaces={"g": NS_G} + )[0] + reporef.attrib["hlink"] = "_r0000" + object_ = expect.xpath( + "//g:repository[@handle='_r0001']", namespaces={"g": NS_G} + )[0] object_.getparent().remove(object_) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[5] - notetag.attrib['value'] = "gramps://Repository/handle/r0000" - self.do_case('R0000', 'R0001', self.basedoc, expect) + notetag.attrib["value"] = "gramps://Repository/handle/r0000" + self.do_case("R0000", "R0001", self.basedoc, expect) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # FamilyCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class FamilyCheck(BaseMergeCheck): """Class that checks what the influence is of merger of other primary objects on families.""" + def setUp(self): self.base_setup() base_str = """ @@ -484,76 +552,83 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) def test_event_merge(self): """Merge two events""" expect = ET.fromstring(self.basedoc, parser=self.parser) - eventref = expect.xpath("//g:family[@handle='_f0001']/g:eventref", - namespaces={"g": NS_G})[0] - eventref.attrib['hlink'] = '_e0000' - event = expect.xpath("//g:event[@handle='_e0001']", - namespaces={"g": NS_G})[0] + eventref = expect.xpath( + "//g:family[@handle='_f0001']/g:eventref", namespaces={"g": NS_G} + )[0] + eventref.attrib["hlink"] = "_e0000" + event = expect.xpath("//g:event[@handle='_e0001']", namespaces={"g": NS_G})[0] event.getparent().remove(event) - self.do_case('E0000', 'E0001', self.basedoc, expect) + self.do_case("E0000", "E0001", self.basedoc, expect) def test_place_merge(self): """Merge two places""" expect = ET.fromstring(self.basedoc, parser=self.parser) - place = expect.xpath("//g:family[@handle='_f0001']/g:lds_ord/g:place", - namespaces={"g": NS_G})[0] - place.attrib['hlink'] = '_p0000' - placeobj = expect.xpath("//g:placeobj[@handle='_p0001']", - namespaces={"g": NS_G})[0] + place = expect.xpath( + "//g:family[@handle='_f0001']/g:lds_ord/g:place", namespaces={"g": NS_G} + )[0] + place.attrib["hlink"] = "_p0000" + placeobj = expect.xpath( + "//g:placeobj[@handle='_p0001']", namespaces={"g": NS_G} + )[0] placeobj.getparent().remove(placeobj) - placeobj = expect.xpath("//g:placeobj[@handle='_p0000']", - namespaces={"g": NS_G})[0] - ET.SubElement(placeobj, NSP + 'pname', value='Place 1') - self.do_case('P0000', 'P0001', self.basedoc, expect) + placeobj = expect.xpath( + "//g:placeobj[@handle='_p0000']", namespaces={"g": NS_G} + )[0] + ET.SubElement(placeobj, NSP + "pname", value="Place 1") + self.do_case("P0000", "P0001", self.basedoc, expect) def test_citation_merge(self): """Merge two citations""" expect = ET.fromstring(self.basedoc, parser=self.parser) - citref = expect.xpath("//g:family[@handle='_f0001']/g:citationref", - namespaces={"g": NS_G})[0] - citref.attrib['hlink'] = '_c0000' - citation = expect.xpath("//g:citation[@handle='_c0001']", - namespaces={"g": NS_G})[0] + citref = expect.xpath( + "//g:family[@handle='_f0001']/g:citationref", namespaces={"g": NS_G} + )[0] + citref.attrib["hlink"] = "_c0000" + citation = expect.xpath( + "//g:citation[@handle='_c0001']", namespaces={"g": NS_G} + )[0] citation.getparent().remove(citation) - self.do_case('C0000', 'C0001', self.basedoc, expect) + self.do_case("C0000", "C0001", self.basedoc, expect) def test_media_merge(self): """Merge two media objects""" expect = ET.fromstring(self.basedoc, parser=self.parser) - objref = expect.xpath("//g:family[@handle='_f0001']/g:objref", - namespaces={"g": NS_G})[0] - objref.attrib['hlink'] = '_o0000' - object_ = expect.xpath("//g:object[@handle='_o0001']", - namespaces={"g": NS_G})[0] + objref = expect.xpath( + "//g:family[@handle='_f0001']/g:objref", namespaces={"g": NS_G} + )[0] + objref.attrib["hlink"] = "_o0000" + object_ = expect.xpath("//g:object[@handle='_o0001']", namespaces={"g": NS_G})[ + 0 + ] object_.getparent().remove(object_) - self.do_case('O0000', 'O0001', self.basedoc, expect) + self.do_case("O0000", "O0001", self.basedoc, expect) def test_note_merge(self): """Merge two notes""" expect = ET.fromstring(self.basedoc, parser=self.parser) - noteref = expect.xpath("//g:family[@handle='_f0001']/g:noteref", - namespaces={"g": NS_G})[0] - noteref.attrib['hlink'] = '_n0000' - note = expect.xpath("//g:note[@handle='_n0001']", - namespaces={"g": NS_G})[0] + noteref = expect.xpath( + "//g:family[@handle='_f0001']/g:noteref", namespaces={"g": NS_G} + )[0] + noteref.attrib["hlink"] = "_n0000" + note = expect.xpath("//g:note[@handle='_n0001']", namespaces={"g": NS_G})[0] note.getparent().remove(note) - self.do_case('N0000', 'N0001', self.basedoc, expect) + self.do_case("N0000", "N0001", self.basedoc, expect) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # EventCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class EventCheck(BaseMergeCheck): """Class that checks what the influence is of merger of other primary objects on events.""" + def setUp(self): self.base_setup() base_str = """ @@ -622,65 +697,72 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) def test_place_merge(self): """Merge two places""" expect = ET.fromstring(self.basedoc, parser=self.parser) - place = expect.xpath("//g:event[@handle='_e0001']/g:place", - namespaces={"g": NS_G})[0] - place.attrib['hlink'] = '_p0000' - placeobj = expect.xpath("//g:placeobj[@handle='_p0001']", - namespaces={"g": NS_G})[0] + place = expect.xpath( + "//g:event[@handle='_e0001']/g:place", namespaces={"g": NS_G} + )[0] + place.attrib["hlink"] = "_p0000" + placeobj = expect.xpath( + "//g:placeobj[@handle='_p0001']", namespaces={"g": NS_G} + )[0] placeobj.getparent().remove(placeobj) - placeobj = expect.xpath("//g:placeobj[@handle='_p0000']", - namespaces={"g": NS_G})[0] - ET.SubElement(placeobj, NSP + 'pname', value='Place 1') - self.do_case('P0000', 'P0001', self.basedoc, expect) + placeobj = expect.xpath( + "//g:placeobj[@handle='_p0000']", namespaces={"g": NS_G} + )[0] + ET.SubElement(placeobj, NSP + "pname", value="Place 1") + self.do_case("P0000", "P0001", self.basedoc, expect) def test_citation_merge(self): """Merge two citations""" expect = ET.fromstring(self.basedoc, parser=self.parser) - citref = expect.xpath("//g:event[@handle='_e0001']/g:citationref", - namespaces={"g": NS_G})[0] - citref.attrib['hlink'] = '_c0000' - citation = expect.xpath("//g:citation[@handle='_c0001']", - namespaces={"g": NS_G})[0] + citref = expect.xpath( + "//g:event[@handle='_e0001']/g:citationref", namespaces={"g": NS_G} + )[0] + citref.attrib["hlink"] = "_c0000" + citation = expect.xpath( + "//g:citation[@handle='_c0001']", namespaces={"g": NS_G} + )[0] citation.getparent().remove(citation) - self.do_case('C0000', 'C0001', self.basedoc, expect) + self.do_case("C0000", "C0001", self.basedoc, expect) def test_media_merge(self): """Merge two media objects""" expect = ET.fromstring(self.basedoc, parser=self.parser) - objref = expect.xpath("//g:event[@handle='_e0001']/g:objref", - namespaces={"g": NS_G})[0] - objref.attrib['hlink'] = '_o0000' - object_ = expect.xpath("//g:object[@handle='_o0001']", - namespaces={"g": NS_G})[0] + objref = expect.xpath( + "//g:event[@handle='_e0001']/g:objref", namespaces={"g": NS_G} + )[0] + objref.attrib["hlink"] = "_o0000" + object_ = expect.xpath("//g:object[@handle='_o0001']", namespaces={"g": NS_G})[ + 0 + ] object_.getparent().remove(object_) - self.do_case('O0000', 'O0001', self.basedoc, expect) + self.do_case("O0000", "O0001", self.basedoc, expect) def test_note_merge(self): """Merge two notes""" expect = ET.fromstring(self.basedoc, parser=self.parser) - noteref = expect.xpath("//g:event[@handle='_e0001']/g:noteref", - namespaces={"g": NS_G})[0] - noteref.attrib['hlink'] = '_n0000' - note = expect.xpath("//g:note[@handle='_n0001']", - namespaces={"g": NS_G})[0] + noteref = expect.xpath( + "//g:event[@handle='_e0001']/g:noteref", namespaces={"g": NS_G} + )[0] + noteref.attrib["hlink"] = "_n0000" + note = expect.xpath("//g:note[@handle='_n0001']", namespaces={"g": NS_G})[0] note.getparent().remove(note) - self.do_case('N0000', 'N0001', self.basedoc, expect) + self.do_case("N0000", "N0001", self.basedoc, expect) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # PlaceCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PlaceCheck(BaseMergeCheck): """Class that checks what the influence is of merger of other primary objects on places.""" + def setUp(self): self.base_setup() base_str = """ @@ -737,51 +819,55 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) def test_citation_merge(self): """Merge two citations""" expect = ET.fromstring(self.basedoc, parser=self.parser) - citref = expect.xpath("//g:placeobj[@handle='_p0001']/g:citationref", - namespaces={"g": NS_G})[0] - citref.attrib['hlink'] = '_c0000' - citation = expect.xpath("//g:citation[@handle='_c0001']", - namespaces={"g": NS_G})[0] + citref = expect.xpath( + "//g:placeobj[@handle='_p0001']/g:citationref", namespaces={"g": NS_G} + )[0] + citref.attrib["hlink"] = "_c0000" + citation = expect.xpath( + "//g:citation[@handle='_c0001']", namespaces={"g": NS_G} + )[0] citation.getparent().remove(citation) - self.do_case('C0000', 'C0001', self.basedoc, expect) + self.do_case("C0000", "C0001", self.basedoc, expect) def test_media_merge(self): """Merge two media objects""" expect = ET.fromstring(self.basedoc, parser=self.parser) - objref = expect.xpath("//g:placeobj[@handle='_p0001']/g:objref", - namespaces={"g": NS_G})[0] - objref.attrib['hlink'] = '_o0000' - object_ = expect.xpath("//g:object[@handle='_o0001']", - namespaces={"g": NS_G})[0] + objref = expect.xpath( + "//g:placeobj[@handle='_p0001']/g:objref", namespaces={"g": NS_G} + )[0] + objref.attrib["hlink"] = "_o0000" + object_ = expect.xpath("//g:object[@handle='_o0001']", namespaces={"g": NS_G})[ + 0 + ] object_.getparent().remove(object_) - self.do_case('O0000', 'O0001', self.basedoc, expect) + self.do_case("O0000", "O0001", self.basedoc, expect) def test_note_merge(self): """Merge two notes""" expect = ET.fromstring(self.basedoc, parser=self.parser) - noteref = expect.xpath("//g:placeobj[@handle='_p0001']/g:noteref", - namespaces={"g": NS_G})[0] - noteref.attrib['hlink'] = '_n0000' - note = expect.xpath("//g:note[@handle='_n0001']", - namespaces={"g": NS_G})[0] + noteref = expect.xpath( + "//g:placeobj[@handle='_p0001']/g:noteref", namespaces={"g": NS_G} + )[0] + noteref.attrib["hlink"] = "_n0000" + note = expect.xpath("//g:note[@handle='_n0001']", namespaces={"g": NS_G})[0] note.getparent().remove(note) - self.do_case('N0000', 'N0001', self.basedoc, expect) + self.do_case("N0000", "N0001", self.basedoc, expect) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # SourceCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SourceCheck(BaseMergeCheck): """Class that checks what the influence is of merger of other primary objects on sources.""" + def setUp(self): self.base_setup() base_str = """ @@ -838,56 +924,60 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) - #def test_citation_merge(self): SEE special cases. + # def test_citation_merge(self): SEE special cases. def test_repo_merge(self): """Merge two repositories""" expect = ET.fromstring(self.basedoc, parser=self.parser) # Adjust the repository reference in expectation. - reporef = expect.xpath("//g:source[@handle='_s0001']/g:reporef", - namespaces={"g": NS_G})[0] - reporef.attrib['hlink'] = '_r0000' + reporef = expect.xpath( + "//g:source[@handle='_s0001']/g:reporef", namespaces={"g": NS_G} + )[0] + reporef.attrib["hlink"] = "_r0000" # Remove one repository in expectation. - repo = expect.xpath("//g:repository[@handle='_r0001']", - namespaces={"g": NS_G})[0] + repo = expect.xpath("//g:repository[@handle='_r0001']", namespaces={"g": NS_G})[ + 0 + ] repo.getparent().remove(repo) # Do the actual merger and comparison. - self.do_case('R0000', 'R0001', self.basedoc, expect) + self.do_case("R0000", "R0001", self.basedoc, expect) def test_media_merge(self): """Merge two media objects""" expect = ET.fromstring(self.basedoc, parser=self.parser) - objref = expect.xpath("//g:source[@handle='_s0001']/g:objref", - namespaces={"g": NS_G})[0] - objref.attrib['hlink'] = '_o0000' - object_ = expect.xpath("//g:object[@handle='_o0001']", - namespaces={"g": NS_G})[0] + objref = expect.xpath( + "//g:source[@handle='_s0001']/g:objref", namespaces={"g": NS_G} + )[0] + objref.attrib["hlink"] = "_o0000" + object_ = expect.xpath("//g:object[@handle='_o0001']", namespaces={"g": NS_G})[ + 0 + ] object_.getparent().remove(object_) - self.do_case('O0000', 'O0001', self.basedoc, expect) + self.do_case("O0000", "O0001", self.basedoc, expect) def test_note_merge(self): """Merge two notes""" expect = ET.fromstring(self.basedoc, parser=self.parser) - noteref = expect.xpath("//g:source[@handle='_s0001']/g:noteref", - namespaces={"g": NS_G})[0] - noteref.attrib['hlink'] = '_n0000' - note = expect.xpath("//g:note[@handle='_n0001']", - namespaces={"g": NS_G})[0] + noteref = expect.xpath( + "//g:source[@handle='_s0001']/g:noteref", namespaces={"g": NS_G} + )[0] + noteref.attrib["hlink"] = "_n0000" + note = expect.xpath("//g:note[@handle='_n0001']", namespaces={"g": NS_G})[0] note.getparent().remove(note) - self.do_case('N0000', 'N0001', self.basedoc, expect) + self.do_case("N0000", "N0001", self.basedoc, expect) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # RepoCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class RepoCheck(BaseMergeCheck): """Class that checks what the influence is of merger of other primary objects on repositories.""" + def setUp(self): self.base_setup() base_str = """ @@ -940,41 +1030,43 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) def test_citation_merge(self): """Merge two citations""" expect = ET.fromstring(self.basedoc, parser=self.parser) - citref = expect.xpath("//g:repository[@handle='_r0001']" - "/g:address/g:citationref", - namespaces={"g": NS_G})[0] - citref.attrib['hlink'] = '_c0000' - citation = expect.xpath("//g:citation[@handle='_c0001']", - namespaces={"g": NS_G})[0] + citref = expect.xpath( + "//g:repository[@handle='_r0001']" "/g:address/g:citationref", + namespaces={"g": NS_G}, + )[0] + citref.attrib["hlink"] = "_c0000" + citation = expect.xpath( + "//g:citation[@handle='_c0001']", namespaces={"g": NS_G} + )[0] citation.getparent().remove(citation) - self.do_case('C0000', 'C0001', self.basedoc, expect) + self.do_case("C0000", "C0001", self.basedoc, expect) def test_note_merge(self): """Merge two notes""" expect = ET.fromstring(self.basedoc, parser=self.parser) - noteref = expect.xpath("//g:repository[@handle='_r0001']/g:noteref", - namespaces={"g": NS_G})[0] - noteref.attrib['hlink'] = '_n0000' - note = expect.xpath("//g:note[@handle='_n0001']", - namespaces={"g": NS_G})[0] + noteref = expect.xpath( + "//g:repository[@handle='_r0001']/g:noteref", namespaces={"g": NS_G} + )[0] + noteref.attrib["hlink"] = "_n0000" + note = expect.xpath("//g:note[@handle='_n0001']", namespaces={"g": NS_G})[0] note.getparent().remove(note) - self.do_case('N0000', 'N0001', self.basedoc, expect) + self.do_case("N0000", "N0001", self.basedoc, expect) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # MediaCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MediaCheck(BaseMergeCheck): """Class that checks what the influence is of merger of other primary objects on media objects.""" + def setUp(self): self.base_setup() base_str = """ @@ -1019,43 +1111,45 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) def test_citation_merge(self): """Merge two citations""" expect = ET.fromstring(self.basedoc, parser=self.parser) - citref = expect.xpath("//g:object[@handle='_o0001']/g:citationref", - namespaces={"g": NS_G})[0] - citref.attrib['hlink'] = '_c0000' - citation = expect.xpath("//g:citation[@handle='_c0001']", - namespaces={"g": NS_G})[0] + citref = expect.xpath( + "//g:object[@handle='_o0001']/g:citationref", namespaces={"g": NS_G} + )[0] + citref.attrib["hlink"] = "_c0000" + citation = expect.xpath( + "//g:citation[@handle='_c0001']", namespaces={"g": NS_G} + )[0] citation.getparent().remove(citation) - self.do_case('C0000', 'C0001', self.basedoc, expect) + self.do_case("C0000", "C0001", self.basedoc, expect) def test_note_merge(self): """Merge two notes""" expect = ET.fromstring(self.basedoc, parser=self.parser) - noteref = expect.xpath("//g:object[@handle='_o0001']/g:noteref", - namespaces={"g": NS_G})[0] - noteref.attrib['hlink'] = '_n0000' - note = expect.xpath("//g:note[@handle='_n0001']", - namespaces={"g": NS_G})[0] + noteref = expect.xpath( + "//g:object[@handle='_o0001']/g:noteref", namespaces={"g": NS_G} + )[0] + noteref.attrib["hlink"] = "_n0000" + note = expect.xpath("//g:note[@handle='_n0001']", namespaces={"g": NS_G})[0] note.getparent().remove(note) - self.do_case('N0000', 'N0001', self.basedoc, expect) + self.do_case("N0000", "N0001", self.basedoc, expect) + -#========================================================================= +# ========================================================================= # # Special cases # -#========================================================================= +# ========================================================================= -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # SourceSourceCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SourceSourceCheck(BaseMergeCheck): def setUp(self): self.base_setup() @@ -1105,59 +1199,67 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) def test_citation_merge(self): expect = ET.fromstring(self.basedoc, parser=self.parser) - citrefs = expect.xpath("//g:citation[@handle='_c0001']" - "/g:objref/g:citationref", - namespaces={"g": NS_G}) - citrefs[0].attrib['hlink'] = '_c0002' - citations = expect.xpath("//g:citation[@handle='_c0003']", - namespaces={"g": NS_G}) + citrefs = expect.xpath( + "//g:citation[@handle='_c0001']" "/g:objref/g:citationref", + namespaces={"g": NS_G}, + ) + citrefs[0].attrib["hlink"] = "_c0002" + citations = expect.xpath( + "//g:citation[@handle='_c0003']", namespaces={"g": NS_G} + ) citations[0].getparent().remove(citations[0]) - self.do_case('C0002', 'C0003', self.basedoc, expect) + self.do_case("C0002", "C0003", self.basedoc, expect) def test_citation_cross_merge(self): input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - input_citrefs = input_ctxt.xpath("//g:citation/g:objref/g:citationref", - namespaces={"g": NS_G}) - input_citrefs[0].attrib['hlink'] = '_c0001' - input_citrefs[1].attrib['hlink'] = '_c0000' - rmcit = input_ctxt.xpath("//g:citation[@handle='_c0002']", - namespaces={"g": NS_G}) + input_citrefs = input_ctxt.xpath( + "//g:citation/g:objref/g:citationref", namespaces={"g": NS_G} + ) + input_citrefs[0].attrib["hlink"] = "_c0001" + input_citrefs[1].attrib["hlink"] = "_c0000" + rmcit = input_ctxt.xpath( + "//g:citation[@handle='_c0002']", namespaces={"g": NS_G} + ) rmcit[0].getparent().remove(rmcit[0]) - rmcit = input_ctxt.xpath("//g:citation[@handle='_c0003']", - namespaces={"g": NS_G}) + rmcit = input_ctxt.xpath( + "//g:citation[@handle='_c0003']", namespaces={"g": NS_G} + ) rmcit[0].getparent().remove(rmcit[0]) - rmsrc = input_ctxt.xpath("//g:source[@handle='_s0001']", - namespaces={"g": NS_G}) + rmsrc = input_ctxt.xpath("//g:source[@handle='_s0001']", namespaces={"g": NS_G}) rmsrc[0].getparent().remove(rmsrc[0]) expect = copy.deepcopy(input_ctxt) - citrefs = expect.xpath("//g:citation[@handle='_c0000']/g:objref" - "/g:citationref", namespaces={"g": NS_G}) - citrefs[0].attrib['hlink'] = '_c0000' + citrefs = expect.xpath( + "//g:citation[@handle='_c0000']/g:objref" "/g:citationref", + namespaces={"g": NS_G}, + ) + citrefs[0].attrib["hlink"] = "_c0000" # add objref - objref = expect.xpath("//g:citation[@handle='_c0000']/g:objref", - namespaces={"g": NS_G}) - objref2 = expect.xpath("//g:citation[@handle='_c0001']/g:objref", - namespaces={"g": NS_G}) - #objref[0].addNextSibling(objref2[0]) + objref = expect.xpath( + "//g:citation[@handle='_c0000']/g:objref", namespaces={"g": NS_G} + ) + objref2 = expect.xpath( + "//g:citation[@handle='_c0001']/g:objref", namespaces={"g": NS_G} + ) + # objref[0].addNextSibling(objref2[0]) objref[0].addnext(objref2[0]) # remove citation - citations = expect.xpath("//g:citation[@handle='_c0001']", - namespaces={"g": NS_G}) + citations = expect.xpath( + "//g:citation[@handle='_c0001']", namespaces={"g": NS_G} + ) citations[0].getparent().remove(citations[0]) input_doc = ET.tostring(input_ctxt) - self.do_case('C0000', 'C0001', input_doc, expect) + self.do_case("C0000", "C0001", input_doc, expect) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # BirthCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class BirthCheck(BaseMergeCheck): def setUp(self): self.base_setup() @@ -1188,8 +1290,7 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) surname = Surname() surname.set_surname("Person 0") surname.set_prefix("") @@ -1197,61 +1298,60 @@ def setUp(self): name = Name() name.add_surname(surname) self.expect_str = "person: i0000 ('i0000', 'I0000', 1, %s, [], " % str( - name.serialize()) + name.serialize() + ) def test_birth_loss(self): # check that birth_ref_index is -1 # input_doc = ET.fromstring(self.basedoc, parser=self.parser) expect_str = self.expect_str + "1, -1" - self.raw_contains('E0000', 'E0001', self.basedoc, expect_str) + self.raw_contains("E0000", "E0001", self.basedoc, expect_str) def test_second_birth(self): # check that birth _ref_index is 2 input_doc = ET.fromstring(self.basedoc, parser=self.parser) - events = input_doc.xpath("//g:events", - namespaces={"g": NS_G})[0] - second_birth = ET.SubElement(events, NSP + 'event', - handle='_e0003', id='E0003') - birthtype = ET.SubElement(second_birth, NSP + 'type') - birthtype.text = 'Birth' - birthdesc = ET.SubElement(second_birth, NSP + 'description') - birthdesc.text = 'Event 3' - person = input_doc.xpath("//g:person[@handle='_i0000']", - namespaces={"g": NS_G})[0] - ET.SubElement(person, NSP + 'eventref', hlink='_e0003', role='Primary') + events = input_doc.xpath("//g:events", namespaces={"g": NS_G})[0] + second_birth = ET.SubElement(events, NSP + "event", handle="_e0003", id="E0003") + birthtype = ET.SubElement(second_birth, NSP + "type") + birthtype.text = "Birth" + birthdesc = ET.SubElement(second_birth, NSP + "description") + birthdesc.text = "Event 3" + person = input_doc.xpath( + "//g:person[@handle='_i0000']", namespaces={"g": NS_G} + )[0] + ET.SubElement(person, NSP + "eventref", hlink="_e0003", role="Primary") expect_str = self.expect_str + "1, 2" input_str = ET.tostring(input_doc) - self.raw_contains('E0000', 'E0001', input_str, expect_str) + self.raw_contains("E0000", "E0001", input_str, expect_str) def test_death_merge(self): # check that death_ref_index is -1 expect_str = self.expect_str + "-1, 1" - self.raw_contains('E0000', 'E0002', self.basedoc, expect_str) + self.raw_contains("E0000", "E0002", self.basedoc, expect_str) def test_second_death(self): # check that death _ref_index is 2 input_doc = ET.fromstring(self.basedoc, parser=self.parser) - events = input_doc.xpath("//g:events", - namespaces={"g": NS_G})[0] - second_death = ET.SubElement(events, NSP + 'event', - handle='_e0003', id='E0003') - deathtype = ET.SubElement(second_death, NSP + 'type') - deathtype.text = 'Death' - deathdesc = ET.SubElement(second_death, NSP + 'description') - deathdesc.text = 'Event 3' - person = input_doc.xpath("//g:person[@handle='_i0000']", - namespaces={"g": NS_G})[0] - ET.SubElement(person, NSP + 'eventref', hlink='_e0003', role='Primary') + events = input_doc.xpath("//g:events", namespaces={"g": NS_G})[0] + second_death = ET.SubElement(events, NSP + "event", handle="_e0003", id="E0003") + deathtype = ET.SubElement(second_death, NSP + "type") + deathtype.text = "Death" + deathdesc = ET.SubElement(second_death, NSP + "description") + deathdesc.text = "Event 3" + person = input_doc.xpath( + "//g:person[@handle='_i0000']", namespaces={"g": NS_G} + )[0] + ET.SubElement(person, NSP + "eventref", hlink="_e0003", role="Primary") expect_str = self.expect_str + "2, 1" input_str = ET.tostring(input_doc) - self.raw_contains('E0000', 'E0002', input_str, expect_str) + self.raw_contains("E0000", "E0002", input_str, expect_str) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # PersonPersonCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PersonPersonCheck(BaseMergeCheck): def setUp(self): self.base_setup() @@ -1279,103 +1379,88 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) def test_person_merge(self): """There is a person not involved in merger that references Titanic.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - people = input_ctxt.xpath("//g:people", - namespaces={"g": NS_G})[0] - person = ET.SubElement(people, NSP + 'person', - handle='_i0002', id='I0002') - ET.SubElement(person, NSP + 'gender').text = 'M' - name = ET.SubElement(person, NSP + 'name', type='Birth Name') - ET.SubElement(name, NSP + 'surname').text = 'Person 2' - ET.SubElement(person, NSP + 'personref', - hlink='_i0001', rel='Neighbour') + people = input_ctxt.xpath("//g:people", namespaces={"g": NS_G})[0] + person = ET.SubElement(people, NSP + "person", handle="_i0002", id="I0002") + ET.SubElement(person, NSP + "gender").text = "M" + name = ET.SubElement(person, NSP + "name", type="Birth Name") + ET.SubElement(name, NSP + "surname").text = "Person 2" + ET.SubElement(person, NSP + "personref", hlink="_i0001", rel="Neighbour") expect = copy.deepcopy(input_ctxt) - personref = expect.xpath("//g:personref", - namespaces={"g": NS_G})[0] - personref.attrib['hlink'] = '_i0000' - person = expect.xpath("//g:person[@handle='_i0000']", - namespaces={"g": NS_G})[0] - altname = ET.SubElement(person, NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 1' - ET.SubElement(person, NSP + 'attribute', - type='Merged Gramps ID', value='I0001') - person = expect.xpath("//g:person[@handle='_i0001']", - namespaces={"g": NS_G})[0] + personref = expect.xpath("//g:personref", namespaces={"g": NS_G})[0] + personref.attrib["hlink"] = "_i0000" + person = expect.xpath("//g:person[@handle='_i0000']", namespaces={"g": NS_G})[0] + altname = ET.SubElement(person, NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 1" + ET.SubElement(person, NSP + "attribute", type="Merged Gramps ID", value="I0001") + person = expect.xpath("//g:person[@handle='_i0001']", namespaces={"g": NS_G})[0] person.getparent().remove(person) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + notetag.attrib["value"] = "gramps://Person/handle/i0000" input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0001', input_doc, expect) + self.do_case("I0000", "I0001", input_doc, expect) def test_person_cross(self): """Phoenix has ref to Titanic and vice versa""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - persons = input_ctxt.xpath("//g:person", - namespaces={"g": NS_G}) - ET.SubElement(persons[0], NSP + 'personref', - hlink='_i0001', rel='Neighbour East') - ET.SubElement(persons[1], NSP + 'personref', - hlink='_i0000', rel='Neighbour West') + persons = input_ctxt.xpath("//g:person", namespaces={"g": NS_G}) + ET.SubElement( + persons[0], NSP + "personref", hlink="_i0001", rel="Neighbour East" + ) + ET.SubElement( + persons[1], NSP + "personref", hlink="_i0000", rel="Neighbour West" + ) expect = copy.deepcopy(input_ctxt) - personref = expect.xpath("//g:person[@handle='_i0000']/g:personref", - namespaces={"g": NS_G})[0] - personref.attrib['hlink'] = '_i0000' - person = expect.xpath("//g:person[@handle='_i0000']", - namespaces={"g": NS_G})[0] - altname = ET.SubElement(person, NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 1' - ET.SubElement(person, NSP + 'attribute', - type='Merged Gramps ID', value='I0001') + personref = expect.xpath( + "//g:person[@handle='_i0000']/g:personref", namespaces={"g": NS_G} + )[0] + personref.attrib["hlink"] = "_i0000" + person = expect.xpath("//g:person[@handle='_i0000']", namespaces={"g": NS_G})[0] + altname = ET.SubElement(person, NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 1" + ET.SubElement(person, NSP + "attribute", type="Merged Gramps ID", value="I0001") person.append(personref) # restore order of elements - personref = ET.SubElement(person, NSP + 'personref', - hlink='_i0000', rel='Neighbour West') - person = expect.xpath("//g:person[@handle='_i0001']", - namespaces={"g": NS_G})[0] + personref = ET.SubElement( + person, NSP + "personref", hlink="_i0000", rel="Neighbour West" + ) + person = expect.xpath("//g:person[@handle='_i0001']", namespaces={"g": NS_G})[0] person.getparent().remove(person) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + notetag.attrib["value"] = "gramps://Person/handle/i0000" input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0001', input_doc, expect) + self.do_case("I0000", "I0001", input_doc, expect) def test_person_self(self): """Titanic references itself""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - person = input_ctxt.xpath("//g:person[@handle='_i0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(person, NSP + 'personref', - hlink='_i0001', rel='Neighbour') + person = input_ctxt.xpath( + "//g:person[@handle='_i0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(person, NSP + "personref", hlink="_i0001", rel="Neighbour") expect = copy.deepcopy(input_ctxt) - person = expect.xpath("//g:person[@handle='_i0000']", - namespaces={"g": NS_G})[0] - altname = ET.SubElement(person, NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 1' - ET.SubElement(person, NSP + 'attribute', - type='Merged Gramps ID', value='I0001') - ET.SubElement(person, NSP + 'personref', - hlink='_i0000', rel='Neighbour') - person = expect.xpath("//g:person[@handle='_i0001']", - namespaces={"g": NS_G})[0] + person = expect.xpath("//g:person[@handle='_i0000']", namespaces={"g": NS_G})[0] + altname = ET.SubElement(person, NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 1" + ET.SubElement(person, NSP + "attribute", type="Merged Gramps ID", value="I0001") + ET.SubElement(person, NSP + "personref", hlink="_i0000", rel="Neighbour") + person = expect.xpath("//g:person[@handle='_i0001']", namespaces={"g": NS_G})[0] person.getparent().remove(person) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + notetag.attrib["value"] = "gramps://Person/handle/i0000" input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0001', input_doc, expect) + self.do_case("I0000", "I0001", input_doc, expect) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # ParentFamilyPersonCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ParentFamilyPersonCheck(BaseMergeCheck): def setUp(self): self.base_setup() @@ -1407,38 +1492,39 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) def test_person_merge(self): """Merge two persons that are children in some family""" expect = ET.fromstring(self.basedoc, parser=self.parser) - childref = expect.xpath("//g:family[@handle='_f0001']/g:childref", - namespaces={"g": NS_G})[0] - childref.attrib['hlink'] = '_i0000' - - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 1' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0001') - childof = expect.xpath("//g:person[@handle='_i0000']/g:childof", - namespaces={"g": NS_G})[0] + childref = expect.xpath( + "//g:family[@handle='_f0001']/g:childref", namespaces={"g": NS_G} + )[0] + childref.attrib["hlink"] = "_i0000" + + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 1" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0001" + ) + childof = expect.xpath( + "//g:person[@handle='_i0000']/g:childof", namespaces={"g": NS_G} + )[0] attr.addnext(childof) # restore order of elements - childof = ET.SubElement(persons[0], NSP + 'childof', hlink='_f0001') + childof = ET.SubElement(persons[0], NSP + "childof", hlink="_f0001") persons[1].getparent().remove(persons[1]) - self.do_case('I0000', 'I0001', self.basedoc, expect) + self.do_case("I0000", "I0001", self.basedoc, expect) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # FamilyPersonCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class FamilyPersonCheck(BaseMergeCheck): """Merge two persons that are parents in families""" + def setUp(self): self.base_setup() base_str = """ @@ -1501,473 +1587,489 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) def test_titanic_no_fam(self): "Test merge of two persons where titanic is not a parent in a family" expect = ET.fromstring(self.basedoc, parser=self.parser) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements - notetag = expect.xpath("//g:note[@handle='_n0000']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + notetag = expect.xpath( + "//g:note[@handle='_n0000']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Person/handle/i0000" persons[2].getparent().remove(persons[2]) - self.do_case('I0000', 'I0002', self.basedoc, expect) + self.do_case("I0000", "I0002", self.basedoc, expect) def test_no_fam_merge(self): """Test merge of two persons, both parents in a family, but such that the families will not merge.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - person = input_ctxt.xpath("//g:person[@handle='_i0002']", - namespaces={"g": NS_G})[0] - ET.SubElement(person, NSP + 'parentin', hlink='_f0001') - family = input_ctxt.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'father', hlink='_i0002') + person = input_ctxt.xpath( + "//g:person[@handle='_i0002']", namespaces={"g": NS_G} + )[0] + ET.SubElement(person, NSP + "parentin", hlink="_f0001") + family = input_ctxt.xpath( + "//g:family[@handle='_f0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "father", hlink="_i0002") expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements - ET.SubElement(persons[0], NSP + 'parentin', hlink='_f0001') - father = expect.xpath("//g:family[@handle='_f0001']/g:father", - namespaces={"g": NS_G})[0] - father.attrib['hlink'] = '_i0000' - notetag = expect.xpath("//g:note[@handle='_n0000']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + ET.SubElement(persons[0], NSP + "parentin", hlink="_f0001") + father = expect.xpath( + "//g:family[@handle='_f0001']/g:father", namespaces={"g": NS_G} + )[0] + father.attrib["hlink"] = "_i0000" + notetag = expect.xpath( + "//g:note[@handle='_n0000']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Person/handle/i0000" persons[2].getparent().remove(persons[2]) input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0002', input_doc, expect) + self.do_case("I0000", "I0002", input_doc, expect) def test_multi_rel(self): """Merge two persons where titanic has multiple family relationships with his partner, this should raise an error.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements - ET.SubElement(persons[0], NSP + 'parentin', hlink='_f0001') - ET.SubElement(persons[3], NSP + 'parentin', hlink='_f0001') - ET.SubElement(persons[0], NSP + 'parentin', hlink='_f0002') - ET.SubElement(persons[3], NSP + 'parentin', hlink='_f0002') - family = expect.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'father', hlink='_i0000') - ET.SubElement(family, NSP + 'mother', hlink='_i0003') - families = expect.xpath("//g:families", - namespaces={"g": NS_G})[0] - family = ET.SubElement(families, NSP + 'family', - handle='_f0002', id='F0002') - ET.SubElement(family, NSP + 'rel', type='Married') - ET.SubElement(family, NSP + 'father', hlink='_i0000') - ET.SubElement(family, NSP + 'mother', hlink='_i0003') - notetag = expect.xpath("//g:note[@handle='_n0000']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + ET.SubElement(persons[0], NSP + "parentin", hlink="_f0001") + ET.SubElement(persons[3], NSP + "parentin", hlink="_f0001") + ET.SubElement(persons[0], NSP + "parentin", hlink="_f0002") + ET.SubElement(persons[3], NSP + "parentin", hlink="_f0002") + family = expect.xpath("//g:family[@handle='_f0001']", namespaces={"g": NS_G})[0] + ET.SubElement(family, NSP + "father", hlink="_i0000") + ET.SubElement(family, NSP + "mother", hlink="_i0003") + families = expect.xpath("//g:families", namespaces={"g": NS_G})[0] + family = ET.SubElement(families, NSP + "family", handle="_f0002", id="F0002") + ET.SubElement(family, NSP + "rel", type="Married") + ET.SubElement(family, NSP + "father", hlink="_i0000") + ET.SubElement(family, NSP + "mother", hlink="_i0003") + notetag = expect.xpath( + "//g:note[@handle='_n0000']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Person/handle/i0000" persons[2].getparent().remove(persons[2]) - persons = input_ctxt.xpath("//g:person", - namespaces={"g": NS_G}) - ET.SubElement(persons[2], NSP + 'parentin', hlink='_f0001') - ET.SubElement(persons[3], NSP + 'parentin', hlink='_f0001') - ET.SubElement(persons[2], NSP + 'parentin', hlink='_f0002') - ET.SubElement(persons[3], NSP + 'parentin', hlink='_f0002') - family = input_ctxt.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'father', hlink='_i0002') - ET.SubElement(family, NSP + 'mother', hlink='_i0003') - families = input_ctxt.xpath("//g:families", - namespaces={"g": NS_G})[0] - family = ET.SubElement(families, NSP + 'family', - handle='_f0002', id='F0002') - ET.SubElement(family, NSP + 'rel', type='Married') - ET.SubElement(family, NSP + 'father', hlink='_i0002') - ET.SubElement(family, NSP + 'mother', hlink='_i0003') + persons = input_ctxt.xpath("//g:person", namespaces={"g": NS_G}) + ET.SubElement(persons[2], NSP + "parentin", hlink="_f0001") + ET.SubElement(persons[3], NSP + "parentin", hlink="_f0001") + ET.SubElement(persons[2], NSP + "parentin", hlink="_f0002") + ET.SubElement(persons[3], NSP + "parentin", hlink="_f0002") + family = input_ctxt.xpath( + "//g:family[@handle='_f0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "father", hlink="_i0002") + ET.SubElement(family, NSP + "mother", hlink="_i0003") + families = input_ctxt.xpath("//g:families", namespaces={"g": NS_G})[0] + family = ET.SubElement(families, NSP + "family", handle="_f0002", id="F0002") + ET.SubElement(family, NSP + "rel", type="Married") + ET.SubElement(family, NSP + "father", hlink="_i0002") + ET.SubElement(family, NSP + "mother", hlink="_i0003") input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0002', input_doc, expect, - test_error_str="") + self.do_case("I0000", "I0002", input_doc, expect, test_error_str="") def test_merge_fam(self): """Merge two persons such that also the families in which they are parents get merged.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - persons = input_ctxt.xpath("//g:person", - namespaces={"g": NS_G}) - ET.SubElement(persons[1], NSP + 'parentin', hlink='_f0001') - ET.SubElement(persons[2], NSP + 'parentin', hlink='_f0001') - family = input_ctxt.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'father', hlink='_i0002') - ET.SubElement(family, NSP + 'mother', hlink='_i0001') + persons = input_ctxt.xpath("//g:person", namespaces={"g": NS_G}) + ET.SubElement(persons[1], NSP + "parentin", hlink="_f0001") + ET.SubElement(persons[2], NSP + "parentin", hlink="_f0001") + family = input_ctxt.xpath( + "//g:family[@handle='_f0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "father", hlink="_i0002") + ET.SubElement(family, NSP + "mother", hlink="_i0001") expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements - notetag = expect.xpath("//g:note[@handle='_n0000']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + notetag = expect.xpath( + "//g:note[@handle='_n0000']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Person/handle/i0000" persons[2].getparent().remove(persons[2]) - notetag = expect.xpath("//g:note[@handle='_n0001']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - family = expect.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] + notetag = expect.xpath( + "//g:note[@handle='_n0001']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Family/handle/f0000" + family = expect.xpath("//g:family[@handle='_f0001']", namespaces={"g": NS_G})[0] family.getparent().remove(family) - parentin = expect.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[1] + parentin = expect.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[1] parentin.getparent().remove(parentin) input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0002', input_doc, expect) + self.do_case("I0000", "I0002", input_doc, expect) def test_fam_none_merge(self): """Merge two persons, both father in families without mothers.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - parentin = input_ctxt.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + parentin = input_ctxt.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] parentin.getparent().remove(parentin) - mother = input_ctxt.xpath("//g:family[@handle='_f0000']/g:mother", - namespaces={"g": NS_G})[0] + mother = input_ctxt.xpath( + "//g:family[@handle='_f0000']/g:mother", namespaces={"g": NS_G} + )[0] mother.getparent().remove(mother) - family = input_ctxt.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'father', hlink='_i0002') - person = input_ctxt.xpath("//g:person[@handle='_i0002']", - namespaces={"g": NS_G})[0] - parentin = ET.SubElement(person, NSP + 'parentin', hlink='_f0001', ) + family = input_ctxt.xpath( + "//g:family[@handle='_f0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "father", hlink="_i0002") + person = input_ctxt.xpath( + "//g:person[@handle='_i0002']", namespaces={"g": NS_G} + )[0] + parentin = ET.SubElement( + person, + NSP + "parentin", + hlink="_f0001", + ) expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements - notetag = expect.xpath("//g:note[@handle='_n0000']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" - notetag = expect.xpath("//g:note[@handle='_n0001']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" + notetag = expect.xpath( + "//g:note[@handle='_n0000']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Person/handle/i0000" + notetag = expect.xpath( + "//g:note[@handle='_n0001']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Family/handle/f0000" persons[2].getparent().remove(persons[2]) - family = expect.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] + family = expect.xpath("//g:family[@handle='_f0001']", namespaces={"g": NS_G})[0] family.getparent().remove(family) input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0002', input_doc, expect) + self.do_case("I0000", "I0002", input_doc, expect) # Can't think of a testcase that would merge multiple families. def test_fam_mother_merge(self): """Merge two persons that are mothers in their respective families.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - persons = input_ctxt.xpath("//g:person", - namespaces={"g": NS_G}) - ET.SubElement(persons[0], NSP + 'parentin', hlink='_f0001') - ET.SubElement(persons[3], NSP + 'parentin', hlink='_f0001') - family = input_ctxt.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'father', hlink='_i0000') - ET.SubElement(family, NSP + 'mother', hlink='_i0003') + persons = input_ctxt.xpath("//g:person", namespaces={"g": NS_G}) + ET.SubElement(persons[0], NSP + "parentin", hlink="_f0001") + ET.SubElement(persons[3], NSP + "parentin", hlink="_f0001") + family = input_ctxt.xpath( + "//g:family[@handle='_f0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "father", hlink="_i0000") + ET.SubElement(family, NSP + "mother", hlink="_i0003") expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[1], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 3' - attr = ET.SubElement(persons[1], NSP + 'attribute', - type='Merged Gramps ID', value='I0003') - parentref = expect.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[1], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 3" + attr = ET.SubElement( + persons[1], NSP + "attribute", type="Merged Gramps ID", value="I0003" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements persons[3].getparent().remove(persons[3]) - notetag = expect.xpath("//g:note[@handle='_n0001']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - notetag = expect.xpath("//g:note[@handle='_n0003']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0001" - family = expect.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] + notetag = expect.xpath( + "//g:note[@handle='_n0001']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Family/handle/f0000" + notetag = expect.xpath( + "//g:note[@handle='_n0003']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Person/handle/i0001" + family = expect.xpath("//g:family[@handle='_f0001']", namespaces={"g": NS_G})[0] family.getparent().remove(family) - parentin = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[1] + parentin = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[1] parentin.getparent().remove(parentin) input_doc = ET.tostring(input_ctxt) - self.do_case('I0001', 'I0003', input_doc, expect) + self.do_case("I0001", "I0003", input_doc, expect) def test_childref_notyet(self): - """Merge two people leading to merger of families that have children. - """ + """Merge two people leading to merger of families that have children.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - parentin = input_ctxt.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + parentin = input_ctxt.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] parentin.getparent().remove(parentin) - mother = input_ctxt.xpath("//g:family[@handle='_f0000']/g:mother", - namespaces={"g": NS_G})[0] + mother = input_ctxt.xpath( + "//g:family[@handle='_f0000']/g:mother", namespaces={"g": NS_G} + )[0] mother.getparent().remove(mother) - persons = input_ctxt.xpath("//g:person", - namespaces={"g": NS_G}) - ET.SubElement(persons[1], NSP + 'childof', hlink='_f0000') - families = input_ctxt.xpath("//g:family", - namespaces={"g": NS_G}) - ET.SubElement(families[0], NSP + 'childref', hlink='_i0001') - parentin = ET.SubElement(persons[2], NSP + 'parentin', hlink='_f0001') - ET.SubElement(families[1], NSP + 'father', hlink='_i0002') - ET.SubElement(persons[3], NSP + 'childof', hlink='_f0001') - ET.SubElement(families[1], NSP + 'childref', hlink='_i0003') + persons = input_ctxt.xpath("//g:person", namespaces={"g": NS_G}) + ET.SubElement(persons[1], NSP + "childof", hlink="_f0000") + families = input_ctxt.xpath("//g:family", namespaces={"g": NS_G}) + ET.SubElement(families[0], NSP + "childref", hlink="_i0001") + parentin = ET.SubElement(persons[2], NSP + "parentin", hlink="_f0001") + ET.SubElement(families[1], NSP + "father", hlink="_i0002") + ET.SubElement(persons[3], NSP + "childof", hlink="_f0001") + ET.SubElement(families[1], NSP + "childref", hlink="_i0003") expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements - notetag = expect.xpath("//g:note[@handle='_n0000']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + notetag = expect.xpath( + "//g:note[@handle='_n0000']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Person/handle/i0000" persons[2].getparent().remove(persons[2]) - notetag = expect.xpath("//g:note[@handle='_n0001']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - families = expect.xpath("//g:family", - namespaces={"g": NS_G}) + notetag = expect.xpath( + "//g:note[@handle='_n0001']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Family/handle/f0000" + families = expect.xpath("//g:family", namespaces={"g": NS_G}) families[1].getparent().remove(families[1]) - childof = expect.xpath("//g:person[@handle='_i0003']/g:childof", - namespaces={"g": NS_G})[0] - childof.attrib['hlink'] = '_f0000' - ET.SubElement(families[0], NSP + 'childref', hlink='_i0003') + childof = expect.xpath( + "//g:person[@handle='_i0003']/g:childof", namespaces={"g": NS_G} + )[0] + childof.attrib["hlink"] = "_f0000" + ET.SubElement(families[0], NSP + "childref", hlink="_i0003") input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0002', input_doc, expect) + self.do_case("I0000", "I0002", input_doc, expect) def test_childref_already(self): input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - parentin = input_ctxt.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + parentin = input_ctxt.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] parentin.getparent().remove(parentin) - mother = input_ctxt.xpath("//g:family[@handle='_f0000']/g:mother", - namespaces={"g": NS_G})[0] + mother = input_ctxt.xpath( + "//g:family[@handle='_f0000']/g:mother", namespaces={"g": NS_G} + )[0] mother.getparent().remove(mother) - persons = input_ctxt.xpath("//g:person", - namespaces={"g": NS_G}) - ET.SubElement(persons[1], NSP + 'childof', hlink='_f0000') - ET.SubElement(persons[1], NSP + 'childof', hlink='_f0001') - families = input_ctxt.xpath("//g:family", - namespaces={"g": NS_G}) - ET.SubElement(families[0], NSP + 'childref', hlink='_i0001') - parentin = ET.SubElement(persons[2], NSP + 'parentin', hlink='_f0001') - ET.SubElement(families[1], NSP + 'father', hlink='_i0002') - ET.SubElement(families[1], NSP + 'childref', hlink='_i0001') + persons = input_ctxt.xpath("//g:person", namespaces={"g": NS_G}) + ET.SubElement(persons[1], NSP + "childof", hlink="_f0000") + ET.SubElement(persons[1], NSP + "childof", hlink="_f0001") + families = input_ctxt.xpath("//g:family", namespaces={"g": NS_G}) + ET.SubElement(families[0], NSP + "childref", hlink="_i0001") + parentin = ET.SubElement(persons[2], NSP + "parentin", hlink="_f0001") + ET.SubElement(families[1], NSP + "father", hlink="_i0002") + ET.SubElement(families[1], NSP + "childref", hlink="_i0001") expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements - notetag = expect.xpath("//g:note[@handle='_n0000']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + notetag = expect.xpath( + "//g:note[@handle='_n0000']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Person/handle/i0000" persons[2].getparent().remove(persons[2]) - notetag = expect.xpath("//g:note[@handle='_n0001']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - families = expect.xpath("//g:family", - namespaces={"g": NS_G}) + notetag = expect.xpath( + "//g:note[@handle='_n0001']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Family/handle/f0000" + families = expect.xpath("//g:family", namespaces={"g": NS_G}) families[1].getparent().remove(families[1]) - childof = expect.xpath("//g:person[@handle='_i0001']/g:childof", - namespaces={"g": NS_G}) + childof = expect.xpath( + "//g:person[@handle='_i0001']/g:childof", namespaces={"g": NS_G} + ) childof[1].getparent().remove(childof[1]) input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0002', input_doc, expect) + self.do_case("I0000", "I0002", input_doc, expect) def test_ldsord(self): input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - parentin = input_ctxt.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + parentin = input_ctxt.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] parentin.getparent().remove(parentin) - mother = input_ctxt.xpath("//g:family[@handle='_f0000']/g:mother", - namespaces={"g": NS_G})[0] + mother = input_ctxt.xpath( + "//g:family[@handle='_f0000']/g:mother", namespaces={"g": NS_G} + )[0] mother.getparent().remove(mother) - persons = input_ctxt.xpath("//g:person", - namespaces={"g": NS_G}) - parentin = ET.SubElement(persons[2], NSP + 'parentin', hlink='_f0001') - family = input_ctxt.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'father', hlink='_i0002') - ldsord = ET.SubElement(persons[3], NSP + 'lds_ord', - type='sealed_to_parents') - ET.SubElement(ldsord, NSP + 'sealed_to', hlink='_f0001') + persons = input_ctxt.xpath("//g:person", namespaces={"g": NS_G}) + parentin = ET.SubElement(persons[2], NSP + "parentin", hlink="_f0001") + family = input_ctxt.xpath( + "//g:family[@handle='_f0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "father", hlink="_i0002") + ldsord = ET.SubElement(persons[3], NSP + "lds_ord", type="sealed_to_parents") + ET.SubElement(ldsord, NSP + "sealed_to", hlink="_f0001") expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', alt='1', - type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements - notetag = expect.xpath("//g:note[@handle='_n0000']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + notetag = expect.xpath( + "//g:note[@handle='_n0000']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Person/handle/i0000" persons[2].getparent().remove(persons[2]) - notetag = expect.xpath("//g:note[@handle='_n0001']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - families = expect.xpath("//g:family", - namespaces={"g": NS_G}) + notetag = expect.xpath( + "//g:note[@handle='_n0001']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Family/handle/f0000" + families = expect.xpath("//g:family", namespaces={"g": NS_G}) families[1].getparent().remove(families[1]) - sealedto = expect.xpath("//g:sealed_to", - namespaces={"g": NS_G})[0] - sealedto.attrib['hlink'] = '_f0000' + sealedto = expect.xpath("//g:sealed_to", namespaces={"g": NS_G})[0] + sealedto.attrib["hlink"] = "_f0000" input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0002', input_doc, expect) + self.do_case("I0000", "I0002", input_doc, expect) # This test fails because the assigment of family ids shifts F0000 to F0001 # and F0001 to F0002! def test_ldsord_cross(self): input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - parentin = input_ctxt.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + parentin = input_ctxt.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] parentin.getparent().remove(parentin) - mother = input_ctxt.xpath("//g:family[@handle='_f0000']/g:mother", - namespaces={"g": NS_G})[0] + mother = input_ctxt.xpath( + "//g:family[@handle='_f0000']/g:mother", namespaces={"g": NS_G} + )[0] mother.getparent().remove(mother) - persons = input_ctxt.xpath("//g:person", - namespaces={"g": NS_G}) - parentin = ET.SubElement(persons[2], NSP + 'parentin', hlink='_f0001') - family = input_ctxt.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'father', hlink='_i0002') - ldsord = ET.SubElement(persons[0], NSP + 'lds_ord', - type='sealed_to_parents') - ET.SubElement(ldsord, NSP + 'sealed_to', hlink='_f0001') + persons = input_ctxt.xpath("//g:person", namespaces={"g": NS_G}) + parentin = ET.SubElement(persons[2], NSP + "parentin", hlink="_f0001") + family = input_ctxt.xpath( + "//g:family[@handle='_f0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "father", hlink="_i0002") + ldsord = ET.SubElement(persons[0], NSP + "lds_ord", type="sealed_to_parents") + ET.SubElement(ldsord, NSP + "sealed_to", hlink="_f0001") expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - ldsord = expect.xpath("//g:lds_ord", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + ldsord = expect.xpath("//g:lds_ord", namespaces={"g": NS_G})[0] altname.addnext(ldsord) # restore order of elements - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements - notetag = expect.xpath("//g:note[@handle='_n0000']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + notetag = expect.xpath( + "//g:note[@handle='_n0000']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Person/handle/i0000" persons[2].getparent().remove(persons[2]) - notetag = expect.xpath("//g:note[@handle='_n0001']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - families = expect.xpath("//g:family", - namespaces={"g": NS_G}) + notetag = expect.xpath( + "//g:note[@handle='_n0001']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Family/handle/f0000" + families = expect.xpath("//g:family", namespaces={"g": NS_G}) families[1].getparent().remove(families[1]) - sealedto = expect.xpath("//g:sealed_to", - namespaces={"g": NS_G})[0] - sealedto.attrib['hlink'] = '_f0000' + sealedto = expect.xpath("//g:sealed_to", namespaces={"g": NS_G})[0] + sealedto.attrib["hlink"] = "_f0000" input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0002', input_doc, expect) + self.do_case("I0000", "I0002", input_doc, expect) def test_ldsord_self(self): input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - parentin = input_ctxt.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + parentin = input_ctxt.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] parentin.getparent().remove(parentin) - mother = input_ctxt.xpath("//g:family[@handle='_f0000']/g:mother", - namespaces={"g": NS_G})[0] + mother = input_ctxt.xpath( + "//g:family[@handle='_f0000']/g:mother", namespaces={"g": NS_G} + )[0] mother.getparent().remove(mother) - persons = input_ctxt.xpath("//g:person", - namespaces={"g": NS_G}) - parentin = ET.SubElement(persons[2], NSP + 'parentin', hlink='_f0001') - family = input_ctxt.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'father', hlink='_i0002') - ldsord = ET.SubElement(persons[2], NSP + 'lds_ord', - type='sealed_to_parents') - ET.SubElement(ldsord, NSP + 'sealed_to', hlink='_f0001') + persons = input_ctxt.xpath("//g:person", namespaces={"g": NS_G}) + parentin = ET.SubElement(persons[2], NSP + "parentin", hlink="_f0001") + family = input_ctxt.xpath( + "//g:family[@handle='_f0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "father", hlink="_i0002") + ldsord = ET.SubElement(persons[2], NSP + "lds_ord", type="sealed_to_parents") + ET.SubElement(ldsord, NSP + "sealed_to", hlink="_f0001") expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - ldsord = expect.xpath("//g:lds_ord", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + ldsord = expect.xpath("//g:lds_ord", namespaces={"g": NS_G})[0] altname.addnext(ldsord) # restore order of elements - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements - notetag = expect.xpath("//g:note[@handle='_n0000']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Person/handle/i0000" + notetag = expect.xpath( + "//g:note[@handle='_n0000']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Person/handle/i0000" persons[2].getparent().remove(persons[2]) - notetag = expect.xpath("//g:note[@handle='_n0001']/g:style", - namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - families = expect.xpath("//g:family", - namespaces={"g": NS_G}) + notetag = expect.xpath( + "//g:note[@handle='_n0001']/g:style", namespaces={"g": NS_G} + )[0] + notetag.attrib["value"] = "gramps://Family/handle/f0000" + families = expect.xpath("//g:family", namespaces={"g": NS_G}) families[1].getparent().remove(families[1]) - sealedto = expect.xpath("//g:sealed_to", - namespaces={"g": NS_G})[0] - sealedto.attrib['hlink'] = '_f0000' + sealedto = expect.xpath("//g:sealed_to", namespaces={"g": NS_G})[0] + sealedto.attrib["hlink"] = "_f0000" input_doc = ET.tostring(input_ctxt) - self.do_case('I0000', 'I0002', input_doc, expect) + self.do_case("I0000", "I0002", input_doc, expect) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # FamilyMergeCheck class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class FamilyMergeCheck(BaseMergeCheck): def setUp(self): self.base_setup() @@ -2023,370 +2125,397 @@ def setUp(self): """ - self.basedoc = bytes(bytearray(self.base_str + base_str, - encoding='utf-8')) + self.basedoc = bytes(bytearray(self.base_str + base_str, encoding="utf-8")) def test_father_son_merge(self): """Merge two families where the fathers have a father-son relationship so that an error is raised.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - person = input_ctxt.xpath("//g:person[@handle='_i0002']", - namespaces={"g": NS_G})[0] - ET.SubElement(person, NSP + 'childof', hlink='_f0000') - family = input_ctxt.xpath("//g:family[@handle='_f0000']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'childref', hlink='_i0002') + person = input_ctxt.xpath( + "//g:person[@handle='_i0002']", namespaces={"g": NS_G} + )[0] + ET.SubElement(person, NSP + "childof", hlink="_f0000") + family = input_ctxt.xpath( + "//g:family[@handle='_f0000']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "childref", hlink="_i0002") input_doc = expect = ET.tostring(input_ctxt) self.do_family_case( - 'F0000', 'F0001', 'i0000', 'i0001', input_doc, expect, - test_error_str=_("A parent and child cannot be merged. To merge " - "these people, you must first break the " - "relationship between them.")) + "F0000", + "F0001", + "i0000", + "i0001", + input_doc, + expect, + test_error_str=_( + "A parent and child cannot be merged. To merge " + "these people, you must first break the " + "relationship between them." + ), + ) def test_child_parent_merge_no_father(self): """Merge two families where the phoenix family has no father and the father of the titanic family is a child of the phoenix family. """ input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - parentin = input_ctxt.xpath("//g:person[@handle='_i0002']/g:parentin", - namespaces={"g": NS_G})[0] + parentin = input_ctxt.xpath( + "//g:person[@handle='_i0002']/g:parentin", namespaces={"g": NS_G} + )[0] parentin.getparent().remove(parentin) - father = input_ctxt.xpath("//g:family[@handle='_f0001']/g:father", - namespaces={"g": NS_G})[0] + father = input_ctxt.xpath( + "//g:family[@handle='_f0001']/g:father", namespaces={"g": NS_G} + )[0] father.getparent().remove(father) - person = input_ctxt.xpath("//g:person[@handle='_i0000']", - namespaces={"g": NS_G})[0] - ET.SubElement(person, NSP + 'childof', hlink='_f0001') - family = input_ctxt.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'childref', hlink='_i0000') + person = input_ctxt.xpath( + "//g:person[@handle='_i0000']", namespaces={"g": NS_G} + )[0] + ET.SubElement(person, NSP + "childof", hlink="_f0001") + family = input_ctxt.xpath( + "//g:family[@handle='_f0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "childref", hlink="_i0000") input_doc = expect = ET.tostring(input_ctxt) self.do_family_case( - 'F0000', 'F0001', 'i0000', 'i0001', input_doc, expect, - test_error_str=_("A parent and child cannot be merged. To merge " - "these people, you must first break the " - "relationship between them.")) + "F0000", + "F0001", + "i0000", + "i0001", + input_doc, + expect, + test_error_str=_( + "A parent and child cannot be merged. To merge " + "these people, you must first break the " + "relationship between them." + ), + ) def test_child_parent_merge_no_father_swapped(self): """Merge two families where the phoenix family has no father and the father of the titanic family, which is the phoenix-father, is a child of the phoenix family.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - parentin = input_ctxt.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + parentin = input_ctxt.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] parentin.getparent().remove(parentin) - father = input_ctxt.xpath("//g:family[@handle='_f0000']/g:father", - namespaces={"g": NS_G})[0] + father = input_ctxt.xpath( + "//g:family[@handle='_f0000']/g:father", namespaces={"g": NS_G} + )[0] father.getparent().remove(father) - person = input_ctxt.xpath("//g:person[@handle='_i0002']", - namespaces={"g": NS_G})[0] - ET.SubElement(person, NSP + 'childof', hlink='_f0000') - family = input_ctxt.xpath("//g:family[@handle='_f0000']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'childref', hlink='_i0002') + person = input_ctxt.xpath( + "//g:person[@handle='_i0002']", namespaces={"g": NS_G} + )[0] + ET.SubElement(person, NSP + "childof", hlink="_f0000") + family = input_ctxt.xpath( + "//g:family[@handle='_f0000']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "childref", hlink="_i0002") input_doc = expect = ET.tostring(input_ctxt) self.do_family_case( - 'F0000', 'F0001', 'i0002', 'i0001', input_doc, expect, - test_error_str=_("A parent and child cannot be merged. To merge " - "these people, you must first break the " - "relationship between them.")) + "F0000", + "F0001", + "i0002", + "i0001", + input_doc, + expect, + test_error_str=_( + "A parent and child cannot be merged. To merge " + "these people, you must first break the " + "relationship between them." + ), + ) def test_regular_merge(self): """Merge two families succesfully""" expect = ET.fromstring(self.basedoc, parser=self.parser) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] - attr.addnext(parentref) # restore order of elements + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] + attr.addnext(parentref) # restore order of elements persons[2].getparent().remove(persons[2]) - altname = ET.SubElement(persons[1], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 3' - attr = ET.SubElement(persons[1], NSP + 'attribute', - type='Merged Gramps ID', value='I0003') - parentref = expect.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + altname = ET.SubElement(persons[1], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 3" + attr = ET.SubElement( + persons[1], NSP + "attribute", type="Merged Gramps ID", value="I0003" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements persons[3].getparent().remove(persons[3]) - family = expect.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] + family = expect.xpath("//g:family[@handle='_f0001']", namespaces={"g": NS_G})[0] family.getparent().remove(family) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - self.do_family_case('F0000', 'F0001', 'i0000', 'i0001', - self.basedoc, expect) + notetag.attrib["value"] = "gramps://Family/handle/f0000" + self.do_family_case("F0000", "F0001", "i0000", "i0001", self.basedoc, expect) def test_father_swapped(self): "Merge two families where the phoenix-father is of the titanic family." expect = ET.fromstring(self.basedoc, parser=self.parser) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[2], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 0' - attr = ET.SubElement(persons[2], NSP + 'attribute', - type='Merged Gramps ID', value='I0000') - parentref = expect.xpath("//g:person[@handle='_i0002']/g:parentin", - namespaces={"g": NS_G})[0] - parentref.attrib['hlink'] = '_f0000' + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[2], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 0" + attr = ET.SubElement( + persons[2], NSP + "attribute", type="Merged Gramps ID", value="I0000" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0002']/g:parentin", namespaces={"g": NS_G} + )[0] + parentref.attrib["hlink"] = "_f0000" attr.addnext(parentref) # restore order of elements persons[0].getparent().remove(persons[0]) - altname = ET.SubElement(persons[1], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 3' - attr = ET.SubElement(persons[1], NSP + 'attribute', - type='Merged Gramps ID', value='I0003') - parentref = expect.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + altname = ET.SubElement(persons[1], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 3" + attr = ET.SubElement( + persons[1], NSP + "attribute", type="Merged Gramps ID", value="I0003" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements persons[3].getparent().remove(persons[3]) - family = expect.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] + family = expect.xpath("//g:family[@handle='_f0001']", namespaces={"g": NS_G})[0] family.getparent().remove(family) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - father = expect.xpath("//g:family[@handle='_f0000']/g:father", - namespaces={"g": NS_G})[0] - father.attrib['hlink'] = '_i0002' - self.do_family_case('F0000', 'F0001', 'i0002', 'i0001', - self.basedoc, expect) + notetag.attrib["value"] = "gramps://Family/handle/f0000" + father = expect.xpath( + "//g:family[@handle='_f0000']/g:father", namespaces={"g": NS_G} + )[0] + father.attrib["hlink"] = "_i0002" + self.do_family_case("F0000", "F0001", "i0002", "i0001", self.basedoc, expect) - #def test_mother_swapped(self): + # def test_mother_swapped(self): def test_no_father(self): """Merge two families, where one family has not father""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - parentin = input_ctxt.xpath("//g:person[@handle='_i0002']/g:parentin", - namespaces={"g": NS_G})[0] + parentin = input_ctxt.xpath( + "//g:person[@handle='_i0002']/g:parentin", namespaces={"g": NS_G} + )[0] parentin.getparent().remove(parentin) - father = input_ctxt.xpath("//g:family[@handle='_f0001']/g:father", - namespaces={"g": NS_G})[0] + father = input_ctxt.xpath( + "//g:family[@handle='_f0001']/g:father", namespaces={"g": NS_G} + )[0] father.getparent().remove(father) expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[1], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 3' - attr = ET.SubElement(persons[1], NSP + 'attribute', - type='Merged Gramps ID', value='I0003') - parentref = expect.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[1], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 3" + attr = ET.SubElement( + persons[1], NSP + "attribute", type="Merged Gramps ID", value="I0003" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements persons[3].getparent().remove(persons[3]) - family = expect.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] + family = expect.xpath("//g:family[@handle='_f0001']", namespaces={"g": NS_G})[0] family.getparent().remove(family) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" + notetag.attrib["value"] = "gramps://Family/handle/f0000" input_doc = ET.tostring(input_ctxt) - self.do_family_case('F0000', 'F0001', 'i0000', 'i0001', - input_doc, expect) + self.do_family_case("F0000", "F0001", "i0000", "i0001", input_doc, expect) def test_no_mother_swapped(self): """Merge two families where one family has no mother and the phoenix-mother is from the titanic family.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - parentin = input_ctxt.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + parentin = input_ctxt.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] parentin.getparent().remove(parentin) - mother = input_ctxt.xpath("//g:family[@handle='_f0000']/g:mother", - namespaces={"g": NS_G})[0] + mother = input_ctxt.xpath( + "//g:family[@handle='_f0000']/g:mother", namespaces={"g": NS_G} + )[0] mother.getparent().remove(mother) expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements persons[2].getparent().remove(persons[2]) - parentin = expect.xpath("//g:person[@handle='_i0003']/g:parentin", - namespaces={"g": NS_G})[0] - parentin.attrib['hlink'] = '_f0000' - family = expect.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] + parentin = expect.xpath( + "//g:person[@handle='_i0003']/g:parentin", namespaces={"g": NS_G} + )[0] + parentin.attrib["hlink"] = "_f0000" + family = expect.xpath("//g:family[@handle='_f0001']", namespaces={"g": NS_G})[0] family.getparent().remove(family) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - family = expect.xpath("//g:family[@handle='_f0000']", - namespaces={"g": NS_G})[0] - mother = ET.SubElement(family, NSP + 'mother', hlink='_i0003') + notetag.attrib["value"] = "gramps://Family/handle/f0000" + family = expect.xpath("//g:family[@handle='_f0000']", namespaces={"g": NS_G})[0] + mother = ET.SubElement(family, NSP + "mother", hlink="_i0003") input_doc = ET.tostring(input_ctxt) - self.do_family_case('F0000', 'F0001', 'i0000', 'i0003', - input_doc, expect) + self.do_family_case("F0000", "F0001", "i0000", "i0003", input_doc, expect) - #def test_no_parents(self): + # def test_no_parents(self): def test_childref_notyet(self): """Merge two families with non-duplicate child references.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - people = input_ctxt.xpath("//g:people", - namespaces={"g": NS_G})[0] - person = ET.SubElement(people, NSP + 'person', - handle='_i0004', id='_I0004') - ET.SubElement(person, NSP + 'gender').text = 'M' - name = ET.SubElement(person, NSP + 'name', type='Birth Name') - ET.SubElement(name, NSP + 'surname').text = 'Person 4' - ET.SubElement(person, NSP + 'childof', hlink='_f0001') - family = input_ctxt.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'childref', hlink='_i0004') + people = input_ctxt.xpath("//g:people", namespaces={"g": NS_G})[0] + person = ET.SubElement(people, NSP + "person", handle="_i0004", id="_I0004") + ET.SubElement(person, NSP + "gender").text = "M" + name = ET.SubElement(person, NSP + "name", type="Birth Name") + ET.SubElement(name, NSP + "surname").text = "Person 4" + ET.SubElement(person, NSP + "childof", hlink="_f0001") + family = input_ctxt.xpath( + "//g:family[@handle='_f0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "childref", hlink="_i0004") expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements persons[2].getparent().remove(persons[2]) - altname = ET.SubElement(persons[1], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 3' - attr = ET.SubElement(persons[1], NSP + 'attribute', - type='Merged Gramps ID', value='I0003') - parentref = expect.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + altname = ET.SubElement(persons[1], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 3" + attr = ET.SubElement( + persons[1], NSP + "attribute", type="Merged Gramps ID", value="I0003" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements persons[3].getparent().remove(persons[3]) - family = expect.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] + family = expect.xpath("//g:family[@handle='_f0001']", namespaces={"g": NS_G})[0] family.getparent().remove(family) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - childof = expect.xpath("//g:person[@handle='_i0004']/g:childof", - namespaces={"g": NS_G})[0] - childof.attrib['hlink'] = '_f0000' - family = expect.xpath("//g:family[@handle='_f0000']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'childref', hlink='_i0004') + notetag.attrib["value"] = "gramps://Family/handle/f0000" + childof = expect.xpath( + "//g:person[@handle='_i0004']/g:childof", namespaces={"g": NS_G} + )[0] + childof.attrib["hlink"] = "_f0000" + family = expect.xpath("//g:family[@handle='_f0000']", namespaces={"g": NS_G})[0] + ET.SubElement(family, NSP + "childref", hlink="_i0004") input_doc = ET.tostring(input_ctxt) - self.do_family_case('F0000', 'F0001', 'i0000', 'i0001', - input_doc, expect) + self.do_family_case("F0000", "F0001", "i0000", "i0001", input_doc, expect) def test_childref_already(self): """Merge two families with duplicate child references.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - people = input_ctxt.xpath("//g:people", - namespaces={"g": NS_G})[0] - person = ET.SubElement(people, NSP + 'person', - handle='_i0004', id='_I0004') - ET.SubElement(person, NSP + 'gender').text = 'M' - name = ET.SubElement(person, NSP + 'name', type='Birth Name') - ET.SubElement(name, NSP + 'surname').text = 'Person 4' - ET.SubElement(person, NSP + 'childof', hlink='_f0000') - ET.SubElement(person, NSP + 'childof', hlink='_f0001') - family = input_ctxt.xpath("//g:family[@handle='_f0000']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'childref', hlink='_i0004') - family = input_ctxt.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] - ET.SubElement(family, NSP + 'childref', hlink='_i0004') + people = input_ctxt.xpath("//g:people", namespaces={"g": NS_G})[0] + person = ET.SubElement(people, NSP + "person", handle="_i0004", id="_I0004") + ET.SubElement(person, NSP + "gender").text = "M" + name = ET.SubElement(person, NSP + "name", type="Birth Name") + ET.SubElement(name, NSP + "surname").text = "Person 4" + ET.SubElement(person, NSP + "childof", hlink="_f0000") + ET.SubElement(person, NSP + "childof", hlink="_f0001") + family = input_ctxt.xpath( + "//g:family[@handle='_f0000']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "childref", hlink="_i0004") + family = input_ctxt.xpath( + "//g:family[@handle='_f0001']", namespaces={"g": NS_G} + )[0] + ET.SubElement(family, NSP + "childref", hlink="_i0004") expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements persons[2].getparent().remove(persons[2]) - altname = ET.SubElement(persons[1], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 3' - attr = ET.SubElement(persons[1], NSP + 'attribute', - type='Merged Gramps ID', value='I0003') - parentref = expect.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + altname = ET.SubElement(persons[1], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 3" + attr = ET.SubElement( + persons[1], NSP + "attribute", type="Merged Gramps ID", value="I0003" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements persons[3].getparent().remove(persons[3]) - family = expect.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] + family = expect.xpath("//g:family[@handle='_f0001']", namespaces={"g": NS_G})[0] family.getparent().remove(family) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - childof = expect.xpath("//g:person[@handle='_i0004']/g:childof", - namespaces={"g": NS_G})[1] + notetag.attrib["value"] = "gramps://Family/handle/f0000" + childof = expect.xpath( + "//g:person[@handle='_i0004']/g:childof", namespaces={"g": NS_G} + )[1] childof.getparent().remove(childof) input_doc = ET.tostring(input_ctxt) - self.do_family_case('F0000', 'F0001', 'i0000', 'i0001', - input_doc, expect) + self.do_family_case("F0000", "F0001", "i0000", "i0001", input_doc, expect) # this test fails because the families get IDs F0001 and F0002! def test_ldsord(self): """Merge two families where one person has a reference to the titanic family.""" input_ctxt = ET.fromstring(self.basedoc, parser=self.parser) - person = input_ctxt.xpath("//g:person[@handle='_i0000']", - namespaces={"g": NS_G})[0] - ldsord = ET.SubElement(person, NSP + 'lds_ord', - type='sealed_to_parents') - ET.SubElement(ldsord, NSP + 'sealed_to', hlink='_f0001') - parentin = input_ctxt.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + person = input_ctxt.xpath( + "//g:person[@handle='_i0000']", namespaces={"g": NS_G} + )[0] + ldsord = ET.SubElement(person, NSP + "lds_ord", type="sealed_to_parents") + ET.SubElement(ldsord, NSP + "sealed_to", hlink="_f0001") + parentin = input_ctxt.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] ldsord.addnext(parentin) expect = copy.deepcopy(input_ctxt) - persons = expect.xpath("//g:person", - namespaces={"g": NS_G}) - altname = ET.SubElement(persons[0], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 2' - ldsord = expect.xpath("//g:lds_ord", - namespaces={"g": NS_G})[0] + persons = expect.xpath("//g:person", namespaces={"g": NS_G}) + altname = ET.SubElement(persons[0], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 2" + ldsord = expect.xpath("//g:lds_ord", namespaces={"g": NS_G})[0] altname.addnext(ldsord) # restore order of elements - attr = ET.SubElement(persons[0], NSP + 'attribute', - type='Merged Gramps ID', value='I0002') - parentref = expect.xpath("//g:person[@handle='_i0000']/g:parentin", - namespaces={"g": NS_G})[0] + attr = ET.SubElement( + persons[0], NSP + "attribute", type="Merged Gramps ID", value="I0002" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0000']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements persons[2].getparent().remove(persons[2]) - altname = ET.SubElement(persons[1], NSP + 'name', - alt='1', type='Birth Name') - ET.SubElement(altname, NSP + 'surname').text = 'Person 3' - attr = ET.SubElement(persons[1], NSP + 'attribute', - type='Merged Gramps ID', value='I0003') - parentref = expect.xpath("//g:person[@handle='_i0001']/g:parentin", - namespaces={"g": NS_G})[0] + altname = ET.SubElement(persons[1], NSP + "name", alt="1", type="Birth Name") + ET.SubElement(altname, NSP + "surname").text = "Person 3" + attr = ET.SubElement( + persons[1], NSP + "attribute", type="Merged Gramps ID", value="I0003" + ) + parentref = expect.xpath( + "//g:person[@handle='_i0001']/g:parentin", namespaces={"g": NS_G} + )[0] attr.addnext(parentref) # restore order of elements persons[3].getparent().remove(persons[3]) - family = expect.xpath("//g:family[@handle='_f0001']", - namespaces={"g": NS_G})[0] + family = expect.xpath("//g:family[@handle='_f0001']", namespaces={"g": NS_G})[0] family.getparent().remove(family) notetag = expect.xpath("//g:style", namespaces={"g": NS_G})[0] - notetag.attrib['value'] = "gramps://Family/handle/f0000" - sealedto = expect.xpath("//g:sealed_to", - namespaces={"g": NS_G})[0] - sealedto.attrib['hlink'] = '_f0000' + notetag.attrib["value"] = "gramps://Family/handle/f0000" + sealedto = expect.xpath("//g:sealed_to", namespaces={"g": NS_G})[0] + sealedto.attrib["hlink"] = "_f0000" input_doc = ET.tostring(input_ctxt) - self.do_family_case('F0000', 'F0001', 'i0000', 'i0001', - input_doc, expect) + self.do_family_case("F0000", "F0001", "i0000", "i0001", input_doc, expect) if __name__ == "__main__": import sys + if not HAS_CLIMERGE: - print('This program needs the third party "CliMerge" plugin.', - file=sys.stderr) + print('This program needs the third party "CliMerge" plugin.', file=sys.stderr) sys.exit(1) if not HAS_EXPORTRAW: - print('This program needs the third party "ExportRaw" plugin.', - file=sys.stderr) + print('This program needs the third party "ExportRaw" plugin.', file=sys.stderr) sys.exit(1) unittest.main() diff --git a/gramps/gen/mime/__init__.py b/gramps/gen/mime/__init__.py index ff817ca4667..2b12f1c6ffc 100644 --- a/gramps/gen/mime/__init__.py +++ b/gramps/gen/mime/__init__.py @@ -24,16 +24,21 @@ except: from ._pythonmime import get_description, get_type, mime_type_is_defined + def base_type(val): - return val.split('/')[0] + return val.split("/")[0] + def is_image_type(val): return base_type(val) == "image" + def is_directory(val): return base_type(val) == "x-directory" -_invalid_mime_types = ('x-directory','x-special') + +_invalid_mime_types = ("x-directory", "x-special") + def is_valid_type(val): return base_type(val) not in _invalid_mime_types diff --git a/gramps/gen/mime/_pythonmime.py b/gramps/gen/mime/_pythonmime.py index 979f3b86ccd..e4575569540 100644 --- a/gramps/gen/mime/_pythonmime.py +++ b/gramps/gen/mime/_pythonmime.py @@ -21,33 +21,36 @@ import mimetypes from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext _type_map = { - 'application/x-gramps' : 'Gramps database', - 'application/x-gramps-xml' : 'Gramps XML database', - 'application/x-gedcom' : 'GEDCOM database', - 'application/x-gramps-package': 'Gramps package', - 'image/jpeg' : 'JPEG image', - 'image/tiff' : 'TIFF image', - 'image/png' : 'PNG image', - 'application/pdf' : 'PDF document', - 'text/rtf' : 'Rich Text File', + "application/x-gramps": "Gramps database", + "application/x-gramps-xml": "Gramps XML database", + "application/x-gedcom": "GEDCOM database", + "application/x-gramps-package": "Gramps package", + "image/jpeg": "JPEG image", + "image/tiff": "TIFF image", + "image/png": "PNG image", + "application/pdf": "PDF document", + "text/rtf": "Rich Text File", } -mimetypes.add_type('application/x-gramps','.grdb') -mimetypes.add_type('application/x-gramps','.GRDB') -mimetypes.add_type('application/x-gramps-xml','.gramps') -mimetypes.add_type('application/x-gramps-xml','.Gramps') -mimetypes.add_type('application/x-gedcom','.ged') -mimetypes.add_type('application/x-gedcom','.GED') -mimetypes.add_type('application/x-gramps-package','.gpkg') -mimetypes.add_type('application/x-gramps-package','.GPKG') -mimetypes.add_type('text/x-comma-separated-values', '.csv') +mimetypes.add_type("application/x-gramps", ".grdb") +mimetypes.add_type("application/x-gramps", ".GRDB") +mimetypes.add_type("application/x-gramps-xml", ".gramps") +mimetypes.add_type("application/x-gramps-xml", ".Gramps") +mimetypes.add_type("application/x-gedcom", ".ged") +mimetypes.add_type("application/x-gedcom", ".GED") +mimetypes.add_type("application/x-gramps-package", ".gpkg") +mimetypes.add_type("application/x-gramps-package", ".GPKG") +mimetypes.add_type("text/x-comma-separated-values", ".csv") + def get_description(mime_type): """Return the description of the specified mime type""" - return _type_map.get(mime_type,_("unknown")) + return _type_map.get(mime_type, _("unknown")) + def get_type(filename): """Return the mime type of the specified file""" @@ -55,7 +58,8 @@ def get_type(filename): if value and value[0]: return value[0] else: - return _('unknown') + return _("unknown") + def mime_type_is_defined(mime_type): """ diff --git a/gramps/gen/mime/_winmime.py b/gramps/gen/mime/_winmime.py index 899247e56df..2cdda9af021 100644 --- a/gramps/gen/mime/_winmime.py +++ b/gramps/gen/mime/_winmime.py @@ -22,23 +22,25 @@ Mime utility functions for the MS Windows platform """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import os from winreg import * -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import _pythonmime from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext + def get_description(mime_type): """Return the description of the specfied mime type""" desc = None @@ -58,10 +60,12 @@ def get_description(mime_type): return desc + def get_type(file): """Return the mime type of the specified file""" return _pythonmime.get_type(file) + def mime_type_is_defined(mime_type): """ Return True if a description for a mime type exists. @@ -72,11 +76,12 @@ def mime_type_is_defined(mime_type): else: return _pythonmime.mime_type_is_defined(mime_type) -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # private functions # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- def _get_extension(mime_type): """ Return the extension associated with this mime type @@ -97,14 +102,15 @@ def _get_extension(mime_type): if not extension: # Work around for Windows mime problems extmap = { - 'application/abiword' : '.abw', - 'application/rtf' : '.rtf', - } + "application/abiword": ".abw", + "application/rtf": ".rtf", + } if mime_type in extmap: extension = extmap[mime_type] return extension + def _get_prog_id(extension): """ Return the program ID associated with this extension @@ -120,4 +126,3 @@ def _get_prog_id(extension): return progid except WindowsError: return None - diff --git a/gramps/gen/plug/__init__.py b/gramps/gen/plug/__init__.py index 667fa447d1a..82a73da8964 100644 --- a/gramps/gen/plug/__init__.py +++ b/gramps/gen/plug/__init__.py @@ -25,17 +25,43 @@ """ from ._plugin import Plugin -from ._pluginreg import (PluginData, PluginRegister, REPORT, TOOL, - CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE, - CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ, CATEGORY_TREE, - TOOL_DEBUG, TOOL_ANAL, TOOL_DBPROC, TOOL_DBFIX, TOOL_REVCTL, - TOOL_UTILS, CATEGORY_QR_MISC, CATEGORY_QR_PERSON, - CATEGORY_QR_FAMILY, CATEGORY_QR_EVENT, CATEGORY_QR_SOURCE, - CATEGORY_QR_PLACE, CATEGORY_QR_REPOSITORY, CATEGORY_QR_NOTE, - CATEGORY_QR_DATE, PTYPE_STR, CATEGORY_QR_MEDIA, - CATEGORY_QR_CITATION, CATEGORY_QR_SOURCE_OR_CITATION, - START, END, make_environment, AUDIENCETEXT, STATUSTEXT, - ) +from ._pluginreg import ( + PluginData, + PluginRegister, + REPORT, + TOOL, + CATEGORY_TEXT, + CATEGORY_DRAW, + CATEGORY_CODE, + CATEGORY_WEB, + CATEGORY_BOOK, + CATEGORY_GRAPHVIZ, + CATEGORY_TREE, + TOOL_DEBUG, + TOOL_ANAL, + TOOL_DBPROC, + TOOL_DBFIX, + TOOL_REVCTL, + TOOL_UTILS, + CATEGORY_QR_MISC, + CATEGORY_QR_PERSON, + CATEGORY_QR_FAMILY, + CATEGORY_QR_EVENT, + CATEGORY_QR_SOURCE, + CATEGORY_QR_PLACE, + CATEGORY_QR_REPOSITORY, + CATEGORY_QR_NOTE, + CATEGORY_QR_DATE, + PTYPE_STR, + CATEGORY_QR_MEDIA, + CATEGORY_QR_CITATION, + CATEGORY_QR_SOURCE_OR_CITATION, + START, + END, + make_environment, + AUDIENCETEXT, + STATUSTEXT, +) from ._import import ImportPlugin from ._export import ExportPlugin from ._docgenplugin import DocGenPlugin @@ -43,18 +69,54 @@ from ._gramplet import Gramplet from ._thumbnailer import Thumbnailer from .utils import * -from ._options import (Options, OptionListCollection, OptionList, - OptionHandler, MenuOptions) +from ._options import ( + Options, + OptionListCollection, + OptionList, + OptionHandler, + MenuOptions, +) -__all__ = [ "docbackend", "docgen", "menu", "Plugin", "PluginData", - "PluginRegister", "BasePluginManager", "ImportPlugin", - "ExportPlugin", "DocGenPlugin", "REPORT", "TOOL", "CATEGORY_TEXT", - "CATEGORY_DRAW", "CATEGORY_CODE", "CATEGORY_WEB", "CATEGORY_BOOK", - "CATEGORY_GRAPHVIZ", "CATEGORY_TREE", "TOOL_DEBUG", "TOOL_ANAL", - "TOOL_DBPROC", "TOOL_DBFIX", "TOOL_REVCTL","TOOL_UTILS", - "CATEGORY_QR_MISC", "CATEGORY_QR_PERSON", "CATEGORY_QR_FAMILY", - "CATEGORY_QR_EVENT", "CATEGORY_QR_SOURCE", "CATEGORY_QR_PLACE", - "CATEGORY_QR_REPOSITORY", "CATEGORY_QR_NOTE", "CATEGORY_QR_DATE", - "PTYPE_STR", "CATEGORY_QR_MEDIA", "CATEGORY_QR_CITATION", - "CATEGORY_QR_SOURCE_OR_CITATION", "START", "END", - "make_environment"] +__all__ = [ + "docbackend", + "docgen", + "menu", + "Plugin", + "PluginData", + "PluginRegister", + "BasePluginManager", + "ImportPlugin", + "ExportPlugin", + "DocGenPlugin", + "REPORT", + "TOOL", + "CATEGORY_TEXT", + "CATEGORY_DRAW", + "CATEGORY_CODE", + "CATEGORY_WEB", + "CATEGORY_BOOK", + "CATEGORY_GRAPHVIZ", + "CATEGORY_TREE", + "TOOL_DEBUG", + "TOOL_ANAL", + "TOOL_DBPROC", + "TOOL_DBFIX", + "TOOL_REVCTL", + "TOOL_UTILS", + "CATEGORY_QR_MISC", + "CATEGORY_QR_PERSON", + "CATEGORY_QR_FAMILY", + "CATEGORY_QR_EVENT", + "CATEGORY_QR_SOURCE", + "CATEGORY_QR_PLACE", + "CATEGORY_QR_REPOSITORY", + "CATEGORY_QR_NOTE", + "CATEGORY_QR_DATE", + "PTYPE_STR", + "CATEGORY_QR_MEDIA", + "CATEGORY_QR_CITATION", + "CATEGORY_QR_SOURCE_OR_CITATION", + "START", + "END", + "make_environment", +] diff --git a/gramps/gen/plug/_docgenplugin.py b/gramps/gen/plug/_docgenplugin.py index 0b8bad334cb..5c9b8f9cffd 100644 --- a/gramps/gen/plug/_docgenplugin.py +++ b/gramps/gen/plug/_docgenplugin.py @@ -26,12 +26,23 @@ from . import Plugin from .docgen import TextDoc, DrawDoc + class DocGenPlugin(Plugin): """ This class represents a plugin for generating documents from Gramps """ - def __init__(self, name, description, basedoc, - paper, style, extension, docoptclass, basedocname): + + def __init__( + self, + name, + description, + basedoc, + paper, + style, + extension, + docoptclass, + basedocname, + ): """ :param name: A friendly name to call this plugin. Example: "Plain Text" diff --git a/gramps/gen/plug/_export.py b/gramps/gen/plug/_export.py index 922b4a597e8..3b9c716227b 100644 --- a/gramps/gen/plug/_export.py +++ b/gramps/gen/plug/_export.py @@ -24,12 +24,13 @@ from . import Plugin + class ExportPlugin(Plugin): """ This class represents a plugin for exporting data from Gramps """ - def __init__(self, name, description, export_function, - extension, config=None): + + def __init__(self, name, description, export_function, extension, config=None): """ :param name: A friendly name to call this plugin. Example: "GEDCOM Export" diff --git a/gramps/gen/plug/_gramplet.py b/gramps/gen/plug/_gramplet.py index 5aab65d80fc..884e0a0fac8 100644 --- a/gramps/gen/plug/_gramplet.py +++ b/gramps/gen/plug/_gramplet.py @@ -19,22 +19,24 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import types import logging + LOG = logging.getLogger(".Gramplets") -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Gramps modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ from ...gui.dbguielement import DbGUIElement from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext @@ -42,6 +44,7 @@ class Gramplet: """ Base class for non-graphical gramplet code. """ + def __init__(self, gui, nav_group=0): """ Internal constructor for non-graphical gramplets. @@ -58,8 +61,8 @@ def __init__(self, gui, nav_group=0): self._signal = {} self.option_order = [] # links to each other: - self.gui = gui # plugin gramplet has link to gui - gui.pui = self # gui has link to plugin ui + self.gui = gui # plugin gramplet has link to gui + gui.pui = self # gui has link to plugin ui self.nav_group = nav_group self.dbstate = gui.dbstate self.uistate = gui.uistate @@ -68,13 +71,11 @@ def __init__(self, gui, nav_group=0): self.build_options() self.dbstate.connect("database-changed", self._db_changed) self.dbstate.connect("no-database", self._no_db) - self.gui.textview.connect("button-press-event", - self.gui.on_button_press) - self.gui.textview.connect("motion-notify-event", - self.gui.on_motion) + self.gui.textview.connect("button-press-event", self.gui.on_button_press) + self.gui.textview.connect("motion-notify-event", self.gui.on_motion) self._db_changed(self.dbstate.db) - active_person = self.get_active('Person') - if active_person: # already changed + active_person = self.get_active("Person") + if active_person: # already changed self._active_changed(active_person) self.post_init() @@ -88,7 +89,7 @@ def connect_signal(self, nav_type, method): # print('History: nave-type = %s' % nav_type) self.connect(history, "active-changed", method) - def init(self): # once, constructor + def init(self): # once, constructor """ External constructor for developers to put their initialization code. Designed to be overridden. @@ -105,7 +106,7 @@ def build_options(self): """ pass - def main(self): # return false finishes + def main(self): # return false finishes """ The main place for the gramplet's code. This is a generator. Generator which will be run in the background, through :meth:`update`. @@ -137,8 +138,7 @@ def get_active_object(self, nav_type): Return the object of the active handle for the given navigation type. """ handle = self.uistate.get_active(nav_type, self.nav_group) - handle_func = getattr(self.dbstate.db, - 'get_%s_from_handle' % nav_type.lower()) + handle_func = getattr(self.dbstate.db, "get_%s_from_handle" % nav_type.lower()) if handle: return handle_func(handle) return None @@ -206,7 +206,7 @@ def clear_text(self): """ self.gui.clear_text() - def set_text(self, text, scroll_to='start'): + def set_text(self, text, scroll_to="start"): """ Clear and set the text to the given text. Additionally, move the cursor to the position given. Positions are: @@ -248,6 +248,7 @@ def set_wrap(self, value): """ textview = self.gui.textview from gi.repository import Gtk + # Gtk.WrapMode.NONE, Gtk.WrapMode.CHAR, Gtk.WrapMode.WORD or Gtk.WrapMode.WORD_CHAR. if value in [True, 1]: textview.set_wrap_mode(Gtk.WrapMode.WORD) @@ -259,8 +260,8 @@ def set_wrap(self, value): textview.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) else: raise ValueError( - "Unknown wrap mode: '%s': use 0,1,'char' or 'word char')" - % value) + "Unknown wrap mode: '%s': use 0,1,'char' or 'word char')" % value + ) def no_wrap(self): """ @@ -279,7 +280,7 @@ def load_data_to_text(self, pos=0): if len(self.gui.data) >= pos + 1: text = self.gui.data[pos] text = text.replace("\\n", chr(10)) - self.set_text(text, 'end') + self.set_text(text, "end") def save_text_to_data(self): """ @@ -294,24 +295,23 @@ def update(self, *args): The main interface for running the :meth:`main` method. """ from gi.repository import GLib - if ((not self.active) and - not self.gui.force_update): + + if (not self.active) and not self.gui.force_update: self.dirty = True if self.dbstate.is_open(): - #print " %s is not active" % self.gui.gname + # print " %s is not active" % self.gui.gname self.update_has_data() else: self.set_has_data(False) return - #print " %s is UPDATING" % self.gui.gname + # print " %s is UPDATING" % self.gui.gname self.dirty = False LOG.debug("gramplet updater: %s: running" % self.gui.title) if self._idle_id != 0: self.interrupt() self._generator = self.main() self._pause = False - self._idle_id = GLib.idle_add(self._updater, - priority=GLib.PRIORITY_LOW - 10) + self._idle_id = GLib.idle_add(self._updater, priority=GLib.PRIORITY_LOW - 10) def _updater(self): """ @@ -329,22 +329,23 @@ def _updater(self): if self._pause: LOG.debug("gramplet updater: %s: return False" % self.gui.title) return False - LOG.debug("gramplet updater: %s: return %s" % - (self.gui.title, retval)) + LOG.debug("gramplet updater: %s: return %s" % (self.gui.title, retval)) return retval except StopIteration: self._idle_id = 0 self._generator.close() - LOG.debug("gramplet updater: %s: Done!" % self.gui.title) + LOG.debug("gramplet updater: %s: Done!" % self.gui.title) return False except Exception as e: import traceback + LOG.warning("Gramplet gave an error: %s" % self.gui.title) traceback.print_exc() print("Continuing after gramplet error...") self._idle_id = 0 - self.uistate.push_message(self.dbstate, - _("Gramplet %s caused an error") % self.gui.title) + self.uistate.push_message( + self.dbstate, _("Gramplet %s caused an error") % self.gui.title + ) return False def pause(self, *args): @@ -358,9 +359,9 @@ def resume(self, *args): Resume the :meth:`main` method that has previously paused. """ from gi.repository import GLib + self._pause = False - self._idle_id = GLib.idle_add(self._updater, - priority=GLib.PRIORITY_LOW - 10) + self._idle_id = GLib.idle_add(self._updater, priority=GLib.PRIORITY_LOW - 10) def update_all(self, *args): """ @@ -377,6 +378,7 @@ def interrupt(self, *args): Force the generator to stop running. """ from gi.repository import GLib + self._pause = True if self._idle_id != 0: GLib.source_remove(self._idle_id) @@ -396,15 +398,15 @@ def _db_changed(self, db): # allows Person Gramplets to be informed of active-changed # Some Gramplets .gpr files don't have navtypes set, thus the # hasattr - if hasattr(self.gui, 'navtypes') and 'Person' in self.gui.navtypes: - self.connect_signal('Person', self._active_changed) + if hasattr(self.gui, "navtypes") and "Person" in self.gui.navtypes: + self.connect_signal("Person", self._active_changed) self.db_changed() # Some Gramplets use DbGUIElement; and DbGUIElement needs to know if # db is changed. However, at initialization, DbGUIElement is not yet # initialized when _db_changed is called, thus the test for callman if hasattr(self, "callman") and isinstance(self, DbGUIElement): # get DbGUIElement informed if in use - self._change_db(db) # DbGUIElement method + self._change_db(db) # DbGUIElement method self.update() @@ -449,7 +451,7 @@ def connect(self, signal_obj, signal, method): def disconnect(self, signal): if signal in self._signal: - for (id, signal_obj) in self._signal[signal]: + for id, signal_obj in self._signal[signal]: signal_obj.disconnect(id) self._signal[signal] = [] else: @@ -460,7 +462,7 @@ def disconnect_all(self): Used to disconnect all the signals for this specific gramplet """ for signal in self._signal: - for (sig_id, signal_obj) in self._signal[signal]: + for sig_id, signal_obj in self._signal[signal]: signal_obj.disconnect(sig_id) self._signal[signal] = [] diff --git a/gramps/gen/plug/_import.py b/gramps/gen/plug/_import.py index d07a00fea73..7eab9f93cc4 100644 --- a/gramps/gen/plug/_import.py +++ b/gramps/gen/plug/_import.py @@ -24,10 +24,12 @@ from . import Plugin + class ImportPlugin(Plugin): """ This class represents a plugin for importing data into Gramps """ + def __init__(self, name, description, import_function, extension): """ :param name: A friendly name to call this plugin. @@ -50,7 +52,7 @@ def import_function(db, filename, user): :type extension: str :return: nothing """ - Plugin.__init__(self, name, description, import_function.__module__ ) + Plugin.__init__(self, name, description, import_function.__module__) self.__import_func = import_function self.__extension = extension diff --git a/gramps/gen/plug/_manager.py b/gramps/gen/plug/_manager.py index c3e0fed48ce..38fe7e37834 100644 --- a/gramps/gen/plug/_manager.py +++ b/gramps/gen/plug/_manager.py @@ -30,44 +30,47 @@ importers, exporters, quick reports, and document generators. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import os import sys import re import logging import importlib -LOG = logging.getLogger('._manager') + +LOG = logging.getLogger("._manager") LOG.progagate = True from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..config import config from . import PluginRegister, ImportPlugin, ExportPlugin, DocGenPlugin from ..constfunc import win -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Constants # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- _UNAVAILABLE = _("No description was provided") -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # BasePluginManager # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class BasePluginManager: - """ unique singleton storage class for a :class:`.PluginManager`. """ + """unique singleton storage class for a :class:`.PluginManager`.""" __instance = None @@ -76,16 +79,18 @@ def get_instance(): Use this function to get the instance of the :class:`.PluginManager` """ if BasePluginManager.__instance is None: - BasePluginManager.__instance = 1 # Set to 1 for __init__() + BasePluginManager.__instance = 1 # Set to 1 for __init__() BasePluginManager.__instance = BasePluginManager() return BasePluginManager.__instance + get_instance = staticmethod(get_instance) def __init__(self): - """ This function should only be run once by get_instance() """ + """This function should only be run once by get_instance()""" if BasePluginManager.__instance != 1: - raise Exception("This class is a singleton. " - "Use the get_instance() method") + raise Exception( + "This class is a singleton. " "Use the get_instance() method" + ) self.__import_plugins = [] self.__export_plugins = [] @@ -104,16 +109,18 @@ def __init__(self): self.__loaded_plugins = {} self.__scanned_dirs = [] - def reg_plugin_dir(self, direct, dbstate=None, uistate=None, - load_on_reg=False, rescan=False): + def reg_plugin_dir( + self, direct, dbstate=None, uistate=None, load_on_reg=False, rescan=False + ): """ Register plugins in a given directory. """ self.__scanned_dirs.remove(direct) self.reg_plugins(direct, dbstate, uistate, load_on_reg, rescan) - def reg_plugins(self, direct, dbstate=None, uistate=None, - load_on_reg=False, rescan=False): + def reg_plugins( + self, direct, dbstate=None, uistate=None, load_on_reg=False, rescan=False + ): """ Searches the specified directory, and registers python plugin that are being defined in gpr.py files. @@ -137,12 +144,14 @@ def reg_plugins(self, direct, dbstate=None, uistate=None, # direct in self.__scanned_dirs, os.path.isdir(direct)) if os.path.isdir(direct): - for (dirpath, dirnames, filenames) in os.walk(direct, - topdown=True): + for dirpath, dirnames, filenames in os.walk(direct, topdown=True): for dirname in dirnames[:]: # Skip hidden and system directories: - if dirname.startswith(".") or dirname in ["po", "locale", - "__pycache__"]: + if dirname.startswith(".") or dirname in [ + "po", + "locale", + "__pycache__", + ]: dirnames.remove(dirname) # LOG.warning("Plugin dir scanned: %s", dirpath) if dirpath not in self.__scanned_dirs: @@ -165,7 +174,7 @@ def reg_plugins(self, direct, dbstate=None, uistate=None, count = 0 max_count = len(plugins_to_load) while plugins_to_load: - for plugin in plugins_to_load[:]: # copy of list + for plugin in plugins_to_load[:]: # copy of list # LOG.warning("\nDependencies for %s at registration", # plugin.id) delay = False @@ -174,7 +183,7 @@ def reg_plugins(self, direct, dbstate=None, uistate=None, delay = True break if delay: - pass # wait till next loop + pass # wait till next loop else: if plugin not in plugins_sorted: plugins_sorted.append(plugin) @@ -184,8 +193,10 @@ def reg_plugins(self, direct, dbstate=None, uistate=None, if count > max_count: print("Cannot resolve the following plugin dependencies:") for plugin in plugins_to_load: - print(" Plugin '%s' requires: %s" % ( - plugin.id, plugin.depends_on)) + print( + " Plugin '%s' requires: %s" + % (plugin.id, plugin.depends_on) + ) break # now load them: for plugin in plugins_sorted: @@ -199,6 +210,7 @@ def reg_plugins(self, direct, dbstate=None, uistate=None, results = mod.load_on_reg(dbstate, uistate, plugin) except: import traceback + traceback.print_exc() print("Plugin '%s' did not run; continuing..." % plugin.name) continue @@ -212,7 +224,8 @@ def reg_plugins(self, direct, dbstate=None, uistate=None, mod = self.load_plugin(plugin) # load the addon rule # get place in rule heirarchy to put the new rule obj_rules = importlib.import_module( - 'gramps.gen.filters.rules.' + plugin.namespace.lower()) + "gramps.gen.filters.rules." + plugin.namespace.lower() + ) # get the new rule class object r_class = getattr(mod, plugin.ruleclass) # make the new rule findable via import statements @@ -238,16 +251,16 @@ def load_plugin(self, pdata): need_reload = False filename = pdata.fname if filename in self.__modules: - #filename is loaded already, a different plugin in this module + # filename is loaded already, a different plugin in this module _module = self.__modules[filename] self.__success_list.append((filename, _module, pdata)) self.__loaded_plugins[pdata.id] = _module - self.__mod2text[_module.__name__] += ' - ' + pdata.description + self.__mod2text[_module.__name__] += " - " + pdata.description return _module if filename in self.__attempt_list: - #new load attempt after a fail, a reload needed + # new load attempt after a fail, a reload needed need_reload = True - #remove previous fail of the plugins in this file + # remove previous fail of the plugins in this file dellist = [] for index, data in enumerate(self.__failmsg_list): if data[0] == filename: @@ -272,6 +285,7 @@ def load_plugin(self, pdata): return _module except: import traceback + traceback.print_exc() self.__failmsg_list.append((filename, sys.exc_info(), pdata)) @@ -298,7 +312,7 @@ def import_plugin(self, pdata): if win(): # we don't want to load Gramps core plugin like this # only 3rd party plugins - if "gramps" in pdata.fpath: + if "gramps" in pdata.fpath: try: sys.path.insert(0, ".") oldwd = os.getcwd() @@ -307,14 +321,16 @@ def import_plugin(self, pdata): os.chdir(oldwd) sys.path.pop(0) except ValueError as err: - LOG.warning("Plugin error (from '%s'): %s" - % (pdata.mod_name, err)) + LOG.warning( + "Plugin error (from '%s'): %s" + % (pdata.mod_name, err) + ) else: - LOG.warning("Plugin error (from '%s'): %s" - % (pdata.mod_name, err)) + LOG.warning( + "Plugin error (from '%s'): %s" % (pdata.mod_name, err) + ) except ImportError as err: - LOG.warning("Plugin error (from '%s'): %s" - % (pdata.mod_name, err)) + LOG.warning("Plugin error (from '%s'): %s" % (pdata.mod_name, err)) sys.path.pop(0) else: print("WARNING: module cannot be loaded") @@ -323,7 +339,7 @@ def import_plugin(self, pdata): return module def empty_managed_plugins(self): - """ For some plugins, managed Plugin are used. These are only + """For some plugins, managed Plugin are used. These are only reobtained from the registry if this method is called """ # TODO: do other lists need to be reset here, too? @@ -332,9 +348,8 @@ def empty_managed_plugins(self): self.__docgen_plugins = [] self.__docgen_names = [] - def reload_plugins(self): - """ Reload previously loaded plugins """ + """Reload previously loaded plugins""" pymod = re.compile(r"^(.*)\.py$") oldfailmsg = self.__failmsg_list[:] @@ -347,14 +362,14 @@ def reload_plugins(self): oldmodules = self.__modules self.__modules = {} dellist = [] - #reload first modules that loaded successfully previously - for (index, plugin) in enumerate(self.__success_list): + # reload first modules that loaded successfully previously + for index, plugin in enumerate(self.__success_list): filename = plugin[0] pdata = plugin[2] - filename = filename.replace('pyc','py') - filename = filename.replace('pyo','py') + filename = filename.replace("pyc", "py") + filename = filename.replace("pyo", "py") if filename in self.__modules: - #module already reloaded, a second plugin in same module + # module already reloaded, a second plugin in same module continue try: self.reload(plugin[1], pdata) @@ -373,7 +388,7 @@ def reload_plugins(self): self.__purge_failed() # attempt to load the plugins that have failed in the past - for (filename, message, pdata) in oldfailmsg: + for filename, message, pdata in oldfailmsg: self.load_plugin(pdata) def reload(self, module, pdata): @@ -391,11 +406,11 @@ def reload(self, module, pdata): return module def get_fail_list(self): - """ Return the list of failed plugins. """ + """Return the list of failed plugins.""" return self.__failmsg_list def get_success_list(self): - """ Return the list of succeeded plugins. """ + """Return the list of succeeded plugins.""" return self.__success_list def get_plugin(self, id): @@ -405,90 +420,77 @@ def get_plugin(self, id): return self.__pgr.get_plugin(id) def get_reg_reports(self, gui=True): - """ Return list of registered reports + """Return list of registered reports :param gui: bool indicating if GUI reports or CLI reports must be returned """ return self.__pgr.report_plugins(gui) def get_reg_tools(self, gui=True): - """ Return list of registered tools + """Return list of registered tools :aram gui: bool indicating if GUI reports or CLI reports must be returned """ return self.__pgr.tool_plugins(gui) def get_reg_quick_reports(self): - """ Return list of registered quick reports - """ + """Return list of registered quick reports""" return self.__pgr.quickreport_plugins() def get_reg_views(self): - """ Return list of registered views - """ + """Return list of registered views""" return self.__pgr.view_plugins() def get_reg_mapservices(self): - """ Return list of registered mapservices - """ + """Return list of registered mapservices""" return self.__pgr.mapservice_plugins() def get_reg_bookitems(self): - """ Return list of reports registered as bookitem - """ + """Return list of reports registered as bookitem""" return self.__pgr.bookitem_plugins() def get_reg_gramplets(self): - """ Return list of non hidden gramplets. - """ + """Return list of non hidden gramplets.""" return self.__pgr.gramplet_plugins() def get_reg_sidebars(self): - """ Return list of registered sidebars. - """ + """Return list of registered sidebars.""" return self.__pgr.sidebar_plugins() def get_reg_databases(self): - """ Return list of registered database backends - """ + """Return list of registered database backends""" return self.__pgr.database_plugins() def get_reg_thumbnailers(self): - """ Return list of registered thumbnailers. - """ + """Return list of registered thumbnailers.""" return self.__pgr.thumbnailer_plugins() def get_reg_cite(self): - """ Return list of registered cite plugins. - """ + """Return list of registered cite plugins.""" return self.__pgr.cite_plugins() def get_external_opt_dict(self): - """ Return the dictionary of external options. """ + """Return the dictionary of external options.""" return self.__external_opt_dict def get_module_description(self, module): - """ Given a module name, return the module description. """ - return self.__mod2text.get(module, '') + """Given a module name, return the module description.""" + return self.__mod2text.get(module, "") def get_reg_importers(self): - """ Return list of registered importers - """ + """Return list of registered importers""" return self.__pgr.import_plugins() def get_reg_exporters(self): - """ Return list of registered exporters - """ + """Return list of registered exporters""" return self.__pgr.export_plugins() def get_reg_docgens(self): - """ Return list of registered docgen - """ + """Return list of registered docgen""" return self.__pgr.docgen_plugins() def get_reg_general(self, category=None): - """ Return list of registered general libs - """ + """Return list of registered general libs""" return self.__pgr.general_plugins(category) def load_plugin_category(self, category): @@ -557,16 +559,18 @@ def get_import_plugins(self): ## TODO: would it not be better to remove ImportPlugin and use ## only PluginData, loading from module when importfunction needed? if self.__import_plugins == []: - #The module still needs to be imported + # The module still needs to be imported for pdata in self.get_reg_importers(): if pdata.id in config.get("plugin.hiddenplugins"): continue mod = self.load_plugin(pdata) if mod: - imp = ImportPlugin(name=pdata.name, - description = pdata.description, - import_function = getattr(mod, pdata.import_function), - extension = pdata.extension) + imp = ImportPlugin( + name=pdata.name, + description=pdata.description, + import_function=getattr(mod, pdata.import_function), + extension=pdata.extension, + ) self.__import_plugins.append(imp) return self.__import_plugins @@ -580,21 +584,22 @@ def get_export_plugins(self): ## TODO: would it not be better to remove ExportPlugin and use ## only PluginData, loading from module when export/options needed? if self.__export_plugins == []: - #The modules still need to be imported + # The modules still need to be imported for pdata in self.get_reg_exporters(): if pdata.id in config.get("plugin.hiddenplugins"): continue mod = self.load_plugin(pdata) if mod: options = None - if (pdata.export_options and - hasattr(mod, pdata.export_options)): + if pdata.export_options and hasattr(mod, pdata.export_options): options = getattr(mod, pdata.export_options) - exp = ExportPlugin(name=pdata.name_accell, - description = pdata.description, - export_function = getattr(mod, pdata.export_function), - extension = pdata.extension, - config = (pdata.export_options_title, options)) + exp = ExportPlugin( + name=pdata.name_accell, + description=pdata.description, + export_function=getattr(mod, pdata.export_function), + extension=pdata.extension, + config=(pdata.export_options_title, options), + ) self.__export_plugins.append(exp) return self.__export_plugins @@ -609,7 +614,7 @@ def get_docgen_plugins(self): ## import those docgen that will then actuallly be needed? ## So, only do import when docgen.get_basedoc() is requested if self.__docgen_plugins == []: - #The modules still need to be imported + # The modules still need to be imported hiddenplugins = config.get("plugin.hiddenplugins") for pdata in self.get_reg_docgens(): if pdata.id in hiddenplugins: @@ -619,14 +624,16 @@ def get_docgen_plugins(self): oclass = None if pdata.optionclass: oclass = getattr(mod, pdata.optionclass) - dgp = DocGenPlugin(name=pdata.name, - description = pdata.description, - basedoc = getattr(mod, pdata.docclass), - paper = pdata.paper, - style = pdata.style, - extension = pdata.extension, - docoptclass = oclass, - basedocname = pdata.docclass ) + dgp = DocGenPlugin( + name=pdata.name, + description=pdata.description, + basedoc=getattr(mod, pdata.docclass), + paper=pdata.paper, + style=pdata.style, + extension=pdata.extension, + docoptclass=oclass, + basedocname=pdata.docclass, + ) self.__docgen_plugins.append(dgp) return self.__docgen_plugins @@ -658,7 +665,7 @@ def register_option(self, option, guioption): :param guioption: the gui-option class :type guioption: class that inherits from Gtk.Widget. """ - self.__external_opt_dict[option] = guioption; + self.__external_opt_dict[option] = guioption def __purge_failed(self): """ @@ -667,11 +674,20 @@ def __purge_failed(self): failed_module_names = [ os.path.splitext(os.path.basename(filename))[0] for filename, msg, pdata in self.__failmsg_list - ] - - self.__export_plugins[:] = [ item for item in self.__export_plugins - if item.get_module_name() not in failed_module_names ][:] - self.__import_plugins[:] = [ item for item in self.__import_plugins - if item.get_module_name() not in failed_module_names ][:] - self.__docgen_plugins[:] = [ item for item in self.__docgen_plugins - if item.get_module_name() not in failed_module_names ][:] + ] + + self.__export_plugins[:] = [ + item + for item in self.__export_plugins + if item.get_module_name() not in failed_module_names + ][:] + self.__import_plugins[:] = [ + item + for item in self.__import_plugins + if item.get_module_name() not in failed_module_names + ][:] + self.__docgen_plugins[:] = [ + item + for item in self.__docgen_plugins + if item.get_module_name() not in failed_module_names + ][:] diff --git a/gramps/gen/plug/_options.py b/gramps/gen/plug/_options.py index f2513d03768..a06bd405957 100644 --- a/gramps/gen/plug/_options.py +++ b/gramps/gen/plug/_options.py @@ -26,38 +26,42 @@ General option handling, including saving and parsing. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import os import sys -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # SAX interface # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from xml.sax import make_parser, handler, SAXParseException from xml.sax.saxutils import quoteattr -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ..utils.cast import get_type_converter from .menu import Menu from ..plug import BasePluginManager + PLUGMAN = BasePluginManager.get_instance() from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- + + +# ------------------------------------------------------------------------- # # List of options for a single module # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class OptionList: """ Implements a set of options to parse and store for a given module. @@ -116,11 +120,12 @@ def get_option(self, name): """ return self.options.get(name, None) -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Collection of option lists # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class OptionListCollection: """ Implements a collection of option lists. @@ -202,53 +207,60 @@ def save(self): Saves the current OptionListCollection to the associated file. """ with open(self.filename, "w", encoding="utf-8") as file: - file.write("\n") - file.write('\n') + file.write('\n') + file.write("\n") self.write_common(file) - for module_name in sorted(self.get_module_names()): # enable a diff + for module_name in sorted(self.get_module_names()): # enable a diff option_list = self.get_option_list(module_name) module_docgen_opts = {} for docgen_name in self.docgen_names: module_docgen_opts[docgen_name] = [] - file.write('\n' % quoteattr(module_name)) + file.write("\n" % quoteattr(module_name)) options = option_list.get_options() - for option_name in sorted(options.keys()): # enable a diff + for option_name in sorted(options.keys()): # enable a diff option_data = options[option_name] if isinstance(option_data, (list, tuple)): if option_data and option_data[0] in self.docgen_names: module_docgen_opts[option_data[0]].append( - (option_name, option_data[1])) + (option_name, option_data[1]) + ) else: - file.write(' \n') + file.write( + " \n' + % (list_index, quoteattr(str(list_data))) + ) + file.write(" \n") else: - file.write(' \n') + file.write("\n") - file.write('\n') + file.write("\n") def parse(self): """ @@ -262,11 +274,12 @@ def parse(self): except (IOError, OSError, SAXParseException): pass -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # OptionParser # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class OptionParser(handler.ContentHandler): """ SAX parsing class for the OptionListCollection XML file. @@ -293,17 +306,17 @@ def startElement(self, tag, attrs): Overridden class that handles the start of a XML element """ if tag in ("report", "module"): - self.mname = attrs['name'] + self.mname = attrs["name"] self.option_list = self.list_class() self.odict = {} elif tag == "option": - self.oname = attrs['name'] - if 'length' in attrs: + self.oname = attrs["name"] + if "length" in attrs: self.an_o = [] else: - self.an_o = attrs['value'] + self.an_o = attrs["value"] elif tag == "listitem": - self.an_o.append(attrs['value']) + self.an_o.append(attrs["value"]) def endElement(self, tag): "Overridden class that handles the end of a XML element" @@ -313,11 +326,12 @@ def endElement(self, tag): self.option_list.set_options(self.odict) self.collection.set_option_list(self.mname, self.option_list) -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Class handling options for plugins # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class OptionHandler: """ Implements handling of the options for the plugins. @@ -333,7 +347,8 @@ def __init__(self, module_name, options_dict, person_id=None): self.option_list_collection = self.collection_class(self.filename) self.init_common() self.saved_option_list = self.option_list_collection.get_option_list( - module_name) + module_name + ) self.person_id = person_id # Whatever was found should override the defaults @@ -342,8 +357,9 @@ def __init__(self, module_name, options_dict, person_id=None): else: # If nothing was found, set up the option list self.saved_option_list = self.list_class() - self.option_list_collection.set_option_list(module_name, - self.saved_option_list) + self.option_list_collection.set_option_list( + module_name, self.saved_option_list + ) def init_subclass(self): self.collection_class = OptionListCollection @@ -380,14 +396,22 @@ def set_options(self): docgen_names = self.option_list_collection.docgen_names for option_name in bad_opts: option_data = options[option_name] - if not (isinstance(option_data, list) - and option_data - and option_data[0] in docgen_names): - print(_("Option '%(opt_name)s' is present in %(file)s\n" + if not ( + isinstance(option_data, list) + and option_data + and option_data[0] in docgen_names + ): + print( + _( + "Option '%(opt_name)s' is present in %(file)s\n" " but is not known to the module. Ignoring..." - ) % {'opt_name' : option_name, - 'file' : self.option_list_collection.filename}, - file=sys.stderr) + ) + % { + "opt_name": option_name, + "file": self.option_list_collection.filename, + }, + file=sys.stderr, + ) options.pop(option_name) # Then we set common options from whatever was found @@ -410,7 +434,8 @@ def save_options(self): self.saved_option_list.remove_option(option_name) else: self.saved_option_list.set_option( - option_name, self.options_dict[option_name]) + option_name, self.options_dict[option_name] + ) # Handle common options self.save_common_options() @@ -427,11 +452,12 @@ def get_person_id(self): def set_person_id(self, val): self.person_id = val -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # Base Options class # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class Options: """ @@ -476,8 +502,7 @@ def load_previous_values(self): Modifies all options to have the value they were last used as. Call this function after all options have been added. """ - self.handler = OptionHandler( - self.name, self.options_dict, self.person_id) + self.handler = OptionHandler(self.name, self.options_dict, self.person_id) def add_user_options(self): """ @@ -506,11 +531,12 @@ def parse_user_options(self): """ pass -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # MenuOptions class # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class MenuOptions: """ **Introduction** @@ -518,6 +544,7 @@ class MenuOptions: A MenuOptions is used to implement the necessary functions for adding options to a menu. """ + def __init__(self): self.menu = Menu() diff --git a/gramps/gen/plug/_plugin.py b/gramps/gen/plug/_plugin.py index 8c681cd6a07..7126a8e9d82 100644 --- a/gramps/gen/plug/_plugin.py +++ b/gramps/gen/plug/_plugin.py @@ -23,11 +23,13 @@ This module provides the base class for plugins. """ + class Plugin: """ This class serves as a base class for all plugins that can be registered with the plugin manager """ + def __init__(self, name, description, module_name): """ :param name: A friendly name to call this plugin. @@ -68,4 +70,3 @@ def get_module_name(self): :return: a string representing the name of the module for this plugin """ return self.__mod_name - diff --git a/gramps/gen/plug/_pluginreg.py b/gramps/gen/plug/_pluginreg.py index 5ea3cf7db4b..28c53e6bef3 100644 --- a/gramps/gen/plug/_pluginreg.py +++ b/gramps/gen/plug/_pluginreg.py @@ -24,34 +24,36 @@ It provides an object containing data about the plugin (version, filename, ...) and a register for the data of all plugins . """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import os import sys import re import traceback -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...version import VERSION as GRAMPSVERSION, VERSION_TUPLE from ..utils.requirements import Requirements from ..const import IMAGE_DIR from ..const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext import logging -LOG = logging.getLogger('._manager') -#------------------------------------------------------------------------- +LOG = logging.getLogger("._manager") + +# ------------------------------------------------------------------------- # # PluginData # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # Development status UNSTABLE = 0 @@ -59,23 +61,23 @@ BETA = 2 STABLE = 3 STATUS = [UNSTABLE, EXPERIMENTAL, BETA, STABLE] -STATUSTEXT = {UNSTABLE: _('Unstable'), - EXPERIMENTAL: _('Experimental'), - BETA: _('Beta'), - STABLE: _('Stable')} +STATUSTEXT = { + UNSTABLE: _("Unstable"), + EXPERIMENTAL: _("Experimental"), + BETA: _("Beta"), + STABLE: _("Stable"), +} # Intended audience EVERYONE = 0 DEVELOPER = 1 EXPERT = 2 AUDIENCE = [EVERYONE, DEVELOPER, EXPERT] -AUDIENCETEXT = {EVERYONE: _('Everyone'), - DEVELOPER: _('Developer'), - EXPERT: _('Expert')} +AUDIENCETEXT = {EVERYONE: _("Everyone"), DEVELOPER: _("Developer"), EXPERT: _("Expert")} -#possible plugin types +# possible plugin types REPORT = 0 -QUICKREPORT = 1 # deprecated +QUICKREPORT = 1 # deprecated QUICKVIEW = 1 TOOL = 2 IMPORT = 3 @@ -91,29 +93,44 @@ RULE = 13 THUMBNAILER = 14 CITE = 15 -PTYPE = [REPORT, QUICKREPORT, TOOL, IMPORT, EXPORT, DOCGEN, GENERAL, - MAPSERVICE, VIEW, RELCALC, GRAMPLET, SIDEBAR, DATABASE, RULE, - THUMBNAILER, CITE] +PTYPE = [ + REPORT, + QUICKREPORT, + TOOL, + IMPORT, + EXPORT, + DOCGEN, + GENERAL, + MAPSERVICE, + VIEW, + RELCALC, + GRAMPLET, + SIDEBAR, + DATABASE, + RULE, + THUMBNAILER, + CITE, +] PTYPE_STR = { - REPORT: _('Report') , - QUICKREPORT: _('Quickreport'), - TOOL: _('Tool'), - IMPORT: _('Importer'), - EXPORT: _('Exporter'), - DOCGEN: _('Doc creator'), - GENERAL: _('Plugin lib'), - MAPSERVICE: _('Map service'), - VIEW: _('Gramps View'), - RELCALC: _('Relationships'), - GRAMPLET: _('Gramplet'), - SIDEBAR: _('Sidebar'), - DATABASE: _('Database'), - RULE: _('Rule'), - THUMBNAILER: _('Thumbnailer'), - CITE: _('Citation formatter'), - } - -#possible report categories + REPORT: _("Report"), + QUICKREPORT: _("Quickreport"), + TOOL: _("Tool"), + IMPORT: _("Importer"), + EXPORT: _("Exporter"), + DOCGEN: _("Doc creator"), + GENERAL: _("Plugin lib"), + MAPSERVICE: _("Map service"), + VIEW: _("Gramps View"), + RELCALC: _("Relationships"), + GRAMPLET: _("Gramplet"), + SIDEBAR: _("Sidebar"), + DATABASE: _("Database"), + RULE: _("Rule"), + THUMBNAILER: _("Thumbnailer"), + CITE: _("Citation formatter"), +} + +# possible report categories CATEGORY_TEXT = 0 CATEGORY_DRAW = 1 CATEGORY_CODE = 2 @@ -121,20 +138,25 @@ CATEGORY_BOOK = 4 CATEGORY_GRAPHVIZ = 5 CATEGORY_TREE = 6 -REPORT_CAT = [ CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE, - CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ, - CATEGORY_TREE] -#possible tool categories +REPORT_CAT = [ + CATEGORY_TEXT, + CATEGORY_DRAW, + CATEGORY_CODE, + CATEGORY_WEB, + CATEGORY_BOOK, + CATEGORY_GRAPHVIZ, + CATEGORY_TREE, +] +# possible tool categories TOOL_DEBUG = -1 TOOL_ANAL = 0 TOOL_DBPROC = 1 TOOL_DBFIX = 2 TOOL_REVCTL = 3 TOOL_UTILS = 4 -TOOL_CAT = [ TOOL_DEBUG, TOOL_ANAL, TOOL_DBPROC, TOOL_DBFIX, TOOL_REVCTL, - TOOL_UTILS] +TOOL_CAT = [TOOL_DEBUG, TOOL_ANAL, TOOL_DBPROC, TOOL_DBFIX, TOOL_REVCTL, TOOL_UTILS] -#possible quickreport categories +# possible quickreport categories CATEGORY_QR_MISC = -1 CATEGORY_QR_PERSON = 0 CATEGORY_QR_FAMILY = 1 @@ -149,25 +171,26 @@ CATEGORY_QR_SOURCE_OR_CITATION = 10 # Modes for generating reports -REPORT_MODE_GUI = 1 # Standalone report using GUI -REPORT_MODE_BKI = 2 # Book Item interface using GUI -REPORT_MODE_CLI = 4 # Command line interface (CLI) +REPORT_MODE_GUI = 1 # Standalone report using GUI +REPORT_MODE_BKI = 2 # Book Item interface using GUI +REPORT_MODE_CLI = 4 # Command line interface (CLI) REPORT_MODES = [REPORT_MODE_GUI, REPORT_MODE_BKI, REPORT_MODE_CLI] # Modes for running tools -TOOL_MODE_GUI = 1 # Standard tool using GUI -TOOL_MODE_CLI = 2 # Command line interface (CLI) +TOOL_MODE_GUI = 1 # Standard tool using GUI +TOOL_MODE_CLI = 2 # Command line interface (CLI) TOOL_MODES = [TOOL_MODE_GUI, TOOL_MODE_CLI] # possible view orders START = 1 END = 2 -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Functions and classes # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- def myint(s): """ Protected version of int() @@ -178,28 +201,33 @@ def myint(s): v = s return v + def version(sversion): """ Return the tuple version of a string version. """ return tuple([myint(x or "0") for x in (sversion + "..").split(".")]) + def valid_plugin_version(plugin_version_string): """ Checks to see if string is a valid version string for this version of Gramps. """ - if not isinstance(plugin_version_string, str): return False + if not isinstance(plugin_version_string, str): + return False dots = plugin_version_string.count(".") if dots == 1: plugin_version = tuple(map(int, plugin_version_string.split(".", 1))) return plugin_version == VERSION_TUPLE[:2] elif dots == 2: plugin_version = tuple(map(int, plugin_version_string.split(".", 2))) - return (plugin_version[:2] == VERSION_TUPLE[:2] and - plugin_version <= VERSION_TUPLE) + return ( + plugin_version[:2] == VERSION_TUPLE[:2] and plugin_version <= VERSION_TUPLE + ) return False + class PluginData: """ This is the base class for all plugin data objects. @@ -418,9 +446,9 @@ class PluginData: """ def __init__(self): - #read/write attribute + # read/write attribute self.directory = None - #base attributes + # base attributes self._id = None self._name = None self._name_accell = None @@ -446,68 +474,68 @@ def __init__(self): self._requires_exe = [] self._include_in_listing = True self._help_url = None - #derived var + # derived var self.mod_name = None - #RELCALC attr + # RELCALC attr self._relcalcclass = None self._lang_list = None - #REPORT attr + # REPORT attr self._reportclass = None self._require_active = True self._report_modes = [REPORT_MODE_GUI] - #REPORT and TOOL and GENERAL attr + # REPORT and TOOL and GENERAL attr self._category = None - #REPORT and TOOL attr + # REPORT and TOOL attr self._optionclass = None - #TOOL attr + # TOOL attr self._toolclass = None self._tool_modes = [TOOL_MODE_GUI] - #DOCGEN attr + # DOCGEN attr self._paper = True self._style = True - self._extension = '' - #QUICKREPORT attr + self._extension = "" + # QUICKREPORT attr self._runfunc = None - #MAPSERVICE attr + # MAPSERVICE attr self._mapservice = None - #EXPORT attr + # EXPORT attr self._export_function = None self._export_options = None - self._export_options_title = '' - #IMPORT attr + self._export_options_title = "" + # IMPORT attr self._import_function = None - #GRAMPLET attr + # GRAMPLET attr self._gramplet = None self._height = 200 self._detached_height = 300 self._detached_width = 400 self._expand = False - self._gramplet_title = _('Gramplet') + self._gramplet_title = _("Gramplet") self._navtypes = [] self._orientation = None - #VIEW attr + # VIEW attr self._viewclass = None self._stock_category_icon = None self._stock_icon = None - #SIDEBAR attr + # SIDEBAR attr self._sidebarclass = None - self._menu_label = '' - #VIEW and SIDEBAR attr + self._menu_label = "" + # VIEW and SIDEBAR attr self._order = END - #DATABASE attr + # DATABASE attr self._databaseclass = None self._reset_system = False - #GENERAL attr + # GENERAL attr self._data = [] self._process = None - #RULE attr + # RULE attr self._ruleclass = None self._namespace = None - #THUMBNAILER attr + # THUMBNAILER attr self._thumbnailer = None def _set_id(self, id): - self._id = id + self._id = id def _get_id(self): return self._id @@ -534,20 +562,20 @@ def _get_description(self): return self._description def _set_version(self, version): - self._version = version + self._version = version def _get_version(self): return self._version def _set_gramps_target_version(self, version): - self._gramps_target_version = version + self._gramps_target_version = version def _get_gramps_target_version(self): return self._gramps_target_version def _set_status(self, status): if status not in STATUS: - raise ValueError('plugin status cannot be %s' % str(status)) + raise ValueError("plugin status cannot be %s" % str(status)) self._status = status def _get_status(self): @@ -555,7 +583,7 @@ def _get_status(self): def _set_audience(self, audience): if audience not in AUDIENCE: - raise ValueError('plugin audience cannot be %s' % str(audience)) + raise ValueError("plugin audience cannot be %s" % str(audience)) self._audience = audience def _get_audience(self): @@ -575,9 +603,9 @@ def _get_fpath(self): def _set_ptype(self, ptype): if ptype not in PTYPE: - raise ValueError('Plugin type cannot be %s' % str(ptype)) + raise ValueError("Plugin type cannot be %s" % str(ptype)) elif self._ptype is not None: - raise ValueError('Plugin type may not be changed') + raise ValueError("Plugin type may not be changed") self._ptype = ptype if self._ptype == REPORT: self._category = CATEGORY_TEXT @@ -587,7 +615,7 @@ def _set_ptype(self, ptype): self._category = CATEGORY_QR_PERSON elif self._ptype == VIEW: self._category = ("Miscellaneous", _("Miscellaneous")) - #if self._ptype == DOCGEN: + # if self._ptype == DOCGEN: # self._load_on_reg = True def _get_ptype(self): @@ -627,7 +655,7 @@ def _get_maintainers_email(self): def _set_supported(self, supported): if not isinstance(supported, bool): - raise ValueError('Plugin must have supported=True or False') + raise ValueError("Plugin must have supported=True or False") self._supported = supported def _get_supported(self): @@ -635,7 +663,7 @@ def _get_supported(self): def _set_load_on_reg(self, load_on_reg): if not isinstance(load_on_reg, bool): - raise ValueError('Plugin must have load_on_reg=True or False') + raise ValueError("Plugin must have load_on_reg=True or False") self._load_on_reg = load_on_reg def _get_load_on_reg(self): @@ -646,7 +674,7 @@ def _get_icons(self): def _set_icons(self, icons): if not isinstance(icons, list): - raise ValueError('Plugin must have icons as a list') + raise ValueError("Plugin must have icons as a list") self._icons = icons def _get_icondir(self): @@ -660,7 +688,7 @@ def _get_depends_on(self): def _set_depends_on(self, depends): if not isinstance(depends, list): - raise ValueError('Plugin must have depends_on as a list') + raise ValueError("Plugin must have depends_on as a list") self._depends_on = depends def _get_requires_mod(self): @@ -668,7 +696,7 @@ def _get_requires_mod(self): def _set_requires_mod(self, requires): if not isinstance(requires, list): - raise ValueError('Plugin must have requires_mod as a list') + raise ValueError("Plugin must have requires_mod as a list") self._requires_mod = requires def _get_requires_gi(self): @@ -676,7 +704,7 @@ def _get_requires_gi(self): def _set_requires_gi(self, requires): if not isinstance(requires, list): - raise ValueError('Plugin must have requires_gi as a list') + raise ValueError("Plugin must have requires_gi as a list") self._requires_gi = requires def _get_requires_exe(self): @@ -684,7 +712,7 @@ def _get_requires_exe(self): def _set_requires_exe(self, requires): if not isinstance(requires, list): - raise ValueError('Plugin must have requires_exe as a list') + raise ValueError("Plugin must have requires_exe as a list") self._requires_exe = requires def _get_include_in_listing(self): @@ -692,7 +720,7 @@ def _get_include_in_listing(self): def _set_include_in_listing(self, include): if not isinstance(include, bool): - raise ValueError('Plugin must have include_in_listing as a bool') + raise ValueError("Plugin must have include_in_listing as a bool") self._include_in_listing = include def _set_help_url(self, help_url): @@ -706,8 +734,9 @@ def _get_help_url(self): name_accell = property(_get_name_accell, _set_name_accell) description = property(_get_description, _set_description) version = property(_get_version, _set_version) - gramps_target_version = property(_get_gramps_target_version, - _set_gramps_target_version) + gramps_target_version = property( + _get_gramps_target_version, _set_gramps_target_version + ) status = property(_get_status, _set_status) audience = property(_get_audience, _set_audience) fname = property(_get_fname, _set_fname) @@ -731,12 +760,12 @@ def _get_help_url(self): def statustext(self): return STATUSTEXT[self.status] - #type specific plugin attributes + # type specific plugin attributes - #RELCALC attributes + # RELCALC attributes def _set_relcalcclass(self, relcalcclass): if not self._ptype == RELCALC: - raise ValueError('relcalcclass may only be set for RELCALC plugins') + raise ValueError("relcalcclass may only be set for RELCALC plugins") self._relcalcclass = relcalcclass def _get_relcalcclass(self): @@ -744,7 +773,7 @@ def _get_relcalcclass(self): def _set_lang_list(self, lang_list): if not self._ptype == RELCALC: - raise ValueError('relcalcclass may only be set for RELCALC plugins') + raise ValueError("relcalcclass may only be set for RELCALC plugins") self._lang_list = lang_list def _get_lang_list(self): @@ -753,12 +782,12 @@ def _get_lang_list(self): relcalcclass = property(_get_relcalcclass, _set_relcalcclass) lang_list = property(_get_lang_list, _set_lang_list) - #REPORT attributes + # REPORT attributes def _set_require_active(self, require_active): if not self._ptype == REPORT: - raise ValueError('require_active may only be set for REPORT plugins') + raise ValueError("require_active may only be set for REPORT plugins") if not isinstance(require_active, bool): - raise ValueError('Report must have require_active=True or False') + raise ValueError("Report must have require_active=True or False") self._require_active = require_active def _get_require_active(self): @@ -766,7 +795,7 @@ def _get_require_active(self): def _set_reportclass(self, reportclass): if not self._ptype == REPORT: - raise ValueError('reportclass may only be set for REPORT plugins') + raise ValueError("reportclass may only be set for REPORT plugins") self._reportclass = reportclass def _get_reportclass(self): @@ -774,39 +803,43 @@ def _get_reportclass(self): def _set_report_modes(self, report_modes): if not self._ptype == REPORT: - raise ValueError('report_modes may only be set for REPORT plugins') + raise ValueError("report_modes may only be set for REPORT plugins") if not isinstance(report_modes, list): - raise ValueError('report_modes must be a list') + raise ValueError("report_modes must be a list") self._report_modes = [x for x in report_modes if x in REPORT_MODES] if not self._report_modes: - raise ValueError('report_modes not a valid list of modes') + raise ValueError("report_modes not a valid list of modes") def _get_report_modes(self): return self._report_modes - #REPORT or TOOL or QUICKREPORT or GENERAL attributes + # REPORT or TOOL or QUICKREPORT or GENERAL attributes def _set_category(self, category): if self._ptype not in [REPORT, TOOL, QUICKREPORT, VIEW, GENERAL]: - raise ValueError('category may only be set for ' \ - 'REPORT/TOOL/QUICKREPORT/VIEW/GENERAL plugins') + raise ValueError( + "category may only be set for " + "REPORT/TOOL/QUICKREPORT/VIEW/GENERAL plugins" + ) self._category = category def _get_category(self): return self._category - #REPORT OR TOOL attributes + # REPORT OR TOOL attributes def _set_optionclass(self, optionclass): if not (self._ptype == REPORT or self.ptype == TOOL or self._ptype == DOCGEN): - raise ValueError('optionclass may only be set for REPORT/TOOL/DOCGEN plugins') + raise ValueError( + "optionclass may only be set for REPORT/TOOL/DOCGEN plugins" + ) self._optionclass = optionclass def _get_optionclass(self): return self._optionclass - #TOOL attributes + # TOOL attributes def _set_toolclass(self, toolclass): if not self._ptype == TOOL: - raise ValueError('toolclass may only be set for TOOL plugins') + raise ValueError("toolclass may only be set for TOOL plugins") self._toolclass = toolclass def _get_toolclass(self): @@ -814,12 +847,12 @@ def _get_toolclass(self): def _set_tool_modes(self, tool_modes): if not self._ptype == TOOL: - raise ValueError('tool_modes may only be set for TOOL plugins') + raise ValueError("tool_modes may only be set for TOOL plugins") if not isinstance(tool_modes, list): - raise ValueError('tool_modes must be a list') + raise ValueError("tool_modes must be a list") self._tool_modes = [x for x in tool_modes if x in TOOL_MODES] if not self._tool_modes: - raise ValueError('tool_modes not a valid list of modes') + raise ValueError("tool_modes not a valid list of modes") def _get_tool_modes(self): return self._tool_modes @@ -832,12 +865,12 @@ def _get_tool_modes(self): toolclass = property(_get_toolclass, _set_toolclass) tool_modes = property(_get_tool_modes, _set_tool_modes) - #DOCGEN attributes + # DOCGEN attributes def _set_paper(self, paper): if not self._ptype == DOCGEN: - raise ValueError('paper may only be set for DOCGEN plugins') + raise ValueError("paper may only be set for DOCGEN plugins") if not isinstance(paper, bool): - raise ValueError('Plugin must have paper=True or False') + raise ValueError("Plugin must have paper=True or False") self._paper = paper def _get_paper(self): @@ -845,19 +878,21 @@ def _get_paper(self): def _set_style(self, style): if not self._ptype == DOCGEN: - raise ValueError('style may only be set for DOCGEN plugins') + raise ValueError("style may only be set for DOCGEN plugins") if not isinstance(style, bool): - raise ValueError('Plugin must have style=True or False') + raise ValueError("Plugin must have style=True or False") self._style = style def _get_style(self): return self._style def _set_extension(self, extension): - if not (self._ptype == DOCGEN or self._ptype == EXPORT - or self._ptype == IMPORT): - raise ValueError('extension may only be set for DOCGEN/EXPORT/'\ - 'IMPORT plugins') + if not ( + self._ptype == DOCGEN or self._ptype == EXPORT or self._ptype == IMPORT + ): + raise ValueError( + "extension may only be set for DOCGEN/EXPORT/" "IMPORT plugins" + ) self._extension = extension def _get_extension(self): @@ -867,10 +902,10 @@ def _get_extension(self): style = property(_get_style, _set_style) extension = property(_get_extension, _set_extension) - #QUICKREPORT attributes + # QUICKREPORT attributes def _set_runfunc(self, runfunc): if not self._ptype == QUICKREPORT: - raise ValueError('runfunc may only be set for QUICKREPORT plugins') + raise ValueError("runfunc may only be set for QUICKREPORT plugins") self._runfunc = runfunc def _get_runfunc(self): @@ -878,10 +913,10 @@ def _get_runfunc(self): runfunc = property(_get_runfunc, _set_runfunc) - #MAPSERVICE attributes + # MAPSERVICE attributes def _set_mapservice(self, mapservice): if not self._ptype == MAPSERVICE: - raise ValueError('mapservice may only be set for MAPSERVICE plugins') + raise ValueError("mapservice may only be set for MAPSERVICE plugins") self._mapservice = mapservice def _get_mapservice(self): @@ -889,10 +924,10 @@ def _get_mapservice(self): mapservice = property(_get_mapservice, _set_mapservice) - #EXPORT attributes + # EXPORT attributes def _set_export_function(self, export_function): if not self._ptype == EXPORT: - raise ValueError('export_function may only be set for EXPORT plugins') + raise ValueError("export_function may only be set for EXPORT plugins") self._export_function = export_function def _get_export_function(self): @@ -900,7 +935,7 @@ def _get_export_function(self): def _set_export_options(self, export_options): if not self._ptype == EXPORT: - raise ValueError('export_options may only be set for EXPORT plugins') + raise ValueError("export_options may only be set for EXPORT plugins") self._export_options = export_options def _get_export_options(self): @@ -908,7 +943,7 @@ def _get_export_options(self): def _set_export_options_title(self, export_options_title): if not self._ptype == EXPORT: - raise ValueError('export_options_title may only be set for EXPORT plugins') + raise ValueError("export_options_title may only be set for EXPORT plugins") self._export_options_title = export_options_title def _get_export_options_title(self): @@ -916,13 +951,14 @@ def _get_export_options_title(self): export_function = property(_get_export_function, _set_export_function) export_options = property(_get_export_options, _set_export_options) - export_options_title = property(_get_export_options_title, - _set_export_options_title) + export_options_title = property( + _get_export_options_title, _set_export_options_title + ) - #IMPORT attributes + # IMPORT attributes def _set_import_function(self, import_function): if not self._ptype == IMPORT: - raise ValueError('import_function may only be set for IMPORT plugins') + raise ValueError("import_function may only be set for IMPORT plugins") self._import_function = import_function def _get_import_function(self): @@ -930,10 +966,10 @@ def _get_import_function(self): import_function = property(_get_import_function, _set_import_function) - #GRAMPLET attributes + # GRAMPLET attributes def _set_gramplet(self, gramplet): if not self._ptype == GRAMPLET: - raise ValueError('gramplet may only be set for GRAMPLET plugins') + raise ValueError("gramplet may only be set for GRAMPLET plugins") self._gramplet = gramplet def _get_gramplet(self): @@ -941,9 +977,9 @@ def _get_gramplet(self): def _set_height(self, height): if not self._ptype == GRAMPLET: - raise ValueError('height may only be set for GRAMPLET plugins') + raise ValueError("height may only be set for GRAMPLET plugins") if not isinstance(height, int): - raise ValueError('Plugin must have height an integer') + raise ValueError("Plugin must have height an integer") self._height = height def _get_height(self): @@ -951,9 +987,9 @@ def _get_height(self): def _set_detached_height(self, detached_height): if not self._ptype == GRAMPLET: - raise ValueError('detached_height may only be set for GRAMPLET plugins') + raise ValueError("detached_height may only be set for GRAMPLET plugins") if not isinstance(detached_height, int): - raise ValueError('Plugin must have detached_height an integer') + raise ValueError("Plugin must have detached_height an integer") self._detached_height = detached_height def _get_detached_height(self): @@ -961,9 +997,9 @@ def _get_detached_height(self): def _set_detached_width(self, detached_width): if not self._ptype == GRAMPLET: - raise ValueError('detached_width may only be set for GRAMPLET plugins') + raise ValueError("detached_width may only be set for GRAMPLET plugins") if not isinstance(detached_width, int): - raise ValueError('Plugin must have detached_width an integer') + raise ValueError("Plugin must have detached_width an integer") self._detached_width = detached_width def _get_detached_width(self): @@ -971,9 +1007,9 @@ def _get_detached_width(self): def _set_expand(self, expand): if not self._ptype == GRAMPLET: - raise ValueError('expand may only be set for GRAMPLET plugins') + raise ValueError("expand may only be set for GRAMPLET plugins") if not isinstance(expand, bool): - raise ValueError('Plugin must have expand as a bool') + raise ValueError("Plugin must have expand as a bool") self._expand = expand def _get_expand(self): @@ -981,9 +1017,12 @@ def _get_expand(self): def _set_gramplet_title(self, gramplet_title): if not self._ptype == GRAMPLET: - raise ValueError('gramplet_title may only be set for GRAMPLET plugins') + raise ValueError("gramplet_title may only be set for GRAMPLET plugins") if not isinstance(gramplet_title, str): - raise ValueError('gramplet_title is type %s, string or unicode required' % type(gramplet_title)) + raise ValueError( + "gramplet_title is type %s, string or unicode required" + % type(gramplet_title) + ) self._gramplet_title = gramplet_title def _get_gramplet_title(self): @@ -991,7 +1030,7 @@ def _get_gramplet_title(self): def _set_navtypes(self, navtypes): if not self._ptype == GRAMPLET: - raise ValueError('navtypes may only be set for GRAMPLET plugins') + raise ValueError("navtypes may only be set for GRAMPLET plugins") self._navtypes = navtypes def _get_navtypes(self): @@ -999,7 +1038,7 @@ def _get_navtypes(self): def _set_orientation(self, orientation): if not self._ptype == GRAMPLET: - raise ValueError('orientation may only be set for GRAMPLET plugins') + raise ValueError("orientation may only be set for GRAMPLET plugins") self._orientation = orientation def _get_orientation(self): @@ -1016,7 +1055,7 @@ def _get_orientation(self): def _set_viewclass(self, viewclass): if not self._ptype == VIEW: - raise ValueError('viewclass may only be set for VIEW plugins') + raise ValueError("viewclass may only be set for VIEW plugins") self._viewclass = viewclass def _get_viewclass(self): @@ -1024,7 +1063,7 @@ def _get_viewclass(self): def _set_stock_category_icon(self, stock_category_icon): if not self._ptype == VIEW: - raise ValueError('stock_category_icon may only be set for VIEW plugins') + raise ValueError("stock_category_icon may only be set for VIEW plugins") self._stock_category_icon = stock_category_icon def _get_stock_category_icon(self): @@ -1032,7 +1071,7 @@ def _get_stock_category_icon(self): def _set_stock_icon(self, stock_icon): if not self._ptype == VIEW: - raise ValueError('stock_icon may only be set for VIEW plugins') + raise ValueError("stock_icon may only be set for VIEW plugins") self._stock_icon = stock_icon def _get_stock_icon(self): @@ -1042,10 +1081,10 @@ def _get_stock_icon(self): stock_category_icon = property(_get_stock_category_icon, _set_stock_category_icon) stock_icon = property(_get_stock_icon, _set_stock_icon) - #SIDEBAR attributes + # SIDEBAR attributes def _set_sidebarclass(self, sidebarclass): if not self._ptype == SIDEBAR: - raise ValueError('sidebarclass may only be set for SIDEBAR plugins') + raise ValueError("sidebarclass may only be set for SIDEBAR plugins") self._sidebarclass = sidebarclass def _get_sidebarclass(self): @@ -1053,7 +1092,7 @@ def _get_sidebarclass(self): def _set_menu_label(self, menu_label): if not self._ptype == SIDEBAR: - raise ValueError('menu_label may only be set for SIDEBAR plugins') + raise ValueError("menu_label may only be set for SIDEBAR plugins") self._menu_label = menu_label def _get_menu_label(self): @@ -1062,10 +1101,12 @@ def _get_menu_label(self): sidebarclass = property(_get_sidebarclass, _set_sidebarclass) menu_label = property(_get_menu_label, _set_menu_label) - #VIEW, SIDEBAR and THUMBNAILER attributes + # VIEW, SIDEBAR and THUMBNAILER attributes def _set_order(self, order): if not self._ptype in (VIEW, SIDEBAR, THUMBNAILER): - raise ValueError('order may only be set for VIEW/SIDEBAR/THUMBNAILER plugins') + raise ValueError( + "order may only be set for VIEW/SIDEBAR/THUMBNAILER plugins" + ) self._order = order def _get_order(self): @@ -1073,10 +1114,10 @@ def _get_order(self): order = property(_get_order, _set_order) - #DATABASE attributes + # DATABASE attributes def _set_databaseclass(self, databaseclass): if not self._ptype == DATABASE: - raise ValueError('databaseclass may only be set for DATABASE plugins') + raise ValueError("databaseclass may only be set for DATABASE plugins") self._databaseclass = databaseclass def _get_databaseclass(self): @@ -1084,7 +1125,7 @@ def _get_databaseclass(self): def _set_reset_system(self, reset_system): if not self._ptype == DATABASE: - raise ValueError('reset_system may only be set for DATABASE plugins') + raise ValueError("reset_system may only be set for DATABASE plugins") self._reset_system = reset_system def _get_reset_system(self): @@ -1093,10 +1134,10 @@ def _get_reset_system(self): databaseclass = property(_get_databaseclass, _set_databaseclass) reset_system = property(_get_reset_system, _set_reset_system) - #GENERAL attr + # GENERAL attr def _set_data(self, data): if not self._ptype in (GENERAL,): - raise ValueError('data may only be set for GENERAL plugins') + raise ValueError("data may only be set for GENERAL plugins") self._data = data def _get_data(self): @@ -1104,7 +1145,7 @@ def _get_data(self): def _set_process(self, process): if not self._ptype in (GENERAL,): - raise ValueError('process may only be set for GENERAL plugins') + raise ValueError("process may only be set for GENERAL plugins") self._process = process def _get_process(self): @@ -1113,10 +1154,10 @@ def _get_process(self): data = property(_get_data, _set_data) process = property(_get_process, _set_process) - #RULE attr + # RULE attr def _set_ruleclass(self, data): if self._ptype != RULE: - raise ValueError('ruleclass may only be set for RULE plugins') + raise ValueError("ruleclass may only be set for RULE plugins") self._ruleclass = data def _get_ruleclass(self): @@ -1124,7 +1165,7 @@ def _get_ruleclass(self): def _set_namespace(self, data): if self._ptype != RULE: - raise ValueError('namespace may only be set for RULE plugins') + raise ValueError("namespace may only be set for RULE plugins") self._namespace = data def _get_namespace(self): @@ -1133,10 +1174,10 @@ def _get_namespace(self): ruleclass = property(_get_ruleclass, _set_ruleclass) namespace = property(_get_namespace, _set_namespace) - #THUMBNAILER attr + # THUMBNAILER attr def _set_thumbnailer(self, data): if self._ptype != THUMBNAILER: - raise ValueError('thumbnailer may only be set for THUMBNAILER plugins') + raise ValueError("thumbnailer may only be set for THUMBNAILER plugins") self._thumbnailer = data def _get_thumbnailer(self): @@ -1144,6 +1185,7 @@ def _get_thumbnailer(self): thumbnailer = property(_get_thumbnailer, _set_thumbnailer) + def newplugin(): """ Function to create a new plugindata object, add it to list of @@ -1156,6 +1198,7 @@ def newplugin(): gpr.add_plugindata(pgd) return pgd + def register(ptype, **kwargs): """ Convenience function to register a new plugin using a dictionary as input. @@ -1172,82 +1215,84 @@ def register(ptype, **kwargs): plg = newplugin() plg.ptype = ptype for prop in kwargs: - #check it is a valid attribute with getattr + # check it is a valid attribute with getattr getattr(plg, prop) - #set the value + # set the value setattr(plg, prop, kwargs[prop]) return plg + def make_environment(**kwargs): env = { - 'newplugin': newplugin, - 'register': register, - 'UNSTABLE': UNSTABLE, - 'EXPERIMENTAL': EXPERIMENTAL, - 'BETA': BETA, - 'STABLE': STABLE, - 'EVERYONE': EVERYONE, - 'DEVELOPER': DEVELOPER, - 'EXPERT': EXPERT, - 'REPORT': REPORT, - 'QUICKREPORT': QUICKREPORT, - 'TOOL': TOOL, - 'IMPORT': IMPORT, - 'EXPORT': EXPORT, - 'DOCGEN': DOCGEN, - 'GENERAL': GENERAL, - 'RULE': RULE, - 'MAPSERVICE': MAPSERVICE, - 'VIEW': VIEW, - 'RELCALC': RELCALC, - 'GRAMPLET': GRAMPLET, - 'SIDEBAR': SIDEBAR, - 'THUMBNAILER': THUMBNAILER, - 'CITE': CITE, - 'CATEGORY_TEXT': CATEGORY_TEXT, - 'CATEGORY_DRAW': CATEGORY_DRAW, - 'CATEGORY_CODE': CATEGORY_CODE, - 'CATEGORY_WEB': CATEGORY_WEB, - 'CATEGORY_BOOK': CATEGORY_BOOK, - 'CATEGORY_GRAPHVIZ': CATEGORY_GRAPHVIZ, - 'CATEGORY_TREE': CATEGORY_TREE, - 'TOOL_DEBUG': TOOL_DEBUG, - 'TOOL_ANAL': TOOL_ANAL, - 'TOOL_DBPROC': TOOL_DBPROC, - 'TOOL_DBFIX': TOOL_DBFIX, - 'TOOL_REVCTL': TOOL_REVCTL, - 'TOOL_UTILS': TOOL_UTILS, - 'CATEGORY_QR_MISC': CATEGORY_QR_MISC, - 'CATEGORY_QR_PERSON': CATEGORY_QR_PERSON, - 'CATEGORY_QR_FAMILY': CATEGORY_QR_FAMILY, - 'CATEGORY_QR_EVENT': CATEGORY_QR_EVENT, - 'CATEGORY_QR_SOURCE': CATEGORY_QR_SOURCE, - 'CATEGORY_QR_CITATION': CATEGORY_QR_CITATION, - 'CATEGORY_QR_SOURCE_OR_CITATION': CATEGORY_QR_SOURCE_OR_CITATION, - 'CATEGORY_QR_PLACE': CATEGORY_QR_PLACE, - 'CATEGORY_QR_MEDIA': CATEGORY_QR_MEDIA, - 'CATEGORY_QR_REPOSITORY': CATEGORY_QR_REPOSITORY, - 'CATEGORY_QR_NOTE': CATEGORY_QR_NOTE, - 'CATEGORY_QR_DATE': CATEGORY_QR_DATE, - 'REPORT_MODE_GUI': REPORT_MODE_GUI, - 'REPORT_MODE_BKI': REPORT_MODE_BKI, - 'REPORT_MODE_CLI': REPORT_MODE_CLI, - 'TOOL_MODE_GUI': TOOL_MODE_GUI, - 'TOOL_MODE_CLI': TOOL_MODE_CLI, - 'DATABASE': DATABASE, - 'GRAMPSVERSION': GRAMPSVERSION, - 'START': START, - 'END': END, - 'IMAGE_DIR': IMAGE_DIR, - } + "newplugin": newplugin, + "register": register, + "UNSTABLE": UNSTABLE, + "EXPERIMENTAL": EXPERIMENTAL, + "BETA": BETA, + "STABLE": STABLE, + "EVERYONE": EVERYONE, + "DEVELOPER": DEVELOPER, + "EXPERT": EXPERT, + "REPORT": REPORT, + "QUICKREPORT": QUICKREPORT, + "TOOL": TOOL, + "IMPORT": IMPORT, + "EXPORT": EXPORT, + "DOCGEN": DOCGEN, + "GENERAL": GENERAL, + "RULE": RULE, + "MAPSERVICE": MAPSERVICE, + "VIEW": VIEW, + "RELCALC": RELCALC, + "GRAMPLET": GRAMPLET, + "SIDEBAR": SIDEBAR, + "THUMBNAILER": THUMBNAILER, + "CITE": CITE, + "CATEGORY_TEXT": CATEGORY_TEXT, + "CATEGORY_DRAW": CATEGORY_DRAW, + "CATEGORY_CODE": CATEGORY_CODE, + "CATEGORY_WEB": CATEGORY_WEB, + "CATEGORY_BOOK": CATEGORY_BOOK, + "CATEGORY_GRAPHVIZ": CATEGORY_GRAPHVIZ, + "CATEGORY_TREE": CATEGORY_TREE, + "TOOL_DEBUG": TOOL_DEBUG, + "TOOL_ANAL": TOOL_ANAL, + "TOOL_DBPROC": TOOL_DBPROC, + "TOOL_DBFIX": TOOL_DBFIX, + "TOOL_REVCTL": TOOL_REVCTL, + "TOOL_UTILS": TOOL_UTILS, + "CATEGORY_QR_MISC": CATEGORY_QR_MISC, + "CATEGORY_QR_PERSON": CATEGORY_QR_PERSON, + "CATEGORY_QR_FAMILY": CATEGORY_QR_FAMILY, + "CATEGORY_QR_EVENT": CATEGORY_QR_EVENT, + "CATEGORY_QR_SOURCE": CATEGORY_QR_SOURCE, + "CATEGORY_QR_CITATION": CATEGORY_QR_CITATION, + "CATEGORY_QR_SOURCE_OR_CITATION": CATEGORY_QR_SOURCE_OR_CITATION, + "CATEGORY_QR_PLACE": CATEGORY_QR_PLACE, + "CATEGORY_QR_MEDIA": CATEGORY_QR_MEDIA, + "CATEGORY_QR_REPOSITORY": CATEGORY_QR_REPOSITORY, + "CATEGORY_QR_NOTE": CATEGORY_QR_NOTE, + "CATEGORY_QR_DATE": CATEGORY_QR_DATE, + "REPORT_MODE_GUI": REPORT_MODE_GUI, + "REPORT_MODE_BKI": REPORT_MODE_BKI, + "REPORT_MODE_CLI": REPORT_MODE_CLI, + "TOOL_MODE_GUI": TOOL_MODE_GUI, + "TOOL_MODE_CLI": TOOL_MODE_CLI, + "DATABASE": DATABASE, + "GRAMPSVERSION": GRAMPSVERSION, + "START": START, + "END": END, + "IMAGE_DIR": IMAGE_DIR, + } env.update(kwargs) return env -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # PluginRegister # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PluginRegister: """ PluginRegister is a Singleton which holds plugin data @@ -1255,21 +1300,24 @@ class PluginRegister: .. attribute : stable_only Bool, include stable plugins only or not. Default True """ + __instance = None def get_instance(): - """ Use this function to get the instance of the PluginRegister """ + """Use this function to get the instance of the PluginRegister""" if PluginRegister.__instance is None: - PluginRegister.__instance = 1 # Set to 1 for __init__() + PluginRegister.__instance = 1 # Set to 1 for __init__() PluginRegister.__instance = PluginRegister() return PluginRegister.__instance + get_instance = staticmethod(get_instance) def __init__(self): - """ This function should only be run once by get_instance() """ + """This function should only be run once by get_instance()""" if PluginRegister.__instance != 1: - raise Exception("This class is a singleton. " - "Use the get_instance() method") + raise Exception( + "This class is a singleton. " "Use the get_instance() method" + ) self.stable_only = True if __debug__: self.stable_only = False @@ -1278,12 +1326,11 @@ def __init__(self): self.__req = Requirements() def add_plugindata(self, plugindata): - """ This is used to add an entry to the registration list. The way it + """This is used to add an entry to the registration list. The way it is used, this entry is not yet filled in, so we cannot use the id to - add to the __id_to_pdata dict at this time. """ + add to the __id_to_pdata dict at this time.""" self.__plugindata.append(plugindata) - def scan_dir(self, dir, filenames, uistate=None): """ The dir name will be scanned for plugin registration code, which will @@ -1305,28 +1352,36 @@ def scan_dir(self, dir, filenames, uistate=None): lenpd = len(self.__plugindata) full_filename = os.path.join(dir, filename) try: - with open(full_filename, "r", encoding='utf-8') as fd: + with open(full_filename, "r", encoding="utf-8") as fd: stream = fd.read() except Exception as msg: - print(_('ERROR: Failed reading plugin registration %(filename)s') % \ - {'filename' : filename}) + print( + _("ERROR: Failed reading plugin registration %(filename)s") + % {"filename": filename} + ) print(msg) continue - if os.path.exists(os.path.join(os.path.dirname(full_filename), - 'locale')): + if os.path.exists(os.path.join(os.path.dirname(full_filename), "locale")): try: local_gettext = glocale.get_addon_translator(full_filename).gettext except ValueError: - print(_('WARNING: Plugin %(plugin_name)s has no translation' - ' for any of your configured languages, using US' - ' English instead') % - {'plugin_name' : filename.split('.')[0] }) + print( + _( + "WARNING: Plugin %(plugin_name)s has no translation" + " for any of your configured languages, using US" + " English instead" + ) + % {"plugin_name": filename.split(".")[0]} + ) local_gettext = glocale.translation.gettext else: local_gettext = glocale.translation.gettext try: - exec (compile(stream, filename, 'exec'), - make_environment(_=local_gettext), {'uistate': uistate}) + exec( + compile(stream, filename, "exec"), + make_environment(_=local_gettext), + {"uistate": uistate}, + ) for pdata in self.__plugindata[lenpd:]: if pdata.id in self.__id_to_pdata: # reloading @@ -1335,33 +1390,42 @@ def scan_dir(self, dir, filenames, uistate=None): lenpd -= 1 self.__id_to_pdata[pdata.id] = pdata except ValueError as msg: - print(_('ERROR: Failed reading plugin registration %(filename)s') % \ - {'filename' : filename}) + print( + _("ERROR: Failed reading plugin registration %(filename)s") + % {"filename": filename} + ) print(msg) self.__plugindata = self.__plugindata[:lenpd] except: - print(_('ERROR: Failed reading plugin registration %(filename)s') % \ - {'filename' : filename}) + print( + _("ERROR: Failed reading plugin registration %(filename)s") + % {"filename": filename} + ) print("".join(traceback.format_exception(*sys.exc_info()))) self.__plugindata = self.__plugindata[:lenpd] - #check if: + # check if: # 1. plugin exists, if not remove, otherwise set module name # 2. plugin not stable, if stable_only=True, remove # 3. TOOL_DEBUG only if __debug__ True rmlist = [] - ind = lenpd-1 + ind = lenpd - 1 for plugin in self.__plugindata[lenpd:]: - #LOG.warning("\nPlugin scanned %s at registration", plugin.id) + # LOG.warning("\nPlugin scanned %s at registration", plugin.id) ind += 1 plugin.directory = dir if not valid_plugin_version(plugin.gramps_target_version): - print(_('ERROR: Plugin file %(filename)s has a version of ' + print( + _( + "ERROR: Plugin file %(filename)s has a version of " '"%(gramps_target_version)s" which is invalid for Gramps ' - '"%(gramps_version)s".' % - {'filename': os.path.join(dir, plugin.fname), - 'gramps_version': GRAMPSVERSION, - 'gramps_target_version': plugin.gramps_target_version,} - )) + '"%(gramps_version)s".' + % { + "filename": os.path.join(dir, plugin.fname), + "gramps_version": GRAMPSVERSION, + "gramps_target_version": plugin.gramps_target_version, + } + ) + ) rmlist.append(ind) continue if not self.__req.check_plugin(plugin): @@ -1370,8 +1434,11 @@ def scan_dir(self, dir, filenames, uistate=None): if not plugin.status == STABLE and self.stable_only: rmlist.append(ind) continue - if plugin.ptype == TOOL and plugin.category == TOOL_DEBUG \ - and not __debug__: + if ( + plugin.ptype == TOOL + and plugin.category == TOOL_DEBUG + and not __debug__ + ): rmlist.append(ind) continue if plugin.fname is None: @@ -1379,24 +1446,34 @@ def scan_dir(self, dir, filenames, uistate=None): match = pymod.match(plugin.fname) if not match: rmlist.append(ind) - print(_('ERROR: Wrong python file %(filename)s in register file ' - '%(regfile)s') % { - 'filename': os.path.join(dir, plugin.fname), - 'regfile': os.path.join(dir, filename) - }) + print( + _( + "ERROR: Wrong python file %(filename)s in register file " + "%(regfile)s" + ) + % { + "filename": os.path.join(dir, plugin.fname), + "regfile": os.path.join(dir, filename), + } + ) continue if not os.path.isfile(os.path.join(dir, plugin.fname)): rmlist.append(ind) - print(_('ERROR: Python file %(filename)s in register file ' - '%(regfile)s does not exist') % { - 'filename': os.path.join(dir, plugin.fname), - 'regfile': os.path.join(dir, filename) - }) + print( + _( + "ERROR: Python file %(filename)s in register file " + "%(regfile)s does not exist" + ) + % { + "filename": os.path.join(dir, plugin.fname), + "regfile": os.path.join(dir, filename), + } + ) continue module = match.groups()[0] plugin.mod_name = module plugin.fpath = dir - #LOG.warning("\nPlugin added %s at registration", plugin.id) + # LOG.warning("\nPlugin added %s at registration", plugin.id) rmlist.reverse() for ind in rmlist: del self.__id_to_pdata[self.__plugindata[ind].id] @@ -1406,7 +1483,7 @@ def get_plugin(self, id): """ Return the :class:`PluginData` for the plugin with id """ - assert(len(self.__id_to_pdata) == len(self.__plugindata)) + assert len(self.__id_to_pdata) == len(self.__plugindata) # if len(self.__id_to_pdata) != len(self.__plugindata): # print(len(self.__id_to_pdata), len(self.__plugindata)) return self.__id_to_pdata.get(id, None) @@ -1424,31 +1501,35 @@ def report_plugins(self, gui=True): :param gui: bool, if True then gui plugin, otherwise cli plugin """ if gui: - return [x for x in self.type_plugins(REPORT) if REPORT_MODE_GUI - in x.report_modes] + return [ + x + for x in self.type_plugins(REPORT) + if REPORT_MODE_GUI in x.report_modes + ] else: - return [x for x in self.type_plugins(REPORT) if REPORT_MODE_CLI - in x.report_modes] + return [ + x + for x in self.type_plugins(REPORT) + if REPORT_MODE_CLI in x.report_modes + ] def tool_plugins(self, gui=True): """ Return a list of :class:`PluginData` that are of type TOOL """ if gui: - return [x for x in self.type_plugins(TOOL) if TOOL_MODE_GUI - in x.tool_modes] + return [x for x in self.type_plugins(TOOL) if TOOL_MODE_GUI in x.tool_modes] else: - return [x for x in self.type_plugins(TOOL) if TOOL_MODE_CLI - in x.tool_modes] - + return [x for x in self.type_plugins(TOOL) if TOOL_MODE_CLI in x.tool_modes] def bookitem_plugins(self): """ Return a list of REPORT :class:`PluginData` that are can be used as bookitem """ - return [x for x in self.type_plugins(REPORT) if REPORT_MODE_BKI - in x.report_modes] + return [ + x for x in self.type_plugins(REPORT) if REPORT_MODE_BKI in x.report_modes + ] def quickreport_plugins(self): """ @@ -1480,8 +1561,7 @@ def general_plugins(self, category=None): """ plugins = self.type_plugins(GENERAL) if category: - return [plugin for plugin in plugins - if plugin.category == category] + return [plugin for plugin in plugins if plugin.category == category] return plugins def mapservice_plugins(self): diff --git a/gramps/gen/plug/_thumbnailer.py b/gramps/gen/plug/_thumbnailer.py index 3728e0a1c8e..71c15671704 100644 --- a/gramps/gen/plug/_thumbnailer.py +++ b/gramps/gen/plug/_thumbnailer.py @@ -22,20 +22,20 @@ 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): """ diff --git a/gramps/gen/plug/docbackend/__init__.py b/gramps/gen/plug/docbackend/__init__.py index 82dd2b9d44c..3eaa3cce918 100644 --- a/gramps/gen/plug/docbackend/__init__.py +++ b/gramps/gen/plug/docbackend/__init__.py @@ -27,4 +27,4 @@ from .docbackend import DocBackendError, DocBackend from .cairobackend import CairoBackend -#__all__ = [ DocBackend, CairoBackend, LaTeXBackend ] +# __all__ = [ DocBackend, CairoBackend, LaTeXBackend ] diff --git a/gramps/gen/plug/docbackend/cairobackend.py b/gramps/gen/plug/docbackend/cairobackend.py index 9fc217271d3..e7e41702d17 100644 --- a/gramps/gen/plug/docbackend/cairobackend.py +++ b/gramps/gen/plug/docbackend/cairobackend.py @@ -21,39 +21,41 @@ """File and File format management for the different reports """ -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Python modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ from xml.sax.saxutils import escape -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # GTK modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Gramps modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ from .docbackend import DocBackend -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Set up logging # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ import logging + LOG = logging.getLogger(".cairobackend.py") -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Document Backend class for cairo docs # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ + class CairoBackend(DocBackend): """ @@ -61,28 +63,29 @@ class CairoBackend(DocBackend): """ STYLETAG_TO_PROPERTY = { - DocBackend.FONTCOLOR : 'foreground', - DocBackend.HIGHLIGHT : 'background', - DocBackend.FONTFACE : 'face', - DocBackend.FONTSIZE : 'size', + DocBackend.FONTCOLOR: "foreground", + DocBackend.HIGHLIGHT: "background", + DocBackend.FONTFACE: "face", + DocBackend.FONTSIZE: "size", } # overwrite base class attributes, they become static var of CairoDoc SUPPORTED_MARKUP = [ - DocBackend.BOLD, - DocBackend.ITALIC, - DocBackend.UNDERLINE, - DocBackend.FONTFACE, - DocBackend.FONTSIZE, - DocBackend.FONTCOLOR, - DocBackend.HIGHLIGHT, - DocBackend.SUPERSCRIPT ] + DocBackend.BOLD, + DocBackend.ITALIC, + DocBackend.UNDERLINE, + DocBackend.FONTFACE, + DocBackend.FONTSIZE, + DocBackend.FONTCOLOR, + DocBackend.HIGHLIGHT, + DocBackend.SUPERSCRIPT, + ] STYLETAG_MARKUP = { - DocBackend.BOLD : ("", ""), - DocBackend.ITALIC : ("", ""), - DocBackend.UNDERLINE : ("", ""), - DocBackend.SUPERSCRIPT : ("", ""), + DocBackend.BOLD: ("", ""), + DocBackend.ITALIC: ("", ""), + DocBackend.UNDERLINE: ("", ""), + DocBackend.SUPERSCRIPT: ("", ""), } ESCAPE_FUNC = lambda x: escape @@ -95,9 +98,11 @@ def _create_xmltag(self, tagtype, value): if tagtype not in self.SUPPORTED_MARKUP: return None if tagtype == DocBackend.FONTSIZE: - #size is in thousandths of a point in pango + # size is in thousandths of a point in pango value = str(1000 * value) - return ('' % (self.STYLETAG_TO_PROPERTY[tagtype], - self.ESCAPE_FUNC()(value)), - '') + return ( + '' + % (self.STYLETAG_TO_PROPERTY[tagtype], self.ESCAPE_FUNC()(value)), + "", + ) diff --git a/gramps/gen/plug/docbackend/docbackend.py b/gramps/gen/plug/docbackend/docbackend.py index 9431d476744..f1394d970f7 100644 --- a/gramps/gen/plug/docbackend/docbackend.py +++ b/gramps/gen/plug/docbackend/docbackend.py @@ -21,27 +21,30 @@ """File and File format management for the different reports """ -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Python modules # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Set up logging # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ import logging + LOG = logging.getLogger(".docbackend.py") -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Functions # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ + def noescape(text): """ @@ -49,13 +52,15 @@ def noescape(text): """ return text -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # DocBackend exception # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class DocBackendError(Exception): """Error used to report docbackend errors.""" + def __init__(self, value=""): Exception.__init__(self) self.value = value @@ -63,11 +68,13 @@ def __init__(self, value=""): def __str__(self): return self.value -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # Document Backend class # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ + class DocBackend: """ @@ -78,6 +85,7 @@ class DocBackend: Specifically for text reports a translation of styled notes to the file format usage is done. """ + BOLD = 0 ITALIC = 1 UNDERLINE = 2 @@ -91,20 +99,19 @@ class DocBackend: SUPPORTED_MARKUP = [] ESCAPE_FUNC = lambda: noescape - #Map between styletypes and internally used values. This map is needed + # Map between styletypes and internally used values. This map is needed # to make TextDoc officially independant of gen.lib.styledtexttag - STYLETYPE_MAP = { - } + STYLETYPE_MAP = {} CLASSMAP = None - #STYLETAGTABLE to store markup for write_markup associated with style tags + # STYLETAGTABLE to store markup for write_markup associated with style tags STYLETAG_MARKUP = { - BOLD : ("", ""), - ITALIC : ("", ""), - UNDERLINE : ("", ""), - SUPERSCRIPT : ("", ""), - LINK : ("", ""), - } + BOLD: ("", ""), + ITALIC: ("", ""), + UNDERLINE: ("", ""), + SUPERSCRIPT: ("", ""), + LINK: ("", ""), + } def __init__(self, filename=None): """ @@ -126,7 +133,7 @@ def setf(self, value): Can only be done if the previous filename is not open. """ if self.__file is not None: - raise ValueError(_('Close file first')) + raise ValueError(_("Close file first")) self._filename = value filename = property(getf, setf, None, "The filename the backend works on") @@ -136,10 +143,11 @@ def open(self): Opens the document. """ if self.filename is None: - raise DocBackendError(_('No filename given')) - if self.__file is not None : - raise DocBackendError(_('File %s already open, close it first.') - % self.filename) + raise DocBackendError(_("No filename given")) + if self.__file is not None: + raise DocBackendError( + _("File %s already open, close it first.") % self.filename + ) self._checkfilename() try: self.__file = open(self.filename, "w", encoding="utf-8") @@ -160,7 +168,7 @@ def close(self): Closes the file that is written on. """ if self.__file is None: - raise IOError('No file open') + raise IOError("No file open") self.__file.close() self.__file = None @@ -189,7 +197,6 @@ def escape(self, preformatted=False): """ return self.ESCAPE_FUNC() - def find_tag_by_stag(self, s_tag): """ :param s_tag: object: assumed styledtexttag @@ -204,8 +211,7 @@ def find_tag_by_stag(self, s_tag): """ tagtype = s_tag.name - if not self.STYLETYPE_MAP or \ - self.CLASSMAP != tagtype.__class__.__name__ : + if not self.STYLETYPE_MAP or self.CLASSMAP != tagtype.__class__.__name__: self.CLASSMAP = tagtype.__class__.__name__ self.STYLETYPE_MAP[tagtype.BOLD] = self.BOLD self.STYLETYPE_MAP[tagtype.ITALIC] = self.ITALIC @@ -234,7 +240,7 @@ def find_tag_by_stag(self, s_tag): tags = self.STYLETAG_MARKUP.get(tag_name) if tags is not None: return tags - #no tag known yet, create the markup, add to lookup, and return + # no tag known yet, create the markup, add to lookup, and return tags = self._create_xmltag(self.STYLETYPE_MAP[typeval], s_tagvalue) self.STYLETAG_MARKUP[tag_name] = tags return tags @@ -246,9 +252,9 @@ def _create_xmltag(self, tagtype, value): """ if tagtype not in self.SUPPORTED_MARKUP: return None - return ('', '') + return ("", "") - def add_markup_from_styled(self, text, s_tags, split='', escape=True): + def add_markup_from_styled(self, text, s_tags, split="", escape=True): """ Input is plain text, output is text with markup added according to the s_tags which are assumed to be styledtexttags. @@ -275,7 +281,7 @@ def add_markup_from_styled(self, text, s_tags, split='', escape=True): if not escape: escape_func = self.ESCAPE_FUNC self.ESCAPE_FUNC = lambda: (lambda text: text) - #unicode text must be sliced correctly + # unicode text must be sliced correctly text = str(text) FIRST = 0 LAST = 1 @@ -283,7 +289,7 @@ def add_markup_from_styled(self, text, s_tags, split='', escape=True): for s_tag in s_tags: tag = self.find_tag_by_stag(s_tag) if tag is not None: - for (start, end) in s_tag.ranges: + for start, end in s_tag.ranges: if start in tagspos: tagspos[start] += [(tag, FIRST)] else: @@ -298,66 +304,69 @@ def add_markup_from_styled(self, text, s_tags, split='', escape=True): keylist.sort() keylist = [x for x in keylist if x <= len(text)] opentags = [] - otext = "" #the output, text with markup + otext = "" # the output, text with markup lensplit = len(split) for pos in keylist: - #write text up to tag + # write text up to tag if pos > start: if split: - #make sure text can split + # make sure text can split splitpos = text[start:pos].find(split) while splitpos != -1: - otext += self.ESCAPE_FUNC()(text[start:start+splitpos]) - #close open tags + otext += self.ESCAPE_FUNC()(text[start : start + splitpos]) + # close open tags for opentag in reversed(opentags): otext += opentag[1] - #add split text + # add split text otext += self.ESCAPE_FUNC()(split) - #open the tags again + # open the tags again for opentag in opentags: otext += opentag[0] - #obtain new values + # obtain new values start = start + splitpos + lensplit splitpos = text[start:pos].find(split) otext += self.ESCAPE_FUNC()(text[start:pos]) - #write out tags + # write out tags for tag in tagspos[pos]: - #close open tags starting from last open + # close open tags starting from last open for opentag in reversed(opentags): otext += opentag[1] - #if start, add to opentag in beginning as first to open + # if start, add to opentag in beginning as first to open if tag[1] == FIRST: opentags = [tag[0]] + opentags else: - #end tag, is closed already, remove from opentag - opentags = [x for x in opentags if not x == tag[0] ] - #now all tags are closed, open the ones that should open + # end tag, is closed already, remove from opentag + opentags = [x for x in opentags if not x == tag[0]] + # now all tags are closed, open the ones that should open for opentag in opentags: otext += opentag[0] start = pos - #add remainder of text, no markup present there if all is correct + # add remainder of text, no markup present there if all is correct if opentags: # a problem, we don't have a closing tag left but there are open # tags. Just keep them up to end of text pos = len(text) - print('WARNING: DocBackend : More style tags in text than length '\ - 'of text allows.\n', opentags) + print( + "WARNING: DocBackend : More style tags in text than length " + "of text allows.\n", + opentags, + ) if pos > start: if split: - #make sure text can split + # make sure text can split splitpos = text[start:pos].find(split) while splitpos != -1: - otext += self.ESCAPE_FUNC()(text[start:start+splitpos]) - #close open tags + otext += self.ESCAPE_FUNC()(text[start : start + splitpos]) + # close open tags for opentag in reversed(opentags): otext += opentag[1] - #add split text + # add split text otext += self.ESCAPE_FUNC()(split) - #open the tags again + # open the tags again for opentag in opentags: otext += opentag[0] - #obtain new values + # obtain new values start = start + splitpos + lensplit splitpos = text[start:pos].find(split) @@ -378,4 +387,3 @@ def format_link(self, value): """ return self.STYLETAG_MARKUP[DocBackend.UNDERLINE] - diff --git a/gramps/gen/plug/docgen/__init__.py b/gramps/gen/plug/docgen/__init__.py index a6fd37ca113..07a3351d4e8 100644 --- a/gramps/gen/plug/docgen/__init__.py +++ b/gramps/gen/plug/docgen/__init__.py @@ -28,13 +28,25 @@ from .basedoc import BaseDoc from .paperstyle import PaperSize, PaperStyle, PAPER_PORTRAIT, PAPER_LANDSCAPE from .fontstyle import FontStyle, FONT_SANS_SERIF, FONT_SERIF, FONT_MONOSPACE -from .paragraphstyle import ParagraphStyle, PARA_ALIGN_CENTER, PARA_ALIGN_LEFT,\ - PARA_ALIGN_RIGHT, PARA_ALIGN_JUSTIFY +from .paragraphstyle import ( + ParagraphStyle, + PARA_ALIGN_CENTER, + PARA_ALIGN_LEFT, + PARA_ALIGN_RIGHT, + PARA_ALIGN_JUSTIFY, +) from .tablestyle import TableStyle, TableCellStyle from .stylesheet import StyleSheetList, StyleSheet, SheetParser from .graphicstyle import GraphicsStyle, SOLID, DASHED, DOTTED -from .textdoc import TextDoc, IndexMark,INDEX_TYPE_ALP, INDEX_TYPE_TOC,\ - URL_PATTERN, LOCAL_HYPERLINK, LOCAL_TARGET +from .textdoc import ( + TextDoc, + IndexMark, + INDEX_TYPE_ALP, + INDEX_TYPE_TOC, + URL_PATTERN, + LOCAL_HYPERLINK, + LOCAL_TARGET, +) from .drawdoc import DrawDoc from .graphdoc import GVDoc from .treedoc import TreeDoc diff --git a/gramps/gen/plug/docgen/basedoc.py b/gramps/gen/plug/docgen/basedoc.py index a82d8e2ba47..0886e14d650 100644 --- a/gramps/gen/plug/docgen/basedoc.py +++ b/gramps/gen/plug/docgen/basedoc.py @@ -28,39 +28,42 @@ interfaces should be derived from the core classes. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from abc import ABCMeta, abstractmethod -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .stylesheet import StyleSheet -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + log = logging.getLogger(".basedoc") -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # BaseDoc # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class BaseDoc(metaclass=ABCMeta): """ Base class for document generators. Different output formats, such as OpenOffice, AbiWord, and LaTeX are derived from this base class, providing a common interface to all document generators. """ + def __init__(self, styles, paper_style, track=[], uistate=None): """ Create a BaseDoc instance, which provides a document generation @@ -79,7 +82,7 @@ def __init__(self, styles, paper_style, track=[], uistate=None): self._creator = "" self.init_called = False self.uistate = uistate - self._rtl_doc = False # does the document have right-to-left text? + self._rtl_doc = False # does the document have right-to-left text? def set_rtl_doc(self, value): self._rtl_doc = value diff --git a/gramps/gen/plug/docgen/drawdoc.py b/gramps/gen/plug/docgen/drawdoc.py index afbdb95c334..d6acf02034d 100644 --- a/gramps/gen/plug/docgen/drawdoc.py +++ b/gramps/gen/plug/docgen/drawdoc.py @@ -24,33 +24,35 @@ # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from abc import ABCMeta, abstractmethod -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import fontscale -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + log = logging.getLogger(".drawdoc") -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # DrawDoc # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class DrawDoc(metaclass=ABCMeta): """ Abstract Interface for graphical document generators. Output formats diff --git a/gramps/gen/plug/docgen/fontscale.py b/gramps/gen/plug/docgen/fontscale.py index 93b57b3fe66..855a4c931e6 100644 --- a/gramps/gen/plug/docgen/fontscale.py +++ b/gramps/gen/plug/docgen/fontscale.py @@ -24,237 +24,2085 @@ """ SWISS = [ -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.278, 0.278, 0.355, 0.556, 0.556, 0.889, 0.667, 0.191, -0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278, 0.556, 0.556, -0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, -0.584, 0.584, 0.584, 0.556, 1.015, 0.667, 0.667, 0.722, 0.722, 0.667, -0.611, 0.778, 0.722, 0.278, 0.500, 0.667, 0.556, 0.833, 0.722, 0.778, -0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944, 0.667, 0.667, -0.611, 0.278, 0.278, 0.278, 0.469, 0.556, 0.333, 0.556, 0.556, 0.500, -0.556, 0.556, 0.278, 0.556, 0.556, 0.222, 0.222, 0.500, 0.222, 0.833, -0.556, 0.556, 0.556, 0.556, 0.333, 0.500, 0.278, 0.556, 0.500, 0.722, -0.500, 0.500, 0.500, 0.334, 0.260, 0.334, 0.584, 0.350, 0.556, 0.350, -0.222, 0.556, 0.333, 1.000, 0.556, 0.556, 0.333, 1.000, 0.667, 0.333, -1.000, 0.350, 0.611, 0.350, 0.350, 0.222, 0.222, 0.333, 0.333, 0.350, -0.556, 1.000, 0.333, 1.000, 0.500, 0.333, 0.944, 0.350, 0.500, 0.667, -0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.260, 0.556, 0.333, 0.737, -0.370, 0.556, 0.584, 0.333, 0.737, 0.333, 0.400, 0.584, 0.333, 0.333, -0.333, 0.556, 0.537, 0.278, 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, -0.834, 0.611, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 1.000, 0.722, -0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278, 0.722, 0.722, -0.778, 0.778, 0.778, 0.778, 0.778, 0.584, 0.778, 0.722, 0.722, 0.722, -0.722, 0.667, 0.667, 0.611, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, -0.889, 0.500, 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278, -0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.584, 0.611, 0.556, -0.556, 0.556, 0.556, 0.500, 0.556, 0.500] + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.278, + 0.278, + 0.355, + 0.556, + 0.556, + 0.889, + 0.667, + 0.191, + 0.333, + 0.333, + 0.389, + 0.584, + 0.278, + 0.333, + 0.278, + 0.278, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.278, + 0.278, + 0.584, + 0.584, + 0.584, + 0.556, + 1.015, + 0.667, + 0.667, + 0.722, + 0.722, + 0.667, + 0.611, + 0.778, + 0.722, + 0.278, + 0.500, + 0.667, + 0.556, + 0.833, + 0.722, + 0.778, + 0.667, + 0.778, + 0.722, + 0.667, + 0.611, + 0.722, + 0.667, + 0.944, + 0.667, + 0.667, + 0.611, + 0.278, + 0.278, + 0.278, + 0.469, + 0.556, + 0.333, + 0.556, + 0.556, + 0.500, + 0.556, + 0.556, + 0.278, + 0.556, + 0.556, + 0.222, + 0.222, + 0.500, + 0.222, + 0.833, + 0.556, + 0.556, + 0.556, + 0.556, + 0.333, + 0.500, + 0.278, + 0.556, + 0.500, + 0.722, + 0.500, + 0.500, + 0.500, + 0.334, + 0.260, + 0.334, + 0.584, + 0.350, + 0.556, + 0.350, + 0.222, + 0.556, + 0.333, + 1.000, + 0.556, + 0.556, + 0.333, + 1.000, + 0.667, + 0.333, + 1.000, + 0.350, + 0.611, + 0.350, + 0.350, + 0.222, + 0.222, + 0.333, + 0.333, + 0.350, + 0.556, + 1.000, + 0.333, + 1.000, + 0.500, + 0.333, + 0.944, + 0.350, + 0.500, + 0.667, + 0.278, + 0.333, + 0.556, + 0.556, + 0.556, + 0.556, + 0.260, + 0.556, + 0.333, + 0.737, + 0.370, + 0.556, + 0.584, + 0.333, + 0.737, + 0.333, + 0.400, + 0.584, + 0.333, + 0.333, + 0.333, + 0.556, + 0.537, + 0.278, + 0.333, + 0.333, + 0.365, + 0.556, + 0.834, + 0.834, + 0.834, + 0.611, + 0.667, + 0.667, + 0.667, + 0.667, + 0.667, + 0.667, + 1.000, + 0.722, + 0.667, + 0.667, + 0.667, + 0.667, + 0.278, + 0.278, + 0.278, + 0.278, + 0.722, + 0.722, + 0.778, + 0.778, + 0.778, + 0.778, + 0.778, + 0.584, + 0.778, + 0.722, + 0.722, + 0.722, + 0.722, + 0.667, + 0.667, + 0.611, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.889, + 0.500, + 0.556, + 0.556, + 0.556, + 0.556, + 0.278, + 0.278, + 0.278, + 0.278, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.584, + 0.611, + 0.556, + 0.556, + 0.556, + 0.556, + 0.500, + 0.556, + 0.500, +] SWISS_B = [ -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.278, 0.333, 0.474, 0.556, 0.556, 0.889, 0.722, 0.238, -0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278, 0.556, 0.556, -0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.333, 0.333, -0.584, 0.584, 0.584, 0.611, 0.975, 0.722, 0.722, 0.722, 0.722, 0.667, -0.611, 0.778, 0.722, 0.278, 0.556, 0.722, 0.611, 0.833, 0.722, 0.778, -0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944, 0.667, 0.667, -0.611, 0.333, 0.278, 0.333, 0.584, 0.556, 0.333, 0.556, 0.611, 0.556, -0.611, 0.556, 0.333, 0.611, 0.611, 0.278, 0.278, 0.556, 0.278, 0.889, -0.611, 0.611, 0.611, 0.611, 0.389, 0.556, 0.333, 0.611, 0.556, 0.778, -0.556, 0.556, 0.500, 0.389, 0.280, 0.389, 0.584, 0.350, 0.556, 0.350, -0.278, 0.556, 0.500, 1.000, 0.556, 0.556, 0.333, 1.000, 0.667, 0.333, -1.000, 0.350, 0.611, 0.350, 0.350, 0.278, 0.278, 0.500, 0.500, 0.350, -0.556, 1.000, 0.333, 1.000, 0.556, 0.333, 0.944, 0.350, 0.500, 0.667, -0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.280, 0.556, 0.333, 0.737, -0.370, 0.556, 0.584, 0.333, 0.737, 0.333, 0.400, 0.584, 0.333, 0.333, -0.333, 0.611, 0.556, 0.278, 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, -0.834, 0.611, 0.722, 0.722, 0.722, 0.722, 0.722, 0.722, 1.000, 0.722, -0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278, 0.722, 0.722, -0.778, 0.778, 0.778, 0.778, 0.778, 0.584, 0.778, 0.722, 0.722, 0.722, -0.722, 0.667, 0.667, 0.611, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, -0.889, 0.556, 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278, -0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.584, 0.611, 0.611, -0.611, 0.611, 0.611, 0.556, 0.611, 0.556] + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.278, + 0.333, + 0.474, + 0.556, + 0.556, + 0.889, + 0.722, + 0.238, + 0.333, + 0.333, + 0.389, + 0.584, + 0.278, + 0.333, + 0.278, + 0.278, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.333, + 0.333, + 0.584, + 0.584, + 0.584, + 0.611, + 0.975, + 0.722, + 0.722, + 0.722, + 0.722, + 0.667, + 0.611, + 0.778, + 0.722, + 0.278, + 0.556, + 0.722, + 0.611, + 0.833, + 0.722, + 0.778, + 0.667, + 0.778, + 0.722, + 0.667, + 0.611, + 0.722, + 0.667, + 0.944, + 0.667, + 0.667, + 0.611, + 0.333, + 0.278, + 0.333, + 0.584, + 0.556, + 0.333, + 0.556, + 0.611, + 0.556, + 0.611, + 0.556, + 0.333, + 0.611, + 0.611, + 0.278, + 0.278, + 0.556, + 0.278, + 0.889, + 0.611, + 0.611, + 0.611, + 0.611, + 0.389, + 0.556, + 0.333, + 0.611, + 0.556, + 0.778, + 0.556, + 0.556, + 0.500, + 0.389, + 0.280, + 0.389, + 0.584, + 0.350, + 0.556, + 0.350, + 0.278, + 0.556, + 0.500, + 1.000, + 0.556, + 0.556, + 0.333, + 1.000, + 0.667, + 0.333, + 1.000, + 0.350, + 0.611, + 0.350, + 0.350, + 0.278, + 0.278, + 0.500, + 0.500, + 0.350, + 0.556, + 1.000, + 0.333, + 1.000, + 0.556, + 0.333, + 0.944, + 0.350, + 0.500, + 0.667, + 0.278, + 0.333, + 0.556, + 0.556, + 0.556, + 0.556, + 0.280, + 0.556, + 0.333, + 0.737, + 0.370, + 0.556, + 0.584, + 0.333, + 0.737, + 0.333, + 0.400, + 0.584, + 0.333, + 0.333, + 0.333, + 0.611, + 0.556, + 0.278, + 0.333, + 0.333, + 0.365, + 0.556, + 0.834, + 0.834, + 0.834, + 0.611, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 1.000, + 0.722, + 0.667, + 0.667, + 0.667, + 0.667, + 0.278, + 0.278, + 0.278, + 0.278, + 0.722, + 0.722, + 0.778, + 0.778, + 0.778, + 0.778, + 0.778, + 0.584, + 0.778, + 0.722, + 0.722, + 0.722, + 0.722, + 0.667, + 0.667, + 0.611, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.889, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.278, + 0.278, + 0.278, + 0.278, + 0.611, + 0.611, + 0.611, + 0.611, + 0.611, + 0.611, + 0.611, + 0.584, + 0.611, + 0.611, + 0.611, + 0.611, + 0.611, + 0.556, + 0.611, + 0.556, +] SWISS_I = [ -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.278, 0.278, 0.355, 0.556, 0.556, 0.889, 0.667, 0.191, -0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278, 0.556, 0.556, -0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, -0.584, 0.584, 0.584, 0.556, 1.015, 0.667, 0.667, 0.722, 0.722, 0.667, -0.611, 0.778, 0.722, 0.278, 0.500, 0.667, 0.556, 0.833, 0.722, 0.778, -0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944, 0.667, 0.667, -0.611, 0.278, 0.278, 0.278, 0.469, 0.556, 0.333, 0.556, 0.556, 0.500, -0.556, 0.556, 0.278, 0.556, 0.556, 0.222, 0.222, 0.500, 0.222, 0.833, -0.556, 0.556, 0.556, 0.556, 0.333, 0.500, 0.278, 0.556, 0.500, 0.722, -0.500, 0.500, 0.500, 0.334, 0.260, 0.334, 0.584, 0.350, 0.556, 0.350, -0.222, 0.556, 0.333, 1.000, 0.556, 0.556, 0.333, 1.000, 0.667, 0.333, -1.000, 0.350, 0.611, 0.350, 0.350, 0.222, 0.222, 0.333, 0.333, 0.350, -0.556, 1.000, 0.333, 1.000, 0.500, 0.333, 0.944, 0.350, 0.500, 0.667, -0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.260, 0.556, 0.333, 0.737, -0.370, 0.556, 0.584, 0.333, 0.737, 0.333, 0.400, 0.584, 0.333, 0.333, -0.333, 0.556, 0.537, 0.278, 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, -0.834, 0.611, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 1.000, 0.722, -0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278, 0.722, 0.722, -0.778, 0.778, 0.778, 0.778, 0.778, 0.584, 0.778, 0.722, 0.722, 0.722, -0.722, 0.667, 0.667, 0.611, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, -0.889, 0.500, 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278, -0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.584, 0.611, 0.556, -0.556, 0.556, 0.556, 0.500, 0.556, 0.500] + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.278, + 0.278, + 0.355, + 0.556, + 0.556, + 0.889, + 0.667, + 0.191, + 0.333, + 0.333, + 0.389, + 0.584, + 0.278, + 0.333, + 0.278, + 0.278, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.278, + 0.278, + 0.584, + 0.584, + 0.584, + 0.556, + 1.015, + 0.667, + 0.667, + 0.722, + 0.722, + 0.667, + 0.611, + 0.778, + 0.722, + 0.278, + 0.500, + 0.667, + 0.556, + 0.833, + 0.722, + 0.778, + 0.667, + 0.778, + 0.722, + 0.667, + 0.611, + 0.722, + 0.667, + 0.944, + 0.667, + 0.667, + 0.611, + 0.278, + 0.278, + 0.278, + 0.469, + 0.556, + 0.333, + 0.556, + 0.556, + 0.500, + 0.556, + 0.556, + 0.278, + 0.556, + 0.556, + 0.222, + 0.222, + 0.500, + 0.222, + 0.833, + 0.556, + 0.556, + 0.556, + 0.556, + 0.333, + 0.500, + 0.278, + 0.556, + 0.500, + 0.722, + 0.500, + 0.500, + 0.500, + 0.334, + 0.260, + 0.334, + 0.584, + 0.350, + 0.556, + 0.350, + 0.222, + 0.556, + 0.333, + 1.000, + 0.556, + 0.556, + 0.333, + 1.000, + 0.667, + 0.333, + 1.000, + 0.350, + 0.611, + 0.350, + 0.350, + 0.222, + 0.222, + 0.333, + 0.333, + 0.350, + 0.556, + 1.000, + 0.333, + 1.000, + 0.500, + 0.333, + 0.944, + 0.350, + 0.500, + 0.667, + 0.278, + 0.333, + 0.556, + 0.556, + 0.556, + 0.556, + 0.260, + 0.556, + 0.333, + 0.737, + 0.370, + 0.556, + 0.584, + 0.333, + 0.737, + 0.333, + 0.400, + 0.584, + 0.333, + 0.333, + 0.333, + 0.556, + 0.537, + 0.278, + 0.333, + 0.333, + 0.365, + 0.556, + 0.834, + 0.834, + 0.834, + 0.611, + 0.667, + 0.667, + 0.667, + 0.667, + 0.667, + 0.667, + 1.000, + 0.722, + 0.667, + 0.667, + 0.667, + 0.667, + 0.278, + 0.278, + 0.278, + 0.278, + 0.722, + 0.722, + 0.778, + 0.778, + 0.778, + 0.778, + 0.778, + 0.584, + 0.778, + 0.722, + 0.722, + 0.722, + 0.722, + 0.667, + 0.667, + 0.611, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.889, + 0.500, + 0.556, + 0.556, + 0.556, + 0.556, + 0.278, + 0.278, + 0.278, + 0.278, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.584, + 0.611, + 0.556, + 0.556, + 0.556, + 0.556, + 0.500, + 0.556, + 0.500, +] SWISS_BI = [ -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.278, 0.333, 0.474, 0.556, 0.556, 0.889, 0.722, 0.238, -0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278, 0.556, 0.556, -0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.333, 0.333, -0.584, 0.584, 0.584, 0.611, 0.975, 0.722, 0.722, 0.722, 0.722, 0.667, -0.611, 0.778, 0.722, 0.278, 0.556, 0.722, 0.611, 0.833, 0.722, 0.778, -0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944, 0.667, 0.667, -0.611, 0.333, 0.278, 0.333, 0.584, 0.556, 0.333, 0.556, 0.611, 0.556, -0.611, 0.556, 0.333, 0.611, 0.611, 0.278, 0.278, 0.556, 0.278, 0.889, -0.611, 0.611, 0.611, 0.611, 0.389, 0.556, 0.333, 0.611, 0.556, 0.778, -0.556, 0.556, 0.500, 0.389, 0.280, 0.389, 0.584, 0.350, 0.556, 0.350, -0.278, 0.556, 0.500, 1.000, 0.556, 0.556, 0.333, 1.000, 0.667, 0.333, -1.000, 0.350, 0.611, 0.350, 0.350, 0.278, 0.278, 0.500, 0.500, 0.350, -0.556, 1.000, 0.333, 1.000, 0.556, 0.333, 0.944, 0.350, 0.500, 0.667, -0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.280, 0.556, 0.333, 0.737, -0.370, 0.556, 0.584, 0.333, 0.737, 0.333, 0.400, 0.584, 0.333, 0.333, -0.333, 0.611, 0.556, 0.278, 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, -0.834, 0.611, 0.722, 0.722, 0.722, 0.722, 0.722, 0.722, 1.000, 0.722, -0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278, 0.722, 0.722, -0.778, 0.778, 0.778, 0.778, 0.778, 0.584, 0.778, 0.722, 0.722, 0.722, -0.722, 0.667, 0.667, 0.611, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, -0.889, 0.556, 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278, -0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.584, 0.611, 0.611, -0.611, 0.611, 0.611, 0.556, 0.611, 0.556] + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.278, + 0.333, + 0.474, + 0.556, + 0.556, + 0.889, + 0.722, + 0.238, + 0.333, + 0.333, + 0.389, + 0.584, + 0.278, + 0.333, + 0.278, + 0.278, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.333, + 0.333, + 0.584, + 0.584, + 0.584, + 0.611, + 0.975, + 0.722, + 0.722, + 0.722, + 0.722, + 0.667, + 0.611, + 0.778, + 0.722, + 0.278, + 0.556, + 0.722, + 0.611, + 0.833, + 0.722, + 0.778, + 0.667, + 0.778, + 0.722, + 0.667, + 0.611, + 0.722, + 0.667, + 0.944, + 0.667, + 0.667, + 0.611, + 0.333, + 0.278, + 0.333, + 0.584, + 0.556, + 0.333, + 0.556, + 0.611, + 0.556, + 0.611, + 0.556, + 0.333, + 0.611, + 0.611, + 0.278, + 0.278, + 0.556, + 0.278, + 0.889, + 0.611, + 0.611, + 0.611, + 0.611, + 0.389, + 0.556, + 0.333, + 0.611, + 0.556, + 0.778, + 0.556, + 0.556, + 0.500, + 0.389, + 0.280, + 0.389, + 0.584, + 0.350, + 0.556, + 0.350, + 0.278, + 0.556, + 0.500, + 1.000, + 0.556, + 0.556, + 0.333, + 1.000, + 0.667, + 0.333, + 1.000, + 0.350, + 0.611, + 0.350, + 0.350, + 0.278, + 0.278, + 0.500, + 0.500, + 0.350, + 0.556, + 1.000, + 0.333, + 1.000, + 0.556, + 0.333, + 0.944, + 0.350, + 0.500, + 0.667, + 0.278, + 0.333, + 0.556, + 0.556, + 0.556, + 0.556, + 0.280, + 0.556, + 0.333, + 0.737, + 0.370, + 0.556, + 0.584, + 0.333, + 0.737, + 0.333, + 0.400, + 0.584, + 0.333, + 0.333, + 0.333, + 0.611, + 0.556, + 0.278, + 0.333, + 0.333, + 0.365, + 0.556, + 0.834, + 0.834, + 0.834, + 0.611, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 1.000, + 0.722, + 0.667, + 0.667, + 0.667, + 0.667, + 0.278, + 0.278, + 0.278, + 0.278, + 0.722, + 0.722, + 0.778, + 0.778, + 0.778, + 0.778, + 0.778, + 0.584, + 0.778, + 0.722, + 0.722, + 0.722, + 0.722, + 0.667, + 0.667, + 0.611, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.889, + 0.556, + 0.556, + 0.556, + 0.556, + 0.556, + 0.278, + 0.278, + 0.278, + 0.278, + 0.611, + 0.611, + 0.611, + 0.611, + 0.611, + 0.611, + 0.611, + 0.584, + 0.611, + 0.611, + 0.611, + 0.611, + 0.611, + 0.556, + 0.611, + 0.556, +] ROMAN = [ -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.250, 0.333, 0.408, 0.500, 0.500, 0.833, 0.778, 0.180, -0.333, 0.333, 0.500, 0.564, 0.250, 0.333, 0.250, 0.278, 0.500, 0.500, -0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.278, 0.278, -0.564, 0.564, 0.564, 0.444, 0.921, 0.722, 0.667, 0.667, 0.722, 0.611, -0.556, 0.722, 0.722, 0.333, 0.389, 0.722, 0.611, 0.889, 0.722, 0.722, -0.556, 0.722, 0.667, 0.556, 0.611, 0.722, 0.722, 0.944, 0.722, 0.722, -0.611, 0.333, 0.278, 0.333, 0.469, 0.500, 0.333, 0.444, 0.500, 0.444, -0.500, 0.444, 0.333, 0.500, 0.500, 0.278, 0.278, 0.500, 0.278, 0.778, -0.500, 0.500, 0.500, 0.500, 0.333, 0.389, 0.278, 0.500, 0.500, 0.722, -0.500, 0.500, 0.444, 0.480, 0.200, 0.480, 0.541, 0.350, 0.500, 0.350, -0.333, 0.500, 0.444, 1.000, 0.500, 0.500, 0.333, 1.000, 0.556, 0.333, -0.889, 0.350, 0.611, 0.350, 0.350, 0.333, 0.333, 0.444, 0.444, 0.350, -0.500, 1.000, 0.333, 0.980, 0.389, 0.333, 0.722, 0.350, 0.444, 0.722, -0.250, 0.333, 0.500, 0.500, 0.500, 0.500, 0.200, 0.500, 0.333, 0.760, -0.276, 0.500, 0.564, 0.333, 0.760, 0.333, 0.400, 0.564, 0.300, 0.300, -0.333, 0.500, 0.453, 0.250, 0.333, 0.300, 0.310, 0.500, 0.750, 0.750, -0.750, 0.444, 0.722, 0.722, 0.722, 0.722, 0.722, 0.722, 0.889, 0.667, -0.611, 0.611, 0.611, 0.611, 0.333, 0.333, 0.333, 0.333, 0.722, 0.722, -0.722, 0.722, 0.722, 0.722, 0.722, 0.564, 0.722, 0.722, 0.722, 0.722, -0.722, 0.722, 0.556, 0.500, 0.444, 0.444, 0.444, 0.444, 0.444, 0.444, -0.667, 0.444, 0.444, 0.444, 0.444, 0.444, 0.278, 0.278, 0.278, 0.278, -0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.564, 0.500, 0.500, -0.500, 0.500, 0.500, 0.500, 0.500, 0.500] + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.250, + 0.333, + 0.408, + 0.500, + 0.500, + 0.833, + 0.778, + 0.180, + 0.333, + 0.333, + 0.500, + 0.564, + 0.250, + 0.333, + 0.250, + 0.278, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.278, + 0.278, + 0.564, + 0.564, + 0.564, + 0.444, + 0.921, + 0.722, + 0.667, + 0.667, + 0.722, + 0.611, + 0.556, + 0.722, + 0.722, + 0.333, + 0.389, + 0.722, + 0.611, + 0.889, + 0.722, + 0.722, + 0.556, + 0.722, + 0.667, + 0.556, + 0.611, + 0.722, + 0.722, + 0.944, + 0.722, + 0.722, + 0.611, + 0.333, + 0.278, + 0.333, + 0.469, + 0.500, + 0.333, + 0.444, + 0.500, + 0.444, + 0.500, + 0.444, + 0.333, + 0.500, + 0.500, + 0.278, + 0.278, + 0.500, + 0.278, + 0.778, + 0.500, + 0.500, + 0.500, + 0.500, + 0.333, + 0.389, + 0.278, + 0.500, + 0.500, + 0.722, + 0.500, + 0.500, + 0.444, + 0.480, + 0.200, + 0.480, + 0.541, + 0.350, + 0.500, + 0.350, + 0.333, + 0.500, + 0.444, + 1.000, + 0.500, + 0.500, + 0.333, + 1.000, + 0.556, + 0.333, + 0.889, + 0.350, + 0.611, + 0.350, + 0.350, + 0.333, + 0.333, + 0.444, + 0.444, + 0.350, + 0.500, + 1.000, + 0.333, + 0.980, + 0.389, + 0.333, + 0.722, + 0.350, + 0.444, + 0.722, + 0.250, + 0.333, + 0.500, + 0.500, + 0.500, + 0.500, + 0.200, + 0.500, + 0.333, + 0.760, + 0.276, + 0.500, + 0.564, + 0.333, + 0.760, + 0.333, + 0.400, + 0.564, + 0.300, + 0.300, + 0.333, + 0.500, + 0.453, + 0.250, + 0.333, + 0.300, + 0.310, + 0.500, + 0.750, + 0.750, + 0.750, + 0.444, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.889, + 0.667, + 0.611, + 0.611, + 0.611, + 0.611, + 0.333, + 0.333, + 0.333, + 0.333, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.564, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.556, + 0.500, + 0.444, + 0.444, + 0.444, + 0.444, + 0.444, + 0.444, + 0.667, + 0.444, + 0.444, + 0.444, + 0.444, + 0.444, + 0.278, + 0.278, + 0.278, + 0.278, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.564, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, +] ROMAN_B = [ -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.250, 0.333, 0.555, 0.500, 0.500, 1.000, 0.833, 0.278, -0.333, 0.333, 0.500, 0.570, 0.250, 0.333, 0.250, 0.278, 0.500, 0.500, -0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.333, 0.333, -0.570, 0.570, 0.570, 0.500, 0.930, 0.722, 0.667, 0.722, 0.722, 0.667, -0.611, 0.778, 0.778, 0.389, 0.500, 0.778, 0.667, 0.944, 0.722, 0.778, -0.611, 0.778, 0.722, 0.556, 0.667, 0.722, 0.722, 1.000, 0.722, 0.722, -0.667, 0.333, 0.278, 0.333, 0.581, 0.500, 0.333, 0.500, 0.556, 0.444, -0.556, 0.444, 0.333, 0.500, 0.556, 0.278, 0.333, 0.556, 0.278, 0.833, -0.556, 0.500, 0.556, 0.556, 0.444, 0.389, 0.333, 0.556, 0.500, 0.722, -0.500, 0.500, 0.444, 0.394, 0.220, 0.394, 0.520, 0.350, 0.500, 0.350, -0.333, 0.500, 0.500, 1.000, 0.500, 0.500, 0.333, 1.000, 0.556, 0.333, -1.000, 0.350, 0.667, 0.350, 0.350, 0.333, 0.333, 0.500, 0.500, 0.350, -0.500, 1.000, 0.333, 1.000, 0.389, 0.333, 0.722, 0.350, 0.444, 0.722, -0.250, 0.333, 0.500, 0.500, 0.500, 0.500, 0.220, 0.500, 0.333, 0.747, -0.300, 0.500, 0.570, 0.333, 0.747, 0.333, 0.400, 0.570, 0.300, 0.300, -0.333, 0.556, 0.540, 0.250, 0.333, 0.300, 0.330, 0.500, 0.750, 0.750, -0.750, 0.500, 0.722, 0.722, 0.722, 0.722, 0.722, 0.722, 1.000, 0.722, -0.667, 0.667, 0.667, 0.667, 0.389, 0.389, 0.389, 0.389, 0.722, 0.722, -0.778, 0.778, 0.778, 0.778, 0.778, 0.570, 0.778, 0.722, 0.722, 0.722, -0.722, 0.722, 0.611, 0.556, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, -0.722, 0.444, 0.444, 0.444, 0.444, 0.444, 0.278, 0.278, 0.278, 0.278, -0.500, 0.556, 0.500, 0.500, 0.500, 0.500, 0.500, 0.570, 0.500, 0.556, -0.556, 0.556, 0.556, 0.500, 0.556, 0.500] + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.250, + 0.333, + 0.555, + 0.500, + 0.500, + 1.000, + 0.833, + 0.278, + 0.333, + 0.333, + 0.500, + 0.570, + 0.250, + 0.333, + 0.250, + 0.278, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.333, + 0.333, + 0.570, + 0.570, + 0.570, + 0.500, + 0.930, + 0.722, + 0.667, + 0.722, + 0.722, + 0.667, + 0.611, + 0.778, + 0.778, + 0.389, + 0.500, + 0.778, + 0.667, + 0.944, + 0.722, + 0.778, + 0.611, + 0.778, + 0.722, + 0.556, + 0.667, + 0.722, + 0.722, + 1.000, + 0.722, + 0.722, + 0.667, + 0.333, + 0.278, + 0.333, + 0.581, + 0.500, + 0.333, + 0.500, + 0.556, + 0.444, + 0.556, + 0.444, + 0.333, + 0.500, + 0.556, + 0.278, + 0.333, + 0.556, + 0.278, + 0.833, + 0.556, + 0.500, + 0.556, + 0.556, + 0.444, + 0.389, + 0.333, + 0.556, + 0.500, + 0.722, + 0.500, + 0.500, + 0.444, + 0.394, + 0.220, + 0.394, + 0.520, + 0.350, + 0.500, + 0.350, + 0.333, + 0.500, + 0.500, + 1.000, + 0.500, + 0.500, + 0.333, + 1.000, + 0.556, + 0.333, + 1.000, + 0.350, + 0.667, + 0.350, + 0.350, + 0.333, + 0.333, + 0.500, + 0.500, + 0.350, + 0.500, + 1.000, + 0.333, + 1.000, + 0.389, + 0.333, + 0.722, + 0.350, + 0.444, + 0.722, + 0.250, + 0.333, + 0.500, + 0.500, + 0.500, + 0.500, + 0.220, + 0.500, + 0.333, + 0.747, + 0.300, + 0.500, + 0.570, + 0.333, + 0.747, + 0.333, + 0.400, + 0.570, + 0.300, + 0.300, + 0.333, + 0.556, + 0.540, + 0.250, + 0.333, + 0.300, + 0.330, + 0.500, + 0.750, + 0.750, + 0.750, + 0.500, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 1.000, + 0.722, + 0.667, + 0.667, + 0.667, + 0.667, + 0.389, + 0.389, + 0.389, + 0.389, + 0.722, + 0.722, + 0.778, + 0.778, + 0.778, + 0.778, + 0.778, + 0.570, + 0.778, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.611, + 0.556, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.722, + 0.444, + 0.444, + 0.444, + 0.444, + 0.444, + 0.278, + 0.278, + 0.278, + 0.278, + 0.500, + 0.556, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.570, + 0.500, + 0.556, + 0.556, + 0.556, + 0.556, + 0.500, + 0.556, + 0.500, +] ROMAN_I = [ -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.250, 0.333, 0.420, 0.500, 0.500, 0.833, 0.778, 0.214, -0.333, 0.333, 0.500, 0.675, 0.250, 0.333, 0.250, 0.278, 0.500, 0.500, -0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.333, 0.333, -0.675, 0.675, 0.675, 0.500, 0.920, 0.611, 0.611, 0.667, 0.722, 0.611, -0.611, 0.722, 0.722, 0.333, 0.444, 0.667, 0.556, 0.833, 0.667, 0.722, -0.611, 0.722, 0.611, 0.500, 0.556, 0.722, 0.611, 0.833, 0.611, 0.556, -0.556, 0.389, 0.278, 0.389, 0.422, 0.500, 0.333, 0.500, 0.500, 0.444, -0.500, 0.444, 0.278, 0.500, 0.500, 0.278, 0.278, 0.444, 0.278, 0.722, -0.500, 0.500, 0.500, 0.500, 0.389, 0.389, 0.278, 0.500, 0.444, 0.667, -0.444, 0.444, 0.389, 0.400, 0.275, 0.400, 0.541, 0.350, 0.500, 0.350, -0.333, 0.500, 0.556, 0.889, 0.500, 0.500, 0.333, 1.000, 0.500, 0.333, -0.944, 0.350, 0.556, 0.350, 0.350, 0.333, 0.333, 0.556, 0.556, 0.350, -0.500, 0.889, 0.333, 0.980, 0.389, 0.333, 0.667, 0.350, 0.389, 0.556, -0.250, 0.389, 0.500, 0.500, 0.500, 0.500, 0.275, 0.500, 0.333, 0.760, -0.276, 0.500, 0.675, 0.333, 0.760, 0.333, 0.400, 0.675, 0.300, 0.300, -0.333, 0.500, 0.523, 0.250, 0.333, 0.300, 0.310, 0.500, 0.750, 0.750, -0.750, 0.500, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.889, 0.667, -0.611, 0.611, 0.611, 0.611, 0.333, 0.333, 0.333, 0.333, 0.722, 0.667, -0.722, 0.722, 0.722, 0.722, 0.722, 0.675, 0.722, 0.722, 0.722, 0.722, -0.722, 0.556, 0.611, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, -0.667, 0.444, 0.444, 0.444, 0.444, 0.444, 0.278, 0.278, 0.278, 0.278, -0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.675, 0.500, 0.500, -0.500, 0.500, 0.500, 0.444, 0.500, 0.444] + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.250, + 0.333, + 0.420, + 0.500, + 0.500, + 0.833, + 0.778, + 0.214, + 0.333, + 0.333, + 0.500, + 0.675, + 0.250, + 0.333, + 0.250, + 0.278, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.333, + 0.333, + 0.675, + 0.675, + 0.675, + 0.500, + 0.920, + 0.611, + 0.611, + 0.667, + 0.722, + 0.611, + 0.611, + 0.722, + 0.722, + 0.333, + 0.444, + 0.667, + 0.556, + 0.833, + 0.667, + 0.722, + 0.611, + 0.722, + 0.611, + 0.500, + 0.556, + 0.722, + 0.611, + 0.833, + 0.611, + 0.556, + 0.556, + 0.389, + 0.278, + 0.389, + 0.422, + 0.500, + 0.333, + 0.500, + 0.500, + 0.444, + 0.500, + 0.444, + 0.278, + 0.500, + 0.500, + 0.278, + 0.278, + 0.444, + 0.278, + 0.722, + 0.500, + 0.500, + 0.500, + 0.500, + 0.389, + 0.389, + 0.278, + 0.500, + 0.444, + 0.667, + 0.444, + 0.444, + 0.389, + 0.400, + 0.275, + 0.400, + 0.541, + 0.350, + 0.500, + 0.350, + 0.333, + 0.500, + 0.556, + 0.889, + 0.500, + 0.500, + 0.333, + 1.000, + 0.500, + 0.333, + 0.944, + 0.350, + 0.556, + 0.350, + 0.350, + 0.333, + 0.333, + 0.556, + 0.556, + 0.350, + 0.500, + 0.889, + 0.333, + 0.980, + 0.389, + 0.333, + 0.667, + 0.350, + 0.389, + 0.556, + 0.250, + 0.389, + 0.500, + 0.500, + 0.500, + 0.500, + 0.275, + 0.500, + 0.333, + 0.760, + 0.276, + 0.500, + 0.675, + 0.333, + 0.760, + 0.333, + 0.400, + 0.675, + 0.300, + 0.300, + 0.333, + 0.500, + 0.523, + 0.250, + 0.333, + 0.300, + 0.310, + 0.500, + 0.750, + 0.750, + 0.750, + 0.500, + 0.611, + 0.611, + 0.611, + 0.611, + 0.611, + 0.611, + 0.889, + 0.667, + 0.611, + 0.611, + 0.611, + 0.611, + 0.333, + 0.333, + 0.333, + 0.333, + 0.722, + 0.667, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.675, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.556, + 0.611, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.667, + 0.444, + 0.444, + 0.444, + 0.444, + 0.444, + 0.278, + 0.278, + 0.278, + 0.278, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.675, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.444, + 0.500, + 0.444, +] ROMAN_BI = [ -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, -0.000, 0.000, 0.250, 0.389, 0.555, 0.500, 0.500, 0.833, 0.778, 0.278, -0.333, 0.333, 0.500, 0.570, 0.250, 0.333, 0.250, 0.278, 0.500, 0.500, -0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.333, 0.333, -0.570, 0.570, 0.570, 0.500, 0.832, 0.667, 0.667, 0.667, 0.722, 0.667, -0.667, 0.722, 0.778, 0.389, 0.500, 0.667, 0.611, 0.889, 0.722, 0.722, -0.611, 0.722, 0.667, 0.556, 0.611, 0.722, 0.667, 0.889, 0.667, 0.611, -0.611, 0.333, 0.278, 0.333, 0.570, 0.500, 0.333, 0.500, 0.500, 0.444, -0.500, 0.444, 0.333, 0.500, 0.556, 0.278, 0.278, 0.500, 0.278, 0.778, -0.556, 0.500, 0.500, 0.500, 0.389, 0.389, 0.278, 0.556, 0.444, 0.667, -0.500, 0.444, 0.389, 0.348, 0.220, 0.348, 0.570, 0.350, 0.500, 0.350, -0.333, 0.500, 0.500, 1.000, 0.500, 0.500, 0.333, 1.000, 0.556, 0.333, -0.944, 0.350, 0.611, 0.350, 0.350, 0.333, 0.333, 0.500, 0.500, 0.350, -0.500, 1.000, 0.333, 1.000, 0.389, 0.333, 0.722, 0.350, 0.389, 0.611, -0.250, 0.389, 0.500, 0.500, 0.500, 0.500, 0.220, 0.500, 0.333, 0.747, -0.266, 0.500, 0.606, 0.333, 0.747, 0.333, 0.400, 0.570, 0.300, 0.300, -0.333, 0.576, 0.500, 0.250, 0.333, 0.300, 0.300, 0.500, 0.750, 0.750, -0.750, 0.500, 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 0.944, 0.667, -0.667, 0.667, 0.667, 0.667, 0.389, 0.389, 0.389, 0.389, 0.722, 0.722, -0.722, 0.722, 0.722, 0.722, 0.722, 0.570, 0.722, 0.722, 0.722, 0.722, -0.722, 0.611, 0.611, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, 0.500, -0.722, 0.444, 0.444, 0.444, 0.444, 0.444, 0.278, 0.278, 0.278, 0.278, -0.500, 0.556, 0.500, 0.500, 0.500, 0.500, 0.500, 0.570, 0.500, 0.556, -0.556, 0.556, 0.556, 0.444, 0.500, 0.444] + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.000, + 0.250, + 0.389, + 0.555, + 0.500, + 0.500, + 0.833, + 0.778, + 0.278, + 0.333, + 0.333, + 0.500, + 0.570, + 0.250, + 0.333, + 0.250, + 0.278, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.333, + 0.333, + 0.570, + 0.570, + 0.570, + 0.500, + 0.832, + 0.667, + 0.667, + 0.667, + 0.722, + 0.667, + 0.667, + 0.722, + 0.778, + 0.389, + 0.500, + 0.667, + 0.611, + 0.889, + 0.722, + 0.722, + 0.611, + 0.722, + 0.667, + 0.556, + 0.611, + 0.722, + 0.667, + 0.889, + 0.667, + 0.611, + 0.611, + 0.333, + 0.278, + 0.333, + 0.570, + 0.500, + 0.333, + 0.500, + 0.500, + 0.444, + 0.500, + 0.444, + 0.333, + 0.500, + 0.556, + 0.278, + 0.278, + 0.500, + 0.278, + 0.778, + 0.556, + 0.500, + 0.500, + 0.500, + 0.389, + 0.389, + 0.278, + 0.556, + 0.444, + 0.667, + 0.500, + 0.444, + 0.389, + 0.348, + 0.220, + 0.348, + 0.570, + 0.350, + 0.500, + 0.350, + 0.333, + 0.500, + 0.500, + 1.000, + 0.500, + 0.500, + 0.333, + 1.000, + 0.556, + 0.333, + 0.944, + 0.350, + 0.611, + 0.350, + 0.350, + 0.333, + 0.333, + 0.500, + 0.500, + 0.350, + 0.500, + 1.000, + 0.333, + 1.000, + 0.389, + 0.333, + 0.722, + 0.350, + 0.389, + 0.611, + 0.250, + 0.389, + 0.500, + 0.500, + 0.500, + 0.500, + 0.220, + 0.500, + 0.333, + 0.747, + 0.266, + 0.500, + 0.606, + 0.333, + 0.747, + 0.333, + 0.400, + 0.570, + 0.300, + 0.300, + 0.333, + 0.576, + 0.500, + 0.250, + 0.333, + 0.300, + 0.300, + 0.500, + 0.750, + 0.750, + 0.750, + 0.500, + 0.667, + 0.667, + 0.667, + 0.667, + 0.667, + 0.667, + 0.944, + 0.667, + 0.667, + 0.667, + 0.667, + 0.667, + 0.389, + 0.389, + 0.389, + 0.389, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.570, + 0.722, + 0.722, + 0.722, + 0.722, + 0.722, + 0.611, + 0.611, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.722, + 0.444, + 0.444, + 0.444, + 0.444, + 0.444, + 0.278, + 0.278, + 0.278, + 0.278, + 0.500, + 0.556, + 0.500, + 0.500, + 0.500, + 0.500, + 0.500, + 0.570, + 0.500, + 0.556, + 0.556, + 0.556, + 0.556, + 0.444, + 0.500, + 0.444, +] -FONT_ARRAY = [ [SWISS, SWISS_B, SWISS_I, SWISS_BI ], - [ROMAN, ROMAN_B, ROMAN_I, ROMAN_BI ] ] +FONT_ARRAY = [[SWISS, SWISS_B, SWISS_I, SWISS_BI], [ROMAN, ROMAN_B, ROMAN_I, ROMAN_BI]] -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # string_width # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- def string_width(font, text): """ returns with width of a string in the specified font @@ -262,7 +2110,7 @@ def string_width(font, text): ## TODO: Does it not make sense to use writing on a pango Layout to know ## text width? i = font.get_type_face() - j = font.get_bold() + font.get_italic()*2 + j = font.get_bold() + font.get_italic() * 2 s = font.get_size() l = FONT_ARRAY[i][j] r = 0 @@ -270,24 +2118,26 @@ def string_width(font, text): try: r = r + l[ord(c)] except: - r = r + l[ord('n')] - return (r+1)*s + r = r + l[ord("n")] + return (r + 1) * s + def string_multiline_width(font, text): - max = 0 - for line in text.splitlines(): - width = string_width(font, line) - if width > max: - max = width - return max + max = 0 + for line in text.splitlines(): + width = string_width(font, line) + if width > max: + max = width + return max + -def string_trim(font, text, width, ellipses = "..."): +def string_trim(font, text, width, ellipses="..."): """ Like string_width, but this makes sure the length of the string is <= width. Optionally, add ellipses (...). """ i = font.get_type_face() - j = font.get_bold() + font.get_italic()*2 + j = font.get_bold() + font.get_italic() * 2 s = font.get_size() l = FONT_ARRAY[i][j] ellipses_length = 0 @@ -296,7 +2146,7 @@ def string_trim(font, text, width, ellipses = "..."): try: ellipses_length += l[ord(c)] except: - ellipses_length += l[ord('n')] + ellipses_length += l[ord("n")] # find the part that is < width retval = "" sumlen = 0 @@ -304,7 +2154,7 @@ def string_trim(font, text, width, ellipses = "..."): try: length = l[ord(c)] except: - length = l[ord('n')] + length = l[ord("n")] # too long: if (sumlen + length + 1) * s > width: if ellipses_length > 0: @@ -327,7 +2177,7 @@ def string_trim(font, text, width, ellipses = "..."): try: length = l[ord(c)] except: - length = l[ord('n')] + length = l[ord("n")] if (sumlen + length + 1) * s > width: return retval if (sumlen + length + ellipses_length + 1) * s > width: diff --git a/gramps/gen/plug/docgen/fontstyle.py b/gramps/gen/plug/docgen/fontstyle.py index 22ba7786f57..29c7fc1292e 100644 --- a/gramps/gen/plug/docgen/fontstyle.py +++ b/gramps/gen/plug/docgen/fontstyle.py @@ -23,41 +23,43 @@ # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + log = logging.getLogger(".fontstyle") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # constants # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- FONT_SANS_SERIF = 0 FONT_SERIF = 1 FONT_MONOSPACE = 2 -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # FontStyle # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class FontStyle: """ Defines a font style. Controls the font face, size, color, and @@ -92,8 +94,9 @@ def __init__(self, style=None): self.color = (0, 0, 0) self.under = 0 - def set(self, face=None, size=None, italic=None, bold=None, - underline=None, color=None): + def set( + self, face=None, size=None, italic=None, bold=None, underline=None, color=None + ): """ Set font characteristics. diff --git a/gramps/gen/plug/docgen/graphdoc.py b/gramps/gen/plug/docgen/graphdoc.py index a311592d2c9..aa93728f87f 100644 --- a/gramps/gen/plug/docgen/graphdoc.py +++ b/gramps/gen/plug/docgen/graphdoc.py @@ -28,76 +28,86 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # """ Graphviz adapter for Graphs """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from abc import ABCMeta, abstractmethod import os from io import BytesIO import tempfile from subprocess import Popen, PIPE -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext from ...utils.file import search_for, where_is from . import BaseDoc -from ..menu import NumberOption, TextOption, EnumeratedListOption, \ - BooleanOption +from ..menu import NumberOption, TextOption, EnumeratedListOption, BooleanOption from ...constfunc import win -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + LOG = logging.getLogger(".graphdoc") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Private Constants # -#------------------------------------------------------------------------- -_FONTS = [{'name' : _("Default"), 'value' : "serif"}, - {'name' : _("PostScript / Helvetica"), 'value' : "Helvetica"}, - {'name' : _("TrueType / FreeSans"), 'value' : "FreeSans"}] - -_RANKDIR = [{'name' : _("Vertical (↓)"), 'value' : "TB"}, - {'name' : _("Vertical (↑)"), 'value' : "BT"}, - {'name' : _("Horizontal (→)"), 'value' : "LR"}, - {'name' : _("Horizontal (←)"), 'value' : "RL"}] - -_NODE_PORTS = {"TB" : ("n", "s"), - "BT" : ("s", "n"), - "LR" : ("w", "e"), - "RL" : ("e", "w")} - -_PAGEDIR = [{'name' : _("Bottom, left"), 'value' : "BL"}, - {'name' : _("Bottom, right"), 'value' : "BR"}, - {'name' : _("Top, left"), 'value' : "TL"}, - {'name' : _("Top, Right"), 'value' : "TR"}, - {'name' : _("Right, bottom"), 'value' : "RB"}, - {'name' : _("Right, top"), 'value' : "RT"}, - {'name' : _("Left, bottom"), 'value' : "LB"}, - {'name' : _("Left, top"), 'value' : "LT"}] - -_RATIO = [{'name' : _("Compress to minimal size"), 'value': "compress"}, - {'name' : _("Fill the given area"), 'value': "fill"}, - {'name' : _("Expand uniformly"), 'value': "expand"}] - -_NOTELOC = [{'name' : _("Top"), 'value' : "t"}, - {'name' : _("Bottom"), 'value' : "b"}] - -_SPLINE = [{'name' : _("Straight"), 'value' : "false"}, - {'name' : _("Curved"), 'value' : "true", }, - {'name' : _("Orthogonal"), 'value' : 'ortho'}] +# ------------------------------------------------------------------------- +_FONTS = [ + {"name": _("Default"), "value": "serif"}, + {"name": _("PostScript / Helvetica"), "value": "Helvetica"}, + {"name": _("TrueType / FreeSans"), "value": "FreeSans"}, +] + +_RANKDIR = [ + {"name": _("Vertical (↓)"), "value": "TB"}, + {"name": _("Vertical (↑)"), "value": "BT"}, + {"name": _("Horizontal (→)"), "value": "LR"}, + {"name": _("Horizontal (←)"), "value": "RL"}, +] + +_NODE_PORTS = {"TB": ("n", "s"), "BT": ("s", "n"), "LR": ("w", "e"), "RL": ("e", "w")} + +_PAGEDIR = [ + {"name": _("Bottom, left"), "value": "BL"}, + {"name": _("Bottom, right"), "value": "BR"}, + {"name": _("Top, left"), "value": "TL"}, + {"name": _("Top, Right"), "value": "TR"}, + {"name": _("Right, bottom"), "value": "RB"}, + {"name": _("Right, top"), "value": "RT"}, + {"name": _("Left, bottom"), "value": "LB"}, + {"name": _("Left, top"), "value": "LT"}, +] + +_RATIO = [ + {"name": _("Compress to minimal size"), "value": "compress"}, + {"name": _("Fill the given area"), "value": "fill"}, + {"name": _("Expand uniformly"), "value": "expand"}, +] + +_NOTELOC = [{"name": _("Top"), "value": "t"}, {"name": _("Bottom"), "value": "b"}] + +_SPLINE = [ + {"name": _("Straight"), "value": "false"}, + { + "name": _("Curved"), + "value": "true", + }, + {"name": _("Orthogonal"), "value": "ortho"}, +] if win(): _DOT_FOUND = search_for("dot.exe") @@ -117,16 +127,17 @@ def esc(id_txt): return id_txt.replace('"', '\\"') -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVOptions # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVOptions: """ Defines all of the controls necessary to configure the graph reports. """ + def __init__(self): self.h_pages = None self.v_pages = None @@ -147,10 +158,14 @@ def add_menu_options(self, menu): font_family = EnumeratedListOption(_("Font family"), "") for item in _FONTS: font_family.add_item(item["value"], item["name"]) - font_family.set_help(_("Choose the font family. If international " - "characters don't show, use FreeSans font. " - "FreeSans is available from: " - "http://www.nongnu.org/freefont/")) + font_family.set_help( + _( + "Choose the font family. If international " + "characters don't show, use FreeSans font. " + "FreeSans is available from: " + "http://www.nongnu.org/freefont/" + ) + ) menu.add_option(category, "font_family", font_family) font_size = NumberOption(_("Font size"), 14, 8, 128) @@ -160,32 +175,45 @@ def add_menu_options(self, menu): rank_dir = EnumeratedListOption(_("Graph Direction"), "TB") for item in _RANKDIR: rank_dir.add_item(item["value"], item["name"]) - rank_dir.set_help(_("Whether graph goes from top to bottom " - "or left to right.")) + rank_dir.set_help( + _("Whether graph goes from top to bottom " "or left to right.") + ) menu.add_option(category, "rank_dir", rank_dir) h_pages = NumberOption(_("Number of Horizontal Pages"), 1, 1, 25) - h_pages.set_help(_("Graphviz can create very large graphs by " - "spreading the graph across a rectangular " - "array of pages. This controls the number " - "pages in the array horizontally. " - "Only valid for dot and pdf via Ghostscript.")) + h_pages.set_help( + _( + "Graphviz can create very large graphs by " + "spreading the graph across a rectangular " + "array of pages. This controls the number " + "pages in the array horizontally. " + "Only valid for dot and pdf via Ghostscript." + ) + ) menu.add_option(category, "h_pages", h_pages) v_pages = NumberOption(_("Number of Vertical Pages"), 1, 1, 25) - v_pages.set_help(_("Graphviz can create very large graphs by " - "spreading the graph across a rectangular " - "array of pages. This controls the number " - "pages in the array vertically. " - "Only valid for dot and pdf via Ghostscript.")) + v_pages.set_help( + _( + "Graphviz can create very large graphs by " + "spreading the graph across a rectangular " + "array of pages. This controls the number " + "pages in the array vertically. " + "Only valid for dot and pdf via Ghostscript." + ) + ) menu.add_option(category, "v_pages", v_pages) page_dir = EnumeratedListOption(_("Paging Direction"), "BL") for item in _PAGEDIR: page_dir.add_item(item["value"], item["name"]) - page_dir.set_help(_("The order in which the graph pages are output. " - "This option only applies if the horizontal pages " - "or vertical pages are greater than 1.")) + page_dir.set_help( + _( + "The order in which the graph pages are output. " + "This option only applies if the horizontal pages " + "or vertical pages are greater than 1." + ) + ) menu.add_option(category, "page_dir", page_dir) spline = EnumeratedListOption(_("Connecting lines"), "true") @@ -207,8 +235,8 @@ def add_menu_options(self, menu): # the page direction option only makes sense when the # number of horizontal and/or vertical pages is > 1 - self.h_pages.connect('value-changed', self.pages_changed) - self.v_pages.connect('value-changed', self.pages_changed) + self.h_pages.connect("value-changed", self.pages_changed) + self.v_pages.connect("value-changed", self.pages_changed) ################################ category = _("Graphviz Options") @@ -218,60 +246,71 @@ def add_menu_options(self, menu): for item in _RATIO: aspect_ratio.add_item(item["value"], item["name"]) help_text = _( - 'Affects node spacing and scaling of the graph.\n' - 'If the graph is smaller than the print area:\n' - ' Compress will not change the node spacing. \n' - ' Fill will increase the node spacing to fit the print area in ' - 'both width and height.\n' - ' Expand will increase the node spacing uniformly to preserve ' - 'the aspect ratio.\n' - 'If the graph is larger than the print area:\n' - ' Compress will shrink the graph to achieve tight packing at the ' - 'expense of symmetry.\n' - ' Fill will shrink the graph to fit the print area after first ' - 'increasing the node spacing.\n' - ' Expand will shrink the graph uniformly to fit the print area.') + "Affects node spacing and scaling of the graph.\n" + "If the graph is smaller than the print area:\n" + " Compress will not change the node spacing. \n" + " Fill will increase the node spacing to fit the print area in " + "both width and height.\n" + " Expand will increase the node spacing uniformly to preserve " + "the aspect ratio.\n" + "If the graph is larger than the print area:\n" + " Compress will shrink the graph to achieve tight packing at the " + "expense of symmetry.\n" + " Fill will shrink the graph to fit the print area after first " + "increasing the node spacing.\n" + " Expand will shrink the graph uniformly to fit the print area." + ) aspect_ratio.set_help(help_text) menu.add_option(category, "ratio", aspect_ratio) dpi = NumberOption(_("DPI"), 75, 20, 1200) - dpi.set_help(_("Dots per inch. When creating images such as " - ".gif or .png files for the web, try numbers " - "such as 100 or 300 DPI. PostScript and PDF files " - "always use 72 DPI.")) + dpi.set_help( + _( + "Dots per inch. When creating images such as " + ".gif or .png files for the web, try numbers " + "such as 100 or 300 DPI. PostScript and PDF files " + "always use 72 DPI." + ) + ) menu.add_option(category, "dpi", dpi) self.dpi = dpi nodesep = NumberOption(_("Node spacing"), 0.20, 0.01, 5.00, 0.01) - nodesep.set_help(_("The minimum amount of free space, in inches, " - "between individual nodes. For vertical graphs, " - "this corresponds to spacing between columns. " - "For horizontal graphs, this corresponds to " - "spacing between rows.")) + nodesep.set_help( + _( + "The minimum amount of free space, in inches, " + "between individual nodes. For vertical graphs, " + "this corresponds to spacing between columns. " + "For horizontal graphs, this corresponds to " + "spacing between rows." + ) + ) menu.add_option(category, "nodesep", nodesep) ranksep = NumberOption(_("Rank spacing"), 0.20, 0.01, 5.00, 0.01) - ranksep.set_help(_("The minimum amount of free space, in inches, " - "between ranks. For vertical graphs, this " - "corresponds to spacing between rows. For " - "horizontal graphs, this corresponds to spacing " - "between columns.")) + ranksep.set_help( + _( + "The minimum amount of free space, in inches, " + "between ranks. For vertical graphs, this " + "corresponds to spacing between rows. For " + "horizontal graphs, this corresponds to spacing " + "between columns." + ) + ) menu.add_option(category, "ranksep", ranksep) ################################ category = _("Note") ################################ - note = TextOption(_("Note to add to the graph"), - [""]) + note = TextOption(_("Note to add to the graph"), [""]) note.set_help(_("This text will be added to the graph.")) menu.add_option(category, "note", note) - noteloc = EnumeratedListOption(_("Note location"), 't') + noteloc = EnumeratedListOption(_("Note location"), "t") for i in range(0, len(_NOTELOC)): noteloc.add_item(_NOTELOC[i]["value"], _NOTELOC[i]["name"]) - noteloc.set_help(_("Whether note will appear on top " - "or bottom of the page.")) + noteloc.set_help(_("Whether note will appear on top " "or bottom of the page.")) menu.add_option(category, "noteloc", noteloc) notesize = NumberOption(_("Note size"), 32, 8, 128) @@ -291,11 +330,11 @@ def pages_changed(self): self.page_dir.set_available(False) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVDoc(metaclass=ABCMeta): """ Abstract Interface for Graphviz document generators. Output formats @@ -304,8 +343,17 @@ class GVDoc(metaclass=ABCMeta): """ @abstractmethod - def add_node(self, node_id, label, shape="", color="", - style="", fillcolor="", url="", htmloutput=False): + def add_node( + self, + node_id, + label, + shape="", + color="", + style="", + fillcolor="", + url="", + htmloutput=False, + ): """ Add a node to this graph. Nodes can be different shapes like boxes and circles. @@ -410,17 +458,18 @@ def end_subgraph(self): """ -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVDocBase # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVDocBase(BaseDoc, GVDoc): """ Base document generator for all Graphviz document generators. Classes that inherit from this class will only need to implement the close function. The close function will generate the actual file of the appropriate type. """ + def __init__(self, options, paper_style, uistate=None): BaseDoc.__init__(self, None, paper_style, uistate=uistate) @@ -430,33 +479,37 @@ def __init__(self, options, paper_style, uistate=None): get_option = options.menu.get_option_by_name - self.dpi = get_option('dpi').get_value() - self.fontfamily = get_option('font_family').get_value() - self.fontsize = get_option('font_size').get_value() - self.hpages = get_option('h_pages').get_value() - self.nodesep = get_option('nodesep').get_value() - self.noteloc = get_option('noteloc').get_value() - self.notesize = get_option('notesize').get_value() - self.note = get_option('note').get_value() - self.pagedir = get_option('page_dir').get_value() - self.rankdir = get_option('rank_dir').get_value() - self.ranksep = get_option('ranksep').get_value() - self.ratio = get_option('ratio').get_value() - self.vpages = get_option('v_pages').get_value() - self.spline = get_option('spline').get_value() - self.node_ports = get_option('node_ports').get_value() + self.dpi = get_option("dpi").get_value() + self.fontfamily = get_option("font_family").get_value() + self.fontsize = get_option("font_size").get_value() + self.hpages = get_option("h_pages").get_value() + self.nodesep = get_option("nodesep").get_value() + self.noteloc = get_option("noteloc").get_value() + self.notesize = get_option("notesize").get_value() + self.note = get_option("note").get_value() + self.pagedir = get_option("page_dir").get_value() + self.rankdir = get_option("rank_dir").get_value() + self.ranksep = get_option("ranksep").get_value() + self.ratio = get_option("ratio").get_value() + self.vpages = get_option("v_pages").get_value() + self.spline = get_option("spline").get_value() + self.node_ports = get_option("node_ports").get_value() paper_size = paper_style.get_size() # Subtract 0.01" from the drawing area to make some room between # this area and the margin in order to compensate for different # rounding errors internally in dot - sizew = (paper_size.get_width() - - self._paper.get_left_margin() - - self._paper.get_right_margin()) / 2.54 - 0.01 - sizeh = (paper_size.get_height() - - self._paper.get_top_margin() - - self._paper.get_bottom_margin()) / 2.54 - 0.01 + sizew = ( + paper_size.get_width() + - self._paper.get_left_margin() + - self._paper.get_right_margin() + ) / 2.54 - 0.01 + sizeh = ( + paper_size.get_height() + - self._paper.get_top_margin() + - self._paper.get_bottom_margin() + ) / 2.54 - 0.01 pheight = paper_size.get_height_inches() pwidth = paper_size.get_width_inches() @@ -468,48 +521,52 @@ def __init__(self, options, paper_style, uistate=None): sizeh *= self.vpages self.write( - 'digraph GRAMPS_graph\n' - '{\n' - ' bgcolor=white;\n' + "digraph GRAMPS_graph\n" + "{\n" + " bgcolor=white;\n" ' center="true"; \n' ' charset="utf8";\n' - ' concentrate="false";\n' + - ' dpi="%d";\n' % self.dpi + - ' graph [fontsize=%d];\n' % self.fontsize + - ' margin="%3.2f,%3.2f"; \n' % (xmargin, ymargin) + - ' mclimit="99";\n' + - ' nodesep="%.2f";\n' % self.nodesep + - ' outputorder="edgesfirst";\n' + - ('#' if self.hpages == self.vpages == 1 else '') + + ' concentrate="false";\n' + + ' dpi="%d";\n' % self.dpi + + " graph [fontsize=%d];\n" % self.fontsize + + ' margin="%3.2f,%3.2f"; \n' % (xmargin, ymargin) + + ' mclimit="99";\n' + + ' nodesep="%.2f";\n' % self.nodesep + + ' outputorder="edgesfirst";\n' + + ("#" if self.hpages == self.vpages == 1 else "") + + # comment out "page=" if the graph is on 1 page (bug #2121) - ' page="%3.2f,%3.2f";\n' % (pwidth, pheight) + - ' pagedir="%s";\n' % self.pagedir + - ' rankdir="%s";\n' % self.rankdir + - ' ranksep="%.2f";\n' % self.ranksep + - ' ratio="%s";\n' % self.ratio + - ' searchsize="100";\n' + - ' size="%3.2f,%3.2f"; \n' % (sizew, sizeh) + - ' splines="%s";\n' % self.spline + - '\n' + - ' edge [len=0.5 style=solid fontsize=%d];\n' % self.fontsize) + ' page="%3.2f,%3.2f";\n' % (pwidth, pheight) + + ' pagedir="%s";\n' % self.pagedir + + ' rankdir="%s";\n' % self.rankdir + + ' ranksep="%.2f";\n' % self.ranksep + + ' ratio="%s";\n' % self.ratio + + ' searchsize="100";\n' + + ' size="%3.2f,%3.2f"; \n' % (sizew, sizeh) + + ' splines="%s";\n' % self.spline + + "\n" + + " edge [len=0.5 style=solid fontsize=%d];\n" % self.fontsize + ) if self.node_ports: - self.write(' edge [headport=%s tailport=%s];\n' - % _NODE_PORTS[self.rankdir]) + self.write( + " edge [headport=%s tailport=%s];\n" % _NODE_PORTS[self.rankdir] + ) if self.fontfamily: - self.write(' node [style=filled fontname="%s" fontsize=%d];\n' - % (self.fontfamily, self.fontsize)) + self.write( + ' node [style=filled fontname="%s" fontsize=%d];\n' + % (self.fontfamily, self.fontsize) + ) else: - self.write(' node [style=filled fontsize=%d];\n' - % self.fontsize) - self.write('\n') + self.write(" node [style=filled fontsize=%d];\n" % self.fontsize) + self.write("\n") def write(self, text): - """ Write text to the dot file """ - self._dot.write(text.encode('utf8', 'xmlcharrefreplace')) + """Write text to the dot file""" + self._dot.write(text.encode("utf8", "xmlcharrefreplace")) def open(self, filename): - """ Implement GVDocBase.open() """ + """Implement GVDocBase.open()""" self._filename = os.path.normpath(os.path.abspath(filename)) def close(self): @@ -519,33 +576,43 @@ def close(self): """ if self.note: # build up the label - label = '' - for line in self.note: # for every line in the note... + label = "" + for line in self.note: # for every line in the note... line = line.strip() # ...strip whitespace from this line... - if line != '': # ...and if we still have a line... - if label != '': # ...see if we need to insert a newline... - label += '\\n' - label += line.replace('"', '\\\"') + if line != "": # ...and if we still have a line... + if label != "": # ...see if we need to insert a newline... + label += "\\n" + label += line.replace('"', '\\"') # after all that, see if we have a label to display - if label != '': + if label != "": self.write( - '\n' + - ' label="%s";\n' % label + - ' labelloc="%s";\n' % self.noteloc + - ' fontsize="%d";\n' % self.notesize) - - self.write('}\n\n') - - def add_node(self, node_id, label, shape="", color="", - style="", fillcolor="", url="", htmloutput=False): + "\n" + + ' label="%s";\n' % label + + ' labelloc="%s";\n' % self.noteloc + + ' fontsize="%d";\n' % self.notesize + ) + + self.write("}\n\n") + + def add_node( + self, + node_id, + label, + shape="", + color="", + style="", + fillcolor="", + url="", + htmloutput=False, + ): """ Add a node to this graph. Nodes can be different shapes like boxes and circles. Implements GVDocBase.add_node(). """ - text = '[' + text = "[" if shape: text += ' shape="%s"' % shape @@ -563,7 +630,7 @@ def add_node(self, node_id, label, shape="", color="", # otherwise Graphviz uses the node ID as the label which is unlikely # to be what the user wants to see in the graph if label.startswith("<") or htmloutput: - text += ' label=<%s>' % label + text += " label=<%s>" % label else: text += ' label="%s"' % label @@ -582,32 +649,32 @@ def add_link(self, id1, id2, style="", head="", tail="", comment=""): self.write(' "%s" -> "%s"' % (esc(id1), esc(id2))) if style or head or tail: - self.write(' [') + self.write(" [") if style: - self.write(' style=%s' % style) + self.write(" style=%s" % style) if head: - self.write(' arrowhead=%s' % head) + self.write(" arrowhead=%s" % head) if tail: - self.write(' arrowtail=%s' % tail) + self.write(" arrowtail=%s" % tail) if head: if tail: - self.write(' dir=both') + self.write(" dir=both") else: - self.write(' dir=forward') + self.write(" dir=forward") else: if tail: - self.write(' dir=back') + self.write(" dir=back") else: - self.write(' dir=none') - self.write(' ]') + self.write(" dir=none") + self.write(" ]") - self.write(';') + self.write(";") if comment: - self.write(' // %s' % comment) + self.write(" // %s" % comment) - self.write('\n') + self.write("\n") def add_comment(self, comment): """ @@ -615,15 +682,15 @@ def add_comment(self, comment): Implements GVDocBase.add_comment(). """ - tmp = comment.split('\n') + tmp = comment.split("\n") for line in tmp: text = line.strip() if text == "": - self.write('\n') - elif text.startswith('#'): - self.write('%s\n' % text) + self.write("\n") + elif text.startswith("#"): + self.write("%s\n" % text) else: - self.write('# %s\n' % text) + self.write("# %s\n" % text) def add_samerank(self, id1, id2): """ @@ -642,28 +709,27 @@ def rewrite_label(self, id, label): self.write(' "%s" [label = "%s"]\n' % (esc(id), label)) def start_subgraph(self, graph_id): - """ Implement GVDocBase.start_subgraph() """ - graph_id = graph_id.replace(' ', '_') # for user-defined ID with space + """Implement GVDocBase.start_subgraph()""" + graph_id = graph_id.replace(" ", "_") # for user-defined ID with space self.write( - ' subgraph cluster_%s\n' % graph_id + - ' {\n' + - ' style="invis";\n') # no border around subgraph (#0002176) + " subgraph cluster_%s\n" % graph_id + " {\n" + ' style="invis";\n' + ) # no border around subgraph (#0002176) def end_subgraph(self): - """ Implement GVDocBase.end_subgraph() """ - self.write(' }\n') + """Implement GVDocBase.end_subgraph()""" + self.write(" }\n") -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVDotDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVDotDoc(GVDocBase): - """ GVDoc implementation that generates a .gv text file. """ + """GVDoc implementation that generates a .gv text file.""" def close(self): - """ Implements GVDotDoc.close() """ + """Implements GVDotDoc.close()""" GVDocBase.close(self) # Make sure the extension is correct @@ -674,29 +740,29 @@ def close(self): dotfile.write(self._dot.getvalue()) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVPsDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVPsDoc(GVDocBase): - """ GVDoc implementation that generates a .ps file using Graphviz. """ + """GVDoc implementation that generates a .ps file using Graphviz.""" def __init__(self, options, paper_style): # DPI must always be 72 for PDF. # GV documentation says dpi is only for image formats. - options.menu.get_option_by_name('dpi').set_value(72) + options.menu.get_option_by_name("dpi").set_value(72) GVDocBase.__init__(self, options, paper_style) # GV documentation allow multiple pages only for ps format, # But it does not work with -Tps:cairo in order to # show Non Latin-1 letters. Force to only 1 page. # See bug tracker issue 2815 - options.menu.get_option_by_name('v_pages').set_value(1) - options.menu.get_option_by_name('h_pages').set_value(1) + options.menu.get_option_by_name("v_pages").set_value(1) + options.menu.get_option_by_name("h_pages").set_value(1) GVDocBase.__init__(self, options, paper_style) def close(self): - """ Implements GVPsDoc.close() """ + """Implements GVPsDoc.close()""" GVDocBase.close(self) # Make sure the extension is correct @@ -725,36 +791,36 @@ def close(self): # large page. command = 'dot -Tps:cairo -o"%s" "%s"' % (self._filename, tmp_dot) - dotversion = str(Popen(['dot', '-V'], - stderr=PIPE).communicate(input=None)[1]) + dotversion = str(Popen(["dot", "-V"], stderr=PIPE).communicate(input=None)[1]) # Problem with dot 2.26.3 and later and multiple pages, which gives # "cairo: out of memory" If the :cairo is skipped for these cases it # gives bad result for non-Latin-1 characters (utf-8). - if (dotversion.find('2.26.3') or dotversion.find('2.28.0') != -1) and \ - (self.vpages * self.hpages) > 1: - command = command.replace(':cairo', '') + if (dotversion.find("2.26.3") or dotversion.find("2.28.0") != -1) and ( + self.vpages * self.hpages + ) > 1: + command = command.replace(":cairo", "") os.system(command) # Delete the temporary dot file os.remove(tmp_dot) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVSvgDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVSvgDoc(GVDocBase): - """ GVDoc implementation that generates a .svg file using Graphviz. """ + """GVDoc implementation that generates a .svg file using Graphviz.""" def __init__(self, options, paper_style): # GV documentation allow multiple pages only for ps format, # which also includes pdf via ghostscript. - options.menu.get_option_by_name('v_pages').set_value(1) - options.menu.get_option_by_name('h_pages').set_value(1) + options.menu.get_option_by_name("v_pages").set_value(1) + options.menu.get_option_by_name("h_pages").set_value(1) GVDocBase.__init__(self, options, paper_style) def close(self): - """ Implements GVSvgDoc.close() """ + """Implements GVSvgDoc.close()""" GVDocBase.close(self) # Make sure the extension is correct @@ -773,23 +839,23 @@ def close(self): os.remove(tmp_dot) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVSvgzDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVSvgzDoc(GVDocBase): - """ GVDoc implementation that generates a .svg file using Graphviz. """ + """GVDoc implementation that generates a .svg file using Graphviz.""" def __init__(self, options, paper_style): # GV documentation allow multiple pages only for ps format, # which also includes pdf via ghostscript. - options.menu.get_option_by_name('v_pages').set_value(1) - options.menu.get_option_by_name('h_pages').set_value(1) + options.menu.get_option_by_name("v_pages").set_value(1) + options.menu.get_option_by_name("h_pages").set_value(1) GVDocBase.__init__(self, options, paper_style) def close(self): - """ Implements GVSvgzDoc.close() """ + """Implements GVSvgzDoc.close()""" GVDocBase.close(self) # Make sure the extension is correct @@ -808,23 +874,23 @@ def close(self): os.remove(tmp_dot) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVPngDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVPngDoc(GVDocBase): - """ GVDoc implementation that generates a .png file using Graphviz. """ + """GVDoc implementation that generates a .png file using Graphviz.""" def __init__(self, options, paper_style): # GV documentation allow multiple pages only for ps format, # which also includes pdf via ghostscript. - options.menu.get_option_by_name('v_pages').set_value(1) - options.menu.get_option_by_name('h_pages').set_value(1) + options.menu.get_option_by_name("v_pages").set_value(1) + options.menu.get_option_by_name("h_pages").set_value(1) GVDocBase.__init__(self, options, paper_style) def close(self): - """ Implements GVPngDoc.close() """ + """Implements GVPngDoc.close()""" GVDocBase.close(self) # Make sure the extension is correct @@ -843,23 +909,23 @@ def close(self): os.remove(tmp_dot) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVJpegDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVJpegDoc(GVDocBase): - """ GVDoc implementation that generates a .jpg file using Graphviz. """ + """GVDoc implementation that generates a .jpg file using Graphviz.""" def __init__(self, options, paper_style): # GV documentation allow multiple pages only for ps format, # which also includes pdf via ghostscript. - options.menu.get_option_by_name('v_pages').set_value(1) - options.menu.get_option_by_name('h_pages').set_value(1) + options.menu.get_option_by_name("v_pages").set_value(1) + options.menu.get_option_by_name("h_pages").set_value(1) GVDocBase.__init__(self, options, paper_style) def close(self): - """ Implements GVJpegDoc.close() """ + """Implements GVJpegDoc.close()""" GVDocBase.close(self) # Make sure the extension is correct @@ -878,23 +944,23 @@ def close(self): os.remove(tmp_dot) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVGifDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVGifDoc(GVDocBase): - """ GVDoc implementation that generates a .gif file using Graphviz. """ + """GVDoc implementation that generates a .gif file using Graphviz.""" def __init__(self, options, paper_style): # GV documentation allow multiple pages only for ps format, # which also includes pdf via ghostscript. - options.menu.get_option_by_name('v_pages').set_value(1) - options.menu.get_option_by_name('h_pages').set_value(1) + options.menu.get_option_by_name("v_pages").set_value(1) + options.menu.get_option_by_name("h_pages").set_value(1) GVDocBase.__init__(self, options, paper_style) def close(self): - """ Implements GVGifDoc.close() """ + """Implements GVGifDoc.close()""" GVDocBase.close(self) # Make sure the extension is correct @@ -913,26 +979,26 @@ def close(self): os.remove(tmp_dot) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVPdfGvDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVPdfGvDoc(GVDocBase): - """ GVDoc implementation that generates a .pdf file using Graphviz. """ + """GVDoc implementation that generates a .pdf file using Graphviz.""" def __init__(self, options, paper_style): # DPI must always be 72 for PDF. # GV documentation says dpi is only for image formats. - options.menu.get_option_by_name('dpi').set_value(72) + options.menu.get_option_by_name("dpi").set_value(72) # GV documentation allow multiple pages only for ps format, # which also includes pdf via ghostscript. - options.menu.get_option_by_name('v_pages').set_value(1) - options.menu.get_option_by_name('h_pages').set_value(1) + options.menu.get_option_by_name("v_pages").set_value(1) + options.menu.get_option_by_name("h_pages").set_value(1) GVDocBase.__init__(self, options, paper_style) def close(self): - """ Implements GVPdfGvDoc.close() """ + """Implements GVPdfGvDoc.close()""" GVDocBase.close(self) # Make sure the extension is correct @@ -953,21 +1019,22 @@ def close(self): os.remove(tmp_dot) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # GVPdfGsDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class GVPdfGsDoc(GVDocBase): - """ GVDoc implementation that generates a .pdf file using Ghostscript. """ + """GVDoc implementation that generates a .pdf file using Ghostscript.""" + def __init__(self, options, paper_style): # DPI must always be 72 for PDF. # GV documentation says dpi is only for image formats. - options.menu.get_option_by_name('dpi').set_value(72) + options.menu.get_option_by_name("dpi").set_value(72) GVDocBase.__init__(self, options, paper_style) def close(self): - """ Implements GVPdfGsDoc.close() """ + """Implements GVPdfGsDoc.close()""" GVDocBase.close(self) # Make sure the extension is correct @@ -996,14 +1063,16 @@ def close(self): # Add .5 to remove rounding errors. paper_size = self._paper.get_size() - width_pt = int((paper_size.get_width_inches() * 72) + .5) - height_pt = int((paper_size.get_height_inches() * 72) + .5) + width_pt = int((paper_size.get_width_inches() * 72) + 0.5) + height_pt = int((paper_size.get_height_inches() * 72) + 0.5) if (self.vpages * self.hpages) == 1: # -dDEVICEWIDTHPOINTS=%d' -dDEVICEHEIGHTPOINTS=%d - command = '%s -q -sDEVICE=pdfwrite -dNOPAUSE '\ - '-dDEVICEWIDTHPOINTS=%d -dDEVICEHEIGHTPOINTS=%d '\ - '-sOutputFile="%s" "%s" -c quit' % ( - _GS_CMD, width_pt, height_pt, self._filename, tmp_ps) + command = ( + "%s -q -sDEVICE=pdfwrite -dNOPAUSE " + "-dDEVICEWIDTHPOINTS=%d -dDEVICEHEIGHTPOINTS=%d " + '-sOutputFile="%s" "%s" -c quit' + % (_GS_CMD, width_pt, height_pt, self._filename, tmp_ps) + ) os.system(command) os.remove(tmp_ps) return @@ -1017,11 +1086,17 @@ def close(self): # Convert to PDF using ghostscript list_of_pieces = [] - x_rng = range(1, self.hpages + 1) if 'L' in self.pagedir \ + x_rng = ( + range(1, self.hpages + 1) + if "L" in self.pagedir else range(self.hpages, 0, -1) - y_rng = range(1, self.vpages + 1) if 'B' in self.pagedir \ + ) + y_rng = ( + range(1, self.vpages + 1) + if "B" in self.pagedir else range(self.vpages, 0, -1) - if self.pagedir[0] in 'TB': + ) + if self.pagedir[0] in "TB": the_list = ((__x, __y) for __y in y_rng for __x in x_rng) else: the_list = ((__x, __y) for __x in x_rng for __y in y_rng) @@ -1032,20 +1107,34 @@ def close(self): tmp_pdf_piece = "%s_%d_%d.pdf" % (tmp_ps, __x, __y) list_of_pieces.append(tmp_pdf_piece) # Generate Ghostscript code - command = '%s -q -dBATCH -dNOPAUSE -dSAFER '\ - '-dDEVICEWIDTHPOINTS=%d -dDEVICEHEIGHTPOINTS=%d '\ - '-dFIXEDMEDIA -sOutputFile="%s" -sDEVICE=pdfwrite '\ - '-c "<> '\ - 'setpagedevice" -f "%s"' % ( - _GS_CMD, width_pt + 10, height_pt + 10, tmp_pdf_piece, - margin_l, margin_b, margin_r, margin_t, - page_offset_x + 5, page_offset_y + 5, tmp_ps) + command = ( + "%s -q -dBATCH -dNOPAUSE -dSAFER " + "-dDEVICEWIDTHPOINTS=%d -dDEVICEHEIGHTPOINTS=%d " + '-dFIXEDMEDIA -sOutputFile="%s" -sDEVICE=pdfwrite ' + '-c "<> ' + 'setpagedevice" -f "%s"' + % ( + _GS_CMD, + width_pt + 10, + height_pt + 10, + tmp_pdf_piece, + margin_l, + margin_b, + margin_r, + margin_t, + page_offset_x + 5, + page_offset_y + 5, + tmp_ps, + ) + ) # Execute Ghostscript os.system(command) # Merge pieces to single multipage PDF ; - command = '%s -q -dBATCH -dNOPAUSE '\ - '-sOUTPUTFILE="%s" -sDEVICE=pdfwrite %s '\ - % (_GS_CMD, self._filename, ' '.join(list_of_pieces)) + command = ( + "%s -q -dBATCH -dNOPAUSE " + '-sOUTPUTFILE="%s" -sDEVICE=pdfwrite %s ' + % (_GS_CMD, self._filename, " ".join(list_of_pieces)) + ) os.system(command) # Clean temporary files @@ -1054,66 +1143,102 @@ def close(self): os.remove(tmp_pdf_piece) os.remove(tmp_dot) -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ # # Various Graphviz formats. # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ FORMATS = [] if _DOT_FOUND: - if _GS_CMD != "": - FORMATS += [{'type' : "gspdf", - 'ext' : "pdf", - 'descr': _("PDF (Ghostscript)"), - 'mime' : "application/pdf", - 'class': GVPdfGsDoc}] - - FORMATS += [{'type' : "gvpdf", - 'ext' : "pdf", - 'descr': _("PDF (Graphviz)"), - 'mime' : "application/pdf", - 'class': GVPdfGvDoc}] - - FORMATS += [{'type' : "ps", - 'ext' : "ps", - 'descr': _("PostScript"), - 'mime' : "application/postscript", - 'class': GVPsDoc}] - - FORMATS += [{'type' : "svg", - 'ext' : "svg", - 'descr': _("Structured Vector Graphics (SVG)"), - 'mime' : "image/svg", - 'class': GVSvgDoc}] - - FORMATS += [{'type' : "svgz", - 'ext' : "svgz", - 'descr': _("Compressed Structured Vector Graphs (SVGZ)"), - 'mime' : "image/svgz", - 'class': GVSvgzDoc}] - - FORMATS += [{'type' : "jpg", - 'ext' : "jpg", - 'descr': _("JPEG image"), - 'mime' : "image/jpeg", - 'class': GVJpegDoc}] - - FORMATS += [{'type' : "gif", - 'ext' : "gif", - 'descr': _("GIF image"), - 'mime' : "image/gif", - 'class': GVGifDoc}] - - FORMATS += [{'type' : "png", - 'ext' : "png", - 'descr': _("PNG image"), - 'mime' : "image/png", - 'class': GVPngDoc}] - -FORMATS += [{'type' : "dot", - 'ext' : "gv", - 'descr': _("Graphviz File"), - 'mime' : "text/x-graphviz", - 'class': GVDotDoc}] + FORMATS += [ + { + "type": "gspdf", + "ext": "pdf", + "descr": _("PDF (Ghostscript)"), + "mime": "application/pdf", + "class": GVPdfGsDoc, + } + ] + + FORMATS += [ + { + "type": "gvpdf", + "ext": "pdf", + "descr": _("PDF (Graphviz)"), + "mime": "application/pdf", + "class": GVPdfGvDoc, + } + ] + + FORMATS += [ + { + "type": "ps", + "ext": "ps", + "descr": _("PostScript"), + "mime": "application/postscript", + "class": GVPsDoc, + } + ] + + FORMATS += [ + { + "type": "svg", + "ext": "svg", + "descr": _("Structured Vector Graphics (SVG)"), + "mime": "image/svg", + "class": GVSvgDoc, + } + ] + + FORMATS += [ + { + "type": "svgz", + "ext": "svgz", + "descr": _("Compressed Structured Vector Graphs (SVGZ)"), + "mime": "image/svgz", + "class": GVSvgzDoc, + } + ] + + FORMATS += [ + { + "type": "jpg", + "ext": "jpg", + "descr": _("JPEG image"), + "mime": "image/jpeg", + "class": GVJpegDoc, + } + ] + + FORMATS += [ + { + "type": "gif", + "ext": "gif", + "descr": _("GIF image"), + "mime": "image/gif", + "class": GVGifDoc, + } + ] + + FORMATS += [ + { + "type": "png", + "ext": "png", + "descr": _("PNG image"), + "mime": "image/png", + "class": GVPngDoc, + } + ] + +FORMATS += [ + { + "type": "dot", + "ext": "gv", + "descr": _("Graphviz File"), + "mime": "text/x-graphviz", + "class": GVDotDoc, + } +] diff --git a/gramps/gen/plug/docgen/graphicstyle.py b/gramps/gen/plug/docgen/graphicstyle.py index 50b21c10f71..cd7e05a301e 100644 --- a/gramps/gen/plug/docgen/graphicstyle.py +++ b/gramps/gen/plug/docgen/graphicstyle.py @@ -24,33 +24,34 @@ # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + log = logging.getLogger(".graphicstyle") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Line style # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- SOLID = 0 DASHED = 1 DOTTED = 2 @@ -60,27 +61,30 @@ # 2) the style names are used by the ODF generator and should be unique # 3) the line style constants above need to be imported in the # gen.plug.docgen.__init__ file so they can be used in a report add-on -line_style_names = ('solid', 'dashed', 'dotted') -_DASH_ARRAY = [ [1, 0], [2, 4], [1, 2] ] +line_style_names = ("solid", "dashed", "dotted") +_DASH_ARRAY = [[1, 0], [2, 4], [1, 2]] + def get_line_style_by_name(style_name): which = 0 - for (idx, sn) in enumerate(line_style_names): + for idx, sn in enumerate(line_style_names): if sn == style_name: which = idx break return _DASH_ARRAY[which] -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # GraphicsStyle # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class GraphicsStyle: """ Defines the properties of graphics objects, such as line width, color, fill, ect. """ + def __init__(self, obj=None): """ Initialize the object with default values, unless a source @@ -136,7 +140,7 @@ def get_line_style(self): def set_line_style(self, val): self.lstyle = val - def get_dash_style(self, val = None): + def get_dash_style(self, val=None): if val is None: val = self.lstyle if val >= 0 and val < len(_DASH_ARRAY): diff --git a/gramps/gen/plug/docgen/paperstyle.py b/gramps/gen/plug/docgen/paperstyle.py index 4fb61e58012..41f4893c4ad 100644 --- a/gramps/gen/plug/docgen/paperstyle.py +++ b/gramps/gen/plug/docgen/paperstyle.py @@ -23,46 +23,50 @@ # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + log = logging.getLogger(".paperstyle") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Page orientation # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- PAPER_PORTRAIT = 0 PAPER_LANDSCAPE = 1 -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # PaperSize # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class PaperSize: """ Defines the dimensions of a sheet of paper. All dimensions are in centimeters. """ + def __init__(self, name, height, width): """ Create a new paper style with. @@ -74,12 +78,12 @@ def __init__(self, name, height, width): self.name = name self.height = height self.width = width - if self.name == 'Letter': - self.trans_pname = _('Letter', 'paper size') - elif self.name == 'Legal': - self.trans_pname = _('Legal', 'paper size') - elif self.name == 'Custom Size': - self.trans_pname = _('Custom Size') + if self.name == "Letter": + self.trans_pname = _("Letter", "paper size") + elif self.name == "Legal": + self.trans_pname = _("Legal", "paper size") + elif self.name == "Custom Size": + self.trans_pname = _("Custom Size") else: self.trans_pname = None @@ -111,17 +115,20 @@ def get_width_inches(self): "Return the page width in inches" return self.width / 2.54 -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # PaperStyle # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class PaperStyle: """ Define the various options for a sheet of paper. """ - def __init__(self, size, orientation, - lmargin=2.54, rmargin=2.54, tmargin=2.54, bmargin=2.54): + + def __init__( + self, size, orientation, lmargin=2.54, rmargin=2.54, tmargin=2.54, bmargin=2.54 + ): """ Create a new paper style. @@ -134,13 +141,13 @@ def __init__(self, size, orientation, self.__orientation = orientation if orientation == PAPER_PORTRAIT: - self.__size = PaperSize(size.get_name(), - size.get_height(), - size.get_width()) + self.__size = PaperSize( + size.get_name(), size.get_height(), size.get_width() + ) else: - self.__size = PaperSize(size.get_name(), - size.get_width(), - size.get_height()) + self.__size = PaperSize( + size.get_name(), size.get_width(), size.get_height() + ) self.__lmargin = lmargin self.__rmargin = rmargin self.__tmargin = tmargin diff --git a/gramps/gen/plug/docgen/paragraphstyle.py b/gramps/gen/plug/docgen/paragraphstyle.py index 2fc66679884..5ab47ccc107 100644 --- a/gramps/gen/plug/docgen/paragraphstyle.py +++ b/gramps/gen/plug/docgen/paragraphstyle.py @@ -22,42 +22,44 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .fontstyle import FontStyle -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + log = logging.getLogger(".paragraphstyle") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Paragraph alignment # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- PARA_ALIGN_CENTER = 0 PARA_ALIGN_LEFT = 1 PARA_ALIGN_RIGHT = 2 PARA_ALIGN_JUSTIFY = 3 -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # ParagraphStyle # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class ParagraphStyle: """ Defines the characteristics of a paragraph. The characteristics are: @@ -66,6 +68,7 @@ class ParagraphStyle: bottom border, right border, left border, padding, and background color. """ + def __init__(self, source=None): """ :param source: if not None, then the ParagraphStyle is created using the @@ -118,10 +121,22 @@ def get_description(self): """ return self.description - def set(self, rmargin=None, lmargin=None, first_indent=None, - tmargin=None, bmargin=None, align=None, - tborder=None, bborder=None, rborder=None, lborder=None, - pad=None, bgcolor=None, font=None): + def set( + self, + rmargin=None, + lmargin=None, + first_indent=None, + tmargin=None, + bmargin=None, + align=None, + tborder=None, + bborder=None, + rborder=None, + lborder=None, + pad=None, + bgcolor=None, + font=None, + ): """ Allows the values of the object to be set. diff --git a/gramps/gen/plug/docgen/stylesheet.py b/gramps/gen/plug/docgen/stylesheet.py index a5b260c6bae..b8d832c9665 100644 --- a/gramps/gen/plug/docgen/stylesheet.py +++ b/gramps/gen/plug/docgen/stylesheet.py @@ -24,50 +24,54 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import os from xml.sax.saxutils import escape + def escxml(string): """ Escapes XML special characters. """ - return escape(string, { '"' : '"' } ) + return escape(string, {'"': """}) + -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from .paragraphstyle import ParagraphStyle from .fontstyle import FontStyle from .tablestyle import TableStyle, TableCellStyle from .graphicstyle import GraphicsStyle -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + log = logging.getLogger(".stylesheet") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # SAX interface # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from xml.sax import make_parser, handler, SAXParseException -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # cnv2color # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ def cnv2color(text): """ converts a hex value in the form of #XXXXXX into a tuple of integers @@ -76,11 +80,11 @@ def cnv2color(text): return (int(text[1:3], 16), int(text[3:5], 16), int(text[5:7], 16)) -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # StyleSheetList # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class StyleSheetList: """ Interface into the user's defined style sheets. Each StyleSheetList @@ -96,8 +100,8 @@ def __init__(self, filename, defstyle): file - XML file that contains style definitions defstyle - default style """ - defstyle.set_name('default') - self.map = { "default" : defstyle } + defstyle.set_name("default") + self.map = {"default": defstyle} self.__file = filename self.parse() @@ -146,9 +150,9 @@ def save(self): """ with open(self.__file, "w") as xml_file: xml_file.write('\n') - xml_file.write('\n') + xml_file.write("\n") - for name in sorted(self.map.keys()): # enable diff of archived ones + for name in sorted(self.map.keys()): # enable diff of archived ones if name == "default": continue sheet = self.map[name] @@ -166,11 +170,10 @@ def save(self): for g_name in sorted(sheet.get_draw_style_names()): self.write_graphics_style(xml_file, sheet, g_name) - xml_file.write(' \n') - xml_file.write('\n') + xml_file.write(" \n") + xml_file.write("\n") def write_paragraph_style(self, xml_file, sheet, p_name): - para = sheet.get_paragraph_style(p_name) # Get variables for substitutions @@ -185,90 +188,88 @@ def write_paragraph_style(self, xml_file, sheet, p_name): # Write out style definition xml_file.write( - ' \n' + ' \n" ) def write_table_style(self, xml_file, sheet, t_name): - t_style = sheet.get_table_style(t_name) # Write out style definition xml_file.write( - ' \n') + xml_file.write(" \n") + xml_file.write(" \n") def write_cell_style(self, xml_file, sheet, c_name): - cell = sheet.get_cell_style(c_name) # Write out style definition xml_file.write( - ' \n' + ' \n" ) def write_graphics_style(self, xml_file, sheet, g_name): - draw = sheet.get_draw_style(g_name) # Write out style definition xml_file.write( - ' \n' + ' \n" ) def parse(self): @@ -284,11 +285,12 @@ def parse(self): except (IOError, OSError, SAXParseException): pass -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # StyleSheet # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class StyleSheet: """ A collection of named paragraph styles. @@ -339,10 +341,12 @@ def clear(self): def is_empty(self): "Checks if any styles are defined" - style_count = len(self.para_styles) + \ - len(self.draw_styles) + \ - len(self.table_styles) + \ - len(self.cell_styles) + style_count = ( + len(self.para_styles) + + len(self.draw_styles) + + len(self.table_styles) + + len(self.cell_styles) + ) if style_count > 0: return False else: @@ -432,11 +436,12 @@ def get_cell_style_names(self): "Return the list of cell style names in the StyleSheet" return list(self.cell_styles.keys()) -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # SheetParser # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SheetParser(handler.ContentHandler): """ SAX parsing class for the StyleSheetList XML file. @@ -465,69 +470,68 @@ def startElement(self, tag, attrs): """ if tag == "sheet": self.s = StyleSheet(self.sheetlist.map["default"]) - self.sheet_name = attrs['name'] + self.sheet_name = attrs["name"] elif tag == "font": self.f = FontStyle() - self.f.set_type_face(int(attrs['face'])) - self.f.set_size(int(attrs['size'])) - self.f.set_italic(int(attrs['italic'])) - self.f.set_bold(int(attrs['bold'])) - self.f.set_underline(int(attrs['underline'])) - self.f.set_color(cnv2color(attrs['color'])) + self.f.set_type_face(int(attrs["face"])) + self.f.set_size(int(attrs["size"])) + self.f.set_italic(int(attrs["italic"])) + self.f.set_bold(int(attrs["bold"])) + self.f.set_underline(int(attrs["underline"])) + self.f.set_color(cnv2color(attrs["color"])) elif tag == "para": self.p = ParagraphStyle() - if 'description' in attrs: - self.p.set_description(attrs['description']) - self.p.set_right_margin(float(attrs['rmargin'])) - self.p.set_left_margin(float(attrs['lmargin'])) - self.p.set_first_indent(float(attrs['first'])) + if "description" in attrs: + self.p.set_description(attrs["description"]) + self.p.set_right_margin(float(attrs["rmargin"])) + self.p.set_left_margin(float(attrs["lmargin"])) + self.p.set_first_indent(float(attrs["first"])) try: # This is needed to read older style files # lacking tmargin and bmargin - self.p.set_top_margin(float(attrs['tmargin'])) - self.p.set_bottom_margin(float(attrs['bmargin'])) + self.p.set_top_margin(float(attrs["tmargin"])) + self.p.set_bottom_margin(float(attrs["bmargin"])) except KeyError: pass - self.p.set_padding(float(attrs['pad'])) - self.p.set_alignment(int(attrs['align'])) - self.p.set_right_border(int(attrs['rborder'])) - self.p.set_header_level(int(attrs['level'])) - self.p.set_left_border(int(attrs['lborder'])) - self.p.set_top_border(int(attrs['tborder'])) - self.p.set_bottom_border(int(attrs['bborder'])) - self.p.set_background_color(cnv2color(attrs['bgcolor'])) + self.p.set_padding(float(attrs["pad"])) + self.p.set_alignment(int(attrs["align"])) + self.p.set_right_border(int(attrs["rborder"])) + self.p.set_header_level(int(attrs["level"])) + self.p.set_left_border(int(attrs["lborder"])) + self.p.set_top_border(int(attrs["tborder"])) + self.p.set_bottom_border(int(attrs["bborder"])) + self.p.set_background_color(cnv2color(attrs["bgcolor"])) self.p.set_font(self.f) elif tag == "style": - self.style_name = attrs['name'] + self.style_name = attrs["name"] elif tag == "table": self.t = TableStyle() - if 'description' in attrs: - self.t.set_description(attrs['description']) - self.t.set_width(int(attrs['width'])) - self.t.set_columns(int(attrs['columns'])) + if "description" in attrs: + self.t.set_description(attrs["description"]) + self.t.set_width(int(attrs["width"])) + self.t.set_columns(int(attrs["columns"])) self.column_widths = [] elif tag == "column": - self.column_widths.append(int(attrs['width'])) + self.column_widths.append(int(attrs["width"])) elif tag == "cell": self.c = TableCellStyle() - if 'description' in attrs: - self.c.set_description(attrs['description']) - self.c.set_left_border(int(attrs['lborder'])) - self.c.set_right_border(int(attrs['rborder'])) - self.c.set_top_border(int(attrs['tborder'])) - self.c.set_bottom_border(int(attrs['bborder'])) - self.c.set_padding(float(attrs['pad'])) + if "description" in attrs: + self.c.set_description(attrs["description"]) + self.c.set_left_border(int(attrs["lborder"])) + self.c.set_right_border(int(attrs["rborder"])) + self.c.set_top_border(int(attrs["tborder"])) + self.c.set_bottom_border(int(attrs["bborder"])) + self.c.set_padding(float(attrs["pad"])) elif tag == "draw": self.g = GraphicsStyle() - if 'description' in attrs: - self.g.set_description(attrs['description']) - self.g.set_paragraph_style(attrs['para']) - self.g.set_line_width(float(attrs['width'])) - self.g.set_line_style(int(attrs['style'])) - self.g.set_color(cnv2color(attrs['color'])) - self.g.set_fill_color(cnv2color(attrs['fillcolor'])) - self.g.set_shadow(int(attrs['shadow']), - float(attrs['space'])) + if "description" in attrs: + self.g.set_description(attrs["description"]) + self.g.set_paragraph_style(attrs["para"]) + self.g.set_line_width(float(attrs["width"])) + self.g.set_line_style(int(attrs["style"])) + self.g.set_color(cnv2color(attrs["color"])) + self.g.set_fill_color(cnv2color(attrs["fillcolor"])) + self.g.set_shadow(int(attrs["shadow"]), float(attrs["space"])) def endElement(self, tag): "Overridden class that handles the end of a XML element" diff --git a/gramps/gen/plug/docgen/tablestyle.py b/gramps/gen/plug/docgen/tablestyle.py index cf1472fa9b8..674e502374d 100644 --- a/gramps/gen/plug/docgen/tablestyle.py +++ b/gramps/gen/plug/docgen/tablestyle.py @@ -22,31 +22,33 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + log = logging.getLogger(".tablestyle") -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # TableStyle # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class TableStyle: """ Specifies the style or format of a table. The TableStyle contains the @@ -54,6 +56,7 @@ class TableStyle: number of columns, and the width of each column as a percentage of the width of the table. """ + def __init__(self, obj=None): """ Create a new TableStyle object, with the values initialized to @@ -71,7 +74,7 @@ def __init__(self, obj=None): else: self.width = 0 self.columns = 0 - self.colwid = [ 0 ] * 100 + self.colwid = [0] * 100 self.description = "" def set_description(self, text): @@ -140,16 +143,18 @@ def get_column_width(self, index): """ return self.colwid[index] -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # TableCellStyle # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class TableCellStyle: """ Defines the style of a particular table cell. Characteristics are: right border, left border, top border, bottom border, and padding. """ + def __init__(self, obj=None): """ Create a new TableCellStyle instance. diff --git a/gramps/gen/plug/docgen/textdoc.py b/gramps/gen/plug/docgen/textdoc.py index cd26ffd6d84..b27ade10931 100644 --- a/gramps/gen/plug/docgen/textdoc.py +++ b/gramps/gen/plug/docgen/textdoc.py @@ -25,54 +25,58 @@ # - -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from abc import ABCMeta, abstractmethod -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging + log = logging.getLogger(".textdoc") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # URL string pattern # -#------------------------------------------------------------------------- -URL_PATTERN = r'''(((https?|mailto):)(//([^ /?#"]*))?([^ ?#"]*)(\?([^ #"]*))?(#([^ "]*))?)''' +# ------------------------------------------------------------------------- +URL_PATTERN = ( + r"""(((https?|mailto):)(//([^ /?#"]*))?([^ ?#"]*)(\?([^ #"]*))?(#([^ "]*))?)""" +) -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # IndexMark types # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- INDEX_TYPE_ALP = 0 INDEX_TYPE_TOC = 1 LOCAL_HYPERLINK = 2 LOCAL_TARGET = 3 -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # IndexMark # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class IndexMark: """ Defines a mark to be associated with text for indexing. """ + def __init__(self, key="", itype=INDEX_TYPE_ALP, level=1): """ Initialize the object with default values, unless values are specified. @@ -82,11 +86,12 @@ def __init__(self, key="", itype=INDEX_TYPE_ALP, level=1): self.level = level -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # TextDoc # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ + class TextDoc(metaclass=ABCMeta): """ @@ -209,8 +214,9 @@ def write_markup(self, text, s_tags, mark=None): """ self.write_text(text, mark=mark) - def write_styled_note(self, styledtext, format, style_name, - contains_html=False, links=False): + def write_styled_note( + self, styledtext, format, style_name, contains_html=False, links=False + ): """ Convenience function to write a styledtext to the cairo doc. @@ -247,7 +253,7 @@ def write_text_citation(self, text, mark=None, links=None): self.write_text(piecesplit[0], links=links) self.end_superscript() if not piecesplit[1]: - #text ended with ' ... ' + # text ended with ' ... ' continue if not markset: self.write_text(piecesplit[1], mark, links=links) @@ -262,7 +268,7 @@ def write_text_citation(self, text, mark=None, links=None): self.write_text(piece, links=links) @abstractmethod - def add_media(self, name, align, w_cm, h_cm, alt='', style_name=None, crop=None): + def add_media(self, name, align, w_cm, h_cm, alt="", style_name=None, crop=None): """ Add a photo of the specified width (in centimeters). diff --git a/gramps/gen/plug/docgen/treedoc.py b/gramps/gen/plug/docgen/treedoc.py index ef12e59254d..8d6a76a7909 100644 --- a/gramps/gen/plug/docgen/treedoc.py +++ b/gramps/gen/plug/docgen/treedoc.py @@ -18,11 +18,11 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # """ LaTeX Genealogy Tree adapter for Trees """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from abc import ABCMeta, abstractmethod import os import shutil @@ -32,11 +32,11 @@ import tempfile import logging -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...utils.file import search_for from ...lib import Person, EventType, EventRoleType, Date from ...display.place import displayer as _pd @@ -46,65 +46,87 @@ from ...constfunc import win from ...config import config from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- LOG = logging.getLogger(".treedoc") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Private Constants # -#------------------------------------------------------------------------- -_DETAIL = [{'name': _("Full"), 'value': "full"}, - {'name': _("Medium"), 'value': "medium"}, - {'name': _("Short"), 'value': "short"}] - -_NAME_FORMAT = [{'name': _("Given Nickname Surname"), 'value': "1"}, - {'name': _("Surname Given Nickname"), 'value': "2"}, - {'name': _("Surname, Given Nickname"), 'value': "3"}, - {'name': _("GivenNicknameSurname"), 'value': "4"}] - -_PREFERRED_NAME = [{'name': _("Auto"), 'value': "1"}, - {'name': _("Call Name Only"), 'value': "2"}, - {'name': _("Whole Given Name"), 'value': "3"}] - -_MARRIAGE = [{'name': _("Default"), 'value': ""}, - {'name': _("Above"), 'value': "marriage above"}, - {'name': _("Below"), 'value': "marriage below"}, - {'name': _("Not shown"), 'value': "no marriage"}] - -_COLOR = [{'name': _("None"), 'value': "none"}, - {'name': _("Default"), 'value': "default"}, - {'name': _("Preferences"), 'value': "preferences"}] - -_TIMEFLOW = [{'name': _("Down (↓)"), 'value': ""}, - {'name': _("Up (↑)"), 'value': "up"}, - {'name': _("Right (→)"), 'value': "right"}, - {'name': _("Left (←)"), 'value': "left"}] - -_EDGES = [{'name': _("Perpendicular"), 'value': ""}, - {'name': _("Rounded"), 'value': "rounded", }, - {'name': _("Swing"), 'value': "swing", }, - {'name': _("Mesh"), 'value': 'mesh'}] - -_NOTELOC = [{'name': _("Top"), 'value': "t"}, - {'name': _("Bottom"), 'value': "b"}] - -_NOTESIZE = [{'name': _("Tiny"), 'value': "tiny"}, - {'name': _("Script"), 'value': "scriptsize"}, - {'name': _("Footnote"), 'value': "footnotesize"}, - {'name': _("Small"), 'value': "small"}, - {'name': _("Normal"), 'value': "normalsize"}, - {'name': _("Large"), 'value': "large"}, - {'name': _("Very large"), 'value': "Large"}, - {'name': _("Extra large"), 'value': "LARGE"}, - {'name': _("Huge"), 'value': "huge"}, - {'name': _("Extra huge"), 'value': "Huge"}] +# ------------------------------------------------------------------------- +_DETAIL = [ + {"name": _("Full"), "value": "full"}, + {"name": _("Medium"), "value": "medium"}, + {"name": _("Short"), "value": "short"}, +] + +_NAME_FORMAT = [ + {"name": _("Given Nickname Surname"), "value": "1"}, + {"name": _("Surname Given Nickname"), "value": "2"}, + {"name": _("Surname, Given Nickname"), "value": "3"}, + {"name": _("GivenNicknameSurname"), "value": "4"}, +] + +_PREFERRED_NAME = [ + {"name": _("Auto"), "value": "1"}, + {"name": _("Call Name Only"), "value": "2"}, + {"name": _("Whole Given Name"), "value": "3"}, +] + +_MARRIAGE = [ + {"name": _("Default"), "value": ""}, + {"name": _("Above"), "value": "marriage above"}, + {"name": _("Below"), "value": "marriage below"}, + {"name": _("Not shown"), "value": "no marriage"}, +] + +_COLOR = [ + {"name": _("None"), "value": "none"}, + {"name": _("Default"), "value": "default"}, + {"name": _("Preferences"), "value": "preferences"}, +] + +_TIMEFLOW = [ + {"name": _("Down (↓)"), "value": ""}, + {"name": _("Up (↑)"), "value": "up"}, + {"name": _("Right (→)"), "value": "right"}, + {"name": _("Left (←)"), "value": "left"}, +] + +_EDGES = [ + {"name": _("Perpendicular"), "value": ""}, + { + "name": _("Rounded"), + "value": "rounded", + }, + { + "name": _("Swing"), + "value": "swing", + }, + {"name": _("Mesh"), "value": "mesh"}, +] + +_NOTELOC = [{"name": _("Top"), "value": "t"}, {"name": _("Bottom"), "value": "b"}] + +_NOTESIZE = [ + {"name": _("Tiny"), "value": "tiny"}, + {"name": _("Script"), "value": "scriptsize"}, + {"name": _("Footnote"), "value": "footnotesize"}, + {"name": _("Small"), "value": "small"}, + {"name": _("Normal"), "value": "normalsize"}, + {"name": _("Large"), "value": "large"}, + {"name": _("Very large"), "value": "Large"}, + {"name": _("Extra large"), "value": "LARGE"}, + {"name": _("Huge"), "value": "huge"}, + {"name": _("Extra huge"), "value": "Huge"}, +] if win(): _LATEX_FOUND = search_for("lualatex.exe") @@ -112,46 +134,49 @@ else: _LATEX_FOUND = search_for("lualatex") + def escape(text): lookup = { - '&': '\\&', - '%': '\\%', - '$': '\\$', - '#': '\\#', - '_': '\\_', - '{': '\\{', - '}': '\\}', - '~': '\\~{}', - '^': '\\^{}', - '\\': '\\textbackslash{}' - } - pattern = re.compile('|'.join([re.escape(key) for key in lookup.keys()])) + "&": "\\&", + "%": "\\%", + "$": "\\$", + "#": "\\#", + "_": "\\_", + "{": "\\{", + "}": "\\}", + "~": "\\~{}", + "^": "\\^{}", + "\\": "\\textbackslash{}", + } + pattern = re.compile("|".join([re.escape(key) for key in lookup.keys()])) return pattern.sub(lambda match: lookup[match.group(0)], text) -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ # # TreeOptions # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class TreeOptions: """ Defines all of the controls necessary to configure the genealogy tree reports. """ + def __init__(self): - #Node Options + # Node Options self.detail = None self.marriage = None self.nodesize = None self.levelsize = None self.nodecolor = None - #Tree Options + # Tree Options self.timeflow = None self.edges = None self.leveldist = None - #Note + # Note self.note = None self.noteloc = None self.notesize = None @@ -184,10 +209,14 @@ def add_menu_options(self, menu): preferred_name = EnumeratedListOption(_("Preferred Name"), "1") for item in _PREFERRED_NAME: preferred_name.add_item(item["value"], item["name"]) - preferred_name.set_help(_("Select the portion of the given name to be " - "marked as preferred. Auto sets the call " - "name if one exists, otherwise the whole " - "given name.")) + preferred_name.set_help( + _( + "Select the portion of the given name to be " + "marked as preferred. Auto sets the call " + "name if one exists, otherwise the whole " + "given name." + ) + ) menu.add_option(category, "preferred_name", preferred_name) marriage = EnumeratedListOption(_("Marriage"), "") @@ -198,16 +227,24 @@ def add_menu_options(self, menu): self.marriage = marriage nodesize = NumberOption(_("Node size"), 25, 5, 100, 5) - nodesize.set_help(_("One dimension of a node, in mm. If the timeflow " - "is up or down then this is the width, otherwise " - "it is the height.")) + nodesize.set_help( + _( + "One dimension of a node, in mm. If the timeflow " + "is up or down then this is the width, otherwise " + "it is the height." + ) + ) menu.add_option(category, "nodesize", nodesize) self.nodesize = nodesize levelsize = NumberOption(_("Level size"), 35, 5, 100, 5) - levelsize.set_help(_("One dimension of a node, in mm. If the timeflow " - "is up or down then this is the height, otherwise " - "it is the width.")) + levelsize.set_help( + _( + "One dimension of a node, in mm. If the timeflow " + "is up or down then this is the height, otherwise " + "it is the width." + ) + ) menu.add_option(category, "levelsize", levelsize) self.levelsize = levelsize @@ -237,11 +274,15 @@ def add_menu_options(self, menu): self.edges = edges leveldist = NumberOption(_("Level distance"), 5, 1, 20, 1) - leveldist.set_help(_("The minimum amount of free space, in mm, " - "between levels. For vertical graphs, this " - "corresponds to spacing between rows. For " - "horizontal graphs, this corresponds to spacing " - "between columns.")) + leveldist.set_help( + _( + "The minimum amount of free space, in mm, " + "between levels. For vertical graphs, this " + "corresponds to spacing between rows. For " + "horizontal graphs, this corresponds to spacing " + "between columns." + ) + ) menu.add_option(category, "leveldist", leveldist) self.leveldist = leveldist @@ -255,15 +296,14 @@ def add_menu_options(self, menu): menu.add_option(category, "note", note) self.note = note - noteloc = EnumeratedListOption(_("Note location"), 't') + noteloc = EnumeratedListOption(_("Note location"), "t") for item in _NOTELOC: noteloc.add_item(item["value"], item["name"]) - noteloc.set_help(_("Whether note will appear on top " - "or bottom of the page.")) + noteloc.set_help(_("Whether note will appear on top " "or bottom of the page.")) menu.add_option(category, "noteloc", noteloc) self.noteloc = noteloc - notesize = EnumeratedListOption(_("Note size"), 'normalsize') + notesize = EnumeratedListOption(_("Note size"), "normalsize") for item in _NOTESIZE: notesize.add_item(item["value"], item["name"]) notesize.set_help(_("The size of note text.")) @@ -271,17 +311,18 @@ def add_menu_options(self, menu): self.notesize = notesize -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # TreeDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class TreeDoc(metaclass=ABCMeta): """ Abstract Interface for genealogy tree document generators. Output formats for genealogy tree reports must implement this interface to be used by the report system. """ + @abstractmethod def start_tree(self, option_list): """ @@ -307,24 +348,24 @@ def end_subgraph(self, level): """ @abstractmethod - def write_node(self, db, level, node_type, person, marriage_flag, - option_list=None): + def write_node(self, db, level, node_type, person, marriage_flag, option_list=None): """ Write the contents of a node. """ -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # TreeDocBase # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class TreeDocBase(BaseDoc, TreeDoc): """ Base document generator for all Graphviz document generators. Classes that inherit from this class will only need to implement the close function. The close function will generate the actual file of the appropriate type. """ + def __init__(self, options, paper_style): BaseDoc.__init__(self, None, paper_style) @@ -334,21 +375,21 @@ def __init__(self, options, paper_style): get_option = options.menu.get_option_by_name - self.detail = get_option('detail').get_value() - self.name_format = get_option('name_format').get_value() - self.preferred_name = get_option('preferred_name').get_value() - self.marriage = get_option('marriage').get_value() - self.nodesize = get_option('nodesize').get_value() - self.levelsize = get_option('levelsize').get_value() - self.nodecolor = get_option('nodecolor').get_value() + self.detail = get_option("detail").get_value() + self.name_format = get_option("name_format").get_value() + self.preferred_name = get_option("preferred_name").get_value() + self.marriage = get_option("marriage").get_value() + self.nodesize = get_option("nodesize").get_value() + self.levelsize = get_option("levelsize").get_value() + self.nodecolor = get_option("nodecolor").get_value() - self.timeflow = get_option('timeflow').get_value() - self.edges = get_option('edges').get_value() - self.leveldist = get_option('leveldist').get_value() + self.timeflow = get_option("timeflow").get_value() + self.edges = get_option("edges").get_value() + self.leveldist = get_option("leveldist").get_value() - self.note = get_option('note').get_value() - self.noteloc = get_option('noteloc').get_value() - self.notesize = get_option('notesize').get_value() + self.note = get_option("note").get_value() + self.noteloc = get_option("noteloc").get_value() + self.notesize = get_option("notesize").get_value() def write_start(self): """ @@ -356,190 +397,205 @@ def write_start(self): """ paper_size = self._paper.get_size() name = paper_size.get_name().lower() - if name == 'custom size': + if name == "custom size": width = str(paper_size.get_width()) height = str(paper_size.get_height()) - paper = 'papersize={%scm,%scm}' % (width, height) - elif name in ('a', 'b', 'c', 'd', 'e'): - paper = 'ansi' + name + 'paper' + paper = "papersize={%scm,%scm}" % (width, height) + elif name in ("a", "b", "c", "d", "e"): + paper = "ansi" + name + "paper" else: - paper = name + 'paper' + paper = name + "paper" if self._paper.get_orientation() == PAPER_PORTRAIT: - orientation = 'portrait' + orientation = "portrait" else: - orientation = 'landscape' + orientation = "landscape" lmargin = self._paper.get_left_margin() rmargin = self._paper.get_right_margin() tmargin = self._paper.get_top_margin() bmargin = self._paper.get_bottom_margin() if lmargin == rmargin == tmargin == bmargin: - margin = 'margin=%scm'% lmargin + margin = "margin=%scm" % lmargin else: if lmargin == rmargin: - margin = 'hmargin=%scm' % lmargin + margin = "hmargin=%scm" % lmargin else: - margin = 'hmargin={%scm,%scm}' % (lmargin, rmargin) + margin = "hmargin={%scm,%scm}" % (lmargin, rmargin) if tmargin == bmargin: - margin += ',vmargin=%scm' % tmargin + margin += ",vmargin=%scm" % tmargin else: - margin += ',vmargin={%scm,%scm}' % (tmargin, bmargin) + margin += ",vmargin={%scm,%scm}" % (tmargin, bmargin) - self.write(0, '\\documentclass[%s]{article}\n' % orientation) + self.write(0, "\\documentclass[%s]{article}\n" % orientation) - self.write(0, '\\IfFileExists{libertine.sty}{\n') - self.write(0, ' \\usepackage{libertine}\n') - self.write(0, '}{}\n') + self.write(0, "\\IfFileExists{libertine.sty}{\n") + self.write(0, " \\usepackage{libertine}\n") + self.write(0, "}{}\n") - self.write(0, '\\usepackage[%s,%s]{geometry}\n' % (paper, margin)) - self.write(0, '\\usepackage[all]{genealogytree}\n') - self.write(0, '\\usepackage{color}\n') - self.write(0, '\\begin{document}\n') + self.write(0, "\\usepackage[%s,%s]{geometry}\n" % (paper, margin)) + self.write(0, "\\usepackage[all]{genealogytree}\n") + self.write(0, "\\usepackage{color}\n") + self.write(0, "\\begin{document}\n") - if self.nodecolor == 'preferences': - scheme = config.get('colors.scheme') - male_bg = config.get('colors.male-dead')[scheme][1:] - female_bg = config.get('colors.female-dead')[scheme][1:] - neuter_bg = config.get('colors.unknown-dead')[scheme][1:] - self.write(0, '\\definecolor{male-bg}{HTML}{%s}\n' % male_bg) - self.write(0, '\\definecolor{female-bg}{HTML}{%s}\n' % female_bg) - self.write(0, '\\definecolor{neuter-bg}{HTML}{%s}\n' % neuter_bg) + if self.nodecolor == "preferences": + scheme = config.get("colors.scheme") + male_bg = config.get("colors.male-dead")[scheme][1:] + female_bg = config.get("colors.female-dead")[scheme][1:] + neuter_bg = config.get("colors.unknown-dead")[scheme][1:] + self.write(0, "\\definecolor{male-bg}{HTML}{%s}\n" % male_bg) + self.write(0, "\\definecolor{female-bg}{HTML}{%s}\n" % female_bg) + self.write(0, "\\definecolor{neuter-bg}{HTML}{%s}\n" % neuter_bg) - if ''.join(self.note) != '' and self.noteloc == 't': + if "".join(self.note) != "" and self.noteloc == "t": for line in self.note: - self.write(0, '{\\%s %s}\\par\n' % (self.notesize, line)) - self.write(0, '\\bigskip\n') + self.write(0, "{\\%s %s}\\par\n" % (self.notesize, line)) + self.write(0, "\\bigskip\n") - self.write(0, '\\begin{tikzpicture}\n') + self.write(0, "\\begin{tikzpicture}\n") def start_tree(self, option_list): - self.write(0, '\\genealogytree[\n') - self.write(0, 'processing=database,\n') + self.write(0, "\\genealogytree[\n") + self.write(0, "processing=database,\n") if self.marriage: - info = self.detail + ' ' + self.marriage + info = self.detail + " " + self.marriage else: info = self.detail - self.write(0, 'database format=%s,\n' % info) + self.write(0, "database format=%s,\n" % info) if self.timeflow: - self.write(0, 'timeflow=%s,\n' % self.timeflow) + self.write(0, "timeflow=%s,\n" % self.timeflow) if self.edges: - self.write(0, 'edges=%s,\n' % self.edges) + self.write(0, "edges=%s,\n" % self.edges) if self.leveldist != 5: - self.write(0, 'level distance=%smm,\n' % self.leveldist) + self.write(0, "level distance=%smm,\n" % self.leveldist) if self.nodesize != 25: - self.write(0, 'node size=%smm,\n' % self.nodesize) + self.write(0, "node size=%smm,\n" % self.nodesize) if self.levelsize != 35: - self.write(0, 'level size=%smm,\n' % self.levelsize) - if self.nodecolor == 'none': - self.write(0, 'tcbset={male/.style={},\n') - self.write(0, ' female/.style={},\n') - self.write(0, ' neuter/.style={}},\n') - if self.nodecolor == 'preferences': - self.write(0, 'tcbset={male/.style={colback=male-bg},\n') - self.write(0, ' female/.style={colback=female-bg},\n') - self.write(0, ' neuter/.style={colback=neuter-bg}},\n') + self.write(0, "level size=%smm,\n" % self.levelsize) + if self.nodecolor == "none": + self.write(0, "tcbset={male/.style={},\n") + self.write(0, " female/.style={},\n") + self.write(0, " neuter/.style={}},\n") + if self.nodecolor == "preferences": + self.write(0, "tcbset={male/.style={colback=male-bg},\n") + self.write(0, " female/.style={colback=female-bg},\n") + self.write(0, " neuter/.style={colback=neuter-bg}},\n") for option in option_list: - self.write(0, '%s,\n' % option) + self.write(0, "%s,\n" % option) - self.write(0, ']{\n') + self.write(0, "]{\n") def end_tree(self): - self.write(0, '}\n') + self.write(0, "}\n") def write_end(self): """ Write the end of the document. """ - self.write(0, '\\end{tikzpicture}\n') + self.write(0, "\\end{tikzpicture}\n") - if ''.join(self.note) != '' and self.noteloc == 'b': - self.write(0, '\\bigskip\n') + if "".join(self.note) != "" and self.noteloc == "b": + self.write(0, "\\bigskip\n") for line in self.note: - self.write(0, '\\par{\\%s %s}\n' % (self.notesize, line)) + self.write(0, "\\par{\\%s %s}\n" % (self.notesize, line)) - self.write(0, '\\end{document}\n') + self.write(0, "\\end{document}\n") def start_subgraph(self, level, subgraph_type, family, option_list=None): - options = ['id=%s' % family.gramps_id] + options = ["id=%s" % family.gramps_id] if option_list: options.extend(option_list) - self.write(level, '%s[%s]{\n' % (subgraph_type, ','.join(options))) + self.write(level, "%s[%s]{\n" % (subgraph_type, ",".join(options))) def end_subgraph(self, level): - self.write(level, '}\n') + self.write(level, "}\n") - def write_node(self, db, level, node_type, person, marriage_flag, - option_list=None): - options = ['id=%s' % person.gramps_id] + def write_node(self, db, level, node_type, person, marriage_flag, option_list=None): + options = ["id=%s" % person.gramps_id] if option_list: options.extend(option_list) - self.write(level, '%s[%s]{\n' % (node_type, ','.join(options))) + self.write(level, "%s[%s]{\n" % (node_type, ",".join(options))) if person.gender == Person.MALE: - self.write(level+1, 'male,\n') + self.write(level + 1, "male,\n") elif person.gender == Person.FEMALE: - self.write(level+1, 'female,\n') + self.write(level + 1, "female,\n") elif person.gender in (Person.UNKNOWN, Person.OTHER): - self.write(level+1, 'neuter,\n') + self.write(level + 1, "neuter,\n") name = person.get_primary_name() nick = name.get_nick_name() surn = name.get_surname() if self.name_format == "1": - name_parts = [self.format_given_names(name), - '\\nick{{{}}}'.format(escape(nick)) if nick else '', - '\\surn{{{}}}'.format(escape(surn)) if surn else ''] - self.write(level+1, 'name = {{{}}},\n'.format( - ' '.join([e for e in name_parts if e]))) + name_parts = [ + self.format_given_names(name), + "\\nick{{{}}}".format(escape(nick)) if nick else "", + "\\surn{{{}}}".format(escape(surn)) if surn else "", + ] + self.write( + level + 1, + "name = {{{}}},\n".format(" ".join([e for e in name_parts if e])), + ) elif self.name_format == "2": - name_parts = ['\\surn{{{}}}'.format(escape(surn)) if surn else '', - self.format_given_names(name), - '\\nick{{{}}}'.format(escape(nick)) if nick else ''] - self.write(level+1, 'name = {{{}}},\n'.format( - ' '.join([e for e in name_parts if e]))) + name_parts = [ + "\\surn{{{}}}".format(escape(surn)) if surn else "", + self.format_given_names(name), + "\\nick{{{}}}".format(escape(nick)) if nick else "", + ] + self.write( + level + 1, + "name = {{{}}},\n".format(" ".join([e for e in name_parts if e])), + ) elif self.name_format == "3": - name_parts1 = [self.format_given_names(name), - '\\nick{{{}}}'.format(escape(nick)) if nick else ''] - given_nick = ' '.join([e for e in name_parts1 if e]) - name_parts2 = ['\\surn{{{}}}'.format(escape(surn)) if surn else '', - given_nick] - self.write(level+1, 'name = {{{}}},\n'.format( - ', '.join([e for e in name_parts2 if e]))) + name_parts1 = [ + self.format_given_names(name), + "\\nick{{{}}}".format(escape(nick)) if nick else "", + ] + given_nick = " ".join([e for e in name_parts1 if e]) + name_parts2 = [ + "\\surn{{{}}}".format(escape(surn)) if surn else "", + given_nick, + ] + self.write( + level + 1, + "name = {{{}}},\n".format(", ".join([e for e in name_parts2 if e])), + ) elif self.name_format == "4": - name_parts = [self.format_given_names(name), - '\\nick{{{}}}'.format(escape(nick)) if nick else '', - '\\surn{{{}}}'.format(escape(surn)) if surn else ''] - self.write(level+1, 'name = {{{}}},\n'.format( - ''.join([e for e in name_parts if e]))) + name_parts = [ + self.format_given_names(name), + "\\nick{{{}}}".format(escape(nick)) if nick else "", + "\\surn{{{}}}".format(escape(surn)) if surn else "", + ] + self.write( + level + 1, + "name = {{{}}},\n".format("".join([e for e in name_parts if e])), + ) for eventref in person.get_event_ref_list(): if eventref.role == EventRoleType.PRIMARY: event = db.get_event_from_handle(eventref.ref) - self.write_event(db, level+1, event) + self.write_event(db, level + 1, event) if marriage_flag: for handle in person.get_family_handle_list(): family = db.get_family_from_handle(handle) for eventref in family.get_event_ref_list(): if eventref.role == EventRoleType.FAMILY: event = db.get_event_from_handle(eventref.ref) - self.write_event(db, level+1, event) + self.write_event(db, level + 1, event) for attr in person.get_attribute_list(): # Comparison with 'Occupation' for backwards compatibility with Gramps 5.0 attr_type = str(attr.get_type()) - if attr_type in ('Occupation', _('Occupation')): - self.write(level+1, 'profession = {%s},\n' % - escape(attr.get_value())) - if attr_type == 'Comment': - self.write(level+1, 'comment = {%s},\n' % - escape(attr.get_value())) + if attr_type in ("Occupation", _("Occupation")): + self.write(level + 1, "profession = {%s},\n" % escape(attr.get_value())) + if attr_type == "Comment": + self.write(level + 1, "comment = {%s},\n" % escape(attr.get_value())) for mediaref in person.get_media_list(): media = db.get_media_from_handle(mediaref.ref) path = media_path_full(db, media.get_path()) if os.path.isfile(path): if win(): - path = path.replace('\\', '/') - self.write(level+1, 'image = {%s},\n' % path) - break # first image only - self.write(level, '}\n') + path = path.replace("\\", "/") + self.write(level + 1, "image = {%s},\n" % path) + break # first image only + self.write(level, "}\n") def write_event(self, db, level, event): """ @@ -547,66 +603,66 @@ def write_event(self, db, level, event): """ modifier = None if event.type == EventType.BIRTH: - event_type = 'birth' - if 'died' in event.description.lower(): - modifier = 'died' - if 'stillborn' in event.description.lower(): - modifier = 'stillborn' + event_type = "birth" + if "died" in event.description.lower(): + modifier = "died" + if "stillborn" in event.description.lower(): + modifier = "stillborn" # modifier = 'out of wedlock' elif event.type == EventType.BAPTISM: - event_type = 'baptism' + event_type = "baptism" elif event.type == EventType.ENGAGEMENT: - event_type = 'engagement' + event_type = "engagement" elif event.type == EventType.MARRIAGE: - event_type = 'marriage' + event_type = "marriage" elif event.type == EventType.DIVORCE: - event_type = 'divorce' + event_type = "divorce" elif event.type == EventType.DEATH: - event_type = 'death' + event_type = "death" elif event.type == EventType.BURIAL: - event_type = 'burial' - if 'killed' in event.description.lower(): - modifier = 'killed' + event_type = "burial" + if "killed" in event.description.lower(): + modifier = "killed" elif event.type == EventType.CREMATION: - event_type = 'burial' - modifier = 'cremated' + event_type = "burial" + modifier = "cremated" else: return date = event.get_date_object() if date.get_calendar() == Date.CAL_GREGORIAN: - calendar = 'AD' # GR + calendar = "AD" # GR elif date.get_calendar() == Date.CAL_JULIAN: - calendar = 'JU' + calendar = "JU" else: - calendar = '' + calendar = "" if date.get_modifier() == Date.MOD_ABOUT: - calendar = 'ca' + calendar + calendar = "ca" + calendar date_str = self.format_iso(date.get_ymd(), calendar) if date.get_modifier() == Date.MOD_BEFORE: - date_str = '/' + date_str + date_str = "/" + date_str elif date.get_modifier() == Date.MOD_AFTER: - date_str = date_str + '/' + date_str = date_str + "/" elif date.is_compound(): stop_date = self.format_iso(date.get_stop_ymd(), calendar) - date_str = date_str + '/' + stop_date + date_str = date_str + "/" + stop_date place = escape(_pd.display_event(db, event)) place = place.replace("-", "\--") if modifier: - event_type += '+' - self.write(level, '%s = {%s}{%s}{%s},\n' % - (event_type, date_str, place, modifier)) - elif place == '': - event_type += '-' - self.write(level, '%s = {%s},\n' % (event_type, date_str)) + event_type += "+" + self.write( + level, "%s = {%s}{%s}{%s},\n" % (event_type, date_str, place, modifier) + ) + elif place == "": + event_type += "-" + self.write(level, "%s = {%s},\n" % (event_type, date_str)) else: - self.write(level, '%s = {%s}{%s},\n' % - (event_type, date_str, place)) + self.write(level, "%s = {%s}{%s},\n" % (event_type, date_str, place)) def format_given_names(self, name): """ @@ -617,12 +673,13 @@ def format_given_names(self, name): if call and self.preferred_name != "3": if call in first: where = first.index(call) - return '{before}\\pref{{{call}}}{after}'.format( + return "{before}\\pref{{{call}}}{after}".format( before=escape(first[:where]), call=escape(call), - after=escape(first[where+len(call):])) + after=escape(first[where + len(call) :]), + ) elif self.preferred_name in ("1", "3"): - return '\\pref{{{}}}'.format(escape(first)) + return "\\pref{{{}}}".format(escape(first)) elif self.preferred_name == "2": return escape(first) @@ -632,25 +689,25 @@ def format_iso(self, date_tuple, calendar): """ year, month, day = date_tuple if year == 0: - iso_date = '' + iso_date = "" elif month == 0: iso_date = str(year) elif day == 0: - iso_date = '%s-%s' % (year, month) + iso_date = "%s-%s" % (year, month) else: - iso_date = '%s-%s-%s' % (year, month, day) - if calendar and calendar != 'AD': - iso_date = '(%s)%s' % (calendar, iso_date) + iso_date = "%s-%s-%s" % (year, month, day) + if calendar and calendar != "AD": + iso_date = "(%s)%s" % (calendar, iso_date) return iso_date def write(self, level, text): """ Write indented text. """ - self._tex.write(' '*level + text) + self._tex.write(" " * level + text) def open(self, filename): - """ Implement TreeDocBase.open() """ + """Implement TreeDocBase.open()""" self._filename = os.path.normpath(os.path.abspath(filename)) self.write_start() @@ -662,11 +719,11 @@ def close(self): self.write_end() -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # TreeGraphDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class TreeGraphDoc(TreeDocBase): """ TreeGraphDoc implementation that generates a .graph file. @@ -697,46 +754,47 @@ def write_end(self): pass def close(self): - """ Implements TreeDocBase.close() """ + """Implements TreeDocBase.close()""" TreeDocBase.close(self) - with open(self._filename, 'w', encoding='utf-8') as texfile: + with open(self._filename, "w", encoding="utf-8") as texfile: texfile.write(self._tex.getvalue()) -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ # # TreeTexDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class TreeTexDoc(TreeDocBase): """ TreeTexDoc implementation that generates a .tex file. """ def close(self): - """ Implements TreeDocBase.close() """ + """Implements TreeDocBase.close()""" TreeDocBase.close(self) # Make sure the extension is correct if self._filename[-4:] != ".tex": self._filename += ".tex" - with open(self._filename, 'w', encoding='utf-8') as texfile: + with open(self._filename, "w", encoding="utf-8") as texfile: texfile.write(self._tex.getvalue()) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # TreePdfDoc # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ class TreePdfDoc(TreeDocBase): """ TreePdfDoc implementation that generates a .pdf file. """ def close(self): - """ Implements TreeDocBase.close() """ + """Implements TreeDocBase.close()""" TreeDocBase.close(self) # Make sure the extension is correct @@ -745,38 +803,54 @@ def close(self): with tempfile.TemporaryDirectory() as tmpdir: basename = os.path.basename(self._filename) - args = ['lualatex', '-output-directory', tmpdir, - '-jobname', basename[:-4]] + args = ["lualatex", "-output-directory", tmpdir, "-jobname", basename[:-4]] if win(): - proc = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, - creationflags=DETACHED_PROCESS) + proc = Popen( + args, + stdin=PIPE, + stdout=PIPE, + stderr=PIPE, + creationflags=DETACHED_PROCESS, + ) else: proc = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE) - proc.communicate(input=self._tex.getvalue().encode('utf-8')) + proc.communicate(input=self._tex.getvalue().encode("utf-8")) shutil.copy(os.path.join(tmpdir, basename), self._filename) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # # Various Genealogy Tree formats. # -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ FORMATS = [] if _LATEX_FOUND: - FORMATS += [{'type' : "pdf", - 'ext' : "pdf", - 'descr': _("PDF"), - 'mime' : "application/pdf", - 'class': TreePdfDoc}] - -FORMATS += [{'type' : "graph", - 'ext' : "graph", - 'descr': _("Graph File for genealogytree"), - 'class': TreeGraphDoc}] - -FORMATS += [{'type' : "tex", - 'ext' : "tex", - 'descr': _("LaTeX File"), - 'mime' : "application/x-latex", - 'class': TreeTexDoc}] + FORMATS += [ + { + "type": "pdf", + "ext": "pdf", + "descr": _("PDF"), + "mime": "application/pdf", + "class": TreePdfDoc, + } + ] + +FORMATS += [ + { + "type": "graph", + "ext": "graph", + "descr": _("Graph File for genealogytree"), + "class": TreeGraphDoc, + } +] + +FORMATS += [ + { + "type": "tex", + "ext": "tex", + "descr": _("LaTeX File"), + "mime": "application/x-latex", + "class": TreeTexDoc, + } +] diff --git a/gramps/gen/plug/menu/_boolean.py b/gramps/gen/plug/menu/_boolean.py index 34d8543e36f..d38af5405fa 100644 --- a/gramps/gen/plug/menu/_boolean.py +++ b/gramps/gen/plug/menu/_boolean.py @@ -23,22 +23,24 @@ Option class representing a boolean (yes/no, true/false). """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Option -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # BooleanOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class BooleanOption(Option): """ This class describes an option that is a boolean (True or False). """ + def __init__(self, label, value): """ :param label: A friendly label to be applied to this option. diff --git a/gramps/gen/plug/menu/_booleanlist.py b/gramps/gen/plug/menu/_booleanlist.py index 5b25aa29aeb..c1322dc8741 100644 --- a/gramps/gen/plug/menu/_booleanlist.py +++ b/gramps/gen/plug/menu/_booleanlist.py @@ -22,22 +22,24 @@ Option class representing a list of boolean values. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Option -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # BooleanListOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class BooleanListOption(Option): """ This class describes an option that provides a list of check buttons. """ + def __init__(self, heading): """ :param heading: A heading for the entire list of check buttons. @@ -45,7 +47,7 @@ def __init__(self, heading): :type heading: string :return: nothing """ - Option.__init__(self, heading, '') + Option.__init__(self, heading, "") self.__descriptions = [] def add_button(self, description, default): @@ -62,10 +64,10 @@ def add_button(self, description, default): """ self.__descriptions.append(description) value = self.get_value() - if value == '': + if value == "": value = str(default) else: - value = value + ',' + str(default) + value = value + "," + str(default) self.set_value(value) def get_descriptions(self): @@ -83,6 +85,5 @@ def get_selected(self): :return: a list of check button descriptions. """ descriptions = self.__descriptions - values = self.get_value().split(',') - return [x[0] for x in zip(descriptions, values) if x[1] == 'True'] - + values = self.get_value().split(",") + return [x[0] for x in zip(descriptions, values) if x[1] == "True"] diff --git a/gramps/gen/plug/menu/_color.py b/gramps/gen/plug/menu/_color.py index f2d33d3a512..7bf0ad29d18 100644 --- a/gramps/gen/plug/menu/_color.py +++ b/gramps/gen/plug/menu/_color.py @@ -23,22 +23,24 @@ Option class representing a color. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Option -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # ColorOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class ColorOption(Option): """ This class describes an option that allows the selection of a color. """ + def __init__(self, label, value): """ :param label: A friendly label to be applied to this option. diff --git a/gramps/gen/plug/menu/_destination.py b/gramps/gen/plug/menu/_destination.py index 200632d8441..b129767f1d4 100644 --- a/gramps/gen/plug/menu/_destination.py +++ b/gramps/gen/plug/menu/_destination.py @@ -23,18 +23,19 @@ Option class representing a file destination. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import StringOption -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # DestinationOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class DestinationOption(StringOption): """ This class describes an option that specifies a destination file or path. @@ -42,7 +43,7 @@ class DestinationOption(StringOption): the extension can be specified. """ - __signals__ = { 'options-changed' : None } + __signals__ = {"options-changed": None} def __init__(self, label, value): """ @@ -70,7 +71,7 @@ def set_directory_entry(self, is_directory): :return: nothing """ self.__is_directory = is_directory - self.emit('options-changed') + self.emit("options-changed") def get_directory_entry(self): """ diff --git a/gramps/gen/plug/menu/_enumeratedlist.py b/gramps/gen/plug/menu/_enumeratedlist.py index 51e7168195a..3aad286b590 100644 --- a/gramps/gen/plug/menu/_enumeratedlist.py +++ b/gramps/gen/plug/menu/_enumeratedlist.py @@ -23,34 +23,36 @@ Option class representing an enumerated list of possible values. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Option from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.sgettext -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # set up logging # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import logging -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # EnumeratedListOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class EnumeratedListOption(Option): """ This class describes an option that provides a finite number of values. Each possible value is assigned a value and a description. """ - __signals__ = { 'options-changed' : None } + __signals__ = {"options-changed": None} def __init__(self, label, value): """ @@ -81,12 +83,12 @@ def add_item(self, value, description, xml_item=False): :type _xml_item: Boolean :return: nothing """ - if not xml_item: # localized item description is being passed in + if not xml_item: # localized item description is being passed in self.__items.append((value, description)) - else: # English item description is being passed in + else: # English item description is being passed in self.__xml_items.append((value, description)) self.__items.append((value, _(description))) - self.emit('options-changed') + self.emit("options-changed") def set_items(self, items, xml_items=False): """ @@ -99,13 +101,13 @@ def set_items(self, items, xml_items=False): :type _xml_items: Boolean :return: nothing """ - if not xml_items: # localized item descriptions are being passed in + if not xml_items: # localized item descriptions are being passed in self.__items = items - else: # English item descriptions are being passed in + else: # English item descriptions are being passed in self.__xml_items = items - for (value, description) in items: + for value, description in items: self.__items.append((value, _(description))) - self.emit('options-changed') + self.emit("options-changed") def get_items(self, xml_items=False): """ @@ -115,9 +117,9 @@ def get_items(self, xml_items=False): :type _xml_items: Boolean :return: an array of tuples containing (value,description) pairs. """ - if not xml_items: # localized item descriptions are wanted + if not xml_items: # localized item descriptions are wanted return self.__items - return self.__xml_items # English item descriptions are wanted + return self.__xml_items # English item descriptions are wanted def clear(self): """ @@ -126,7 +128,7 @@ def clear(self): :return: nothing. """ self.__items = [] - self.emit('options-changed') + self.emit("options-changed") def set_value(self, value): """ @@ -142,6 +144,8 @@ def set_value(self, value): elif value == self.ini_value: return else: - logging.warning(_("Value '%(val)s' not found for option '%(opt)s'") % - {'val' : str(value), 'opt' : self.get_label()}) + logging.warning( + _("Value '%(val)s' not found for option '%(opt)s'") + % {"val": str(value), "opt": self.get_label()} + ) logging.warning(_("Valid values: ") + str(self.__items)) diff --git a/gramps/gen/plug/menu/_family.py b/gramps/gen/plug/menu/_family.py index 96f96130dde..b3810c463a2 100644 --- a/gramps/gen/plug/menu/_family.py +++ b/gramps/gen/plug/menu/_family.py @@ -23,23 +23,25 @@ Option class representing a family. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import StringOption -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # FamilyOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class FamilyOption(StringOption): """ This class describes an option that allows a family from the database to be selected. """ + def __init__(self, label): """ :param label: A friendly label to be applied to this option. diff --git a/gramps/gen/plug/menu/_filter.py b/gramps/gen/plug/menu/_filter.py index 992406e2c46..9082565f43d 100644 --- a/gramps/gen/plug/menu/_filter.py +++ b/gramps/gen/plug/menu/_filter.py @@ -23,23 +23,25 @@ Option class representing a list of filters. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import EnumeratedListOption -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # FilterOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class FilterOption(EnumeratedListOption): """ This class describes an option that provides a list of person filters. Each possible value represents one of the possible filters. """ + def __init__(self, label, value): """ :param label: A friendly label to be applied to this option. @@ -62,12 +64,11 @@ def set_filters(self, filter_list): :return: nothing """ curval = self.get_value() - items = [(value, filt.get_name()) - for value, filt in enumerate(filter_list)] + items = [(value, filt.get_name()) for value, filt in enumerate(filter_list)] self.__filters = filter_list self.clear() - self.set_items( items ) + self.set_items(items) self.set_value(curval) diff --git a/gramps/gen/plug/menu/_media.py b/gramps/gen/plug/menu/_media.py index fdcfc42f9c5..6d02317dde0 100644 --- a/gramps/gen/plug/menu/_media.py +++ b/gramps/gen/plug/menu/_media.py @@ -23,23 +23,25 @@ Option class representing a media object. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import StringOption -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # MediaOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class MediaOption(StringOption): """ This class describes an option that allows a media object from the database to be selected. """ + def __init__(self, label): """ :param label: A friendly label to be applied to this option. diff --git a/gramps/gen/plug/menu/_menu.py b/gramps/gen/plug/menu/_menu.py index f807d76cf65..1c58d3068eb 100644 --- a/gramps/gen/plug/menu/_menu.py +++ b/gramps/gen/plug/menu/_menu.py @@ -23,11 +23,12 @@ Abstracted option handling. """ -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Menu class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Menu: """ **Introduction** @@ -48,6 +49,7 @@ class Menu: the part of the system that will actually represent the menu to the user. """ + def __init__(self): # __options holds all the options by their category self.__options = {} @@ -89,7 +91,7 @@ def get_option_names(self, category): :return: a list of strings """ names = [] - for (name, option) in self.__options[category]: + for name, option in self.__options[category]: names.append(name) return names @@ -99,7 +101,7 @@ def get_option(self, category, name): :return: an :class:`.Option` instance or None on failure. """ - for (oname, option) in self.__options[category]: + for oname, option in self.__options[category]: if oname == name: return option return None @@ -112,7 +114,7 @@ def get_all_option_names(self): """ names = [] for category in self.__options: - for (name, option) in self.__options[category]: + for name, option in self.__options[category]: names.append(name) return names @@ -123,7 +125,7 @@ def get_option_by_name(self, name): :return: an :class:`.Option` instance or None on failure. """ for category in self.__options: - for (oname, option) in self.__options[category]: + for oname, option in self.__options[category]: if oname == name: return option return None diff --git a/gramps/gen/plug/menu/_note.py b/gramps/gen/plug/menu/_note.py index a9827fb32a4..aac23a5eceb 100644 --- a/gramps/gen/plug/menu/_note.py +++ b/gramps/gen/plug/menu/_note.py @@ -23,23 +23,25 @@ Option class representing a string. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import StringOption -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # NoteOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class NoteOption(StringOption): """ This class describes an option that allows a note from the database to be selected. """ + def __init__(self, label): """ :param label: A friendly label to be applied to this option. diff --git a/gramps/gen/plug/menu/_number.py b/gramps/gen/plug/menu/_number.py index d925fbf41cd..b7ce19468e0 100644 --- a/gramps/gen/plug/menu/_number.py +++ b/gramps/gen/plug/menu/_number.py @@ -23,24 +23,26 @@ Option class representing a number. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Option -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # NumberOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class NumberOption(Option): """ This class describes an option that is a simple number with defined maximum and minimum values. """ - def __init__(self, label, value, min_val, max_val, step = 1): + + def __init__(self, label, value, min_val, max_val, step=1): """ :param label: A friendly label to be applied to this option. Example: "Number of generations to include" diff --git a/gramps/gen/plug/menu/_option.py b/gramps/gen/plug/menu/_option.py index 44179ae2faa..eab1790612b 100644 --- a/gramps/gen/plug/menu/_option.py +++ b/gramps/gen/plug/menu/_option.py @@ -23,18 +23,19 @@ The base option class for all other option classes. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...utils.callback import Callback -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # Option class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class Option(Callback): """ This class serves as a base class for all options. All Options must @@ -42,8 +43,7 @@ class Option(Callback): to add additional functionality. """ - __signals__ = { 'value-changed' : None, - 'avail-changed' : None} + __signals__ = {"value-changed": None, "avail-changed": None} def __init__(self, label, value): """ @@ -98,7 +98,7 @@ def set_value(self, value): :return: nothing """ self.__value = value - self.emit('value-changed') + self.emit("value-changed") def get_help(self): """ @@ -132,7 +132,7 @@ def set_available(self, avail): """ if avail != self.__available: self.__available = avail - self.emit('avail-changed') + self.emit("avail-changed") def get_available(self): """ diff --git a/gramps/gen/plug/menu/_person.py b/gramps/gen/plug/menu/_person.py index 004b8825ae4..c4134e2caed 100644 --- a/gramps/gen/plug/menu/_person.py +++ b/gramps/gen/plug/menu/_person.py @@ -23,23 +23,25 @@ Option class representing a person. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import StringOption -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # PersonOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PersonOption(StringOption): """ This class describes an option that allows a person from the database to be selected. """ + def __init__(self, label): """ :param label: A friendly label to be applied to this option. diff --git a/gramps/gen/plug/menu/_personlist.py b/gramps/gen/plug/menu/_personlist.py index ba9a4832204..0e661c2e827 100644 --- a/gramps/gen/plug/menu/_personlist.py +++ b/gramps/gen/plug/menu/_personlist.py @@ -23,23 +23,25 @@ Option class representing a list of people. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Option -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # PersonListOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PersonListOption(Option): """ This class describes a widget that allows multiple people from the database to be selected. """ + def __init__(self, label): """ :param label: A friendly label to be applied to this option. diff --git a/gramps/gen/plug/menu/_placelist.py b/gramps/gen/plug/menu/_placelist.py index 7a73c166157..f1a5ba8c84d 100644 --- a/gramps/gen/plug/menu/_placelist.py +++ b/gramps/gen/plug/menu/_placelist.py @@ -23,23 +23,25 @@ Option class representing a list of places. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Option -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # PlaceListOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class PlaceListOption(Option): """ This class describes a widget that allows multiple places from the database to be selected. """ + def __init__(self, label): """ :param label: A label to be applied to this option. diff --git a/gramps/gen/plug/menu/_string.py b/gramps/gen/plug/menu/_string.py index 53b470fc940..a581f9e0b1a 100644 --- a/gramps/gen/plug/menu/_string.py +++ b/gramps/gen/plug/menu/_string.py @@ -23,22 +23,24 @@ Option class representing a string. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Option -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # StringOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class StringOption(Option): """ This class describes an option that is a simple one-line string. """ + def __init__(self, label, value): """ :param label: A friendly label to be applied to this option. diff --git a/gramps/gen/plug/menu/_style.py b/gramps/gen/plug/menu/_style.py index 4bb292f8214..95b4a162355 100644 --- a/gramps/gen/plug/menu/_style.py +++ b/gramps/gen/plug/menu/_style.py @@ -23,20 +23,21 @@ Option class representing a document style. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import EnumeratedListOption from ..docgen import StyleSheetList -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # StyleOption class # -#------------------------------------------------------------------------- -class StyleOption(EnumeratedListOption): # TODO this is likely dead code +# ------------------------------------------------------------------------- +class StyleOption(EnumeratedListOption): # TODO this is likely dead code """ This class describes an option that allows the use to select a style sheet. """ @@ -59,21 +60,19 @@ def __init__(self, label, default_style, module_name): self.__default_style = default_style self.__default_style.set_name("default") self.__style_file = "%s_style.xml" % module_name - style_list = StyleSheetList(self.__style_file, - self.__default_style) + style_list = StyleSheetList(self.__style_file, self.__default_style) for style_name in style_list.get_style_names(): self.add_item(style_name, style_name) def get_default_style(self): - """ Get the default style """ + """Get the default style""" return self.__default_style def get_style_file(self): - """ Get the name of the style file """ + """Get the name of the style file""" return self.__style_file def get_style(self): - """ Get the selected style """ - style_list = StyleSheetList(self.__style_file, - self.__default_style) + """Get the selected style""" + style_list = StyleSheetList(self.__style_file, self.__default_style) return style_list.get_style_sheet(self.get_value()) diff --git a/gramps/gen/plug/menu/_surnamecolor.py b/gramps/gen/plug/menu/_surnamecolor.py index 975e45d4732..2d04845eec6 100644 --- a/gramps/gen/plug/menu/_surnamecolor.py +++ b/gramps/gen/plug/menu/_surnamecolor.py @@ -23,24 +23,26 @@ Option class representing color/surname mappings. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Option -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # SurnameColorOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class SurnameColorOption(Option): """ This class describes a widget that allows multiple surnames to be selected from the database, and to assign a color (not necessarily unique) to each one. """ + def __init__(self, label): """ :param label: A friendly label to be applied to this option. diff --git a/gramps/gen/plug/menu/_text.py b/gramps/gen/plug/menu/_text.py index cae1613b9a4..ed1b6eecead 100644 --- a/gramps/gen/plug/menu/_text.py +++ b/gramps/gen/plug/menu/_text.py @@ -23,22 +23,24 @@ Option class representing a block of text. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from . import Option -#------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- # # TextOption class # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- class TextOption(Option): """ This class describes an option that is a multi-line string. """ + def __init__(self, label, value): """ :param label: A friendly label to be applied to this option. diff --git a/gramps/gen/plug/report/_bibliography.py b/gramps/gen/plug/report/_bibliography.py index 49e91194c0b..9e6d7b7286e 100644 --- a/gramps/gen/plug/report/_bibliography.py +++ b/gramps/gen/plug/report/_bibliography.py @@ -24,25 +24,27 @@ Contain and organize bibliographic information. """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import string import math -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...lib.citation import Citation as lib_Citation + class Citation: """ Store information about a citation and all of its references. """ + def __init__(self): """ Initialize members. @@ -87,7 +89,7 @@ def add_reference(self, source_ref): :return: The key of the added reference among all the references. :rtype: char """ - letters = string.ascii_lowercase # or (e.g.) "abcdef" for testing + letters = string.ascii_lowercase # or (e.g.) "abcdef" for testing letter_count = len(letters) ref_count = len(self.__ref_list) x_ref_count = ref_count @@ -95,17 +97,15 @@ def add_reference(self, source_ref): if ref_count == 0: self.__ref_list.append((letters[0], source_ref)) return letters[0] - last_letter = letters[ ref_count % letter_count ] + last_letter = letters[ref_count % letter_count] key = "" # Calculate prek number of digits. - number_of_letters = 1 + int(math.log(float(ref_count), - float(letter_count))) + number_of_letters = 1 + int(math.log(float(ref_count), float(letter_count))) # Exclude index for number_of_letters-1 - for n in range(1, number_of_letters-1): + for n in range(1, number_of_letters - 1): ref_count -= pow(letter_count, n) # Adjust number_of_letters for new index - number_of_letters = 1 + int(math.log(float(ref_count), - float(letter_count))) + number_of_letters = 1 + int(math.log(float(ref_count), float(letter_count))) for n in range(1, number_of_letters): x_ref_count -= pow(letter_count, n) for letter in range(1, number_of_letters): @@ -115,10 +115,12 @@ def add_reference(self, source_ref): self.__ref_list.append((key, source_ref)) return key + class Bibliography: """ Store and organize multiple citations into a bibliography. """ + MODE_DATE = 2**0 MODE_PAGE = 2**1 MODE_CONF = 2**2 @@ -222,22 +224,21 @@ def __sref_has_info(self, source_ref): Determine if this source_ref has any useful information based on the current mode. """ - if ( self.mode & self.MODE_PAGE ) == self.MODE_PAGE: + if (self.mode & self.MODE_PAGE) == self.MODE_PAGE: if source_ref.get_page() != "": return True - if ( self.mode & self.MODE_DATE ) == self.MODE_DATE: + if (self.mode & self.MODE_DATE) == self.MODE_DATE: date = source_ref.get_date_object() if date is not None and not date.is_empty(): return True - if ( self.mode & self.MODE_CONF ) == self.MODE_CONF: + if (self.mode & self.MODE_CONF) == self.MODE_CONF: confidence = source_ref.get_confidence_level() - if confidence is not None and confidence != \ - lib_Citation.CONF_NORMAL: + if confidence is not None and confidence != lib_Citation.CONF_NORMAL: return True - if ( self.mode & self.MODE_NOTE ) == self.MODE_NOTE: + if (self.mode & self.MODE_NOTE) == self.MODE_NOTE: if len(source_ref.get_note_list()) != 0: return True - if ( self.mode & self.MODE_MEDIA ) == self.MODE_MEDIA: + if (self.mode & self.MODE_MEDIA) == self.MODE_MEDIA: if len(source_ref.get_media_list()) != 0: return True # Can't find anything interesting. @@ -259,20 +260,20 @@ def __srefs_are_equal(self, source_ref1, source_ref2): # are intended to represent the same citation. if self.mode == self.MODE_ALL: return source_ref1.handle == source_ref2.handle - if ( self.mode & self.MODE_PAGE ) == self.MODE_PAGE: + if (self.mode & self.MODE_PAGE) == self.MODE_PAGE: if source_ref1.get_page() != source_ref2.get_page(): return False - if ( self.mode & self.MODE_DATE ) == self.MODE_DATE: + if (self.mode & self.MODE_DATE) == self.MODE_DATE: date1 = source_ref1.get_date_object() date2 = source_ref2.get_date_object() if not date1.is_equal(date2): return False - if ( self.mode & self.MODE_CONF ) == self.MODE_CONF: + if (self.mode & self.MODE_CONF) == self.MODE_CONF: conf1 = source_ref1.get_confidence_level() conf2 = source_ref2.get_confidence_level() if conf1 != conf2: return False - if ( self.mode & self.MODE_NOTE ) == self.MODE_NOTE: + if (self.mode & self.MODE_NOTE) == self.MODE_NOTE: nl1 = source_ref1.get_note_list() nl2 = source_ref2.get_note_list() if len(nl1) != len(nl2): @@ -280,7 +281,7 @@ def __srefs_are_equal(self, source_ref1, source_ref2): for notehandle in nl1: if notehandle not in nl2: return False - if ( self.mode & self.MODE_MEDIA ) == self.MODE_MEDIA: + if (self.mode & self.MODE_MEDIA) == self.MODE_MEDIA: nl1 = source_ref1.get_media_list() nl2 = source_ref2.get_media_list() if len(nl1) != len(nl2): diff --git a/gramps/gen/plug/report/_book.py b/gramps/gen/plug/report/_book.py index be92ccf604d..88eec1f67f7 100644 --- a/gramps/gen/plug/report/_book.py +++ b/gramps/gen/plug/report/_book.py @@ -26,36 +26,38 @@ """ the non-UI-specific (i.e. common, shared) classes for books """ -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Standard Python modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- import copy import os -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Set up logging # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ import logging + LOG = logging.getLogger(".Book") -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # SAX interface # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from xml.sax import make_parser, handler, SAXParseException from xml.sax.saxutils import escape -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # Gramps modules # -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- from ...const import GRAMPS_LOCALE as glocale + _ = glocale.translation.gettext from ...const import USER_DATA from ...utils.cast import get_type_converter_by_name, type_name @@ -63,18 +65,19 @@ from .. import BasePluginManager from . import book_categories -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ # # Private Constants # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ _UNSUPPORTED = _("Unsupported") -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # Book Item class # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class BookItem: """ Interface into the book item -- a smallest element of the book. @@ -144,11 +147,12 @@ def get_style_name(self): """ return self.style_name -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # Book class # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class Book: """ Interface into the user-defined Book -- a collection of book items. @@ -168,7 +172,7 @@ def __init__(self, obj=None, exact_copy=True): @type exact_copy: boolean """ - self.name = "" # this is tested for, in several places + self.name = "" # this is tested for, in several places self.dbname = "" self.paper_name = None self.paper_orientation = None @@ -411,11 +415,12 @@ def get_output(self): """ return self.paper_output -#------------------------------------------------------------------------ + +# ------------------------------------------------------------------------ # # BookList class # -#------------------------------------------------------------------------ +# ------------------------------------------------------------------------ class BookList: """ Interface into the user-defined list of books. @@ -445,13 +450,13 @@ def delete_book(self, name): """ del self.bookmap[name] -## 2/2016 the string "get_book_map" appears nowhere else in gramps -## def get_book_map(self): -## """ -## Return the map of names to books. -## """ -## return self.bookmap -## + ## 2/2016 the string "get_book_map" appears nowhere else in gramps + ## def get_book_map(self): + ## """ + ## Return the map of names to books. + ## """ + ## return self.bookmap + ## def get_book(self, name): """ Return the Book associated with the name @@ -496,79 +501,80 @@ def save(self): Saves the current BookList to the associated file. """ with open(self.file, "w", encoding="utf-8") as b_f: - b_f.write("\n") - b_f.write('\n') - for name in sorted(self.bookmap): # enable a diff of archived copies + b_f.write('\n') + b_f.write("\n") + for name in sorted(self.bookmap): # enable a diff of archived copies book = self.get_book(name) dbname = escape(book.get_dbname()) - b_f.write(' ' - '\n' % (escape(name), dbname)) + b_f.write( + ' ' "\n" % (escape(name), dbname) + ) for item in book.get_item_list(): - b_f.write(' \n' % ( - item.get_name(), - item.get_translated_name())) + b_f.write( + ' \n' + % (item.get_name(), item.get_translated_name()) + ) options = item.option_class.handler.options_dict - for option_name in sorted(options.keys()): # enable a diff + for option_name in sorted(options.keys()): # enable a diff option_value = options[option_name] if isinstance(option_value, (list, tuple)): - b_f.write(' \n') + value = value.replace('"', """) + b_f.write( + ' \n' + % (list_index, option_type, value) + ) + b_f.write(" \n") else: option_type = type_name(option_value) value = escape(str(option_value)) - value = value.replace('"', '"') - b_f.write('