dupeguru /

Full commit
# Created By: Virgil Dupras
# Created On: 2009-12-30
# Copyright 2012 Hardcoded Software (
# This software is licensed under the "BSD" License as described in the "LICENSE" file, 
# which should be included with this package. The terms are also available at 

import os
import os.path as op
import compileall
import shutil
import json
from argparse import ArgumentParser

from hscommon.plat import ISWINDOWS, ISLINUX
from import (build_dmg, add_to_pythonpath, print_and_do, copy_packages,
    build_debian_changelog, copy_qt_plugins, get_module_version)

def parse_args():
    parser = ArgumentParser()
    parser.add_argument('--sign', dest='sign_identity',
        help="Sign app under specified identity before packaging (OS X only)")
    args = parser.parse_args()
    return args

def package_cocoa(edition, sign_identity):
    app_path = {
        'se': 'cocoa/se/',
        'me': 'cocoa/me/dupeGuru',
        'pe': 'cocoa/pe/dupeGuru',
    # Rather than signing our app in XCode during the build phase, we sign it during the package
    # phase because running the app before packaging can modify it and we want to be sure to have
    # a valid signature.
    if sign_identity:
        sign_identity = "Developer ID Application: {}".format(sign_identity)
        print_and_do('codesign --force --sign "{}" "{}"'.format(sign_identity, app_path))
        print("WARNING: packaging an unsigned application")
    build_dmg(app_path, '.')

def package_windows(edition, dev):
    if not ISWINDOWS:
        print("Qt packaging only works under Windows.")
    app_version = get_module_version('core_{}'.format(edition))
    distdir = 'dist'
    if op.exists(distdir):
    # Since v4.2.3, cx_freeze started to falsely include tkinter in the package. We exclude it explicitly because of that.
    cmd = 'cxfreeze --base-name Win32GUI --target-dir "{0}" --target-name "{1}.exe" --icon {2} --exclude-modules tkinter'
    target_name = {'se': 'dupeGuru', 'me': 'dupeGuru ME', 'pe': 'dupeGuru PE'}[edition]
    icon_path = 'images\\dg{0}_logo.ico'.format(edition)
    print_and_do(cmd.format(distdir, target_name, icon_path))
    if not dev:
        # Copy qt plugins
        plugin_dest = op.join(distdir, 'qt4_plugins')
        plugin_names = ['accessible', 'codecs', 'iconengines', 'imageformats']
        copy_qt_plugins(plugin_names, plugin_dest)
        # Compress with UPX 
        libs = [name for name in os.listdir(distdir) if op.splitext(name)[1] in ('.pyd', '.dll', '.exe')]
        for lib in libs:
            print_and_do("upx --best \"{0}\"".format(op.join(distdir, lib)))
    help_path = op.join('build', 'help')
    print("Copying {} to dist\\help".format(help_path))
    shutil.copytree(help_path, op.join(distdir, 'help'))
    locale_path = op.join('build', 'locale')
    print("Copying {} to dist\\locale".format(locale_path))
    shutil.copytree(locale_path, op.join(distdir, 'locale'))

    # has to be in your PATH
    # this is so we don'a have to re-commit installer.aip at every version change
    installer_path = op.join('qt', edition, 'installer.aip')
    shutil.copy(installer_path, 'installer_tmp.aip')
    print_and_do(' /edit installer_tmp.aip /SetVersion %s' % app_version)
    print_and_do(' /build installer_tmp.aip -force')
    if op.exists('installer_tmp.back.aip'):

def package_debian(edition):
    app_version = get_module_version('core_{}'.format(edition))
    ed = lambda s: s.format(edition)
    destpath = op.join('build', 'dupeguru-{0}-{1}'.format(edition, app_version))
    if op.exists(destpath):
    srcpath = op.join(destpath, 'src')
    shutil.copy('', op.join(srcpath, ''))
    packages = ['hscommon', 'core', ed('core_{0}'), 'qtlib', 'qt', 'send2trash', 'jobprogress']
    if edition == 'me':
    copy_packages(packages, srcpath)
    shutil.copytree(ed('debian_{0}'), op.join(destpath, 'debian'))
    changelogpath = op.join('help', ed('changelog_{}'))
    changelog_dest = op.join(destpath, 'debian', 'changelog')
    project_name = ed('dupeguru-{0}')
    from_version = {'se': '2.9.2', 'me': '5.7.2', 'pe': '1.8.5'}[edition]
    build_debian_changelog(changelogpath, changelog_dest, project_name, from_version=from_version)
    shutil.copytree(op.join('build', 'help'), op.join(srcpath, 'help'))
    shutil.copytree(op.join('build', 'locale'), op.join(srcpath, 'locale'))
    shutil.copy(op.join('images', ed('dg{0}_logo_128.png')), srcpath)

def main():
    args = parse_args()
    conf = json.load(open('conf.json'))
    edition = conf['edition']
    ui = conf['ui']
    dev = conf['dev']
    print("Packaging dupeGuru {0} with UI {1}".format(edition.upper(), ui))
    if ui == 'cocoa':
        package_cocoa(edition, args.sign_identity)
    elif ui == 'qt':
        if ISWINDOWS:
            package_windows(edition, dev)
        elif ISLINUX:
            print("Qt packaging only works under Windows or Linux.")

if __name__ == '__main__':