diff options
Diffstat (limited to 'setup.py')
-rw-r--r-- | setup.py | 489 |
1 files changed, 397 insertions, 92 deletions
@@ -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, + }, ) |