a7777e13 by root

Initial commit

	new file:   thiccMud/README.md
	new file:   thiccMud/__init__.py
	new file:   thiccMud/commands/README.md
	new file:   thiccMud/commands/__init__.py
	new file:   thiccMud/commands/command.py
	new file:   thiccMud/commands/default_cmdsets.py
	new file:   thiccMud/server/README.md
	new file:   thiccMud/server/__init__.py
	new file:   thiccMud/server/conf/__init__.py
	new file:   thiccMud/server/conf/at_initial_setup.py
	new file:   thiccMud/server/conf/at_search.py
	new file:   thiccMud/server/conf/at_server_startstop.py
	new file:   thiccMud/server/conf/cmdparser.py
	new file:   thiccMud/server/conf/connection_screens.py
	new file:   thiccMud/server/conf/inlinefuncs.py
	new file:   thiccMud/server/conf/inputfuncs.py
	new file:   thiccMud/server/conf/lockfuncs.py
	new file:   thiccMud/server/conf/mssp.py
	new file:   thiccMud/server/conf/portal_services_plugins.py
	new file:   thiccMud/server/conf/server_services_plugins.py
	new file:   thiccMud/server/conf/serversession.py
	new file:   thiccMud/server/conf/web_plugins.py
	new file:   thiccMud/typeclasses/README.md
	new file:   thiccMud/typeclasses/__init__.py
	new file:   thiccMud/typeclasses/channels.py
	new file:   thiccMud/typeclasses/characters.py
	new file:   thiccMud/typeclasses/exits.py
	new file:   thiccMud/typeclasses/objects.py
	new file:   thiccMud/typeclasses/players.py
	new file:   thiccMud/typeclasses/rooms.py
	new file:   thiccMud/typeclasses/scripts.py
	new file:   thiccMud/web/__init__.py
	new file:   thiccMud/web/static_overrides/README.md
	new file:   thiccMud/web/static_overrides/webclient/css/README.md
	new file:   thiccMud/web/static_overrides/webclient/js/README.md
	new file:   thiccMud/web/static_overrides/website/css/README.md
	new file:   thiccMud/web/static_overrides/website/images/README.md
	new file:   thiccMud/web/template_overrides/README.md
	new file:   thiccMud/web/template_overrides/webclient/README.md
	new file:   thiccMud/web/template_overrides/website/README.md
	new file:   thiccMud/web/template_overrides/website/flatpages/README.md
	new file:   thiccMud/web/template_overrides/website/registration/README.md
	new file:   thiccMud/web/urls.py
	new file:   thiccMud/world/README.md
	new file:   thiccMud/world/__init__.py
	new file:   thiccMud/world/batch_cmds.ev
	new file:   thiccMud/world/prototypes.py
