pyrecli 0.1.2__tar.gz → 0.2.0__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.
- {pyrecli-0.1.2 → pyrecli-0.2.0}/PKG-INFO +1 -1
- {pyrecli-0.1.2 → pyrecli-0.2.0}/pyproject.toml +1 -1
- {pyrecli-0.1.2 → pyrecli-0.2.0}/pyrecli/command/docs.py +13 -9
- {pyrecli-0.1.2 → pyrecli-0.2.0}/pyrecli/command/grabinv.py +4 -4
- {pyrecli-0.1.2 → pyrecli-0.2.0}/pyrecli/command/rename.py +13 -13
- pyrecli-0.2.0/pyrecli/command/scan.py +19 -0
- {pyrecli-0.1.2 → pyrecli-0.2.0}/pyrecli/command/script.py +21 -15
- {pyrecli-0.1.2 → pyrecli-0.2.0}/pyrecli/command/send.py +6 -2
- pyrecli-0.2.0/pyrecli/command/slice.py +21 -0
- {pyrecli-0.1.2 → pyrecli-0.2.0}/pyrecli/pyrecli.py +22 -2
- {pyrecli-0.1.2 → pyrecli-0.2.0}/pyrecli/util.py +34 -6
- pyrecli-0.1.2/pyrecli/command/scan.py +0 -24
- {pyrecli-0.1.2 → pyrecli-0.2.0}/LICENSE +0 -0
- {pyrecli-0.1.2 → pyrecli-0.2.0}/README.md +0 -0
- {pyrecli-0.1.2 → pyrecli-0.2.0}/pyrecli/__init__.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from typing import Literal, TypedDict
|
|
2
|
-
from result import Result,
|
|
2
|
+
from result import Result, Err
|
|
3
3
|
from dfpyre import DFTemplate, Item, Parameter
|
|
4
4
|
from mcitemlib.itemlib import MCItemlibException
|
|
5
|
-
from pyrecli.util import
|
|
5
|
+
from pyrecli.util import read_input_file, write_output_file, parse_templates_from_string
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
STARTER_BLOCK_LOOKUP = {
|
|
@@ -25,7 +25,11 @@ class TemplateDocData(TypedDict):
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
def docs_command(input_path: str, output_path: str, title: str, include_hidden: bool, omit_toc: bool) -> Result[None, str]:
|
|
28
|
-
|
|
28
|
+
input_result = read_input_file(input_path)
|
|
29
|
+
if input_result.is_err():
|
|
30
|
+
return Err(input_result.err_value)
|
|
31
|
+
|
|
32
|
+
templates_result = parse_templates_from_string(input_result.ok_value)
|
|
29
33
|
if templates_result.is_err():
|
|
30
34
|
return Err(templates_result.err_value)
|
|
31
35
|
templates = templates_result.ok_value
|
|
@@ -68,7 +72,10 @@ def docs_command(input_path: str, output_path: str, title: str, include_hidden:
|
|
|
68
72
|
lore_text = [escape_md(l.to_string()) for l in first_arg.get_lore()]
|
|
69
73
|
if lore_text:
|
|
70
74
|
template_doc_lines.extend(lore_text)
|
|
71
|
-
except MCItemlibException:
|
|
75
|
+
except (MCItemlibException, AttributeError):
|
|
76
|
+
# There are so many things that can go wrong here due to various legacy
|
|
77
|
+
# item formats and weird MC string edge cases, so we can just skip
|
|
78
|
+
# if there's a problem.
|
|
72
79
|
pass
|
|
73
80
|
|
|
74
81
|
# Parse parameters
|
|
@@ -108,13 +115,10 @@ def docs_command(input_path: str, output_path: str, title: str, include_hidden:
|
|
|
108
115
|
add_toc_group(process_templates, 'Processes')
|
|
109
116
|
output_lines.append('\n')
|
|
110
117
|
|
|
111
|
-
|
|
112
118
|
# Add template docs to output lines
|
|
113
119
|
for doc_data in template_docs:
|
|
114
120
|
output_lines.extend(doc_data['doc_lines'])
|
|
115
121
|
output_lines.append('')
|
|
116
122
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return Ok(None)
|
|
123
|
+
write_result = write_output_file(output_path, '\n'.join(output_lines))
|
|
124
|
+
return write_result
|
|
@@ -2,7 +2,7 @@ import json
|
|
|
2
2
|
from result import Result, Ok, Err
|
|
3
3
|
import amulet_nbt
|
|
4
4
|
from amulet_nbt import CompoundTag, StringTag
|
|
5
|
-
from pyrecli.util import connect_to_codeclient
|
|
5
|
+
from pyrecli.util import write_output_file, connect_to_codeclient
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def grabinv_command(output_path: str) -> Result[None, str]:
|
|
@@ -42,8 +42,8 @@ def grabinv_command(output_path: str) -> Result[None, str]:
|
|
|
42
42
|
if not template_codes:
|
|
43
43
|
return Err('Could not find any templates in the inventory.')
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
output_result = write_output_file(output_path, '\n'.join(template_codes))
|
|
46
|
+
if output_result.is_err():
|
|
47
|
+
return output_result
|
|
47
48
|
|
|
48
|
-
print(f'Saved {len(template_codes)} template{"s" if len(template_codes) != 1 else ''} to "{output_path}".')
|
|
49
49
|
return Ok(None)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from typing import Literal
|
|
2
2
|
import re
|
|
3
|
-
from result import Result,
|
|
3
|
+
from result import Result, Err
|
|
4
4
|
from dfpyre import Variable, Number, String, Text
|
|
5
|
-
from pyrecli.util import
|
|
5
|
+
from pyrecli.util import read_input_file, write_output_file, parse_templates_from_string
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
TEXT_CODE_PATTERNS = [
|
|
@@ -22,8 +22,13 @@ def rename_var_in_text_code(s: str, var_to_rename: str, new_var_name: str):
|
|
|
22
22
|
|
|
23
23
|
def rename_command(input_path: str, output_path: str|None,
|
|
24
24
|
var_to_rename: str, new_var_name: str,
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
var_to_rename_scope: Literal['game', 'saved', 'local', 'line']|None) -> Result[None, str]:
|
|
26
|
+
|
|
27
|
+
input_result = read_input_file(input_path)
|
|
28
|
+
if input_result.is_err():
|
|
29
|
+
return Err(input_result.err_value)
|
|
30
|
+
|
|
31
|
+
templates_result = parse_templates_from_string(input_result.ok_value)
|
|
27
32
|
if templates_result.is_err():
|
|
28
33
|
return Err(templates_result.err_value)
|
|
29
34
|
templates = templates_result.ok_value
|
|
@@ -32,11 +37,8 @@ def rename_command(input_path: str, output_path: str|None,
|
|
|
32
37
|
for codeblock in template.codeblocks:
|
|
33
38
|
for argument in codeblock.args:
|
|
34
39
|
if isinstance(argument, Variable):
|
|
35
|
-
if argument.name == var_to_rename:
|
|
36
|
-
|
|
37
|
-
argument.name = new_var_name
|
|
38
|
-
elif argument.scope != renamed_var_scope:
|
|
39
|
-
argument.name = new_var_name
|
|
40
|
+
if argument.name == var_to_rename and (var_to_rename_scope is None or argument.scope == var_to_rename_scope):
|
|
41
|
+
argument.name = new_var_name
|
|
40
42
|
argument.name = rename_var_in_text_code(argument.name, var_to_rename, new_var_name)
|
|
41
43
|
|
|
42
44
|
elif isinstance(argument, (Number, String, Text)) and isinstance(argument.value, str):
|
|
@@ -48,7 +50,5 @@ def rename_command(input_path: str, output_path: str|None,
|
|
|
48
50
|
|
|
49
51
|
new_file_content = '\n'.join(t.build() for t in templates)
|
|
50
52
|
write_path = output_path if output_path else input_path
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return Ok(None)
|
|
53
|
+
write_result = write_output_file(write_path, new_file_content)
|
|
54
|
+
return write_result
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from result import Result, Err
|
|
2
|
+
from pyrecli.util import write_output_file, connect_to_codeclient
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def scan_command(output_path: str) -> Result[None, str]:
|
|
6
|
+
ws_result = connect_to_codeclient('read_plot')
|
|
7
|
+
if ws_result.is_err():
|
|
8
|
+
return Err(ws_result.err_value)
|
|
9
|
+
ws = ws_result.ok_value
|
|
10
|
+
|
|
11
|
+
print('Scanning plot...')
|
|
12
|
+
ws.send('scan')
|
|
13
|
+
|
|
14
|
+
scan_results = ws.recv()
|
|
15
|
+
print('Done.')
|
|
16
|
+
ws.close()
|
|
17
|
+
|
|
18
|
+
write_result = write_output_file(output_path, scan_results)
|
|
19
|
+
return write_result
|
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from result import Result, Ok, Err
|
|
3
3
|
from dfpyre import DFTemplate
|
|
4
|
-
from pyrecli.util import
|
|
4
|
+
from pyrecli.util import read_input_file, write_output_file, parse_templates_from_string
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def write_to_directory(dir_name: str, templates: list[DFTemplate], flags: dict[str, int|bool]):
|
|
7
|
+
def write_to_directory(dir_name: str, templates: list[DFTemplate], flags: dict[str, int|bool]) -> Result[None, str]:
|
|
8
8
|
if not os.path.isdir(dir_name):
|
|
9
9
|
os.mkdir(dir_name)
|
|
10
10
|
|
|
11
11
|
for template in templates:
|
|
12
12
|
script_path = f'{dir_name}/{template._get_template_name()}.py'
|
|
13
13
|
script_string = template.generate_script(**flags)
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
try:
|
|
15
|
+
with open(script_path, 'w') as f:
|
|
16
|
+
f.write(script_string)
|
|
17
|
+
except OSError as e:
|
|
18
|
+
return Err(str(e))
|
|
19
|
+
|
|
20
|
+
return Ok(None)
|
|
16
21
|
|
|
17
22
|
|
|
18
|
-
def write_to_single_file(file_path: str, templates: list[DFTemplate], flags: dict[str, int|bool]):
|
|
23
|
+
def write_to_single_file(file_path: str, templates: list[DFTemplate], flags: dict[str, int|bool]) -> Result[None, str]:
|
|
19
24
|
file_content = []
|
|
20
25
|
for i, template in enumerate(templates):
|
|
21
26
|
if i == 0:
|
|
@@ -23,20 +28,21 @@ def write_to_single_file(file_path: str, templates: list[DFTemplate], flags: dic
|
|
|
23
28
|
else:
|
|
24
29
|
template_script = template.generate_script(include_import=False, assign_variable=True, **flags)
|
|
25
30
|
file_content.append(template_script)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
f.write('\n\n'.join(file_content))
|
|
31
|
+
|
|
32
|
+
return write_output_file(file_path, '\n\n'.join(file_content))
|
|
29
33
|
|
|
30
34
|
|
|
31
35
|
def script_command(input_path: str, output_path: str, one_file: bool, flags: dict[str, int|bool]) -> Result[None, str]:
|
|
32
|
-
|
|
36
|
+
input_result = read_input_file(input_path)
|
|
37
|
+
if input_result.is_err():
|
|
38
|
+
return Err(input_result.err_value)
|
|
39
|
+
|
|
40
|
+
templates_result = parse_templates_from_string(input_result.ok_value)
|
|
33
41
|
if templates_result.is_err():
|
|
34
42
|
return Err(templates_result.err_value)
|
|
35
43
|
templates = templates_result.ok_value
|
|
36
44
|
|
|
37
|
-
if one_file:
|
|
38
|
-
write_to_single_file(output_path, templates, flags)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return Ok(None)
|
|
45
|
+
if one_file or output_path == '-':
|
|
46
|
+
return write_to_single_file(output_path, templates, flags)
|
|
47
|
+
|
|
48
|
+
return write_to_directory(output_path, templates, flags)
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
from result import Result, Ok, Err
|
|
2
|
-
from pyrecli.util import connect_to_codeclient,
|
|
2
|
+
from pyrecli.util import connect_to_codeclient, read_input_file, parse_templates_from_string
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def send_command(input_path: str) -> Result[None, str]:
|
|
6
|
-
|
|
6
|
+
input_result = read_input_file(input_path)
|
|
7
|
+
if input_result.is_err():
|
|
8
|
+
return Err(input_result.err_value)
|
|
9
|
+
|
|
10
|
+
templates_result = parse_templates_from_string(input_result.ok_value)
|
|
7
11
|
if templates_result.is_err():
|
|
8
12
|
return Err(templates_result.err_value)
|
|
9
13
|
templates = templates_result.ok_value
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from result import Result, Err
|
|
2
|
+
from pyrecli.util import read_input_file, write_output_file, parse_templates_from_string
|
|
3
|
+
|
|
4
|
+
def slice_command(input_path: str, output_path: str, target_length: int) -> Result[None, str]:
|
|
5
|
+
input_result = read_input_file(input_path)
|
|
6
|
+
if input_result.is_err():
|
|
7
|
+
return Err(input_result.err_value)
|
|
8
|
+
|
|
9
|
+
templates_result = parse_templates_from_string(input_result.ok_value)
|
|
10
|
+
if templates_result.is_err():
|
|
11
|
+
return Err(templates_result.err_value)
|
|
12
|
+
templates = templates_result.ok_value
|
|
13
|
+
|
|
14
|
+
if not templates:
|
|
15
|
+
return Err(f'Could not find any templates in {input_path}')
|
|
16
|
+
|
|
17
|
+
first_template = templates[0]
|
|
18
|
+
sliced_templates = first_template.slice(target_length)
|
|
19
|
+
built_templates = [t.build() for t in sliced_templates]
|
|
20
|
+
|
|
21
|
+
return write_output_file(output_path, '\n'.join(built_templates))
|
|
@@ -8,6 +8,15 @@ from pyrecli.command.script import script_command
|
|
|
8
8
|
from pyrecli.command.rename import rename_command
|
|
9
9
|
from pyrecli.command.grabinv import grabinv_command
|
|
10
10
|
from pyrecli.command.docs import docs_command
|
|
11
|
+
from pyrecli.command.slice import slice_command
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def slice_target_length(value):
|
|
15
|
+
MINIMUM_LENGTH = 5
|
|
16
|
+
ivalue = int(value)
|
|
17
|
+
if ivalue < MINIMUM_LENGTH:
|
|
18
|
+
raise argparse.ArgumentTypeError(f'Target length must be at least {MINIMUM_LENGTH} codeblocks')
|
|
19
|
+
return ivalue
|
|
11
20
|
|
|
12
21
|
|
|
13
22
|
def main():
|
|
@@ -36,18 +45,23 @@ def main():
|
|
|
36
45
|
parser_rename.add_argument('var_to_rename', help='The variable to rename', type=str)
|
|
37
46
|
parser_rename.add_argument('new_var_name', help='The new name for the variable', type=str)
|
|
38
47
|
parser_rename.add_argument('--var_to_rename_scope', '-s', help='The scope to match', type=str, default=None)
|
|
39
|
-
parser_rename.add_argument('--output_path', '-o', help='The file
|
|
48
|
+
parser_rename.add_argument('--output_path', '-o', help='The file to output to', type=str, default=None)
|
|
40
49
|
|
|
41
50
|
parser_grabinv = subparsers.add_parser('grabinv', help='Save all templates in the inventory to a file with CodeClient')
|
|
42
51
|
parser_grabinv.add_argument('output_path', help='The file to output template data to', type=str)
|
|
43
52
|
|
|
44
53
|
parser_docs = subparsers.add_parser('docs', help='Generate markdown documentation from template data')
|
|
45
54
|
parser_docs.add_argument('input_path', help='The file containing template data', type=str)
|
|
46
|
-
parser_docs.add_argument('output_path', help='The file
|
|
55
|
+
parser_docs.add_argument('output_path', help='The file to output to', type=str)
|
|
47
56
|
parser_docs.add_argument('title', help='The title for the docs', type=str)
|
|
48
57
|
parser_docs.add_argument('--include_hidden', '-ih', help='Include hidden functions and processes', action='store_true')
|
|
49
58
|
parser_docs.add_argument('--notoc', help='Omit the table of contents', action='store_true')
|
|
50
59
|
|
|
60
|
+
parser_slice = subparsers.add_parser('slice', help='Slice a template into multiple smaller templates')
|
|
61
|
+
parser_slice.add_argument('input_path', help='The file containing template data', type=str)
|
|
62
|
+
parser_slice.add_argument('output_path', help='The file to output template data to', type=str)
|
|
63
|
+
parser_slice.add_argument('target_length', help='The maximum length of each sliced template', type=slice_target_length)
|
|
64
|
+
|
|
51
65
|
parsed_args = parser.parse_args()
|
|
52
66
|
|
|
53
67
|
match parsed_args.command:
|
|
@@ -81,6 +95,12 @@ def main():
|
|
|
81
95
|
parsed_args.input_path, parsed_args.output_path,
|
|
82
96
|
parsed_args.title, parsed_args.include_hidden, parsed_args.notoc
|
|
83
97
|
)
|
|
98
|
+
|
|
99
|
+
case 'slice':
|
|
100
|
+
command_result = slice_command(
|
|
101
|
+
parsed_args.input_path, parsed_args.output_path,
|
|
102
|
+
parsed_args.target_length
|
|
103
|
+
)
|
|
84
104
|
|
|
85
105
|
if command_result.is_err():
|
|
86
106
|
print(command_result.err_value)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import re
|
|
3
|
+
import sys
|
|
3
4
|
from result import Result, Ok, Err
|
|
4
5
|
import websocket
|
|
5
6
|
from dfpyre import DFTemplate
|
|
@@ -31,12 +32,8 @@ def connect_to_codeclient(scopes: str|None=None) -> Result[websocket.WebSocket,
|
|
|
31
32
|
return Ok(ws)
|
|
32
33
|
|
|
33
34
|
|
|
34
|
-
def
|
|
35
|
-
|
|
36
|
-
return Err(f'"{path}" is not a file.')
|
|
37
|
-
|
|
38
|
-
with open(path, 'r') as f:
|
|
39
|
-
template_codes = f.read().split('\n')
|
|
35
|
+
def parse_templates_from_string(templates: str) -> Result[list[DFTemplate], str]:
|
|
36
|
+
template_codes = templates.split('\n')
|
|
40
37
|
|
|
41
38
|
for i, template_code in enumerate(template_codes):
|
|
42
39
|
if not BASE64_REGEX.match(template_code):
|
|
@@ -46,3 +43,34 @@ def parse_templates_from_file(path: str) -> Result[list[DFTemplate], str]:
|
|
|
46
43
|
return Ok([DFTemplate.from_code(c) for c in template_codes])
|
|
47
44
|
except Exception as e:
|
|
48
45
|
return Err(str(e))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def read_input_file(path: str) -> Result[str, str]:
|
|
49
|
+
if path == '-':
|
|
50
|
+
try:
|
|
51
|
+
input_string = sys.stdin.read()
|
|
52
|
+
except EOFError:
|
|
53
|
+
pass
|
|
54
|
+
return Ok(input_string.strip())
|
|
55
|
+
|
|
56
|
+
if not os.path.isfile(path):
|
|
57
|
+
return Err(f'"{path}" is not a file.')
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
with open(path, 'r') as f:
|
|
61
|
+
return Ok(f.read())
|
|
62
|
+
except OSError as e:
|
|
63
|
+
return Err(str(e))
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def write_output_file(path: str, content: str) -> Result[None, str]:
|
|
67
|
+
if path == '-':
|
|
68
|
+
print(content, end='')
|
|
69
|
+
else:
|
|
70
|
+
try:
|
|
71
|
+
with open(path, 'w') as f:
|
|
72
|
+
f.write(content)
|
|
73
|
+
except OSError as e:
|
|
74
|
+
return Err(str(e))
|
|
75
|
+
|
|
76
|
+
return Ok(None)
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
from result import Result, Ok, Err
|
|
2
|
-
from pyrecli.util import connect_to_codeclient
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def scan_command(output_path: str) -> Result[None, str]:
|
|
6
|
-
ws_result = connect_to_codeclient('read_plot')
|
|
7
|
-
if ws_result.is_err():
|
|
8
|
-
return Err(ws_result.err_value)
|
|
9
|
-
ws = ws_result.ok_value
|
|
10
|
-
|
|
11
|
-
print('Scanning plot...')
|
|
12
|
-
ws.send('scan')
|
|
13
|
-
|
|
14
|
-
scan_results = ws.recv()
|
|
15
|
-
print('Done.')
|
|
16
|
-
ws.close()
|
|
17
|
-
|
|
18
|
-
with open(output_path, 'w') as f:
|
|
19
|
-
f.write(scan_results)
|
|
20
|
-
|
|
21
|
-
amount_templates = scan_results.count('\n')
|
|
22
|
-
print(f'Scanned {amount_templates} template{"s" if amount_templates != 1 else ''} successfully.')
|
|
23
|
-
|
|
24
|
-
return Ok(None)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|