forked from github.com/pypiserver
Use relative & imprv imports.
This commit is contained in:
parent
e579abdd4e
commit
a1e111fb1f
@ -21,7 +21,7 @@ def app(root=None,
|
|||||||
__import__("pypiserver._app")
|
__import__("pypiserver._app")
|
||||||
_app = sys.modules["pypiserver._app"]
|
_app = sys.modules["pypiserver._app"]
|
||||||
|
|
||||||
import bottle
|
from . import bottle
|
||||||
|
|
||||||
if root is None:
|
if root is None:
|
||||||
root = os.path.expanduser("~/packages")
|
root = os.path.expanduser("~/packages")
|
||||||
|
@ -12,20 +12,21 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
from StringIO import StringIO as BytesIO
|
from StringIO import StringIO as BytesIO
|
||||||
|
|
||||||
try: #PY3
|
try: # PY3
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
except ImportError: #PY2
|
except ImportError: # PY2
|
||||||
from urlparse import urljoin
|
from urlparse import urljoin
|
||||||
|
|
||||||
from bottle import static_file, redirect, request, response, HTTPError, Bottle, template
|
from .bottle import static_file, redirect, request, response, HTTPError, Bottle, template
|
||||||
from pypiserver import __version__
|
from . import __version__
|
||||||
from pypiserver.core import listdir, find_packages, store, get_prefixes, exists
|
from .core import listdir, find_packages, store, get_prefixes, exists
|
||||||
|
|
||||||
log = logging.getLogger('pypiserver.http')
|
log = logging.getLogger('pypiserver.http')
|
||||||
packages = None
|
packages = None
|
||||||
|
|
||||||
|
|
||||||
class Configuration(object):
|
class Configuration(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.fallback_url = "http://pypi.python.org/simple"
|
self.fallback_url = "http://pypi.python.org/simple"
|
||||||
self.redirect_to_fallback = True
|
self.redirect_to_fallback = True
|
||||||
@ -53,7 +54,8 @@ class auth(object):
|
|||||||
def protector(*args, **kwargs):
|
def protector(*args, **kwargs):
|
||||||
if self.action in config.authenticated:
|
if self.action in config.authenticated:
|
||||||
if not request.auth or request.auth[1] is None:
|
if not request.auth or request.auth[1] is None:
|
||||||
raise HTTPError(401, header={"WWW-Authenticate": 'Basic realm="pypi"'})
|
raise HTTPError(
|
||||||
|
401, header={"WWW-Authenticate": 'Basic realm="pypi"'})
|
||||||
if not validate_user(*request.auth):
|
if not validate_user(*request.auth):
|
||||||
raise HTTPError(403)
|
raise HTTPError(403)
|
||||||
return method(*args, **kwargs)
|
return method(*args, **kwargs)
|
||||||
@ -67,25 +69,25 @@ def configure(root=None,
|
|||||||
authenticated=None,
|
authenticated=None,
|
||||||
password_file=None,
|
password_file=None,
|
||||||
overwrite=False,
|
overwrite=False,
|
||||||
log_req_frmt=None,
|
log_req_frmt=None,
|
||||||
log_res_frmt=None,
|
log_res_frmt=None,
|
||||||
log_err_frmt=None,
|
log_err_frmt=None,
|
||||||
welcome_file=None,
|
welcome_file=None,
|
||||||
cache_control=None,
|
cache_control=None,
|
||||||
):
|
):
|
||||||
global packages
|
global packages
|
||||||
|
|
||||||
log.info("Starting(%s)", dict(root=root,
|
log.info("Starting(%s)", dict(root=root,
|
||||||
redirect_to_fallback=redirect_to_fallback,
|
redirect_to_fallback=redirect_to_fallback,
|
||||||
fallback_url=fallback_url,
|
fallback_url=fallback_url,
|
||||||
authenticated=authenticated,
|
authenticated=authenticated,
|
||||||
password_file=password_file,
|
password_file=password_file,
|
||||||
overwrite=overwrite,
|
overwrite=overwrite,
|
||||||
welcome_file=welcome_file,
|
welcome_file=welcome_file,
|
||||||
log_req_frmt=log_req_frmt,
|
log_req_frmt=log_req_frmt,
|
||||||
log_res_frmt=log_res_frmt,
|
log_res_frmt=log_res_frmt,
|
||||||
log_err_frmt=log_err_frmt,
|
log_err_frmt=log_err_frmt,
|
||||||
cache_control=cache_control))
|
cache_control=cache_control))
|
||||||
|
|
||||||
config.authenticated = authenticated or []
|
config.authenticated = authenticated or []
|
||||||
|
|
||||||
@ -115,40 +117,42 @@ def configure(root=None,
|
|||||||
config.fallback_url = fallback_url
|
config.fallback_url = fallback_url
|
||||||
config.cache_control = cache_control
|
config.cache_control = cache_control
|
||||||
if password_file:
|
if password_file:
|
||||||
from passlib.apache import HtpasswdFile
|
from passlib.apache import HtpasswdFile # @UnresolvedImport
|
||||||
config.htpasswdfile = HtpasswdFile(password_file)
|
config.htpasswdfile = HtpasswdFile(password_file)
|
||||||
config.overwrite = overwrite
|
config.overwrite = overwrite
|
||||||
|
|
||||||
## Read welcome-msg from external file,
|
# Read welcome-msg from external file,
|
||||||
# or failback to the embedded-msg (ie. in standalone mode).
|
# or failback to the embedded-msg (ie. in standalone mode).
|
||||||
#
|
#
|
||||||
try:
|
try:
|
||||||
if not welcome_file:
|
if not welcome_file:
|
||||||
welcome_file = pkg_resources.resource_filename(__name__, "welcome.html") # @UndefinedVariable
|
welcome_file = pkg_resources.resource_filename( # @UndefinedVariable
|
||||||
|
__name__, "welcome.html") # @UndefinedVariable
|
||||||
config.welcome_file = welcome_file
|
config.welcome_file = welcome_file
|
||||||
with io.open(config.welcome_file, 'r', encoding='utf-8') as fd:
|
with io.open(config.welcome_file, 'r', encoding='utf-8') as fd:
|
||||||
config.welcome_msg = fd.read()
|
config.welcome_msg = fd.read()
|
||||||
except Exception:
|
except Exception:
|
||||||
log.warning("Could not load welcome-file(%s)!", welcome_file, exc_info=1)
|
log.warning(
|
||||||
|
"Could not load welcome-file(%s)!", welcome_file, exc_info=1)
|
||||||
if not config.welcome_msg:
|
if not config.welcome_msg:
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
config.welcome_msg = dedent("""\
|
config.welcome_msg = dedent("""\
|
||||||
<html><head><title>Welcome to pypiserver!</title></head><body>
|
<html><head><title>Welcome to pypiserver!</title></head><body>
|
||||||
<h1>Welcome to pypiserver!</h1>
|
<h1>Welcome to pypiserver!</h1>
|
||||||
<p>This is a PyPI compatible package index serving {{NUMPKGS}} packages.</p>
|
<p>This is a PyPI compatible package index serving {{NUMPKGS}} packages.</p>
|
||||||
|
|
||||||
<p> To use this server with pip, run the the following command:
|
<p> To use this server with pip, run the the following command:
|
||||||
<blockquote><pre>
|
<blockquote><pre>
|
||||||
pip install -i {{URL}}simple/ PACKAGE [PACKAGE2...]
|
pip install -i {{URL}}simple/ PACKAGE [PACKAGE2...]
|
||||||
</pre></blockquote></p>
|
</pre></blockquote></p>
|
||||||
|
|
||||||
<p> To use this server with easy_install, run the the following command:
|
<p> To use this server with easy_install, run the the following command:
|
||||||
<blockquote><pre>
|
<blockquote><pre>
|
||||||
easy_install -i {{URL}}simple/ PACKAGE
|
easy_install -i {{URL}}simple/ PACKAGE
|
||||||
</pre></blockquote></p>
|
</pre></blockquote></p>
|
||||||
|
|
||||||
<p>The complete list of all packages can be found <a href="{{PACKAGES}}">here</a> or via the <a href="{{SIMPLE}}">simple</a> index.</p>
|
<p>The complete list of all packages can be found <a href="{{PACKAGES}}">here</a> or via the <a href="{{SIMPLE}}">simple</a> index.</p>
|
||||||
|
|
||||||
<p>This instance is running version {{VERSION}} of the <a href="http://pypi.python.org/pypi/pypiserver">pypiserver</a> software.</p>
|
<p>This instance is running version {{VERSION}} of the <a href="http://pypi.python.org/pypi/pypiserver">pypiserver</a> software.</p>
|
||||||
</body></html>\
|
</body></html>\
|
||||||
""")
|
""")
|
||||||
@ -167,12 +171,12 @@ def log_request():
|
|||||||
|
|
||||||
@app.hook('after_request')
|
@app.hook('after_request')
|
||||||
def log_response():
|
def log_response():
|
||||||
log.info(config.log_res_frmt, #vars(response)) ## DOES NOT WORK!
|
log.info(config.log_res_frmt, # vars(response)) ## DOES NOT WORK!
|
||||||
dict(
|
dict(
|
||||||
response=response,
|
response=response,
|
||||||
status=response.status, headers=response.headers,
|
status=response.status, headers=response.headers,
|
||||||
body=response.body, cookies=response.COOKIES,
|
body=response.body, cookies=response.COOKIES,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
@app.error
|
@app.error
|
||||||
@ -194,14 +198,15 @@ def root():
|
|||||||
except:
|
except:
|
||||||
numpkgs = 0
|
numpkgs = 0
|
||||||
|
|
||||||
msg = config.welcome_msg + '\n' ## Ensure template() does not consider `msg` as filename!
|
# Ensure template() does not consider `msg` as filename!
|
||||||
return template(msg,
|
msg = config.welcome_msg + '\n'
|
||||||
URL=request.url,
|
return template(msg,
|
||||||
VERSION=__version__,
|
URL=request.url,
|
||||||
NUMPKGS=numpkgs,
|
VERSION=__version__,
|
||||||
PACKAGES=urljoin(fp, "packages/"),
|
NUMPKGS=numpkgs,
|
||||||
SIMPLE=urljoin(fp, "simple/")
|
PACKAGES=urljoin(fp, "packages/"),
|
||||||
)
|
SIMPLE=urljoin(fp, "simple/")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.post('/')
|
@app.post('/')
|
||||||
@ -256,7 +261,7 @@ def update():
|
|||||||
|
|
||||||
if not config.overwrite and exists(packages.root, content.filename):
|
if not config.overwrite and exists(packages.root, content.filename):
|
||||||
log.warn("Cannot upload package(%s) since it already exists! \n" +
|
log.warn("Cannot upload package(%s) since it already exists! \n" +
|
||||||
" You may use `--overwrite` option when starting server to disable this check. ",
|
" You may use `--overwrite` option when starting server to disable this check. ",
|
||||||
content.filename)
|
content.filename)
|
||||||
raise HTTPError(409, output="file already exists")
|
raise HTTPError(409, output="file already exists")
|
||||||
|
|
||||||
@ -297,13 +302,15 @@ def simple(prefix=""):
|
|||||||
if not fp.endswith("/"):
|
if not fp.endswith("/"):
|
||||||
fp += "/"
|
fp += "/"
|
||||||
|
|
||||||
files = [x.relfn for x in sorted(find_packages(packages(), prefix=prefix), key=lambda x: (x.parsed_version, x.relfn))]
|
files = [x.relfn for x in sorted(find_packages(
|
||||||
|
packages(), prefix=prefix), key=lambda x: (x.parsed_version, x.relfn))]
|
||||||
if not files:
|
if not files:
|
||||||
if config.redirect_to_fallback:
|
if config.redirect_to_fallback:
|
||||||
return redirect("%s/%s/" % (config.fallback_url.rstrip("/"), prefix))
|
return redirect("%s/%s/" % (config.fallback_url.rstrip("/"), prefix))
|
||||||
return HTTPError(404)
|
return HTTPError(404)
|
||||||
|
|
||||||
links = [(os.path.basename(f), urljoin(fp, "../../packages/%s" % f.replace("\\", "/"))) for f in files]
|
links = [(os.path.basename(f), urljoin(fp, "../../packages/%s" %
|
||||||
|
f.replace("\\", "/"))) for f in files]
|
||||||
tmpl = """\
|
tmpl = """\
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
@ -352,9 +359,11 @@ def server_static(filename):
|
|||||||
for x in entries:
|
for x in entries:
|
||||||
f = x.relfn.replace("\\", "/")
|
f = x.relfn.replace("\\", "/")
|
||||||
if f == filename:
|
if f == filename:
|
||||||
response = static_file(filename, root=x.root, mimetype=mimetypes.guess_type(filename)[0])
|
response = static_file(
|
||||||
|
filename, root=x.root, mimetype=mimetypes.guess_type(filename)[0])
|
||||||
if config.cache_control:
|
if config.cache_control:
|
||||||
response.set_header("Cache-Control", "public, max-age=%s" % config.cache_control)
|
response.set_header(
|
||||||
|
"Cache-Control", "public, max-age=%s" % config.cache_control)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
return HTTPError(404)
|
return HTTPError(404)
|
||||||
|
@ -4,15 +4,14 @@ from subprocess import call
|
|||||||
|
|
||||||
from pypiserver import core
|
from pypiserver import core
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info >= (3, 0):
|
if sys.version_info >= (3, 0):
|
||||||
from xmlrpc.client import Server
|
from xmlrpc.client import Server
|
||||||
|
|
||||||
def make_pypi_client(url):
|
def make_pypi_client(url):
|
||||||
return Server(url)
|
return Server(url)
|
||||||
else:
|
else:
|
||||||
from xmlrpclib import Server, Transport
|
from xmlrpclib import Transport # @UnresolvedImport
|
||||||
import httplib
|
import httplib # @UnresolvedImport
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
class ProxiedTransport(Transport):
|
class ProxiedTransport(Transport):
|
||||||
@ -29,7 +28,8 @@ else:
|
|||||||
return _http_connection(self.proxy)
|
return _http_connection(self.proxy)
|
||||||
|
|
||||||
def send_request(self, connection, handler, request_body):
|
def send_request(self, connection, handler, request_body):
|
||||||
connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
|
connection.putrequest(
|
||||||
|
"POST", 'http://%s%s' % (self.realhost, handler))
|
||||||
|
|
||||||
def send_host(self, connection, host):
|
def send_host(self, connection, host):
|
||||||
connection.putheader('Host', self.realhost)
|
connection.putheader('Host', self.realhost)
|
||||||
@ -38,7 +38,8 @@ else:
|
|||||||
http_proxy_url = urllib.getproxies().get("http", "")
|
http_proxy_url = urllib.getproxies().get("http", "")
|
||||||
|
|
||||||
if http_proxy_url:
|
if http_proxy_url:
|
||||||
http_proxy_spec = urllib.splithost(urllib.splittype(http_proxy_url)[1])[0]
|
http_proxy_spec = urllib.splithost(
|
||||||
|
urllib.splittype(http_proxy_url)[1])[0]
|
||||||
transport = ProxiedTransport()
|
transport = ProxiedTransport()
|
||||||
transport.set_proxy(http_proxy_spec)
|
transport.set_proxy(http_proxy_spec)
|
||||||
else:
|
else:
|
||||||
@ -98,7 +99,8 @@ def find_updates(pkgset, stable_only=True):
|
|||||||
|
|
||||||
latest_pkgs = frozenset(filter_latest_pkgs(pkgset))
|
latest_pkgs = frozenset(filter_latest_pkgs(pkgset))
|
||||||
|
|
||||||
sys.stdout.write("checking %s packages for newer version\n" % len(latest_pkgs),)
|
sys.stdout.write(
|
||||||
|
"checking %s packages for newer version\n" % len(latest_pkgs),)
|
||||||
need_update = set()
|
need_update = set()
|
||||||
|
|
||||||
pypi = make_pypi_client("https://pypi.python.org/pypi/")
|
pypi = make_pypi_client("https://pypi.python.org/pypi/")
|
||||||
@ -125,7 +127,8 @@ def find_updates(pkgset, stable_only=True):
|
|||||||
write("\n\n")
|
write("\n\n")
|
||||||
|
|
||||||
if no_releases:
|
if no_releases:
|
||||||
sys.stdout.write("no releases found on pypi for %s\n\n" % (", ".join(sorted(no_releases)),))
|
sys.stdout.write("no releases found on pypi for %s\n\n" %
|
||||||
|
(", ".join(sorted(no_releases)),))
|
||||||
|
|
||||||
return need_update
|
return need_update
|
||||||
|
|
||||||
@ -133,7 +136,8 @@ def find_updates(pkgset, stable_only=True):
|
|||||||
def update(pkgset, destdir=None, dry_run=False, stable_only=True):
|
def update(pkgset, destdir=None, dry_run=False, stable_only=True):
|
||||||
need_update = find_updates(pkgset, stable_only=stable_only)
|
need_update = find_updates(pkgset, stable_only=stable_only)
|
||||||
for pkg in sorted(need_update, key=lambda x: x.pkgname):
|
for pkg in sorted(need_update, key=lambda x: x.pkgname):
|
||||||
sys.stdout.write("# update %s from %s to %s\n" % (pkg.pkgname, pkg.replaces.version, pkg.version))
|
sys.stdout.write("# update %s from %s to %s\n" %
|
||||||
|
(pkg.pkgname, pkg.replaces.version, pkg.version))
|
||||||
|
|
||||||
cmd = ["pip", "-q", "install", "--no-deps", "-i", "https://pypi.python.org/simple",
|
cmd = ["pip", "-q", "install", "--no-deps", "-i", "https://pypi.python.org/simple",
|
||||||
"-d", destdir or os.path.dirname(pkg.replaces.fn),
|
"-d", destdir or os.path.dirname(pkg.replaces.fn),
|
||||||
|
Loading…
Reference in New Issue
Block a user