1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3 4 5from __future__ import print_function 6from setuptools import Command, find_packages, setup 7from setuptools.command.test import test as TestCommand 8from wsgidav._version import __version__ 9 10# from datetime import datetime 11import os 12import sys 13 14 15version = __version__ 16 17 18# Override 'setup.py test' command 19class ToxCommand(TestCommand): 20 def finalize_options(self): 21 TestCommand.finalize_options(self) 22 self.test_args = [] 23 self.test_suite = True 24 25 def run_tests(self): 26 # Import here, cause outside the eggs aren't loaded 27 import tox 28 29 # Raises SystemExit 30 tox.cmdline(self.test_args) 31 32 33# Add custom command 'setup.py sphinx' 34# See https://dankeder.com/posts/adding-custom-commands-to-setup-py/ 35# and http://stackoverflow.com/a/22273180/19166 36class SphinxCommand(Command): 37 user_options = [] 38 description = "Build docs using Sphinx" 39 40 def initialize_options(self): 41 pass 42 43 def finalize_options(self): 44 pass 45 46 def run(self): 47 import subprocess 48 49 res = subprocess.call( 50 "sphinx-build -b html doc/sphinx doc/sphinx-build", shell=True 51 ) 52 outdir = os.path.join("doc", "sphinx-build") 53 if res: 54 print("ERROR: sphinx-build exited with code {}".format(res)) 55 else: 56 print("Documentation created at {}.".format(os.path.abspath(outdir))) 57 58 59try: 60 readme = open("README.md", "rt").read() 61except IOError: 62 readme = "(Readme file not found. Running from tox/setup.py test?)" 63 64# 'setup.py upload' fails on Vista, because .pypirc is searched on 'HOME' path 65if "HOME" not in os.environ and "HOMEPATH" in os.environ: 66 os.environ.setdefault("HOME", os.environ.get("HOMEPATH", "")) 67 print("Initializing HOME environment variable to '{}'".format(os.environ["HOME"])) 68 69use_cx_freeze = False 70for cmd in ["bdist_msi"]: 71 if cmd in sys.argv: 72 use_cx_freeze = True 73 break 74 75# CherryPy is required for the tests and benchmarks. It is also the preferrred 76# server for the stand-alone mode (`wsgidav.server.server_cli.py`). 77# We currently do not add it as an installation requirement, because 78# 1. users may not need the command line server at all 79# 2. users may prefer another server 80# 3. there may already cherrypy versions installed 81 82install_requires = ["defusedxml", "six", "Jinja2", "json5", "PyYAML"] 83setup_requires = install_requires 84tests_require = [] 85 86if use_cx_freeze: 87 # The Windows MSI Setup should include lxml, pywin32, and CherryPy 88 install_requires.extend( 89 [ 90 "cheroot", 91 "cheroot.ssl.builtin", 92 "lxml", 93 # "win32", 94 "wsgidav.dc.nt_dc", 95 ] 96 ) 97 # Since we included pywin32 extensions, cx_Freeze tries to create a 98 # version resource. This only supports the 'a.b.c[.d]' format: 99 try: 100 int_version = list(map(int, version.split("."))) 101 except ValueError: 102 # version = "0.0.0.{}".format(datetime.now().strftime("%Y%m%d")) 103 version = "0.0.0" 104 105 try: 106 # Only import cx_Freeze, when 'bdist_msi' command was used, because 107 # cx_Freeze seems to sabotage wheel creation: 108 from cx_Freeze import setup, Executable # noqa F811 109 110 from cx_Freeze import hooks 111 112 assert not hasattr(hooks, "load_Jinja2") 113 114 def load_Jinja2(finder, module): 115 # TODO: rename folder? 116 # finder.IncludeModule("pywintypes") 117 print("* " * 40) 118 print("load_Jinja2") 119 120 hooks.load_Jinja2 = load_Jinja2 121 122 assert not hasattr(hooks, "load_jinja2") 123 124 def load_jinja2(finder, module): 125 print("* " * 40) 126 print("load_jinja2") 127 128 hooks.load_jinja2 = load_jinja2 129 130 # cx_Freeze seems to be confused by module name 'PyYAML' which 131 # must be imported as 'yaml', so we rename here. However it must 132 # be listed as 'PyYAML' in the requirements.txt and be installed! 133 install_requires.remove("PyYAML") 134 install_requires.append("yaml") 135 136 # See also build_exe_options below: 137 install_requires.remove("Jinja2") 138 139 executables = [ 140 Executable( 141 script="wsgidav/server/server_cli.py", 142 base=None, 143 # base="Win32GUI", 144 targetName="wsgidav.exe", 145 icon="doc/logo.ico", 146 shortcutName="WsgiDAV", 147 # requires cx_Freeze PR#94: 148 # copyright="(c) 2009-2020 Martin Wendt", 149 # trademarks="...", 150 ) 151 ] 152 except ImportError: 153 # tox has problems to install cx_Freeze to it's venvs, but it is not 154 # needed for the tests anyway 155 print( 156 "Could not import cx_Freeze; 'build' and 'bdist' commands will not be available." 157 ) 158 print("See https://pypi.python.org/pypi/cx_Freeze") 159 executables = [] 160else: 161 print( 162 "Did not import cx_Freeze, because 'bdist_msi' commands are not used ({}).".format( 163 sys.argv 164 ) 165 ) 166 print("NOTE: this is a hack, because cx_Freeze seemed to sabotage wheel creation") 167 executables = [] 168 169 170# https://stackoverflow.com/a/43034479/19166 171PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__)) 172os.environ["TCL_LIBRARY"] = os.path.join(PYTHON_INSTALL_DIR, "tcl", "tcl8.6") 173os.environ["TK_LIBRARY"] = os.path.join(PYTHON_INSTALL_DIR, "tcl", "tk8.6") 174 175build_exe_options = { 176 "includes": install_requires, 177 "include_files": [ 178 # https://stackoverflow.com/a/43034479/19166 179 # os.path.join(PYTHON_INSTALL_DIR, "DLLs", "tk86t.dll"), 180 # os.path.join(PYTHON_INSTALL_DIR, "DLLs", "tcl86t.dll"), 181 # NOTE: this seems to fix a problem where Jinja2 package 182 # was copied as `<project>\build\exe.win32-3.6\lib\Jinja2` with a 183 # capital 'J'. 184 # Hotfix: we remove it from the dependencies (see above) and 185 # copy it manually from a vendored source. 186 # See 187 # https://github.com/anthony-tuininga/cx_Freeze/issues/418 188 ("vendor/jinja2", "lib/jinja2") 189 ], 190 "packages": [ 191 "asyncio", # https://stackoverflow.com/a/41881598/19166 192 "wsgidav.dir_browser", 193 # "wsgidav.dc.nt_dc", 194 ], 195 "excludes": ["tkinter"], 196 "constants": "BUILD_COPYRIGHT='(c) 2009-2020 Martin Wendt'", 197 # "init_script": "Console", 198 "include_msvcr": True, 199} 200 201bdist_msi_options = { 202 "upgrade_code": "{92F74137-38D1-48F6-9730-D5128C8B611E}", 203 "add_to_path": True, 204 # "all_users": True, 205} 206 207setup( 208 name="WsgiDAV", 209 version=version, 210 author="Martin Wendt, Ho Chun Wei", 211 author_email="wsgidav@wwwendt.de", 212 maintainer="Martin Wendt", 213 maintainer_email="wsgidav@wwwendt.de", 214 url="https://github.com/mar10/wsgidav/", 215 description="Generic and extendable WebDAV server based on WSGI", 216 long_description=readme, 217 long_description_content_type="text/markdown", 218 classifiers=[ 219 # "Development Status :: 4 - Beta", 220 "Development Status :: 5 - Production/Stable", 221 "Intended Audience :: Information Technology", 222 "Intended Audience :: Developers", 223 "Intended Audience :: System Administrators", 224 "License :: OSI Approved :: MIT License", 225 "Operating System :: OS Independent", 226 "Programming Language :: Python", 227 "Programming Language :: Python :: 2", 228 "Programming Language :: Python :: 2.7", 229 "Programming Language :: Python :: 3", 230 # "Programming Language :: Python :: 3.4", # EOL 2019-03-18 231 "Programming Language :: Python :: 3.5", 232 "Programming Language :: Python :: 3.6", 233 "Programming Language :: Python :: 3.7", 234 "Programming Language :: Python :: 3.8", 235 "Topic :: Internet :: WWW/HTTP", 236 "Topic :: Internet :: WWW/HTTP :: HTTP Servers", 237 "Topic :: Internet :: WWW/HTTP :: Dynamic Content", 238 "Topic :: Internet :: WWW/HTTP :: WSGI", 239 "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", 240 "Topic :: Internet :: WWW/HTTP :: WSGI :: Server", 241 "Topic :: Software Development :: Libraries :: Python Modules", 242 ], 243 keywords="web wsgi webdav application server", 244 license="MIT", 245 packages=find_packages(exclude=["tests"]), 246 package_data={ 247 # If any package contains *.txt files, include them: 248 # "": ["*.css", "*.html", "*.ico", "*.js"], 249 "wsgidav.dir_browser": ["htdocs/*.*"] 250 }, 251 install_requires=install_requires, 252 setup_requires=setup_requires, 253 tests_require=tests_require, 254 py_modules=[], 255 zip_safe=False, 256 extras_require={}, 257 cmdclass={"test": ToxCommand, "sphinx": SphinxCommand}, 258 entry_points={"console_scripts": ["wsgidav = wsgidav.server.server_cli:run"]}, 259 options={"build_exe": build_exe_options, "bdist_msi": bdist_msi_options}, 260 # Used by cx_Freeze: 261 executables=executables, 262) 263