synapse 2.206.0__py311-none-any.whl → 2.208.0__py311-none-any.whl
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.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/axon.py +4 -4
- synapse/cortex.py +12 -3
- synapse/lib/boss.py +5 -1
- synapse/lib/modelrev.py +27 -4
- synapse/lib/storm.lark +2 -2
- synapse/lib/storm.py +5 -5
- synapse/lib/stormhttp.py +6 -6
- synapse/lib/stormlib/auth.py +1 -1
- synapse/lib/stormlib/cortex.py +1 -1
- synapse/lib/stormlib/vault.py +1 -1
- synapse/lib/stormsvc.py +1 -1
- synapse/lib/stormtypes.py +64 -37
- synapse/lib/task.py +7 -1
- synapse/lib/time.py +8 -2
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +6 -1
- synapse/tests/test_axon.py +10 -0
- synapse/tests/test_cortex.py +4 -4
- synapse/tests/test_datamodel.py +1 -1
- synapse/tests/test_lib_ast.py +5 -5
- synapse/tests/test_lib_boss.py +2 -2
- synapse/tests/test_lib_nexus.py +5 -11
- synapse/tests/test_lib_storm.py +83 -6
- synapse/tests/test_lib_stormhttp.py +21 -8
- synapse/tests/test_lib_stormlib_cache.py +2 -2
- synapse/tests/test_lib_stormlib_scrape.py +1 -1
- synapse/tests/test_lib_stormlib_storm.py +63 -0
- synapse/tests/test_lib_stormsvc.py +3 -0
- synapse/tests/test_lib_stormtypes.py +44 -9
- synapse/tests/test_lib_trigger.py +3 -4
- synapse/tests/test_lib_view.py +3 -3
- synapse/tests/test_tools_csvtool.py +1 -1
- {synapse-2.206.0.dist-info → synapse-2.208.0.dist-info}/METADATA +6 -6
- {synapse-2.206.0.dist-info → synapse-2.208.0.dist-info}/RECORD +37 -37
- {synapse-2.206.0.dist-info → synapse-2.208.0.dist-info}/WHEEL +0 -0
- {synapse-2.206.0.dist-info → synapse-2.208.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.206.0.dist-info → synapse-2.208.0.dist-info}/top_level.txt +0 -0
synapse/axon.py
CHANGED
|
@@ -1659,7 +1659,7 @@ class Axon(s_cell.Cell):
|
|
|
1659
1659
|
'code': resp.status,
|
|
1660
1660
|
'body': await resp.read(),
|
|
1661
1661
|
'reason': s_common.httpcodereason(resp.status),
|
|
1662
|
-
'headers':
|
|
1662
|
+
'headers': {str(k): v for k, v in resp.headers.items()},
|
|
1663
1663
|
}
|
|
1664
1664
|
return info
|
|
1665
1665
|
|
|
@@ -1706,7 +1706,7 @@ class Axon(s_cell.Cell):
|
|
|
1706
1706
|
'url': str(resp.url),
|
|
1707
1707
|
'code': resp.status,
|
|
1708
1708
|
'reason': s_common.httpcodereason(resp.status),
|
|
1709
|
-
'headers':
|
|
1709
|
+
'headers': {str(k): v for k, v in resp.headers.items()},
|
|
1710
1710
|
}
|
|
1711
1711
|
return info
|
|
1712
1712
|
|
|
@@ -1736,11 +1736,11 @@ class Axon(s_cell.Cell):
|
|
|
1736
1736
|
'ok': True,
|
|
1737
1737
|
'url': str(resp.real_url),
|
|
1738
1738
|
'code': resp.status,
|
|
1739
|
-
'headers':
|
|
1739
|
+
'headers': {str(k): v for k, v in resp.headers.items()},
|
|
1740
1740
|
'reason': s_common.httpcodereason(resp.status),
|
|
1741
1741
|
'request': {
|
|
1742
1742
|
'url': str(resp.request_info.real_url),
|
|
1743
|
-
'headers':
|
|
1743
|
+
'headers': {str(k): v for k, v in resp.request_info.headers.items()},
|
|
1744
1744
|
'method': str(resp.request_info.method),
|
|
1745
1745
|
}
|
|
1746
1746
|
}
|
synapse/cortex.py
CHANGED
|
@@ -1581,6 +1581,9 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1581
1581
|
for layer in self.layers.values():
|
|
1582
1582
|
await layer.initLayerActive()
|
|
1583
1583
|
|
|
1584
|
+
for pkgdef in list(self.stormpkgs.values()):
|
|
1585
|
+
self._runStormPkgOnload(pkgdef)
|
|
1586
|
+
|
|
1584
1587
|
self.runActiveTask(_runMigrations())
|
|
1585
1588
|
|
|
1586
1589
|
await self.initStormPool()
|
|
@@ -2638,6 +2641,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2638
2641
|
return
|
|
2639
2642
|
|
|
2640
2643
|
self.loadStormPkg(pkgdef)
|
|
2644
|
+
self._runStormPkgOnload(pkgdef)
|
|
2641
2645
|
self.pkgdefs.set(name, pkgdef)
|
|
2642
2646
|
|
|
2643
2647
|
self._clearPermDefs()
|
|
@@ -2929,9 +2933,13 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2929
2933
|
self._initEasyPerm(gdef)
|
|
2930
2934
|
self.pkggraphs[gdef['iden']] = gdef
|
|
2931
2935
|
|
|
2936
|
+
def _runStormPkgOnload(self, pkgdef):
|
|
2937
|
+
name = pkgdef.get('name')
|
|
2932
2938
|
onload = pkgdef.get('onload')
|
|
2939
|
+
|
|
2933
2940
|
if onload is not None and self.isactive:
|
|
2934
2941
|
async def _onload():
|
|
2942
|
+
await self.fire('core:pkg:onload:start', pkg=name)
|
|
2935
2943
|
try:
|
|
2936
2944
|
async for mesg in self.storm(onload):
|
|
2937
2945
|
if mesg[0] == 'print':
|
|
@@ -2943,10 +2951,11 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2943
2951
|
await asyncio.sleep(0)
|
|
2944
2952
|
except asyncio.CancelledError: # pragma: no cover
|
|
2945
2953
|
raise
|
|
2946
|
-
except Exception: # pragma: no cover
|
|
2947
|
-
logger.warning(f'onload failed for package: {name}')
|
|
2954
|
+
except Exception as exc: # pragma: no cover
|
|
2955
|
+
logger.warning(f'onload failed for package: {name}', exc_info=exc)
|
|
2948
2956
|
await self.fire('core:pkg:onload:complete', pkg=name)
|
|
2949
|
-
|
|
2957
|
+
|
|
2958
|
+
self.runActiveTask(_onload())
|
|
2950
2959
|
|
|
2951
2960
|
# N.B. This function is intentionally not async in order to prevent possible user race conditions for code
|
|
2952
2961
|
# executing outside of the nexus lock.
|
synapse/lib/boss.py
CHANGED
|
@@ -10,6 +10,10 @@ class Boss(s_base.Base):
|
|
|
10
10
|
|
|
11
11
|
'''
|
|
12
12
|
An object to track "promoted" async tasks.
|
|
13
|
+
|
|
14
|
+
Promoted tasks are asyncio tasks, wrapped in a synapse task
|
|
15
|
+
(``s_task.Task``), that are visible to storm users via the task tracking
|
|
16
|
+
libs/commands such as ``ps.list`` and ``$lib.ps.list()``.
|
|
13
17
|
'''
|
|
14
18
|
async def __anit__(self):
|
|
15
19
|
await s_base.Base.__anit__(self)
|
|
@@ -45,7 +49,7 @@ class Boss(s_base.Base):
|
|
|
45
49
|
|
|
46
50
|
async def promotetask(self, task, name, user, info=None, taskiden=None):
|
|
47
51
|
|
|
48
|
-
synt =
|
|
52
|
+
synt = s_task.syntask(task)
|
|
49
53
|
|
|
50
54
|
if synt is not None:
|
|
51
55
|
|
synapse/lib/modelrev.py
CHANGED
|
@@ -1466,6 +1466,7 @@ class ModelMigration_0_2_31:
|
|
|
1466
1466
|
if (v2_2 := props.get('v2_2')) is not None:
|
|
1467
1467
|
propvalu, stortype = v2_2
|
|
1468
1468
|
if not s_infotech.isValidCpe22(propvalu):
|
|
1469
|
+
logger.debug(f'Queueing invalid v2_2 value for deletion iden={s_common.ehex(buid)} valu={propvalu}')
|
|
1469
1470
|
await self._queueEdit(
|
|
1470
1471
|
layer.iden,
|
|
1471
1472
|
(buid, 'it:sec:cpe', (
|
|
@@ -1622,10 +1623,25 @@ class ModelMigration_0_2_31:
|
|
|
1622
1623
|
if propvalu is not None:
|
|
1623
1624
|
break
|
|
1624
1625
|
|
|
1625
|
-
|
|
1626
|
-
|
|
1626
|
+
if propvalu is None: # pragma: no cover
|
|
1627
|
+
# We didn't find a v2_2 value so remove this node
|
|
1628
|
+
await self.removeNode(buid)
|
|
1629
|
+
removed += 1
|
|
1630
|
+
|
|
1631
|
+
else:
|
|
1632
|
+
# We did find a v2_2 value so try to norm it and use that new value to move the node. If this fails,
|
|
1633
|
+
# remove the node.
|
|
1634
|
+
try:
|
|
1635
|
+
newvalu, _ = form.type.norm(propvalu)
|
|
1627
1636
|
|
|
1628
|
-
|
|
1637
|
+
except s_exc.BadTypeValu: # pragma: no cover
|
|
1638
|
+
logger.debug('Unexpectedly encountered invalid v2_2 prop: iden=%s valu=%s', s_common.ehex(buid), propvalu)
|
|
1639
|
+
await self.removeNode(buid)
|
|
1640
|
+
removed += 1
|
|
1641
|
+
|
|
1642
|
+
else:
|
|
1643
|
+
await self.moveNode(buid, newvalu)
|
|
1644
|
+
migrated += 1
|
|
1629
1645
|
|
|
1630
1646
|
elif action == 'remove':
|
|
1631
1647
|
newvalu = None
|
|
@@ -1636,10 +1652,17 @@ class ModelMigration_0_2_31:
|
|
|
1636
1652
|
if propvalu is None:
|
|
1637
1653
|
continue
|
|
1638
1654
|
|
|
1639
|
-
newvalu, _ = form.type.norm(propvalu)
|
|
1640
1655
|
# This prop is going to be the new primary value so delete the secondary prop
|
|
1641
1656
|
await self.editPropDel(layriden, buid, 'it:sec:cpe', 'v2_2', propvalu, stortype)
|
|
1642
1657
|
|
|
1658
|
+
# We did find a v2_2 value so try to norm it and use that new value to move the node. If this fails,
|
|
1659
|
+
# remove the node.
|
|
1660
|
+
try:
|
|
1661
|
+
newvalu, _ = form.type.norm(propvalu)
|
|
1662
|
+
except s_exc.BadTypeValu: # pragma: no cover
|
|
1663
|
+
logger.debug('Unexpectedly encountered invalid v2_2 prop: iden=%s valu=%s', s_common.ehex(buid), propvalu)
|
|
1664
|
+
continue
|
|
1665
|
+
|
|
1643
1666
|
# Oh yeah! Migrate the node instead of removing it
|
|
1644
1667
|
await self.moveNode(buid, newvalu)
|
|
1645
1668
|
|
synapse/lib/storm.lark
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
%ignore CPPCOMMENT
|
|
6
6
|
%ignore WS
|
|
7
7
|
|
|
8
|
-
WS: /[\s]/+
|
|
8
|
+
WS.-1: /[\s]/+
|
|
9
9
|
|
|
10
10
|
// C comment: /* */
|
|
11
11
|
// From https://stackoverflow.com/a/36328890/6518334
|
|
@@ -466,7 +466,7 @@ TRIPLEQUOTEDSTRING: /'''.*?'''/s
|
|
|
466
466
|
DOUBLEQUOTEDSTRING: ESCAPED_STRING
|
|
467
467
|
SINGLEQUOTEDSTRING: /'[^']*'(?!')/
|
|
468
468
|
|
|
469
|
-
FORMATTEXT: /
|
|
469
|
+
FORMATTEXT.-1: /((?<!\\)(\\\\)*\\[`{]|[^`{])+/s
|
|
470
470
|
_formatexpr: "{" expror "}"
|
|
471
471
|
formatstring: "`" (_formatexpr | FORMATTEXT)* "`"
|
|
472
472
|
|
synapse/lib/storm.py
CHANGED
|
@@ -507,7 +507,7 @@ stormcmds = (
|
|
|
507
507
|
if ( $defv = $lib.null ) {
|
|
508
508
|
$defv = $lib.false
|
|
509
509
|
}
|
|
510
|
-
$text = `{
|
|
510
|
+
$text = `{('.').join($permdef.perm).ljust(32)} : {$permdef.desc} ( default: {$defv} )`
|
|
511
511
|
$lib.print($text)
|
|
512
512
|
}
|
|
513
513
|
} else {
|
|
@@ -594,7 +594,7 @@ stormcmds = (
|
|
|
594
594
|
$ssl = $lib.true
|
|
595
595
|
if $cmdopts.ssl_noverify { $ssl = $lib.false }
|
|
596
596
|
|
|
597
|
-
$headers = ({'X-Synapse-Version':
|
|
597
|
+
$headers = ({'X-Synapse-Version': ('.').join($lib.version.synapse())})
|
|
598
598
|
|
|
599
599
|
$resp = $lib.inet.http.get($cmdopts.url, ssl_verify=$ssl, headers=$headers)
|
|
600
600
|
|
|
@@ -629,7 +629,7 @@ stormcmds = (
|
|
|
629
629
|
$synv = $lib.version.synapse()
|
|
630
630
|
|
|
631
631
|
if $synv {
|
|
632
|
-
$synv =
|
|
632
|
+
$synv = ('.').join($synv)
|
|
633
633
|
}
|
|
634
634
|
|
|
635
635
|
if $comm {
|
|
@@ -1078,8 +1078,8 @@ stormcmds = (
|
|
|
1078
1078
|
$lib.print('entries: incunit incval required')
|
|
1079
1079
|
|
|
1080
1080
|
for $rec in $job.recs {
|
|
1081
|
-
$incunit =
|
|
1082
|
-
$incval =
|
|
1081
|
+
$incunit = (`{$rec.incunit}`).ljust(10)
|
|
1082
|
+
$incval = (`{$rec.incval}`).ljust(6)
|
|
1083
1083
|
|
|
1084
1084
|
$lib.print(' {incunit} {incval} {reqdict}',
|
|
1085
1085
|
incunit=$incunit, incval=$incval, reqdict=$rec.reqdict)
|
synapse/lib/stormhttp.py
CHANGED
|
@@ -457,23 +457,23 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
457
457
|
hnfo = {
|
|
458
458
|
'code': hist.status,
|
|
459
459
|
'reason': await self.codereason(hist.status),
|
|
460
|
-
'headers':
|
|
460
|
+
'headers': {str(k): v for k, v in hist.headers.items()},
|
|
461
461
|
'url': str(hist.url),
|
|
462
462
|
# aiohttp has already closed the connection by this point
|
|
463
463
|
# so there is no connection to read a body from.
|
|
464
464
|
'body': b'',
|
|
465
465
|
'history': [],
|
|
466
|
-
'request_headers':
|
|
466
|
+
'request_headers': {str(k): v for k, v in hist.request_info.headers.items()}
|
|
467
467
|
}
|
|
468
468
|
history.append(hnfo)
|
|
469
469
|
info = {
|
|
470
470
|
'code': resp.status,
|
|
471
471
|
'reason': await self.codereason(resp.status),
|
|
472
|
-
'headers':
|
|
472
|
+
'headers': {str(k): v for k, v in resp.headers.items()},
|
|
473
473
|
'url': str(resp.url),
|
|
474
474
|
'body': await resp.read(),
|
|
475
475
|
'history': history,
|
|
476
|
-
'request_headers':
|
|
476
|
+
'request_headers': {str(k): v for k, v in resp.request_info.headers.items()},
|
|
477
477
|
}
|
|
478
478
|
return HttpResp(info)
|
|
479
479
|
|
|
@@ -492,11 +492,11 @@ class LibHttp(s_stormtypes.Lib):
|
|
|
492
492
|
'err': err,
|
|
493
493
|
'code': -1,
|
|
494
494
|
'reason': reason,
|
|
495
|
-
'headers':
|
|
495
|
+
'headers': {},
|
|
496
496
|
'url': url,
|
|
497
497
|
'body': b'',
|
|
498
498
|
'history': [],
|
|
499
|
-
'request_headers':
|
|
499
|
+
'request_headers': {},
|
|
500
500
|
}
|
|
501
501
|
return HttpResp(info)
|
|
502
502
|
|
synapse/lib/stormlib/auth.py
CHANGED
synapse/lib/stormlib/cortex.py
CHANGED
|
@@ -107,7 +107,7 @@ stormcmds = [
|
|
|
107
107
|
if $perms {
|
|
108
108
|
$lib.print('The following user permissions are required to run this HTTP API endpoint:')
|
|
109
109
|
for $pdef in $perms {
|
|
110
|
-
$perm =
|
|
110
|
+
$perm = ('.').join($pdef.perm)
|
|
111
111
|
$lib.print($perm)
|
|
112
112
|
$lib.print(` default: {$pdef.default}`)
|
|
113
113
|
}
|
synapse/lib/stormlib/vault.py
CHANGED
synapse/lib/stormsvc.py
CHANGED
synapse/lib/stormtypes.py
CHANGED
|
@@ -1235,7 +1235,7 @@ class LibBase(Lib):
|
|
|
1235
1235
|
Examples:
|
|
1236
1236
|
Fire an event called ``demo`` with some data::
|
|
1237
1237
|
|
|
1238
|
-
|
|
1238
|
+
storm> $foo='bar' $lib.fire('demo', foo=$foo, knight='ni')
|
|
1239
1239
|
...
|
|
1240
1240
|
('storm:fire', {'type': 'demo', 'data': {'foo': 'bar', 'knight': 'ni'}})
|
|
1241
1241
|
...
|
|
@@ -1268,7 +1268,7 @@ class LibBase(Lib):
|
|
|
1268
1268
|
Examples:
|
|
1269
1269
|
Create a dictionary object with a key whose value is null, and call ``$lib.fire()`` with it::
|
|
1270
1270
|
|
|
1271
|
-
|
|
1271
|
+
storm> $d=({"key": $lib.null}) $lib.fire('demo', d=$d)
|
|
1272
1272
|
('storm:fire', {'type': 'demo', 'data': {'d': {'key': None}}})
|
|
1273
1273
|
''',
|
|
1274
1274
|
'type': 'null', },
|
|
@@ -1295,7 +1295,7 @@ class LibBase(Lib):
|
|
|
1295
1295
|
Examples:
|
|
1296
1296
|
Conditionally print a statement based on the constant value::
|
|
1297
1297
|
|
|
1298
|
-
|
|
1298
|
+
storm> if $lib.true { $lib.print('Is True') } else { $lib.print('Is False') }
|
|
1299
1299
|
Is True
|
|
1300
1300
|
''',
|
|
1301
1301
|
'type': 'boolean', },
|
|
@@ -1305,10 +1305,10 @@ class LibBase(Lib):
|
|
|
1305
1305
|
Examples:
|
|
1306
1306
|
Conditionally print a statement based on the constant value::
|
|
1307
1307
|
|
|
1308
|
-
|
|
1308
|
+
storm> if $lib.false { $lib.print('Is True') } else { $lib.print('Is False') }
|
|
1309
1309
|
Is False''',
|
|
1310
1310
|
'type': 'boolean', },
|
|
1311
|
-
{'name': 'text', 'desc':
|
|
1311
|
+
{'name': 'text', 'desc': "Get a Storm Text object. This is deprecated; please use a list to append strings to, and then use ``('.').join($listOfStr)`` to join them on demand.",
|
|
1312
1312
|
'deprecated': {'eolvers': '3.0.0'},
|
|
1313
1313
|
'type': {'type': 'function', '_funcname': '_text',
|
|
1314
1314
|
'args': (
|
|
@@ -1344,19 +1344,19 @@ class LibBase(Lib):
|
|
|
1344
1344
|
Examples:
|
|
1345
1345
|
Print a simple string::
|
|
1346
1346
|
|
|
1347
|
-
|
|
1347
|
+
storm> $lib.print("Hello world!")
|
|
1348
1348
|
Hello world!
|
|
1349
1349
|
|
|
1350
1350
|
Format and print string based on variables::
|
|
1351
1351
|
|
|
1352
|
-
|
|
1352
|
+
storm> $d=({"key1": (1), "key2": "two"})
|
|
1353
1353
|
for ($key, $value) in $d { $lib.print('{k} => {v}', k=$key, v=$value) }
|
|
1354
1354
|
key1 => 1
|
|
1355
1355
|
key2 => two
|
|
1356
1356
|
|
|
1357
1357
|
Use values off of a node to format and print string::
|
|
1358
1358
|
|
|
1359
|
-
|
|
1359
|
+
storm> inet:ipv4:asn
|
|
1360
1360
|
$lib.print("node: {ndef}, asn: {asn}", ndef=$node.ndef(), asn=:asn) | spin
|
|
1361
1361
|
node: ('inet:ipv4', 16909060), asn: 1138
|
|
1362
1362
|
|
|
@@ -1376,7 +1376,7 @@ class LibBase(Lib):
|
|
|
1376
1376
|
Examples:
|
|
1377
1377
|
Generate a sequence of integers based on the size of an array::
|
|
1378
1378
|
|
|
1379
|
-
|
|
1379
|
+
storm> $a=(foo,bar,(2)) for $i in $lib.range($lib.len($a)) {$lib.fire('test', indx=$i, valu=$a.$i)}
|
|
1380
1380
|
Executing query at 2021/03/22 19:25:48.835
|
|
1381
1381
|
('storm:fire', {'type': 'test', 'data': {'index': 0, 'valu': 'foo'}})
|
|
1382
1382
|
('storm:fire', {'type': 'test', 'data': {'index': 1, 'valu': 'bar'}})
|
|
@@ -1691,7 +1691,7 @@ class LibBase(Lib):
|
|
|
1691
1691
|
s_common.deprecated('$lib.text()', curv='2.194.0')
|
|
1692
1692
|
runt = s_scope.get('runt')
|
|
1693
1693
|
if runt:
|
|
1694
|
-
await runt.snap.warnonce(
|
|
1694
|
+
await runt.snap.warnonce("$lib.text() is deprecated. Please use a list to append strings to, and then use ``('').join($listOfStr)`` to join them on demand.")
|
|
1695
1695
|
valu = ''.join(args)
|
|
1696
1696
|
return Text(valu)
|
|
1697
1697
|
|
|
@@ -2023,15 +2023,8 @@ class LibStr(Lib):
|
|
|
2023
2023
|
A Storm Library for interacting with strings.
|
|
2024
2024
|
'''
|
|
2025
2025
|
_storm_locals = (
|
|
2026
|
-
{'name': 'join', 'desc': ''
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
Examples:
|
|
2030
|
-
Join together a list of strings with a dot separator::
|
|
2031
|
-
|
|
2032
|
-
cli> storm $foo=$lib.str.join('.', ('rep', 'vtx', 'tag')) $lib.print($foo)
|
|
2033
|
-
|
|
2034
|
-
rep.vtx.tag''',
|
|
2026
|
+
{'name': 'join', 'desc': 'Join items into a string using a separator.',
|
|
2027
|
+
# 'deprecated': {'eolvers': 'v3.0.0', 'mesg': 'Use ``('').join($foo, $bar, $baz, ....)`` instead.'},
|
|
2035
2028
|
'type': {'type': 'function', '_funcname': 'join',
|
|
2036
2029
|
'args': (
|
|
2037
2030
|
{'name': 'sepr', 'type': 'str', 'desc': 'The separator used to join strings with.', },
|
|
@@ -2039,22 +2032,14 @@ class LibStr(Lib):
|
|
|
2039
2032
|
),
|
|
2040
2033
|
'returns': {'type': 'str', 'desc': 'The joined string.', }}},
|
|
2041
2034
|
{'name': 'concat', 'desc': 'Concatenate a set of strings together.',
|
|
2035
|
+
# 'deprecated': {'eolvers': 'v3.0.0', 'mesg': "Use ``('').join($foo, $bar, $baz, ....)`` instead."},
|
|
2042
2036
|
'type': {'type': 'function', '_funcname': 'concat',
|
|
2043
2037
|
'args': (
|
|
2044
2038
|
{'name': '*args', 'type': 'any', 'desc': 'Items to join together.', },
|
|
2045
2039
|
),
|
|
2046
2040
|
'returns': {'type': 'str', 'desc': 'The joined string.', }}},
|
|
2047
|
-
{'name': 'format', 'desc': ''
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
Examples:
|
|
2051
|
-
Format a string with a fixed argument and a variable::
|
|
2052
|
-
|
|
2053
|
-
cli> storm $list=(1,2,3,4)
|
|
2054
|
-
$str=$lib.str.format('Hello {name}, your list is {list}!', name='Reader', list=$list)
|
|
2055
|
-
$lib.print($str)
|
|
2056
|
-
|
|
2057
|
-
Hello Reader, your list is ['1', '2', '3', '4']!''',
|
|
2041
|
+
{'name': 'format', 'desc': 'Format a text string.',
|
|
2042
|
+
# 'deprecated': {'eolvers': 'v3.0.0', 'mesg': 'Use ``$mystr.format(foo=$bar)`` instead.'},
|
|
2058
2043
|
'type': {'type': 'function', '_funcname': 'format',
|
|
2059
2044
|
'args': (
|
|
2060
2045
|
{'name': 'text', 'type': 'str', 'desc': 'The base text string.', },
|
|
@@ -2065,6 +2050,10 @@ class LibStr(Lib):
|
|
|
2065
2050
|
)
|
|
2066
2051
|
_storm_lib_path = ('str',)
|
|
2067
2052
|
|
|
2053
|
+
# _lib_str_join_depr_mesg = '$lib.str.join(), use "$sepr.join($items)" instead.'
|
|
2054
|
+
# _lib_str_concat_depr_mesg = "$lib.str.concat(), use ('').join($foo, $bar, $baz, ....) instead."
|
|
2055
|
+
# _lib_str_format_depr_mesg = '$lib.str.format(), use "$mystr.format(foo=$bar)" instead.'
|
|
2056
|
+
|
|
2068
2057
|
def getObjLocals(self):
|
|
2069
2058
|
return {
|
|
2070
2059
|
'join': self.join,
|
|
@@ -2074,17 +2063,29 @@ class LibStr(Lib):
|
|
|
2074
2063
|
|
|
2075
2064
|
@stormfunc(readonly=True)
|
|
2076
2065
|
async def concat(self, *args):
|
|
2066
|
+
# s_common.deprecated(self._lib_str_concat_depr_mesg)
|
|
2067
|
+
# runt = s_scope.get('runt')
|
|
2068
|
+
# if runt:
|
|
2069
|
+
# await runt.snap.warnonce(self._lib_str_concat_depr_mesg)
|
|
2077
2070
|
strs = [await tostr(a) for a in args]
|
|
2078
2071
|
return ''.join(strs)
|
|
2079
2072
|
|
|
2080
2073
|
@stormfunc(readonly=True)
|
|
2081
2074
|
async def format(self, text, **kwargs):
|
|
2075
|
+
# s_common.deprecated(self._lib_str_format_depr_mesg)
|
|
2076
|
+
# runt = s_scope.get('runt')
|
|
2077
|
+
# if runt:
|
|
2078
|
+
# await runt.snap.warnonce(self._lib_str_format_depr_mesg)
|
|
2082
2079
|
text = await kwarg_format(text, **kwargs)
|
|
2083
2080
|
|
|
2084
2081
|
return text
|
|
2085
2082
|
|
|
2086
2083
|
@stormfunc(readonly=True)
|
|
2087
2084
|
async def join(self, sepr, items):
|
|
2085
|
+
# s_common.deprecated(self._lib_str_join_depr_mesg)
|
|
2086
|
+
# runt = s_scope.get('runt')
|
|
2087
|
+
# if runt:
|
|
2088
|
+
# await runt.snap.warnonce(self._lib_str_join_depr_mesg)
|
|
2088
2089
|
strs = [await tostr(item) async for item in toiter(items)]
|
|
2089
2090
|
return sepr.join(strs)
|
|
2090
2091
|
|
|
@@ -2324,7 +2325,7 @@ class LibAxon(Lib):
|
|
|
2324
2325
|
Examples:
|
|
2325
2326
|
Save a base64 encoded buffer to the Axon::
|
|
2326
2327
|
|
|
2327
|
-
|
|
2328
|
+
storm> $s='dGVzdA==' $buf=$lib.base64.decode($s) ($size, $sha256)=$lib.axon.put($buf)
|
|
2328
2329
|
$lib.print('size={size} sha256={sha256}', size=$size, sha256=$sha256)
|
|
2329
2330
|
|
|
2330
2331
|
size=4 sha256=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08''',
|
|
@@ -2340,7 +2341,7 @@ class LibAxon(Lib):
|
|
|
2340
2341
|
Check if the Axon has a given file::
|
|
2341
2342
|
|
|
2342
2343
|
# This example assumes the Axon does have the bytes
|
|
2343
|
-
|
|
2344
|
+
storm> if $lib.axon.has(9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08) {
|
|
2344
2345
|
$lib.print("Has bytes")
|
|
2345
2346
|
} else {
|
|
2346
2347
|
$lib.print("Does not have bytes")
|
|
@@ -2812,7 +2813,7 @@ class LibBytes(Lib):
|
|
|
2812
2813
|
Examples:
|
|
2813
2814
|
Save a base64 encoded buffer to the Axon::
|
|
2814
2815
|
|
|
2815
|
-
|
|
2816
|
+
storm> $s='dGVzdA==' $buf=$lib.base64.decode($s) ($size, $sha256)=$lib.bytes.put($buf)
|
|
2816
2817
|
$lib.print('size={size} sha256={sha256}', size=$size, sha256=$sha256)
|
|
2817
2818
|
|
|
2818
2819
|
size=4 sha256=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08''',
|
|
@@ -2828,7 +2829,7 @@ class LibBytes(Lib):
|
|
|
2828
2829
|
Check if the Axon has a given file::
|
|
2829
2830
|
|
|
2830
2831
|
# This example assumes the Axon does have the bytes
|
|
2831
|
-
|
|
2832
|
+
storm> if $lib.bytes.has(9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08) {
|
|
2832
2833
|
$lib.print("Has bytes")
|
|
2833
2834
|
} else {
|
|
2834
2835
|
$lib.print("Does not have bytes")
|
|
@@ -3002,7 +3003,7 @@ class LibTime(Lib):
|
|
|
3002
3003
|
Examples:
|
|
3003
3004
|
Convert a timestamp from seconds to millis and format it::
|
|
3004
3005
|
|
|
3005
|
-
|
|
3006
|
+
storm> $seconds=1594684800 $millis=$lib.time.fromunix($seconds)
|
|
3006
3007
|
$str=$lib.time.format($millis, '%A %d, %B %Y') $lib.print($str)
|
|
3007
3008
|
|
|
3008
3009
|
Tuesday 14, July 2020''',
|
|
@@ -3017,7 +3018,7 @@ class LibTime(Lib):
|
|
|
3017
3018
|
Examples:
|
|
3018
3019
|
Parse a string as for its month/day/year value into a timestamp::
|
|
3019
3020
|
|
|
3020
|
-
|
|
3021
|
+
storm> $s='06/01/2020' $ts=$lib.time.parse($s, '%m/%d/%Y') $lib.print($ts)
|
|
3021
3022
|
|
|
3022
3023
|
1590969600000''',
|
|
3023
3024
|
'type': {'type': 'function', '_funcname': '_parse',
|
|
@@ -3034,7 +3035,7 @@ class LibTime(Lib):
|
|
|
3034
3035
|
Examples:
|
|
3035
3036
|
Format a timestamp into a string::
|
|
3036
3037
|
|
|
3037
|
-
|
|
3038
|
+
storm> $now=$lib.time.now() $str=$lib.time.format($now, '%A %d, %B %Y') $lib.print($str)
|
|
3038
3039
|
|
|
3039
3040
|
Tuesday 14, July 2020''',
|
|
3040
3041
|
'type': {'type': 'function', '_funcname': '_format',
|
|
@@ -4659,6 +4660,26 @@ class Str(Prim):
|
|
|
4659
4660
|
{'name': 'json', 'desc': 'Parse a JSON string and return the deserialized data.',
|
|
4660
4661
|
'type': {'type': 'function', '_funcname': '_methStrJson', 'args': (),
|
|
4661
4662
|
'returns': {'type': 'prim', 'desc': 'The JSON deserialized object.', }}},
|
|
4663
|
+
{'name': 'join', 'desc': '''
|
|
4664
|
+
Join items into a string using the current string as a separator.
|
|
4665
|
+
|
|
4666
|
+
Examples:
|
|
4667
|
+
Join together a list of strings with a dot separator::
|
|
4668
|
+
|
|
4669
|
+
storm> $sepr='.' $foo=$sepr.join(('rep', 'vtx', 'tag')) $lib.print($foo)
|
|
4670
|
+
|
|
4671
|
+
rep.vtx.tag
|
|
4672
|
+
|
|
4673
|
+
Join values inline together with a dot separator::
|
|
4674
|
+
|
|
4675
|
+
storm> $foo=('.').join(('rep', 'vtx', 'tag')) $lib.print($foo)
|
|
4676
|
+
|
|
4677
|
+
rep.vtx.tag''',
|
|
4678
|
+
'type': {'type': 'function', '_funcname': '_methStrJoin',
|
|
4679
|
+
'args': (
|
|
4680
|
+
{'name': 'items', 'type': 'list', 'desc': 'A list of items to join together.', },
|
|
4681
|
+
),
|
|
4682
|
+
'returns': {'type': 'str', 'desc': 'The joined string.', }}},
|
|
4662
4683
|
)
|
|
4663
4684
|
_storm_typename = 'str'
|
|
4664
4685
|
_ismutable = False
|
|
@@ -4689,6 +4710,7 @@ class Str(Prim):
|
|
|
4689
4710
|
'reverse': self._methStrReverse,
|
|
4690
4711
|
'format': self._methStrFormat,
|
|
4691
4712
|
'json': self._methStrJson,
|
|
4713
|
+
'join': self._methStrJoin,
|
|
4692
4714
|
}
|
|
4693
4715
|
|
|
4694
4716
|
def __int__(self):
|
|
@@ -4808,6 +4830,11 @@ class Str(Prim):
|
|
|
4808
4830
|
async def _methStrJson(self):
|
|
4809
4831
|
return s_json.loads(self.valu)
|
|
4810
4832
|
|
|
4833
|
+
@stormfunc(readonly=True)
|
|
4834
|
+
async def _methStrJoin(self, items):
|
|
4835
|
+
strs = [await tostr(item) async for item in toiter(items)]
|
|
4836
|
+
return self.valu.join(strs)
|
|
4837
|
+
|
|
4811
4838
|
@registry.registerType
|
|
4812
4839
|
class Bytes(Prim):
|
|
4813
4840
|
'''
|
synapse/lib/task.py
CHANGED
|
@@ -132,12 +132,18 @@ def loop():
|
|
|
132
132
|
except Exception:
|
|
133
133
|
return None
|
|
134
134
|
|
|
135
|
+
def syntask(task):
|
|
136
|
+
'''
|
|
137
|
+
Return the synapse task associated with the provided asyncio task.
|
|
138
|
+
'''
|
|
139
|
+
return getattr(task, '_syn_task', None)
|
|
140
|
+
|
|
135
141
|
def current():
|
|
136
142
|
'''
|
|
137
143
|
Return the current synapse task.
|
|
138
144
|
'''
|
|
139
145
|
task = asyncio.current_task()
|
|
140
|
-
return
|
|
146
|
+
return syntask(task)
|
|
141
147
|
|
|
142
148
|
def user():
|
|
143
149
|
'''
|
synapse/lib/time.py
CHANGED
|
@@ -312,5 +312,11 @@ def toUTC(tick, fromzone):
|
|
|
312
312
|
mesg = f'Unknown timezone: {fromzone}'
|
|
313
313
|
raise s_exc.BadArg(mesg=mesg) from e
|
|
314
314
|
|
|
315
|
-
base = datetime.datetime(1970, 1, 1
|
|
316
|
-
|
|
315
|
+
base = datetime.datetime(1970, 1, 1) + datetime.timedelta(milliseconds=tick)
|
|
316
|
+
try:
|
|
317
|
+
localized = tz.localize(base, is_dst=None)
|
|
318
|
+
except pytz.exceptions.AmbiguousTimeError as e:
|
|
319
|
+
mesg = f'Ambiguous time: {base} {fromzone}'
|
|
320
|
+
raise s_exc.BadArg(mesg=mesg) from e
|
|
321
|
+
|
|
322
|
+
return int(localized.astimezone(pytz.UTC).timestamp() * 1000)
|
synapse/lib/version.py
CHANGED
|
@@ -223,6 +223,6 @@ def reqVersion(valu, reqver,
|
|
|
223
223
|
##############################################################################
|
|
224
224
|
# The following are touched during the release process by bumpversion.
|
|
225
225
|
# Do not modify these directly.
|
|
226
|
-
version = (2,
|
|
226
|
+
version = (2, 208, 0)
|
|
227
227
|
verstring = '.'.join([str(x) for x in version])
|
|
228
|
-
commit = '
|
|
228
|
+
commit = '2cc5a903edc504ca95e4a6b905fdb468b7e3b361'
|
synapse/lib/view.py
CHANGED
|
@@ -8,6 +8,7 @@ import synapse.common as s_common
|
|
|
8
8
|
|
|
9
9
|
import synapse.lib.cell as s_cell
|
|
10
10
|
import synapse.lib.snap as s_snap
|
|
11
|
+
import synapse.lib.task as s_task
|
|
11
12
|
import synapse.lib.layer as s_layer
|
|
12
13
|
import synapse.lib.nexus as s_nexus
|
|
13
14
|
import synapse.lib.scope as s_scope
|
|
@@ -1000,7 +1001,11 @@ class View(s_nexus.Pusher): # type: ignore
|
|
|
1000
1001
|
keepalive = opts.get('keepalive')
|
|
1001
1002
|
if keepalive is not None and keepalive <= 0:
|
|
1002
1003
|
raise s_exc.BadArg(mesg=f'keepalive must be > 0; got {keepalive}')
|
|
1003
|
-
|
|
1004
|
+
|
|
1005
|
+
if (synt := s_task.current()) is None:
|
|
1006
|
+
# we only want to promote if we aren't already a syntask because we're probably a worker task that shouldn't
|
|
1007
|
+
# show up in the main task list
|
|
1008
|
+
synt = await self.core.boss.promote('storm', user=user, info=taskinfo, taskiden=taskiden)
|
|
1004
1009
|
|
|
1005
1010
|
show = opts.get('show', set())
|
|
1006
1011
|
|