mirror of
https://github.com/codex-storage/deluge.git
synced 2025-01-11 20:14:13 +00:00
15e9f5f218
Two more commands were added to setup.py: * develop_plugins - Installs each of the plugins in development mode * egg_info_plugins - Create the '.egg-info' distribution directories for each plugin. This will make the plugin discoverable by deluge Both these commands are intended to be used while developing deluge.
546 lines
18 KiB
Python
546 lines
18 KiB
Python
#!/usr/bin/env python
|
|
#
|
|
# setup.py
|
|
#
|
|
# Copyright (C) 2007 Andrew Resch <andrewresch@gmail.com>
|
|
# 2009 Damien Churchill <damoxc@gmail.com>
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3, or (at your option)
|
|
# any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, write to:
|
|
# The Free Software Foundation, Inc.,
|
|
# 51 Franklin Street, Fifth Floor
|
|
# Boston, MA 02110-1301, USA.
|
|
#
|
|
|
|
try:
|
|
from setuptools import setup, find_packages, Extension
|
|
except ImportError:
|
|
import ez_setup
|
|
ez_setup.use_setuptools()
|
|
from setuptools import setup, find_packages, Extension
|
|
|
|
import glob
|
|
import sys
|
|
|
|
from distutils import cmd, sysconfig
|
|
from distutils.command.build import build as _build
|
|
from distutils.command.build_ext import build_ext as _build_ext
|
|
from distutils.command.clean import clean as _clean
|
|
try:
|
|
from sphinx.setup_command import BuildDoc
|
|
except ImportError:
|
|
class BuildDoc(object):
|
|
pass
|
|
|
|
import msgfmt
|
|
import os
|
|
import platform
|
|
|
|
python_version = platform.python_version()[0:3]
|
|
|
|
def windows_check():
|
|
return platform.system() in ('Windows', 'Microsoft')
|
|
|
|
def osx_check():
|
|
return platform.system() == "Darwin"
|
|
|
|
if not os.environ.has_key("CC"):
|
|
os.environ["CC"] = "gcc"
|
|
|
|
if not os.environ.has_key("CXX"):
|
|
os.environ["CXX"] = "gcc"
|
|
|
|
if not os.environ.has_key("CPP"):
|
|
os.environ["CPP"] = "g++"
|
|
|
|
# The libtorrent extension
|
|
_extra_compile_args = [
|
|
"-D_FILE_OFFSET_BITS=64",
|
|
"-DNDEBUG",
|
|
"-DTORRENT_USE_OPENSSL=1",
|
|
"-DBOOST_FILESYSTEM_VERSION=2",
|
|
"-O2",
|
|
]
|
|
|
|
if windows_check():
|
|
_extra_compile_args += [
|
|
"-D__USE_W32_SOCKETS",
|
|
"-D_WIN32_WINNT=0x0500",
|
|
"-D_WIN32",
|
|
"-DWIN32_LEAN_AND_MEAN",
|
|
"-DBOOST_ALL_NO_LIB",
|
|
"-DBOOST_THREAD_USE_LIB",
|
|
"-DBOOST_WINDOWS",
|
|
"-DBOOST_WINDOWS_API",
|
|
"-DWIN32",
|
|
"-DUNICODE",
|
|
"-D_UNICODE",
|
|
"-D_SCL_SECURE_NO_WARNINGS",
|
|
"/O2",
|
|
"/Ob2",
|
|
"/W3",
|
|
"/GR",
|
|
"/MD",
|
|
"/wd4675",
|
|
"/Zc:wchar_t",
|
|
"/Zc:forScope",
|
|
"/EHsc",
|
|
"-c",
|
|
]
|
|
else:
|
|
_extra_compile_args += ["-Wno-missing-braces"]
|
|
|
|
def remove_from_cflags(flags):
|
|
if not windows_check():
|
|
keys = ["OPT", "CFLAGS"]
|
|
if python_version == '2.5':
|
|
keys = ["CFLAGS"]
|
|
|
|
for key in keys:
|
|
cv_opt = sysconfig.get_config_vars()[key]
|
|
for flag in flags:
|
|
cv_opt = cv_opt.replace(flag, " ")
|
|
sysconfig.get_config_vars()[key] = " ".join(cv_opt.split())
|
|
|
|
removals = ["-Wstrict-prototypes"]
|
|
remove_from_cflags(removals)
|
|
|
|
_library_dirs = [
|
|
]
|
|
|
|
_include_dirs = [
|
|
'./libtorrent',
|
|
'./libtorrent/include',
|
|
'./libtorrent/include/libtorrent'
|
|
]
|
|
|
|
if windows_check():
|
|
_include_dirs += ['./win32/include','./win32/include/openssl', './win32/include/zlib']
|
|
_library_dirs += ['./win32/lib']
|
|
_libraries = [
|
|
'advapi32',
|
|
'boost_filesystem-vc-mt-1_37',
|
|
'boost_date_time-vc-mt-1_37',
|
|
'boost_iostreams-vc-mt-1_37',
|
|
'boost_python-vc-mt-1_37',
|
|
'boost_system-vc-mt-1_37',
|
|
'boost_thread-vc-mt-1_37',
|
|
'gdi32',
|
|
'libeay32',
|
|
'ssleay32',
|
|
'ws2_32',
|
|
'wsock32',
|
|
'zlib'
|
|
]
|
|
else:
|
|
_include_dirs += [
|
|
'/usr/include/python' + python_version,
|
|
sysconfig.get_config_var("INCLUDEDIR")
|
|
]
|
|
for include in os.environ.get("INCLUDEDIR", "").split(":"):
|
|
_include_dirs.append(include)
|
|
|
|
_library_dirs += [sysconfig.get_config_var("LIBDIR"), '/opt/local/lib']
|
|
if osx_check():
|
|
_include_dirs += [
|
|
'/opt/local/include/boost-1_35',
|
|
'/opt/local/include/boost-1_36',
|
|
'/sw/include/boost-1_35',
|
|
'/sw/include/boost'
|
|
]
|
|
_libraries = [
|
|
'boost_filesystem',
|
|
'boost_date_time',
|
|
'boost_iostreams',
|
|
'boost_python',
|
|
'boost_thread',
|
|
'pthread',
|
|
'ssl',
|
|
'z'
|
|
]
|
|
|
|
if not windows_check():
|
|
dynamic_lib_extension = ".so"
|
|
if osx_check():
|
|
dynamic_lib_extension = ".dylib"
|
|
|
|
_lib_extensions = ['-mt', '-mt_1_39', '-mt-1_38', '-mt-1_37', '-mt-1_36', '-mt-1_35']
|
|
|
|
# Modify the libs if necessary for systems with only -mt boost libs
|
|
for lib in _libraries:
|
|
if lib[:6] == "boost_":
|
|
for lib_prefix in _library_dirs:
|
|
for lib_suffix in _lib_extensions:
|
|
# If there is a -mt version use that
|
|
if os.path.exists(os.path.join(lib_prefix, "lib" + lib + lib_suffix + dynamic_lib_extension)):
|
|
_libraries[_libraries.index(lib)] = lib + lib_suffix
|
|
lib = lib + lib_suffix
|
|
break
|
|
|
|
_sources = glob.glob("./libtorrent/src/*.cpp") + \
|
|
glob.glob("./libtorrent/src/*.c") + \
|
|
glob.glob("./libtorrent/src/kademlia/*.cpp") + \
|
|
glob.glob("./libtorrent/bindings/python/src/*.cpp")
|
|
|
|
# Remove some files from the source that aren't needed
|
|
_source_removals = ["mapped_storage.cpp", "memdebug.cpp"]
|
|
to_remove = []
|
|
for source in _sources:
|
|
for rem in _source_removals:
|
|
if rem in source:
|
|
to_remove.append(source)
|
|
|
|
for rem in to_remove:
|
|
_sources.remove(rem)
|
|
|
|
_ext_modules = []
|
|
|
|
# Check for a system libtorrent and if found, then do not build the libtorrent extension
|
|
build_libtorrent = True
|
|
try:
|
|
from deluge._libtorrent import lt
|
|
except ImportError:
|
|
build_libtorrent = True
|
|
else:
|
|
build_libtorrent = False
|
|
|
|
if build_libtorrent:
|
|
got_libtorrent = False
|
|
if not os.path.exists("libtorrent"):
|
|
import subprocess
|
|
if subprocess.call(['./get_libtorrent.sh']) > 0:
|
|
got_libtorrent = False
|
|
else:
|
|
got_libtorrent = True
|
|
else:
|
|
got_libtorrent = True
|
|
|
|
if got_libtorrent:
|
|
# There isn't a system libtorrent library, so let's build the one included with deluge
|
|
libtorrent = Extension(
|
|
'libtorrent',
|
|
extra_compile_args = _extra_compile_args,
|
|
include_dirs = _include_dirs,
|
|
libraries = _libraries,
|
|
library_dirs = _library_dirs,
|
|
sources = _sources
|
|
)
|
|
|
|
_ext_modules = [libtorrent]
|
|
|
|
class build_trans(cmd.Command):
|
|
description = 'Compile .po files into .mo files'
|
|
|
|
user_options = [
|
|
('build-lib', None, "lib build folder")
|
|
]
|
|
|
|
def initialize_options(self):
|
|
self.build_lib = None
|
|
|
|
def finalize_options(self):
|
|
self.set_undefined_options('build', ('build_lib', 'build_lib'))
|
|
|
|
def run(self):
|
|
po_dir = os.path.join(os.path.dirname(__file__), 'deluge/i18n/')
|
|
for path, names, filenames in os.walk(po_dir):
|
|
for f in filenames:
|
|
if f.endswith('.po'):
|
|
lang = f[:len(f) - 3]
|
|
src = os.path.join(path, f)
|
|
dest_path = os.path.join(self.build_lib, 'deluge', 'i18n', lang, \
|
|
'LC_MESSAGES')
|
|
dest = os.path.join(dest_path, 'deluge.mo')
|
|
if not os.path.exists(dest_path):
|
|
os.makedirs(dest_path)
|
|
if not os.path.exists(dest):
|
|
print('Compiling %s' % src)
|
|
msgfmt.make(src, dest)
|
|
else:
|
|
src_mtime = os.stat(src)[8]
|
|
dest_mtime = os.stat(dest)[8]
|
|
if src_mtime > dest_mtime:
|
|
print('Compiling %s' % src)
|
|
msgfmt.make(src, dest)
|
|
|
|
class build_plugins(cmd.Command):
|
|
description = "Build plugins into .eggs"
|
|
|
|
user_options = []
|
|
|
|
def initialize_options(self):
|
|
pass
|
|
|
|
def finalize_options(self):
|
|
pass
|
|
|
|
def run(self):
|
|
# Build the plugin eggs
|
|
PLUGIN_PATH = "deluge/plugins/*"
|
|
|
|
for path in glob.glob(PLUGIN_PATH):
|
|
if os.path.exists(os.path.join(path, "setup.py")):
|
|
os.system("cd " + path + "&& " + sys.executable + " setup.py bdist_egg -d ..")
|
|
|
|
|
|
class develop_plugins(cmd.Command):
|
|
description = "install plugin's in 'development mode'"
|
|
|
|
user_options = []
|
|
|
|
def initialize_options(self):
|
|
pass
|
|
|
|
def finalize_options(self):
|
|
pass
|
|
|
|
def run(self):
|
|
# Build the plugin eggs
|
|
PLUGIN_PATH = "deluge/plugins/*"
|
|
|
|
for path in glob.glob(PLUGIN_PATH):
|
|
if os.path.exists(os.path.join(path, "setup.py")):
|
|
os.system("cd " + path + "&& " + sys.executable + " setup.py develop")
|
|
|
|
|
|
class egg_info_plugins(cmd.Command):
|
|
description = "create a distribution's .egg-info directory"
|
|
|
|
user_options = []
|
|
|
|
def initialize_options(self):
|
|
pass
|
|
|
|
def finalize_options(self):
|
|
pass
|
|
|
|
def run(self):
|
|
# Build the plugin eggs
|
|
PLUGIN_PATH = "deluge/plugins/*"
|
|
|
|
for path in glob.glob(PLUGIN_PATH):
|
|
if os.path.exists(os.path.join(path, "setup.py")):
|
|
os.system("cd " + path + "&& " + sys.executable + " setup.py egg_info")
|
|
|
|
|
|
class build_docs(BuildDoc):
|
|
def run(self):
|
|
class FakeModule(object):
|
|
def __init__(self, *args, **kwargs): pass
|
|
|
|
def __call__(self, *args, **kwargs):
|
|
return FakeModule()
|
|
|
|
def __getattr__(self, key):
|
|
return FakeModule()
|
|
|
|
def __setattr__(self, key, value):
|
|
self.__dict__[key] = value
|
|
|
|
old_import = __builtins__.__import__
|
|
def new_import(name, globals={}, locals={}, fromlist=[], level=-1):
|
|
try:
|
|
return old_import(name, globals, locals, fromlist, level)
|
|
except ImportError:
|
|
return FakeModule()
|
|
except Exception, e:
|
|
print "Skipping Exception: ", e
|
|
return FakeModule()
|
|
__builtins__.__import__ = new_import
|
|
|
|
BuildDoc.run(self)
|
|
|
|
class build(_build):
|
|
sub_commands = [('build_trans', None), ('build_plugins', None)] + _build.sub_commands
|
|
def run(self):
|
|
# Run all sub-commands (at least those that need to be run)
|
|
_build.run(self)
|
|
|
|
class build_debug(build):
|
|
sub_commands = [x for x in build.sub_commands if x[0] != 'build_ext'] + [('build_ext_debug', None)]
|
|
|
|
class build_ext_debug(_build_ext):
|
|
|
|
def run(self):
|
|
if not self.distribution.ext_modules:
|
|
return _build_ext.run(self)
|
|
|
|
lt_ext = None
|
|
for ext in self.distribution.ext_modules:
|
|
if ext.name == 'libtorrent':
|
|
lt_ext = ext
|
|
|
|
if not lt_ext:
|
|
return _build_ext.run(self)
|
|
|
|
lt_ext.extra_compile_args.remove('-DNDEBUG')
|
|
lt_ext.extra_compile_args.remove('-O2')
|
|
lt_ext.extra_compile_args.append('-g')
|
|
remove_from_cflags(["-DNDEBUG", "-O2"])
|
|
return _build_ext.run(self)
|
|
|
|
class clean_plugins(cmd.Command):
|
|
description = "Cleans the plugin folders"
|
|
user_options = [
|
|
('all', 'a', "remove all build output, not just temporary by-products")
|
|
]
|
|
boolean_options = ['all']
|
|
|
|
def initialize_options(self):
|
|
self.all = None
|
|
|
|
def finalize_options(self):
|
|
self.set_undefined_options('clean', ('all', 'all'))
|
|
|
|
def run(self):
|
|
print("Cleaning the plugin's folders..")
|
|
|
|
PLUGIN_PATH = "deluge/plugins/*"
|
|
|
|
for path in glob.glob(PLUGIN_PATH):
|
|
if os.path.exists(os.path.join(path, "setup.py")):
|
|
c = "cd " + path + "&& " + sys.executable + " setup.py clean"
|
|
if self.all:
|
|
c += " -a"
|
|
os.system(c)
|
|
|
|
# Delete the .eggs
|
|
if path[-4:] == ".egg":
|
|
print("Deleting %s" % path)
|
|
os.remove(path)
|
|
|
|
EGG_INFO_DIR_PATH = "deluge/plugins/*/*.egg-info"
|
|
|
|
for path in glob.glob(EGG_INFO_DIR_PATH):
|
|
# Delete the .egg-info's directories
|
|
if path[-9:] == ".egg-info":
|
|
print("Deleting %s" % path)
|
|
for fpath in os.listdir(path):
|
|
os.remove(os.path.join(path, fpath))
|
|
os.removedirs(path)
|
|
|
|
class clean(_clean):
|
|
sub_commands = _clean.sub_commands + [('clean_plugins', None)]
|
|
|
|
def run(self):
|
|
# Run all sub-commands (at least those that need to be run)
|
|
for cmd_name in self.get_sub_commands():
|
|
self.run_command(cmd_name)
|
|
_clean.run(self)
|
|
|
|
cmdclass = {
|
|
'build': build,
|
|
'build_trans': build_trans,
|
|
'build_plugins': build_plugins,
|
|
'build_docs': build_docs,
|
|
'build_debug': build_debug,
|
|
'build_ext_debug': build_ext_debug,
|
|
'clean_plugins': clean_plugins,
|
|
'clean': clean,
|
|
'develop_plugins': develop_plugins,
|
|
'egg_info_plugins': egg_info_plugins
|
|
}
|
|
|
|
# Data files to be installed to the system
|
|
_data_files = [
|
|
('share/icons/scalable/apps', ['deluge/ui/data/icons/scalable/apps/deluge.svg']),
|
|
('share/icons/hicolor/128x128/apps', ['deluge/ui/data/icons/hicolor/128x128/apps/deluge.png']),
|
|
('share/icons/hicolor/16x16/apps', ['deluge/ui/data/icons/hicolor/16x16/apps/deluge.png']),
|
|
('share/icons/hicolor/192x192/apps', ['deluge/ui/data/icons/hicolor/192x192/apps/deluge.png']),
|
|
('share/icons/hicolor/22x22/apps', ['deluge/ui/data/icons/hicolor/22x22/apps/deluge.png']),
|
|
('share/icons/hicolor/24x24/apps', ['deluge/ui/data/icons/hicolor/24x24/apps/deluge.png']),
|
|
('share/icons/hicolor/256x256/apps', ['deluge/ui/data/icons/hicolor/256x256/apps/deluge.png']),
|
|
('share/icons/hicolor/32x32/apps', ['deluge/ui/data/icons/hicolor/32x32/apps/deluge.png']),
|
|
('share/icons/hicolor/36x36/apps', ['deluge/ui/data/icons/hicolor/36x36/apps/deluge.png']),
|
|
('share/icons/hicolor/48x48/apps', ['deluge/ui/data/icons/hicolor/48x48/apps/deluge.png']),
|
|
('share/icons/hicolor/64x64/apps', ['deluge/ui/data/icons/hicolor/64x64/apps/deluge.png']),
|
|
('share/icons/hicolor/72x72/apps', ['deluge/ui/data/icons/hicolor/72x72/apps/deluge.png']),
|
|
('share/icons/hicolor/96x96/apps', ['deluge/ui/data/icons/hicolor/96x96/apps/deluge.png']),
|
|
('share/applications', ['deluge/ui/data/share/applications/deluge.desktop']),
|
|
('share/pixmaps', ['deluge/ui/data/pixmaps/deluge.png', 'deluge/ui/data/pixmaps/deluge.xpm']),
|
|
('share/man/man1', [
|
|
'docs/man/deluge.1',
|
|
'docs/man/deluged.1',
|
|
'docs/man/deluge-gtk.1',
|
|
'docs/man/deluge-web.1',
|
|
'docs/man/deluge-console.1'])
|
|
]
|
|
|
|
entry_points = {
|
|
"console_scripts": [
|
|
"deluge-console = deluge.ui.console:start",
|
|
"deluge-web = deluge.ui.web:start",
|
|
"deluged = deluge.main:start_daemon"
|
|
],
|
|
"gui_scripts": [
|
|
"deluge = deluge.main:start_ui",
|
|
"deluge-gtk = deluge.ui.gtkui:start"
|
|
]
|
|
}
|
|
|
|
|
|
if windows_check():
|
|
entry_points["console_scripts"].append("deluge-debug = deluge.main:start_ui")
|
|
|
|
# Main setup
|
|
setup(
|
|
name = "deluge",
|
|
version = "1.3.900",
|
|
fullname = "Deluge Bittorrent Client",
|
|
description = "Bittorrent Client",
|
|
author = "Andrew Resch, Damien Churchill",
|
|
author_email = "andrewresch@gmail.com, damoxc@gmail.com",
|
|
keywords = "torrent bittorrent p2p fileshare filesharing",
|
|
long_description = """Deluge is a bittorrent client that utilizes a
|
|
daemon/client model. There are various user interfaces available for
|
|
Deluge such as the GTKui, the webui and a console ui. Deluge uses
|
|
libtorrent in it's backend to handle the bittorrent protocol.""",
|
|
url = "http://deluge-torrent.org",
|
|
license = "GPLv3",
|
|
|
|
cmdclass = cmdclass,
|
|
data_files = _data_files,
|
|
ext_package = "deluge",
|
|
ext_modules = _ext_modules,
|
|
package_data = {"deluge": ["ui/gtkui/glade/*.glade",
|
|
"ui/data/pixmaps/*.png",
|
|
"ui/data/pixmaps/*.svg",
|
|
"ui/data/pixmaps/*.ico",
|
|
"ui/data/pixmaps/*.gif",
|
|
"ui/data/pixmaps/flags/*.png",
|
|
"plugins/*.egg",
|
|
"i18n/*.pot",
|
|
"i18n/*/LC_MESSAGES/*.mo",
|
|
"ui/web/gettext.js",
|
|
"ui/web/index.html",
|
|
"ui/web/css/*.css",
|
|
"ui/web/icons/*.png",
|
|
"ui/web/images/*.gif",
|
|
"ui/web/images/*.png",
|
|
"ui/web/js/*.js",
|
|
"ui/web/js/*/*.js",
|
|
"ui/web/js/*/.order",
|
|
"ui/web/js/*/*/*.js",
|
|
"ui/web/js/*/*/.order",
|
|
"ui/web/render/*.html",
|
|
"ui/web/themes/css/*.css",
|
|
"ui/web/themes/images/*/*.gif",
|
|
"ui/web/themes/images/*/*.png",
|
|
"ui/web/themes/images/*/*/*.gif",
|
|
"ui/web/themes/images/*/*/*.png"
|
|
]},
|
|
packages = find_packages(exclude=["plugins", "docs", "tests"]),
|
|
namespace_packages = ["deluge", "deluge.plugins"],
|
|
entry_points = entry_points
|
|
)
|