0 parents
Showing 867 changed files with 1957 additions and 0 deletions
evennia @ e82799fb
1 Subproject commit e82799fb13ad1424081559ab5d65d52ab8046e42
1 # This file must be used with "source bin/activate" *from bash*
2 # you cannot run it directly
3
4 deactivate () {
5 unset -f pydoc >/dev/null 2>&1
6
7 # reset old environment variables
8 # ! [ -z ${VAR+_} ] returns true if VAR is declared at all
9 if ! [ -z "${_OLD_VIRTUAL_PATH+_}" ] ; then
10 PATH="$_OLD_VIRTUAL_PATH"
11 export PATH
12 unset _OLD_VIRTUAL_PATH
13 fi
14 if ! [ -z "${_OLD_VIRTUAL_PYTHONHOME+_}" ] ; then
15 PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
16 export PYTHONHOME
17 unset _OLD_VIRTUAL_PYTHONHOME
18 fi
19
20 # This should detect bash and zsh, which have a hash command that must
21 # be called to get it to forget past commands. Without forgetting
22 # past commands the $PATH changes we made may not be respected
23 if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then
24 hash -r 2>/dev/null
25 fi
26
27 if ! [ -z "${_OLD_VIRTUAL_PS1+_}" ] ; then
28 PS1="$_OLD_VIRTUAL_PS1"
29 export PS1
30 unset _OLD_VIRTUAL_PS1
31 fi
32
33 unset VIRTUAL_ENV
34 if [ ! "${1-}" = "nondestructive" ] ; then
35 # Self destruct!
36 unset -f deactivate
37 fi
38 }
39
40 # unset irrelevant variables
41 deactivate nondestructive
42
43 VIRTUAL_ENV="/opt/buntasThiccMud/pyenv"
44 export VIRTUAL_ENV
45
46 _OLD_VIRTUAL_PATH="$PATH"
47 PATH="$VIRTUAL_ENV/bin:$PATH"
48 export PATH
49
50 # unset PYTHONHOME if set
51 if ! [ -z "${PYTHONHOME+_}" ] ; then
52 _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
53 unset PYTHONHOME
54 fi
55
56 if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then
57 _OLD_VIRTUAL_PS1="$PS1"
58 if [ "x" != x ] ; then
59 PS1="$PS1"
60 else
61 PS1="(`basename \"$VIRTUAL_ENV\"`) $PS1"
62 fi
63 export PS1
64 fi
65
66 # Make sure to unalias pydoc if it's already there
67 alias pydoc 2>/dev/null >/dev/null && unalias pydoc
68
69 pydoc () {
70 python -m pydoc "$@"
71 }
72
73 # This should detect bash and zsh, which have a hash command that must
74 # be called to get it to forget past commands. Without forgetting
75 # past commands the $PATH changes we made may not be respected
76 if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then
77 hash -r 2>/dev/null
78 fi
1 # This file must be used with "source bin/activate.csh" *from csh*.
2 # You cannot run it directly.
3 # Created by Davide Di Blasi <davidedb@gmail.com>.
4
5 alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc'
6
7 # Unset irrelevant variables.
8 deactivate nondestructive
9
10 setenv VIRTUAL_ENV "/opt/buntasThiccMud/pyenv"
11
12 set _OLD_VIRTUAL_PATH="$PATH"
13 setenv PATH "$VIRTUAL_ENV/bin:$PATH"
14
15
16
17 if ("" != "") then
18 set env_name = ""
19 else
20 set env_name = `basename "$VIRTUAL_ENV"`
21 endif
22
23 # Could be in a non-interactive environment,
24 # in which case, $prompt is undefined and we wouldn't
25 # care about the prompt anyway.
26 if ( $?prompt ) then
27 set _OLD_VIRTUAL_PROMPT="$prompt"
28 set prompt = "[$env_name] $prompt"
29 endif
30
31 unset env_name
32
33 alias pydoc python -m pydoc
34
35 rehash
36
1 # This file must be used using `. bin/activate.fish` *within a running fish ( http://fishshell.com ) session*.
2 # Do not run it directly.
3
4 function deactivate -d 'Exit virtualenv mode and return to the normal environment.'
5 # reset old environment variables
6 if test -n "$_OLD_VIRTUAL_PATH"
7 set -gx PATH $_OLD_VIRTUAL_PATH
8 set -e _OLD_VIRTUAL_PATH
9 end
10
11 if test -n "$_OLD_VIRTUAL_PYTHONHOME"
12 set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
13 set -e _OLD_VIRTUAL_PYTHONHOME
14 end
15
16 if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
17 # Set an empty local `$fish_function_path` to allow the removal of `fish_prompt` using `functions -e`.
18 set -l fish_function_path
19
20 # Erase virtualenv's `fish_prompt` and restore the original.
21 functions -e fish_prompt
22 functions -c _old_fish_prompt fish_prompt
23 functions -e _old_fish_prompt
24 set -e _OLD_FISH_PROMPT_OVERRIDE
25 end
26
27 set -e VIRTUAL_ENV
28
29 if test "$argv[1]" != 'nondestructive'
30 # Self-destruct!
31 functions -e pydoc
32 functions -e deactivate
33 end
34 end
35
36 # Unset irrelevant variables.
37 deactivate nondestructive
38
39 set -gx VIRTUAL_ENV "/opt/buntasThiccMud/pyenv"
40
41 set -gx _OLD_VIRTUAL_PATH $PATH
42 set -gx PATH "$VIRTUAL_ENV/bin" $PATH
43
44 # Unset `$PYTHONHOME` if set.
45 if set -q PYTHONHOME
46 set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
47 set -e PYTHONHOME
48 end
49
50 function pydoc
51 python -m pydoc $argv
52 end
53
54 if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
55 # Copy the current `fish_prompt` function as `_old_fish_prompt`.
56 functions -c fish_prompt _old_fish_prompt
57
58 function fish_prompt
59 # Save the current $status, for fish_prompts that display it.
60 set -l old_status $status
61
62 # Prompt override provided?
63 # If not, just prepend the environment name.
64 if test -n ""
65 printf '%s%s' "" (set_color normal)
66 else
67 printf '%s(%s%s%s) ' (set_color normal) (set_color -o white) (basename "$VIRTUAL_ENV") (set_color normal)
68 end
69
70 # Restore the original $status
71 echo "exit $old_status" | source
72 _old_fish_prompt
73 end
74
75 set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
76 end
1 """By using execfile(this_file, dict(__file__=this_file)) you will
2 activate this virtualenv environment.
3
4 This can be used when you must use an existing Python interpreter, not
5 the virtualenv bin/python
6 """
7
8 try:
9 __file__
10 except NameError:
11 raise AssertionError(
12 "You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))")
13 import sys
14 import os
15
16 old_os_path = os.environ.get('PATH', '')
17 os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + os.pathsep + old_os_path
18 base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
19 if sys.platform == 'win32':
20 site_packages = os.path.join(base, 'Lib', 'site-packages')
21 else:
22 site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
23 prev_sys_path = list(sys.path)
24 import site
25 site.addsitedir(site_packages)
26 sys.real_prefix = sys.prefix
27 sys.prefix = base
28 # Move the added items to the front of the path:
29 new_sys_path = []
30 for item in list(sys.path):
31 if item not in prev_sys_path:
32 new_sys_path.append(item)
33 sys.path.remove(item)
34 sys.path[:0] = new_sys_path
1 #!/opt/buntasThiccMud/pyenv/bin/python2
2
3 # -*- coding: utf-8 -*-
4 import re
5 import sys
6
7 from setuptools.command.easy_install import main
8
9 if __name__ == '__main__':
10 sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
11 sys.exit(main())
1 #!/opt/buntasThiccMud/pyenv/bin/python2
2
3 # -*- coding: utf-8 -*-
4 import re
5 import sys
6
7 from setuptools.command.easy_install import main
8
9 if __name__ == '__main__':
10 sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
11 sys.exit(main())
1 #!/opt/buntasThiccMud/pyenv/bin/python2
2
3 # -*- coding: utf-8 -*-
4 import re
5 import sys
6
7 from pip import main
8
9 if __name__ == '__main__':
10 sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
11 sys.exit(main())
1 #!/opt/buntasThiccMud/pyenv/bin/python2
2
3 # -*- coding: utf-8 -*-
4 import re
5 import sys
6
7 from pip import main
8
9 if __name__ == '__main__':
10 sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
11 sys.exit(main())
1 #!/opt/buntasThiccMud/pyenv/bin/python2
2
3 # -*- coding: utf-8 -*-
4 import re
5 import sys
6
7 from pip import main
8
9 if __name__ == '__main__':
10 sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
11 sys.exit(main())
1 python2
...\ No newline at end of file ...\ No newline at end of file
1 #!/opt/buntasThiccMud/pyenv/bin/python
2
3 import sys
4 import getopt
5 import sysconfig
6
7 valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags',
8 'ldflags', 'help']
9
10 if sys.version_info >= (3, 2):
11 valid_opts.insert(-1, 'extension-suffix')
12 valid_opts.append('abiflags')
13 if sys.version_info >= (3, 3):
14 valid_opts.append('configdir')
15
16
17 def exit_with_usage(code=1):
18 sys.stderr.write("Usage: {0} [{1}]\n".format(
19 sys.argv[0], '|'.join('--'+opt for opt in valid_opts)))
20 sys.exit(code)
21
22 try:
23 opts, args = getopt.getopt(sys.argv[1:], '', valid_opts)
24 except getopt.error:
25 exit_with_usage()
26
27 if not opts:
28 exit_with_usage()
29
30 pyver = sysconfig.get_config_var('VERSION')
31 getvar = sysconfig.get_config_var
32
33 opt_flags = [flag for (flag, val) in opts]
34
35 if '--help' in opt_flags:
36 exit_with_usage(code=0)
37
38 for opt in opt_flags:
39 if opt == '--prefix':
40 print(sysconfig.get_config_var('prefix'))
41
42 elif opt == '--exec-prefix':
43 print(sysconfig.get_config_var('exec_prefix'))
44
45 elif opt in ('--includes', '--cflags'):
46 flags = ['-I' + sysconfig.get_path('include'),
47 '-I' + sysconfig.get_path('platinclude')]
48 if opt == '--cflags':
49 flags.extend(getvar('CFLAGS').split())
50 print(' '.join(flags))
51
52 elif opt in ('--libs', '--ldflags'):
53 abiflags = getattr(sys, 'abiflags', '')
54 libs = ['-lpython' + pyver + abiflags]
55 libs += getvar('LIBS').split()
56 libs += getvar('SYSLIBS').split()
57 # add the prefix/lib/pythonX.Y/config dir, but only if there is no
58 # shared library in prefix/lib/.
59 if opt == '--ldflags':
60 if not getvar('Py_ENABLE_SHARED'):
61 libs.insert(0, '-L' + getvar('LIBPL'))
62 if not getvar('PYTHONFRAMEWORK'):
63 libs.extend(getvar('LINKFORSHARED').split())
64 print(' '.join(libs))
65
66 elif opt == '--extension-suffix':
67 ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')
68 if ext_suffix is None:
69 ext_suffix = sysconfig.get_config_var('SO')
70 print(ext_suffix)
71
72 elif opt == '--abiflags':
73 if not getattr(sys, 'abiflags', None):
74 exit_with_usage()
75 print(sys.abiflags)
76
77 elif opt == '--configdir':
78 print(sysconfig.get_config_var('LIBPL'))
No preview for this file type
1 python2
...\ No newline at end of file ...\ No newline at end of file
1 #!/opt/buntasThiccMud/pyenv/bin/python2
2
3 # -*- coding: utf-8 -*-
4 import re
5 import sys
6
7 from wheel.tool import main
8
9 if __name__ == '__main__':
10 sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
11 sys.exit(main())
1 /usr/include/python2.7
...\ No newline at end of file ...\ No newline at end of file
1 /usr/lib/python2.7/UserDict.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 /usr/lib/python2.7/_abcoll.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 /usr/lib/python2.7/_weakrefset.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 /usr/lib/python2.7/abc.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 /usr/lib/python2.7/codecs.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 /usr/lib/python2.7/copy_reg.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 import os
2 import sys
3 import warnings
4 import imp
5 import opcode # opcode is not a virtualenv module, so we can use it to find the stdlib
6 # Important! To work on pypy, this must be a module that resides in the
7 # lib-python/modified-x.y.z directory
8
9 dirname = os.path.dirname
10
11 distutils_path = os.path.join(os.path.dirname(opcode.__file__), 'distutils')
12 if os.path.normpath(distutils_path) == os.path.dirname(os.path.normpath(__file__)):
13 warnings.warn(
14 "The virtualenv distutils package at %s appears to be in the same location as the system distutils?")
15 else:
16 __path__.insert(0, distutils_path)
17 real_distutils = imp.load_module("_virtualenv_distutils", None, distutils_path, ('', '', imp.PKG_DIRECTORY))
18 # Copy the relevant attributes
19 try:
20 __revision__ = real_distutils.__revision__
21 except AttributeError:
22 pass
23 __version__ = real_distutils.__version__
24
25 from distutils import dist, sysconfig
26
27 try:
28 basestring
29 except NameError:
30 basestring = str
31
32 ## patch build_ext (distutils doesn't know how to get the libs directory
33 ## path on windows - it hardcodes the paths around the patched sys.prefix)
34
35 if sys.platform == 'win32':
36 from distutils.command.build_ext import build_ext as old_build_ext
37 class build_ext(old_build_ext):
38 def finalize_options (self):
39 if self.library_dirs is None:
40 self.library_dirs = []
41 elif isinstance(self.library_dirs, basestring):
42 self.library_dirs = self.library_dirs.split(os.pathsep)
43
44 self.library_dirs.insert(0, os.path.join(sys.real_prefix, "Libs"))
45 old_build_ext.finalize_options(self)
46
47 from distutils.command import build_ext as build_ext_module
48 build_ext_module.build_ext = build_ext
49
50 ## distutils.dist patches:
51
52 old_find_config_files = dist.Distribution.find_config_files
53 def find_config_files(self):
54 found = old_find_config_files(self)
55 system_distutils = os.path.join(distutils_path, 'distutils.cfg')
56 #if os.path.exists(system_distutils):
57 # found.insert(0, system_distutils)
58 # What to call the per-user config file
59 if os.name == 'posix':
60 user_filename = ".pydistutils.cfg"
61 else:
62 user_filename = "pydistutils.cfg"
63 user_filename = os.path.join(sys.prefix, user_filename)
64 if os.path.isfile(user_filename):
65 for item in list(found):
66 if item.endswith('pydistutils.cfg'):
67 found.remove(item)
68 found.append(user_filename)
69 return found
70 dist.Distribution.find_config_files = find_config_files
71
72 ## distutils.sysconfig patches:
73
74 old_get_python_inc = sysconfig.get_python_inc
75 def sysconfig_get_python_inc(plat_specific=0, prefix=None):
76 if prefix is None:
77 prefix = sys.real_prefix
78 return old_get_python_inc(plat_specific, prefix)
79 sysconfig_get_python_inc.__doc__ = old_get_python_inc.__doc__
80 sysconfig.get_python_inc = sysconfig_get_python_inc
81
82 old_get_python_lib = sysconfig.get_python_lib
83 def sysconfig_get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
84 if standard_lib and prefix is None:
85 prefix = sys.real_prefix
86 return old_get_python_lib(plat_specific, standard_lib, prefix)
87 sysconfig_get_python_lib.__doc__ = old_get_python_lib.__doc__
88 sysconfig.get_python_lib = sysconfig_get_python_lib
89
90 old_get_config_vars = sysconfig.get_config_vars
91 def sysconfig_get_config_vars(*args):
92 real_vars = old_get_config_vars(*args)
93 if sys.platform == 'win32':
94 lib_dir = os.path.join(sys.real_prefix, "libs")
95 if isinstance(real_vars, dict) and 'LIBDIR' not in real_vars:
96 real_vars['LIBDIR'] = lib_dir # asked for all
97 elif isinstance(real_vars, list) and 'LIBDIR' in args:
98 real_vars = real_vars + [lib_dir] # asked for list
99 return real_vars
100 sysconfig_get_config_vars.__doc__ = old_get_config_vars.__doc__
101 sysconfig.get_config_vars = sysconfig_get_config_vars
No preview for this file type
1 # This is a config file local to this virtualenv installation
2 # You may include options that will be used by all distutils commands,
3 # and by easy_install. For instance:
4 #
5 # [easy_install]
6 # find_links = http://mylocalsite
1 /usr/lib/python2.7/encodings
...\ No newline at end of file ...\ No newline at end of file
1 /usr/lib/python2.7/fnmatch.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 /usr/lib/python2.7/genericpath.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 /usr/lib/python2.7/lib-dynload
...\ No newline at end of file ...\ No newline at end of file
1 /usr/lib/python2.7/linecache.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 /usr/lib/python2.7/locale.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 /usr/lib/python2.7/ntpath.py
...\ No newline at end of file ...\ No newline at end of file
1 /usr
...\ No newline at end of file ...\ No newline at end of file
1 /usr/lib/python2.7/os.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 /usr/lib/python2.7/posixpath.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 /usr/lib/python2.7/re.py
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
1 """Run the EasyInstall command"""
2
3 if __name__ == '__main__':
4 from setuptools.command.easy_install import main
5 main()
1 pip
2 ===
3
4 The `PyPA recommended
5 <https://packaging.python.org/en/latest/current/>`_
6 tool for installing Python packages.
7
8 * `Installation <https://pip.pypa.io/en/stable/installing.html>`_
9 * `Documentation <https://pip.pypa.io/>`_
10 * `Changelog <https://pip.pypa.io/en/stable/news.html>`_
11 * `Github Page <https://github.com/pypa/pip>`_
12 * `Issue Tracking <https://github.com/pypa/pip/issues>`_
13 * `User mailing list <http://groups.google.com/group/python-virtualenv>`_
14 * `Dev mailing list <http://groups.google.com/group/pypa-dev>`_
15 * User IRC: #pypa on Freenode.
16 * Dev IRC: #pypa-dev on Freenode.
17
18
19 .. image:: https://img.shields.io/pypi/v/pip.svg
20 :target: https://pypi.python.org/pypi/pip
21
22 .. image:: https://img.shields.io/travis/pypa/pip/master.svg
23 :target: http://travis-ci.org/pypa/pip
24
25 .. image:: https://img.shields.io/appveyor/ci/pypa/pip.svg
26 :target: https://ci.appveyor.com/project/pypa/pip/history
27
28 .. image:: https://readthedocs.org/projects/pip/badge/?version=stable
29 :target: https://pip.pypa.io/en/stable
30
31 Code of Conduct
32 ---------------
33
34 Everyone interacting in the pip project's codebases, issue trackers, chat
35 rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_.
36
37 .. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/
38
39
1 Metadata-Version: 2.0
2 Name: pip
3 Version: 9.0.1
4 Summary: The PyPA recommended tool for installing Python packages.
5 Home-page: https://pip.pypa.io/
6 Author: The pip developers
7 Author-email: python-virtualenv@groups.google.com
8 License: MIT
9 Keywords: easy_install distutils setuptools egg virtualenv
10 Platform: UNKNOWN
11 Classifier: Development Status :: 5 - Production/Stable
12 Classifier: Intended Audience :: Developers
13 Classifier: License :: OSI Approved :: MIT License
14 Classifier: Topic :: Software Development :: Build Tools
15 Classifier: Programming Language :: Python :: 2
16 Classifier: Programming Language :: Python :: 2.6
17 Classifier: Programming Language :: Python :: 2.7
18 Classifier: Programming Language :: Python :: 3
19 Classifier: Programming Language :: Python :: 3.3
20 Classifier: Programming Language :: Python :: 3.4
21 Classifier: Programming Language :: Python :: 3.5
22 Classifier: Programming Language :: Python :: Implementation :: PyPy
23 Requires-Python: >=2.6,!=3.0.*,!=3.1.*,!=3.2.*
24 Provides-Extra: testing
25 Requires-Dist: mock; extra == 'testing'
26 Requires-Dist: pretend; extra == 'testing'
27 Requires-Dist: pytest; extra == 'testing'
28 Requires-Dist: scripttest (>=1.3); extra == 'testing'
29 Requires-Dist: virtualenv (>=1.10); extra == 'testing'
30
31 pip
32 ===
33
34 The `PyPA recommended
35 <https://packaging.python.org/en/latest/current/>`_
36 tool for installing Python packages.
37
38 * `Installation <https://pip.pypa.io/en/stable/installing.html>`_
39 * `Documentation <https://pip.pypa.io/>`_
40 * `Changelog <https://pip.pypa.io/en/stable/news.html>`_
41 * `Github Page <https://github.com/pypa/pip>`_
42 * `Issue Tracking <https://github.com/pypa/pip/issues>`_
43 * `User mailing list <http://groups.google.com/group/python-virtualenv>`_
44 * `Dev mailing list <http://groups.google.com/group/pypa-dev>`_
45 * User IRC: #pypa on Freenode.
46 * Dev IRC: #pypa-dev on Freenode.
47
48
49 .. image:: https://img.shields.io/pypi/v/pip.svg
50 :target: https://pypi.python.org/pypi/pip
51
52 .. image:: https://img.shields.io/travis/pypa/pip/master.svg
53 :target: http://travis-ci.org/pypa/pip
54
55 .. image:: https://img.shields.io/appveyor/ci/pypa/pip.svg
56 :target: https://ci.appveyor.com/project/pypa/pip/history
57
58 .. image:: https://readthedocs.org/projects/pip/badge/?version=stable
59 :target: https://pip.pypa.io/en/stable
60
61 Code of Conduct
62 ---------------
63
64 Everyone interacting in the pip project's codebases, issue trackers, chat
65 rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_.
66
67 .. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/
68
69
1 Wheel-Version: 1.0
2 Generator: bdist_wheel (0.29.0)
3 Root-Is-Purelib: true
4 Tag: py2-none-any
5 Tag: py3-none-any
6
1 [console_scripts]
2 pip = pip:main
3 pip3 = pip:main
4 pip3.5 = pip:main
5
1 {"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Topic :: Software Development :: Build Tools", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: Implementation :: PyPy"], "extensions": {"python.commands": {"wrap_console": {"pip": "pip:main", "pip3": "pip:main", "pip3.5": "pip:main"}}, "python.details": {"contacts": [{"email": "python-virtualenv@groups.google.com", "name": "The pip developers", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://pip.pypa.io/"}}, "python.exports": {"console_scripts": {"pip": "pip:main", "pip3": "pip:main", "pip3.5": "pip:main"}}}, "extras": ["testing"], "generator": "bdist_wheel (0.29.0)", "keywords": ["easy_install", "distutils", "setuptools", "egg", "virtualenv"], "license": "MIT", "metadata_version": "2.0", "name": "pip", "requires_python": ">=2.6,!=3.0.*,!=3.1.*,!=3.2.*", "run_requires": [{"extra": "testing", "requires": ["mock", "pretend", "pytest", "scripttest (>=1.3)", "virtualenv (>=1.10)"]}], "summary": "The PyPA recommended tool for installing Python packages.", "test_requires": [{"requires": ["mock", "pretend", "pytest", "scripttest (>=1.3)", "virtualenv (>=1.10)"]}], "version": "9.0.1"}
...\ No newline at end of file ...\ No newline at end of file
1 from __future__ import absolute_import
2
3 import os
4 import sys
5
6 # If we are running from a wheel, add the wheel to sys.path
7 # This allows the usage python pip-*.whl/pip install pip-*.whl
8 if __package__ == '':
9 # __file__ is pip-*.whl/pip/__main__.py
10 # first dirname call strips of '/__main__.py', second strips off '/pip'
11 # Resulting path is the name of the wheel itself
12 # Add that to sys.path so we can import pip
13 path = os.path.dirname(os.path.dirname(__file__))
14 sys.path.insert(0, path)
15
16 import pip # noqa
17
18 if __name__ == '__main__':
19 sys.exit(pip.main())
1 """
2 pip._vendor is for vendoring dependencies of pip to prevent needing pip to
3 depend on something external.
4
5 Files inside of pip._vendor should be considered immutable and should only be
6 updated to versions from upstream.
7 """
8 from __future__ import absolute_import
9
10 import glob
11 import os.path
12 import sys
13
14 # Downstream redistributors which have debundled our dependencies should also
15 # patch this value to be true. This will trigger the additional patching
16 # to cause things like "six" to be available as pip.
17 DEBUNDLED = False
18
19 # By default, look in this directory for a bunch of .whl files which we will
20 # add to the beginning of sys.path before attempting to import anything. This
21 # is done to support downstream re-distributors like Debian and Fedora who
22 # wish to create their own Wheels for our dependencies to aid in debundling.
23 WHEEL_DIR = os.path.abspath(os.path.dirname(__file__))
24
25
26 # Define a small helper function to alias our vendored modules to the real ones
27 # if the vendored ones do not exist. This idea of this was taken from
28 # https://github.com/kennethreitz/requests/pull/2567.
29 def vendored(modulename):
30 vendored_name = "{0}.{1}".format(__name__, modulename)
31
32 try:
33 __import__(vendored_name, globals(), locals(), level=0)
34 except ImportError:
35 try:
36 __import__(modulename, globals(), locals(), level=0)
37 except ImportError:
38 # We can just silently allow import failures to pass here. If we
39 # got to this point it means that ``import pip._vendor.whatever``
40 # failed and so did ``import whatever``. Since we're importing this
41 # upfront in an attempt to alias imports, not erroring here will
42 # just mean we get a regular import error whenever pip *actually*
43 # tries to import one of these modules to use it, which actually
44 # gives us a better error message than we would have otherwise
45 # gotten.
46 pass
47 else:
48 sys.modules[vendored_name] = sys.modules[modulename]
49 base, head = vendored_name.rsplit(".", 1)
50 setattr(sys.modules[base], head, sys.modules[modulename])
51
52
53 # If we're operating in a debundled setup, then we want to go ahead and trigger
54 # the aliasing of our vendored libraries as well as looking for wheels to add
55 # to our sys.path. This will cause all of this code to be a no-op typically
56 # however downstream redistributors can enable it in a consistent way across
57 # all platforms.
58 if DEBUNDLED:
59 # Actually look inside of WHEEL_DIR to find .whl files and add them to the
60 # front of our sys.path.
61 sys.path[:] = glob.glob(os.path.join(WHEEL_DIR, "*.whl")) + sys.path
62
63 # Actually alias all of our vendored dependencies.
64 vendored("cachecontrol")
65 vendored("colorama")
66 vendored("distlib")
67 vendored("distro")
68 vendored("html5lib")
69 vendored("lockfile")
70 vendored("six")
71 vendored("six.moves")
72 vendored("six.moves.urllib")
73 vendored("packaging")
74 vendored("packaging.version")
75 vendored("packaging.specifiers")
76 vendored("pkg_resources")
77 vendored("progress")
78 vendored("retrying")
79 vendored("requests")
80 vendored("requests.packages")
81 vendored("requests.packages.urllib3")
82 vendored("requests.packages.urllib3._collections")
83 vendored("requests.packages.urllib3.connection")
84 vendored("requests.packages.urllib3.connectionpool")
85 vendored("requests.packages.urllib3.contrib")
86 vendored("requests.packages.urllib3.contrib.ntlmpool")
87 vendored("requests.packages.urllib3.contrib.pyopenssl")
88 vendored("requests.packages.urllib3.exceptions")
89 vendored("requests.packages.urllib3.fields")
90 vendored("requests.packages.urllib3.filepost")
91 vendored("requests.packages.urllib3.packages")
92 vendored("requests.packages.urllib3.packages.ordered_dict")
93 vendored("requests.packages.urllib3.packages.six")
94 vendored("requests.packages.urllib3.packages.ssl_match_hostname")
95 vendored("requests.packages.urllib3.packages.ssl_match_hostname."
96 "_implementation")
97 vendored("requests.packages.urllib3.poolmanager")
98 vendored("requests.packages.urllib3.request")
99 vendored("requests.packages.urllib3.response")
100 vendored("requests.packages.urllib3.util")
101 vendored("requests.packages.urllib3.util.connection")
102 vendored("requests.packages.urllib3.util.request")
103 vendored("requests.packages.urllib3.util.response")
104 vendored("requests.packages.urllib3.util.retry")
105 vendored("requests.packages.urllib3.util.ssl_")
106 vendored("requests.packages.urllib3.util.timeout")
107 vendored("requests.packages.urllib3.util.url")
1 """CacheControl import Interface.
2
3 Make it easy to import from cachecontrol without long namespaces.
4 """
5 __author__ = 'Eric Larson'
6 __email__ = 'eric@ionrock.org'
7 __version__ = '0.11.7'
8
9 from .wrapper import CacheControl
10 from .adapter import CacheControlAdapter
11 from .controller import CacheController
1 import logging
2
3 from pip._vendor import requests
4
5 from pip._vendor.cachecontrol.adapter import CacheControlAdapter
6 from pip._vendor.cachecontrol.cache import DictCache
7 from pip._vendor.cachecontrol.controller import logger
8
9 from argparse import ArgumentParser
10
11
12 def setup_logging():
13 logger.setLevel(logging.DEBUG)
14 handler = logging.StreamHandler()
15 logger.addHandler(handler)
16
17
18 def get_session():
19 adapter = CacheControlAdapter(
20 DictCache(),
21 cache_etags=True,
22 serializer=None,
23 heuristic=None,
24 )
25 sess = requests.Session()
26 sess.mount('http://', adapter)
27 sess.mount('https://', adapter)
28
29 sess.cache_controller = adapter.controller
30 return sess
31
32
33 def get_args():
34 parser = ArgumentParser()
35 parser.add_argument('url', help='The URL to try and cache')
36 return parser.parse_args()
37
38
39 def main(args=None):
40 args = get_args()
41 sess = get_session()
42
43 # Make a request to get a response
44 resp = sess.get(args.url)
45
46 # Turn on logging
47 setup_logging()
48
49 # try setting the cache
50 sess.cache_controller.cache_response(resp.request, resp.raw)
51
52 # Now try to get it
53 if sess.cache_controller.cached_request(resp.request):
54 print('Cached!')
55 else:
56 print('Not cached :(')
57
58
59 if __name__ == '__main__':
60 main()
1 import types
2 import functools
3
4 from pip._vendor.requests.adapters import HTTPAdapter
5
6 from .controller import CacheController
7 from .cache import DictCache
8 from .filewrapper import CallbackFileWrapper
9
10
11 class CacheControlAdapter(HTTPAdapter):
12 invalidating_methods = set(['PUT', 'DELETE'])
13
14 def __init__(self, cache=None,
15 cache_etags=True,
16 controller_class=None,
17 serializer=None,
18 heuristic=None,
19 *args, **kw):
20 super(CacheControlAdapter, self).__init__(*args, **kw)
21 self.cache = cache or DictCache()
22 self.heuristic = heuristic
23
24 controller_factory = controller_class or CacheController
25 self.controller = controller_factory(
26 self.cache,
27 cache_etags=cache_etags,
28 serializer=serializer,
29 )
30
31 def send(self, request, **kw):
32 """
33 Send a request. Use the request information to see if it
34 exists in the cache and cache the response if we need to and can.
35 """
36 if request.method == 'GET':
37 cached_response = self.controller.cached_request(request)
38 if cached_response:
39 return self.build_response(request, cached_response,
40 from_cache=True)
41
42 # check for etags and add headers if appropriate
43 request.headers.update(
44 self.controller.conditional_headers(request)
45 )
46
47 resp = super(CacheControlAdapter, self).send(request, **kw)
48
49 return resp
50
51 def build_response(self, request, response, from_cache=False):
52 """
53 Build a response by making a request or using the cache.
54
55 This will end up calling send and returning a potentially
56 cached response
57 """
58 if not from_cache and request.method == 'GET':
59 # Check for any heuristics that might update headers
60 # before trying to cache.
61 if self.heuristic:
62 response = self.heuristic.apply(response)
63
64 # apply any expiration heuristics
65 if response.status == 304:
66 # We must have sent an ETag request. This could mean
67 # that we've been expired already or that we simply
68 # have an etag. In either case, we want to try and
69 # update the cache if that is the case.
70 cached_response = self.controller.update_cached_response(
71 request, response
72 )
73
74 if cached_response is not response:
75 from_cache = True
76
77 # We are done with the server response, read a
78 # possible response body (compliant servers will
79 # not return one, but we cannot be 100% sure) and
80 # release the connection back to the pool.
81 response.read(decode_content=False)
82 response.release_conn()
83
84 response = cached_response
85
86 # We always cache the 301 responses
87 elif response.status == 301:
88 self.controller.cache_response(request, response)
89 else:
90 # Wrap the response file with a wrapper that will cache the
91 # response when the stream has been consumed.
92 response._fp = CallbackFileWrapper(
93 response._fp,
94 functools.partial(
95 self.controller.cache_response,
96 request,
97 response,
98 )
99 )
100 if response.chunked:
101 super_update_chunk_length = response._update_chunk_length
102
103 def _update_chunk_length(self):
104 super_update_chunk_length()
105 if self.chunk_left == 0:
106 self._fp._close()
107 response._update_chunk_length = types.MethodType(_update_chunk_length, response)
108
109 resp = super(CacheControlAdapter, self).build_response(
110 request, response
111 )
112
113 # See if we should invalidate the cache.
114 if request.method in self.invalidating_methods and resp.ok:
115 cache_url = self.controller.cache_url(request.url)
116 self.cache.delete(cache_url)
117
118 # Give the request a from_cache attr to let people use it
119 resp.from_cache = from_cache
120
121 return resp
122
123 def close(self):
124 self.cache.close()
125 super(CacheControlAdapter, self).close()
1 """
2 The cache object API for implementing caches. The default is a thread
3 safe in-memory dictionary.
4 """
5 from threading import Lock
6
7
8 class BaseCache(object):
9
10 def get(self, key):
11 raise NotImplemented()
12
13 def set(self, key, value):
14 raise NotImplemented()
15
16 def delete(self, key):
17 raise NotImplemented()
18
19 def close(self):
20 pass
21
22
23 class DictCache(BaseCache):
24
25 def __init__(self, init_dict=None):
26 self.lock = Lock()
27 self.data = init_dict or {}
28
29 def get(self, key):
30 return self.data.get(key, None)
31
32 def set(self, key, value):
33 with self.lock:
34 self.data.update({key: value})
35
36 def delete(self, key):
37 with self.lock:
38 if key in self.data:
39 self.data.pop(key)
1 from textwrap import dedent
2
3 try:
4 from .file_cache import FileCache
5 except ImportError:
6 notice = dedent('''
7 NOTE: In order to use the FileCache you must have
8 lockfile installed. You can install it via pip:
9 pip install lockfile
10 ''')
11 print(notice)
12
13
14 try:
15 import redis
16 from .redis_cache import RedisCache
17 except ImportError:
18 pass
1 import hashlib
2 import os
3
4 from pip._vendor.lockfile import LockFile
5 from pip._vendor.lockfile.mkdirlockfile import MkdirLockFile
6
7 from ..cache import BaseCache
8 from ..controller import CacheController
9
10
11 def _secure_open_write(filename, fmode):
12 # We only want to write to this file, so open it in write only mode
13 flags = os.O_WRONLY
14
15 # os.O_CREAT | os.O_EXCL will fail if the file already exists, so we only
16 # will open *new* files.
17 # We specify this because we want to ensure that the mode we pass is the
18 # mode of the file.
19 flags |= os.O_CREAT | os.O_EXCL
20
21 # Do not follow symlinks to prevent someone from making a symlink that
22 # we follow and insecurely open a cache file.
23 if hasattr(os, "O_NOFOLLOW"):
24 flags |= os.O_NOFOLLOW
25
26 # On Windows we'll mark this file as binary
27 if hasattr(os, "O_BINARY"):
28 flags |= os.O_BINARY
29
30 # Before we open our file, we want to delete any existing file that is
31 # there
32 try:
33 os.remove(filename)
34 except (IOError, OSError):
35 # The file must not exist already, so we can just skip ahead to opening
36 pass
37
38 # Open our file, the use of os.O_CREAT | os.O_EXCL will ensure that if a
39 # race condition happens between the os.remove and this line, that an
40 # error will be raised. Because we utilize a lockfile this should only
41 # happen if someone is attempting to attack us.
42 fd = os.open(filename, flags, fmode)
43 try:
44 return os.fdopen(fd, "wb")
45 except:
46 # An error occurred wrapping our FD in a file object
47 os.close(fd)
48 raise
49
50
51 class FileCache(BaseCache):
52 def __init__(self, directory, forever=False, filemode=0o0600,
53 dirmode=0o0700, use_dir_lock=None, lock_class=None):
54
55 if use_dir_lock is not None and lock_class is not None:
56 raise ValueError("Cannot use use_dir_lock and lock_class together")
57
58 if use_dir_lock:
59 lock_class = MkdirLockFile
60
61 if lock_class is None:
62 lock_class = LockFile
63
64 self.directory = directory
65 self.forever = forever
66 self.filemode = filemode
67 self.dirmode = dirmode
68 self.lock_class = lock_class
69
70
71 @staticmethod
72 def encode(x):
73 return hashlib.sha224(x.encode()).hexdigest()
74
75 def _fn(self, name):
76 # NOTE: This method should not change as some may depend on it.
77 # See: https://github.com/ionrock/cachecontrol/issues/63
78 hashed = self.encode(name)
79 parts = list(hashed[:5]) + [hashed]
80 return os.path.join(self.directory, *parts)
81
82 def get(self, key):
83 name = self._fn(key)
84 if not os.path.exists(name):
85 return None
86
87 with open(name, 'rb') as fh:
88 return fh.read()
89
90 def set(self, key, value):
91 name = self._fn(key)
92
93 # Make sure the directory exists
94 try:
95 os.makedirs(os.path.dirname(name), self.dirmode)
96 except (IOError, OSError):
97 pass
98
99 with self.lock_class(name) as lock:
100 # Write our actual file
101 with _secure_open_write(lock.path, self.filemode) as fh:
102 fh.write(value)
103
104 def delete(self, key):
105 name = self._fn(key)
106 if not self.forever:
107 os.remove(name)
108
109
110 def url_to_file_path(url, filecache):
111 """Return the file cache path based on the URL.
112
113 This does not ensure the file exists!
114 """
115 key = CacheController.cache_url(url)
116 return filecache._fn(key)
1 from __future__ import division
2
3 from datetime import datetime
4
5
6 def total_seconds(td):
7 """Python 2.6 compatability"""
8 if hasattr(td, 'total_seconds'):
9 return td.total_seconds()
10
11 ms = td.microseconds
12 secs = (td.seconds + td.days * 24 * 3600)
13 return (ms + secs * 10**6) / 10**6
14
15
16 class RedisCache(object):
17
18 def __init__(self, conn):
19 self.conn = conn
20
21 def get(self, key):
22 return self.conn.get(key)
23
24 def set(self, key, value, expires=None):
25 if not expires:
26 self.conn.set(key, value)
27 else:
28 expires = expires - datetime.now()
29 self.conn.setex(key, total_seconds(expires), value)
30
31 def delete(self, key):
32 self.conn.delete(key)
33
34 def clear(self):
35 """Helper for clearing all the keys in a database. Use with
36 caution!"""
37 for key in self.conn.keys():
38 self.conn.delete(key)
39
40 def close(self):
41 self.conn.disconnect()
1 try:
2 from urllib.parse import urljoin
3 except ImportError:
4 from urlparse import urljoin
5
6
7 try:
8 import cPickle as pickle
9 except ImportError:
10 import pickle
11
12
13 from pip._vendor.requests.packages.urllib3.response import HTTPResponse
14 from pip._vendor.requests.packages.urllib3.util import is_fp_closed
15
16 # Replicate some six behaviour
17 try:
18 text_type = (unicode,)
19 except NameError:
20 text_type = (str,)
1 from io import BytesIO
2
3
4 class CallbackFileWrapper(object):
5 """
6 Small wrapper around a fp object which will tee everything read into a
7 buffer, and when that file is closed it will execute a callback with the
8 contents of that buffer.
9
10 All attributes are proxied to the underlying file object.
11
12 This class uses members with a double underscore (__) leading prefix so as
13 not to accidentally shadow an attribute.
14 """
15
16 def __init__(self, fp, callback):
17 self.__buf = BytesIO()
18 self.__fp = fp
19 self.__callback = callback
20
21 def __getattr__(self, name):
22 # The vaguaries of garbage collection means that self.__fp is
23 # not always set. By using __getattribute__ and the private
24 # name[0] allows looking up the attribute value and raising an
25 # AttributeError when it doesn't exist. This stop thigns from
26 # infinitely recursing calls to getattr in the case where
27 # self.__fp hasn't been set.
28 #
29 # [0] https://docs.python.org/2/reference/expressions.html#atom-identifiers
30 fp = self.__getattribute__('_CallbackFileWrapper__fp')
31 return getattr(fp, name)
32
33 def __is_fp_closed(self):
34 try:
35 return self.__fp.fp is None
36 except AttributeError:
37 pass
38
39 try:
40 return self.__fp.closed
41 except AttributeError:
42 pass
43
44 # We just don't cache it then.
45 # TODO: Add some logging here...
46 return False
47
48 def _close(self):
49 if self.__callback:
50 self.__callback(self.__buf.getvalue())
51
52 # We assign this to None here, because otherwise we can get into
53 # really tricky problems where the CPython interpreter dead locks
54 # because the callback is holding a reference to something which
55 # has a __del__ method. Setting this to None breaks the cycle
56 # and allows the garbage collector to do it's thing normally.
57 self.__callback = None
58
59 def read(self, amt=None):
60 data = self.__fp.read(amt)
61 self.__buf.write(data)
62 if self.__is_fp_closed():
63 self._close()
64
65 return data
66
67 def _safe_read(self, amt):
68 data = self.__fp._safe_read(amt)
69 if amt == 2 and data == b'\r\n':
70 # urllib executes this read to toss the CRLF at the end
71 # of the chunk.
72 return data
73
74 self.__buf.write(data)
75 if self.__is_fp_closed():
76 self._close()
77
78 return data
1 import calendar
2 import time
3
4 from email.utils import formatdate, parsedate, parsedate_tz
5
6 from datetime import datetime, timedelta
7
8 TIME_FMT = "%a, %d %b %Y %H:%M:%S GMT"
9
10
11 def expire_after(delta, date=None):
12 date = date or datetime.now()
13 return date + delta
14
15
16 def datetime_to_header(dt):
17 return formatdate(calendar.timegm(dt.timetuple()))
18
19
20 class BaseHeuristic(object):
21
22 def warning(self, response):
23 """
24 Return a valid 1xx warning header value describing the cache
25 adjustments.
26
27 The response is provided too allow warnings like 113
28 http://tools.ietf.org/html/rfc7234#section-5.5.4 where we need
29 to explicitly say response is over 24 hours old.
30 """
31 return '110 - "Response is Stale"'
32
33 def update_headers(self, response):
34 """Update the response headers with any new headers.
35
36 NOTE: This SHOULD always include some Warning header to
37 signify that the response was cached by the client, not
38 by way of the provided headers.
39 """
40 return {}
41
42 def apply(self, response):
43 updated_headers = self.update_headers(response)
44
45 if updated_headers:
46 response.headers.update(updated_headers)
47 warning_header_value = self.warning(response)
48 if warning_header_value is not None:
49 response.headers.update({'Warning': warning_header_value})
50
51 return response
52
53
54 class OneDayCache(BaseHeuristic):
55 """
56 Cache the response by providing an expires 1 day in the
57 future.
58 """
59 def update_headers(self, response):
60 headers = {}
61
62 if 'expires' not in response.headers:
63 date = parsedate(response.headers['date'])
64 expires = expire_after(timedelta(days=1),
65 date=datetime(*date[:6]))
66 headers['expires'] = datetime_to_header(expires)
67 headers['cache-control'] = 'public'
68 return headers
69
70
71 class ExpiresAfter(BaseHeuristic):
72 """
73 Cache **all** requests for a defined time period.
74 """
75
76 def __init__(self, **kw):
77 self.delta = timedelta(**kw)
78
79 def update_headers(self, response):
80 expires = expire_after(self.delta)
81 return {
82 'expires': datetime_to_header(expires),
83 'cache-control': 'public',
84 }
85
86 def warning(self, response):
87 tmpl = '110 - Automatically cached for %s. Response might be stale'
88 return tmpl % self.delta
89
90
91 class LastModified(BaseHeuristic):
92 """
93 If there is no Expires header already, fall back on Last-Modified
94 using the heuristic from
95 http://tools.ietf.org/html/rfc7234#section-4.2.2
96 to calculate a reasonable value.
97
98 Firefox also does something like this per
99 https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ
100 http://lxr.mozilla.org/mozilla-release/source/netwerk/protocol/http/nsHttpResponseHead.cpp#397
101 Unlike mozilla we limit this to 24-hr.
102 """
103 cacheable_by_default_statuses = set([
104 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501
105 ])
106
107 def update_headers(self, resp):
108 headers = resp.headers
109
110 if 'expires' in headers:
111 return {}
112
113 if 'cache-control' in headers and headers['cache-control'] != 'public':
114 return {}
115
116 if resp.status not in self.cacheable_by_default_statuses:
117 return {}
118
119 if 'date' not in headers or 'last-modified' not in headers:
120 return {}
121
122 date = calendar.timegm(parsedate_tz(headers['date']))
123 last_modified = parsedate(headers['last-modified'])
124 if date is None or last_modified is None:
125 return {}
126
127 now = time.time()
128 current_age = max(0, now - date)
129 delta = date - calendar.timegm(last_modified)
130 freshness_lifetime = max(0, min(delta / 10, 24 * 3600))
131 if freshness_lifetime <= current_age:
132 return {}
133
134 expires = date + freshness_lifetime
135 return {'expires': time.strftime(TIME_FMT, time.gmtime(expires))}
136
137 def warning(self, resp):
138 return None
1 import base64
2 import io
3 import json
4 import zlib
5
6 from pip._vendor.requests.structures import CaseInsensitiveDict
7
8 from .compat import HTTPResponse, pickle, text_type
9
10
11 def _b64_encode_bytes(b):
12 return base64.b64encode(b).decode("ascii")
13
14
15 def _b64_encode_str(s):
16 return _b64_encode_bytes(s.encode("utf8"))
17
18
19 def _b64_encode(s):
20 if isinstance(s, text_type):
21 return _b64_encode_str(s)
22 return _b64_encode_bytes(s)
23
24
25 def _b64_decode_bytes(b):
26 return base64.b64decode(b.encode("ascii"))
27
28
29 def _b64_decode_str(s):
30 return _b64_decode_bytes(s).decode("utf8")
31
32
33 class Serializer(object):
34
35 def dumps(self, request, response, body=None):
36 response_headers = CaseInsensitiveDict(response.headers)
37
38 if body is None:
39 body = response.read(decode_content=False)
40
41 # NOTE: 99% sure this is dead code. I'm only leaving it
42 # here b/c I don't have a test yet to prove
43 # it. Basically, before using
44 # `cachecontrol.filewrapper.CallbackFileWrapper`,
45 # this made an effort to reset the file handle. The
46 # `CallbackFileWrapper` short circuits this code by
47 # setting the body as the content is consumed, the
48 # result being a `body` argument is *always* passed
49 # into cache_response, and in turn,
50 # `Serializer.dump`.
51 response._fp = io.BytesIO(body)
52
53 data = {
54 "response": {
55 "body": _b64_encode_bytes(body),
56 "headers": dict(
57 (_b64_encode(k), _b64_encode(v))
58 for k, v in response.headers.items()
59 ),
60 "status": response.status,
61 "version": response.version,
62 "reason": _b64_encode_str(response.reason),
63 "strict": response.strict,
64 "decode_content": response.decode_content,
65 },
66 }
67
68 # Construct our vary headers
69 data["vary"] = {}
70 if "vary" in response_headers:
71 varied_headers = response_headers['vary'].split(',')
72 for header in varied_headers:
73 header = header.strip()
74 data["vary"][header] = request.headers.get(header, None)
75
76 # Encode our Vary headers to ensure they can be serialized as JSON
77 data["vary"] = dict(
78 (_b64_encode(k), _b64_encode(v) if v is not None else v)
79 for k, v in data["vary"].items()
80 )
81
82 return b",".join([
83 b"cc=2",
84 zlib.compress(
85 json.dumps(
86 data, separators=(",", ":"), sort_keys=True,
87 ).encode("utf8"),
88 ),
89 ])
90
91 def loads(self, request, data):
92 # Short circuit if we've been given an empty set of data
93 if not data:
94 return
95
96 # Determine what version of the serializer the data was serialized
97 # with
98 try:
99 ver, data = data.split(b",", 1)
100 except ValueError:
101 ver = b"cc=0"
102
103 # Make sure that our "ver" is actually a version and isn't a false
104 # positive from a , being in the data stream.
105 if ver[:3] != b"cc=":
106 data = ver + data
107 ver = b"cc=0"
108
109 # Get the version number out of the cc=N
110 ver = ver.split(b"=", 1)[-1].decode("ascii")
111
112 # Dispatch to the actual load method for the given version
113 try:
114 return getattr(self, "_loads_v{0}".format(ver))(request, data)
115 except AttributeError:
116 # This is a version we don't have a loads function for, so we'll
117 # just treat it as a miss and return None
118 return
119
120 def prepare_response(self, request, cached):
121 """Verify our vary headers match and construct a real urllib3
122 HTTPResponse object.
123 """
124 # Special case the '*' Vary value as it means we cannot actually
125 # determine if the cached response is suitable for this request.
126 if "*" in cached.get("vary", {}):
127 return
128
129 # Ensure that the Vary headers for the cached response match our
130 # request
131 for header, value in cached.get("vary", {}).items():
132 if request.headers.get(header, None) != value:
133 return
134
135 body_raw = cached["response"].pop("body")
136
137 headers = CaseInsensitiveDict(data=cached['response']['headers'])
138 if headers.get('transfer-encoding', '') == 'chunked':
139 headers.pop('transfer-encoding')
140
141 cached['response']['headers'] = headers
142
143 try:
144 body = io.BytesIO(body_raw)
145 except TypeError:
146 # This can happen if cachecontrol serialized to v1 format (pickle)
147 # using Python 2. A Python 2 str(byte string) will be unpickled as
148 # a Python 3 str (unicode string), which will cause the above to
149 # fail with:
150 #
151 # TypeError: 'str' does not support the buffer interface
152 body = io.BytesIO(body_raw.encode('utf8'))
153
154 return HTTPResponse(
155 body=body,
156 preload_content=False,
157 **cached["response"]
158 )
159
160 def _loads_v0(self, request, data):
161 # The original legacy cache data. This doesn't contain enough
162 # information to construct everything we need, so we'll treat this as
163 # a miss.
164 return
165
166 def _loads_v1(self, request, data):
167 try:
168 cached = pickle.loads(data)
169 except ValueError:
170 return
171
172 return self.prepare_response(request, cached)
173
174 def _loads_v2(self, request, data):
175 try:
176 cached = json.loads(zlib.decompress(data).decode("utf8"))
177 except ValueError:
178 return
179
180 # We need to decode the items that we've base64 encoded
181 cached["response"]["body"] = _b64_decode_bytes(
182 cached["response"]["body"]
183 )
184 cached["response"]["headers"] = dict(
185 (_b64_decode_str(k), _b64_decode_str(v))
186 for k, v in cached["response"]["headers"].items()
187 )
188 cached["response"]["reason"] = _b64_decode_str(
189 cached["response"]["reason"],
190 )
191 cached["vary"] = dict(
192 (_b64_decode_str(k), _b64_decode_str(v) if v is not None else v)
193 for k, v in cached["vary"].items()
194 )
195
196 return self.prepare_response(request, cached)
1 from .adapter import CacheControlAdapter
2 from .cache import DictCache
3
4
5 def CacheControl(sess,
6 cache=None,
7 cache_etags=True,
8 serializer=None,
9 heuristic=None):
10
11 cache = cache or DictCache()
12 adapter = CacheControlAdapter(
13 cache,
14 cache_etags=cache_etags,
15 serializer=serializer,
16 heuristic=heuristic,
17 )
18 sess.mount('http://', adapter)
19 sess.mount('https://', adapter)
20
21 return sess
1 # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
2 from .initialise import init, deinit, reinit, colorama_text
3 from .ansi import Fore, Back, Style, Cursor
4 from .ansitowin32 import AnsiToWin32
5
6 __version__ = '0.3.7'
7
1 # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
2 '''
3 This module generates ANSI character codes to printing colors to terminals.
4 See: http://en.wikipedia.org/wiki/ANSI_escape_code
5 '''
6
7 CSI = '\033['
8 OSC = '\033]'
9 BEL = '\007'
10
11
12 def code_to_chars(code):
13 return CSI + str(code) + 'm'
14
15 def set_title(title):
16 return OSC + '2;' + title + BEL
17
18 def clear_screen(mode=2):
19 return CSI + str(mode) + 'J'
20
21 def clear_line(mode=2):
22 return CSI + str(mode) + 'K'
23
24
25 class AnsiCodes(object):
26 def __init__(self):
27 # the subclasses declare class attributes which are numbers.
28 # Upon instantiation we define instance attributes, which are the same
29 # as the class attributes but wrapped with the ANSI escape sequence
30 for name in dir(self):
31 if not name.startswith('_'):
32 value = getattr(self, name)
33 setattr(self, name, code_to_chars(value))
34
35
36 class AnsiCursor(object):
37 def UP(self, n=1):
38 return CSI + str(n) + 'A'
39 def DOWN(self, n=1):
40 return CSI + str(n) + 'B'
41 def FORWARD(self, n=1):
42 return CSI + str(n) + 'C'
43 def BACK(self, n=1):
44 return CSI + str(n) + 'D'
45 def POS(self, x=1, y=1):
46 return CSI + str(y) + ';' + str(x) + 'H'
47
48
49 class AnsiFore(AnsiCodes):
50 BLACK = 30
51 RED = 31
52 GREEN = 32
53 YELLOW = 33
54 BLUE = 34
55 MAGENTA = 35
56 CYAN = 36
57 WHITE = 37
58 RESET = 39
59
60 # These are fairly well supported, but not part of the standard.
61 LIGHTBLACK_EX = 90
62 LIGHTRED_EX = 91
63 LIGHTGREEN_EX = 92
64 LIGHTYELLOW_EX = 93
65 LIGHTBLUE_EX = 94
66 LIGHTMAGENTA_EX = 95
67 LIGHTCYAN_EX = 96
68 LIGHTWHITE_EX = 97
69
70
71 class AnsiBack(AnsiCodes):
72 BLACK = 40
73 RED = 41
74 GREEN = 42
75 YELLOW = 43
76 BLUE = 44
77 MAGENTA = 45
78 CYAN = 46
79 WHITE = 47
80 RESET = 49
81
82 # These are fairly well supported, but not part of the standard.
83 LIGHTBLACK_EX = 100
84 LIGHTRED_EX = 101
85 LIGHTGREEN_EX = 102
86 LIGHTYELLOW_EX = 103
87 LIGHTBLUE_EX = 104
88 LIGHTMAGENTA_EX = 105
89 LIGHTCYAN_EX = 106
90 LIGHTWHITE_EX = 107
91
92
93 class AnsiStyle(AnsiCodes):
94 BRIGHT = 1
95 DIM = 2
96 NORMAL = 22
97 RESET_ALL = 0
98
99 Fore = AnsiFore()
100 Back = AnsiBack()
101 Style = AnsiStyle()
102 Cursor = AnsiCursor()
1 # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
2 import re
3 import sys
4 import os
5
6 from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style
7 from .winterm import WinTerm, WinColor, WinStyle
8 from .win32 import windll, winapi_test
9
10
11 winterm = None
12 if windll is not None:
13 winterm = WinTerm()
14
15
16 def is_stream_closed(stream):
17 return not hasattr(stream, 'closed') or stream.closed
18
19
20 def is_a_tty(stream):
21 return hasattr(stream, 'isatty') and stream.isatty()
22
23
24 class StreamWrapper(object):
25 '''
26 Wraps a stream (such as stdout), acting as a transparent proxy for all
27 attribute access apart from method 'write()', which is delegated to our
28 Converter instance.
29 '''
30 def __init__(self, wrapped, converter):
31 # double-underscore everything to prevent clashes with names of
32 # attributes on the wrapped stream object.
33 self.__wrapped = wrapped
34 self.__convertor = converter
35
36 def __getattr__(self, name):
37 return getattr(self.__wrapped, name)
38
39 def write(self, text):
40 self.__convertor.write(text)
41
42
43 class AnsiToWin32(object):
44 '''
45 Implements a 'write()' method which, on Windows, will strip ANSI character
46 sequences from the text, and if outputting to a tty, will convert them into
47 win32 function calls.
48 '''
49 ANSI_CSI_RE = re.compile('\001?\033\[((?:\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer
50 ANSI_OSC_RE = re.compile('\001?\033\]((?:.|;)*?)(\x07)\002?') # Operating System Command
51
52 def __init__(self, wrapped, convert=None, strip=None, autoreset=False):
53 # The wrapped stream (normally sys.stdout or sys.stderr)
54 self.wrapped = wrapped
55
56 # should we reset colors to defaults after every .write()
57 self.autoreset = autoreset
58
59 # create the proxy wrapping our output stream
60 self.stream = StreamWrapper(wrapped, self)
61
62 on_windows = os.name == 'nt'
63 # We test if the WinAPI works, because even if we are on Windows
64 # we may be using a terminal that doesn't support the WinAPI
65 # (e.g. Cygwin Terminal). In this case it's up to the terminal
66 # to support the ANSI codes.
67 conversion_supported = on_windows and winapi_test()
68
69 # should we strip ANSI sequences from our output?
70 if strip is None:
71 strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped))
72 self.strip = strip
73
74 # should we should convert ANSI sequences into win32 calls?
75 if convert is None:
76 convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped)
77 self.convert = convert
78
79 # dict of ansi codes to win32 functions and parameters
80 self.win32_calls = self.get_win32_calls()
81
82 # are we wrapping stderr?
83 self.on_stderr = self.wrapped is sys.stderr
84
85 def should_wrap(self):
86 '''
87 True if this class is actually needed. If false, then the output
88 stream will not be affected, nor will win32 calls be issued, so
89 wrapping stdout is not actually required. This will generally be
90 False on non-Windows platforms, unless optional functionality like
91 autoreset has been requested using kwargs to init()
92 '''
93 return self.convert or self.strip or self.autoreset
94
95 def get_win32_calls(self):
96 if self.convert and winterm:
97 return {
98 AnsiStyle.RESET_ALL: (winterm.reset_all, ),
99 AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT),
100 AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL),
101 AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL),
102 AnsiFore.BLACK: (winterm.fore, WinColor.BLACK),
103 AnsiFore.RED: (winterm.fore, WinColor.RED),
104 AnsiFore.GREEN: (winterm.fore, WinColor.GREEN),
105 AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW),
106 AnsiFore.BLUE: (winterm.fore, WinColor.BLUE),
107 AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA),
108 AnsiFore.CYAN: (winterm.fore, WinColor.CYAN),
109 AnsiFore.WHITE: (winterm.fore, WinColor.GREY),
110 AnsiFore.RESET: (winterm.fore, ),
111 AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True),
112 AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True),
113 AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True),
114 AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True),
115 AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True),
116 AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True),
117 AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True),
118 AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True),
119 AnsiBack.BLACK: (winterm.back, WinColor.BLACK),
120 AnsiBack.RED: (winterm.back, WinColor.RED),
121 AnsiBack.GREEN: (winterm.back, WinColor.GREEN),
122 AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW),
123 AnsiBack.BLUE: (winterm.back, WinColor.BLUE),
124 AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA),
125 AnsiBack.CYAN: (winterm.back, WinColor.CYAN),
126 AnsiBack.WHITE: (winterm.back, WinColor.GREY),
127 AnsiBack.RESET: (winterm.back, ),
128 AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True),
129 AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True),
130 AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True),
131 AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True),
132 AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True),
133 AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True),
134 AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True),
135 AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True),
136 }
137 return dict()
138
139 def write(self, text):
140 if self.strip or self.convert:
141 self.write_and_convert(text)
142 else:
143 self.wrapped.write(text)
144 self.wrapped.flush()
145 if self.autoreset:
146 self.reset_all()
147
148
149 def reset_all(self):
150 if self.convert:
151 self.call_win32('m', (0,))
152 elif not self.strip and not is_stream_closed(self.wrapped):
153 self.wrapped.write(Style.RESET_ALL)
154
155
156 def write_and_convert(self, text):
157 '''
158 Write the given text to our wrapped stream, stripping any ANSI
159 sequences from the text, and optionally converting them into win32
160 calls.
161 '''
162 cursor = 0
163 text = self.convert_osc(text)
164 for match in self.ANSI_CSI_RE.finditer(text):
165 start, end = match.span()
166 self.write_plain_text(text, cursor, start)
167 self.convert_ansi(*match.groups())
168 cursor = end
169 self.write_plain_text(text, cursor, len(text))
170
171
172 def write_plain_text(self, text, start, end):
173 if start < end:
174 self.wrapped.write(text[start:end])
175 self.wrapped.flush()
176
177
178 def convert_ansi(self, paramstring, command):
179 if self.convert:
180 params = self.extract_params(command, paramstring)
181 self.call_win32(command, params)
182
183
184 def extract_params(self, command, paramstring):
185 if command in 'Hf':
186 params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';'))
187 while len(params) < 2:
188 # defaults:
189 params = params + (1,)
190 else:
191 params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0)
192 if len(params) == 0:
193 # defaults:
194 if command in 'JKm':
195 params = (0,)
196 elif command in 'ABCD':
197 params = (1,)
198
199 return params
200
201
202 def call_win32(self, command, params):
203 if command == 'm':
204 for param in params:
205 if param in self.win32_calls:
206 func_args = self.win32_calls[param]
207 func = func_args[0]
208 args = func_args[1:]
209 kwargs = dict(on_stderr=self.on_stderr)
210 func(*args, **kwargs)
211 elif command in 'J':
212 winterm.erase_screen(params[0], on_stderr=self.on_stderr)
213 elif command in 'K':
214 winterm.erase_line(params[0], on_stderr=self.on_stderr)
215 elif command in 'Hf': # cursor position - absolute
216 winterm.set_cursor_position(params, on_stderr=self.on_stderr)
217 elif command in 'ABCD': # cursor position - relative
218 n = params[0]
219 # A - up, B - down, C - forward, D - back
220 x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command]
221 winterm.cursor_adjust(x, y, on_stderr=self.on_stderr)
222
223
224 def convert_osc(self, text):
225 for match in self.ANSI_OSC_RE.finditer(text):
226 start, end = match.span()
227 text = text[:start] + text[end:]
228 paramstring, command = match.groups()
229 if command in '\x07': # \x07 = BEL
230 params = paramstring.split(";")
231 # 0 - change title and icon (we will only change title)
232 # 1 - change icon (we don't support this)
233 # 2 - change title
234 if params[0] in '02':
235 winterm.set_title(params[1])
236 return text
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type