summaryrefslogtreecommitdiff
path: root/setup.py
diff options
context:
space:
mode:
Diffstat (limited to 'setup.py')
-rw-r--r--setup.py489
1 files changed, 397 insertions, 92 deletions
diff --git a/setup.py b/setup.py
index c640197..67f31f5 100644
--- a/setup.py
+++ b/setup.py
@@ -1,98 +1,403 @@
-#!/usr/bin/env python
-# -*- coding: latin1 -*-
+#!/usr/bin/python3
-from distutils.core import setup
-from distutils.command.install_data import install_data
-from distutils.dep_util import newer
-from distutils.log import info
+# Copyright (C) 2009-2017 Damon Lynch <damonlynch@gmail.com>
+
+# This file is part of Rapid Photo Downloader.
+#
+# Rapid Photo Downloader is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Rapid Photo Downloader is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Rapid Photo Downloader. If not,
+# see <http://www.gnu.org/licenses/>.
+
+# Copyright 2009-2017 Damon Lynch
+# Contains portions Copyright 2014 Donald Stufft
+# Contains portions Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, Canonical Ltd
+
+__author__ = 'Damon Lynch'
+__copyright__ = "Copyright 2009-2017, Damon Lynch"
-from rapid.config import version
-import glob
import os
+import os.path
+from glob import glob
+import distutils
+import distutils.command.build
+from distutils.command.clean import clean
+from setuptools import setup, Command
+from setuptools.command.install import install
+
+
+here = os.path.abspath(os.path.dirname(__file__))
+
+with open(os.path.join(here, "raphodo", "__about__.py")) as f:
+ about = {}
+ exec(f.read(), about)
+
+
+class build_extra(distutils.command.build.build):
+ """
+ Adds the extra commands to the build target. This class should be used
+ with the core distutils
+
+ Taken straight from DistutilsExtra, minus finalize_options
+ """
+ def __init__(self, dist):
+ distutils.command.build.build.__init__(self, dist)
+
+ self.user_options.extend([("i18n", None, "use the localisation"),
+ ("icons", None, "use icons"),
+ ("kdeui", None, "use kdeui"),
+ ("help", None, "use help system")])
+ def initialize_options(self):
+ distutils.command.build.build.initialize_options(self)
+ self.i18n = False
+ self.icons = False
+ self.help = False
+ self.kdeui = False
+
+
+class build_extra_commands(build_extra):
+ """
+ Adds the extra commands to the build target.
+ This class should be used with setuptools.
+
+ Taken straight from DistutilsExtra
+ """
+
+ def finalize_options(self):
+ def has_help(command):
+ return self.help == "True"
+ def has_icons(command):
+ return self.icons == "True"
+ def has_i18n(command):
+ return self.i18n == "True"
+ def has_kdeui(command):
+ return self.kdeui == "True"
+ distutils.command.build.build.finalize_options(self)
+ self.sub_commands.append(("build_i18n", has_i18n))
+ self.sub_commands.append(("build_icons", has_icons))
+ self.sub_commands.append(("build_help", has_help))
+ self.sub_commands.insert(0, ("build_kdeui", has_kdeui)) # need to run before build_py
+
+
+class build_extra_man_page(build_extra_commands):
+ """
+ Taken from the Canonical project 'germinate'
+ """
+ def __init__(self, dist):
+ super().__init__(dist)
+ self.user_options.extend([('pod2man', None, 'use pod2man')])
+
+ def initialize_options(self):
+ super().initialize_options()
+ self.pod2man = False
+
+ def finalize_options(self):
+ def has_pod2man(command):
+ return self.pod2man == 'True'
+
+ super().finalize_options()
+ self.sub_commands.append(('build_pod2man', has_pod2man))
+
+
+class build_pod2man(Command):
+ """
+ Based on code in the Canonical project 'germinate'
+ """
+ description = "build POD manual pages"
+
+ user_options = [('pod-files=', None, 'POD files to build')]
+
+ def initialize_options(self):
+ self.pod_files = []
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ for pod_file in glob('doc/*.1.pod'):
+ name = os.path.basename(pod_file)[:-6].upper()
+ build_path = os.path.join('build', os.path.splitext(pod_file)[0])
+ if not os.path.isdir(os.path.join('build', 'doc')):
+ os.mkdir(os.path.join('build', 'doc'))
+ self.spawn(['pod2man', '--section=1', '--release={}'.format(about["__version__"]),
+ "--center=General Commands Manual", '--name="{}"'.format(name),
+ pod_file, build_path])
+
+
+class build_i18n(distutils.cmd.Command):
+ """ Taken straight from DistutilsExtra"""
+
+ description = "integrate the gettext framework"
+
+ user_options = [
+ ('desktop-files=', None, '.desktop.in files that should be merged'),
+ ('xml-files=', None, '.xml.in files that should be merged'),
+ ('schemas-files=', None, '.schemas.in files that should be merged'),
+ ('ba-files=', None, 'bonobo-activation files that should be merged'),
+ ('rfc822deb-files=', None, 'RFC822 files that should be merged'),
+ ('key-files=', None, '.key.in files that should be merged'),
+ ('domain=', 'd', 'gettext domain'),
+ ('merge-po', 'm', 'merge po files against template'),
+ ('po-dir=', 'p', 'directory that holds the i18n files'),
+ ('bug-contact=', None, 'contact address for msgid bugs')
+ ]
-name = 'rapid-photo-downloader'
-
-class InstallData(install_data):
- """ This class is largely copied from setup.py in Terminator 0.8.1 by Chris Jones <cmsj@tenshu.net>"""
- def run (self):
- self.data_files.extend (self._compile_po_files ())
- install_data.run (self)
-
- def _compile_po_files (self):
- data_files = []
-
- PO_DIR = 'po'
- for po in glob.glob (os.path.join (PO_DIR,'*.po')):
- lang = os.path.basename(po[:-3])
- mo = os.path.join('build', 'mo', lang, '%s.mo' % name)
-
- directory = os.path.dirname(mo)
- if not os.path.exists(directory):
- info('creating %s' % directory)
- os.makedirs(directory)
-
- if newer(po, mo):
- # True if mo doesn't exist
- cmd = 'msgfmt -o %s %s' % (mo, po)
- info('compiling %s -> %s' % (po, mo))
- if os.system(cmd) != 0:
- raise SystemExit('Error while running msgfmt')
-
- dest = os.path.dirname(os.path.join('share', 'locale', lang, 'LC_MESSAGES', '%s.mo' % name))
- data_files.append((dest, [mo]))
-
- return data_files
-
-package_data={'rapid': ['glade3/about.ui',
- 'glade3/photo.svg',
- 'glade3/photo66.png',
- 'glade3/photo_icon.png',
- 'glade3/prefs.ui',
- 'glade3/rapid.ui',
- 'glade3/errorlog.ui',
- 'glade3/media-eject.png',
- 'glade3/rapid-photo-downloader.svg',
- 'glade3/rapid-photo-downloader-download-pending.png',
- 'glade3/rapid-photo-downloader-downloaded-with-error.svg',
- 'glade3/rapid-photo-downloader-downloaded-with-warning.svg',
- 'glade3/rapid-photo-downloader-downloaded.svg',
- 'glade3/rapid-photo-downloader-jobcode.svg',
- 'glade3/thumbnails_icon.png',
- 'glade3/video.svg',
- 'glade3/video66.png',
- 'glade3/zoom-in.png',
- 'glade3/zoom-out.png',
- ]}
-
-setup(name=name,
- version=version,
- description='Rapid Photo Downloader for Linux',
- license='GPL',
- author='Damon Lynch',
- author_email='damonlynch@gmail.com',
- maintainer='Damon Lynch',
- url='http://www.damonlynch.net/rapid',
- long_description=
-"""Rapid Photo Downloader is written by a photographer for professional and
-amateur photographers. It can download photos and videos from multiple
-cameras, memory cards and Portable Storage Devices simultaneously. It
-provides many flexible, user-defined options for subfolder creation,
-photo and video renaming, and backup.
-""",
- packages = ['rapid'],
- package_data=package_data,
- scripts=['rapid-photo-downloader'],
- platforms=['linux'],
- data_files=[
- ('share/applications', ['data/rapid-photo-downloader.desktop']),
- ('share/pixmaps', ['data/icons/48x48/apps/rapid-photo-downloader.png', 'data/icons/rapid-photo-downloader.xpm']),
- ('share/icons/hicolor/scalable/apps', glob.glob('data/icons/scalable/apps/*.svg')),
- ('share/icons/hicolor/16x16/apps', glob.glob('data/icons/16x16/apps/*.png')),
- ('share/icons/hicolor/22x22/apps', glob.glob('data/icons/22x22/apps/*.png')),
- ('share/icons/hicolor/24x24/apps', glob.glob('data/icons/24x24/apps/*.png')),
- ('share/icons/hicolor/48x48/apps', glob.glob('data/icons/48x48/apps/*.png')),
- ('/usr/share/kde4/apps/solid/actions/', ['data/kde/rapid-photo-downloader.desktop']),
- ('/usr/share/appdata/', ['data/rapid-photo-downloader.appdata.xml']),
+ boolean_options = ['merge-po']
+
+ def initialize_options(self):
+ self.desktop_files = []
+ self.xml_files = []
+ self.key_files = []
+ self.schemas_files = []
+ self.ba_files = []
+ self.rfc822deb_files = []
+ self.domain = None
+ self.merge_po = False
+ self.bug_contact = None
+ self.po_dir = None
+
+ def finalize_options(self):
+ if self.domain is None:
+ self.domain = self.distribution.metadata.name
+ if self.po_dir is None:
+ self.po_dir = "po"
+
+ def run(self):
+ """
+ Update the language files, generate mo files and add them
+ to the to be installed files
+ """
+ if not os.path.isdir(self.po_dir):
+ return
+
+ data_files = self.distribution.data_files
+ if data_files is None:
+ # in case not data_files are defined in setup.py
+ self.distribution.data_files = data_files = []
+
+ if self.bug_contact is not None:
+ os.environ["XGETTEXT_ARGS"] = "--msgid-bugs-address=%s " % \
+ self.bug_contact
+
+ # Print a warning if there is a Makefile that would overwrite our
+ # values
+ if os.path.exists("%s/Makefile" % self.po_dir):
+ self.announce("""
+WARNING: Intltool will use the values specified from the
+ existing po/Makefile in favor of the vaules
+ from setup.cfg.
+ Remove the Makefile to avoid problems.""")
+
+ # If there is a po/LINGUAS file, or the LINGUAS environment variable
+ # is set, only compile the languages listed there.
+ selected_languages = None
+ linguas_file = os.path.join(self.po_dir, "LINGUAS")
+ if os.path.isfile(linguas_file):
+ selected_languages = open(linguas_file).read().split()
+ if "LINGUAS" in os.environ:
+ selected_languages = os.environ["LINGUAS"].split()
+
+ # Update po(t) files and print a report
+ # We have to change the working dir to the po dir for intltool
+ cmd = ["intltool-update", (self.merge_po and "-r" or "-p"), "-g", self.domain]
+ wd = os.getcwd()
+ os.chdir(self.po_dir)
+ self.spawn(cmd)
+ os.chdir(wd)
+ max_po_mtime = 0
+ for po_file in glob("%s/*.po" % self.po_dir):
+ lang = os.path.basename(po_file[:-3])
+ if selected_languages and not lang in selected_languages:
+ continue
+ mo_dir = os.path.join("build", "mo", lang, "LC_MESSAGES")
+ mo_file = os.path.join(mo_dir, "%s.mo" % self.domain)
+ if not os.path.exists(mo_dir):
+ os.makedirs(mo_dir)
+ cmd = ["msgfmt", po_file, "-o", mo_file]
+ po_mtime = os.path.getmtime(po_file)
+ mo_mtime = os.path.exists(mo_file) and os.path.getmtime(mo_file) or 0
+ if po_mtime > max_po_mtime:
+ max_po_mtime = po_mtime
+ if po_mtime > mo_mtime:
+ self.spawn(cmd)
+
+ targetpath = os.path.join("share/locale", lang, "LC_MESSAGES")
+ data_files.append((targetpath, (mo_file,)))
+
+ # merge .in with translation
+ for (option, switch) in ((self.xml_files, "-x"),
+ (self.desktop_files, "-d"),
+ (self.schemas_files, "-s"),
+ (self.rfc822deb_files, "-r"),
+ (self.ba_files, "-b"),
+ (self.key_files, "-k"),):
+ try:
+ file_set = eval(option)
+ except:
+ continue
+ for (target, files) in file_set:
+ build_target = os.path.join("build", target)
+ if not os.path.exists(build_target):
+ os.makedirs(build_target)
+ files_merged = []
+ for file in files:
+ if file.endswith(".in"):
+ file_merged = os.path.basename(file[:-3])
+ else:
+ file_merged = os.path.basename(file)
+ file_merged = os.path.join(build_target, file_merged)
+ cmd = ["intltool-merge", switch, self.po_dir, file,
+ file_merged]
+ mtime_merged = os.path.exists(file_merged) and \
+ os.path.getmtime(file_merged) or 0
+ mtime_file = os.path.getmtime(file)
+ if mtime_merged < max_po_mtime or mtime_merged < mtime_file:
+ # Only build if output is older than input (.po,.in)
+ self.spawn(cmd)
+ files_merged.append(file_merged)
+ data_files.append((target, files_merged))
+
+
+class build_icons(distutils.cmd.Command):
+ """ Taken straight from DistutilsExtra"""
+
+ description = "select all icons for installation"
+
+ user_options= [('icon-dir=', 'i', 'icon directory of the source tree')]
+
+ def initialize_options(self):
+ self.icon_dir = None
+
+ def finalize_options(self):
+ if self.icon_dir is None:
+ self.icon_dir = os.path.join("data","icons")
+
+ def run(self):
+ data_files = self.distribution.data_files
+
+ for size in glob(os.path.join(self.icon_dir, "*")):
+ for category in glob(os.path.join(size, "*")):
+ icons = []
+ for icon in glob(os.path.join(category,"*")):
+ if not os.path.islink(icon):
+ icons.append(icon)
+ if icons:
+ data_files.append(
+ (
+ "share/icons/hicolor/%s/%s" % (
+ os.path.basename(size), os.path.basename(category)
+ ), icons
+ )
+ )
+
+class clean_extra(clean):
+ def run(self):
+ clean.run(self)
+
+ for path, dirs, files in os.walk('.'):
+ for i in reversed(range(len(dirs))):
+ if dirs[i].startswith('.') or dirs[i] == 'debian':
+ del dirs[i]
+ elif dirs[i] == '__pycache__' or dirs[i].endswith('.egg-info'):
+ self.spawn(['rm', '-r', os.path.join(path, dirs[i])])
+ del dirs[i]
+
+ for f in files:
+ f = os.path.join(path, f)
+ if f.endswith('.pyc'):
+ self.spawn(['rm', f])
+ elif f.startswith('./debhelper') and f.endswith('.1'):
+ self.spawn(['rm', f])
+
+
+with open(os.path.join(here, 'README.rst'), encoding='utf-8') as f:
+ long_description = f.read()
+
+setup(
+ name=about["__title__"],
+ version=about["__version__"],
+
+ description=about["__summary__"],
+ long_description=long_description,
+ license=about["__license__"],
+ url=about["__uri__"],
+
+ author=about["__author__"],
+ author_email=about["__email__"],
+ zip_safe=False,
+ install_requires=[
+ 'gphoto2',
+ 'pyzmq',
+ 'psutil',
+ 'pyxdg',
+ 'arrow',
+ 'python-dateutil',
+ 'colorlog',
+ 'pyprind',
+ 'rawkit',
+ 'easygui',
+ 'colour',
+ 'pymediainfo',
+ 'sortedcontainers'
+ ],
+ extras_require={':python_version == "3.4"': ['scandir', 'typing']},
+ include_package_data = False,
+ data_files = [
+ (
+ 'share/man/man1', [
+ 'build/doc/rapid-photo-downloader.1', 'build/doc/analyze-pv-structure.1'
+ ]
+ ),
+ (
+ 'share/applications', [
+ 'build/share/applications/net.damonlynch.rapid-photo-downloader.desktop'
+ ]
+ ),
+ (
+ 'share/solid/actions', [
+ 'build/share/solid/actions/net.damonlynch.rapid-photo-downloader.desktop'
+ ],
+ ),
+ (
+ 'share/appdata', [
+ 'build/share/appdata/net.damonlynch.rapid-photo-downloader.appdata.xml'
+ ]
+ )
+ ],
+ packages = ['raphodo'],
+ entry_points={
+ 'gui_scripts': ['rapid-photo-downloader=raphodo.rapid:main'],
+ 'console_scripts': ['analyze-pv-structure=raphodo.analyzephotos:main']
+ },
+ classifiers=[
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: X11 Applications :: Qt',
+ 'Intended Audience :: End Users/Desktop',
+ 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
+ 'Operating System :: POSIX :: Linux',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
+ 'Topic :: Multimedia :: Graphics',
+ 'Topic :: Multimedia :: Video'
],
- cmdclass={'install_data': InstallData}
+ keywords='photo, video, download, ingest, import, camera, phone, backup, rename, photography,' \
+ ' photographer, transfer, copy, raw, cr2, nef, arw',
+ cmdclass={
+ 'build': build_extra_man_page,
+ 'build_pod2man': build_pod2man,
+ "build_icons" : build_icons,
+ 'install': install,
+ 'clean': clean_extra,
+ "build_i18n": build_i18n,
+ },
)