python-plugins 0.1.7__tar.gz → 0.1.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_plugins-0.1.7 → python_plugins-0.1.9}/CHANGES.rst +15 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/PKG-INFO +3 -2
- {python_plugins-0.1.7 → python_plugins-0.1.9}/docs/usage.rst +1 -1
- {python_plugins-0.1.7 → python_plugins-0.1.9}/pyproject.toml +1 -0
- python_plugins-0.1.9/src/python_plugins/__about__.py +1 -0
- python_plugins-0.1.9/src/python_plugins/crypto/__init__.py +2 -0
- python_plugins-0.1.9/src/python_plugins/crypto/file_to_file.py +70 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/crypto/str_to_list.py +7 -15
- python_plugins-0.1.9/src/python_plugins/examples/higher_order_functions.py +40 -0
- python_plugins-0.1.9/src/python_plugins/forms/__init__.py +2 -0
- python_plugins-0.1.9/src/python_plugins/forms/fields/__init__.py +2 -0
- python_plugins-0.1.9/src/python_plugins/forms/fields/datetime.py +100 -0
- python_plugins-0.1.9/src/python_plugins/forms/fields/json.py +19 -0
- python_plugins-0.1.9/src/python_plugins/forms/fields/select.py +123 -0
- python_plugins-0.1.9/src/python_plugins/forms/fields/switch.py +10 -0
- python_plugins-0.1.9/src/python_plugins/forms/fields/taglist.py +9 -0
- python_plugins-0.1.9/src/python_plugins/forms/widgets/datetime.py +30 -0
- python_plugins-0.1.9/src/python_plugins/forms/widgets/file.py +4 -0
- python_plugins-0.1.9/src/python_plugins/forms/widgets/select.py +26 -0
- python_plugins-0.1.9/src/python_plugins/models/__init__.py +0 -0
- python_plugins-0.1.9/src/python_plugins/utils/__init__.py +1 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/tests/test_crypt_file.py +23 -21
- {python_plugins-0.1.7 → python_plugins-0.1.9}/tests/test_crypto.py +1 -20
- python_plugins-0.1.9/tests/test_forms.py +19 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/tests/test_utils.py +2 -2
- python_plugins-0.1.7/src/python_plugins/__about__.py +0 -1
- python_plugins-0.1.7/src/python_plugins/crypto/__init__.py +0 -1
- python_plugins-0.1.7/src/python_plugins/crypto/file_to_file.py +0 -112
- {python_plugins-0.1.7 → python_plugins-0.1.9}/.github/workflows/release.yml +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/.gitignore +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/.readthedocs.yaml +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/LICENSE.rst +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/README.rst +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/docs/Makefile +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/docs/api.rst +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/docs/changes.rst +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/docs/conf.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/docs/examples.rst +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/docs/index.rst +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/docs/make.bat +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/docs/requirements.txt +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/examples/README.rst +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/requirements/build.in +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/requirements/test.in +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/__init__.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/convert/__init__.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/convert/datetime_str.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/convert/pretty.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/convert/xml.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/crypto/fernet.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/dumps/__init__.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/dumps/postgresql_dump.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/email/__init__.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/email/smtp.py +0 -0
- {python_plugins-0.1.7/src/python_plugins/models → python_plugins-0.1.9/src/python_plugins/forms/widgets}/__init__.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/hashes/__init__.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/hashes/hash.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/jwt/__init__.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/jwt/jwt.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/mixins/__init__.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/mixins/data_mixin.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/mixins/primary_key_mixin.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/mixins/timestamp_mixin.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/mixins/token_minxin.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/mixins/user_minxin.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/update.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/process/__init__.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/process/python_venv_process.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/process/sub_process.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/random/__init__.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/random/random_str.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/utils/remove_pycache.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/weixin/biz_data_crypt.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/weixin/error_code.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/weixin/format_response.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/weixin/wechat.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/weixin/wechat_crypt.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/weixin/weixin_api.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/tests/__init__.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/tests/conftest.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/tests/test_email.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/tests/test_jwt.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/tests/test_process.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/tests/test_random.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/tests/test_sqlalchemy.py +0 -0
- {python_plugins-0.1.7 → python_plugins-0.1.9}/tests/test_weixin.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: python-plugins
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9
|
|
4
4
|
Summary: A collection of Python functions and classes.
|
|
5
5
|
Project-URL: Documentation, https://python-plugins.readthedocs.io
|
|
6
6
|
Project-URL: Source, https://github.com/ojso/python-plugins
|
|
@@ -27,7 +27,6 @@ License: MIT License
|
|
|
27
27
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
28
28
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
29
29
|
SOFTWARE.
|
|
30
|
-
License-File: LICENSE.rst
|
|
31
30
|
Keywords: plugin,utils
|
|
32
31
|
Classifier: Development Status :: 3 - Alpha
|
|
33
32
|
Classifier: Intended Audience :: Developers
|
|
@@ -50,6 +49,8 @@ Provides-Extra: requests
|
|
|
50
49
|
Requires-Dist: requests; extra == 'requests'
|
|
51
50
|
Provides-Extra: sqlalchemy
|
|
52
51
|
Requires-Dist: sqlalchemy; extra == 'sqlalchemy'
|
|
52
|
+
Provides-Extra: wtforms
|
|
53
|
+
Requires-Dist: wtforms; extra == 'wtforms'
|
|
53
54
|
Description-Content-Type: text/x-rst
|
|
54
55
|
|
|
55
56
|
python-plugins
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.9"
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from getpass import getpass
|
|
3
|
+
from .str_to_list import encrypt_str_to_list
|
|
4
|
+
from .str_to_list import decrypt_list_to_str
|
|
5
|
+
|
|
6
|
+
def get_prompts_line(s, pattern=r"prompts\((\d+)\)"):
|
|
7
|
+
match = re.search(pattern, s)
|
|
8
|
+
if match:
|
|
9
|
+
return int(match[1])
|
|
10
|
+
|
|
11
|
+
def str_from_txtfile(fin) -> str:
|
|
12
|
+
with open(fin, encoding="utf-8") as f:
|
|
13
|
+
s = f.read()
|
|
14
|
+
return s
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def str_to_txtfile(s: str, fout=None):
|
|
18
|
+
if fout is None:
|
|
19
|
+
print(s)
|
|
20
|
+
else:
|
|
21
|
+
with open(fout, "w", encoding="utf-8") as f:
|
|
22
|
+
f.write(s)
|
|
23
|
+
|
|
24
|
+
def encrypt_txtfile(fin, fout=None, password=None, prompt='prompts(1)'):
|
|
25
|
+
s = str_from_txtfile(fin)
|
|
26
|
+
|
|
27
|
+
if not prompt:
|
|
28
|
+
prompt = input("input prompt=")
|
|
29
|
+
|
|
30
|
+
if password == "[input]":
|
|
31
|
+
password = getpass("input password=")
|
|
32
|
+
|
|
33
|
+
if password:
|
|
34
|
+
encrypted_list = encrypt_str_to_list(s, password)
|
|
35
|
+
encrypted_list[0] = "-"
|
|
36
|
+
else:
|
|
37
|
+
encrypted_list = encrypt_str_to_list(s)
|
|
38
|
+
|
|
39
|
+
s2 = "\n".join([prompt] + encrypted_list)
|
|
40
|
+
|
|
41
|
+
if fout == ".":
|
|
42
|
+
fout = fin+"_1"
|
|
43
|
+
|
|
44
|
+
str_to_txtfile(s2, fout)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def decrypt_txtfile(fin, fout=None, password=None):
|
|
48
|
+
s = str_from_txtfile(fin)
|
|
49
|
+
if password == "[input]":
|
|
50
|
+
password = getpass("input password=")
|
|
51
|
+
s_list = s.split("\n")
|
|
52
|
+
prompts = get_prompts_line(s_list[0])
|
|
53
|
+
if prompts is None:
|
|
54
|
+
prompts_line = 1
|
|
55
|
+
else:
|
|
56
|
+
prompts_line = prompts
|
|
57
|
+
encrypted_list = s_list[prompts_line:]
|
|
58
|
+
|
|
59
|
+
if encrypted_list[0] == "-" and password is None:
|
|
60
|
+
password = getpass("input password=")
|
|
61
|
+
|
|
62
|
+
if password is None:
|
|
63
|
+
s2 = decrypt_list_to_str(encrypted_list)
|
|
64
|
+
else:
|
|
65
|
+
s2 = decrypt_list_to_str(encrypted_list, password)
|
|
66
|
+
|
|
67
|
+
if fout == ".":
|
|
68
|
+
fout = fin+"_2"
|
|
69
|
+
str_to_txtfile(s2, fout)
|
|
70
|
+
|
|
@@ -54,34 +54,26 @@ def str_randsplit_to_list(s, n1=10, n2=30):
|
|
|
54
54
|
return r
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
def encrypt_bytes_to_list(s: bytes, password=None
|
|
57
|
+
def encrypt_bytes_to_list(s: bytes, password=None):
|
|
58
58
|
if password is None:
|
|
59
59
|
password = rand_letter(random.randint(6, 16))
|
|
60
|
-
out_password = password
|
|
61
|
-
else:
|
|
62
|
-
out_password = "-"
|
|
63
|
-
if prefix is not None:
|
|
64
|
-
password = str(prefix) + password
|
|
65
|
-
|
|
66
60
|
key, safe_salt, times = get_key(password)
|
|
67
61
|
|
|
68
62
|
cipher_suite = Fernet(key)
|
|
69
63
|
encrypted_data = cipher_suite.encrypt(s)
|
|
70
64
|
safe_data = bytes_to_url64str(encrypted_data)
|
|
71
65
|
|
|
72
|
-
list_out = [
|
|
66
|
+
list_out = [password, safe_salt, str(times)] + str_randsplit_to_list(safe_data)
|
|
73
67
|
|
|
74
68
|
return list_out
|
|
75
69
|
|
|
76
70
|
|
|
77
|
-
def decrypt_list_to_bytes(list_in, password=None
|
|
71
|
+
def decrypt_list_to_bytes(list_in, password=None) -> bytes:
|
|
78
72
|
_password, safe_salt, _times, *_data = list_in
|
|
79
73
|
if password is None:
|
|
80
74
|
password = _password
|
|
81
75
|
else:
|
|
82
76
|
password = password
|
|
83
|
-
if prefix is not None:
|
|
84
|
-
password = str(prefix) + password
|
|
85
77
|
|
|
86
78
|
times = int(_times)
|
|
87
79
|
s = "".join(_data)
|
|
@@ -91,11 +83,11 @@ def decrypt_list_to_bytes(list_in, password=None, prefix=None) -> bytes:
|
|
|
91
83
|
return decrypted_bytes
|
|
92
84
|
|
|
93
85
|
|
|
94
|
-
def encrypt_str_to_list(s: str, password=None
|
|
95
|
-
arr = encrypt_bytes_to_list(s.encode(), password
|
|
86
|
+
def encrypt_str_to_list(s: str, password=None):
|
|
87
|
+
arr = encrypt_bytes_to_list(s.encode(), password)
|
|
96
88
|
return arr
|
|
97
89
|
|
|
98
90
|
|
|
99
|
-
def decrypt_list_to_str(list_in, password=None
|
|
100
|
-
decrypted_bytes = decrypt_list_to_bytes(list_in, password
|
|
91
|
+
def decrypt_list_to_str(list_in, password=None):
|
|
92
|
+
decrypted_bytes = decrypt_list_to_bytes(list_in, password)
|
|
101
93
|
return decrypted_bytes.decode()
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
|
|
3
|
+
# lambda parameters: expression
|
|
4
|
+
|
|
5
|
+
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
|
6
|
+
|
|
7
|
+
print(lst)
|
|
8
|
+
|
|
9
|
+
# map(function, iterable, *iterables) -> iterable
|
|
10
|
+
|
|
11
|
+
lst_2 = list(map(lambda i: i**2, lst))
|
|
12
|
+
|
|
13
|
+
print(lst_2)
|
|
14
|
+
|
|
15
|
+
print([i**2 for i in lst])
|
|
16
|
+
|
|
17
|
+
lst_3 = list(map(lambda x, y: x + y, lst, lst_2))
|
|
18
|
+
|
|
19
|
+
print(lst_3)
|
|
20
|
+
|
|
21
|
+
# filter(function, iterable) -> iterable
|
|
22
|
+
|
|
23
|
+
result = list(filter(lambda x: x % 2 == 0, lst))
|
|
24
|
+
|
|
25
|
+
print(result)
|
|
26
|
+
|
|
27
|
+
print([item for item in lst if item % 2 == 0])
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# reduce(function, iterable[, initializer])
|
|
31
|
+
|
|
32
|
+
result = functools.reduce(lambda x, y: x + y, lst)
|
|
33
|
+
|
|
34
|
+
print(result)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# zip(*iterables)
|
|
38
|
+
|
|
39
|
+
# sorted(iterable, key=None, reverse=False)
|
|
40
|
+
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import datetime
|
|
3
|
+
from wtforms import fields as wtforms_fields
|
|
4
|
+
from ..widgets.datetime import DateTimePickerWidget
|
|
5
|
+
from ..widgets.datetime import TimePickerWidget
|
|
6
|
+
|
|
7
|
+
class DateTimeField(wtforms_fields.DateTimeField):
|
|
8
|
+
"""
|
|
9
|
+
Allows modifying the datetime format of a DateTimeField using form_args.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
widget = DateTimePickerWidget()
|
|
13
|
+
|
|
14
|
+
def __init__(self, label=None, validators=None, format=None, **kwargs):
|
|
15
|
+
"""Constructor
|
|
16
|
+
|
|
17
|
+
:param label:
|
|
18
|
+
Label
|
|
19
|
+
:param validators:
|
|
20
|
+
Field validators
|
|
21
|
+
:param format:
|
|
22
|
+
Format for text to date conversion. Defaults to '%Y-%m-%d %H:%M:%S'
|
|
23
|
+
:param kwargs:
|
|
24
|
+
Any additional parameters
|
|
25
|
+
"""
|
|
26
|
+
super().__init__(
|
|
27
|
+
label, validators, format or "%Y-%m-%d %H:%M:%S", **kwargs
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class TimeField(wtforms_fields.Field):
|
|
32
|
+
"""
|
|
33
|
+
A text field which stores a `datetime.time` object.
|
|
34
|
+
Accepts time string in multiple formats: 20:10, 20:10:00, 10:00 am, 9:30pm, etc.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
widget = TimePickerWidget()
|
|
38
|
+
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
label=None,
|
|
42
|
+
validators=None,
|
|
43
|
+
formats=None,
|
|
44
|
+
default_format=None,
|
|
45
|
+
widget_format=None,
|
|
46
|
+
**kwargs
|
|
47
|
+
):
|
|
48
|
+
"""
|
|
49
|
+
Constructor
|
|
50
|
+
|
|
51
|
+
:param label:
|
|
52
|
+
Label
|
|
53
|
+
:param validators:
|
|
54
|
+
Field validators
|
|
55
|
+
:param formats:
|
|
56
|
+
Supported time formats, as a enumerable.
|
|
57
|
+
:param default_format:
|
|
58
|
+
Default time format. Defaults to '%H:%M:%S'
|
|
59
|
+
:param kwargs:
|
|
60
|
+
Any additional parameters
|
|
61
|
+
"""
|
|
62
|
+
super(TimeField, self).__init__(label, validators, **kwargs)
|
|
63
|
+
|
|
64
|
+
self.formats = formats or (
|
|
65
|
+
"%H:%M:%S",
|
|
66
|
+
"%H:%M",
|
|
67
|
+
"%I:%M:%S%p",
|
|
68
|
+
"%I:%M%p",
|
|
69
|
+
"%I:%M:%S %p",
|
|
70
|
+
"%I:%M %p",
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
self.default_format = default_format or "%H:%M:%S"
|
|
74
|
+
|
|
75
|
+
def _value(self):
|
|
76
|
+
if self.raw_data:
|
|
77
|
+
return " ".join(self.raw_data)
|
|
78
|
+
elif self.data is not None:
|
|
79
|
+
return self.data.strftime(self.default_format)
|
|
80
|
+
else:
|
|
81
|
+
return ""
|
|
82
|
+
|
|
83
|
+
def process_formdata(self, valuelist):
|
|
84
|
+
if valuelist:
|
|
85
|
+
date_str = " ".join(valuelist)
|
|
86
|
+
|
|
87
|
+
if date_str.strip():
|
|
88
|
+
for format in self.formats:
|
|
89
|
+
try:
|
|
90
|
+
timetuple = time.strptime(date_str, format)
|
|
91
|
+
self.data = datetime.time(
|
|
92
|
+
timetuple.tm_hour, timetuple.tm_min, timetuple.tm_sec
|
|
93
|
+
)
|
|
94
|
+
return
|
|
95
|
+
except ValueError:
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
raise ValueError(self.gettext("Invalid time format"))
|
|
99
|
+
else:
|
|
100
|
+
self.data = None
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from wtforms.fields import TextAreaField
|
|
3
|
+
|
|
4
|
+
class JSONField(TextAreaField):
|
|
5
|
+
def process_formdata(self, valuelist):
|
|
6
|
+
if valuelist:
|
|
7
|
+
if not valuelist[0]:
|
|
8
|
+
self.data = None
|
|
9
|
+
return
|
|
10
|
+
try:
|
|
11
|
+
self.data = json.loads(valuelist[0])
|
|
12
|
+
except ValueError:
|
|
13
|
+
raise ValueError(self.gettext("Invalid JSON"))
|
|
14
|
+
|
|
15
|
+
def _value(self):
|
|
16
|
+
if self.data:
|
|
17
|
+
return json.dumps(self.data, ensure_ascii=False)
|
|
18
|
+
else:
|
|
19
|
+
return ""
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from wtforms import fields as wtforms_fields
|
|
3
|
+
from ..widgets.select import Select2Widget
|
|
4
|
+
from ..widgets.select import Select2TagsWidget
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Select2Field(wtforms_fields.SelectField):
|
|
8
|
+
"""
|
|
9
|
+
`Select2 <https://github.com/ivaynberg/select2>`_ styled select widget.
|
|
10
|
+
|
|
11
|
+
You must include select2.js, form-x.x.x.js and select2 stylesheet for it to
|
|
12
|
+
work.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
widget = Select2Widget()
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
label=None,
|
|
20
|
+
validators=None,
|
|
21
|
+
coerce=str,
|
|
22
|
+
choices=None,
|
|
23
|
+
allow_blank=False,
|
|
24
|
+
blank_text=None,
|
|
25
|
+
**kwargs
|
|
26
|
+
):
|
|
27
|
+
super(Select2Field, self).__init__(label, validators, coerce, choices, **kwargs)
|
|
28
|
+
self.allow_blank = allow_blank
|
|
29
|
+
self.blank_text = blank_text or " "
|
|
30
|
+
|
|
31
|
+
def iter_choices(self):
|
|
32
|
+
if self.allow_blank:
|
|
33
|
+
yield ("__None", self.blank_text, self.data is None)
|
|
34
|
+
|
|
35
|
+
for choice in self.choices:
|
|
36
|
+
if isinstance(choice, tuple):
|
|
37
|
+
yield (choice[0], choice[1], self.coerce(choice[0]) == self.data)
|
|
38
|
+
else:
|
|
39
|
+
yield (
|
|
40
|
+
choice.value,
|
|
41
|
+
choice.name,
|
|
42
|
+
self.coerce(choice.value) == self.data,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def process_data(self, value):
|
|
46
|
+
if value is None:
|
|
47
|
+
self.data = None
|
|
48
|
+
else:
|
|
49
|
+
try:
|
|
50
|
+
self.data = self.coerce(value)
|
|
51
|
+
except (ValueError, TypeError):
|
|
52
|
+
self.data = None
|
|
53
|
+
|
|
54
|
+
def process_formdata(self, valuelist):
|
|
55
|
+
if valuelist:
|
|
56
|
+
if valuelist[0] == "__None":
|
|
57
|
+
self.data = None
|
|
58
|
+
else:
|
|
59
|
+
try:
|
|
60
|
+
self.data = self.coerce(valuelist[0])
|
|
61
|
+
except ValueError:
|
|
62
|
+
raise ValueError(self.gettext("Invalid Choice: could not coerce"))
|
|
63
|
+
|
|
64
|
+
def pre_validate(self, form):
|
|
65
|
+
if self.allow_blank and self.data is None:
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
super(Select2Field, self).pre_validate(form)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class Select2TagsField(wtforms_fields.StringField):
|
|
72
|
+
"""`Select2 <http://ivaynberg.github.com/select2/#tags>`_ styled text field.
|
|
73
|
+
You must include select2.js, form-x.x.x.js and select2 stylesheet for it to work.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
widget = Select2TagsWidget()
|
|
77
|
+
_strip_regex = re.compile(
|
|
78
|
+
r"#\d+(?:(,)|\s$)"
|
|
79
|
+
) # e.g., 'tag#123, anothertag#425 ' => 'tag, anothertag'
|
|
80
|
+
|
|
81
|
+
def __init__(
|
|
82
|
+
self,
|
|
83
|
+
label=None,
|
|
84
|
+
validators=None,
|
|
85
|
+
save_as_list=False,
|
|
86
|
+
coerce=str,
|
|
87
|
+
allow_duplicates=False,
|
|
88
|
+
**kwargs
|
|
89
|
+
):
|
|
90
|
+
"""Initialization
|
|
91
|
+
|
|
92
|
+
:param save_as_list:
|
|
93
|
+
If `True` then populate ``obj`` using list else string
|
|
94
|
+
:param allow_duplicates
|
|
95
|
+
If `True` then duplicate tags are allowed in the field.
|
|
96
|
+
"""
|
|
97
|
+
self.save_as_list = save_as_list
|
|
98
|
+
self.allow_duplicates = allow_duplicates
|
|
99
|
+
self.coerce = coerce
|
|
100
|
+
|
|
101
|
+
super(Select2TagsField, self).__init__(label, validators, **kwargs)
|
|
102
|
+
|
|
103
|
+
def process_formdata(self, valuelist):
|
|
104
|
+
if valuelist:
|
|
105
|
+
entrylist = valuelist[0]
|
|
106
|
+
if self.allow_duplicates and entrylist.endswith(" "):
|
|
107
|
+
# This means this is an allowed duplicate (see form.js, `createSearchChoice`), so its ID was modified.
|
|
108
|
+
# Hence, we need to restore the original IDs.
|
|
109
|
+
entrylist = re.sub(self._strip_regex, "\\1", entrylist)
|
|
110
|
+
if self.save_as_list:
|
|
111
|
+
self.data = [
|
|
112
|
+
self.coerce(v.strip()) for v in entrylist.split(",") if v.strip()
|
|
113
|
+
]
|
|
114
|
+
else:
|
|
115
|
+
self.data = self.coerce(entrylist)
|
|
116
|
+
|
|
117
|
+
def _value(self):
|
|
118
|
+
if isinstance(self.data, (list, tuple)):
|
|
119
|
+
return ",".join(v for v in self.data)
|
|
120
|
+
elif self.data:
|
|
121
|
+
return self.data
|
|
122
|
+
else:
|
|
123
|
+
return ""
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from wtforms.fields import StringField
|
|
2
|
+
|
|
3
|
+
class TagListField(StringField):
|
|
4
|
+
def process_formdata(self, valuelist):
|
|
5
|
+
if valuelist:
|
|
6
|
+
self.data = [x.strip() for x in valuelist[0].split(",")]
|
|
7
|
+
|
|
8
|
+
def _value(self):
|
|
9
|
+
return ",".join(self.data) if self.data is not None else ""
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from wtforms.widgets import TextInput
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class DatePickerWidget(TextInput):
|
|
5
|
+
"""Date picker widget."""
|
|
6
|
+
|
|
7
|
+
def __call__(self, field, **kwargs):
|
|
8
|
+
kwargs.setdefault("data-role", "datepicker")
|
|
9
|
+
kwargs.setdefault("data-date-format", "YYYY-MM-DD")
|
|
10
|
+
|
|
11
|
+
self.date_format = kwargs["data-date-format"]
|
|
12
|
+
return super().__call__(field, **kwargs)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DateTimePickerWidget(TextInput):
|
|
16
|
+
"""Datetime picker widget."""
|
|
17
|
+
|
|
18
|
+
def __call__(self, field, **kwargs):
|
|
19
|
+
kwargs.setdefault("data-role", "datetimepicker")
|
|
20
|
+
kwargs.setdefault("data-date-format", "YYYY-MM-DD HH:mm:ss")
|
|
21
|
+
return super().__call__(field, **kwargs)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class TimePickerWidget(TextInput):
|
|
25
|
+
"""Date picker widget."""
|
|
26
|
+
|
|
27
|
+
def __call__(self, field, **kwargs):
|
|
28
|
+
kwargs.setdefault("data-role", "timepicker")
|
|
29
|
+
kwargs.setdefault("data-date-format", "HH:mm:ss")
|
|
30
|
+
return super().__call__(field, **kwargs)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from wtforms.widgets import Select
|
|
2
|
+
from wtforms.widgets import TextInput
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Select2Widget(Select):
|
|
6
|
+
"""Select2 Widget."""
|
|
7
|
+
|
|
8
|
+
def __call__(self, field, **kwargs):
|
|
9
|
+
kwargs.setdefault("data-role", "select2")
|
|
10
|
+
allow_blank = getattr(field, "allow_blank", False)
|
|
11
|
+
if allow_blank and not self.multiple:
|
|
12
|
+
kwargs["data-allow-blank"] = "1"
|
|
13
|
+
|
|
14
|
+
return super().__call__(field, **kwargs)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Select2TagsWidget(TextInput):
|
|
18
|
+
"""Select2Tags Widget."""
|
|
19
|
+
|
|
20
|
+
def __call__(self, field, **kwargs):
|
|
21
|
+
kwargs.setdefault("data-role", "select2-tags")
|
|
22
|
+
kwargs.setdefault(
|
|
23
|
+
"data-allow-duplicate-tags",
|
|
24
|
+
"true" if getattr(field, "allow_duplicates", False) else "false",
|
|
25
|
+
)
|
|
26
|
+
return super().__call__(field, **kwargs)
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .remove_pycache import remove_pycache
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
+
import pytest
|
|
1
2
|
import os
|
|
2
3
|
import os.path as op
|
|
3
4
|
import filecmp
|
|
4
5
|
from python_plugins.random.random_str import rand_sentence
|
|
5
|
-
from python_plugins.crypto
|
|
6
|
-
from python_plugins.crypto
|
|
7
|
-
from python_plugins.crypto.file_to_file import encrypt_file
|
|
8
|
-
from python_plugins.crypto.file_to_file import decrypt_file
|
|
9
|
-
|
|
6
|
+
from python_plugins.crypto import encrypt_txtfile
|
|
7
|
+
from python_plugins.crypto import decrypt_txtfile
|
|
10
8
|
|
|
11
9
|
tmp_path = op.join(os.path.dirname(os.path.abspath(__file__)), "tmp")
|
|
12
10
|
|
|
@@ -38,47 +36,51 @@ def _remove_testfiles():
|
|
|
38
36
|
safe_delete(path_4)
|
|
39
37
|
safe_delete(path_5)
|
|
40
38
|
|
|
41
|
-
|
|
42
39
|
def test_crypto_file():
|
|
43
40
|
create_tmp = _create_temp()
|
|
44
41
|
if create_tmp:
|
|
45
42
|
print(create_tmp)
|
|
46
43
|
|
|
47
|
-
prompt = "test"
|
|
48
|
-
|
|
49
44
|
with open(path_1, "w") as f:
|
|
50
45
|
f.write(rand_sentence(30))
|
|
51
46
|
f.write(rand_sentence(30))
|
|
52
47
|
|
|
53
|
-
encrypt_txtfile(path_1, path_2
|
|
48
|
+
encrypt_txtfile(path_1, path_2)
|
|
49
|
+
# decrypt_txtfile(path_2)
|
|
54
50
|
decrypt_txtfile(path_2, path_3)
|
|
55
51
|
cmp_result = filecmp.cmp(path_1, path_3)
|
|
56
52
|
assert cmp_result is True
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
_remove_testfiles()
|
|
55
|
+
|
|
56
|
+
def test_crypto_file_with_password():
|
|
57
|
+
|
|
58
|
+
with open(path_1, "w") as f:
|
|
59
|
+
f.write(rand_sentence(30))
|
|
60
|
+
f.write(rand_sentence(30))
|
|
61
|
+
|
|
62
|
+
password = rand_sentence(10)
|
|
63
|
+
encrypt_txtfile(path_1, path_2, password=password)
|
|
64
|
+
with pytest.raises(Exception):
|
|
65
|
+
decrypt_txtfile(path_2, path_3,password="")
|
|
66
|
+
decrypt_txtfile(path_2, path_3, password=password)
|
|
67
|
+
cmp_result = filecmp.cmp(path_1, path_3)
|
|
61
68
|
assert cmp_result is True
|
|
62
69
|
|
|
63
70
|
_remove_testfiles()
|
|
64
71
|
|
|
65
|
-
# pytest with `input()` must using `-s`
|
|
72
|
+
# pytest with `input()` must using `-s`
|
|
66
73
|
# pytest tests\test_crypt_file.py::test_crypto_file_with_password -s
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
@pytest.mark.skip
|
|
75
|
+
def test_crypto_file_with_input_password():
|
|
69
76
|
|
|
70
77
|
with open(path_1, "w") as f:
|
|
71
78
|
f.write(rand_sentence(30))
|
|
72
79
|
f.write(rand_sentence(30))
|
|
73
80
|
|
|
74
|
-
encrypt_txtfile(path_1, path_2,
|
|
81
|
+
encrypt_txtfile(path_1, path_2, password='[input]')
|
|
75
82
|
decrypt_txtfile(path_2, path_3)
|
|
76
83
|
cmp_result = filecmp.cmp(path_1, path_3)
|
|
77
84
|
assert cmp_result is True
|
|
78
85
|
|
|
79
|
-
encrypt_file(path_1, path_4, accept_password=True)
|
|
80
|
-
decrypt_file(path_2, path_5)
|
|
81
|
-
cmp_result = filecmp.cmp(path_1, path_5)
|
|
82
|
-
assert cmp_result is True
|
|
83
|
-
|
|
84
86
|
_remove_testfiles()
|
|
@@ -56,27 +56,8 @@ class TestStr2List:
|
|
|
56
56
|
password = rand_letter(16)
|
|
57
57
|
encrypted_list = encrypt_str_to_list(s, password)
|
|
58
58
|
with pytest.raises(Exception):
|
|
59
|
-
s1 = decrypt_list_to_str(encrypted_list)
|
|
59
|
+
s1 = decrypt_list_to_str([None] + encrypted_list[1:])
|
|
60
60
|
s2 = decrypt_list_to_str(encrypted_list, password)
|
|
61
61
|
assert s == s2
|
|
62
62
|
s3 = decrypt_list_to_str([None] + encrypted_list[1:], password)
|
|
63
63
|
assert s == s3
|
|
64
|
-
|
|
65
|
-
def test_encrypt_decrypt_with_prefix(self):
|
|
66
|
-
s = rand_sentence(random.randint(10, 100))
|
|
67
|
-
prefix = rand_letter(16)
|
|
68
|
-
encrypted_list = encrypt_str_to_list(s, prefix=prefix)
|
|
69
|
-
with pytest.raises(Exception):
|
|
70
|
-
s1 = decrypt_list_to_str(encrypted_list)
|
|
71
|
-
s2 = decrypt_list_to_str(encrypted_list, prefix=prefix)
|
|
72
|
-
assert s == s2
|
|
73
|
-
|
|
74
|
-
def test_encrypt_decrypt_with_password_prefix(self):
|
|
75
|
-
s = rand_sentence(random.randint(10, 100))
|
|
76
|
-
password = rand_letter(16)
|
|
77
|
-
prefix = rand_letter(16)
|
|
78
|
-
encrypted_list = encrypt_str_to_list(s, password, prefix)
|
|
79
|
-
with pytest.raises(Exception):
|
|
80
|
-
s1 = decrypt_list_to_str(encrypted_list, prefix=prefix)
|
|
81
|
-
s2 = decrypt_list_to_str(encrypted_list, password, prefix)
|
|
82
|
-
assert s == s2
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from wtforms.form import Form
|
|
2
|
+
from python_plugins.forms.fields import JSONField
|
|
3
|
+
from python_plugins.forms.fields import DateTimeField
|
|
4
|
+
|
|
5
|
+
class F(Form):
|
|
6
|
+
a = JSONField()
|
|
7
|
+
b = DateTimeField()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_fields():
|
|
11
|
+
f=F()
|
|
12
|
+
|
|
13
|
+
# print(f.a())
|
|
14
|
+
assert "textarea" in f.a()
|
|
15
|
+
|
|
16
|
+
# print(f.b())
|
|
17
|
+
assert "input" in f.b()
|
|
18
|
+
|
|
19
|
+
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
|
|
3
|
-
from python_plugins.utils
|
|
3
|
+
from python_plugins.utils import remove_pycache
|
|
4
4
|
|
|
5
5
|
@pytest.mark.skip
|
|
6
6
|
def test_remove_pycache():
|
|
7
7
|
remove_pycache("./tests")
|
|
8
8
|
|
|
9
|
-
@pytest.mark.skip
|
|
9
|
+
@pytest.mark.skip()
|
|
10
10
|
def test_remove_pycache():
|
|
11
11
|
remove_pycache()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.7"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .fernet import generate_fernet_key,fernet_encrypt,fernet_decrypt
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
from .str_to_list import encrypt_bytes_to_list
|
|
2
|
-
from .str_to_list import encrypt_str_to_list
|
|
3
|
-
from .str_to_list import decrypt_list_to_bytes
|
|
4
|
-
from .str_to_list import decrypt_list_to_str
|
|
5
|
-
from getpass import getpass
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def bytes_from_file(fin) -> bytes:
|
|
9
|
-
with open(fin, "rb") as f:
|
|
10
|
-
s = f.read()
|
|
11
|
-
return s
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def bytes_to_file(s: bytes, fout):
|
|
15
|
-
with open(fout, "wb") as f:
|
|
16
|
-
f.write(s)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def str_from_txtfile(fin) -> str:
|
|
20
|
-
with open(fin, encoding="utf-8") as f:
|
|
21
|
-
s = f.read()
|
|
22
|
-
return s
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def str_to_txtfile(s: str, fout):
|
|
26
|
-
with open(fout, "w", encoding="utf-8") as f:
|
|
27
|
-
f.write(s)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def bytes_to_file(s, fout):
|
|
31
|
-
with open(fout, "wb") as f:
|
|
32
|
-
f.write(s)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def encrypt_txt(s: str, prompt=None, accept_password=False):
|
|
36
|
-
if not prompt:
|
|
37
|
-
prompt = input("input prompt=")
|
|
38
|
-
password = None
|
|
39
|
-
if accept_password:
|
|
40
|
-
password = getpass("input password=")
|
|
41
|
-
if password:
|
|
42
|
-
encrypted_list = encrypt_str_to_list(s, password)
|
|
43
|
-
encrypted_list[0] = "-"
|
|
44
|
-
else:
|
|
45
|
-
encrypted_list = encrypt_str_to_list(s)
|
|
46
|
-
s2 = "\n".join([prompt] + encrypted_list)
|
|
47
|
-
return s2
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def decrypt_txt(s: str):
|
|
51
|
-
encrypted_list = s.split("\n")
|
|
52
|
-
prompt = encrypted_list[0]
|
|
53
|
-
if encrypted_list[1] == "-":
|
|
54
|
-
print(prompt)
|
|
55
|
-
password = getpass("input password=")
|
|
56
|
-
s2 = decrypt_list_to_str(encrypted_list[1:], password)
|
|
57
|
-
else:
|
|
58
|
-
s2 = decrypt_list_to_str(encrypted_list[1:])
|
|
59
|
-
|
|
60
|
-
return s2
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def encrypt_txtfile(fin, fout, prompt=None, accept_password=False):
|
|
64
|
-
s = str_from_txtfile(fin)
|
|
65
|
-
s2 = encrypt_txt(s, prompt, accept_password)
|
|
66
|
-
str_to_txtfile(s2, fout)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def decrypt_txtfile(fin, fout):
|
|
70
|
-
s = str_from_txtfile(fin)
|
|
71
|
-
s2 = decrypt_txt(s)
|
|
72
|
-
str_to_txtfile(s2, fout)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def encrypt_bytes(s: bytes, prompt=None, accept_password=False):
|
|
76
|
-
if not prompt:
|
|
77
|
-
prompt = input("input prompt=")
|
|
78
|
-
password = None
|
|
79
|
-
if accept_password:
|
|
80
|
-
password = getpass("input password=")
|
|
81
|
-
if password:
|
|
82
|
-
encrypted_list = encrypt_bytes_to_list(s, password)
|
|
83
|
-
encrypted_list[0] = "-"
|
|
84
|
-
else:
|
|
85
|
-
encrypted_list = encrypt_bytes_to_list(s)
|
|
86
|
-
s2 = "\n".join([prompt] + encrypted_list)
|
|
87
|
-
return s2
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def decrypt_bytes(s: str):
|
|
91
|
-
encrypted_list = s.split("\n")
|
|
92
|
-
prompt = encrypted_list[0]
|
|
93
|
-
if encrypted_list[1] == "-":
|
|
94
|
-
print(prompt)
|
|
95
|
-
password = getpass("input password=")
|
|
96
|
-
s2 = decrypt_list_to_bytes(encrypted_list[1:], password)
|
|
97
|
-
else:
|
|
98
|
-
s2 = decrypt_list_to_bytes(encrypted_list[1:])
|
|
99
|
-
|
|
100
|
-
return s2
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def encrypt_file(fin, fout, prompt=None, accept_password=False):
|
|
104
|
-
s = bytes_from_file(fin)
|
|
105
|
-
s2 = encrypt_bytes(s, prompt, accept_password)
|
|
106
|
-
str_to_txtfile(s2, fout)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def decrypt_file(fin, fout):
|
|
110
|
-
s = str_from_txtfile(fin)
|
|
111
|
-
s2 = decrypt_bytes(s)
|
|
112
|
-
bytes_to_file(s2, fout)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/mixins/data_mixin.py
RENAMED
|
File without changes
|
{python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/mixins/primary_key_mixin.py
RENAMED
|
File without changes
|
{python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/mixins/timestamp_mixin.py
RENAMED
|
File without changes
|
{python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/mixins/token_minxin.py
RENAMED
|
File without changes
|
{python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/models/mixins/user_minxin.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_plugins-0.1.7 → python_plugins-0.1.9}/src/python_plugins/process/python_venv_process.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|