stormlibpp 0.6.2__tar.gz → 0.6.4__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.
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/PKG-INFO +2 -1
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/pyproject.toml +2 -2
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/__init__.py +1 -1
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/errors.py +9 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/hstorm.py +0 -3
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/httpcore.py +27 -2
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/import.py +29 -12
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/output.py +10 -3
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp.egg-info/PKG-INFO +2 -1
- stormlibpp-0.6.4/src/stormlibpp.egg-info/requires.txt +1 -0
- stormlibpp-0.6.2/src/stormlibpp.egg-info/requires.txt +0 -1
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/LICENSE +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/README.md +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/setup.cfg +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/node.py +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/stormcli.py +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/stormpkg.py +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/telepath.py +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/tmpcortex.py +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/utils.py +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp.egg-info/SOURCES.txt +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp.egg-info/dependency_links.txt +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp.egg-info/top_level.txt +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/tests/test_httpcore.py +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/tests/test_node.py +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/tests/test_stormpkg.py +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/tests/test_telepath.py +0 -0
- {stormlibpp-0.6.2 → stormlibpp-0.6.4}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: stormlibpp
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.4
|
|
4
4
|
Summary: The stormlibpp Python package
|
|
5
5
|
Author: John Gorman
|
|
6
6
|
License: MIT License
|
|
@@ -29,6 +29,7 @@ Project-URL: Documentation, https://gormo.co/stormlibpp/
|
|
|
29
29
|
Requires-Python: >=3.11
|
|
30
30
|
Description-Content-Type: text/markdown
|
|
31
31
|
License-File: LICENSE
|
|
32
|
+
Requires-Dist: synapse>=2.139.0
|
|
32
33
|
|
|
33
34
|
# stormlibpp
|
|
34
35
|
|
|
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "stormlibpp"
|
|
7
|
-
version = "0.6.
|
|
7
|
+
version = "0.6.4"
|
|
8
8
|
description = "The stormlibpp Python package"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
11
11
|
|
|
12
12
|
# Fill in dependencies here.
|
|
13
13
|
dependencies = [
|
|
14
|
-
"synapse
|
|
14
|
+
"synapse>=2.139.0"
|
|
15
15
|
]
|
|
16
16
|
|
|
17
17
|
[[project.authors]]
|
|
@@ -46,7 +46,7 @@ that can be used for testing other tools. It creates a user (``test``) with pass
|
|
|
46
46
|
script will support custom Cortex configuration.
|
|
47
47
|
"""
|
|
48
48
|
|
|
49
|
-
__version__ = "0.6.
|
|
49
|
+
__version__ = "0.6.4"
|
|
50
50
|
|
|
51
51
|
# TODO - Do we want to change this to only import submods, or do we even need that?
|
|
52
52
|
from . import errors
|
|
@@ -8,6 +8,10 @@ class StormSyntaxError(Exception):
|
|
|
8
8
|
"""There was a syntax error in Storm code."""
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
class StormRaiseError(Exception):
|
|
12
|
+
"""There was a syntax error in Storm code."""
|
|
13
|
+
|
|
14
|
+
|
|
11
15
|
class StormPkgError(Exception):
|
|
12
16
|
"""An error in a StormPkg."""
|
|
13
17
|
|
|
@@ -23,6 +27,7 @@ class StormPkgResolveError(StormPkgError):
|
|
|
23
27
|
class StormPkgBadDefError(StormPkgError):
|
|
24
28
|
"""The package proto's directory for a StormPkg could not be resolved."""
|
|
25
29
|
|
|
30
|
+
|
|
26
31
|
class StormPkgSyntaxError(StormPkgError, StormSyntaxError):
|
|
27
32
|
"""The Storm code defined in a StormPkg has a syntax error."""
|
|
28
33
|
|
|
@@ -40,3 +45,7 @@ class HttpCortexNotImplementedError(s_exc.SynErr, NotImplementedError):
|
|
|
40
45
|
|
|
41
46
|
Wraps ``synapse.exc.SynErr`` so this can be caught by builtin Synapse tools.
|
|
42
47
|
"""
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class HttpCortexJsonError(HttpCortexError):
|
|
51
|
+
"""Unable to parse JSON response from Synapse with HttpCortex."""
|
|
@@ -13,6 +13,7 @@ import synapse.lib.msgpack as s_msgpack
|
|
|
13
13
|
|
|
14
14
|
from .errors import (
|
|
15
15
|
HttpCortexError,
|
|
16
|
+
HttpCortexJsonError,
|
|
16
17
|
HttpCortexLoginError,
|
|
17
18
|
HttpCortexNotImplementedError,
|
|
18
19
|
)
|
|
@@ -248,17 +249,41 @@ class HttpCortex:
|
|
|
248
249
|
|
|
249
250
|
try:
|
|
250
251
|
async with self.sess.get(url, json=data, ssl=self.ssl_verify) as resp:
|
|
251
|
-
|
|
252
|
+
buf = b""
|
|
253
|
+
async for byts, chunkend in resp.content.iter_chunks():
|
|
252
254
|
if not byts:
|
|
253
255
|
break
|
|
254
256
|
|
|
255
|
-
|
|
257
|
+
buf += byts
|
|
258
|
+
if not chunkend:
|
|
259
|
+
continue
|
|
260
|
+
|
|
261
|
+
try:
|
|
262
|
+
data = json.loads(byts)
|
|
263
|
+
except json.JSONDecodeError as err:
|
|
264
|
+
# HACK - This is the only way I found to fix a bug - may require reworking.
|
|
265
|
+
# TODO - Add a retry count here or something to not get stuck in loop?
|
|
266
|
+
# Since we're chunking the response, occasionally we get part of a JSON
|
|
267
|
+
# doc instead of all of it, which will cause this error. Try reading more
|
|
268
|
+
# chunks until there's a readable JSON doc.
|
|
269
|
+
if "Unterminated string starting at" in str(err):
|
|
270
|
+
continue
|
|
271
|
+
else:
|
|
272
|
+
raise err
|
|
273
|
+
|
|
256
274
|
if tuplify:
|
|
257
275
|
yield s_msgpack.deepcopy(data)
|
|
258
276
|
else:
|
|
259
277
|
yield data
|
|
260
278
|
|
|
279
|
+
except json.JSONDecodeError as err:
|
|
280
|
+
raise HttpCortexJsonError(
|
|
281
|
+
f"Malformed JSON response from {self.url}: {err}\nDoc:\n{err.doc}", err
|
|
282
|
+
) from err
|
|
283
|
+
|
|
261
284
|
except Exception as err:
|
|
285
|
+
if isinstance(err, KeyboardInterrupt) or isinstance(err, SystemExit):
|
|
286
|
+
raise err
|
|
262
287
|
raise HttpCortexError(
|
|
263
288
|
f"Unable to execute storm on {self.url}: {err}", err
|
|
264
289
|
) from err
|
|
@@ -21,6 +21,18 @@ from .output import OUTP, handle_msg
|
|
|
21
21
|
from .stormcli import start_storm_cli
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
def endswith(text, items):
|
|
25
|
+
for item in items:
|
|
26
|
+
if text.endswith(item):
|
|
27
|
+
return True
|
|
28
|
+
return False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def csv_genr(fd):
|
|
32
|
+
for row in csv.reader(fd):
|
|
33
|
+
yield row
|
|
34
|
+
|
|
35
|
+
|
|
24
36
|
def json_genr(fd):
|
|
25
37
|
# TODO - Support nested key to start with
|
|
26
38
|
data = json.load(fd)
|
|
@@ -40,9 +52,15 @@ def txt_genr(fd):
|
|
|
40
52
|
yield row.strip()
|
|
41
53
|
|
|
42
54
|
|
|
43
|
-
def
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
async def import_storm_text(core, text, stormopts, print_skips):
|
|
56
|
+
async for msg in core.storm(text, opts=stormopts):
|
|
57
|
+
handle_msg(msg, print_skips=print_skips)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
async def import_storml_file(core, storm_script, stormopts, print_skips):
|
|
61
|
+
with open(storm_script, "r") as fd:
|
|
62
|
+
for line in txt_genr(fd):
|
|
63
|
+
await import_storm_text(core, line, stormopts, print_skips)
|
|
46
64
|
|
|
47
65
|
|
|
48
66
|
class Importer:
|
|
@@ -226,13 +244,9 @@ async def main(argv: list[str]):
|
|
|
226
244
|
dirs.sort() # NOTE - Ensures the next iteration of dirs is in order.
|
|
227
245
|
for file in sorted(files):
|
|
228
246
|
fullpath = os.path.join(dir, file)
|
|
229
|
-
if
|
|
247
|
+
if endswith(file, (".storm", ".storml")):
|
|
230
248
|
storm_scripts.append(fullpath)
|
|
231
|
-
elif (
|
|
232
|
-
file.endswith(".json")
|
|
233
|
-
or file.endswith(".txt")
|
|
234
|
-
or file.endswith(".csv")
|
|
235
|
-
):
|
|
249
|
+
elif endswith(file, (".json", ".txt", ".csv")):
|
|
236
250
|
data_files.append(fullpath)
|
|
237
251
|
else:
|
|
238
252
|
print(f"{path} doesn't exist!")
|
|
@@ -255,9 +269,12 @@ async def main(argv: list[str]):
|
|
|
255
269
|
debug=args.debug,
|
|
256
270
|
).add_data()
|
|
257
271
|
else:
|
|
258
|
-
|
|
259
|
-
# TODO -
|
|
260
|
-
|
|
272
|
+
if storm_script.endswith(".storml"):
|
|
273
|
+
# TODO - This will wind up opening and closing the file twice.
|
|
274
|
+
# Do we want that? Maybe we do because we won't get here much?
|
|
275
|
+
await import_storml_file(core, storm_script, stormopts, print_skips)
|
|
276
|
+
else:
|
|
277
|
+
await import_storm_text(core, text, stormopts, print_skips)
|
|
261
278
|
|
|
262
279
|
if args.cli:
|
|
263
280
|
await start_storm_cli(core, outp=OUTP, opts=args)
|
|
@@ -8,6 +8,8 @@ from the Storm CLI and modified it to work in standalone methods.
|
|
|
8
8
|
import synapse.lib.node as s_node
|
|
9
9
|
import synapse.lib.output as s_output
|
|
10
10
|
|
|
11
|
+
from .errors import StormRaiseError
|
|
12
|
+
|
|
11
13
|
|
|
12
14
|
OUTP = s_output.stdout
|
|
13
15
|
|
|
@@ -16,7 +18,7 @@ def print_node_prop(name, valu):
|
|
|
16
18
|
OUTP.printf(f" {name} = {valu}")
|
|
17
19
|
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
def handle_err(mesg, storm_raise=True):
|
|
20
22
|
err = mesg[1]
|
|
21
23
|
if err[0] == "BadSyntax":
|
|
22
24
|
pos = err[1].get("at", None)
|
|
@@ -38,6 +40,10 @@ async def handleErr(mesg):
|
|
|
38
40
|
OUTP.printf(f'{" " * pos}^')
|
|
39
41
|
OUTP.printf(f"Syntax Error: {mesg}")
|
|
40
42
|
return
|
|
43
|
+
elif err[0] == "StormRaise" and storm_raise:
|
|
44
|
+
errname = err[1].get("errname", "")
|
|
45
|
+
if errname == "stormlibpp:exit":
|
|
46
|
+
raise StormRaiseError(f"{errname}: {err[1].get('mesg', err[0])}")
|
|
41
47
|
|
|
42
48
|
text = err[1].get("mesg", err[0])
|
|
43
49
|
OUTP.printf(f"ERROR: {text}")
|
|
@@ -48,6 +54,7 @@ def handle_msg(
|
|
|
48
54
|
hideprops: bool = False,
|
|
49
55
|
hidetags: bool = False,
|
|
50
56
|
print_skips: list[str] = [],
|
|
57
|
+
print_fini: bool = True
|
|
51
58
|
):
|
|
52
59
|
mtyp = mesg[0]
|
|
53
60
|
|
|
@@ -119,7 +126,7 @@ def handle_msg(
|
|
|
119
126
|
count = sum(len(e[2]) for e in edit.get("edits", ()))
|
|
120
127
|
OUTP.printf("." * count, addnl=False)
|
|
121
128
|
|
|
122
|
-
elif mtyp == "fini":
|
|
129
|
+
elif mtyp == "fini" and print_fini:
|
|
123
130
|
took = mesg[1].get("took")
|
|
124
131
|
took = max(took, 1)
|
|
125
132
|
count = mesg[1].get("count")
|
|
@@ -138,4 +145,4 @@ def handle_msg(
|
|
|
138
145
|
OUTP.printf(f"WARNING: {warn}")
|
|
139
146
|
|
|
140
147
|
elif mtyp == "err":
|
|
141
|
-
|
|
148
|
+
handle_err(mesg)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: stormlibpp
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.4
|
|
4
4
|
Summary: The stormlibpp Python package
|
|
5
5
|
Author: John Gorman
|
|
6
6
|
License: MIT License
|
|
@@ -29,6 +29,7 @@ Project-URL: Documentation, https://gormo.co/stormlibpp/
|
|
|
29
29
|
Requires-Python: >=3.11
|
|
30
30
|
Description-Content-Type: text/markdown
|
|
31
31
|
License-File: LICENSE
|
|
32
|
+
Requires-Dist: synapse>=2.139.0
|
|
32
33
|
|
|
33
34
|
# stormlibpp
|
|
34
35
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
synapse>=2.139.0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
synapse==2.139.0
|
|
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
|