HyoJoon

upload RaspberryPi code

Showing 1000 changed files with 2788 additions and 0 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

1 +This is a placeholder... the Android content will come eventually!
No preview for this file type
1 +
2 +
3 +# Import packages
4 +import os
5 +import argparse
6 +import cv2
7 +import numpy as np
8 +import sys
9 +import time
10 +from threading import Thread
11 +import importlib.util
12 +import paho.mqtt.client as mqtt
13 +
14 +class VideoStream:
15 + """Camera object that controls video streaming from the Picamera"""
16 + def __init__(self,resolution=(640,480),framerate=30):
17 + # Initialize the PiCamera and the camera image stream
18 + self.stream = cv2.VideoCapture(0)
19 + ret = self.stream.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
20 + ret = self.stream.set(3,resolution[0])
21 + ret = self.stream.set(4,resolution[1])
22 +
23 + # Read first frame from the stream
24 + (self.grabbed, self.frame) = self.stream.read()
25 +
26 + # Variable to control when the camera is stopped
27 + self.stopped = False
28 +
29 + def start(self):
30 + # Start the thread that reads frames from the video stream
31 + Thread(target=self.update,args=()).start()
32 + return self
33 +
34 + def update(self):
35 + # Keep looping indefinitely until the thread is stopped
36 + while True:
37 + # If the camera is stopped, stop the thread
38 + if self.stopped:
39 + # Close camera resources
40 + self.stream.release()
41 + return
42 +
43 + # Otherwise, grab the next frame from the stream
44 + (self.grabbed, self.frame) = self.stream.read()
45 +
46 + def read(self):
47 + # Return the most recent frame
48 + return self.frame
49 +
50 + def stop(self):
51 + # Indicate that the camera and thread should be stopped
52 + self.stopped = True
53 +
54 +# Define and parse input arguments
55 +parser = argparse.ArgumentParser()
56 +parser.add_argument('--modeldir', help='Folder the .tflite file is located in',
57 + required=True)
58 +parser.add_argument('--graph', help='Name of the .tflite file, if different than detect.tflite',
59 + default='detect.tflite')
60 +parser.add_argument('--labels', help='Name of the labelmap file, if different than labelmap.txt',
61 + default='labelmap.txt')
62 +parser.add_argument('--threshold', help='Minimum confidence threshold for displaying detected objects',
63 + default=0.5)
64 +parser.add_argument('--resolution', help='Desired webcam resolution in WxH. If the webcam does not support the resolution entered, errors may occur.',
65 + default='1280x720')
66 +parser.add_argument('--edgetpu', help='Use Coral Edge TPU Accelerator to speed up detection',
67 + action='store_true')
68 +
69 +args = parser.parse_args()
70 +
71 +MODEL_NAME = args.modeldir
72 +GRAPH_NAME = args.graph
73 +LABELMAP_NAME = args.labels
74 +min_conf_threshold = float(args.threshold)
75 +resW, resH = args.resolution.split('x')
76 +imW, imH = int(resW), int(resH)
77 +use_TPU = args.edgetpu
78 +
79 +# Import TensorFlow libraries
80 +# If tflite_runtime is installed, import interpreter from tflite_runtime, else import from regular tensorflow
81 +# If using Coral Edge TPU, import the load_delegate library
82 +pkg = importlib.util.find_spec('tflite_runtime')
83 +if pkg:
84 + from tflite_runtime.interpreter import Interpreter
85 + if use_TPU:
86 + from tflite_runtime.interpreter import load_delegate
87 +else:
88 + from tensorflow.lite.python.interpreter import Interpreter
89 + if use_TPU:
90 + from tensorflow.lite.python.interpreter import load_delegate
91 +
92 +# If using Edge TPU, assign filename for Edge TPU model
93 +if use_TPU:
94 + # If user has specified the name of the .tflite file, use that name, otherwise use default 'edgetpu.tflite'
95 + if (GRAPH_NAME == 'detect.tflite'):
96 + GRAPH_NAME = 'edgetpu.tflite'
97 +
98 +# Get path to current working directory
99 +CWD_PATH = os.getcwd()
100 +
101 +# Path to .tflite file, which contains the model that is used for object detection
102 +PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,GRAPH_NAME)
103 +
104 +# Path to label map file
105 +PATH_TO_LABELS = os.path.join(CWD_PATH,MODEL_NAME,LABELMAP_NAME)
106 +
107 +# Load the label map
108 +with open(PATH_TO_LABELS, 'r') as f:
109 + labels = [line.strip() for line in f.readlines()]
110 +
111 +if labels[0] == '???':
112 + del(labels[0])
113 +
114 +# Load the Tensorflow Lite model.
115 +# If using Edge TPU, use special load_delegate argument
116 +if use_TPU:
117 + interpreter = Interpreter(model_path=PATH_TO_CKPT,
118 + experimental_delegates=[load_delegate('libedgetpu.so.1.0')])
119 + print(PATH_TO_CKPT)
120 +else:
121 + interpreter = Interpreter(model_path=PATH_TO_CKPT)
122 +
123 +interpreter.allocate_tensors()
124 +
125 +# Get model details
126 +input_details = interpreter.get_input_details()
127 +output_details = interpreter.get_output_details()
128 +height = input_details[0]['shape'][1]
129 +width = input_details[0]['shape'][2]
130 +
131 +floating_model = (input_details[0]['dtype'] == np.float32)
132 +
133 +input_mean = 127.5
134 +input_std = 127.5
135 +
136 +# Initialize frame rate calculation
137 +frame_rate_calc = 1
138 +freq = cv2.getTickFrequency()
139 +
140 +# Initialize video stream
141 +videostream = VideoStream(resolution=(imW,imH),framerate=30).start()
142 +time.sleep(1)
143 +
144 +#for frame1 in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True):
145 +while True:
146 +
147 + # Start timer (for calculating frame rate)
148 + t1 = cv2.getTickCount()
149 +
150 + # Grab frame from video stream
151 + frame1 = videostream.read()
152 +
153 + # Acquire frame and resize to expected shape [1xHxWx3]
154 + frame = frame1.copy()
155 + frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
156 + frame_resized = cv2.resize(frame_rgb, (width, height))
157 + input_data = np.expand_dims(frame_resized, axis=0)
158 +
159 + # Normalize pixel values if using a floating model (i.e. if model is non-quantized)
160 + if floating_model:
161 + input_data = (np.float32(input_data) - input_mean) / input_std
162 +
163 + # Perform the actual detection by running the model with the image as input
164 + interpreter.set_tensor(input_details[0]['index'],input_data)
165 + interpreter.invoke()
166 +
167 + # Retrieve detection results
168 + boxes = interpreter.get_tensor(output_details[0]['index'])[0] # Bounding box coordinates of detected objects
169 + classes = interpreter.get_tensor(output_details[1]['index'])[0] # Class index of detected objects
170 + scores = interpreter.get_tensor(output_details[2]['index'])[0] # Confidence of detected objects
171 + #num = interpreter.get_tensor(output_details[3]['index'])[0] # Total number of detected objects (inaccurate and not needed)
172 +
173 + # Loop over all detections and draw detection box if confidence is above minimum threshold
174 + for i in range(len(scores)):
175 + if ((scores[i] > min_conf_threshold) and (scores[i] <= 1.0)):
176 +
177 + # Get bounding box coordinates and draw box
178 + # Interpreter can return coordinates that are outside of image dimensions, need to force them to be within image using max() and min()
179 + ymin = int(max(1,(boxes[i][0] * imH)))
180 + xmin = int(max(1,(boxes[i][1] * imW)))
181 + ymax = int(min(imH,(boxes[i][2] * imH)))
182 + xmax = int(min(imW,(boxes[i][3] * imW)))
183 +
184 + cv2.rectangle(frame, (xmin,ymin), (xmax,ymax), (10, 255, 0), 2)
185 +
186 + # Draw label
187 + object_name = labels[int(classes[i])] # Look up object name from "labels" array using class index
188 + label = '%s' % (object_name) # Example: 'person: 72%'
189 + labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2) # Get font size
190 + label_ymin = max(ymin, labelSize[1] + 10) # Make sure not to draw label too close to top of window
191 + cv2.rectangle(frame, (xmin, label_ymin-labelSize[1]-10), (xmin+labelSize[0], label_ymin+baseLine-10), (255, 255, 255), cv2.FILLED) # Draw white box to put label text in
192 + cv2.putText(frame, label, (xmin, label_ymin-7), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2) # Draw label text
193 + # MQTT
194 + mqttc = mqtt.Client("python_pub")
195 + mqttc.connect("test.mosquitto.org", 1883)
196 + mqttc.publish("hello/fire", "fire detection")
197 +
198 + # Draw framerate in corner of frame
199 + cv2.putText(frame,'FPS: {0:.2f}'.format(frame_rate_calc),(30,50),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,0),2,cv2.LINE_AA)
200 +
201 + # All the results have been drawn on the frame, so it's time to display it.
202 + cv2.imshow('Object detector', frame)
203 +
204 + # Calculate framerate
205 + t2 = cv2.getTickCount()
206 + time1 = (t2-t1)/freq
207 + frame_rate_calc= 1/time1
208 +
209 + # Press 'q' to quit
210 + if cv2.waitKey(1) == ord('q'):
211 + break
212 +
213 +# Clean up
214 +cv2.destroyAllWindows()
215 +videostream.stop()
No preview for this file type
1 +#!/bin/bash
2 +
3 +# Get packages required for OpenCV
4 +
5 +sudo apt-get -y install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
6 +sudo apt-get -y install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
7 +sudo apt-get -y install libxvidcore-dev libx264-dev
8 +sudo apt-get -y install qt4-dev-tools libatlas-base-dev
9 +
10 +# Need to get an older version of OpenCV because version 4 has errors
11 +pip3 install opencv-python==3.4.6.27
12 +
13 +# Get packages required for TensorFlow
14 +# Using the tflite_runtime packages available at https://www.tensorflow.org/lite/guide/python
15 +# Will change to just 'pip3 install tensorflow' once newer versions of TF are added to piwheels
16 +
17 +#pip3 install tensorflow
18 +
19 +version=$(python -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
20 +
21 +if [ $version == "3.7" ]; then
22 +pip3 install https://dl.google.com/coral/python/tflite_runtime-2.1.0.post1-cp37-cp37m-linux_armv7l.whl
23 +fi
24 +
25 +if [ $version == "3.5" ]; then
26 +pip3 install https://dl.google.com/coral/python/tflite_runtime-2.1.0.post1-cp35-cp35m-linux_armv7l.whl
27 +fi
28 +
1 +# This file must be used with "source bin/activate" *from bash*
2 +# you cannot run it directly
3 +
4 +deactivate () {
5 + # reset old environment variables
6 + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
7 + PATH="${_OLD_VIRTUAL_PATH:-}"
8 + export PATH
9 + unset _OLD_VIRTUAL_PATH
10 + fi
11 + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
12 + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
13 + export PYTHONHOME
14 + unset _OLD_VIRTUAL_PYTHONHOME
15 + fi
16 +
17 + # This should detect bash and zsh, which have a hash command that must
18 + # be called to get it to forget past commands. Without forgetting
19 + # past commands the $PATH changes we made may not be respected
20 + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
21 + hash -r
22 + fi
23 +
24 + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
25 + PS1="${_OLD_VIRTUAL_PS1:-}"
26 + export PS1
27 + unset _OLD_VIRTUAL_PS1
28 + fi
29 +
30 + unset VIRTUAL_ENV
31 + if [ ! "$1" = "nondestructive" ] ; then
32 + # Self destruct!
33 + unset -f deactivate
34 + fi
35 +}
36 +
37 +# unset irrelevant variables
38 +deactivate nondestructive
39 +
40 +VIRTUAL_ENV="/home/pi/tflite1/tflite1-env"
41 +export VIRTUAL_ENV
42 +
43 +_OLD_VIRTUAL_PATH="$PATH"
44 +PATH="$VIRTUAL_ENV/bin:$PATH"
45 +export PATH
46 +
47 +# unset PYTHONHOME if set
48 +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
49 +# could use `if (set -u; : $PYTHONHOME) ;` in bash
50 +if [ -n "${PYTHONHOME:-}" ] ; then
51 + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
52 + unset PYTHONHOME
53 +fi
54 +
55 +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
56 + _OLD_VIRTUAL_PS1="${PS1:-}"
57 + if [ "x(tflite1-env) " != x ] ; then
58 + PS1="(tflite1-env) ${PS1:-}"
59 + else
60 + if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
61 + # special case for Aspen magic directories
62 + # see http://www.zetadev.com/software/aspen/
63 + PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
64 + else
65 + PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
66 + fi
67 + fi
68 + export PS1
69 +fi
70 +
71 +# This should detect bash and zsh, which have a hash command that must
72 +# be called to get it to forget past commands. Without forgetting
73 +# past commands the $PATH changes we made may not be respected
74 +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
75 + hash -r
76 +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 +# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
5 +
6 +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'
7 +
8 +# Unset irrelevant variables.
9 +deactivate nondestructive
10 +
11 +setenv VIRTUAL_ENV "/home/pi/tflite1/tflite1-env"
12 +
13 +set _OLD_VIRTUAL_PATH="$PATH"
14 +setenv PATH "$VIRTUAL_ENV/bin:$PATH"
15 +
16 +
17 +set _OLD_VIRTUAL_PROMPT="$prompt"
18 +
19 +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
20 + if ("tflite1-env" != "") then
21 + set env_name = "tflite1-env"
22 + else
23 + if (`basename "VIRTUAL_ENV"` == "__") then
24 + # special case for Aspen magic directories
25 + # see http://www.zetadev.com/software/aspen/
26 + set env_name = `basename \`dirname "$VIRTUAL_ENV"\``
27 + else
28 + set env_name = `basename "$VIRTUAL_ENV"`
29 + endif
30 + endif
31 + set prompt = "[$env_name] $prompt"
32 + unset env_name
33 +endif
34 +
35 +alias pydoc python -m pydoc
36 +
37 +rehash
1 +# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org)
2 +# you cannot run it directly
3 +
4 +function deactivate -d "Exit virtualenv and return to normal shell 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 + if test -n "$_OLD_VIRTUAL_PYTHONHOME"
11 + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
12 + set -e _OLD_VIRTUAL_PYTHONHOME
13 + end
14 +
15 + if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
16 + functions -e fish_prompt
17 + set -e _OLD_FISH_PROMPT_OVERRIDE
18 + functions -c _old_fish_prompt fish_prompt
19 + functions -e _old_fish_prompt
20 + end
21 +
22 + set -e VIRTUAL_ENV
23 + if test "$argv[1]" != "nondestructive"
24 + # Self destruct!
25 + functions -e deactivate
26 + end
27 +end
28 +
29 +# unset irrelevant variables
30 +deactivate nondestructive
31 +
32 +set -gx VIRTUAL_ENV "/home/pi/tflite1/tflite1-env"
33 +
34 +set -gx _OLD_VIRTUAL_PATH $PATH
35 +set -gx PATH "$VIRTUAL_ENV/bin" $PATH
36 +
37 +# unset PYTHONHOME if set
38 +if set -q PYTHONHOME
39 + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
40 + set -e PYTHONHOME
41 +end
42 +
43 +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
44 + # fish uses a function instead of an env var to generate the prompt.
45 +
46 + # save the current fish_prompt function as the function _old_fish_prompt
47 + functions -c fish_prompt _old_fish_prompt
48 +
49 + # with the original prompt function renamed, we can override with our own.
50 + function fish_prompt
51 + # Save the return status of the last command
52 + set -l old_status $status
53 +
54 + # Prompt override?
55 + if test -n "(tflite1-env) "
56 + printf "%s%s" "(tflite1-env) " (set_color normal)
57 + else
58 + # ...Otherwise, prepend env
59 + set -l _checkbase (basename "$VIRTUAL_ENV")
60 + if test $_checkbase = "__"
61 + # special case for Aspen magic directories
62 + # see http://www.zetadev.com/software/aspen/
63 + printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal)
64 + else
65 + printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal)
66 + end
67 + end
68 +
69 + # Restore the return status of the previous command.
70 + echo "exit $old_status" | .
71 + _old_fish_prompt
72 + end
73 +
74 + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
75 +end
1 +#!/home/pi/tflite1/tflite1-env/bin/python3
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 +#!/home/pi/tflite1/tflite1-env/bin/python3
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 +#!/home/pi/tflite1/tflite1-env/bin/python3
2 +
3 +# -*- coding: utf-8 -*-
4 +import re
5 +import sys
6 +
7 +from numpy.f2py.f2py2e 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 +#!/home/pi/tflite1/tflite1-env/bin/python3
2 +
3 +# -*- coding: utf-8 -*-
4 +import re
5 +import sys
6 +
7 +from numpy.f2py.f2py2e 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 +#!/home/pi/tflite1/tflite1-env/bin/python3
2 +
3 +# -*- coding: utf-8 -*-
4 +import re
5 +import sys
6 +
7 +from numpy.f2py.f2py2e 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 +#!/home/pi/tflite1/tflite1-env/bin/python3
2 +# -*- coding: utf-8 -*-
3 +import re
4 +import sys
5 +from flask.cli import main
6 +if __name__ == '__main__':
7 + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
8 + sys.exit(main())
1 +#!/home/pi/tflite1/tflite1-env/bin/python3
2 +
3 +# -*- coding: utf-8 -*-
4 +import re
5 +import sys
6 +
7 +from pip._internal.cli.main 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 +#!/home/pi/tflite1/tflite1-env/bin/python3
2 +
3 +# -*- coding: utf-8 -*-
4 +import re
5 +import sys
6 +
7 +from pip._internal.cli.main 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 +#!/home/pi/tflite1/tflite1-env/bin/python3
2 +
3 +# -*- coding: utf-8 -*-
4 +import re
5 +import sys
6 +
7 +from pip._internal.cli.main 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 +Copyright 2010 Pallets
2 +
3 +Redistribution and use in source and binary forms, with or without
4 +modification, are permitted provided that the following conditions are
5 +met:
6 +
7 +1. Redistributions of source code must retain the above copyright
8 + notice, this list of conditions and the following disclaimer.
9 +
10 +2. Redistributions in binary form must reproduce the above copyright
11 + notice, this list of conditions and the following disclaimer in the
12 + documentation and/or other materials provided with the distribution.
13 +
14 +3. Neither the name of the copyright holder nor the names of its
15 + contributors may be used to endorse or promote products derived from
16 + this software without specific prior written permission.
17 +
18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 +Metadata-Version: 2.1
2 +Name: Flask
3 +Version: 1.1.2
4 +Summary: A simple framework for building complex web applications.
5 +Home-page: https://palletsprojects.com/p/flask/
6 +Author: Armin Ronacher
7 +Author-email: armin.ronacher@active-4.com
8 +Maintainer: Pallets
9 +Maintainer-email: contact@palletsprojects.com
10 +License: BSD-3-Clause
11 +Project-URL: Documentation, https://flask.palletsprojects.com/
12 +Project-URL: Code, https://github.com/pallets/flask
13 +Project-URL: Issue tracker, https://github.com/pallets/flask/issues
14 +Platform: UNKNOWN
15 +Classifier: Development Status :: 5 - Production/Stable
16 +Classifier: Environment :: Web Environment
17 +Classifier: Framework :: Flask
18 +Classifier: Intended Audience :: Developers
19 +Classifier: License :: OSI Approved :: BSD License
20 +Classifier: Operating System :: OS Independent
21 +Classifier: Programming Language :: Python
22 +Classifier: Programming Language :: Python :: 2
23 +Classifier: Programming Language :: Python :: 2.7
24 +Classifier: Programming Language :: Python :: 3
25 +Classifier: Programming Language :: Python :: 3.5
26 +Classifier: Programming Language :: Python :: 3.6
27 +Classifier: Programming Language :: Python :: 3.7
28 +Classifier: Programming Language :: Python :: 3.8
29 +Classifier: Programming Language :: Python :: Implementation :: CPython
30 +Classifier: Programming Language :: Python :: Implementation :: PyPy
31 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
32 +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
33 +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
34 +Classifier: Topic :: Software Development :: Libraries :: Python Modules
35 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
36 +Requires-Dist: Werkzeug (>=0.15)
37 +Requires-Dist: Jinja2 (>=2.10.1)
38 +Requires-Dist: itsdangerous (>=0.24)
39 +Requires-Dist: click (>=5.1)
40 +Provides-Extra: dev
41 +Requires-Dist: pytest ; extra == 'dev'
42 +Requires-Dist: coverage ; extra == 'dev'
43 +Requires-Dist: tox ; extra == 'dev'
44 +Requires-Dist: sphinx ; extra == 'dev'
45 +Requires-Dist: pallets-sphinx-themes ; extra == 'dev'
46 +Requires-Dist: sphinxcontrib-log-cabinet ; extra == 'dev'
47 +Requires-Dist: sphinx-issues ; extra == 'dev'
48 +Provides-Extra: docs
49 +Requires-Dist: sphinx ; extra == 'docs'
50 +Requires-Dist: pallets-sphinx-themes ; extra == 'docs'
51 +Requires-Dist: sphinxcontrib-log-cabinet ; extra == 'docs'
52 +Requires-Dist: sphinx-issues ; extra == 'docs'
53 +Provides-Extra: dotenv
54 +Requires-Dist: python-dotenv ; extra == 'dotenv'
55 +
56 +Flask
57 +=====
58 +
59 +Flask is a lightweight `WSGI`_ web application framework. It is designed
60 +to make getting started quick and easy, with the ability to scale up to
61 +complex applications. It began as a simple wrapper around `Werkzeug`_
62 +and `Jinja`_ and has become one of the most popular Python web
63 +application frameworks.
64 +
65 +Flask offers suggestions, but doesn't enforce any dependencies or
66 +project layout. It is up to the developer to choose the tools and
67 +libraries they want to use. There are many extensions provided by the
68 +community that make adding new functionality easy.
69 +
70 +
71 +Installing
72 +----------
73 +
74 +Install and update using `pip`_:
75 +
76 +.. code-block:: text
77 +
78 + pip install -U Flask
79 +
80 +
81 +A Simple Example
82 +----------------
83 +
84 +.. code-block:: python
85 +
86 + from flask import Flask
87 +
88 + app = Flask(__name__)
89 +
90 + @app.route("/")
91 + def hello():
92 + return "Hello, World!"
93 +
94 +.. code-block:: text
95 +
96 + $ env FLASK_APP=hello.py flask run
97 + * Serving Flask app "hello"
98 + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
99 +
100 +
101 +Contributing
102 +------------
103 +
104 +For guidance on setting up a development environment and how to make a
105 +contribution to Flask, see the `contributing guidelines`_.
106 +
107 +.. _contributing guidelines: https://github.com/pallets/flask/blob/master/CONTRIBUTING.rst
108 +
109 +
110 +Donate
111 +------
112 +
113 +The Pallets organization develops and supports Flask and the libraries
114 +it uses. In order to grow the community of contributors and users, and
115 +allow the maintainers to devote more time to the projects, `please
116 +donate today`_.
117 +
118 +.. _please donate today: https://psfmember.org/civicrm/contribute/transact?reset=1&id=20
119 +
120 +
121 +Links
122 +-----
123 +
124 +* Website: https://palletsprojects.com/p/flask/
125 +* Documentation: https://flask.palletsprojects.com/
126 +* Releases: https://pypi.org/project/Flask/
127 +* Code: https://github.com/pallets/flask
128 +* Issue tracker: https://github.com/pallets/flask/issues
129 +* Test status: https://dev.azure.com/pallets/flask/_build
130 +* Official chat: https://discord.gg/t6rrQZH
131 +
132 +.. _WSGI: https://wsgi.readthedocs.io
133 +.. _Werkzeug: https://www.palletsprojects.com/p/werkzeug/
134 +.. _Jinja: https://www.palletsprojects.com/p/jinja/
135 +.. _pip: https://pip.pypa.io/en/stable/quickstart/
136 +
137 +
1 +../../../bin/flask,sha256=iH6UDOllZbvgGvBDFqXFNo9fQxLywt7oppo9V1zC0EM,232
2 +Flask-1.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
3 +Flask-1.1.2.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475
4 +Flask-1.1.2.dist-info/METADATA,sha256=3INpPWH6nKfZ33R2N-bQZy4TOe1wQCMweZc9mwcNrtc,4591
5 +Flask-1.1.2.dist-info/RECORD,,
6 +Flask-1.1.2.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110
7 +Flask-1.1.2.dist-info/entry_points.txt,sha256=gBLA1aKg0OYR8AhbAfg8lnburHtKcgJLDU52BBctN0k,42
8 +Flask-1.1.2.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6
9 +flask/__init__.py,sha256=YnA9wkwbJcnb_jTT-nMsMFeFE_UWt33khKzdHmMSuyI,1894
10 +flask/__main__.py,sha256=fjVtt3QTANXlpJCOv3Ha7d5H-76MwzSIOab7SFD9TEk,254
11 +flask/__pycache__/__init__.cpython-37.pyc,,
12 +flask/__pycache__/__main__.cpython-37.pyc,,
13 +flask/__pycache__/_compat.cpython-37.pyc,,
14 +flask/__pycache__/app.cpython-37.pyc,,
15 +flask/__pycache__/blueprints.cpython-37.pyc,,
16 +flask/__pycache__/cli.cpython-37.pyc,,
17 +flask/__pycache__/config.cpython-37.pyc,,
18 +flask/__pycache__/ctx.cpython-37.pyc,,
19 +flask/__pycache__/debughelpers.cpython-37.pyc,,
20 +flask/__pycache__/globals.cpython-37.pyc,,
21 +flask/__pycache__/helpers.cpython-37.pyc,,
22 +flask/__pycache__/logging.cpython-37.pyc,,
23 +flask/__pycache__/sessions.cpython-37.pyc,,
24 +flask/__pycache__/signals.cpython-37.pyc,,
25 +flask/__pycache__/templating.cpython-37.pyc,,
26 +flask/__pycache__/testing.cpython-37.pyc,,
27 +flask/__pycache__/views.cpython-37.pyc,,
28 +flask/__pycache__/wrappers.cpython-37.pyc,,
29 +flask/_compat.py,sha256=8KPT54Iig96TuLipdogLRHNYToIcg-xPhnSV5VRERnw,4099
30 +flask/app.py,sha256=tmEhx_XrIRP24vZg39dHMWFzJ2jj-YxIcd51LaIT5cE,98059
31 +flask/blueprints.py,sha256=vkdm8NusGsfZUeIfPdCluj733QFmiQcT4Sk1tuZLUjw,21400
32 +flask/cli.py,sha256=SIb22uq9wYBeB2tKMl0pYdhtZ1MAQyZtPL-3m6es4G0,31035
33 +flask/config.py,sha256=3dejvQRYfNHw_V7dCLMxU8UNFpL34xIKemN7gHZIZ8Y,10052
34 +flask/ctx.py,sha256=cks-omGedkxawHFo6bKIrdOHsJCAgg1i_NWw_htxb5U,16724
35 +flask/debughelpers.py,sha256=-whvPKuAoU8AZ9c1z_INuOeBgfYDqE1J2xNBsoriugU,6475
36 +flask/globals.py,sha256=OgcHb6_NCyX6-TldciOdKcyj4PNfyQwClxdMhvov6aA,1637
37 +flask/helpers.py,sha256=IHa578HU_3XAAo1wpXQv24MYRYO5TzaiDQQwvUIcE6Q,43074
38 +flask/json/__init__.py,sha256=6nITbZYiYOPB8Qfi1-dvsblwn01KRz8VOsMBIZyaYek,11988
39 +flask/json/__pycache__/__init__.cpython-37.pyc,,
40 +flask/json/__pycache__/tag.cpython-37.pyc,,
41 +flask/json/tag.py,sha256=vq9GOllg_0kTWKuVFrwmkeOQzR-jdBD23x-89JyCCQI,8306
42 +flask/logging.py,sha256=WcY5UkqTysGfmosyygSlXyZYGwOp3y-VsE6ehoJ48dk,3250
43 +flask/sessions.py,sha256=G0KsEkr_i1LG_wOINwFSOW3ts7Xbv4bNgEZKc7TRloc,14360
44 +flask/signals.py,sha256=yYLOed2x8WnQ7pirGalQYfpYpCILJ0LJhmNSrnWvjqw,2212
45 +flask/templating.py,sha256=F8E_IZXn9BGsjMzUJ5N_ACMyZdiFBp_SSEaUunvfZ7g,4939
46 +flask/testing.py,sha256=WXsciCQbHBP7xjHqNvOA4bT0k86GvSNpgzncfXLDEEg,10146
47 +flask/views.py,sha256=eeWnadLAj0QdQPLtjKipDetRZyG62CT2y7fNOFDJz0g,5802
48 +flask/wrappers.py,sha256=kgsvtZuMM6RQaDqhRbc5Pcj9vqTnaERl2pmXcdGL7LU,4736
1 +Wheel-Version: 1.0
2 +Generator: bdist_wheel (0.33.6)
3 +Root-Is-Purelib: true
4 +Tag: py2-none-any
5 +Tag: py3-none-any
6 +
1 +Copyright 2007 Pallets
2 +
3 +Redistribution and use in source and binary forms, with or without
4 +modification, are permitted provided that the following conditions are
5 +met:
6 +
7 +1. Redistributions of source code must retain the above copyright
8 + notice, this list of conditions and the following disclaimer.
9 +
10 +2. Redistributions in binary form must reproduce the above copyright
11 + notice, this list of conditions and the following disclaimer in the
12 + documentation and/or other materials provided with the distribution.
13 +
14 +3. Neither the name of the copyright holder nor the names of its
15 + contributors may be used to endorse or promote products derived from
16 + this software without specific prior written permission.
17 +
18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 +Metadata-Version: 2.1
2 +Name: Jinja2
3 +Version: 2.11.2
4 +Summary: A very fast and expressive template engine.
5 +Home-page: https://palletsprojects.com/p/jinja/
6 +Author: Armin Ronacher
7 +Author-email: armin.ronacher@active-4.com
8 +Maintainer: Pallets
9 +Maintainer-email: contact@palletsprojects.com
10 +License: BSD-3-Clause
11 +Project-URL: Documentation, https://jinja.palletsprojects.com/
12 +Project-URL: Code, https://github.com/pallets/jinja
13 +Project-URL: Issue tracker, https://github.com/pallets/jinja/issues
14 +Platform: UNKNOWN
15 +Classifier: Development Status :: 5 - Production/Stable
16 +Classifier: Environment :: Web Environment
17 +Classifier: Intended Audience :: Developers
18 +Classifier: License :: OSI Approved :: BSD License
19 +Classifier: Operating System :: OS Independent
20 +Classifier: Programming Language :: Python
21 +Classifier: Programming Language :: Python :: 2
22 +Classifier: Programming Language :: Python :: 2.7
23 +Classifier: Programming Language :: Python :: 3
24 +Classifier: Programming Language :: Python :: 3.5
25 +Classifier: Programming Language :: Python :: 3.6
26 +Classifier: Programming Language :: Python :: 3.7
27 +Classifier: Programming Language :: Python :: 3.8
28 +Classifier: Programming Language :: Python :: Implementation :: CPython
29 +Classifier: Programming Language :: Python :: Implementation :: PyPy
30 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
31 +Classifier: Topic :: Software Development :: Libraries :: Python Modules
32 +Classifier: Topic :: Text Processing :: Markup :: HTML
33 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
34 +Description-Content-Type: text/x-rst
35 +Requires-Dist: MarkupSafe (>=0.23)
36 +Provides-Extra: i18n
37 +Requires-Dist: Babel (>=0.8) ; extra == 'i18n'
38 +
39 +Jinja
40 +=====
41 +
42 +Jinja is a fast, expressive, extensible templating engine. Special
43 +placeholders in the template allow writing code similar to Python
44 +syntax. Then the template is passed data to render the final document.
45 +
46 +It includes:
47 +
48 +- Template inheritance and inclusion.
49 +- Define and import macros within templates.
50 +- HTML templates can use autoescaping to prevent XSS from untrusted
51 + user input.
52 +- A sandboxed environment can safely render untrusted templates.
53 +- AsyncIO support for generating templates and calling async
54 + functions.
55 +- I18N support with Babel.
56 +- Templates are compiled to optimized Python code just-in-time and
57 + cached, or can be compiled ahead-of-time.
58 +- Exceptions point to the correct line in templates to make debugging
59 + easier.
60 +- Extensible filters, tests, functions, and even syntax.
61 +
62 +Jinja's philosophy is that while application logic belongs in Python if
63 +possible, it shouldn't make the template designer's job difficult by
64 +restricting functionality too much.
65 +
66 +
67 +Installing
68 +----------
69 +
70 +Install and update using `pip`_:
71 +
72 +.. code-block:: text
73 +
74 + $ pip install -U Jinja2
75 +
76 +.. _pip: https://pip.pypa.io/en/stable/quickstart/
77 +
78 +
79 +In A Nutshell
80 +-------------
81 +
82 +.. code-block:: jinja
83 +
84 + {% extends "base.html" %}
85 + {% block title %}Members{% endblock %}
86 + {% block content %}
87 + <ul>
88 + {% for user in users %}
89 + <li><a href="{{ user.url }}">{{ user.username }}</a></li>
90 + {% endfor %}
91 + </ul>
92 + {% endblock %}
93 +
94 +
95 +Links
96 +-----
97 +
98 +- Website: https://palletsprojects.com/p/jinja/
99 +- Documentation: https://jinja.palletsprojects.com/
100 +- Releases: https://pypi.org/project/Jinja2/
101 +- Code: https://github.com/pallets/jinja
102 +- Issue tracker: https://github.com/pallets/jinja/issues
103 +- Test status: https://dev.azure.com/pallets/jinja/_build
104 +- Official chat: https://discord.gg/t6rrQZH
105 +
106 +
1 +Jinja2-2.11.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2 +Jinja2-2.11.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475
3 +Jinja2-2.11.2.dist-info/METADATA,sha256=5ZHRZoIRAMHsJPnqhlJ622_dRPsYePYJ-9EH4-Ry7yI,3535
4 +Jinja2-2.11.2.dist-info/RECORD,,
5 +Jinja2-2.11.2.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110
6 +Jinja2-2.11.2.dist-info/entry_points.txt,sha256=Qy_DkVo6Xj_zzOtmErrATe8lHZhOqdjpt3e4JJAGyi8,61
7 +Jinja2-2.11.2.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7
8 +jinja2/__init__.py,sha256=0QCM_jKKDM10yzSdHRVV4mQbCbDqf0GN0GirAqibn9Y,1549
9 +jinja2/__pycache__/__init__.cpython-37.pyc,,
10 +jinja2/__pycache__/_compat.cpython-37.pyc,,
11 +jinja2/__pycache__/_identifier.cpython-37.pyc,,
12 +jinja2/__pycache__/asyncfilters.cpython-37.pyc,,
13 +jinja2/__pycache__/asyncsupport.cpython-37.pyc,,
14 +jinja2/__pycache__/bccache.cpython-37.pyc,,
15 +jinja2/__pycache__/compiler.cpython-37.pyc,,
16 +jinja2/__pycache__/constants.cpython-37.pyc,,
17 +jinja2/__pycache__/debug.cpython-37.pyc,,
18 +jinja2/__pycache__/defaults.cpython-37.pyc,,
19 +jinja2/__pycache__/environment.cpython-37.pyc,,
20 +jinja2/__pycache__/exceptions.cpython-37.pyc,,
21 +jinja2/__pycache__/ext.cpython-37.pyc,,
22 +jinja2/__pycache__/filters.cpython-37.pyc,,
23 +jinja2/__pycache__/idtracking.cpython-37.pyc,,
24 +jinja2/__pycache__/lexer.cpython-37.pyc,,
25 +jinja2/__pycache__/loaders.cpython-37.pyc,,
26 +jinja2/__pycache__/meta.cpython-37.pyc,,
27 +jinja2/__pycache__/nativetypes.cpython-37.pyc,,
28 +jinja2/__pycache__/nodes.cpython-37.pyc,,
29 +jinja2/__pycache__/optimizer.cpython-37.pyc,,
30 +jinja2/__pycache__/parser.cpython-37.pyc,,
31 +jinja2/__pycache__/runtime.cpython-37.pyc,,
32 +jinja2/__pycache__/sandbox.cpython-37.pyc,,
33 +jinja2/__pycache__/tests.cpython-37.pyc,,
34 +jinja2/__pycache__/utils.cpython-37.pyc,,
35 +jinja2/__pycache__/visitor.cpython-37.pyc,,
36 +jinja2/_compat.py,sha256=B6Se8HjnXVpzz9-vfHejn-DV2NjaVK-Iewupc5kKlu8,3191
37 +jinja2/_identifier.py,sha256=EdgGJKi7O1yvr4yFlvqPNEqV6M1qHyQr8Gt8GmVTKVM,1775
38 +jinja2/asyncfilters.py,sha256=XJtYXTxFvcJ5xwk6SaDL4S0oNnT0wPYvXBCSzc482fI,4250
39 +jinja2/asyncsupport.py,sha256=ZBFsDLuq3Gtji3Ia87lcyuDbqaHZJRdtShZcqwpFnSQ,7209
40 +jinja2/bccache.py,sha256=3Pmp4jo65M9FQuIxdxoDBbEDFwe4acDMQf77nEJfrHA,12139
41 +jinja2/compiler.py,sha256=Ta9W1Lit542wItAHXlDcg0sEOsFDMirCdlFPHAurg4o,66284
42 +jinja2/constants.py,sha256=RR1sTzNzUmKco6aZicw4JpQpJGCuPuqm1h1YmCNUEFY,1458
43 +jinja2/debug.py,sha256=neR7GIGGjZH3_ILJGVUYy3eLQCCaWJMXOb7o0kGInWc,8529
44 +jinja2/defaults.py,sha256=85B6YUUCyWPSdrSeVhcqFVuu_bHUAQXeey--FIwSeVQ,1126
45 +jinja2/environment.py,sha256=XDSLKc4SqNLMOwTSq3TbWEyA5WyXfuLuVD0wAVjEFwM,50629
46 +jinja2/exceptions.py,sha256=VjNLawcmf2ODffqVMCQK1cRmvFaUfQWF4u8ouP3QPcE,5425
47 +jinja2/ext.py,sha256=AtwL5O5enT_L3HR9-oBvhGyUTdGoyaqG_ICtnR_EVd4,26441
48 +jinja2/filters.py,sha256=_RpPgAlgIj7ExvyDzcHAC3B36cocfWK-1TEketbNeM0,41415
49 +jinja2/idtracking.py,sha256=J3O4VHsrbf3wzwiBc7Cro26kHb6_5kbULeIOzocchIU,9211
50 +jinja2/lexer.py,sha256=nUFLRKhhKmmEWkLI65nQePgcQs7qsRdjVYZETMt_v0g,30331
51 +jinja2/loaders.py,sha256=C-fST_dmFjgWkp0ZuCkrgICAoOsoSIF28wfAFink0oU,17666
52 +jinja2/meta.py,sha256=QjyYhfNRD3QCXjBJpiPl9KgkEkGXJbAkCUq4-Ur10EQ,4131
53 +jinja2/nativetypes.py,sha256=Ul__gtVw4xH-0qvUvnCNHedQeNDwmEuyLJztzzSPeRg,2753
54 +jinja2/nodes.py,sha256=Mk1oJPVgIjnQw9WOqILvcu3rLepcFZ0ahxQm2mbwDwc,31095
55 +jinja2/optimizer.py,sha256=gQLlMYzvQhluhzmAIFA1tXS0cwgWYOjprN-gTRcHVsc,1457
56 +jinja2/parser.py,sha256=fcfdqePNTNyvosIvczbytVA332qpsURvYnCGcjDHSkA,35660
57 +jinja2/runtime.py,sha256=0y-BRyIEZ9ltByL2Id6GpHe1oDRQAwNeQvI0SKobNMw,30618
58 +jinja2/sandbox.py,sha256=knayyUvXsZ-F0mk15mO2-ehK9gsw04UhB8td-iUOtLc,17127
59 +jinja2/tests.py,sha256=iO_Y-9Vo60zrVe1lMpSl5sKHqAxe2leZHC08OoZ8K24,4799
60 +jinja2/utils.py,sha256=OoVMlQe9S2-lWT6jJbTu9tDuDvGNyWUhHDcE51i5_Do,22522
61 +jinja2/visitor.py,sha256=DUHupl0a4PGp7nxRtZFttUzAi1ccxzqc2hzetPYUz8U,3240
1 +Wheel-Version: 1.0
2 +Generator: bdist_wheel (0.34.2)
3 +Root-Is-Purelib: true
4 +Tag: py2-none-any
5 +Tag: py3-none-any
6 +
1 +[babel.extractors]
2 +jinja2 = jinja2.ext:babel_extract [i18n]
3 +
1 +Copyright 2010 Pallets
2 +
3 +Redistribution and use in source and binary forms, with or without
4 +modification, are permitted provided that the following conditions are
5 +met:
6 +
7 +1. Redistributions of source code must retain the above copyright
8 + notice, this list of conditions and the following disclaimer.
9 +
10 +2. Redistributions in binary form must reproduce the above copyright
11 + notice, this list of conditions and the following disclaimer in the
12 + documentation and/or other materials provided with the distribution.
13 +
14 +3. Neither the name of the copyright holder nor the names of its
15 + contributors may be used to endorse or promote products derived from
16 + this software without specific prior written permission.
17 +
18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 +Metadata-Version: 2.1
2 +Name: MarkupSafe
3 +Version: 1.1.1
4 +Summary: Safely add untrusted strings to HTML/XML markup.
5 +Home-page: https://palletsprojects.com/p/markupsafe/
6 +Author: Armin Ronacher
7 +Author-email: armin.ronacher@active-4.com
8 +Maintainer: The Pallets Team
9 +Maintainer-email: contact@palletsprojects.com
10 +License: BSD-3-Clause
11 +Project-URL: Documentation, https://markupsafe.palletsprojects.com/
12 +Project-URL: Code, https://github.com/pallets/markupsafe
13 +Project-URL: Issue tracker, https://github.com/pallets/markupsafe/issues
14 +Platform: UNKNOWN
15 +Classifier: Development Status :: 5 - Production/Stable
16 +Classifier: Environment :: Web Environment
17 +Classifier: Intended Audience :: Developers
18 +Classifier: License :: OSI Approved :: BSD License
19 +Classifier: Operating System :: OS Independent
20 +Classifier: Programming Language :: Python
21 +Classifier: Programming Language :: Python :: 2
22 +Classifier: Programming Language :: Python :: 2.7
23 +Classifier: Programming Language :: Python :: 3
24 +Classifier: Programming Language :: Python :: 3.4
25 +Classifier: Programming Language :: Python :: 3.5
26 +Classifier: Programming Language :: Python :: 3.6
27 +Classifier: Programming Language :: Python :: 3.7
28 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
29 +Classifier: Topic :: Software Development :: Libraries :: Python Modules
30 +Classifier: Topic :: Text Processing :: Markup :: HTML
31 +Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*
32 +
33 +MarkupSafe
34 +==========
35 +
36 +MarkupSafe implements a text object that escapes characters so it is
37 +safe to use in HTML and XML. Characters that have special meanings are
38 +replaced so that they display as the actual characters. This mitigates
39 +injection attacks, meaning untrusted user input can safely be displayed
40 +on a page.
41 +
42 +
43 +Installing
44 +----------
45 +
46 +Install and update using `pip`_:
47 +
48 +.. code-block:: text
49 +
50 + pip install -U MarkupSafe
51 +
52 +.. _pip: https://pip.pypa.io/en/stable/quickstart/
53 +
54 +
55 +Examples
56 +--------
57 +
58 +.. code-block:: pycon
59 +
60 + >>> from markupsafe import Markup, escape
61 + >>> # escape replaces special characters and wraps in Markup
62 + >>> escape('<script>alert(document.cookie);</script>')
63 + Markup(u'&lt;script&gt;alert(document.cookie);&lt;/script&gt;')
64 + >>> # wrap in Markup to mark text "safe" and prevent escaping
65 + >>> Markup('<strong>Hello</strong>')
66 + Markup('<strong>hello</strong>')
67 + >>> escape(Markup('<strong>Hello</strong>'))
68 + Markup('<strong>hello</strong>')
69 + >>> # Markup is a text subclass (str on Python 3, unicode on Python 2)
70 + >>> # methods and operators escape their arguments
71 + >>> template = Markup("Hello <em>%s</em>")
72 + >>> template % '"World"'
73 + Markup('Hello <em>&#34;World&#34;</em>')
74 +
75 +
76 +Donate
77 +------
78 +
79 +The Pallets organization develops and supports MarkupSafe and other
80 +libraries that use it. In order to grow the community of contributors
81 +and users, and allow the maintainers to devote more time to the
82 +projects, `please donate today`_.
83 +
84 +.. _please donate today: https://palletsprojects.com/donate
85 +
86 +
87 +Links
88 +-----
89 +
90 +* Website: https://palletsprojects.com/p/markupsafe/
91 +* Documentation: https://markupsafe.palletsprojects.com/
92 +* License: `BSD-3-Clause <https://github.com/pallets/markupsafe/blob/master/LICENSE.rst>`_
93 +* Releases: https://pypi.org/project/MarkupSafe/
94 +* Code: https://github.com/pallets/markupsafe
95 +* Issue tracker: https://github.com/pallets/markupsafe/issues
96 +* Test status:
97 +
98 + * Linux, Mac: https://travis-ci.org/pallets/markupsafe
99 + * Windows: https://ci.appveyor.com/project/pallets/markupsafe
100 +
101 +* Test coverage: https://codecov.io/gh/pallets/markupsafe
102 +
103 +
1 +MarkupSafe-1.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2 +MarkupSafe-1.1.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475
3 +MarkupSafe-1.1.1.dist-info/METADATA,sha256=nJHwJ4_4ka-V39QH883jPrslj6inNdyyNASBXbYgHXQ,3570
4 +MarkupSafe-1.1.1.dist-info/RECORD,,
5 +MarkupSafe-1.1.1.dist-info/WHEEL,sha256=GMu0CcHnECe7JSPnzBUPyOsrcZoHb7dOBGXgpe8vHSQ,104
6 +MarkupSafe-1.1.1.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11
7 +markupsafe/__init__.py,sha256=oTblO5f9KFM-pvnq9bB0HgElnqkJyqHnFN1Nx2NIvnY,10126
8 +markupsafe/__pycache__/__init__.cpython-37.pyc,,
9 +markupsafe/__pycache__/_compat.cpython-37.pyc,,
10 +markupsafe/__pycache__/_constants.cpython-37.pyc,,
11 +markupsafe/__pycache__/_native.cpython-37.pyc,,
12 +markupsafe/_compat.py,sha256=uEW1ybxEjfxIiuTbRRaJpHsPFf4yQUMMKaPgYEC5XbU,558
13 +markupsafe/_constants.py,sha256=zo2ajfScG-l1Sb_52EP3MlDCqO7Y1BVHUXXKRsVDRNk,4690
14 +markupsafe/_native.py,sha256=d-8S_zzYt2y512xYcuSxq0NeG2DUUvG80wVdTn-4KI8,1873
15 +markupsafe/_speedups.c,sha256=k0fzEIK3CP6MmMqeY0ob43TP90mVN0DTyn7BAl3RqSg,9884
16 +markupsafe/_speedups.cpython-37m-arm-linux-gnueabihf.so,sha256=UdHbkGis1TxK619S8APiKVHwcmcMKsR0rEA9WFeXTUs,46612
1 +Wheel-Version: 1.0
2 +Generator: bdist_wheel (0.32.3)
3 +Root-Is-Purelib: false
4 +Tag: cp37-cp37m-linux_armv7l
5 +
1 +Copyright 2007 Pallets
2 +
3 +Redistribution and use in source and binary forms, with or without
4 +modification, are permitted provided that the following conditions are
5 +met:
6 +
7 +1. Redistributions of source code must retain the above copyright
8 + notice, this list of conditions and the following disclaimer.
9 +
10 +2. Redistributions in binary form must reproduce the above copyright
11 + notice, this list of conditions and the following disclaimer in the
12 + documentation and/or other materials provided with the distribution.
13 +
14 +3. Neither the name of the copyright holder nor the names of its
15 + contributors may be used to endorse or promote products derived from
16 + this software without specific prior written permission.
17 +
18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 +Metadata-Version: 2.1
2 +Name: Werkzeug
3 +Version: 1.0.1
4 +Summary: The comprehensive WSGI web application library.
5 +Home-page: https://palletsprojects.com/p/werkzeug/
6 +Author: Armin Ronacher
7 +Author-email: armin.ronacher@active-4.com
8 +Maintainer: Pallets
9 +Maintainer-email: contact@palletsprojects.com
10 +License: BSD-3-Clause
11 +Project-URL: Documentation, https://werkzeug.palletsprojects.com/
12 +Project-URL: Code, https://github.com/pallets/werkzeug
13 +Project-URL: Issue tracker, https://github.com/pallets/werkzeug/issues
14 +Platform: UNKNOWN
15 +Classifier: Development Status :: 5 - Production/Stable
16 +Classifier: Environment :: Web Environment
17 +Classifier: Intended Audience :: Developers
18 +Classifier: License :: OSI Approved :: BSD License
19 +Classifier: Operating System :: OS Independent
20 +Classifier: Programming Language :: Python
21 +Classifier: Programming Language :: Python :: 2
22 +Classifier: Programming Language :: Python :: 2.7
23 +Classifier: Programming Language :: Python :: 3
24 +Classifier: Programming Language :: Python :: 3.5
25 +Classifier: Programming Language :: Python :: 3.6
26 +Classifier: Programming Language :: Python :: 3.7
27 +Classifier: Programming Language :: Python :: 3.8
28 +Classifier: Programming Language :: Python :: Implementation :: CPython
29 +Classifier: Programming Language :: Python :: Implementation :: PyPy
30 +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
31 +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
32 +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
33 +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware
34 +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
35 +Classifier: Topic :: Software Development :: Libraries :: Python Modules
36 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
37 +Description-Content-Type: text/x-rst
38 +Provides-Extra: dev
39 +Requires-Dist: pytest ; extra == 'dev'
40 +Requires-Dist: pytest-timeout ; extra == 'dev'
41 +Requires-Dist: coverage ; extra == 'dev'
42 +Requires-Dist: tox ; extra == 'dev'
43 +Requires-Dist: sphinx ; extra == 'dev'
44 +Requires-Dist: pallets-sphinx-themes ; extra == 'dev'
45 +Requires-Dist: sphinx-issues ; extra == 'dev'
46 +Provides-Extra: watchdog
47 +Requires-Dist: watchdog ; extra == 'watchdog'
48 +
49 +Werkzeug
50 +========
51 +
52 +*werkzeug* German noun: "tool". Etymology: *werk* ("work"), *zeug* ("stuff")
53 +
54 +Werkzeug is a comprehensive `WSGI`_ web application library. It began as
55 +a simple collection of various utilities for WSGI applications and has
56 +become one of the most advanced WSGI utility libraries.
57 +
58 +It includes:
59 +
60 +- An interactive debugger that allows inspecting stack traces and
61 + source code in the browser with an interactive interpreter for any
62 + frame in the stack.
63 +- A full-featured request object with objects to interact with
64 + headers, query args, form data, files, and cookies.
65 +- A response object that can wrap other WSGI applications and handle
66 + streaming data.
67 +- A routing system for matching URLs to endpoints and generating URLs
68 + for endpoints, with an extensible system for capturing variables
69 + from URLs.
70 +- HTTP utilities to handle entity tags, cache control, dates, user
71 + agents, cookies, files, and more.
72 +- A threaded WSGI server for use while developing applications
73 + locally.
74 +- A test client for simulating HTTP requests during testing without
75 + requiring running a server.
76 +
77 +Werkzeug is Unicode aware and doesn't enforce any dependencies. It is up
78 +to the developer to choose a template engine, database adapter, and even
79 +how to handle requests. It can be used to build all sorts of end user
80 +applications such as blogs, wikis, or bulletin boards.
81 +
82 +`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while
83 +providing more structure and patterns for defining powerful
84 +applications.
85 +
86 +
87 +Installing
88 +----------
89 +
90 +Install and update using `pip`_:
91 +
92 +.. code-block:: text
93 +
94 + pip install -U Werkzeug
95 +
96 +
97 +A Simple Example
98 +----------------
99 +
100 +.. code-block:: python
101 +
102 + from werkzeug.wrappers import Request, Response
103 +
104 + @Request.application
105 + def application(request):
106 + return Response('Hello, World!')
107 +
108 + if __name__ == '__main__':
109 + from werkzeug.serving import run_simple
110 + run_simple('localhost', 4000, application)
111 +
112 +
113 +Links
114 +-----
115 +
116 +- Website: https://palletsprojects.com/p/werkzeug/
117 +- Documentation: https://werkzeug.palletsprojects.com/
118 +- Releases: https://pypi.org/project/Werkzeug/
119 +- Code: https://github.com/pallets/werkzeug
120 +- Issue tracker: https://github.com/pallets/werkzeug/issues
121 +- Test status: https://dev.azure.com/pallets/werkzeug/_build
122 +- Official chat: https://discord.gg/t6rrQZH
123 +
124 +.. _WSGI: https://wsgi.readthedocs.io/en/latest/
125 +.. _Flask: https://www.palletsprojects.com/p/flask/
126 +.. _pip: https://pip.pypa.io/en/stable/quickstart/
127 +
128 +
1 +Werkzeug-1.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2 +Werkzeug-1.0.1.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475
3 +Werkzeug-1.0.1.dist-info/METADATA,sha256=d0zmVNa4UC2-nAo2A8_81oiy123D6JTGRSuY_Ymgyt4,4730
4 +Werkzeug-1.0.1.dist-info/RECORD,,
5 +Werkzeug-1.0.1.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110
6 +Werkzeug-1.0.1.dist-info/top_level.txt,sha256=QRyj2VjwJoQkrwjwFIOlB8Xg3r9un0NtqVHQF-15xaw,9
7 +werkzeug/__init__.py,sha256=rb-yPiXOjTLbtDOl5fQp5hN7oBdaoXAoQ-slAAvfZAo,502
8 +werkzeug/__pycache__/__init__.cpython-37.pyc,,
9 +werkzeug/__pycache__/_compat.cpython-37.pyc,,
10 +werkzeug/__pycache__/_internal.cpython-37.pyc,,
11 +werkzeug/__pycache__/_reloader.cpython-37.pyc,,
12 +werkzeug/__pycache__/datastructures.cpython-37.pyc,,
13 +werkzeug/__pycache__/exceptions.cpython-37.pyc,,
14 +werkzeug/__pycache__/filesystem.cpython-37.pyc,,
15 +werkzeug/__pycache__/formparser.cpython-37.pyc,,
16 +werkzeug/__pycache__/http.cpython-37.pyc,,
17 +werkzeug/__pycache__/local.cpython-37.pyc,,
18 +werkzeug/__pycache__/posixemulation.cpython-37.pyc,,
19 +werkzeug/__pycache__/routing.cpython-37.pyc,,
20 +werkzeug/__pycache__/security.cpython-37.pyc,,
21 +werkzeug/__pycache__/serving.cpython-37.pyc,,
22 +werkzeug/__pycache__/test.cpython-37.pyc,,
23 +werkzeug/__pycache__/testapp.cpython-37.pyc,,
24 +werkzeug/__pycache__/urls.cpython-37.pyc,,
25 +werkzeug/__pycache__/useragents.cpython-37.pyc,,
26 +werkzeug/__pycache__/utils.cpython-37.pyc,,
27 +werkzeug/__pycache__/wsgi.cpython-37.pyc,,
28 +werkzeug/_compat.py,sha256=zjufTNrhQ8BgYSGSh-sVu6iW3r3O9WzjE9j-qJobx-g,6671
29 +werkzeug/_internal.py,sha256=d_4AqheyS6dHMViwdc0drFrjs67ZzT6Ej2gWf-Z-Iys,14351
30 +werkzeug/_reloader.py,sha256=I3mg3oRQ0lLzl06oEoVopN3bN7CtINuuUQdqDcmTnEs,11531
31 +werkzeug/datastructures.py,sha256=AonxOcwU0TPMEzfKF1368ySULxHgxE-JE-DEAGdo2ts,100480
32 +werkzeug/debug/__init__.py,sha256=3RtUMc5Y9hYyK11ugHltgkQ9Dt-ViR945Vy_X5NV7zU,17289
33 +werkzeug/debug/__pycache__/__init__.cpython-37.pyc,,
34 +werkzeug/debug/__pycache__/console.cpython-37.pyc,,
35 +werkzeug/debug/__pycache__/repr.cpython-37.pyc,,
36 +werkzeug/debug/__pycache__/tbtools.cpython-37.pyc,,
37 +werkzeug/debug/console.py,sha256=OATaO7KHYMqpbzIFe1HeW9Mnl3wZgA3jMQoGDPn5URc,5488
38 +werkzeug/debug/repr.py,sha256=lIwuhbyrMwVe3P_cFqNyqzHL7P93TLKod7lw9clydEw,9621
39 +werkzeug/debug/shared/FONT_LICENSE,sha256=LwAVEI1oYnvXiNMT9SnCH_TaLCxCpeHziDrMg0gPkAI,4673
40 +werkzeug/debug/shared/console.png,sha256=bxax6RXXlvOij_KeqvSNX0ojJf83YbnZ7my-3Gx9w2A,507
41 +werkzeug/debug/shared/debugger.js,sha256=rOhqZMRfpZnnu6_XCGn6wMWPhtfwRAcyZKksdIxPJas,6400
42 +werkzeug/debug/shared/jquery.js,sha256=CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo,88145
43 +werkzeug/debug/shared/less.png,sha256=-4-kNRaXJSONVLahrQKUxMwXGm9R4OnZ9SxDGpHlIR4,191
44 +werkzeug/debug/shared/more.png,sha256=GngN7CioHQoV58rH6ojnkYi8c_qED2Aka5FO5UXrReY,200
45 +werkzeug/debug/shared/source.png,sha256=RoGcBTE4CyCB85GBuDGTFlAnUqxwTBiIfDqW15EpnUQ,818
46 +werkzeug/debug/shared/style.css,sha256=gZ9uhmb5zj3XLuT9RvnMp6jMINgQ-VVBCp-2AZbG3YQ,6604
47 +werkzeug/debug/shared/ubuntu.ttf,sha256=1eaHFyepmy4FyDvjLVzpITrGEBu_CZYY94jE0nED1c0,70220
48 +werkzeug/debug/tbtools.py,sha256=2iJ8RURUZUSbopOIehy53LnVJWx47lsHN2V2l6hc7Wc,20363
49 +werkzeug/exceptions.py,sha256=UTYSDkmAsH-vt8VSidlEffwqBVNXuT7bRg-_NqgUe8A,25188
50 +werkzeug/filesystem.py,sha256=HzKl-j0Hd8Jl66j778UbPTAYNnY6vUZgYLlBZ0e7uw0,2101
51 +werkzeug/formparser.py,sha256=Sto0jZid9im9ZVIf56vilCdyX-arK33wSftkYsLCnzo,21788
52 +werkzeug/http.py,sha256=KVRV3yFK14PJeI56qClEq4qxFdvKUQVy4C_dwuWz9_Q,43107
53 +werkzeug/local.py,sha256=_Tk7gB238pPWUU7habxFkZF02fiCMRVW6d62YWL1Rh0,14371
54 +werkzeug/middleware/__init__.py,sha256=f1SFZo67IlW4k1uqKzNHxYQlsakUS-D6KK_j0e3jjwQ,549
55 +werkzeug/middleware/__pycache__/__init__.cpython-37.pyc,,
56 +werkzeug/middleware/__pycache__/dispatcher.cpython-37.pyc,,
57 +werkzeug/middleware/__pycache__/http_proxy.cpython-37.pyc,,
58 +werkzeug/middleware/__pycache__/lint.cpython-37.pyc,,
59 +werkzeug/middleware/__pycache__/profiler.cpython-37.pyc,,
60 +werkzeug/middleware/__pycache__/proxy_fix.cpython-37.pyc,,
61 +werkzeug/middleware/__pycache__/shared_data.cpython-37.pyc,,
62 +werkzeug/middleware/dispatcher.py,sha256=_-KoMzHtcISHS7ouWKAOraqlCLprdh83YOAn_8DjLp8,2240
63 +werkzeug/middleware/http_proxy.py,sha256=lRjTdMmghHiZuZrS7_UJ3gZc-vlFizhBbFZ-XZPLwIA,7117
64 +werkzeug/middleware/lint.py,sha256=ItTwuWJnflF8xMT1uqU_Ty1ryhux-CjeUfskqaUpxsw,12967
65 +werkzeug/middleware/profiler.py,sha256=8B_s23d6BGrU_q54gJsm6kcCbOJbTSqrXCsioHON0Xs,4471
66 +werkzeug/middleware/proxy_fix.py,sha256=K5oZ3DPXOzdZi0Xba5zW7ClPOxgUuqXHQHvY2-AWCGw,6431
67 +werkzeug/middleware/shared_data.py,sha256=sPSRTKqtKSVBUyN8fr6jOJbdq9cdOLu6pg3gz4Y_1Xo,9599
68 +werkzeug/posixemulation.py,sha256=gSSiv1SCmOyzOM_nq1ZaZCtxP__C5MeDJl_4yXJmi4Q,3541
69 +werkzeug/routing.py,sha256=6-iZ7CKeUILYAehoKXLbmi5E6LgLbwuzUh8TNplnf5Q,79019
70 +werkzeug/security.py,sha256=81149MplFq7-hD4RK4sKp9kzXXejjV9D4lWBzaRyeQ8,8106
71 +werkzeug/serving.py,sha256=YvTqvurA-Mnj8mkqRe2kBdVr2ap4ibCq1ByQjOA6g1w,38694
72 +werkzeug/test.py,sha256=GJ9kxTMSJ-nB7kfGtxuROr9JGmXxDRev-2U1SkeUJGE,39564
73 +werkzeug/testapp.py,sha256=bHekqMsqRfVxwgFbvOMem-DYa_sdB7R47yUXpt1RUTo,9329
74 +werkzeug/urls.py,sha256=T8-hV_1vwhu6xhX93FwsHteK-W-kIE2orj5WoMf-WFw,39322
75 +werkzeug/useragents.py,sha256=TSoGv5IOvP375eK5gLLpsLQCeUgTR6sO1WftmAP_YvM,5563
76 +werkzeug/utils.py,sha256=hrVK4u_wi8z9viBO9bgOLlm1aaIvCpn-p2d1FeZQDEo,25251
77 +werkzeug/wrappers/__init__.py,sha256=S4VioKAmF_av9Ec9zQvG71X1EOkYfPx1TYck9jyDiyY,1384
78 +werkzeug/wrappers/__pycache__/__init__.cpython-37.pyc,,
79 +werkzeug/wrappers/__pycache__/accept.cpython-37.pyc,,
80 +werkzeug/wrappers/__pycache__/auth.cpython-37.pyc,,
81 +werkzeug/wrappers/__pycache__/base_request.cpython-37.pyc,,
82 +werkzeug/wrappers/__pycache__/base_response.cpython-37.pyc,,
83 +werkzeug/wrappers/__pycache__/common_descriptors.cpython-37.pyc,,
84 +werkzeug/wrappers/__pycache__/cors.cpython-37.pyc,,
85 +werkzeug/wrappers/__pycache__/etag.cpython-37.pyc,,
86 +werkzeug/wrappers/__pycache__/json.cpython-37.pyc,,
87 +werkzeug/wrappers/__pycache__/request.cpython-37.pyc,,
88 +werkzeug/wrappers/__pycache__/response.cpython-37.pyc,,
89 +werkzeug/wrappers/__pycache__/user_agent.cpython-37.pyc,,
90 +werkzeug/wrappers/accept.py,sha256=TIvjUc0g73fhTWX54wg_D9NNzKvpnG1X8u1w26tK1o8,1760
91 +werkzeug/wrappers/auth.py,sha256=Pmn6iaGHBrUyHbJpW0lZhO_q9RVoAa5QalaTqcavdAI,1158
92 +werkzeug/wrappers/base_request.py,sha256=4TuGlKWeKQdlq4eU94hJYcXSfWo8Rk7CS1Ef5lJ3ZM0,26012
93 +werkzeug/wrappers/base_response.py,sha256=JTxJZ8o-IBetpoWJqt2HFwPaNWNDAlM3_GXJe1Whw80,27784
94 +werkzeug/wrappers/common_descriptors.py,sha256=X2Ktd5zUWsmcd4ciaF62Dd8Lru9pLGP_XDUNukc8cXs,12829
95 +werkzeug/wrappers/cors.py,sha256=XMbaCol4dWTGvb-dCJBoN0p3JX91v93AIAHd7tnB3L4,3466
96 +werkzeug/wrappers/etag.py,sha256=XMXtyfByBsOjxwaX8U7ZtUY7JXkbQLP45oXZ0qkyTNs,12217
97 +werkzeug/wrappers/json.py,sha256=HvK_A4NpO0sLqgb10sTJcoZydYOwyNiPCJPV7SVgcgE,4343
98 +werkzeug/wrappers/request.py,sha256=QbHGqDpGPN684pnOPEokwkPESfm-NnfYM7ydOMxW_NI,1514
99 +werkzeug/wrappers/response.py,sha256=Oqv8TMG_dnOKTq_V30ddgkO5B7IJhkVPODvm7cbhZ3c,2524
100 +werkzeug/wrappers/user_agent.py,sha256=YJb-vr12cujG7sQMG9V89VsJa-03SWSenhg1W4cT0EY,435
101 +werkzeug/wsgi.py,sha256=ZGk85NzRyQTzkYis-xl8V9ydJgfClBdStvhzDzER2mw,34367
1 +Wheel-Version: 1.0
2 +Generator: bdist_wheel (0.34.2)
3 +Root-Is-Purelib: true
4 +Tag: py2-none-any
5 +Tag: py3-none-any
6 +
1 +Copyright 2014 Pallets
2 +
3 +Redistribution and use in source and binary forms, with or without
4 +modification, are permitted provided that the following conditions are
5 +met:
6 +
7 +1. Redistributions of source code must retain the above copyright
8 + notice, this list of conditions and the following disclaimer.
9 +
10 +2. Redistributions in binary form must reproduce the above copyright
11 + notice, this list of conditions and the following disclaimer in the
12 + documentation and/or other materials provided with the distribution.
13 +
14 +3. Neither the name of the copyright holder nor the names of its
15 + contributors may be used to endorse or promote products derived from
16 + this software without specific prior written permission.
17 +
18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 +Metadata-Version: 2.1
2 +Name: click
3 +Version: 7.1.2
4 +Summary: Composable command line interface toolkit
5 +Home-page: https://palletsprojects.com/p/click/
6 +Maintainer: Pallets
7 +Maintainer-email: contact@palletsprojects.com
8 +License: BSD-3-Clause
9 +Project-URL: Documentation, https://click.palletsprojects.com/
10 +Project-URL: Code, https://github.com/pallets/click
11 +Project-URL: Issue tracker, https://github.com/pallets/click/issues
12 +Platform: UNKNOWN
13 +Classifier: Development Status :: 5 - Production/Stable
14 +Classifier: Intended Audience :: Developers
15 +Classifier: License :: OSI Approved :: BSD License
16 +Classifier: Operating System :: OS Independent
17 +Classifier: Programming Language :: Python
18 +Classifier: Programming Language :: Python :: 2
19 +Classifier: Programming Language :: Python :: 3
20 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
21 +
22 +\$ click\_
23 +==========
24 +
25 +Click is a Python package for creating beautiful command line interfaces
26 +in a composable way with as little code as necessary. It's the "Command
27 +Line Interface Creation Kit". It's highly configurable but comes with
28 +sensible defaults out of the box.
29 +
30 +It aims to make the process of writing command line tools quick and fun
31 +while also preventing any frustration caused by the inability to
32 +implement an intended CLI API.
33 +
34 +Click in three points:
35 +
36 +- Arbitrary nesting of commands
37 +- Automatic help page generation
38 +- Supports lazy loading of subcommands at runtime
39 +
40 +
41 +Installing
42 +----------
43 +
44 +Install and update using `pip`_:
45 +
46 +.. code-block:: text
47 +
48 + $ pip install -U click
49 +
50 +.. _pip: https://pip.pypa.io/en/stable/quickstart/
51 +
52 +
53 +A Simple Example
54 +----------------
55 +
56 +.. code-block:: python
57 +
58 + import click
59 +
60 + @click.command()
61 + @click.option("--count", default=1, help="Number of greetings.")
62 + @click.option("--name", prompt="Your name", help="The person to greet.")
63 + def hello(count, name):
64 + """Simple program that greets NAME for a total of COUNT times."""
65 + for _ in range(count):
66 + click.echo(f"Hello, {name}!")
67 +
68 + if __name__ == '__main__':
69 + hello()
70 +
71 +.. code-block:: text
72 +
73 + $ python hello.py --count=3
74 + Your name: Click
75 + Hello, Click!
76 + Hello, Click!
77 + Hello, Click!
78 +
79 +
80 +Donate
81 +------
82 +
83 +The Pallets organization develops and supports Click and other popular
84 +packages. In order to grow the community of contributors and users, and
85 +allow the maintainers to devote more time to the projects, `please
86 +donate today`_.
87 +
88 +.. _please donate today: https://palletsprojects.com/donate
89 +
90 +
91 +Links
92 +-----
93 +
94 +- Website: https://palletsprojects.com/p/click/
95 +- Documentation: https://click.palletsprojects.com/
96 +- Releases: https://pypi.org/project/click/
97 +- Code: https://github.com/pallets/click
98 +- Issue tracker: https://github.com/pallets/click/issues
99 +- Test status: https://dev.azure.com/pallets/click/_build
100 +- Official chat: https://discord.gg/t6rrQZH
101 +
102 +
1 +click-7.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2 +click-7.1.2.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475
3 +click-7.1.2.dist-info/METADATA,sha256=LrRgakZKV7Yg3qJqX_plu2WhFW81MzP3EqQmZhHIO8M,2868
4 +click-7.1.2.dist-info/RECORD,,
5 +click-7.1.2.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110
6 +click-7.1.2.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6
7 +click/__init__.py,sha256=FkyGDQ-cbiQxP_lxgUspyFYS48f2S_pTcfKPz-d_RMo,2463
8 +click/__pycache__/__init__.cpython-37.pyc,,
9 +click/__pycache__/_bashcomplete.cpython-37.pyc,,
10 +click/__pycache__/_compat.cpython-37.pyc,,
11 +click/__pycache__/_termui_impl.cpython-37.pyc,,
12 +click/__pycache__/_textwrap.cpython-37.pyc,,
13 +click/__pycache__/_unicodefun.cpython-37.pyc,,
14 +click/__pycache__/_winconsole.cpython-37.pyc,,
15 +click/__pycache__/core.cpython-37.pyc,,
16 +click/__pycache__/decorators.cpython-37.pyc,,
17 +click/__pycache__/exceptions.cpython-37.pyc,,
18 +click/__pycache__/formatting.cpython-37.pyc,,
19 +click/__pycache__/globals.cpython-37.pyc,,
20 +click/__pycache__/parser.cpython-37.pyc,,
21 +click/__pycache__/termui.cpython-37.pyc,,
22 +click/__pycache__/testing.cpython-37.pyc,,
23 +click/__pycache__/types.cpython-37.pyc,,
24 +click/__pycache__/utils.cpython-37.pyc,,
25 +click/_bashcomplete.py,sha256=9J98IHQYmCAr2Jup6TDshUr5FJEen-AoQCZR0K5nKxQ,12309
26 +click/_compat.py,sha256=AoMaYnZ-3pwtNXuHtlb6_UXsayoG0QZiHKIRy2VFezc,24169
27 +click/_termui_impl.py,sha256=yNktUMAdjYOU1HMkq915jR3zgAzUNtGSQqSTSSMn3eQ,20702
28 +click/_textwrap.py,sha256=ajCzkzFly5tjm9foQ5N9_MOeaYJMBjAltuFa69n4iXY,1197
29 +click/_unicodefun.py,sha256=apLSNEBZgUsQNPMUv072zJ1swqnm0dYVT5TqcIWTt6w,4201
30 +click/_winconsole.py,sha256=6YDu6Rq1Wxx4w9uinBMK2LHvP83aerZM9GQurlk3QDo,10010
31 +click/core.py,sha256=V6DJzastGhrC6WTDwV9MSLwcJUdX2Uf1ypmgkjBdn_Y,77650
32 +click/decorators.py,sha256=3TvEO_BkaHl7k6Eh1G5eC7JK4LKPdpFqH9JP0QDyTlM,11215
33 +click/exceptions.py,sha256=3pQAyyMFzx5A3eV0Y27WtDTyGogZRbrC6_o5DjjKBbw,8118
34 +click/formatting.py,sha256=Wb4gqFEpWaKPgAbOvnkCl8p-bEZx5KpM5ZSByhlnJNk,9281
35 +click/globals.py,sha256=ht7u2kUGI08pAarB4e4yC8Lkkxy6gJfRZyzxEj8EbWQ,1501
36 +click/parser.py,sha256=mFK-k58JtPpqO0AC36WAr0t5UfzEw1mvgVSyn7WCe9M,15691
37 +click/termui.py,sha256=G7QBEKIepRIGLvNdGwBTYiEtSImRxvTO_AglVpyHH2s,23998
38 +click/testing.py,sha256=EUEsDUqNXFgCLhZ0ZFOROpaVDA5I_rijwnNPE6qICgA,12854
39 +click/types.py,sha256=wuubik4VqgqAw5dvbYFkDt-zSAx97y9TQXuXcVaRyQA,25045
40 +click/utils.py,sha256=4VEcJ7iEHwjnFuzEuRtkT99o5VG3zqSD7Q2CVzv13WU,15940
1 +Wheel-Version: 1.0
2 +Generator: bdist_wheel (0.34.2)
3 +Root-Is-Purelib: true
4 +Tag: py2-none-any
5 +Tag: py3-none-any
6 +
1 +"""
2 +Click is a simple Python module inspired by the stdlib optparse to make
3 +writing command line scripts fun. Unlike other modules, it's based
4 +around a simple API that does not come with too much magic and is
5 +composable.
6 +"""
7 +from .core import Argument
8 +from .core import BaseCommand
9 +from .core import Command
10 +from .core import CommandCollection
11 +from .core import Context
12 +from .core import Group
13 +from .core import MultiCommand
14 +from .core import Option
15 +from .core import Parameter
16 +from .decorators import argument
17 +from .decorators import command
18 +from .decorators import confirmation_option
19 +from .decorators import group
20 +from .decorators import help_option
21 +from .decorators import make_pass_decorator
22 +from .decorators import option
23 +from .decorators import pass_context
24 +from .decorators import pass_obj
25 +from .decorators import password_option
26 +from .decorators import version_option
27 +from .exceptions import Abort
28 +from .exceptions import BadArgumentUsage
29 +from .exceptions import BadOptionUsage
30 +from .exceptions import BadParameter
31 +from .exceptions import ClickException
32 +from .exceptions import FileError
33 +from .exceptions import MissingParameter
34 +from .exceptions import NoSuchOption
35 +from .exceptions import UsageError
36 +from .formatting import HelpFormatter
37 +from .formatting import wrap_text
38 +from .globals import get_current_context
39 +from .parser import OptionParser
40 +from .termui import clear
41 +from .termui import confirm
42 +from .termui import echo_via_pager
43 +from .termui import edit
44 +from .termui import get_terminal_size
45 +from .termui import getchar
46 +from .termui import launch
47 +from .termui import pause
48 +from .termui import progressbar
49 +from .termui import prompt
50 +from .termui import secho
51 +from .termui import style
52 +from .termui import unstyle
53 +from .types import BOOL
54 +from .types import Choice
55 +from .types import DateTime
56 +from .types import File
57 +from .types import FLOAT
58 +from .types import FloatRange
59 +from .types import INT
60 +from .types import IntRange
61 +from .types import ParamType
62 +from .types import Path
63 +from .types import STRING
64 +from .types import Tuple
65 +from .types import UNPROCESSED
66 +from .types import UUID
67 +from .utils import echo
68 +from .utils import format_filename
69 +from .utils import get_app_dir
70 +from .utils import get_binary_stream
71 +from .utils import get_os_args
72 +from .utils import get_text_stream
73 +from .utils import open_file
74 +
75 +# Controls if click should emit the warning about the use of unicode
76 +# literals.
77 +disable_unicode_literals_warning = False
78 +
79 +__version__ = "7.1.2"
1 +import textwrap
2 +from contextlib import contextmanager
3 +
4 +
5 +class TextWrapper(textwrap.TextWrapper):
6 + def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width):
7 + space_left = max(width - cur_len, 1)
8 +
9 + if self.break_long_words:
10 + last = reversed_chunks[-1]
11 + cut = last[:space_left]
12 + res = last[space_left:]
13 + cur_line.append(cut)
14 + reversed_chunks[-1] = res
15 + elif not cur_line:
16 + cur_line.append(reversed_chunks.pop())
17 +
18 + @contextmanager
19 + def extra_indent(self, indent):
20 + old_initial_indent = self.initial_indent
21 + old_subsequent_indent = self.subsequent_indent
22 + self.initial_indent += indent
23 + self.subsequent_indent += indent
24 + try:
25 + yield
26 + finally:
27 + self.initial_indent = old_initial_indent
28 + self.subsequent_indent = old_subsequent_indent
29 +
30 + def indent_only(self, text):
31 + rv = []
32 + for idx, line in enumerate(text.splitlines()):
33 + indent = self.initial_indent
34 + if idx > 0:
35 + indent = self.subsequent_indent
36 + rv.append(indent + line)
37 + return "\n".join(rv)
1 +import codecs
2 +import os
3 +import sys
4 +
5 +from ._compat import PY2
6 +
7 +
8 +def _find_unicode_literals_frame():
9 + import __future__
10 +
11 + if not hasattr(sys, "_getframe"): # not all Python implementations have it
12 + return 0
13 + frm = sys._getframe(1)
14 + idx = 1
15 + while frm is not None:
16 + if frm.f_globals.get("__name__", "").startswith("click."):
17 + frm = frm.f_back
18 + idx += 1
19 + elif frm.f_code.co_flags & __future__.unicode_literals.compiler_flag:
20 + return idx
21 + else:
22 + break
23 + return 0
24 +
25 +
26 +def _check_for_unicode_literals():
27 + if not __debug__:
28 + return
29 +
30 + from . import disable_unicode_literals_warning
31 +
32 + if not PY2 or disable_unicode_literals_warning:
33 + return
34 + bad_frame = _find_unicode_literals_frame()
35 + if bad_frame <= 0:
36 + return
37 + from warnings import warn
38 +
39 + warn(
40 + Warning(
41 + "Click detected the use of the unicode_literals __future__"
42 + " import. This is heavily discouraged because it can"
43 + " introduce subtle bugs in your code. You should instead"
44 + ' use explicit u"" literals for your unicode strings. For'
45 + " more information see"
46 + " https://click.palletsprojects.com/python3/"
47 + ),
48 + stacklevel=bad_frame,
49 + )
50 +
51 +
52 +def _verify_python3_env():
53 + """Ensures that the environment is good for unicode on Python 3."""
54 + if PY2:
55 + return
56 + try:
57 + import locale
58 +
59 + fs_enc = codecs.lookup(locale.getpreferredencoding()).name
60 + except Exception:
61 + fs_enc = "ascii"
62 + if fs_enc != "ascii":
63 + return
64 +
65 + extra = ""
66 + if os.name == "posix":
67 + import subprocess
68 +
69 + try:
70 + rv = subprocess.Popen(
71 + ["locale", "-a"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
72 + ).communicate()[0]
73 + except OSError:
74 + rv = b""
75 + good_locales = set()
76 + has_c_utf8 = False
77 +
78 + # Make sure we're operating on text here.
79 + if isinstance(rv, bytes):
80 + rv = rv.decode("ascii", "replace")
81 +
82 + for line in rv.splitlines():
83 + locale = line.strip()
84 + if locale.lower().endswith((".utf-8", ".utf8")):
85 + good_locales.add(locale)
86 + if locale.lower() in ("c.utf8", "c.utf-8"):
87 + has_c_utf8 = True
88 +
89 + extra += "\n\n"
90 + if not good_locales:
91 + extra += (
92 + "Additional information: on this system no suitable"
93 + " UTF-8 locales were discovered. This most likely"
94 + " requires resolving by reconfiguring the locale"
95 + " system."
96 + )
97 + elif has_c_utf8:
98 + extra += (
99 + "This system supports the C.UTF-8 locale which is"
100 + " recommended. You might be able to resolve your issue"
101 + " by exporting the following environment variables:\n\n"
102 + " export LC_ALL=C.UTF-8\n"
103 + " export LANG=C.UTF-8"
104 + )
105 + else:
106 + extra += (
107 + "This system lists a couple of UTF-8 supporting locales"
108 + " that you can pick from. The following suitable"
109 + " locales were discovered: {}".format(", ".join(sorted(good_locales)))
110 + )
111 +
112 + bad_locale = None
113 + for locale in os.environ.get("LC_ALL"), os.environ.get("LANG"):
114 + if locale and locale.lower().endswith((".utf-8", ".utf8")):
115 + bad_locale = locale
116 + if locale is not None:
117 + break
118 + if bad_locale is not None:
119 + extra += (
120 + "\n\nClick discovered that you exported a UTF-8 locale"
121 + " but the locale system could not pick up from it"
122 + " because it does not exist. The exported locale is"
123 + " '{}' but it is not supported".format(bad_locale)
124 + )
125 +
126 + raise RuntimeError(
127 + "Click will abort further execution because Python 3 was"
128 + " configured to use ASCII as encoding for the environment."
129 + " Consult https://click.palletsprojects.com/python3/ for"
130 + " mitigation steps.{}".format(extra)
131 + )
1 +# -*- coding: utf-8 -*-
2 +# This module is based on the excellent work by Adam Bartoš who
3 +# provided a lot of what went into the implementation here in
4 +# the discussion to issue1602 in the Python bug tracker.
5 +#
6 +# There are some general differences in regards to how this works
7 +# compared to the original patches as we do not need to patch
8 +# the entire interpreter but just work in our little world of
9 +# echo and prmopt.
10 +import ctypes
11 +import io
12 +import os
13 +import sys
14 +import time
15 +import zlib
16 +from ctypes import byref
17 +from ctypes import c_char
18 +from ctypes import c_char_p
19 +from ctypes import c_int
20 +from ctypes import c_ssize_t
21 +from ctypes import c_ulong
22 +from ctypes import c_void_p
23 +from ctypes import POINTER
24 +from ctypes import py_object
25 +from ctypes import windll
26 +from ctypes import WinError
27 +from ctypes import WINFUNCTYPE
28 +from ctypes.wintypes import DWORD
29 +from ctypes.wintypes import HANDLE
30 +from ctypes.wintypes import LPCWSTR
31 +from ctypes.wintypes import LPWSTR
32 +
33 +import msvcrt
34 +
35 +from ._compat import _NonClosingTextIOWrapper
36 +from ._compat import PY2
37 +from ._compat import text_type
38 +
39 +try:
40 + from ctypes import pythonapi
41 +
42 + PyObject_GetBuffer = pythonapi.PyObject_GetBuffer
43 + PyBuffer_Release = pythonapi.PyBuffer_Release
44 +except ImportError:
45 + pythonapi = None
46 +
47 +
48 +c_ssize_p = POINTER(c_ssize_t)
49 +
50 +kernel32 = windll.kernel32
51 +GetStdHandle = kernel32.GetStdHandle
52 +ReadConsoleW = kernel32.ReadConsoleW
53 +WriteConsoleW = kernel32.WriteConsoleW
54 +GetConsoleMode = kernel32.GetConsoleMode
55 +GetLastError = kernel32.GetLastError
56 +GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32))
57 +CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))(
58 + ("CommandLineToArgvW", windll.shell32)
59 +)
60 +LocalFree = WINFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p)(
61 + ("LocalFree", windll.kernel32)
62 +)
63 +
64 +
65 +STDIN_HANDLE = GetStdHandle(-10)
66 +STDOUT_HANDLE = GetStdHandle(-11)
67 +STDERR_HANDLE = GetStdHandle(-12)
68 +
69 +
70 +PyBUF_SIMPLE = 0
71 +PyBUF_WRITABLE = 1
72 +
73 +ERROR_SUCCESS = 0
74 +ERROR_NOT_ENOUGH_MEMORY = 8
75 +ERROR_OPERATION_ABORTED = 995
76 +
77 +STDIN_FILENO = 0
78 +STDOUT_FILENO = 1
79 +STDERR_FILENO = 2
80 +
81 +EOF = b"\x1a"
82 +MAX_BYTES_WRITTEN = 32767
83 +
84 +
85 +class Py_buffer(ctypes.Structure):
86 + _fields_ = [
87 + ("buf", c_void_p),
88 + ("obj", py_object),
89 + ("len", c_ssize_t),
90 + ("itemsize", c_ssize_t),
91 + ("readonly", c_int),
92 + ("ndim", c_int),
93 + ("format", c_char_p),
94 + ("shape", c_ssize_p),
95 + ("strides", c_ssize_p),
96 + ("suboffsets", c_ssize_p),
97 + ("internal", c_void_p),
98 + ]
99 +
100 + if PY2:
101 + _fields_.insert(-1, ("smalltable", c_ssize_t * 2))
102 +
103 +
104 +# On PyPy we cannot get buffers so our ability to operate here is
105 +# serverly limited.
106 +if pythonapi is None:
107 + get_buffer = None
108 +else:
109 +
110 + def get_buffer(obj, writable=False):
111 + buf = Py_buffer()
112 + flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE
113 + PyObject_GetBuffer(py_object(obj), byref(buf), flags)
114 + try:
115 + buffer_type = c_char * buf.len
116 + return buffer_type.from_address(buf.buf)
117 + finally:
118 + PyBuffer_Release(byref(buf))
119 +
120 +
121 +class _WindowsConsoleRawIOBase(io.RawIOBase):
122 + def __init__(self, handle):
123 + self.handle = handle
124 +
125 + def isatty(self):
126 + io.RawIOBase.isatty(self)
127 + return True
128 +
129 +
130 +class _WindowsConsoleReader(_WindowsConsoleRawIOBase):
131 + def readable(self):
132 + return True
133 +
134 + def readinto(self, b):
135 + bytes_to_be_read = len(b)
136 + if not bytes_to_be_read:
137 + return 0
138 + elif bytes_to_be_read % 2:
139 + raise ValueError(
140 + "cannot read odd number of bytes from UTF-16-LE encoded console"
141 + )
142 +
143 + buffer = get_buffer(b, writable=True)
144 + code_units_to_be_read = bytes_to_be_read // 2
145 + code_units_read = c_ulong()
146 +
147 + rv = ReadConsoleW(
148 + HANDLE(self.handle),
149 + buffer,
150 + code_units_to_be_read,
151 + byref(code_units_read),
152 + None,
153 + )
154 + if GetLastError() == ERROR_OPERATION_ABORTED:
155 + # wait for KeyboardInterrupt
156 + time.sleep(0.1)
157 + if not rv:
158 + raise OSError("Windows error: {}".format(GetLastError()))
159 +
160 + if buffer[0] == EOF:
161 + return 0
162 + return 2 * code_units_read.value
163 +
164 +
165 +class _WindowsConsoleWriter(_WindowsConsoleRawIOBase):
166 + def writable(self):
167 + return True
168 +
169 + @staticmethod
170 + def _get_error_message(errno):
171 + if errno == ERROR_SUCCESS:
172 + return "ERROR_SUCCESS"
173 + elif errno == ERROR_NOT_ENOUGH_MEMORY:
174 + return "ERROR_NOT_ENOUGH_MEMORY"
175 + return "Windows error {}".format(errno)
176 +
177 + def write(self, b):
178 + bytes_to_be_written = len(b)
179 + buf = get_buffer(b)
180 + code_units_to_be_written = min(bytes_to_be_written, MAX_BYTES_WRITTEN) // 2
181 + code_units_written = c_ulong()
182 +
183 + WriteConsoleW(
184 + HANDLE(self.handle),
185 + buf,
186 + code_units_to_be_written,
187 + byref(code_units_written),
188 + None,
189 + )
190 + bytes_written = 2 * code_units_written.value
191 +
192 + if bytes_written == 0 and bytes_to_be_written > 0:
193 + raise OSError(self._get_error_message(GetLastError()))
194 + return bytes_written
195 +
196 +
197 +class ConsoleStream(object):
198 + def __init__(self, text_stream, byte_stream):
199 + self._text_stream = text_stream
200 + self.buffer = byte_stream
201 +
202 + @property
203 + def name(self):
204 + return self.buffer.name
205 +
206 + def write(self, x):
207 + if isinstance(x, text_type):
208 + return self._text_stream.write(x)
209 + try:
210 + self.flush()
211 + except Exception:
212 + pass
213 + return self.buffer.write(x)
214 +
215 + def writelines(self, lines):
216 + for line in lines:
217 + self.write(line)
218 +
219 + def __getattr__(self, name):
220 + return getattr(self._text_stream, name)
221 +
222 + def isatty(self):
223 + return self.buffer.isatty()
224 +
225 + def __repr__(self):
226 + return "<ConsoleStream name={!r} encoding={!r}>".format(
227 + self.name, self.encoding
228 + )
229 +
230 +
231 +class WindowsChunkedWriter(object):
232 + """
233 + Wraps a stream (such as stdout), acting as a transparent proxy for all
234 + attribute access apart from method 'write()' which we wrap to write in
235 + limited chunks due to a Windows limitation on binary console streams.
236 + """
237 +
238 + def __init__(self, wrapped):
239 + # double-underscore everything to prevent clashes with names of
240 + # attributes on the wrapped stream object.
241 + self.__wrapped = wrapped
242 +
243 + def __getattr__(self, name):
244 + return getattr(self.__wrapped, name)
245 +
246 + def write(self, text):
247 + total_to_write = len(text)
248 + written = 0
249 +
250 + while written < total_to_write:
251 + to_write = min(total_to_write - written, MAX_BYTES_WRITTEN)
252 + self.__wrapped.write(text[written : written + to_write])
253 + written += to_write
254 +
255 +
256 +_wrapped_std_streams = set()
257 +
258 +
259 +def _wrap_std_stream(name):
260 + # Python 2 & Windows 7 and below
261 + if (
262 + PY2
263 + and sys.getwindowsversion()[:2] <= (6, 1)
264 + and name not in _wrapped_std_streams
265 + ):
266 + setattr(sys, name, WindowsChunkedWriter(getattr(sys, name)))
267 + _wrapped_std_streams.add(name)
268 +
269 +
270 +def _get_text_stdin(buffer_stream):
271 + text_stream = _NonClosingTextIOWrapper(
272 + io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)),
273 + "utf-16-le",
274 + "strict",
275 + line_buffering=True,
276 + )
277 + return ConsoleStream(text_stream, buffer_stream)
278 +
279 +
280 +def _get_text_stdout(buffer_stream):
281 + text_stream = _NonClosingTextIOWrapper(
282 + io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)),
283 + "utf-16-le",
284 + "strict",
285 + line_buffering=True,
286 + )
287 + return ConsoleStream(text_stream, buffer_stream)
288 +
289 +
290 +def _get_text_stderr(buffer_stream):
291 + text_stream = _NonClosingTextIOWrapper(
292 + io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)),
293 + "utf-16-le",
294 + "strict",
295 + line_buffering=True,
296 + )
297 + return ConsoleStream(text_stream, buffer_stream)
298 +
299 +
300 +if PY2:
301 +
302 + def _hash_py_argv():
303 + return zlib.crc32("\x00".join(sys.argv[1:]))
304 +
305 + _initial_argv_hash = _hash_py_argv()
306 +
307 + def _get_windows_argv():
308 + argc = c_int(0)
309 + argv_unicode = CommandLineToArgvW(GetCommandLineW(), byref(argc))
310 + if not argv_unicode:
311 + raise WinError()
312 + try:
313 + argv = [argv_unicode[i] for i in range(0, argc.value)]
314 + finally:
315 + LocalFree(argv_unicode)
316 + del argv_unicode
317 +
318 + if not hasattr(sys, "frozen"):
319 + argv = argv[1:]
320 + while len(argv) > 0:
321 + arg = argv[0]
322 + if not arg.startswith("-") or arg == "-":
323 + break
324 + argv = argv[1:]
325 + if arg.startswith(("-c", "-m")):
326 + break
327 +
328 + return argv[1:]
329 +
330 +
331 +_stream_factories = {
332 + 0: _get_text_stdin,
333 + 1: _get_text_stdout,
334 + 2: _get_text_stderr,
335 +}
336 +
337 +
338 +def _is_console(f):
339 + if not hasattr(f, "fileno"):
340 + return False
341 +
342 + try:
343 + fileno = f.fileno()
344 + except OSError:
345 + return False
346 +
347 + handle = msvcrt.get_osfhandle(fileno)
348 + return bool(GetConsoleMode(handle, byref(DWORD())))
349 +
350 +
351 +def _get_windows_console_stream(f, encoding, errors):
352 + if (
353 + get_buffer is not None
354 + and encoding in ("utf-16-le", None)
355 + and errors in ("strict", None)
356 + and _is_console(f)
357 + ):
358 + func = _stream_factories.get(f.fileno())
359 + if func is not None:
360 + if not PY2:
361 + f = getattr(f, "buffer", None)
362 + if f is None:
363 + return None
364 + else:
365 + # If we are on Python 2 we need to set the stream that we
366 + # deal with to binary mode as otherwise the exercise if a
367 + # bit moot. The same problems apply as for
368 + # get_binary_stdin and friends from _compat.
369 + msvcrt.setmode(f.fileno(), os.O_BINARY)
370 + return func(f)
1 +from ._compat import filename_to_ui
2 +from ._compat import get_text_stderr
3 +from ._compat import PY2
4 +from .utils import echo
5 +
6 +
7 +def _join_param_hints(param_hint):
8 + if isinstance(param_hint, (tuple, list)):
9 + return " / ".join(repr(x) for x in param_hint)
10 + return param_hint
11 +
12 +
13 +class ClickException(Exception):
14 + """An exception that Click can handle and show to the user."""
15 +
16 + #: The exit code for this exception
17 + exit_code = 1
18 +
19 + def __init__(self, message):
20 + ctor_msg = message
21 + if PY2:
22 + if ctor_msg is not None:
23 + ctor_msg = ctor_msg.encode("utf-8")
24 + Exception.__init__(self, ctor_msg)
25 + self.message = message
26 +
27 + def format_message(self):
28 + return self.message
29 +
30 + def __str__(self):
31 + return self.message
32 +
33 + if PY2:
34 + __unicode__ = __str__
35 +
36 + def __str__(self):
37 + return self.message.encode("utf-8")
38 +
39 + def show(self, file=None):
40 + if file is None:
41 + file = get_text_stderr()
42 + echo("Error: {}".format(self.format_message()), file=file)
43 +
44 +
45 +class UsageError(ClickException):
46 + """An internal exception that signals a usage error. This typically
47 + aborts any further handling.
48 +
49 + :param message: the error message to display.
50 + :param ctx: optionally the context that caused this error. Click will
51 + fill in the context automatically in some situations.
52 + """
53 +
54 + exit_code = 2
55 +
56 + def __init__(self, message, ctx=None):
57 + ClickException.__init__(self, message)
58 + self.ctx = ctx
59 + self.cmd = self.ctx.command if self.ctx else None
60 +
61 + def show(self, file=None):
62 + if file is None:
63 + file = get_text_stderr()
64 + color = None
65 + hint = ""
66 + if self.cmd is not None and self.cmd.get_help_option(self.ctx) is not None:
67 + hint = "Try '{} {}' for help.\n".format(
68 + self.ctx.command_path, self.ctx.help_option_names[0]
69 + )
70 + if self.ctx is not None:
71 + color = self.ctx.color
72 + echo("{}\n{}".format(self.ctx.get_usage(), hint), file=file, color=color)
73 + echo("Error: {}".format(self.format_message()), file=file, color=color)
74 +
75 +
76 +class BadParameter(UsageError):
77 + """An exception that formats out a standardized error message for a
78 + bad parameter. This is useful when thrown from a callback or type as
79 + Click will attach contextual information to it (for instance, which
80 + parameter it is).
81 +
82 + .. versionadded:: 2.0
83 +
84 + :param param: the parameter object that caused this error. This can
85 + be left out, and Click will attach this info itself
86 + if possible.
87 + :param param_hint: a string that shows up as parameter name. This
88 + can be used as alternative to `param` in cases
89 + where custom validation should happen. If it is
90 + a string it's used as such, if it's a list then
91 + each item is quoted and separated.
92 + """
93 +
94 + def __init__(self, message, ctx=None, param=None, param_hint=None):
95 + UsageError.__init__(self, message, ctx)
96 + self.param = param
97 + self.param_hint = param_hint
98 +
99 + def format_message(self):
100 + if self.param_hint is not None:
101 + param_hint = self.param_hint
102 + elif self.param is not None:
103 + param_hint = self.param.get_error_hint(self.ctx)
104 + else:
105 + return "Invalid value: {}".format(self.message)
106 + param_hint = _join_param_hints(param_hint)
107 +
108 + return "Invalid value for {}: {}".format(param_hint, self.message)
109 +
110 +
111 +class MissingParameter(BadParameter):
112 + """Raised if click required an option or argument but it was not
113 + provided when invoking the script.
114 +
115 + .. versionadded:: 4.0
116 +
117 + :param param_type: a string that indicates the type of the parameter.
118 + The default is to inherit the parameter type from
119 + the given `param`. Valid values are ``'parameter'``,
120 + ``'option'`` or ``'argument'``.
121 + """
122 +
123 + def __init__(
124 + self, message=None, ctx=None, param=None, param_hint=None, param_type=None
125 + ):
126 + BadParameter.__init__(self, message, ctx, param, param_hint)
127 + self.param_type = param_type
128 +
129 + def format_message(self):
130 + if self.param_hint is not None:
131 + param_hint = self.param_hint
132 + elif self.param is not None:
133 + param_hint = self.param.get_error_hint(self.ctx)
134 + else:
135 + param_hint = None
136 + param_hint = _join_param_hints(param_hint)
137 +
138 + param_type = self.param_type
139 + if param_type is None and self.param is not None:
140 + param_type = self.param.param_type_name
141 +
142 + msg = self.message
143 + if self.param is not None:
144 + msg_extra = self.param.type.get_missing_message(self.param)
145 + if msg_extra:
146 + if msg:
147 + msg += ". {}".format(msg_extra)
148 + else:
149 + msg = msg_extra
150 +
151 + return "Missing {}{}{}{}".format(
152 + param_type,
153 + " {}".format(param_hint) if param_hint else "",
154 + ". " if msg else ".",
155 + msg or "",
156 + )
157 +
158 + def __str__(self):
159 + if self.message is None:
160 + param_name = self.param.name if self.param else None
161 + return "missing parameter: {}".format(param_name)
162 + else:
163 + return self.message
164 +
165 + if PY2:
166 + __unicode__ = __str__
167 +
168 + def __str__(self):
169 + return self.__unicode__().encode("utf-8")
170 +
171 +
172 +class NoSuchOption(UsageError):
173 + """Raised if click attempted to handle an option that does not
174 + exist.
175 +
176 + .. versionadded:: 4.0
177 + """
178 +
179 + def __init__(self, option_name, message=None, possibilities=None, ctx=None):
180 + if message is None:
181 + message = "no such option: {}".format(option_name)
182 + UsageError.__init__(self, message, ctx)
183 + self.option_name = option_name
184 + self.possibilities = possibilities
185 +
186 + def format_message(self):
187 + bits = [self.message]
188 + if self.possibilities:
189 + if len(self.possibilities) == 1:
190 + bits.append("Did you mean {}?".format(self.possibilities[0]))
191 + else:
192 + possibilities = sorted(self.possibilities)
193 + bits.append("(Possible options: {})".format(", ".join(possibilities)))
194 + return " ".join(bits)
195 +
196 +
197 +class BadOptionUsage(UsageError):
198 + """Raised if an option is generally supplied but the use of the option
199 + was incorrect. This is for instance raised if the number of arguments
200 + for an option is not correct.
201 +
202 + .. versionadded:: 4.0
203 +
204 + :param option_name: the name of the option being used incorrectly.
205 + """
206 +
207 + def __init__(self, option_name, message, ctx=None):
208 + UsageError.__init__(self, message, ctx)
209 + self.option_name = option_name
210 +
211 +
212 +class BadArgumentUsage(UsageError):
213 + """Raised if an argument is generally supplied but the use of the argument
214 + was incorrect. This is for instance raised if the number of values
215 + for an argument is not correct.
216 +
217 + .. versionadded:: 6.0
218 + """
219 +
220 + def __init__(self, message, ctx=None):
221 + UsageError.__init__(self, message, ctx)
222 +
223 +
224 +class FileError(ClickException):
225 + """Raised if a file cannot be opened."""
226 +
227 + def __init__(self, filename, hint=None):
228 + ui_filename = filename_to_ui(filename)
229 + if hint is None:
230 + hint = "unknown error"
231 + ClickException.__init__(self, hint)
232 + self.ui_filename = ui_filename
233 + self.filename = filename
234 +
235 + def format_message(self):
236 + return "Could not open file {}: {}".format(self.ui_filename, self.message)
237 +
238 +
239 +class Abort(RuntimeError):
240 + """An internal signalling exception that signals Click to abort."""
241 +
242 +
243 +class Exit(RuntimeError):
244 + """An exception that indicates that the application should exit with some
245 + status code.
246 +
247 + :param code: the status code to exit with.
248 + """
249 +
250 + __slots__ = ("exit_code",)
251 +
252 + def __init__(self, code=0):
253 + self.exit_code = code
1 +from contextlib import contextmanager
2 +
3 +from ._compat import term_len
4 +from .parser import split_opt
5 +from .termui import get_terminal_size
6 +
7 +# Can force a width. This is used by the test system
8 +FORCED_WIDTH = None
9 +
10 +
11 +def measure_table(rows):
12 + widths = {}
13 + for row in rows:
14 + for idx, col in enumerate(row):
15 + widths[idx] = max(widths.get(idx, 0), term_len(col))
16 + return tuple(y for x, y in sorted(widths.items()))
17 +
18 +
19 +def iter_rows(rows, col_count):
20 + for row in rows:
21 + row = tuple(row)
22 + yield row + ("",) * (col_count - len(row))
23 +
24 +
25 +def wrap_text(
26 + text, width=78, initial_indent="", subsequent_indent="", preserve_paragraphs=False
27 +):
28 + """A helper function that intelligently wraps text. By default, it
29 + assumes that it operates on a single paragraph of text but if the
30 + `preserve_paragraphs` parameter is provided it will intelligently
31 + handle paragraphs (defined by two empty lines).
32 +
33 + If paragraphs are handled, a paragraph can be prefixed with an empty
34 + line containing the ``\\b`` character (``\\x08``) to indicate that
35 + no rewrapping should happen in that block.
36 +
37 + :param text: the text that should be rewrapped.
38 + :param width: the maximum width for the text.
39 + :param initial_indent: the initial indent that should be placed on the
40 + first line as a string.
41 + :param subsequent_indent: the indent string that should be placed on
42 + each consecutive line.
43 + :param preserve_paragraphs: if this flag is set then the wrapping will
44 + intelligently handle paragraphs.
45 + """
46 + from ._textwrap import TextWrapper
47 +
48 + text = text.expandtabs()
49 + wrapper = TextWrapper(
50 + width,
51 + initial_indent=initial_indent,
52 + subsequent_indent=subsequent_indent,
53 + replace_whitespace=False,
54 + )
55 + if not preserve_paragraphs:
56 + return wrapper.fill(text)
57 +
58 + p = []
59 + buf = []
60 + indent = None
61 +
62 + def _flush_par():
63 + if not buf:
64 + return
65 + if buf[0].strip() == "\b":
66 + p.append((indent or 0, True, "\n".join(buf[1:])))
67 + else:
68 + p.append((indent or 0, False, " ".join(buf)))
69 + del buf[:]
70 +
71 + for line in text.splitlines():
72 + if not line:
73 + _flush_par()
74 + indent = None
75 + else:
76 + if indent is None:
77 + orig_len = term_len(line)
78 + line = line.lstrip()
79 + indent = orig_len - term_len(line)
80 + buf.append(line)
81 + _flush_par()
82 +
83 + rv = []
84 + for indent, raw, text in p:
85 + with wrapper.extra_indent(" " * indent):
86 + if raw:
87 + rv.append(wrapper.indent_only(text))
88 + else:
89 + rv.append(wrapper.fill(text))
90 +
91 + return "\n\n".join(rv)
92 +
93 +
94 +class HelpFormatter(object):
95 + """This class helps with formatting text-based help pages. It's
96 + usually just needed for very special internal cases, but it's also
97 + exposed so that developers can write their own fancy outputs.
98 +
99 + At present, it always writes into memory.
100 +
101 + :param indent_increment: the additional increment for each level.
102 + :param width: the width for the text. This defaults to the terminal
103 + width clamped to a maximum of 78.
104 + """
105 +
106 + def __init__(self, indent_increment=2, width=None, max_width=None):
107 + self.indent_increment = indent_increment
108 + if max_width is None:
109 + max_width = 80
110 + if width is None:
111 + width = FORCED_WIDTH
112 + if width is None:
113 + width = max(min(get_terminal_size()[0], max_width) - 2, 50)
114 + self.width = width
115 + self.current_indent = 0
116 + self.buffer = []
117 +
118 + def write(self, string):
119 + """Writes a unicode string into the internal buffer."""
120 + self.buffer.append(string)
121 +
122 + def indent(self):
123 + """Increases the indentation."""
124 + self.current_indent += self.indent_increment
125 +
126 + def dedent(self):
127 + """Decreases the indentation."""
128 + self.current_indent -= self.indent_increment
129 +
130 + def write_usage(self, prog, args="", prefix="Usage: "):
131 + """Writes a usage line into the buffer.
132 +
133 + :param prog: the program name.
134 + :param args: whitespace separated list of arguments.
135 + :param prefix: the prefix for the first line.
136 + """
137 + usage_prefix = "{:>{w}}{} ".format(prefix, prog, w=self.current_indent)
138 + text_width = self.width - self.current_indent
139 +
140 + if text_width >= (term_len(usage_prefix) + 20):
141 + # The arguments will fit to the right of the prefix.
142 + indent = " " * term_len(usage_prefix)
143 + self.write(
144 + wrap_text(
145 + args,
146 + text_width,
147 + initial_indent=usage_prefix,
148 + subsequent_indent=indent,
149 + )
150 + )
151 + else:
152 + # The prefix is too long, put the arguments on the next line.
153 + self.write(usage_prefix)
154 + self.write("\n")
155 + indent = " " * (max(self.current_indent, term_len(prefix)) + 4)
156 + self.write(
157 + wrap_text(
158 + args, text_width, initial_indent=indent, subsequent_indent=indent
159 + )
160 + )
161 +
162 + self.write("\n")
163 +
164 + def write_heading(self, heading):
165 + """Writes a heading into the buffer."""
166 + self.write("{:>{w}}{}:\n".format("", heading, w=self.current_indent))
167 +
168 + def write_paragraph(self):
169 + """Writes a paragraph into the buffer."""
170 + if self.buffer:
171 + self.write("\n")
172 +
173 + def write_text(self, text):
174 + """Writes re-indented text into the buffer. This rewraps and
175 + preserves paragraphs.
176 + """
177 + text_width = max(self.width - self.current_indent, 11)
178 + indent = " " * self.current_indent
179 + self.write(
180 + wrap_text(
181 + text,
182 + text_width,
183 + initial_indent=indent,
184 + subsequent_indent=indent,
185 + preserve_paragraphs=True,
186 + )
187 + )
188 + self.write("\n")
189 +
190 + def write_dl(self, rows, col_max=30, col_spacing=2):
191 + """Writes a definition list into the buffer. This is how options
192 + and commands are usually formatted.
193 +
194 + :param rows: a list of two item tuples for the terms and values.
195 + :param col_max: the maximum width of the first column.
196 + :param col_spacing: the number of spaces between the first and
197 + second column.
198 + """
199 + rows = list(rows)
200 + widths = measure_table(rows)
201 + if len(widths) != 2:
202 + raise TypeError("Expected two columns for definition list")
203 +
204 + first_col = min(widths[0], col_max) + col_spacing
205 +
206 + for first, second in iter_rows(rows, len(widths)):
207 + self.write("{:>{w}}{}".format("", first, w=self.current_indent))
208 + if not second:
209 + self.write("\n")
210 + continue
211 + if term_len(first) <= first_col - col_spacing:
212 + self.write(" " * (first_col - term_len(first)))
213 + else:
214 + self.write("\n")
215 + self.write(" " * (first_col + self.current_indent))
216 +
217 + text_width = max(self.width - first_col - 2, 10)
218 + wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True)
219 + lines = wrapped_text.splitlines()
220 +
221 + if lines:
222 + self.write("{}\n".format(lines[0]))
223 +
224 + for line in lines[1:]:
225 + self.write(
226 + "{:>{w}}{}\n".format(
227 + "", line, w=first_col + self.current_indent
228 + )
229 + )
230 +
231 + if len(lines) > 1:
232 + # separate long help from next option
233 + self.write("\n")
234 + else:
235 + self.write("\n")
236 +
237 + @contextmanager
238 + def section(self, name):
239 + """Helpful context manager that writes a paragraph, a heading,
240 + and the indents.
241 +
242 + :param name: the section name that is written as heading.
243 + """
244 + self.write_paragraph()
245 + self.write_heading(name)
246 + self.indent()
247 + try:
248 + yield
249 + finally:
250 + self.dedent()
251 +
252 + @contextmanager
253 + def indentation(self):
254 + """A context manager that increases the indentation."""
255 + self.indent()
256 + try:
257 + yield
258 + finally:
259 + self.dedent()
260 +
261 + def getvalue(self):
262 + """Returns the buffer contents."""
263 + return "".join(self.buffer)
264 +
265 +
266 +def join_options(options):
267 + """Given a list of option strings this joins them in the most appropriate
268 + way and returns them in the form ``(formatted_string,
269 + any_prefix_is_slash)`` where the second item in the tuple is a flag that
270 + indicates if any of the option prefixes was a slash.
271 + """
272 + rv = []
273 + any_prefix_is_slash = False
274 + for opt in options:
275 + prefix = split_opt(opt)[0]
276 + if prefix == "/":
277 + any_prefix_is_slash = True
278 + rv.append((len(prefix), opt))
279 +
280 + rv.sort(key=lambda x: x[0])
281 +
282 + rv = ", ".join(x[1] for x in rv)
283 + return rv, any_prefix_is_slash
1 +from threading import local
2 +
3 +_local = local()
4 +
5 +
6 +def get_current_context(silent=False):
7 + """Returns the current click context. This can be used as a way to
8 + access the current context object from anywhere. This is a more implicit
9 + alternative to the :func:`pass_context` decorator. This function is
10 + primarily useful for helpers such as :func:`echo` which might be
11 + interested in changing its behavior based on the current context.
12 +
13 + To push the current context, :meth:`Context.scope` can be used.
14 +
15 + .. versionadded:: 5.0
16 +
17 + :param silent: if set to `True` the return value is `None` if no context
18 + is available. The default behavior is to raise a
19 + :exc:`RuntimeError`.
20 + """
21 + try:
22 + return _local.stack[-1]
23 + except (AttributeError, IndexError):
24 + if not silent:
25 + raise RuntimeError("There is no active click context.")
26 +
27 +
28 +def push_context(ctx):
29 + """Pushes a new context to the current stack."""
30 + _local.__dict__.setdefault("stack", []).append(ctx)
31 +
32 +
33 +def pop_context():
34 + """Removes the top level from the stack."""
35 + _local.stack.pop()
36 +
37 +
38 +def resolve_color_default(color=None):
39 + """"Internal helper to get the default value of the color flag. If a
40 + value is passed it's returned unchanged, otherwise it's looked up from
41 + the current context.
42 + """
43 + if color is not None:
44 + return color
45 + ctx = get_current_context(silent=True)
46 + if ctx is not None:
47 + return ctx.color
1 +MIT License
2 +
3 +Copyright (c) 2016-2018 Olli-Pekka Heinisuo and contributors
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in all
13 +copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 +SOFTWARE.
...\ No newline at end of file ...\ No newline at end of file
1 +import importlib
2 +
3 +from .cv2 import *
4 +from .data import *
5 +
6 +# wildcard import above does not import "private" variables like __version__
7 +# this makes them available
8 +globals().update(importlib.import_module('cv2.cv2').__dict__)
1 +import os
2 +
3 +haarcascades = os.path.join(os.path.dirname(__file__), '')
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 is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
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.
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.
This diff could not be displayed because it is too large.