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.
Files changed (28) hide show
  1. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/PKG-INFO +2 -1
  2. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/pyproject.toml +2 -2
  3. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/__init__.py +1 -1
  4. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/errors.py +9 -0
  5. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/hstorm.py +0 -3
  6. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/httpcore.py +27 -2
  7. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/import.py +29 -12
  8. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/output.py +10 -3
  9. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp.egg-info/PKG-INFO +2 -1
  10. stormlibpp-0.6.4/src/stormlibpp.egg-info/requires.txt +1 -0
  11. stormlibpp-0.6.2/src/stormlibpp.egg-info/requires.txt +0 -1
  12. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/LICENSE +0 -0
  13. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/README.md +0 -0
  14. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/setup.cfg +0 -0
  15. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/node.py +0 -0
  16. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/stormcli.py +0 -0
  17. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/stormpkg.py +0 -0
  18. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/telepath.py +0 -0
  19. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/tmpcortex.py +0 -0
  20. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp/utils.py +0 -0
  21. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp.egg-info/SOURCES.txt +0 -0
  22. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp.egg-info/dependency_links.txt +0 -0
  23. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/src/stormlibpp.egg-info/top_level.txt +0 -0
  24. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/tests/test_httpcore.py +0 -0
  25. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/tests/test_node.py +0 -0
  26. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/tests/test_stormpkg.py +0 -0
  27. {stormlibpp-0.6.2 → stormlibpp-0.6.4}/tests/test_telepath.py +0 -0
  28. {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.2
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.2"
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==2.139.0"
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.2"
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."""
@@ -23,9 +23,6 @@ import argparse
23
23
  import getpass
24
24
  import sys
25
25
 
26
- import synapse.lib.output as s_output
27
- import synapse.tools.storm as s_storm
28
-
29
26
  from .httpcore import HttpCortex
30
27
  from .output import OUTP
31
28
  from .stormcli import start_storm_cli
@@ -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
- async for byts, _ in resp.content.iter_chunks():
252
+ buf = b""
253
+ async for byts, chunkend in resp.content.iter_chunks():
252
254
  if not byts:
253
255
  break
254
256
 
255
- data = json.loads(byts)
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 csv_genr(fd):
44
- for row in csv.reader(fd):
45
- yield row
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 file.endswith(".storm"):
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
- async for msg in core.storm(text, opts=stormopts):
259
- # TODO - Optionally use hide* args
260
- handle_msg(msg, print_skips=print_skips)
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
- async def handleErr(mesg):
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
- handleErr(mesg)
148
+ handle_err(mesg)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stormlibpp
3
- Version: 0.6.2
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