Compare commits
51 Commits
prd
...
dev-fastap
@ -0,0 +1,29 @@
|
|||||||
|
$('.ui.dropdown')
|
||||||
|
.dropdown('clear')
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var content = [
|
||||||
|
];
|
||||||
|
|
||||||
|
let i = 1
|
||||||
|
document.getElementById("buyNumber").innerHTML = i
|
||||||
|
|
||||||
|
|
||||||
|
$('.ui.search')
|
||||||
|
.search({
|
||||||
|
source: content
|
||||||
|
})
|
||||||
|
;
|
||||||
|
|
||||||
|
function buy_confirm() {
|
||||||
|
j = String(i)
|
||||||
|
content.push({ title: j })
|
||||||
|
$('.ui.search').search({source: content})
|
||||||
|
i=i+1;
|
||||||
|
document.getElementById("buyNumber").innerHTML = i;
|
||||||
|
$('.ui.dropdown').dropdown('clear')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
@ -1,52 +0,0 @@
|
|||||||
# Role model - if len of keys in dict is 0 - all access. If at least len is 1 - only this access
|
|
||||||
# "Orchestrator":{
|
|
||||||
# "Controls": {
|
|
||||||
# "RestartOrchestrator": {}, # Feature to restart orchestrator on virtual machine
|
|
||||||
# "LookMachineScreenshots": {} # Feature to look machina screenshots
|
|
||||||
# },
|
|
||||||
# "RDPActive": { # Robot RDP active module
|
|
||||||
# "ListRead": {} # Access to read RDP session list
|
|
||||||
# "RestartPC": {} # Restart PC
|
|
||||||
# "GITRestartOrchestrator": {} # Update GIT + restart orchestrator
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
# USAGE in .py
|
|
||||||
# inRequest.
|
|
||||||
# inRequest.OpenRPA["DefUserRoleAccessAsk"](["Orchestrator","RDPActive","Controls"]) - return True or False
|
|
||||||
# inRequest.OpenRPA["DefUserRoleHierarchyGet"]() - Return dict of the role hierarchy or {}
|
|
||||||
|
|
||||||
# Init Section
|
|
||||||
gUserNameStr = "Login" # User name without domain name
|
|
||||||
gDomainNameStr = "" # DOMAIN or EMPTY str if no domain
|
|
||||||
gDomainIsDefaultBool = True # If domain is exist and is default (default = you can type login without domain name)
|
|
||||||
|
|
||||||
def SettingsUpdate(inDict):
|
|
||||||
lRuleDomainUserDict = {
|
|
||||||
"MethodMatchURLBeforeList": [
|
|
||||||
{
|
|
||||||
"Method":"GET",
|
|
||||||
"MatchType":"Beginwith",
|
|
||||||
"URL":"/",
|
|
||||||
#"FlagAccessDefRequestGlobalAuthenticate": TestDef
|
|
||||||
"FlagAccess": True
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Method":"POST",
|
|
||||||
"MatchType":"Beginwith",
|
|
||||||
"URL":"/",
|
|
||||||
#"FlagAccessDefRequestGlobalAuthenticate": TestDef
|
|
||||||
"FlagAccess": True
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ControlPanelKeyAllowedList": ["TestControlPanel", "RobotRDPActive","RobotScreenActive", "ControlPanel_Template"], # If empty - all is allowed
|
|
||||||
"RoleHierarchyAllowedDict": {"Key1":"Test"}
|
|
||||||
}
|
|
||||||
# Case add domain + user
|
|
||||||
inDict["Server"]["AccessUsers"]["RuleDomainUserDict"].update({(gDomainNameStr.upper(),gUserNameStr.upper()):lRuleDomainUserDict})
|
|
||||||
if gDomainIsDefaultBool:
|
|
||||||
# Case add default domain + user
|
|
||||||
inDict["Server"]["AccessUsers"]["RuleDomainUserDict"].update({("",gUserNameStr.upper()):lRuleDomainUserDict})
|
|
||||||
#Return current dict
|
|
||||||
return inDict
|
|
@ -1,24 +0,0 @@
|
|||||||
chcp 65001
|
|
||||||
@echo off
|
|
||||||
echo Формат использования init-python-env.cmd [имя запускаемого процесса.exe] [имя убиваемого процесса.exe]
|
|
||||||
echo Пример использования init-python-env.cmd orpa-rbt.exe orpa-rbt.exe
|
|
||||||
|
|
||||||
if [%1]==[] goto :python-env
|
|
||||||
goto create-exe
|
|
||||||
:create-exe
|
|
||||||
copy /Y "%~dp0..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe" "%~dp0..\Resources\WPy64-3720\python-3.7.2.amd64\%1"
|
|
||||||
if [%2]==[] goto :python-env
|
|
||||||
goto taskkill
|
|
||||||
:taskkill
|
|
||||||
taskkill /im "%2" /F /fi "username eq %username%"
|
|
||||||
goto :python-env
|
|
||||||
:python-env
|
|
||||||
set CD_PREV=%cd%
|
|
||||||
cd /d "%~dp0..\Resources\WPy64-3720\python-3.7.2.amd64"
|
|
||||||
set PATH=%cd%;%cd%\Scripts;%PATH%
|
|
||||||
cd /d "%~dp0..\Sources"
|
|
||||||
set PYTHONPATH=%cd%;%PYTHONPATH%
|
|
||||||
cd %CD_PREV%
|
|
||||||
:eof
|
|
||||||
echo Инициализация Python окружения прошла успешно!
|
|
||||||
@echo on
|
|
@ -1,4 +0,0 @@
|
|||||||
chcp 65001
|
|
||||||
cd /d "%~dp0"
|
|
||||||
call init-python-env.cmd orpa-rbt.exe orpa-rbt.exe
|
|
||||||
cmd
|
|
@ -1,5 +1,4 @@
|
|||||||
chcp 65001
|
chcp 65001
|
||||||
cd /d "%~dp0"
|
cd /d "%~dp0"
|
||||||
call init-python-env.cmd orpa-orc.exe orpa-orc.exe
|
call .\..\Scripts\PythonWinInit.cmd script orpa-orc.exe orpa-orc.exe
|
||||||
orpa-orc.exe "config.py"
|
orpa-orc.exe "config.py"
|
||||||
pause>nul
|
|
@ -0,0 +1,15 @@
|
|||||||
|
# This is the canonical package information.
|
||||||
|
__author__ = 'Andrew Dunham'
|
||||||
|
__license__ = 'Apache'
|
||||||
|
__copyright__ = "Copyright (c) 2012-2013, Andrew Dunham"
|
||||||
|
__version__ = "0.0.6"
|
||||||
|
|
||||||
|
|
||||||
|
from .multipart import (
|
||||||
|
FormParser,
|
||||||
|
MultipartParser,
|
||||||
|
QuerystringParser,
|
||||||
|
OctetStreamParser,
|
||||||
|
create_form_parser,
|
||||||
|
parse_form,
|
||||||
|
)
|
@ -0,0 +1,171 @@
|
|||||||
|
import base64
|
||||||
|
import binascii
|
||||||
|
|
||||||
|
from .exceptions import DecodeError
|
||||||
|
|
||||||
|
|
||||||
|
class Base64Decoder:
|
||||||
|
"""This object provides an interface to decode a stream of Base64 data. It
|
||||||
|
is instantiated with an "underlying object", and whenever a write()
|
||||||
|
operation is performed, it will decode the incoming data as Base64, and
|
||||||
|
call write() on the underlying object. This is primarily used for decoding
|
||||||
|
form data encoded as Base64, but can be used for other purposes::
|
||||||
|
|
||||||
|
from multipart.decoders import Base64Decoder
|
||||||
|
fd = open("notb64.txt", "wb")
|
||||||
|
decoder = Base64Decoder(fd)
|
||||||
|
try:
|
||||||
|
decoder.write("Zm9vYmFy") # "foobar" in Base64
|
||||||
|
decoder.finalize()
|
||||||
|
finally:
|
||||||
|
decoder.close()
|
||||||
|
|
||||||
|
# The contents of "notb64.txt" should be "foobar".
|
||||||
|
|
||||||
|
This object will also pass all finalize() and close() calls to the
|
||||||
|
underlying object, if the underlying object supports them.
|
||||||
|
|
||||||
|
Note that this class maintains a cache of base64 chunks, so that a write of
|
||||||
|
arbitrary size can be performed. You must call :meth:`finalize` on this
|
||||||
|
object after all writes are completed to ensure that all data is flushed
|
||||||
|
to the underlying object.
|
||||||
|
|
||||||
|
:param underlying: the underlying object to pass writes to
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, underlying):
|
||||||
|
self.cache = bytearray()
|
||||||
|
self.underlying = underlying
|
||||||
|
|
||||||
|
def write(self, data):
|
||||||
|
"""Takes any input data provided, decodes it as base64, and passes it
|
||||||
|
on to the underlying object. If the data provided is invalid base64
|
||||||
|
data, then this method will raise
|
||||||
|
a :class:`multipart.exceptions.DecodeError`
|
||||||
|
|
||||||
|
:param data: base64 data to decode
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Prepend any cache info to our data.
|
||||||
|
if len(self.cache) > 0:
|
||||||
|
data = self.cache + data
|
||||||
|
|
||||||
|
# Slice off a string that's a multiple of 4.
|
||||||
|
decode_len = (len(data) // 4) * 4
|
||||||
|
val = data[:decode_len]
|
||||||
|
|
||||||
|
# Decode and write, if we have any.
|
||||||
|
if len(val) > 0:
|
||||||
|
try:
|
||||||
|
decoded = base64.b64decode(val)
|
||||||
|
except binascii.Error:
|
||||||
|
raise DecodeError('There was an error raised while decoding '
|
||||||
|
'base64-encoded data.')
|
||||||
|
|
||||||
|
self.underlying.write(decoded)
|
||||||
|
|
||||||
|
# Get the remaining bytes and save in our cache.
|
||||||
|
remaining_len = len(data) % 4
|
||||||
|
if remaining_len > 0:
|
||||||
|
self.cache = data[-remaining_len:]
|
||||||
|
else:
|
||||||
|
self.cache = b''
|
||||||
|
|
||||||
|
# Return the length of the data to indicate no error.
|
||||||
|
return len(data)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""Close this decoder. If the underlying object has a `close()`
|
||||||
|
method, this function will call it.
|
||||||
|
"""
|
||||||
|
if hasattr(self.underlying, 'close'):
|
||||||
|
self.underlying.close()
|
||||||
|
|
||||||
|
def finalize(self):
|
||||||
|
"""Finalize this object. This should be called when no more data
|
||||||
|
should be written to the stream. This function can raise a
|
||||||
|
:class:`multipart.exceptions.DecodeError` if there is some remaining
|
||||||
|
data in the cache.
|
||||||
|
|
||||||
|
If the underlying object has a `finalize()` method, this function will
|
||||||
|
call it.
|
||||||
|
"""
|
||||||
|
if len(self.cache) > 0:
|
||||||
|
raise DecodeError('There are %d bytes remaining in the '
|
||||||
|
'Base64Decoder cache when finalize() is called'
|
||||||
|
% len(self.cache))
|
||||||
|
|
||||||
|
if hasattr(self.underlying, 'finalize'):
|
||||||
|
self.underlying.finalize()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"{self.__class__.__name__}(underlying={self.underlying!r})"
|
||||||
|
|
||||||
|
|
||||||
|
class QuotedPrintableDecoder:
|
||||||
|
"""This object provides an interface to decode a stream of quoted-printable
|
||||||
|
data. It is instantiated with an "underlying object", in the same manner
|
||||||
|
as the :class:`multipart.decoders.Base64Decoder` class. This class behaves
|
||||||
|
in exactly the same way, including maintaining a cache of quoted-printable
|
||||||
|
chunks.
|
||||||
|
|
||||||
|
:param underlying: the underlying object to pass writes to
|
||||||
|
"""
|
||||||
|
def __init__(self, underlying):
|
||||||
|
self.cache = b''
|
||||||
|
self.underlying = underlying
|
||||||
|
|
||||||
|
def write(self, data):
|
||||||
|
"""Takes any input data provided, decodes it as quoted-printable, and
|
||||||
|
passes it on to the underlying object.
|
||||||
|
|
||||||
|
:param data: quoted-printable data to decode
|
||||||
|
"""
|
||||||
|
# Prepend any cache info to our data.
|
||||||
|
if len(self.cache) > 0:
|
||||||
|
data = self.cache + data
|
||||||
|
|
||||||
|
# If the last 2 characters have an '=' sign in it, then we won't be
|
||||||
|
# able to decode the encoded value and we'll need to save it for the
|
||||||
|
# next decoding step.
|
||||||
|
if data[-2:].find(b'=') != -1:
|
||||||
|
enc, rest = data[:-2], data[-2:]
|
||||||
|
else:
|
||||||
|
enc = data
|
||||||
|
rest = b''
|
||||||
|
|
||||||
|
# Encode and write, if we have data.
|
||||||
|
if len(enc) > 0:
|
||||||
|
self.underlying.write(binascii.a2b_qp(enc))
|
||||||
|
|
||||||
|
# Save remaining in cache.
|
||||||
|
self.cache = rest
|
||||||
|
return len(data)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""Close this decoder. If the underlying object has a `close()`
|
||||||
|
method, this function will call it.
|
||||||
|
"""
|
||||||
|
if hasattr(self.underlying, 'close'):
|
||||||
|
self.underlying.close()
|
||||||
|
|
||||||
|
def finalize(self):
|
||||||
|
"""Finalize this object. This should be called when no more data
|
||||||
|
should be written to the stream. This function will not raise any
|
||||||
|
exceptions, but it may write more data to the underlying object if
|
||||||
|
there is data remaining in the cache.
|
||||||
|
|
||||||
|
If the underlying object has a `finalize()` method, this function will
|
||||||
|
call it.
|
||||||
|
"""
|
||||||
|
# If we have a cache, write and then remove it.
|
||||||
|
if len(self.cache) > 0:
|
||||||
|
self.underlying.write(binascii.a2b_qp(self.cache))
|
||||||
|
self.cache = b''
|
||||||
|
|
||||||
|
# Finalize our underlying stream.
|
||||||
|
if hasattr(self.underlying, 'finalize'):
|
||||||
|
self.underlying.finalize()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"{self.__class__.__name__}(underlying={self.underlying!r})"
|
@ -0,0 +1,46 @@
|
|||||||
|
class FormParserError(ValueError):
|
||||||
|
"""Base error class for our form parser."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ParseError(FormParserError):
|
||||||
|
"""This exception (or a subclass) is raised when there is an error while
|
||||||
|
parsing something.
|
||||||
|
"""
|
||||||
|
|
||||||
|
#: This is the offset in the input data chunk (*NOT* the overall stream) in
|
||||||
|
#: which the parse error occurred. It will be -1 if not specified.
|
||||||
|
offset = -1
|
||||||
|
|
||||||
|
|
||||||
|
class MultipartParseError(ParseError):
|
||||||
|
"""This is a specific error that is raised when the MultipartParser detects
|
||||||
|
an error while parsing.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class QuerystringParseError(ParseError):
|
||||||
|
"""This is a specific error that is raised when the QuerystringParser
|
||||||
|
detects an error while parsing.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DecodeError(ParseError):
|
||||||
|
"""This exception is raised when there is a decoding error - for example
|
||||||
|
with the Base64Decoder or QuotedPrintableDecoder.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# On Python 3.3, IOError is the same as OSError, so we don't want to inherit
|
||||||
|
# from both of them. We handle this case below.
|
||||||
|
if IOError is not OSError: # pragma: no cover
|
||||||
|
class FileError(FormParserError, IOError, OSError):
|
||||||
|
"""Exception class for problems with the File class."""
|
||||||
|
pass
|
||||||
|
else: # pragma: no cover
|
||||||
|
class FileError(FormParserError, OSError):
|
||||||
|
"""Exception class for problems with the File class."""
|
||||||
|
pass
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,133 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import types
|
||||||
|
import functools
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_in_path(path):
|
||||||
|
"""
|
||||||
|
Ensure that a given path is in the sys.path array
|
||||||
|
"""
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
raise RuntimeError('Tried to add nonexisting path')
|
||||||
|
|
||||||
|
def _samefile(x, y):
|
||||||
|
try:
|
||||||
|
return os.path.samefile(x, y)
|
||||||
|
except OSError:
|
||||||
|
return False
|
||||||
|
except AttributeError:
|
||||||
|
# Probably on Windows.
|
||||||
|
path1 = os.path.abspath(x).lower()
|
||||||
|
path2 = os.path.abspath(y).lower()
|
||||||
|
return path1 == path2
|
||||||
|
|
||||||
|
# Remove existing copies of it.
|
||||||
|
for pth in sys.path:
|
||||||
|
if _samefile(pth, path):
|
||||||
|
sys.path.remove(pth)
|
||||||
|
|
||||||
|
# Add it at the beginning.
|
||||||
|
sys.path.insert(0, path)
|
||||||
|
|
||||||
|
|
||||||
|
# Check if pytest is imported. If so, we use it to create marking decorators.
|
||||||
|
# If not, we just create a function that does nothing.
|
||||||
|
try:
|
||||||
|
import pytest
|
||||||
|
except ImportError:
|
||||||
|
pytest = None
|
||||||
|
|
||||||
|
if pytest is not None:
|
||||||
|
slow_test = pytest.mark.slow_test
|
||||||
|
xfail = pytest.mark.xfail
|
||||||
|
|
||||||
|
else:
|
||||||
|
slow_test = lambda x: x
|
||||||
|
|
||||||
|
def xfail(*args, **kwargs):
|
||||||
|
if len(args) > 0 and isinstance(args[0], types.FunctionType):
|
||||||
|
return args[0]
|
||||||
|
|
||||||
|
return lambda x: x
|
||||||
|
|
||||||
|
|
||||||
|
# We don't use the pytest parametrizing function, since it seems to break
|
||||||
|
# with unittest.TestCase subclasses.
|
||||||
|
def parametrize(field_names, field_values):
|
||||||
|
# If we're not given a list of field names, we make it.
|
||||||
|
if not isinstance(field_names, (tuple, list)):
|
||||||
|
field_names = (field_names,)
|
||||||
|
field_values = [(val,) for val in field_values]
|
||||||
|
|
||||||
|
# Create a decorator that saves this list of field names and values on the
|
||||||
|
# function for later parametrizing.
|
||||||
|
def decorator(func):
|
||||||
|
func.__dict__['param_names'] = field_names
|
||||||
|
func.__dict__['param_values'] = field_values
|
||||||
|
return func
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
# This is a metaclass that actually performs the parametrization.
|
||||||
|
class ParametrizingMetaclass(type):
|
||||||
|
IDENTIFIER_RE = re.compile('[^A-Za-z0-9]')
|
||||||
|
|
||||||
|
def __new__(klass, name, bases, attrs):
|
||||||
|
new_attrs = attrs.copy()
|
||||||
|
for attr_name, attr in attrs.items():
|
||||||
|
# We only care about functions
|
||||||
|
if not isinstance(attr, types.FunctionType):
|
||||||
|
continue
|
||||||
|
|
||||||
|
param_names = attr.__dict__.pop('param_names', None)
|
||||||
|
param_values = attr.__dict__.pop('param_values', None)
|
||||||
|
if param_names is None or param_values is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Create multiple copies of the function.
|
||||||
|
for i, values in enumerate(param_values):
|
||||||
|
assert len(param_names) == len(values)
|
||||||
|
|
||||||
|
# Get a repr of the values, and fix it to be a valid identifier
|
||||||
|
human = '_'.join(
|
||||||
|
[klass.IDENTIFIER_RE.sub('', repr(x)) for x in values]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create a new name.
|
||||||
|
# new_name = attr.__name__ + "_%d" % i
|
||||||
|
new_name = attr.__name__ + "__" + human
|
||||||
|
|
||||||
|
# Create a replacement function.
|
||||||
|
def create_new_func(func, names, values):
|
||||||
|
# Create a kwargs dictionary.
|
||||||
|
kwargs = dict(zip(names, values))
|
||||||
|
|
||||||
|
@functools.wraps(func)
|
||||||
|
def new_func(self):
|
||||||
|
return func(self, **kwargs)
|
||||||
|
|
||||||
|
# Manually set the name and return the new function.
|
||||||
|
new_func.__name__ = new_name
|
||||||
|
return new_func
|
||||||
|
|
||||||
|
# Actually create the new function.
|
||||||
|
new_func = create_new_func(attr, param_names, values)
|
||||||
|
|
||||||
|
# Save this new function in our attrs dict.
|
||||||
|
new_attrs[new_name] = new_func
|
||||||
|
|
||||||
|
# Remove the old attribute from our new dictionary.
|
||||||
|
del new_attrs[attr_name]
|
||||||
|
|
||||||
|
# We create the class as normal, except we use our new attributes.
|
||||||
|
return type.__new__(klass, name, bases, new_attrs)
|
||||||
|
|
||||||
|
|
||||||
|
# This is a class decorator that actually applies the above metaclass.
|
||||||
|
def parametrize_class(klass):
|
||||||
|
return ParametrizingMetaclass(klass.__name__,
|
||||||
|
klass.__bases__,
|
||||||
|
klass.__dict__)
|
@ -0,0 +1,5 @@
|
|||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
Content-
isposition: form-data; name="field"
|
||||||
|
|
||||||
|
This is a test.
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc--
|
@ -0,0 +1,3 @@
|
|||||||
|
boundary: ----WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
expected:
|
||||||
|
error: 51
|
@ -0,0 +1,5 @@
|
|||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
Content-Disposition: form-data; n
me="field"
|
||||||
|
|
||||||
|
This is a test.
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc--
|
@ -0,0 +1,3 @@
|
|||||||
|
boundary: ----WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
expected:
|
||||||
|
error: 76
|
@ -0,0 +1,13 @@
|
|||||||
|
----boundary
|
||||||
|
Content-Disposition: form-data; name="file"; filename="test.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
--boundari
|
||||||
|
--boundaryq--boundary
q--boundarq
|
||||||
|
--bounaryd--
|
||||||
|
--notbound--
|
||||||
|
--mismatch
|
||||||
|
--mismatch--
|
||||||
|
--boundary-Q
|
||||||
|
--boundary
Q--boundaryQ
|
||||||
|
----boundary--
|
@ -0,0 +1,8 @@
|
|||||||
|
boundary: --boundary
|
||||||
|
expected:
|
||||||
|
- name: file
|
||||||
|
type: file
|
||||||
|
file_name: test.txt
|
||||||
|
data: !!binary |
|
||||||
|
LS1ib3VuZGFyaQ0KLS1ib3VuZGFyeXEtLWJvdW5kYXJ5DXEtLWJvdW5kYXJxDQotLWJvdW5hcnlkLS0NCi0tbm90Ym91bmQtLQ0KLS1taXNtYXRjaA0KLS1taXNtYXRjaC0tDQotLWJvdW5kYXJ5LVENCi0tYm91bmRhcnkNUS0tYm91bmRhcnlR
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
----boundary
|
||||||
|
Content-Disposition: form-data; name="field"
|
||||||
|
|
||||||
|
QQQQQQQQQQQQQQQQQQQQ
|
||||||
|
----boundaryQQQQQQQQQQQQQQQQQQQQ
|
||||||
|
----boundary--
|
@ -0,0 +1,8 @@
|
|||||||
|
boundary: --boundary
|
||||||
|
expected:
|
||||||
|
- name: field
|
||||||
|
type: field
|
||||||
|
data: !!binary |
|
||||||
|
UVFRUVFRUVFRUVFRUVFRUVFRUVENCi0tLS1ib3VuZGFyeVFRUVFRUVFRUVFRUVFRUVFRUVFR
|
||||||
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
----boundary
|
||||||
|
Content-Disposition: form-data; name="field"
|
||||||
|
|
||||||
|
QQQQQQQQQQQQQQQQQQQQ
|
||||||
|
----boundary
QQQQQQQQQQQQQQQQQQQQ
|
||||||
|
----boundary--
|
@ -0,0 +1,8 @@
|
|||||||
|
boundary: --boundary
|
||||||
|
expected:
|
||||||
|
- name: field
|
||||||
|
type: field
|
||||||
|
data: !!binary |
|
||||||
|
UVFRUVFRUVFRUVFRUVFRUVFRUVENCi0tLS1ib3VuZGFyeQ1RUVFRUVFRUVFRUVFRUVFRUVFRUQ==
|
||||||
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
----boundary
|
||||||
|
Content-Disposition: form-data; name="field"
|
||||||
|
|
||||||
|
QQQQQQQQQQQQQQQQQQQQ
|
||||||
|
----boundary-QQQQQQQQQQQQQQQQQQQQ
|
||||||
|
----boundary--
|
@ -0,0 +1,8 @@
|
|||||||
|
boundary: --boundary
|
||||||
|
expected:
|
||||||
|
- name: field
|
||||||
|
type: field
|
||||||
|
data: !!binary |
|
||||||
|
UVFRUVFRUVFRUVFRUVFRUVFRUVENCi0tLS1ib3VuZGFyeS1RUVFRUVFRUVFRUVFRUVFRUVFRUQ==
|
||||||
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
|||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
Content-Disposition: form-data; name="field"
|
||||||
|
QThis is a test.
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc--
|
@ -0,0 +1,3 @@
|
|||||||
|
boundary: ----WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
expected:
|
||||||
|
error: 89
|
@ -0,0 +1,5 @@
|
|||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
Content-999position: form-data; name="field"
|
||||||
|
|
||||||
|
This is a test.
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc--
|
@ -0,0 +1,3 @@
|
|||||||
|
boundary: ----WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
expected:
|
||||||
|
error: 50
|
@ -0,0 +1,5 @@
|
|||||||
|
------WebQitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
Content-Disposition: form-data; name="field"
|
||||||
|
|
||||||
|
This is a test.
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc--
|
@ -0,0 +1,3 @@
|
|||||||
|
boundary: ----WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
expected:
|
||||||
|
error: 9
|
@ -0,0 +1,7 @@
|
|||||||
|
----boundary
|
||||||
|
Content-Disposition: form-data; name="file"; filename="test.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: base64
|
||||||
|
|
||||||
|
VGVzdCAxMjM=
|
||||||
|
----boundary--
|
@ -0,0 +1,7 @@
|
|||||||
|
boundary: --boundary
|
||||||
|
expected:
|
||||||
|
- name: file
|
||||||
|
type: file
|
||||||
|
file_name: test.txt
|
||||||
|
data: !!binary |
|
||||||
|
VGVzdCAxMjM=
|
@ -0,0 +1,5 @@
|
|||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
: form-data; name="field"
|
||||||
|
|
||||||
|
This is a test.
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc--
|
@ -0,0 +1,3 @@
|
|||||||
|
boundary: ----WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
expected:
|
||||||
|
error: 42
|
@ -0,0 +1,9 @@
|
|||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
Content-Disposition: form-data; name="field1"
|
||||||
|
|
||||||
|
field1
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
Content-Disposition: form-data; name="field2"
|
||||||
|
|
||||||
|
field2
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc--
|
@ -0,0 +1,10 @@
|
|||||||
|
boundary: ----WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
expected:
|
||||||
|
- name: field1
|
||||||
|
type: field
|
||||||
|
data: !!binary |
|
||||||
|
ZmllbGQx
|
||||||
|
- name: field2
|
||||||
|
type: field
|
||||||
|
data: !!binary |
|
||||||
|
ZmllbGQy
|
@ -0,0 +1,11 @@
|
|||||||
|
------WebKitFormBoundarygbACTUR58IyeurVf
|
||||||
|
Content-Disposition: form-data; name="file1"; filename="test1.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
Test file #1
|
||||||
|
------WebKitFormBoundarygbACTUR58IyeurVf
|
||||||
|
Content-Disposition: form-data; name="file2"; filename="test2.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
Test file #2
|
||||||
|
------WebKitFormBoundarygbACTUR58IyeurVf--
|
@ -0,0 +1,13 @@
|
|||||||
|
boundary: ----WebKitFormBoundarygbACTUR58IyeurVf
|
||||||
|
expected:
|
||||||
|
- name: file1
|
||||||
|
type: file
|
||||||
|
file_name: test1.txt
|
||||||
|
data: !!binary |
|
||||||
|
VGVzdCBmaWxlICMx
|
||||||
|
- name: file2
|
||||||
|
type: file
|
||||||
|
file_name: test2.txt
|
||||||
|
data: !!binary |
|
||||||
|
VGVzdCBmaWxlICMy
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
----boundary
|
||||||
|
Content-Disposition: form-data; name="file"; filename="test.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
|
foo=3Dbar
|
||||||
|
----boundary--
|
@ -0,0 +1,7 @@
|
|||||||
|
boundary: --boundary
|
||||||
|
expected:
|
||||||
|
- name: file
|
||||||
|
type: file
|
||||||
|
file_name: test.txt
|
||||||
|
data: !!binary |
|
||||||
|
Zm9vPWJhcg==
|
@ -0,0 +1,5 @@
|
|||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
Content-Disposition: form-data; name="field"
|
||||||
|
|
||||||
|
This is a test.
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc--
|
@ -0,0 +1,6 @@
|
|||||||
|
boundary: ----WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
expected:
|
||||||
|
- name: field
|
||||||
|
type: field
|
||||||
|
data: !!binary |
|
||||||
|
VGhpcyBpcyBhIHRlc3Qu
|
@ -0,0 +1,5 @@
|
|||||||
|
--boundary
|
||||||
|
Content-Disposition: form-data; name="field"
|
||||||
|
|
||||||
|
0123456789ABCDEFGHIJ0123456789ABCDEFGHIJ
|
||||||
|
--boundary--
|
@ -0,0 +1,6 @@
|
|||||||
|
boundary: --boundary
|
||||||
|
expected:
|
||||||
|
- name: field
|
||||||
|
type: field
|
||||||
|
data: !!binary |
|
||||||
|
MDEyMzQ1Njc4OUFCQ0RFRkdISUowMTIzNDU2Nzg5QUJDREVGR0hJSg==
|
@ -0,0 +1,5 @@
|
|||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
Content-Disposition: form-data; name="field"
|
||||||
|
|
||||||
|
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc--
|
@ -0,0 +1,6 @@
|
|||||||
|
boundary: ----WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
expected:
|
||||||
|
- name: field
|
||||||
|
type: field
|
||||||
|
data: !!binary |
|
||||||
|
cXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE=
|
@ -0,0 +1,10 @@
|
|||||||
|
--boundary
|
||||||
|
Content-Disposition: form-data; name="field"
|
||||||
|
|
||||||
|
test1
|
||||||
|
--boundary
|
||||||
|
Content-Disposition: form-data; name="file"; filename="file.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
test2
|
||||||
|
--boundary--
|
@ -0,0 +1,13 @@
|
|||||||
|
boundary: boundary
|
||||||
|
expected:
|
||||||
|
- name: field
|
||||||
|
type: field
|
||||||
|
data: !!binary |
|
||||||
|
dGVzdDE=
|
||||||
|
- name: file
|
||||||
|
type: file
|
||||||
|
file_name: file.txt
|
||||||
|
data: !!binary |
|
||||||
|
dGVzdDI=
|
||||||
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
Content-Disposition: form-data; name="field"
|
||||||
|
|
||||||
|
This is a test.
|
||||||
|
------WebKitFormBoundaryTkr3kCBQlBe1nrhc--
|
@ -0,0 +1,6 @@
|
|||||||
|
boundary: ----WebKitFormBoundaryTkr3kCBQlBe1nrhc
|
||||||
|
expected:
|
||||||
|
- name: field
|
||||||
|
type: field
|
||||||
|
data: !!binary |
|
||||||
|
VGhpcyBpcyBhIHRlc3Qu
|
@ -0,0 +1,6 @@
|
|||||||
|
------WebKitFormBoundary5BZGOJCWtXGYC9HW
|
||||||
|
Content-Disposition: form-data; name="file"; filename="test.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
This is a test file.
|
||||||
|
------WebKitFormBoundary5BZGOJCWtXGYC9HW--
|
@ -0,0 +1,8 @@
|
|||||||
|
boundary: ----WebKitFormBoundary5BZGOJCWtXGYC9HW
|
||||||
|
expected:
|
||||||
|
- name: file
|
||||||
|
type: file
|
||||||
|
file_name: test.txt
|
||||||
|
data: !!binary |
|
||||||
|
VGhpcyBpcyBhIHRlc3QgZmlsZS4=
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
------WebKitFormBoundaryI9SCEFp2lpx5DR2K
|
||||||
|
Content-Disposition: form-data; name="file"; filename="???.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
これはテストです。
|
||||||
|
------WebKitFormBoundaryI9SCEFp2lpx5DR2K--
|
@ -0,0 +1,8 @@
|
|||||||
|
boundary: ----WebKitFormBoundaryI9SCEFp2lpx5DR2K
|
||||||
|
expected:
|
||||||
|
- name: file
|
||||||
|
type: file
|
||||||
|
file_name: ???.txt
|
||||||
|
data: !!binary |
|
||||||
|
44GT44KM44Gv44OG44K544OI44Gn44GZ44CC
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@
|
|||||||
|
pip
|
@ -0,0 +1,69 @@
|
|||||||
|
Metadata-Version: 2.1
|
||||||
|
Name: python-multipart
|
||||||
|
Version: 0.0.6
|
||||||
|
Summary: A streaming multipart parser for Python
|
||||||
|
Project-URL: Homepage, https://github.com/andrew-d/python-multipart
|
||||||
|
Project-URL: Documentation, https://andrew-d.github.io/python-multipart/
|
||||||
|
Project-URL: Changelog, https://github.com/andrew-d/python-multipart/tags
|
||||||
|
Project-URL: Source, https://github.com/andrew-d/python-multipart
|
||||||
|
Author-email: Andrew Dunham <andrew@du.nham.ca>
|
||||||
|
License-Expression: Apache-2.0
|
||||||
|
License-File: LICENSE.txt
|
||||||
|
Classifier: Development Status :: 5 - Production/Stable
|
||||||
|
Classifier: Environment :: Web Environment
|
||||||
|
Classifier: Intended Audience :: Developers
|
||||||
|
Classifier: License :: OSI Approved :: Apache Software License
|
||||||
|
Classifier: Operating System :: OS Independent
|
||||||
|
Classifier: Programming Language :: Python :: 3
|
||||||
|
Classifier: Programming Language :: Python :: 3 :: Only
|
||||||
|
Classifier: Programming Language :: Python :: 3.7
|
||||||
|
Classifier: Programming Language :: Python :: 3.8
|
||||||
|
Classifier: Programming Language :: Python :: 3.9
|
||||||
|
Classifier: Programming Language :: Python :: 3.10
|
||||||
|
Classifier: Programming Language :: Python :: 3.11
|
||||||
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||||
|
Requires-Python: >=3.7
|
||||||
|
Provides-Extra: dev
|
||||||
|
Requires-Dist: atomicwrites==1.2.1; extra == 'dev'
|
||||||
|
Requires-Dist: attrs==19.2.0; extra == 'dev'
|
||||||
|
Requires-Dist: coverage==6.5.0; extra == 'dev'
|
||||||
|
Requires-Dist: hatch; extra == 'dev'
|
||||||
|
Requires-Dist: invoke==1.7.3; extra == 'dev'
|
||||||
|
Requires-Dist: more-itertools==4.3.0; extra == 'dev'
|
||||||
|
Requires-Dist: pbr==4.3.0; extra == 'dev'
|
||||||
|
Requires-Dist: pluggy==1.0.0; extra == 'dev'
|
||||||
|
Requires-Dist: py==1.11.0; extra == 'dev'
|
||||||
|
Requires-Dist: pytest-cov==4.0.0; extra == 'dev'
|
||||||
|
Requires-Dist: pytest-timeout==2.1.0; extra == 'dev'
|
||||||
|
Requires-Dist: pytest==7.2.0; extra == 'dev'
|
||||||
|
Requires-Dist: pyyaml==5.1; extra == 'dev'
|
||||||
|
Description-Content-Type: text/x-rst
|
||||||
|
|
||||||
|
==================
|
||||||
|
Python-Multipart
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. image:: https://github.com/andrew-d/python-multipart/actions/workflows/test.yaml/badge.svg
|
||||||
|
:target: https://github.com/andrew-d/python-multipart/actions
|
||||||
|
|
||||||
|
|
||||||
|
python-multipart is an Apache2 licensed streaming multipart parser for Python.
|
||||||
|
Test coverage is currently 100%.
|
||||||
|
Documentation is available `here`_.
|
||||||
|
|
||||||
|
.. _here: https://andrew-d.github.io/python-multipart/
|
||||||
|
|
||||||
|
Why?
|
||||||
|
----
|
||||||
|
|
||||||
|
Because streaming uploads are awesome for large files.
|
||||||
|
|
||||||
|
How to Test
|
||||||
|
-----------
|
||||||
|
|
||||||
|
If you want to test:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ pip install .[dev]
|
||||||
|
$ inv test
|
@ -0,0 +1,62 @@
|
|||||||
|
multipart/__init__.py,sha256=EaZd7hXXXNz5RWfzZ4lr-wKWXC4anMNWE7u4tPXtWr0,335
|
||||||
|
multipart/__pycache__/__init__.cpython-37.pyc,,
|
||||||
|
multipart/__pycache__/decoders.cpython-37.pyc,,
|
||||||
|
multipart/__pycache__/exceptions.cpython-37.pyc,,
|
||||||
|
multipart/__pycache__/multipart.cpython-37.pyc,,
|
||||||
|
multipart/decoders.py,sha256=6LeCVARmDrQgmMsaul1WUIf79Q-mLE9swhGxumQe_98,6107
|
||||||
|
multipart/exceptions.py,sha256=yDZ9pqq3Y9ZMCvj2TkAvOcNdMjFHjLnHl4luFnzt750,1410
|
||||||
|
multipart/multipart.py,sha256=ZRc1beZCgCIXkYe0Xwxh_g4nFdrp3eEid4XODYIfqgQ,71230
|
||||||
|
multipart/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||||
|
multipart/tests/__pycache__/__init__.cpython-37.pyc,,
|
||||||
|
multipart/tests/__pycache__/compat.cpython-37.pyc,,
|
||||||
|
multipart/tests/__pycache__/test_multipart.cpython-37.pyc,,
|
||||||
|
multipart/tests/compat.py,sha256=3aowcimO1SYU6WqS3GlUJ3jmkgLH63e8AsUPjlta1xU,4266
|
||||||
|
multipart/tests/test_data/http/CR_in_header.http,sha256=XEimN_BgEqQXCqK463bMgD9PKIQeLrQhWt2M3vNr9cE,149
|
||||||
|
multipart/tests/test_data/http/CR_in_header.yaml,sha256=OEzE2PqK78fi9kjM23YOu4xM0zQ_LRwSiwqFNAmku50,73
|
||||||
|
multipart/tests/test_data/http/CR_in_header_value.http,sha256=pf4sP-l4_hzZ8Kr51gUE6CFcCifuWSZ10-vnx6mtXDg,149
|
||||||
|
multipart/tests/test_data/http/CR_in_header_value.yaml,sha256=WjqJNYL-cUH2n9k-Xdy1YDvSfDqqXxsiinBDn3HTUu4,73
|
||||||
|
multipart/tests/test_data/http/almost_match_boundary.http,sha256=jIsp1M6BHQIHF9o965z3Pt8TFncVvaBj5N43hprRpBM,264
|
||||||
|
multipart/tests/test_data/http/almost_match_boundary.yaml,sha256=Hr7WZBwZrbf4vjurjRzGGeY9tFVJLRRmV1rEFXop-6s,300
|
||||||
|
multipart/tests/test_data/http/almost_match_boundary_without_CR.http,sha256=KviMqo_FUy1N1-b-YUfyWhs5PmN6_fU7qhMYFTGnUhI,132
|
||||||
|
multipart/tests/test_data/http/almost_match_boundary_without_CR.yaml,sha256=HjlUni-nuX3bG2-3FILo4GLBpLD4DImQ48VPlfnfIWY,167
|
||||||
|
multipart/tests/test_data/http/almost_match_boundary_without_LF.http,sha256=KylmJ0O-RfnUnXbjVhwJpzHsWqNTPJn29_wfsvrG7AM,133
|
||||||
|
multipart/tests/test_data/http/almost_match_boundary_without_LF.yaml,sha256=tkzz_kOFZtkarmMnTen355nm8McPwbmPmWGMxUUBSzU,171
|
||||||
|
multipart/tests/test_data/http/almost_match_boundary_without_final_hyphen.http,sha256=L6bzRistD4X5TTd1zBtfR6gM4EQL77_iBI_Pgaw4ufw,133
|
||||||
|
multipart/tests/test_data/http/almost_match_boundary_without_final_hyphen.yaml,sha256=cFKxwFMYTo9PKRb04Iai__mY9KG29IPkSm3p80DgEZw,171
|
||||||
|
multipart/tests/test_data/http/bad_end_of_headers.http,sha256=ucEDylTCg1_hdEVkIc-1k8ZQ-CBIf5uXfDKbSBsSaF0,149
|
||||||
|
multipart/tests/test_data/http/bad_end_of_headers.yaml,sha256=1UHERY2D7tp0HEUl5xD4SiotP2skETmBOF5EjcG2HTw,73
|
||||||
|
multipart/tests/test_data/http/bad_header_char.http,sha256=zTqXFNQ9yrbc82vubPg95T4edg1Ueh2xadlVD2lO51A,149
|
||||||
|
multipart/tests/test_data/http/bad_header_char.yaml,sha256=9ykVsASnvYvX51qtkCJqhgegeN-hoSU40MsYQvqeVNo,73
|
||||||
|
multipart/tests/test_data/http/bad_initial_boundary.http,sha256=IGFSkpmw21XfAXr0xOHwj0vnhxyj-uCWVjcljo68LLo,149
|
||||||
|
multipart/tests/test_data/http/bad_initial_boundary.yaml,sha256=eBSbue0BYDYhYtKdBCnm1LGq0O_fOMwV6ZoLpZFDFM4,72
|
||||||
|
multipart/tests/test_data/http/base64_encoding.http,sha256=fDbr4BgLdNS8kYiTO7g4HxB81hvmiD2sRUCAoijfRx0,173
|
||||||
|
multipart/tests/test_data/http/base64_encoding.yaml,sha256=cz2KxZxoi81MiXRh7DmJQOWcdqQH5ahkrJydGYv4hpU,125
|
||||||
|
multipart/tests/test_data/http/empty_header.http,sha256=-wSHHSLu1D2wfdC8Zcaw5TX_USTvWz56CANpsceOZYQ,130
|
||||||
|
multipart/tests/test_data/http/empty_header.yaml,sha256=4xdVCYJ-l88HMXkMLNkSQoLNgURoGcKzR1AclPLpkOc,73
|
||||||
|
multipart/tests/test_data/http/multiple_fields.http,sha256=6p93ls_B7bk8mXPYhsrFwvktSX8CuRdUH4vn-EZBaRM,242
|
||||||
|
multipart/tests/test_data/http/multiple_fields.yaml,sha256=mePM5DVfAzty7QNEEyMu2qrFI28TbG9yWRvWFpWj7Jo,197
|
||||||
|
multipart/tests/test_data/http/multiple_files.http,sha256=EtmagVBVpsFGnCqlwfKgswQfU8lGa3QNkP6GVJBa5A0,348
|
||||||
|
multipart/tests/test_data/http/multiple_files.yaml,sha256=QO9JMgTvkL2EmIWAl8LcbDrkfNmDk0eA5SOk3gFuFWE,260
|
||||||
|
multipart/tests/test_data/http/quoted_printable_encoding.http,sha256=--yYceg17SmqIJsazw-SFChdxeTAq8zV4lzPVM_QMrM,180
|
||||||
|
multipart/tests/test_data/http/quoted_printable_encoding.yaml,sha256=G_L6lnP-e4uHfGpYQFopxDdpbd_EbxL2oY8N910BTOI,127
|
||||||
|
multipart/tests/test_data/http/single_field.http,sha256=JjdSwFiM0mG07HYzBCcjzeqgqAA9glx-VcRUjkOh8cA,149
|
||||||
|
multipart/tests/test_data/http/single_field.yaml,sha256=HMXd14-m9sKBvTsnzWOaG12_3wve5SoXeUISF93wlRc,139
|
||||||
|
multipart/tests/test_data/http/single_field_blocks.http,sha256=4laZAIbFmxERZtgPWzuOihvEhLWD1NGTSdqZ6Ra58Ns,115
|
||||||
|
multipart/tests/test_data/http/single_field_blocks.yaml,sha256=6mKvHtmiXh6OxoibJsx5pUreIMyQyPb_DWy7GEG9BX8,147
|
||||||
|
multipart/tests/test_data/http/single_field_longer.http,sha256=BTBt1MsUaxuHauu-mljb3lU-8Z2dpjRN_lkZW4pkDXA,262
|
||||||
|
multipart/tests/test_data/http/single_field_longer.yaml,sha256=aENhQPtHaTPIvgJbdiDHvcOtcthEEUHCQIEfLj0aalY,293
|
||||||
|
multipart/tests/test_data/http/single_field_single_file.http,sha256=G4dV0iCSjvEk5DSJ1VXWy6R8Hon3-WOExep41nPWVeQ,192
|
||||||
|
multipart/tests/test_data/http/single_field_single_file.yaml,sha256=QO9gqdXQsoizLji9r8kdlPWHJB5vO7wszqP1fHvsNV8,189
|
||||||
|
multipart/tests/test_data/http/single_field_with_leading_newlines.http,sha256=YfNEUdZxbi4bBGTU4T4WSQZ6QJDJlcLZUczYzGU5Jaw,153
|
||||||
|
multipart/tests/test_data/http/single_field_with_leading_newlines.yaml,sha256=HMXd14-m9sKBvTsnzWOaG12_3wve5SoXeUISF93wlRc,139
|
||||||
|
multipart/tests/test_data/http/single_file.http,sha256=axRB0Keb4uhAfHxt7Na1x9-PQHCiiKK8s38a2GG860E,202
|
||||||
|
multipart/tests/test_data/http/single_file.yaml,sha256=eUKyGkNTDrXdGni4EyEDbxDBTfAKsstVQ5O5SWghYTc,170
|
||||||
|
multipart/tests/test_data/http/utf8_filename.http,sha256=w_Ryf4hC_KJo7v-a18dJFECqm21nzA5Z18dsGyu6zjA,208
|
||||||
|
multipart/tests/test_data/http/utf8_filename.yaml,sha256=KpDc4e-yYp_JUXa-S5lp591tzoEybgywtGian0kQFPc,177
|
||||||
|
multipart/tests/test_multipart.py,sha256=VrxoOtXO4NWpT1OJqo7FWWIybnxGReumIWCR-FDIHCk,38988
|
||||||
|
python_multipart-0.0.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||||
|
python_multipart-0.0.6.dist-info/METADATA,sha256=J4WQf99XHSSg_EDG7fGgJGotS_Hp7ViCtpY4rQ2OgyM,2459
|
||||||
|
python_multipart-0.0.6.dist-info/RECORD,,
|
||||||
|
python_multipart-0.0.6.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||||
|
python_multipart-0.0.6.dist-info/WHEEL,sha256=Fd6mP6ydyRguakwUJ05oBE7fh2IPxgtDN9IwHJ9OqJQ,87
|
||||||
|
python_multipart-0.0.6.dist-info/licenses/LICENSE.txt,sha256=qOgzF2zWF9rwC51tOfoVyo7evG0WQwec0vSJPAwom-I,556
|
@ -0,0 +1,4 @@
|
|||||||
|
Wheel-Version: 1.0
|
||||||
|
Generator: hatchling 1.13.0
|
||||||
|
Root-Is-Purelib: true
|
||||||
|
Tag: py3-none-any
|
@ -0,0 +1,14 @@
|
|||||||
|
Copyright 2012, Andrew Dunham
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
& separates commands on a line.
|
||||||
|
|
||||||
|
&& executes this command only if previous command's errorlevel is 0.
|
||||||
|
|
||||||
|
|| (not used above) executes this command only if previous command's errorlevel is NOT 0
|
||||||
|
|
||||||
|
> output to a file
|
||||||
|
|
||||||
|
>> append output to a file
|
||||||
|
|
||||||
|
< input from a file
|
||||||
|
|
||||||
|
| output of one command into the input of another command
|
||||||
|
|
||||||
|
^ escapes any of the above, including itself, if needed to be passed to a program
|
||||||
|
|
||||||
|
" parameters with spaces must be enclosed in quotes
|
||||||
|
|
||||||
|
+ used with copy to concatenate files. E.G. copy file1+file2 newfile
|
||||||
|
|
||||||
|
, used with copy to indicate missing parameters. This updates the files modified date. E.G. copy /b file1,,
|
||||||
|
|
||||||
|
%variablename% a inbuilt or user set environmental variable
|
||||||
|
|
||||||
|
!variablename! a user set environmental variable expanded at execution time, turned with SetLocal EnableDelayedExpansion command
|
||||||
|
|
||||||
|
%<number> (%1) the nth command line parameter passed to a batch file. %0 is the batchfile's name.
|
||||||
|
|
||||||
|
%* (%*) the entire command line.
|
||||||
|
|
||||||
|
%<a letter> or %%<a letter> (%A or %%A) the variable in a for loop. Single % sign at command prompt and double % sign in a batch file.
|
@ -0,0 +1,24 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001
|
||||||
|
echo Формат использования PythonWinInit.cmd [console,script] [имя запускаемого процесса.exe] [имя убиваемого процесса.exe]
|
||||||
|
echo Пример использования PythonWinInit.cmd script orpa-rbt.exe orpa-rbt.exe
|
||||||
|
|
||||||
|
if [%2]==[] goto :python-env
|
||||||
|
goto create-exe
|
||||||
|
:create-exe
|
||||||
|
copy /Y "%~dp0..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe" "%~dp0..\Resources\WPy64-3720\python-3.7.2.amd64\%2"
|
||||||
|
if [%3]==[] goto :python-env
|
||||||
|
goto taskkill
|
||||||
|
:taskkill
|
||||||
|
taskkill /im "%3" /F /fi "username eq %username%"
|
||||||
|
goto :python-env
|
||||||
|
:python-env
|
||||||
|
call "%~dp0PythonWinConfigure.cmd"
|
||||||
|
echo Инициализация Python окружения прошла успешно!
|
||||||
|
if [%1]==[] goto :console
|
||||||
|
if [%1]==[console] goto :console
|
||||||
|
goto :eof
|
||||||
|
:console
|
||||||
|
cmd
|
||||||
|
:eof
|
||||||
|
@echo on
|
@ -0,0 +1,22 @@
|
|||||||
|
####################################
|
||||||
|
2. Список изменений
|
||||||
|
####################################
|
||||||
|
|
||||||
|
Ниже представлен список изменений в релизах pyOpenRPA
|
||||||
|
|
||||||
|
.. include:: ../../../changelog.md
|
||||||
|
:literal:
|
||||||
|
|
||||||
|
|
||||||
|
pyOpenRPA - роботы помогут!
|
||||||
|
|
||||||
|
******************************
|
||||||
|
Быстрая навигация
|
||||||
|
******************************
|
||||||
|
|
||||||
|
- `Сообщество pyOpenRPA (telegram) <https://t.me/pyOpenRPA>`_
|
||||||
|
- `Сообщество pyOpenRPA (tenchat) <https://tenchat.ru/iMaslov?utm_source=19f2a84f-3268-437f-950c-d987ae42af24>`_
|
||||||
|
- `Сообщество pyOpenRPA (вконтакте) <https://vk.com/pyopenrpa>`_
|
||||||
|
- `Презентация pyOpenRPA <https://pyopenrpa.ru/Index/pyOpenRPA_product_service.pdf>`_
|
||||||
|
- `Портал pyOpenRPA <https://pyopenrpa.ru>`_
|
||||||
|
- `Репозиторий pyOpenRPA <https://gitlab.com/UnicodeLabs/OpenRPA>`_
|
@ -0,0 +1,65 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" >
|
||||||
|
<head>
|
||||||
|
<!-- Yandex.Metrika counter -->
|
||||||
|
<script async="" src="https://mc.yandex.ru/metrika/tag.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||||
|
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||||
|
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||||
|
|
||||||
|
ym(88079149, "init", {
|
||||||
|
clickmap:true,
|
||||||
|
trackLinks:true,
|
||||||
|
accurateTrackBounce:true,
|
||||||
|
webvisor:true
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<noscript><div><img src="https://mc.yandex.ru/watch/88079149" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||||
|
<!-- /Yandex.Metrika counter -->
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>Оркестратор pyOpenRPA</title>
|
||||||
|
<meta name="description" content="Ведущий RPA разработчик российского программного обеспечения. RPA платформа позволяет решать любые бизнес-задачи. Комплексное решение от компании RPA pyOpenRPA. Первое открытое российское RPA решение для крупного / среднего / малого бизнеса. Доступная автоматизация для каждого." />
|
||||||
|
<meta name="keywords" content="rpa, программные роботы, автоматизация бизнес-процессов, цифровые сотрудники, виртуальные сотрудники" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/orpa/resources/Web/Semantic-UI-CSS-master/semantic.min.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/orpa/resources/Web/orpa/styleset/home.css" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
|
||||||
|
<script
|
||||||
|
src="/orpa/resources/Web/jQuery/jquery-3.1.1.min.js"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="/orpa/resources/Web/Semantic-UI-CSS-master/semantic.min.js"></script>
|
||||||
|
<script src="/orpa/resources/Web/Handlebars/handlebars-v4.1.2.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<style type="text/css">
|
||||||
|
button.ui.green.button {
|
||||||
|
font-family:'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif;
|
||||||
|
background: #368279
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
{% include 'header.xhtml' %}
|
||||||
|
<br /><br /><br /><br /><br />
|
||||||
|
<center>
|
||||||
|
<div class="ui message">
|
||||||
|
<div class="header">Внимание</div>
|
||||||
|
<p>{{errorMsg}}</p>
|
||||||
|
</div>
|
||||||
|
<button class="ui green button" onclick="document.location='/'" style="width: 200px;">Повторить попытку</button>
|
||||||
|
</center>
|
||||||
|
{% include 'footer.xhtml' %}
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
<style type="text/css">
|
||||||
|
.ui.footer.segment {
|
||||||
|
margin: 10.7em 0em 0em;
|
||||||
|
padding: 5em 0em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</html>
|
||||||
|
|
@ -1,24 +1 @@
|
|||||||
import os
|
from ..Utils.Debugger import *
|
||||||
import threading
|
|
||||||
import pdb
|
|
||||||
import time
|
|
||||||
|
|
||||||
"""Module wait file "init_debug" in working directory
|
|
||||||
"""
|
|
||||||
|
|
||||||
gKWARGS = None
|
|
||||||
|
|
||||||
def LiveDebugCheckLoop():
|
|
||||||
while True:
|
|
||||||
if os.path.exists("init_debug"):
|
|
||||||
pdb.set_trace()
|
|
||||||
time.sleep(30.0)
|
|
||||||
|
|
||||||
def LiveDebugCheckThread(**inKWARGS):
|
|
||||||
"""Create thread to wait file appear "init_debug" in the working directory.
|
|
||||||
"""
|
|
||||||
global gKWARGS
|
|
||||||
gKWARGS = inKWARGS
|
|
||||||
lThread = threading.Thread(target=LiveDebugCheckLoop)
|
|
||||||
lThread.setName("DEBUG_LIVE")
|
|
||||||
lThread.start()
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue