#!/usr/bin/env python # -*- coding: utf-8 -*- import os import sys from subprocess import check_output, call, STDOUT from distutils import log from distutils.core import Command from setuptools import setup, find_packages from setuptools.command.develop import develop from setuptools.command.sdist import sdist from setuptools.command.install import install from setuptools.command.bdist_egg import bdist_egg from setuptools.command.egg_info import egg_info ROOT = os.path.join(os.path.dirname(os.path.realpath(__file__))) DEVNULL = open(os.devnull, "wb") # Not sure bower was a great idea... VENDOR_TO_KEEP = [ "burpui/static/vendor/bootswatch/slate/bootstrap.min.css", "burpui/static/vendor/bootswatch/fonts/glyphicons-halflings-regular.eot", "burpui/static/vendor/bootswatch/fonts/glyphicons-halflings-regular.svg", "burpui/static/vendor/bootswatch/fonts/glyphicons-halflings-regular.ttf", "burpui/static/vendor/bootswatch/fonts/glyphicons-halflings-regular.woff", "burpui/static/vendor/bootswatch/fonts/glyphicons-halflings-regular.woff2", "burpui/static/vendor/nvd3/build/nv.d3.min.css", "burpui/static/vendor/datatables.net-bs/css/dataTables.bootstrap.min.css", "burpui/static/vendor/datatables.net-responsive-bs/css/responsive.bootstrap.min.css", "burpui/static/vendor/datatables.net-select-bs/css/select.bootstrap.min.css", "burpui/static/vendor/datatables.net-buttons-bs/css/buttons.bootstrap.min.css", "burpui/static/vendor/datatables.net-fixedheader-bs/css/fixedHeader.bootstrap.min.css", "burpui/static/vendor/jquery.fancytree/dist/skin-bootstrap/ui.fancytree.min.css", "burpui/static/vendor/bootstrap-switch/dist/css/bootstrap3/bootstrap-switch.min.css", "burpui/static/vendor/angular-ui-select/dist/select.min.css", "burpui/static/vendor/jquery/dist/jquery.min.js", "burpui/static/vendor/jquery-ui/jquery-ui.min.js", "burpui/static/vendor/bootstrap/dist/js/bootstrap.min.js", "burpui/static/vendor/typeahead.js/dist/typeahead.jquery.min.js", "burpui/static/vendor/d3/d3.min.js", "burpui/static/vendor/nvd3/build/nv.d3.min.js", "burpui/static/vendor/datatables.net/js/jquery.dataTables.min.js", "burpui/static/vendor/datatables.net-bs/js/dataTables.bootstrap.min.js", "burpui/static/vendor/datatables.net-responsive/js/dataTables.responsive.min.js", "burpui/static/vendor/datatables.net-responsive-bs/js/responsive.bootstrap.min.js", "burpui/static/vendor/datatables.net-select/js/dataTables.select.min.js", "burpui/static/vendor/datatables.net-buttons/js/dataTables.buttons.min.js", "burpui/static/vendor/datatables.net-buttons-bs/js/buttons.bootstrap.min.js", "burpui/static/vendor/datatables.net-fixedheader/js/dataTables.fixedHeader.min.js", "burpui/static/vendor/jquery.floatThead/dist/jquery.floatThead.min.js", "burpui/static/vendor/jquery.fancytree/dist/jquery.fancytree-all.min.js", "burpui/static/vendor/jquery-file-download/src/Scripts/jquery.fileDownload.js", "burpui/static/vendor/lodash/dist/lodash.min.js", "burpui/static/vendor/angular/angular.min.js", "burpui/static/vendor/angular-route/angular-route.min.js", "burpui/static/vendor/angular-sanitize/angular-sanitize.min.js", "burpui/static/vendor/angular-resource/angular-resource.min.js", "burpui/static/vendor/angular-animate/angular-animate.min.js", "burpui/static/vendor/bootstrap-switch/dist/js/bootstrap-switch.min.js", "burpui/static/vendor/angular-bootstrap-switch/dist/angular-bootstrap-switch.min.js", "burpui/static/vendor/angular-ui-select/dist/select.min.js", "burpui/static/vendor/angular-strap/dist/angular-strap.min.js", "burpui/static/vendor/angular-strap/dist/angular-strap.tpl.min.js", "burpui/static/vendor/angular-onbeforeunload/build/angular-onbeforeunload.js", "burpui/static/vendor/angular-datatables-0.6.2/dist/angular-datatables.min.js", "burpui/static/vendor/angular-highlightjs/build/angular-highlightjs.min.js", "burpui/static/vendor/moment/min/moment.min.js", "burpui/static/vendor/moment/locale/fr.js", "burpui/static/vendor/moment/locale/es.js", "burpui/static/vendor/moment/locale/it.js", "burpui/static/vendor/moment-timezone/builds/moment-timezone-with-data-10-year-range.min.js", "burpui/static/vendor/angular-ui-calendar/src/calendar.js", "burpui/static/vendor/fullcalendar/dist/fullcalendar.min.css", "burpui/static/vendor/fullcalendar/dist/fullcalendar.print.min.css", "burpui/static/vendor/fullcalendar/dist/fullcalendar.min.js", "burpui/static/vendor/fullcalendar/dist/gcal.min.js", "burpui/static/vendor/fullcalendar/dist/locale/fr.js", "burpui/static/vendor/fullcalendar/dist/locale/es.js", "burpui/static/vendor/fullcalendar/dist/locale/it.js", "burpui/static/vendor/angular-bootstrap/ui-bootstrap.min.js", "burpui/static/vendor/angular-bootstrap/ui-bootstrap-tpls.min.js", "burpui/static/vendor/components-font-awesome/css/font-awesome.min.css", "burpui/static/vendor/components-font-awesome/fonts/FontAwesome.otf", "burpui/static/vendor/components-font-awesome/fonts/fontawesome-webfont.eot", "burpui/static/vendor/components-font-awesome/fonts/fontawesome-webfont.svg", "burpui/static/vendor/components-font-awesome/fonts/fontawesome-webfont.ttf", "burpui/static/vendor/components-font-awesome/fonts/fontawesome-webfont.woff", "burpui/static/vendor/components-font-awesome/fonts/fontawesome-webfont.woff2", "burpui/static/vendor/socket.io-client/dist/socket.io.min.js", "burpui/static/vendor/js-cookie/src/js.cookie.js", "burpui/static/vendor/ace-builds/src-min-noconflict/ace.js", "burpui/static/vendor/ace-builds/src-min-noconflict/mode-json.js", "burpui/static/vendor/ace-builds/src-min-noconflict/worker-json.js", "burpui/static/vendor/ace-builds/src-min-noconflict/theme-ambiance.js", ] for p in VENDOR_TO_KEEP: if not os.path.exists(p): log.info("!! missing: {}".format(p)) class DevelopWithBuildStatic(develop): def install_for_development(self): self.run_command("build_static") return develop.install_for_development(self) class EggWithBuildStatic(egg_info): def initialize_options(self): self.run_command("build_static") return egg_info.initialize_options(self) class BdistWithBuildStatic(bdist_egg): def initialize_options(self): self.run_command("build_static") return bdist_egg.initialize_options(self) class SdistWithBuildStatic(sdist): def make_distribution(self): self.run_command("build_static") return sdist.make_distribution(self) class PyTest(Command): user_options = [] description = "Run tests" def initialize_options(self): pass def finalize_options(self): pass def run(self): try: errno = call(["make", "test"]) raise SystemExit(errno) except OSError: log.error("Looks like the tools to run the tests are missing") class BuildStatic(Command): user_options = [] description = "Install bower dependencies" def initialize_options(self): pass def finalize_options(self): pass def run(self): os.chdir(ROOT) log.info("compiling translations") call( "{} ./burpui -m manage compile-translation".format(sys.executable).split(), stderr=DEVNULL, ) log.info("getting revision number") rev = "stable" ci = os.getenv("CI") commit = os.getenv("CI_COMMIT_SHA") if ( not ci and os.path.exists(".git") and call("which git", shell=True, stderr=STDOUT, stdout=DEVNULL) == 0 ): try: branch = check_output("git rev-parse HEAD", shell=True).rstrip() ver = open(os.path.join("burpui", "VERSION")).read().rstrip() log.info("version: {}".format(ver)) if branch and "dev" in ver: rev = branch try: log.info("revision: {}".format(rev)) with open("burpui/RELEASE", "wb") as f: f.write(rev) except: log.error("Unable to create release file") except: pass elif ci: try: ver = open(os.path.join("burpui", "VERSION")).read().rstrip() if "dev" in ver: rev = commit try: with open("burpui/RELEASE", "wb") as f: f.write(rev) except: pass except: pass else: log.info("using upstream revision") keep = VENDOR_TO_KEEP dirlist = [] for dirname, subdirs, files in os.walk("burpui/static/vendor"): for filename in files: path = os.path.join(dirname, filename) _, ext = os.path.splitext(path) if ( os.path.isfile(path) and path not in keep and filename not in ["bower.json", "package.json"] ): if (rev == "stable" and ext == ".map") or ext != ".map": os.unlink(path) elif os.path.isdir(path): dirlist.append(path) dirlist.sort(reverse=True) for d in dirlist: if os.path.isdir(d) and not os.listdir(d): os.rmdir(d) class CustomInstall(install): def run(self): self.run_command("build_static") install.run(self) def readme(): """ Function used to skip the screenshots part """ desc = "" cpt = 0 skip = False with open(os.path.join(ROOT, "README.rst")) as f: for line in f.readlines(): if line.rstrip() == "Screenshots": skip = True if skip: cpt += 1 if cpt > 6: skip = False if skip: continue desc += line return desc sys.path.insert(0, os.path.join(ROOT)) from burpui.desc import ( __author__, __author_email__, __description__, __url__, __title__, ) # noqa name = __title__ author = __author__ author_email = __author_email__ description = __description__ url = __url__ with open(os.path.join(ROOT, "requirements.txt")) as f: requires = [x.strip() for x in f if x.strip()] dev_requires = ["flake8", "pylint", "black"] test_requires = [ "pytest", "pytest-cov", "pytest-flask", "pytest-mock", "nose", "coverage", "mock", "mockredispy", "Flask-Session", "Celery", "redis", "Flask-SQLAlchemy", "Flask-Migrate", "sqlalchemy_utils", ] datadir = os.path.join("share", "burpui") confdir = os.path.join(datadir, "etc") contrib = os.path.join(datadir, "contrib") migrations = [ ( os.path.join(datadir, root), [os.path.join(root, f) for f in files if not f.endswith(".pyc")], ) for root, dirs, files in os.walk("migrations") ] setup( name=name, version=open(os.path.join(ROOT, "burpui", "VERSION")).read().rstrip(), description=description, long_description=readme(), license=open(os.path.join(ROOT, "LICENSE")).readline().rstrip(), author=author, author_email=author_email, url=url, keywords="burp web ui backup monitoring", packages=find_packages(), include_package_data=True, package_data={ "static": ["burpui/static/*"], "templates": ["burpui/templates/*"], "VERSION": ["burpui/VERSION"], }, entry_points={ "console_scripts": [ "burp-ui=burpui.__main__:server", "bui-celery=burpui.__main__:celery", "bui-manage=burpui.__main__:manage", "bui-agent-legacy=burpui.__main__:agent", "bui-monitor=burpui.__main__:monitor", "burp-ui-legacy=burpui.__main__:legacy", ], }, data_files=[ (confdir, [os.path.join(confdir, "burpui.sample.cfg")]), (os.path.join(contrib, "centos"), ["contrib/centos/init.sh"]), (os.path.join(contrib, "freebsd"), ["contrib/freebsd/gunicorn.rc"]), (os.path.join(contrib, "gunicorn"), ["contrib/gunicorn/burpui_gunicorn.py"]), ( os.path.join(contrib, "systemd"), [ "contrib/systemd/bui-agent.service", "contrib/systemd/bui-celery.service", "contrib/systemd/bui-celery-beat.service", "contrib/systemd/bui-gunicorn.service", "contrib/systemd/bui-monitor.service", "contrib/systemd/bui-websocket.service", ], ), ] + migrations, python_requires=">=3.7", install_requires=requires, extras_require={ "ldap_authentication": ["ldap3"], "gunicorn": ["gunicorn"], "gunicorn-extra": ["redis"], "ci": test_requires, "dev": dev_requires, "celery": ["Celery>=4.3", "redis"], "sql": ["Flask-SQLAlchemy", "Flask-Migrate>=2.1.0", "sqlalchemy-utils"], "limit": ["Flask-Limiter", "redis"], "websocket": ["flask-socketio", "redis", "gevent-websocket"], "rtd": ["sphinxcontrib-httpdomain==1.6.1"], }, tests_require=test_requires, classifiers=[ "Framework :: Flask", "Intended Audience :: System Administrators", "Natural Language :: English", "License :: OSI Approved :: BSD License", "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3", "Topic :: System :: Archiving :: Backup", "Topic :: System :: Monitoring", ], cmdclass={ "build_static": BuildStatic, "develop": DevelopWithBuildStatic, "sdist": SdistWithBuildStatic, "install": CustomInstall, "bdist_egg": BdistWithBuildStatic, "egg_info": EggWithBuildStatic, }, )