# -*- coding: utf-8 -*- from paver.easy import * from paver.setuputils import setup from paver.doctools import cog import sys import re from urllib import urlretrieve from subprocess import call, Popen, PIPE from zipfile import ZipFile PROJECT_DIR = path(__file__).dirname() sys.path.append(PROJECT_DIR) options = environment.options path('pyload').mkdir() extradeps = [] if sys.version_info <= (2, 5): extradeps += 'simplejson' setup( name="pyload", version="0.4.9", description='Fast, lightweight and full featured download manager.', long_description=open(PROJECT_DIR / "README").read(), keywords = ('pyload', 'download-manager', 'one-click-hoster', 'download'), url="http://pyload.org", download_url='http://pyload.org/download', license='GPL v3', author="pyLoad Team", author_email="support@pyload.org", platforms = ('Any',), #package_dir={'pyload': 'src'}, packages=['pyload'], #package_data=find_package_data(), #data_files=[], include_package_data=True, exclude_package_data={'pyload': ['docs*', 'scripts*', 'tests*']}, #exluced from build but not from sdist # 'bottle >= 0.10.0' not in list, because its small and contain little modifications install_requires=['thrift >= 0.8.0', 'jinja2', 'pycurl', 'Beaker', 'BeautifulSoup>=3.2, <3.3'] + extradeps, extras_require={ 'SSL': ["pyOpenSSL"], 'DLC': ['pycrypto'], 'lightweight webserver': ['bjoern'], 'RSS plugins': ['feedparser'], }, #setup_requires=["setuptools_hg"], entry_points={ 'console_scripts': [ 'pyLoadCore = pyLoadCore:main', 'pyLoadCli = pyLoadCli:main' ]}, zip_safe=False, classifiers=[ "Development Status :: 5 - Production/Stable", "Topic :: Internet :: WWW/HTTP", "Environment :: Console", "Environment :: Web Environment", "Intended Audience :: End Users/Desktop", "License :: OSI Approved :: GNU General Public License (GPL)", "Operating System :: OS Independent", "Programming Language :: Python :: 2" ] ) options( sphinx=Bunch( builddir="_build", sourcedir="" ), get_source=Bunch( src="https://bitbucket.org/spoob/pyload/get/tip.zip", rev=None, clean=False ), thrift=Bunch( path="../thrift/trunk/compiler/cpp/thrift", gen="" ), virtualenv=Bunch( dir="env", python="python2", virtual="virtualenv2", ), cog=Bunch( pattern="*.py", ) ) # xgettext args xargs = ["--from-code=utf-8", "--copyright-holder=pyLoad Team", "--package-name=pyLoad", "--package-version=%s" % options.version, "--msgid-bugs-address='bugs@pyload.org'"] @task @needs('cog') def html(): """Build html documentation""" module = path("docs") / "module" module.rmtree() call_task('paver.doctools.html') @task @cmdopts([ ('src=', 's', 'Url to source'), ('rev=', 'r', "HG revision"), ("clean", 'c', 'Delete old source folder') ]) def get_source(options): """ Downloads pyload source from bitbucket tip or given rev""" if options.rev: options.url = "https://bitbucket.org/spoob/pyload/get/%s.zip" % options.rev pyload = path("pyload") if len(pyload.listdir()) and not options.clean: return elif pyload.exists(): pyload.rmtree() urlretrieve(options.src, "pyload_src.zip") zip = ZipFile("pyload_src.zip") zip.extractall() path("pyload_src.zip").remove() folder = [x for x in path(".").dirs() if x.name.startswith("spoob-pyload-")][0] folder.move(pyload) change_mode(pyload, 0644) change_mode(pyload, 0755, folder=True) for file in pyload.files(): if file.name.endswith(".py"): file.chmod(0755) (pyload / ".hgtags").remove() (pyload / ".hgignore").remove() #(pyload / "docs").rmtree() f = open(pyload / "__init__.py", "wb") f.close() #options.setup.packages = find_packages() #options.setup.package_data = find_package_data() @task @needs('clean', 'generate_setup', 'minilib', 'get_source', 'setuptools.command.sdist') def sdist(): """ Build source code package with distutils """ @task @cmdopts([ ('path=', 'p', 'Thrift path'), ('gen=', 'g', "Extra --gen option") ]) def thrift(options): """ Generate Thrift stubs """ print "add import for TApplicationException manually as long it is not fixed" outdir = path("module") / "remote" / "thriftbackend" (outdir / "gen-py").rmtree() cmd = [options.thrift.path, "-strict", "-o", outdir, "--gen", "py:slots,dynamic", outdir / "pyload.thrift"] if options.gen: cmd.insert(len(cmd) - 1, "--gen") cmd.insert(len(cmd) - 1, options.gen) print "running", cmd p = Popen(cmd) p.communicate() (outdir / "thriftgen").rmtree() (outdir / "gen-py").move(outdir / "thriftgen") #create light ttypes from module.remote.socketbackend.create_ttypes import main main() @task def compile_js(): """ Compile .coffee files to javascript""" root = path("module") / "web" / "media" / "js" for f in root.glob("*.coffee"): print "generate", f coffee = Popen(["coffee", "-cbs"], stdin=open(f, "rb"), stdout=PIPE) yui = Popen(["yuicompressor", "--type", "js"], stdin=coffee.stdout, stdout=PIPE) coffee.stdout.close() content = yui.communicate()[0] with open(root / f.name.replace(".coffee", ".js"), "wb") as js: js.write("{% autoescape true %}\n") js.write(content) js.write("\n{% endautoescape %}") @task def generate_locale(): """ Generates localisation files """ EXCLUDE = ["BeautifulSoup.py", "module/gui", "module/cli", "web/locale", "web/ajax", "web/cnl", "web/pyload", "setup.py"] makepot("core", path("module"), EXCLUDE, "./pyLoadCore.py\n") makepot("gui", path("module") / "gui", [], includes="./pyLoadGui.py\n") makepot("cli", path("module") / "cli", [], includes="./pyLoadCli.py\n") makepot("setup", "", [], includes="./module/setup.py\n") EXCLUDE = ["ServerThread.py", "web/media/default"] # strings from js files strings = set() for fi in path("module/web").walkfiles(): if not fi.name.endswith(".js") and not fi.endswith(".coffee"): continue with open(fi, "rb") as c: content = c.read() strings.update(re.findall(r"_\s*\(\s*\"([^\"]+)", content)) strings.update(re.findall(r"_\s*\(\s*\'([^\']+)", content)) trans = path("module") / "web" / "translations.js" with open(trans, "wb") as js: for s in strings: js.write('_("%s")\n' % s) makepot("django", path("module/web"), EXCLUDE, "./%s\n" % trans.relpath(), [".py", ".html"], ["--language=Python"]) trans.remove() path("includes.txt").remove() print "Locale generated" @task def tests(): call(["nosetests2"]) @task def virtualenv(options): """Setup virtual environment""" if path(options.dir).exists(): return call([options.virtual, "--no-site-packages", "--python", options.python, options.dir]) print "$ source %s/bin/activate" % options.dir @task def clean_env(): """Deletes the virtual environment""" env = path(options.virtualenv.dir) if env.exists(): env.rmtree() @task @needs('generate_setup', 'minilib', 'get_source', 'virtualenv') def env_install(): """Install pyLoad into the virtualenv""" venv = options.virtualenv call([path(venv.dir) / "bin" / "easy_install", "."]) @task def clean(): """Cleans build directories""" path("build").rmtree() path("dist").rmtree() #helper functions def walk_trans(path, EXCLUDE, endings=[".py"]): result = "" for f in path.walkfiles(): if [True for x in EXCLUDE if x in f.dirname().relpath()]: continue if f.name in EXCLUDE: continue for e in endings: if f.name.endswith(e): result += "./%s\n" % f.relpath() break return result def makepot(domain, p, excludes=[], includes="", endings=[".py"], xxargs=[]): print "Generate %s.pot" % domain f = open("includes.txt", "wb") if includes: f.write(includes) if p: f.write(walk_trans(path(p), excludes, endings)) f.close() call(["xgettext", "--files-from=includes.txt", "--default-domain=%s" % domain] + xargs + xxargs) # replace charset und move file with open("%s.po" % domain, "rb") as f: content = f.read() path("%s.po" % domain).remove() content = content.replace("charset=CHARSET", "charset=UTF-8") with open("locale/%s.pot" % domain, "wb") as f: f.write(content) def change_owner(dir, uid, gid): for p in dir.walk(): p.chown(uid, gid) def change_mode(dir, mode, folder=False): for p in dir.walk(): if folder and p.isdir(): p.chmod(mode) elif p.isfile() and not folder: p.chmod(mode)