synapse 2.152.0__py311-none-any.whl → 2.154.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 +19 -16
- synapse/cortex.py +203 -15
- synapse/exc.py +0 -2
- synapse/lib/ast.py +42 -23
- synapse/lib/autodoc.py +2 -2
- synapse/lib/cache.py +16 -1
- synapse/lib/cell.py +5 -5
- synapse/lib/httpapi.py +198 -2
- synapse/lib/layer.py +5 -2
- synapse/lib/modelrev.py +36 -3
- synapse/lib/node.py +2 -5
- synapse/lib/parser.py +1 -1
- synapse/lib/schemas.py +51 -0
- synapse/lib/snap.py +10 -0
- synapse/lib/storm.lark +24 -4
- synapse/lib/storm.py +98 -19
- synapse/lib/storm_format.py +1 -1
- synapse/lib/stormhttp.py +11 -4
- synapse/lib/stormlib/auth.py +16 -2
- synapse/lib/stormlib/backup.py +1 -0
- synapse/lib/stormlib/basex.py +2 -0
- synapse/lib/stormlib/cell.py +7 -0
- synapse/lib/stormlib/compression.py +3 -0
- synapse/lib/stormlib/cortex.py +1168 -0
- synapse/lib/stormlib/ethereum.py +1 -0
- synapse/lib/stormlib/graph.py +2 -0
- synapse/lib/stormlib/hashes.py +5 -0
- synapse/lib/stormlib/hex.py +6 -0
- synapse/lib/stormlib/infosec.py +6 -1
- synapse/lib/stormlib/ipv6.py +1 -0
- synapse/lib/stormlib/iters.py +58 -1
- synapse/lib/stormlib/json.py +5 -0
- synapse/lib/stormlib/mime.py +1 -0
- synapse/lib/stormlib/model.py +19 -3
- synapse/lib/stormlib/modelext.py +1 -0
- synapse/lib/stormlib/notifications.py +2 -0
- synapse/lib/stormlib/pack.py +2 -0
- synapse/lib/stormlib/random.py +1 -0
- synapse/lib/stormlib/smtp.py +0 -7
- synapse/lib/stormlib/stats.py +223 -0
- synapse/lib/stormlib/stix.py +8 -0
- synapse/lib/stormlib/storm.py +1 -0
- synapse/lib/stormlib/version.py +3 -0
- synapse/lib/stormlib/xml.py +3 -0
- synapse/lib/stormlib/yaml.py +2 -0
- synapse/lib/stormtypes.py +250 -170
- synapse/lib/trigger.py +180 -4
- synapse/lib/types.py +1 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +55 -6
- synapse/models/inet.py +21 -6
- synapse/models/orgs.py +48 -2
- synapse/models/risk.py +126 -2
- synapse/models/syn.py +6 -0
- synapse/tests/files/stormpkg/badapidef.yaml +13 -0
- synapse/tests/files/stormpkg/storm/modules/apimod +10 -0
- synapse/tests/files/stormpkg/testpkg.yaml +23 -0
- synapse/tests/test_axon.py +7 -2
- synapse/tests/test_cortex.py +231 -35
- synapse/tests/test_lib_ast.py +138 -43
- synapse/tests/test_lib_autodoc.py +1 -1
- synapse/tests/test_lib_modelrev.py +9 -0
- synapse/tests/test_lib_node.py +55 -0
- synapse/tests/test_lib_storm.py +14 -1
- synapse/tests/test_lib_stormhttp.py +65 -6
- synapse/tests/test_lib_stormlib_auth.py +12 -3
- synapse/tests/test_lib_stormlib_cortex.py +1327 -0
- synapse/tests/test_lib_stormlib_iters.py +116 -0
- synapse/tests/test_lib_stormlib_stats.py +187 -0
- synapse/tests/test_lib_stormlib_storm.py +8 -0
- synapse/tests/test_lib_stormsvc.py +24 -1
- synapse/tests/test_lib_stormtypes.py +124 -69
- synapse/tests/test_lib_trigger.py +315 -0
- synapse/tests/test_lib_view.py +1 -2
- synapse/tests/test_model_base.py +26 -0
- synapse/tests/test_model_inet.py +22 -0
- synapse/tests/test_model_orgs.py +28 -0
- synapse/tests/test_model_risk.py +73 -0
- synapse/tests/test_tools_autodoc.py +25 -0
- synapse/tests/test_tools_genpkg.py +9 -3
- synapse/tests/utils.py +39 -0
- synapse/tools/autodoc.py +42 -2
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/METADATA +2 -2
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/RECORD +87 -79
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/WHEEL +1 -1
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/LICENSE +0 -0
- {synapse-2.152.0.dist-info → synapse-2.154.0.dist-info}/top_level.txt +0 -0
synapse/lib/stormtypes.py
CHANGED
|
@@ -205,8 +205,13 @@ class StormTypesRegistry:
|
|
|
205
205
|
for parameter, argdef in zip(callsig.parameters.values(), args):
|
|
206
206
|
pdef = parameter.default # defaults to inspect._empty for undefined default values.
|
|
207
207
|
adef = argdef.get('default', inspect._empty)
|
|
208
|
-
|
|
209
|
-
|
|
208
|
+
# Allow $lib.undef as a defined default to represent the undef constant.
|
|
209
|
+
if pdef is undef:
|
|
210
|
+
assert adef == '$lib.undef', \
|
|
211
|
+
f'Expected $lib.undef for default value {obj} {funcname}, defvals {pdef} != {adef} for {parameter}'
|
|
212
|
+
else:
|
|
213
|
+
assert pdef == adef, \
|
|
214
|
+
f'Default value mismatch for {obj} {funcname}, defvals {pdef} != {adef} for {parameter}'
|
|
210
215
|
|
|
211
216
|
def _validateStor(self, obj, info, name):
|
|
212
217
|
rtype = info.get('type')
|
|
@@ -228,9 +233,9 @@ class StormTypesRegistry:
|
|
|
228
233
|
args = rtype.get('args')
|
|
229
234
|
assert args is None, f'ctors have no defined args funcname=[{funcname}] for {obj} {info.get("name")}'
|
|
230
235
|
callsig = getCallSig(locl)
|
|
231
|
-
# Assert the callsig for a
|
|
236
|
+
# Assert the callsig for a ctor has one argument
|
|
232
237
|
callsig_args = [str(v).split('=')[0] for v in callsig.parameters.values()]
|
|
233
|
-
assert len(callsig_args) == 1, f'
|
|
238
|
+
assert len(callsig_args) == 1, f'ctor funcs must only have one argument for {obj} {info.get("name")}'
|
|
234
239
|
|
|
235
240
|
def _validateGtor(self, obj, info, name):
|
|
236
241
|
rtype = info.get('type')
|
|
@@ -625,6 +630,7 @@ class LibPkg(Lib):
|
|
|
625
630
|
verify = await tobool(verify)
|
|
626
631
|
await self.runt.snap.core.addStormPkg(pkgdef, verify=verify)
|
|
627
632
|
|
|
633
|
+
@stormfunc(readonly=True)
|
|
628
634
|
async def _libPkgGet(self, name):
|
|
629
635
|
name = await tostr(name)
|
|
630
636
|
pkgdef = await self.runt.snap.core.getStormPkg(name)
|
|
@@ -633,6 +639,7 @@ class LibPkg(Lib):
|
|
|
633
639
|
|
|
634
640
|
return Dict(pkgdef)
|
|
635
641
|
|
|
642
|
+
@stormfunc(readonly=True)
|
|
636
643
|
async def _libPkgHas(self, name):
|
|
637
644
|
name = await tostr(name)
|
|
638
645
|
pkgdef = await self.runt.snap.core.getStormPkg(name)
|
|
@@ -644,10 +651,12 @@ class LibPkg(Lib):
|
|
|
644
651
|
self.runt.confirm(('pkg', 'del'), None)
|
|
645
652
|
await self.runt.snap.core.delStormPkg(name)
|
|
646
653
|
|
|
654
|
+
@stormfunc(readonly=True)
|
|
647
655
|
async def _libPkgList(self):
|
|
648
656
|
pkgs = await self.runt.snap.core.getStormPkgs()
|
|
649
657
|
return list(sorted(pkgs, key=lambda x: x.get('name')))
|
|
650
658
|
|
|
659
|
+
@stormfunc(readonly=True)
|
|
651
660
|
async def _libPkgDeps(self, pkgdef):
|
|
652
661
|
pkgdef = await toprim(pkgdef)
|
|
653
662
|
return await self.runt.snap.core.verifyStormPkgDeps(pkgdef)
|
|
@@ -743,12 +752,15 @@ class LibDmon(Lib):
|
|
|
743
752
|
|
|
744
753
|
await self.runt.snap.core.delStormDmon(iden)
|
|
745
754
|
|
|
755
|
+
@stormfunc(readonly=True)
|
|
746
756
|
async def _libDmonGet(self, iden):
|
|
747
757
|
return await self.runt.snap.core.getStormDmon(iden)
|
|
748
758
|
|
|
759
|
+
@stormfunc(readonly=True)
|
|
749
760
|
async def _libDmonList(self):
|
|
750
761
|
return await self.runt.snap.core.getStormDmons()
|
|
751
762
|
|
|
763
|
+
@stormfunc(readonly=True)
|
|
752
764
|
async def _libDmonLog(self, iden):
|
|
753
765
|
self.runt.confirm(('dmon', 'log'))
|
|
754
766
|
return await self.runt.snap.core.getStormDmonLog(iden)
|
|
@@ -930,12 +942,14 @@ class LibService(Lib):
|
|
|
930
942
|
await self._checkSvcGetPerm(ssvc)
|
|
931
943
|
return Service(self.runt, ssvc)
|
|
932
944
|
|
|
945
|
+
@stormfunc(readonly=True)
|
|
933
946
|
async def _libSvcHas(self, name):
|
|
934
947
|
ssvc = self.runt.snap.core.getStormSvc(name)
|
|
935
948
|
if ssvc is None:
|
|
936
949
|
return False
|
|
937
950
|
return True
|
|
938
951
|
|
|
952
|
+
@stormfunc(readonly=True)
|
|
939
953
|
async def _libSvcList(self):
|
|
940
954
|
self.runt.confirm(('service', 'list'))
|
|
941
955
|
retn = []
|
|
@@ -949,6 +963,7 @@ class LibService(Lib):
|
|
|
949
963
|
|
|
950
964
|
return retn
|
|
951
965
|
|
|
966
|
+
@stormfunc(readonly=True)
|
|
952
967
|
async def _libSvcWait(self, name, timeout=None):
|
|
953
968
|
name = await tostr(name)
|
|
954
969
|
timeout = await toint(timeout, noneok=True)
|
|
@@ -1006,6 +1021,7 @@ class LibTags(Lib):
|
|
|
1006
1021
|
'prefix': self.prefix,
|
|
1007
1022
|
}
|
|
1008
1023
|
|
|
1024
|
+
@stormfunc(readonly=True)
|
|
1009
1025
|
async def prefix(self, names, prefix, ispart=False):
|
|
1010
1026
|
|
|
1011
1027
|
prefix = await tostr(prefix)
|
|
@@ -1375,6 +1391,7 @@ class LibBase(Lib):
|
|
|
1375
1391
|
'trycast': self.trycast,
|
|
1376
1392
|
}
|
|
1377
1393
|
|
|
1394
|
+
@stormfunc(readonly=True)
|
|
1378
1395
|
async def _libBaseImport(self, name, debug=False, reqvers=None):
|
|
1379
1396
|
|
|
1380
1397
|
name = await tostr(name)
|
|
@@ -1512,12 +1529,15 @@ class LibBase(Lib):
|
|
|
1512
1529
|
for item in sorted(valu, reverse=reverse):
|
|
1513
1530
|
yield item
|
|
1514
1531
|
|
|
1532
|
+
@stormfunc(readonly=True)
|
|
1515
1533
|
async def _set(self, *vals):
|
|
1516
1534
|
return Set(vals)
|
|
1517
1535
|
|
|
1536
|
+
@stormfunc(readonly=True)
|
|
1518
1537
|
async def _list(self, *vals):
|
|
1519
1538
|
return List(list(vals))
|
|
1520
1539
|
|
|
1540
|
+
@stormfunc(readonly=True)
|
|
1521
1541
|
async def _text(self, *args):
|
|
1522
1542
|
valu = ''.join(args)
|
|
1523
1543
|
return Text(valu)
|
|
@@ -1707,6 +1727,7 @@ class LibPs(Lib):
|
|
|
1707
1727
|
todo = s_common.todo('kill', self.runt.user, idens[0])
|
|
1708
1728
|
return await self.dyncall('cell', todo)
|
|
1709
1729
|
|
|
1730
|
+
@stormfunc(readonly=True)
|
|
1710
1731
|
async def _list(self):
|
|
1711
1732
|
todo = s_common.todo('ps', self.runt.user)
|
|
1712
1733
|
return await self.dyncall('cell', todo)
|
|
@@ -1766,15 +1787,18 @@ class LibStr(Lib):
|
|
|
1766
1787
|
'format': self.format,
|
|
1767
1788
|
}
|
|
1768
1789
|
|
|
1790
|
+
@stormfunc(readonly=True)
|
|
1769
1791
|
async def concat(self, *args):
|
|
1770
1792
|
strs = [await tostr(a) for a in args]
|
|
1771
1793
|
return ''.join(strs)
|
|
1772
1794
|
|
|
1795
|
+
@stormfunc(readonly=True)
|
|
1773
1796
|
async def format(self, text, **kwargs):
|
|
1774
1797
|
text = await kwarg_format(text, **kwargs)
|
|
1775
1798
|
|
|
1776
1799
|
return text
|
|
1777
1800
|
|
|
1801
|
+
@stormfunc(readonly=True)
|
|
1778
1802
|
async def join(self, sepr, items):
|
|
1779
1803
|
strs = [await tostr(item) async for item in toiter(items)]
|
|
1780
1804
|
return sepr.join(strs)
|
|
@@ -1913,16 +1937,18 @@ class LibAxon(Lib):
|
|
|
1913
1937
|
{'name': 'readlines', 'desc': '''
|
|
1914
1938
|
Yields lines of text from a plain-text file stored in the Axon.
|
|
1915
1939
|
|
|
1916
|
-
|
|
1917
|
-
Get the lines for a given file::
|
|
1940
|
+
Examples:
|
|
1918
1941
|
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1942
|
+
// Get the lines for a given file.
|
|
1943
|
+
for $line in $lib.axon.readlines($sha256) {
|
|
1944
|
+
$dostuff($line)
|
|
1945
|
+
}
|
|
1922
1946
|
''',
|
|
1923
1947
|
'type': {'type': 'function', '_funcname': 'readlines',
|
|
1924
1948
|
'args': (
|
|
1925
1949
|
{'name': 'sha256', 'type': 'str', 'desc': 'The SHA256 hash of the file.'},
|
|
1950
|
+
{'name': 'errors', 'type': 'str', 'default': 'ignore',
|
|
1951
|
+
'desc': 'Specify how encoding errors should handled.'},
|
|
1926
1952
|
),
|
|
1927
1953
|
'returns': {'name': 'yields', 'type': 'str',
|
|
1928
1954
|
'desc': 'A line of text from the file.'}}},
|
|
@@ -1940,6 +1966,8 @@ class LibAxon(Lib):
|
|
|
1940
1966
|
'type': {'type': 'function', '_funcname': 'jsonlines',
|
|
1941
1967
|
'args': (
|
|
1942
1968
|
{'name': 'sha256', 'type': 'str', 'desc': 'The SHA256 hash of the file.'},
|
|
1969
|
+
{'name': 'errors', 'type': 'str', 'default': 'ignore',
|
|
1970
|
+
'desc': 'Specify how encoding errors should handled.'},
|
|
1943
1971
|
),
|
|
1944
1972
|
'returns': {'name': 'yields', 'type': 'any',
|
|
1945
1973
|
'desc': 'A JSON object parsed from a line of text.'}}},
|
|
@@ -1967,6 +1995,8 @@ class LibAxon(Lib):
|
|
|
1967
1995
|
{'name': 'sha256', 'type': 'str', 'desc': 'The SHA256 hash of the file.'},
|
|
1968
1996
|
{'name': 'dialect', 'type': 'str', 'desc': 'The default CSV dialect to use.',
|
|
1969
1997
|
'default': 'excel'},
|
|
1998
|
+
{'name': 'errors', 'type': 'str', 'default': 'ignore',
|
|
1999
|
+
'desc': 'Specify how encoding errors should handled.'},
|
|
1970
2000
|
{'name': '**fmtparams', 'type': 'any', 'desc': 'Format arguments.'},
|
|
1971
2001
|
),
|
|
1972
2002
|
'returns': {'name': 'yields', 'type': 'list',
|
|
@@ -2018,16 +2048,18 @@ class LibAxon(Lib):
|
|
|
2018
2048
|
return {str(k): str(v) for k, v in item.items()}
|
|
2019
2049
|
return item
|
|
2020
2050
|
|
|
2021
|
-
|
|
2051
|
+
@stormfunc(readonly=True)
|
|
2052
|
+
async def readlines(self, sha256, errors='ignore'):
|
|
2022
2053
|
if not self.runt.allowed(('axon', 'get')):
|
|
2023
2054
|
self.runt.confirm(('storm', 'lib', 'axon', 'get'))
|
|
2024
2055
|
await self.runt.snap.core.getAxon()
|
|
2025
2056
|
|
|
2026
2057
|
sha256 = await tostr(sha256)
|
|
2027
|
-
async for line in self.runt.snap.core.axon.readlines(sha256):
|
|
2058
|
+
async for line in self.runt.snap.core.axon.readlines(sha256, errors=errors):
|
|
2028
2059
|
yield line
|
|
2029
2060
|
|
|
2030
|
-
|
|
2061
|
+
@stormfunc(readonly=True)
|
|
2062
|
+
async def jsonlines(self, sha256, errors='ignore'):
|
|
2031
2063
|
if not self.runt.allowed(('axon', 'get')):
|
|
2032
2064
|
self.runt.confirm(('storm', 'lib', 'axon', 'get'))
|
|
2033
2065
|
await self.runt.snap.core.getAxon()
|
|
@@ -2071,9 +2103,6 @@ class LibAxon(Lib):
|
|
|
2071
2103
|
if not self.runt.allowed(('axon', 'wget')):
|
|
2072
2104
|
self.runt.confirm(('storm', 'lib', 'axon', 'wget'))
|
|
2073
2105
|
|
|
2074
|
-
if proxy is not None and not self.runt.isAdmin():
|
|
2075
|
-
raise s_exc.AuthDeny(mesg=s_exc.proxy_admin_mesg, user=self.runt.user.iden, username=self.runt.user.name)
|
|
2076
|
-
|
|
2077
2106
|
url = await tostr(url)
|
|
2078
2107
|
method = await tostr(method)
|
|
2079
2108
|
|
|
@@ -2085,6 +2114,9 @@ class LibAxon(Lib):
|
|
|
2085
2114
|
timeout = await toprim(timeout)
|
|
2086
2115
|
proxy = await toprim(proxy)
|
|
2087
2116
|
|
|
2117
|
+
if proxy is not None:
|
|
2118
|
+
self.runt.confirm(('storm', 'lib', 'inet', 'http', 'proxy'))
|
|
2119
|
+
|
|
2088
2120
|
params = self.strify(params)
|
|
2089
2121
|
headers = self.strify(headers)
|
|
2090
2122
|
|
|
@@ -2106,9 +2138,6 @@ class LibAxon(Lib):
|
|
|
2106
2138
|
if not self.runt.allowed(('axon', 'wput')):
|
|
2107
2139
|
self.runt.confirm(('storm', 'lib', 'axon', 'wput'))
|
|
2108
2140
|
|
|
2109
|
-
if proxy is not None and not self.runt.isAdmin():
|
|
2110
|
-
raise s_exc.AuthDeny(mesg=s_exc.proxy_admin_mesg, user=self.runt.user.iden, username=self.runt.user.name)
|
|
2111
|
-
|
|
2112
2141
|
url = await tostr(url)
|
|
2113
2142
|
sha256 = await tostr(sha256)
|
|
2114
2143
|
method = await tostr(method)
|
|
@@ -2122,6 +2151,9 @@ class LibAxon(Lib):
|
|
|
2122
2151
|
params = self.strify(params)
|
|
2123
2152
|
headers = self.strify(headers)
|
|
2124
2153
|
|
|
2154
|
+
if proxy is not None:
|
|
2155
|
+
self.runt.confirm(('storm', 'lib', 'inet', 'http', 'proxy'))
|
|
2156
|
+
|
|
2125
2157
|
axon = self.runt.snap.core.axon
|
|
2126
2158
|
sha256byts = s_common.uhex(sha256)
|
|
2127
2159
|
|
|
@@ -2190,6 +2222,7 @@ class LibAxon(Lib):
|
|
|
2190
2222
|
|
|
2191
2223
|
return urlfile
|
|
2192
2224
|
|
|
2225
|
+
@stormfunc(readonly=True)
|
|
2193
2226
|
async def list(self, offs=0, wait=False, timeout=None):
|
|
2194
2227
|
offs = await toint(offs)
|
|
2195
2228
|
wait = await tobool(wait)
|
|
@@ -2204,7 +2237,8 @@ class LibAxon(Lib):
|
|
|
2204
2237
|
async for item in axon.hashes(offs, wait=wait, timeout=timeout):
|
|
2205
2238
|
yield (item[0], s_common.ehex(item[1][0]), item[1][1])
|
|
2206
2239
|
|
|
2207
|
-
|
|
2240
|
+
@stormfunc(readonly=True)
|
|
2241
|
+
async def csvrows(self, sha256, dialect='excel', errors='ignore', **fmtparams):
|
|
2208
2242
|
|
|
2209
2243
|
if not self.runt.allowed(('axon', 'get')):
|
|
2210
2244
|
self.runt.confirm(('storm', 'lib', 'axon', 'get'))
|
|
@@ -2214,10 +2248,12 @@ class LibAxon(Lib):
|
|
|
2214
2248
|
sha256 = await tostr(sha256)
|
|
2215
2249
|
dialect = await tostr(dialect)
|
|
2216
2250
|
fmtparams = await toprim(fmtparams)
|
|
2217
|
-
async for item in self.runt.snap.core.axon.csvrows(s_common.uhex(sha256), dialect,
|
|
2251
|
+
async for item in self.runt.snap.core.axon.csvrows(s_common.uhex(sha256), dialect,
|
|
2252
|
+
errors=errors, **fmtparams):
|
|
2218
2253
|
yield item
|
|
2219
2254
|
await asyncio.sleep(0)
|
|
2220
2255
|
|
|
2256
|
+
@stormfunc(readonly=True)
|
|
2221
2257
|
async def metrics(self):
|
|
2222
2258
|
if not self.runt.allowed(('axon', 'has')):
|
|
2223
2259
|
self.runt.confirm(('storm', 'lib', 'axon', 'has'))
|
|
@@ -2325,6 +2361,7 @@ class LibBytes(Lib):
|
|
|
2325
2361
|
size, sha256 = await upload.save()
|
|
2326
2362
|
return size, s_common.ehex(sha256)
|
|
2327
2363
|
|
|
2364
|
+
@stormfunc(readonly=True)
|
|
2328
2365
|
async def _libBytesHas(self, sha256):
|
|
2329
2366
|
sha256 = await tostr(sha256, noneok=True)
|
|
2330
2367
|
if sha256 is None:
|
|
@@ -2335,6 +2372,7 @@ class LibBytes(Lib):
|
|
|
2335
2372
|
ret = await self.dyncall('axon', todo)
|
|
2336
2373
|
return ret
|
|
2337
2374
|
|
|
2375
|
+
@stormfunc(readonly=True)
|
|
2338
2376
|
async def _libBytesSize(self, sha256):
|
|
2339
2377
|
sha256 = await tostr(sha256)
|
|
2340
2378
|
await self.runt.snap.core.getAxon()
|
|
@@ -2353,6 +2391,7 @@ class LibBytes(Lib):
|
|
|
2353
2391
|
|
|
2354
2392
|
return (size, s_common.ehex(sha2))
|
|
2355
2393
|
|
|
2394
|
+
@stormfunc(readonly=True)
|
|
2356
2395
|
async def _libBytesHashset(self, sha256):
|
|
2357
2396
|
sha256 = await tostr(sha256)
|
|
2358
2397
|
await self.runt.snap.core.getAxon()
|
|
@@ -2382,6 +2421,7 @@ class LibLift(Lib):
|
|
|
2382
2421
|
'byNodeData': self._byNodeData,
|
|
2383
2422
|
}
|
|
2384
2423
|
|
|
2424
|
+
@stormfunc(readonly=True)
|
|
2385
2425
|
async def _byNodeData(self, name):
|
|
2386
2426
|
async for node in self.runt.snap.nodesByDataName(name):
|
|
2387
2427
|
yield node
|
|
@@ -2598,6 +2638,7 @@ class LibTime(Lib):
|
|
|
2598
2638
|
'monthofyear': self.monthofyear,
|
|
2599
2639
|
}
|
|
2600
2640
|
|
|
2641
|
+
@stormfunc(readonly=True)
|
|
2601
2642
|
async def toUTC(self, tick, timezone):
|
|
2602
2643
|
|
|
2603
2644
|
tick = await toprim(tick)
|
|
@@ -2611,69 +2652,81 @@ class LibTime(Lib):
|
|
|
2611
2652
|
except s_exc.BadArg as e:
|
|
2612
2653
|
return (False, s_common.excinfo(e))
|
|
2613
2654
|
|
|
2655
|
+
@stormfunc(readonly=True)
|
|
2614
2656
|
def _now(self):
|
|
2615
2657
|
return s_common.now()
|
|
2616
2658
|
|
|
2659
|
+
@stormfunc(readonly=True)
|
|
2617
2660
|
async def day(self, tick):
|
|
2618
2661
|
tick = await toprim(tick)
|
|
2619
2662
|
timetype = self.runt.snap.core.model.type('time')
|
|
2620
2663
|
norm, info = timetype.norm(tick)
|
|
2621
2664
|
return s_time.day(norm)
|
|
2622
2665
|
|
|
2666
|
+
@stormfunc(readonly=True)
|
|
2623
2667
|
async def hour(self, tick):
|
|
2624
2668
|
tick = await toprim(tick)
|
|
2625
2669
|
timetype = self.runt.snap.core.model.type('time')
|
|
2626
2670
|
norm, info = timetype.norm(tick)
|
|
2627
2671
|
return s_time.hour(norm)
|
|
2628
2672
|
|
|
2673
|
+
@stormfunc(readonly=True)
|
|
2629
2674
|
async def year(self, tick):
|
|
2630
2675
|
tick = await toprim(tick)
|
|
2631
2676
|
timetype = self.runt.snap.core.model.type('time')
|
|
2632
2677
|
norm, info = timetype.norm(tick)
|
|
2633
2678
|
return s_time.year(norm)
|
|
2634
2679
|
|
|
2680
|
+
@stormfunc(readonly=True)
|
|
2635
2681
|
async def month(self, tick):
|
|
2636
2682
|
tick = await toprim(tick)
|
|
2637
2683
|
timetype = self.runt.snap.core.model.type('time')
|
|
2638
2684
|
norm, info = timetype.norm(tick)
|
|
2639
2685
|
return s_time.month(norm)
|
|
2640
2686
|
|
|
2687
|
+
@stormfunc(readonly=True)
|
|
2641
2688
|
async def minute(self, tick):
|
|
2642
2689
|
tick = await toprim(tick)
|
|
2643
2690
|
timetype = self.runt.snap.core.model.type('time')
|
|
2644
2691
|
norm, info = timetype.norm(tick)
|
|
2645
2692
|
return s_time.minute(norm)
|
|
2646
2693
|
|
|
2694
|
+
@stormfunc(readonly=True)
|
|
2647
2695
|
async def second(self, tick):
|
|
2648
2696
|
tick = await toprim(tick)
|
|
2649
2697
|
timetype = self.runt.snap.core.model.type('time')
|
|
2650
2698
|
norm, info = timetype.norm(tick)
|
|
2651
2699
|
return s_time.second(norm)
|
|
2652
2700
|
|
|
2701
|
+
@stormfunc(readonly=True)
|
|
2653
2702
|
async def dayofweek(self, tick):
|
|
2654
2703
|
tick = await toprim(tick)
|
|
2655
2704
|
timetype = self.runt.snap.core.model.type('time')
|
|
2656
2705
|
norm, info = timetype.norm(tick)
|
|
2657
2706
|
return s_time.dayofweek(norm)
|
|
2658
2707
|
|
|
2708
|
+
@stormfunc(readonly=True)
|
|
2659
2709
|
async def dayofyear(self, tick):
|
|
2660
2710
|
tick = await toprim(tick)
|
|
2661
2711
|
timetype = self.runt.snap.core.model.type('time')
|
|
2662
2712
|
norm, info = timetype.norm(tick)
|
|
2663
2713
|
return s_time.dayofyear(norm)
|
|
2664
2714
|
|
|
2715
|
+
@stormfunc(readonly=True)
|
|
2665
2716
|
async def dayofmonth(self, tick):
|
|
2666
2717
|
tick = await toprim(tick)
|
|
2667
2718
|
timetype = self.runt.snap.core.model.type('time')
|
|
2668
2719
|
norm, info = timetype.norm(tick)
|
|
2669
2720
|
return s_time.dayofmonth(norm)
|
|
2670
2721
|
|
|
2722
|
+
@stormfunc(readonly=True)
|
|
2671
2723
|
async def monthofyear(self, tick):
|
|
2672
2724
|
tick = await toprim(tick)
|
|
2673
2725
|
timetype = self.runt.snap.core.model.type('time')
|
|
2674
2726
|
norm, info = timetype.norm(tick)
|
|
2675
2727
|
return s_time.month(norm) - 1
|
|
2676
2728
|
|
|
2729
|
+
@stormfunc(readonly=True)
|
|
2677
2730
|
async def _format(self, valu, format):
|
|
2678
2731
|
timetype = self.runt.snap.core.model.type('time')
|
|
2679
2732
|
# Give a times string a shot at being normed prior to formatting.
|
|
@@ -2697,6 +2750,7 @@ class LibTime(Lib):
|
|
|
2697
2750
|
format=format) from None
|
|
2698
2751
|
return ret
|
|
2699
2752
|
|
|
2753
|
+
@stormfunc(readonly=True)
|
|
2700
2754
|
async def _parse(self, valu, format, errok=False):
|
|
2701
2755
|
valu = await tostr(valu)
|
|
2702
2756
|
errok = await tobool(errok)
|
|
@@ -2713,6 +2767,7 @@ class LibTime(Lib):
|
|
|
2713
2767
|
dt = dt.astimezone(datetime.timezone.utc).replace(tzinfo=None)
|
|
2714
2768
|
return int((dt - s_time.EPOCH).total_seconds() * 1000)
|
|
2715
2769
|
|
|
2770
|
+
@stormfunc(readonly=True)
|
|
2716
2771
|
async def _sleep(self, valu):
|
|
2717
2772
|
await self.runt.snap.waitfini(timeout=float(valu))
|
|
2718
2773
|
await self.runt.snap.clearCache()
|
|
@@ -2858,6 +2913,7 @@ class LibRegx(Lib):
|
|
|
2858
2913
|
regx = self.compiled[lkey] = regex.compile(pattern, flags=flags)
|
|
2859
2914
|
return regx
|
|
2860
2915
|
|
|
2916
|
+
@stormfunc(readonly=True)
|
|
2861
2917
|
async def replace(self, pattern, replace, text, flags=0):
|
|
2862
2918
|
text = await tostr(text)
|
|
2863
2919
|
flags = await toint(flags)
|
|
@@ -2866,6 +2922,7 @@ class LibRegx(Lib):
|
|
|
2866
2922
|
regx = await self._getRegx(pattern, flags)
|
|
2867
2923
|
return regx.sub(replace, text)
|
|
2868
2924
|
|
|
2925
|
+
@stormfunc(readonly=True)
|
|
2869
2926
|
async def matches(self, pattern, text, flags=0):
|
|
2870
2927
|
text = await tostr(text)
|
|
2871
2928
|
flags = await toint(flags)
|
|
@@ -2873,6 +2930,7 @@ class LibRegx(Lib):
|
|
|
2873
2930
|
regx = await self._getRegx(pattern, flags)
|
|
2874
2931
|
return regx.match(text) is not None
|
|
2875
2932
|
|
|
2933
|
+
@stormfunc(readonly=True)
|
|
2876
2934
|
async def search(self, pattern, text, flags=0):
|
|
2877
2935
|
text = await tostr(text)
|
|
2878
2936
|
flags = await toint(flags)
|
|
@@ -2885,6 +2943,7 @@ class LibRegx(Lib):
|
|
|
2885
2943
|
|
|
2886
2944
|
return m.groups()
|
|
2887
2945
|
|
|
2946
|
+
@stormfunc(readonly=True)
|
|
2888
2947
|
async def findall(self, pattern, text, flags=0):
|
|
2889
2948
|
text = await tostr(text)
|
|
2890
2949
|
flags = await toint(flags)
|
|
@@ -2914,6 +2973,7 @@ class LibCsv(Lib):
|
|
|
2914
2973
|
'emit': self._libCsvEmit,
|
|
2915
2974
|
}
|
|
2916
2975
|
|
|
2976
|
+
@stormfunc(readonly=True)
|
|
2917
2977
|
async def _libCsvEmit(self, *args, table=None):
|
|
2918
2978
|
row = [await toprim(a) for a in args]
|
|
2919
2979
|
await self.runt.snap.fire('csv:row', row=row, table=table)
|
|
@@ -3040,6 +3100,7 @@ class LibFeed(Lib):
|
|
|
3040
3100
|
return
|
|
3041
3101
|
await self.runt.snap.addFeedData(name, data)
|
|
3042
3102
|
|
|
3103
|
+
@stormfunc(readonly=True)
|
|
3043
3104
|
async def _libList(self):
|
|
3044
3105
|
todo = ('getFeedFuncs', (), {})
|
|
3045
3106
|
return await self.runt.dyncall('cortex', todo)
|
|
@@ -3094,6 +3155,7 @@ class LibPipe(Lib):
|
|
|
3094
3155
|
'gen': self._methPipeGen,
|
|
3095
3156
|
}
|
|
3096
3157
|
|
|
3158
|
+
@stormfunc(readonly=True)
|
|
3097
3159
|
async def _methPipeGen(self, filler, size=10000):
|
|
3098
3160
|
size = await toint(size)
|
|
3099
3161
|
text = await tostr(filler)
|
|
@@ -3196,10 +3258,12 @@ class Pipe(StormType):
|
|
|
3196
3258
|
'size': self._methPipeSize,
|
|
3197
3259
|
}
|
|
3198
3260
|
|
|
3261
|
+
@stormfunc(readonly=True)
|
|
3199
3262
|
async def _methPipePuts(self, items):
|
|
3200
3263
|
items = await toprim(items)
|
|
3201
3264
|
return await self.queue.puts(items)
|
|
3202
3265
|
|
|
3266
|
+
@stormfunc(readonly=True)
|
|
3203
3267
|
async def _methPipePut(self, item):
|
|
3204
3268
|
item = await toprim(item)
|
|
3205
3269
|
return await self.queue.put(item)
|
|
@@ -3211,9 +3275,11 @@ class Pipe(StormType):
|
|
|
3211
3275
|
'''
|
|
3212
3276
|
await self.queue.close()
|
|
3213
3277
|
|
|
3278
|
+
@stormfunc(readonly=True)
|
|
3214
3279
|
async def _methPipeSize(self):
|
|
3215
3280
|
return await self.queue.size()
|
|
3216
3281
|
|
|
3282
|
+
@stormfunc(readonly=True)
|
|
3217
3283
|
async def _methPipeSlice(self, size=1000):
|
|
3218
3284
|
|
|
3219
3285
|
size = await toint(size)
|
|
@@ -3227,6 +3293,7 @@ class Pipe(StormType):
|
|
|
3227
3293
|
|
|
3228
3294
|
return List(items)
|
|
3229
3295
|
|
|
3296
|
+
@stormfunc(readonly=True)
|
|
3230
3297
|
async def _methPipeSlices(self, size=1000):
|
|
3231
3298
|
size = await toint(size)
|
|
3232
3299
|
if size < 1 or size > 10000:
|
|
@@ -3295,6 +3362,7 @@ class LibQueue(Lib):
|
|
|
3295
3362
|
|
|
3296
3363
|
return Queue(self.runt, name, info)
|
|
3297
3364
|
|
|
3365
|
+
@stormfunc(readonly=True)
|
|
3298
3366
|
async def _methQueueGet(self, name):
|
|
3299
3367
|
todo = s_common.todo('getCoreQueue', name)
|
|
3300
3368
|
gatekeys = ((self.runt.user.iden, ('queue', 'get'), f'queue:{name}'),)
|
|
@@ -3313,6 +3381,7 @@ class LibQueue(Lib):
|
|
|
3313
3381
|
gatekeys = ((self.runt.user.iden, ('queue', 'del',), f'queue:{name}'), )
|
|
3314
3382
|
await self.dyncall('cortex', todo, gatekeys=gatekeys)
|
|
3315
3383
|
|
|
3384
|
+
@stormfunc(readonly=True)
|
|
3316
3385
|
async def _methQueueList(self):
|
|
3317
3386
|
retn = []
|
|
3318
3387
|
|
|
@@ -3432,6 +3501,7 @@ class Queue(StormType):
|
|
|
3432
3501
|
await self.runt.reqGateKeys(gatekeys)
|
|
3433
3502
|
await self.runt.snap.core.coreQueueCull(self.name, offs)
|
|
3434
3503
|
|
|
3504
|
+
@stormfunc(readonly=True)
|
|
3435
3505
|
async def _methQueueSize(self):
|
|
3436
3506
|
gatekeys = self._getGateKeys('get')
|
|
3437
3507
|
await self.runt.reqGateKeys(gatekeys)
|
|
@@ -3685,6 +3755,7 @@ class LibBase64(Lib):
|
|
|
3685
3755
|
'decode': self._decode
|
|
3686
3756
|
}
|
|
3687
3757
|
|
|
3758
|
+
@stormfunc(readonly=True)
|
|
3688
3759
|
async def _encode(self, valu, urlsafe=True):
|
|
3689
3760
|
try:
|
|
3690
3761
|
if urlsafe:
|
|
@@ -3694,6 +3765,7 @@ class LibBase64(Lib):
|
|
|
3694
3765
|
mesg = f'Error during base64 encoding - {str(e)}: {repr(valu)[:256]}'
|
|
3695
3766
|
raise s_exc.StormRuntimeError(mesg=mesg, urlsafe=urlsafe) from None
|
|
3696
3767
|
|
|
3768
|
+
@stormfunc(readonly=True)
|
|
3697
3769
|
async def _decode(self, valu, urlsafe=True):
|
|
3698
3770
|
try:
|
|
3699
3771
|
if urlsafe:
|
|
@@ -4196,7 +4268,7 @@ class Bytes(Prim):
|
|
|
4196
4268
|
|
|
4197
4269
|
$subbyts = $byts.slice(3)
|
|
4198
4270
|
''',
|
|
4199
|
-
'type': {'type': 'function', '_funcname': '
|
|
4271
|
+
'type': {'type': 'function', '_funcname': '_methSlice',
|
|
4200
4272
|
'args': (
|
|
4201
4273
|
{'name': 'start', 'type': 'int', 'desc': 'The starting byte index.'},
|
|
4202
4274
|
{'name': 'end', 'type': 'int', 'default': None,
|
|
@@ -4212,7 +4284,7 @@ class Bytes(Prim):
|
|
|
4212
4284
|
|
|
4213
4285
|
($x, $y, $z) = $byts.unpack("<HHH")
|
|
4214
4286
|
''',
|
|
4215
|
-
'type': {'type': 'function', '_funcname': '
|
|
4287
|
+
'type': {'type': 'function', '_funcname': '_methUnpack',
|
|
4216
4288
|
'args': (
|
|
4217
4289
|
{'name': 'fmt', 'type': 'str', 'desc': 'A python struck.pack format string.'},
|
|
4218
4290
|
{'name': 'offset', 'type': 'int', 'desc': 'An offset to begin unpacking from.', 'default': 0},
|
|
@@ -4234,8 +4306,8 @@ class Bytes(Prim):
|
|
|
4234
4306
|
'bzip': self._methBzip,
|
|
4235
4307
|
'gzip': self._methGzip,
|
|
4236
4308
|
'json': self._methJsonLoad,
|
|
4237
|
-
'slice': self.
|
|
4238
|
-
'unpack': self.
|
|
4309
|
+
'slice': self._methSlice,
|
|
4310
|
+
'unpack': self._methUnpack,
|
|
4239
4311
|
}
|
|
4240
4312
|
|
|
4241
4313
|
def __len__(self):
|
|
@@ -4256,7 +4328,8 @@ class Bytes(Prim):
|
|
|
4256
4328
|
item = await s_coro.ornot(self.value)
|
|
4257
4329
|
return s_msgpack.deepcopy(item, use_list=True)
|
|
4258
4330
|
|
|
4259
|
-
|
|
4331
|
+
@stormfunc(readonly=True)
|
|
4332
|
+
async def _methSlice(self, start, end=None):
|
|
4260
4333
|
start = await toint(start)
|
|
4261
4334
|
if end is None:
|
|
4262
4335
|
return self.valu[start:]
|
|
@@ -4264,7 +4337,8 @@ class Bytes(Prim):
|
|
|
4264
4337
|
end = await toint(end)
|
|
4265
4338
|
return self.valu[start:end]
|
|
4266
4339
|
|
|
4267
|
-
|
|
4340
|
+
@stormfunc(readonly=True)
|
|
4341
|
+
async def _methUnpack(self, fmt, offset=0):
|
|
4268
4342
|
fmt = await tostr(fmt)
|
|
4269
4343
|
offset = await toint(offset)
|
|
4270
4344
|
try:
|
|
@@ -4272,6 +4346,7 @@ class Bytes(Prim):
|
|
|
4272
4346
|
except struct.error as e:
|
|
4273
4347
|
raise s_exc.BadArg(mesg=f'unpack() error: {e}')
|
|
4274
4348
|
|
|
4349
|
+
@stormfunc(readonly=True)
|
|
4275
4350
|
async def _methDecode(self, encoding='utf8', errors='surrogatepass'):
|
|
4276
4351
|
encoding = await tostr(encoding)
|
|
4277
4352
|
errors = await tostr(errors)
|
|
@@ -4283,15 +4358,18 @@ class Bytes(Prim):
|
|
|
4283
4358
|
async def _methBunzip(self):
|
|
4284
4359
|
return bz2.decompress(self.valu)
|
|
4285
4360
|
|
|
4361
|
+
@stormfunc(readonly=True)
|
|
4286
4362
|
async def _methBzip(self):
|
|
4287
4363
|
return bz2.compress(self.valu)
|
|
4288
4364
|
|
|
4289
4365
|
async def _methGunzip(self):
|
|
4290
4366
|
return gzip.decompress(self.valu)
|
|
4291
4367
|
|
|
4368
|
+
@stormfunc(readonly=True)
|
|
4292
4369
|
async def _methGzip(self):
|
|
4293
4370
|
return gzip.compress(self.valu)
|
|
4294
4371
|
|
|
4372
|
+
@stormfunc(readonly=True)
|
|
4295
4373
|
async def _methJsonLoad(self, encoding=None, errors='surrogatepass'):
|
|
4296
4374
|
try:
|
|
4297
4375
|
valu = self.valu
|
|
@@ -4477,9 +4555,11 @@ class Set(Prim):
|
|
|
4477
4555
|
async def _methSetSize(self):
|
|
4478
4556
|
return len(self)
|
|
4479
4557
|
|
|
4558
|
+
@stormfunc(readonly=True)
|
|
4480
4559
|
async def _methSetHas(self, item):
|
|
4481
4560
|
return item in self.valu
|
|
4482
4561
|
|
|
4562
|
+
@stormfunc(readonly=True)
|
|
4483
4563
|
async def _methSetAdd(self, *items):
|
|
4484
4564
|
for i in items:
|
|
4485
4565
|
if ismutable(i):
|
|
@@ -4487,6 +4567,7 @@ class Set(Prim):
|
|
|
4487
4567
|
raise s_exc.StormRuntimeError(mesg=mesg)
|
|
4488
4568
|
self.valu.add(i)
|
|
4489
4569
|
|
|
4570
|
+
@stormfunc(readonly=True)
|
|
4490
4571
|
async def _methSetAdds(self, *items):
|
|
4491
4572
|
for item in items:
|
|
4492
4573
|
async for i in toiter(item):
|
|
@@ -4495,13 +4576,16 @@ class Set(Prim):
|
|
|
4495
4576
|
raise s_exc.StormRuntimeError(mesg=mesg)
|
|
4496
4577
|
self.valu.add(i)
|
|
4497
4578
|
|
|
4579
|
+
@stormfunc(readonly=True)
|
|
4498
4580
|
async def _methSetRem(self, *items):
|
|
4499
4581
|
[self.valu.discard(i) for i in items]
|
|
4500
4582
|
|
|
4583
|
+
@stormfunc(readonly=True)
|
|
4501
4584
|
async def _methSetRems(self, *items):
|
|
4502
4585
|
for item in items:
|
|
4503
4586
|
[self.valu.discard(i) async for i in toiter(item)]
|
|
4504
4587
|
|
|
4588
|
+
@stormfunc(readonly=True)
|
|
4505
4589
|
async def _methSetList(self):
|
|
4506
4590
|
return list(self.valu)
|
|
4507
4591
|
|
|
@@ -4516,7 +4600,7 @@ class List(Prim):
|
|
|
4516
4600
|
Implements the Storm API for a List instance.
|
|
4517
4601
|
'''
|
|
4518
4602
|
_storm_locals = (
|
|
4519
|
-
{'name': 'has', 'desc': 'Check
|
|
4603
|
+
{'name': 'has', 'desc': 'Check if a value is in the list.',
|
|
4520
4604
|
'type': {'type': 'function', '_funcname': '_methListHas',
|
|
4521
4605
|
'args': (
|
|
4522
4606
|
{'name': 'valu', 'type': 'any', 'desc': 'The value to check.', },
|
|
@@ -4566,7 +4650,7 @@ class List(Prim):
|
|
|
4566
4650
|
|
|
4567
4651
|
$y=$x.slice(3) // (b, a, r)
|
|
4568
4652
|
''',
|
|
4569
|
-
'type': {'type': 'function', '_funcname': '
|
|
4653
|
+
'type': {'type': 'function', '_funcname': '_methListSlice',
|
|
4570
4654
|
'args': (
|
|
4571
4655
|
{'name': 'start', 'type': 'int', 'desc': 'The starting index.'},
|
|
4572
4656
|
{'name': 'end', 'type': 'int', 'default': None,
|
|
@@ -4590,11 +4674,14 @@ class List(Prim):
|
|
|
4590
4674
|
|
|
4591
4675
|
// $list is now (f, o, o, b, a, r)
|
|
4592
4676
|
''',
|
|
4593
|
-
'type': {'type': 'function', '_funcname': '
|
|
4677
|
+
'type': {'type': 'function', '_funcname': '_methListExtend',
|
|
4594
4678
|
'args': (
|
|
4595
4679
|
{'name': 'valu', 'type': 'list', 'desc': 'A list or other iterable.'},
|
|
4596
4680
|
),
|
|
4597
4681
|
'returns': {'type': 'null'}}},
|
|
4682
|
+
{'name': 'unique', 'desc': 'Get a copy of the list containing unique items.',
|
|
4683
|
+
'type': {'type': 'function', '_funcname': '_methListUnique',
|
|
4684
|
+
'returns': {'type': 'list'}}},
|
|
4598
4685
|
)
|
|
4599
4686
|
_storm_typename = 'list'
|
|
4600
4687
|
_ismutable = True
|
|
@@ -4613,9 +4700,9 @@ class List(Prim):
|
|
|
4613
4700
|
'length': self._methListLength,
|
|
4614
4701
|
'append': self._methListAppend,
|
|
4615
4702
|
'reverse': self._methListReverse,
|
|
4616
|
-
|
|
4617
|
-
'
|
|
4618
|
-
'
|
|
4703
|
+
'slice': self._methListSlice,
|
|
4704
|
+
'extend': self._methListExtend,
|
|
4705
|
+
'unique': self._methListUnique,
|
|
4619
4706
|
}
|
|
4620
4707
|
|
|
4621
4708
|
@stormfunc(readonly=True)
|
|
@@ -4642,6 +4729,7 @@ class List(Prim):
|
|
|
4642
4729
|
def __len__(self):
|
|
4643
4730
|
return len(self.valu)
|
|
4644
4731
|
|
|
4732
|
+
@stormfunc(readonly=True)
|
|
4645
4733
|
async def _methListHas(self, valu):
|
|
4646
4734
|
if valu in self.valu:
|
|
4647
4735
|
return True
|
|
@@ -4652,6 +4740,7 @@ class List(Prim):
|
|
|
4652
4740
|
|
|
4653
4741
|
return prim in self.valu
|
|
4654
4742
|
|
|
4743
|
+
@stormfunc(readonly=True)
|
|
4655
4744
|
async def _methListPop(self):
|
|
4656
4745
|
try:
|
|
4657
4746
|
return self.valu.pop()
|
|
@@ -4659,11 +4748,13 @@ class List(Prim):
|
|
|
4659
4748
|
mesg = 'The list is empty. Nothing to pop.'
|
|
4660
4749
|
raise s_exc.StormRuntimeError(mesg=mesg)
|
|
4661
4750
|
|
|
4751
|
+
@stormfunc(readonly=True)
|
|
4662
4752
|
async def _methListAppend(self, valu):
|
|
4663
4753
|
'''
|
|
4664
4754
|
'''
|
|
4665
4755
|
self.valu.append(valu)
|
|
4666
4756
|
|
|
4757
|
+
@stormfunc(readonly=True)
|
|
4667
4758
|
async def _methListIndex(self, valu):
|
|
4668
4759
|
indx = await toint(valu)
|
|
4669
4760
|
try:
|
|
@@ -4672,9 +4763,11 @@ class List(Prim):
|
|
|
4672
4763
|
raise s_exc.StormRuntimeError(mesg=str(e), valurepr=await self.stormrepr(),
|
|
4673
4764
|
len=len(self.valu), indx=indx) from None
|
|
4674
4765
|
|
|
4766
|
+
@stormfunc(readonly=True)
|
|
4675
4767
|
async def _methListReverse(self):
|
|
4676
4768
|
self.valu.reverse()
|
|
4677
4769
|
|
|
4770
|
+
@stormfunc(readonly=True)
|
|
4678
4771
|
async def _methListLength(self):
|
|
4679
4772
|
s_common.deprecated('StormType List.length()')
|
|
4680
4773
|
runt = s_scope.get('runt')
|
|
@@ -4682,6 +4775,7 @@ class List(Prim):
|
|
|
4682
4775
|
await runt.snap.warnonce('StormType List.length() is deprecated. Use the size() method.')
|
|
4683
4776
|
return len(self)
|
|
4684
4777
|
|
|
4778
|
+
@stormfunc(readonly=True)
|
|
4685
4779
|
async def _methListSort(self, reverse=False):
|
|
4686
4780
|
reverse = await tobool(reverse, noneok=True)
|
|
4687
4781
|
try:
|
|
@@ -4690,10 +4784,11 @@ class List(Prim):
|
|
|
4690
4784
|
raise s_exc.StormRuntimeError(mesg=f'Error sorting list: {str(e)}',
|
|
4691
4785
|
valurepr=await self.stormrepr()) from None
|
|
4692
4786
|
|
|
4787
|
+
@stormfunc(readonly=True)
|
|
4693
4788
|
async def _methListSize(self):
|
|
4694
4789
|
return len(self)
|
|
4695
4790
|
|
|
4696
|
-
async def
|
|
4791
|
+
async def _methListSlice(self, start, end=None):
|
|
4697
4792
|
start = await toint(start)
|
|
4698
4793
|
|
|
4699
4794
|
if end is None:
|
|
@@ -4702,7 +4797,8 @@ class List(Prim):
|
|
|
4702
4797
|
end = await toint(end)
|
|
4703
4798
|
return self.valu[start:end]
|
|
4704
4799
|
|
|
4705
|
-
|
|
4800
|
+
@stormfunc(readonly=True)
|
|
4801
|
+
async def _methListExtend(self, valu):
|
|
4706
4802
|
async for item in toiter(valu):
|
|
4707
4803
|
self.valu.append(item)
|
|
4708
4804
|
|
|
@@ -4713,6 +4809,22 @@ class List(Prim):
|
|
|
4713
4809
|
for item in self.valu:
|
|
4714
4810
|
yield item
|
|
4715
4811
|
|
|
4812
|
+
@stormfunc(readonly=True)
|
|
4813
|
+
async def _methListUnique(self):
|
|
4814
|
+
ret = []
|
|
4815
|
+
checkret = []
|
|
4816
|
+
|
|
4817
|
+
for val in self.valu:
|
|
4818
|
+
try:
|
|
4819
|
+
_cval = await toprim(val)
|
|
4820
|
+
except s_exc.NoSuchType:
|
|
4821
|
+
_cval = val
|
|
4822
|
+
if _cval in checkret:
|
|
4823
|
+
continue
|
|
4824
|
+
checkret.append(_cval)
|
|
4825
|
+
ret.append(val)
|
|
4826
|
+
return ret
|
|
4827
|
+
|
|
4716
4828
|
async def stormrepr(self):
|
|
4717
4829
|
reprs = [await torepr(k) for k in self.valu]
|
|
4718
4830
|
rval = ', '.join(reprs)
|
|
@@ -4801,10 +4913,12 @@ class Number(Prim):
|
|
|
4801
4913
|
'scaleb': self._methScaleb,
|
|
4802
4914
|
}
|
|
4803
4915
|
|
|
4916
|
+
@stormfunc(readonly=True)
|
|
4804
4917
|
async def _methScaleb(self, other):
|
|
4805
4918
|
newv = s_common.hugescaleb(self.value(), await toint(other))
|
|
4806
4919
|
return Number(newv)
|
|
4807
4920
|
|
|
4921
|
+
@stormfunc(readonly=True)
|
|
4808
4922
|
async def _methToInt(self, rounding=None):
|
|
4809
4923
|
if rounding is None:
|
|
4810
4924
|
return int(self.valu)
|
|
@@ -4815,9 +4929,11 @@ class Number(Prim):
|
|
|
4815
4929
|
raise s_exc.StormRuntimeError(mesg=f'Error rounding number: {str(e)}',
|
|
4816
4930
|
valurepr=await self.stormrepr()) from None
|
|
4817
4931
|
|
|
4932
|
+
@stormfunc(readonly=True)
|
|
4818
4933
|
async def _methToStr(self):
|
|
4819
4934
|
return str(self.valu)
|
|
4820
4935
|
|
|
4936
|
+
@stormfunc(readonly=True)
|
|
4821
4937
|
async def _methToFloat(self):
|
|
4822
4938
|
return float(self.valu)
|
|
4823
4939
|
|
|
@@ -4991,9 +5107,11 @@ class LibUser(Lib):
|
|
|
4991
5107
|
'profile': StormHiveDict(self.runt, self.runt.user.profile),
|
|
4992
5108
|
})
|
|
4993
5109
|
|
|
5110
|
+
@stormfunc(readonly=True)
|
|
4994
5111
|
async def _libUserName(self):
|
|
4995
5112
|
return self.runt.user.name
|
|
4996
5113
|
|
|
5114
|
+
@stormfunc(readonly=True)
|
|
4997
5115
|
async def _libUserAllowed(self, permname, gateiden=None, default=False):
|
|
4998
5116
|
permname = await toprim(permname)
|
|
4999
5117
|
gateiden = await tostr(gateiden, noneok=True)
|
|
@@ -5073,6 +5191,7 @@ class LibGlobals(Lib):
|
|
|
5073
5191
|
mesg = 'The name of a persistent variable must be a string.'
|
|
5074
5192
|
raise s_exc.StormRuntimeError(mesg=mesg, name=name)
|
|
5075
5193
|
|
|
5194
|
+
@stormfunc(readonly=True)
|
|
5076
5195
|
async def _methGet(self, name, default=None):
|
|
5077
5196
|
self._reqStr(name)
|
|
5078
5197
|
|
|
@@ -5096,6 +5215,7 @@ class LibGlobals(Lib):
|
|
|
5096
5215
|
todo = s_common.todo('setStormVar', name, valu)
|
|
5097
5216
|
return await self.runt.dyncall('cortex', todo, gatekeys=gatekeys)
|
|
5098
5217
|
|
|
5218
|
+
@stormfunc(readonly=True)
|
|
5099
5219
|
async def _methList(self):
|
|
5100
5220
|
ret = []
|
|
5101
5221
|
|
|
@@ -5157,6 +5277,7 @@ class StormHiveDict(Prim):
|
|
|
5157
5277
|
'list': self._list,
|
|
5158
5278
|
}
|
|
5159
5279
|
|
|
5280
|
+
@stormfunc(readonly=True)
|
|
5160
5281
|
async def _get(self, name, default=None):
|
|
5161
5282
|
return self.info.get(name, default)
|
|
5162
5283
|
|
|
@@ -5172,6 +5293,7 @@ class StormHiveDict(Prim):
|
|
|
5172
5293
|
|
|
5173
5294
|
return await self.info.set(name, valu)
|
|
5174
5295
|
|
|
5296
|
+
@stormfunc(readonly=True)
|
|
5175
5297
|
def _list(self):
|
|
5176
5298
|
return list(self.info.items())
|
|
5177
5299
|
|
|
@@ -5231,18 +5353,23 @@ class LibVars(Lib):
|
|
|
5231
5353
|
'type': self._libVarsType,
|
|
5232
5354
|
}
|
|
5233
5355
|
|
|
5356
|
+
@stormfunc(readonly=True)
|
|
5234
5357
|
async def _libVarsGet(self, name, defv=None):
|
|
5235
5358
|
return self.runt.getVar(name, defv=defv)
|
|
5236
5359
|
|
|
5360
|
+
@stormfunc(readonly=True)
|
|
5237
5361
|
async def _libVarsSet(self, name, valu):
|
|
5238
5362
|
await self.runt.setVar(name, valu)
|
|
5239
5363
|
|
|
5364
|
+
@stormfunc(readonly=True)
|
|
5240
5365
|
async def _libVarsDel(self, name):
|
|
5241
5366
|
await self.runt.popVar(name)
|
|
5242
5367
|
|
|
5368
|
+
@stormfunc(readonly=True)
|
|
5243
5369
|
async def _libVarsList(self):
|
|
5244
5370
|
return list(self.runt.vars.items())
|
|
5245
5371
|
|
|
5372
|
+
@stormfunc(readonly=True)
|
|
5246
5373
|
async def _libVarsType(self, valu):
|
|
5247
5374
|
return await totype(valu)
|
|
5248
5375
|
|
|
@@ -5309,6 +5436,7 @@ class Query(Prim):
|
|
|
5309
5436
|
async for node, path in self._getRuntGenr():
|
|
5310
5437
|
yield Node(node)
|
|
5311
5438
|
|
|
5439
|
+
@stormfunc(readonly=True)
|
|
5312
5440
|
async def _methQueryExec(self):
|
|
5313
5441
|
logger.info(f'Executing storm query via exec() {{{self.text}}} as [{self.runt.user.name}]')
|
|
5314
5442
|
try:
|
|
@@ -5319,6 +5447,7 @@ class Query(Prim):
|
|
|
5319
5447
|
except asyncio.CancelledError: # pragma: no cover
|
|
5320
5448
|
raise
|
|
5321
5449
|
|
|
5450
|
+
@stormfunc(readonly=True)
|
|
5322
5451
|
async def _methQuerySize(self, limit=1000):
|
|
5323
5452
|
limit = await toint(limit)
|
|
5324
5453
|
|
|
@@ -5667,11 +5796,11 @@ class Node(Prim):
|
|
|
5667
5796
|
'type': {'type': 'function', '_funcname': '_methNodeValue',
|
|
5668
5797
|
'returns': {'type': 'prim', 'desc': 'The primary property.', }}},
|
|
5669
5798
|
{'name': 'getByLayer', 'desc': 'Return a dict you can use to lookup which props/tags came from which layers.',
|
|
5670
|
-
'type': {'type': 'function', '_funcname': '
|
|
5799
|
+
'type': {'type': 'function', '_funcname': '_methGetByLayer',
|
|
5671
5800
|
'returns': {'type': 'dict', 'desc': 'property / tag lookup dictionary.', }}},
|
|
5672
5801
|
{'name': 'getStorNodes',
|
|
5673
5802
|
'desc': 'Return a list of "storage nodes" which were fused from the layers to make this node.',
|
|
5674
|
-
'type': {'type': 'function', '_funcname': '
|
|
5803
|
+
'type': {'type': 'function', '_funcname': '_methGetStorNodes',
|
|
5675
5804
|
'returns': {'type': 'list', 'desc': 'List of storage node objects.', }}},
|
|
5676
5805
|
)
|
|
5677
5806
|
_storm_typename = 'node'
|
|
@@ -5703,14 +5832,16 @@ class Node(Prim):
|
|
|
5703
5832
|
'globtags': self._methNodeGlobTags,
|
|
5704
5833
|
'difftags': self._methNodeDiffTags,
|
|
5705
5834
|
'isform': self._methNodeIsForm,
|
|
5706
|
-
'getByLayer': self.
|
|
5707
|
-
'getStorNodes': self.
|
|
5835
|
+
'getByLayer': self._methGetByLayer,
|
|
5836
|
+
'getStorNodes': self._methGetStorNodes,
|
|
5708
5837
|
}
|
|
5709
5838
|
|
|
5710
|
-
|
|
5839
|
+
@stormfunc(readonly=True)
|
|
5840
|
+
async def _methGetStorNodes(self):
|
|
5711
5841
|
return await self.valu.getStorNodes()
|
|
5712
5842
|
|
|
5713
|
-
|
|
5843
|
+
@stormfunc(readonly=True)
|
|
5844
|
+
def _methGetByLayer(self):
|
|
5714
5845
|
return self.valu.getByLayer()
|
|
5715
5846
|
|
|
5716
5847
|
def _ctorNodeData(self, path=None):
|
|
@@ -5955,9 +6086,11 @@ class Path(Prim):
|
|
|
5955
6086
|
'listvars': self._methPathListVars,
|
|
5956
6087
|
}
|
|
5957
6088
|
|
|
6089
|
+
@stormfunc(readonly=True)
|
|
5958
6090
|
async def _methPathIdens(self):
|
|
5959
6091
|
return [n.iden() for n in self.valu.nodes]
|
|
5960
6092
|
|
|
6093
|
+
@stormfunc(readonly=True)
|
|
5961
6094
|
async def _methPathListVars(self):
|
|
5962
6095
|
return list(self.path.vars.items())
|
|
5963
6096
|
|
|
@@ -5994,117 +6127,15 @@ class Text(Prim):
|
|
|
5994
6127
|
def __len__(self):
|
|
5995
6128
|
return len(self.valu)
|
|
5996
6129
|
|
|
6130
|
+
@stormfunc(readonly=True)
|
|
5997
6131
|
async def _methTextAdd(self, text, **kwargs):
|
|
5998
6132
|
text = await kwarg_format(text, **kwargs)
|
|
5999
6133
|
self.valu += text
|
|
6000
6134
|
|
|
6135
|
+
@stormfunc(readonly=True)
|
|
6001
6136
|
async def _methTextStr(self):
|
|
6002
6137
|
return self.valu
|
|
6003
6138
|
|
|
6004
|
-
@registry.registerLib
|
|
6005
|
-
class LibStats(Lib):
|
|
6006
|
-
'''
|
|
6007
|
-
A Storm Library for statistics related functionality.
|
|
6008
|
-
'''
|
|
6009
|
-
_storm_locals = (
|
|
6010
|
-
{'name': 'tally', 'desc': 'Get a Tally object.',
|
|
6011
|
-
'type': {'type': 'function', '_funcname': 'tally',
|
|
6012
|
-
'returns': {'type': 'stat:tally', 'desc': 'A new tally object.', }}},
|
|
6013
|
-
)
|
|
6014
|
-
_storm_lib_path = ('stats',)
|
|
6015
|
-
|
|
6016
|
-
def getObjLocals(self):
|
|
6017
|
-
return {
|
|
6018
|
-
'tally': self.tally,
|
|
6019
|
-
}
|
|
6020
|
-
|
|
6021
|
-
async def tally(self):
|
|
6022
|
-
return StatTally(path=self.path)
|
|
6023
|
-
|
|
6024
|
-
@registry.registerType
|
|
6025
|
-
class StatTally(Prim):
|
|
6026
|
-
'''
|
|
6027
|
-
A tally object.
|
|
6028
|
-
|
|
6029
|
-
An example of using it::
|
|
6030
|
-
|
|
6031
|
-
$tally = $lib.stats.tally()
|
|
6032
|
-
|
|
6033
|
-
$tally.inc(foo)
|
|
6034
|
-
|
|
6035
|
-
for $name, $total in $tally {
|
|
6036
|
-
$doStuff($name, $total)
|
|
6037
|
-
}
|
|
6038
|
-
|
|
6039
|
-
'''
|
|
6040
|
-
_storm_typename = 'stat:tally'
|
|
6041
|
-
_storm_locals = (
|
|
6042
|
-
{'name': 'inc', 'desc': 'Increment a given counter.',
|
|
6043
|
-
'type': {'type': 'function', '_funcname': 'inc',
|
|
6044
|
-
'args': (
|
|
6045
|
-
{'name': 'name', 'desc': 'The name of the counter to increment.', 'type': 'str', },
|
|
6046
|
-
{'name': 'valu', 'desc': 'The value to increment the counter by.', 'type': 'int', 'default': 1, },
|
|
6047
|
-
),
|
|
6048
|
-
'returns': {'type': 'null', }}},
|
|
6049
|
-
{'name': 'get', 'desc': 'Get the value of a given counter.',
|
|
6050
|
-
'type': {'type': 'function', '_funcname': 'get',
|
|
6051
|
-
'args': (
|
|
6052
|
-
{'name': 'name', 'type': 'str', 'desc': 'The name of the counter to get.', },
|
|
6053
|
-
),
|
|
6054
|
-
'returns': {'type': 'int',
|
|
6055
|
-
'desc': 'The value of the counter, or 0 if the counter does not exist.', }}},
|
|
6056
|
-
{'name': 'sorted', 'desc': 'Get a list of (counter, value) tuples in sorted order.',
|
|
6057
|
-
'type': {'type': 'function', '_funcname': 'sorted',
|
|
6058
|
-
'args': (
|
|
6059
|
-
{'name': 'byname', 'desc': 'Sort by counter name instead of value.',
|
|
6060
|
-
'type': 'bool', 'default': False},
|
|
6061
|
-
{'name': 'reverse', 'desc': 'Sort in descending order instead of ascending order.',
|
|
6062
|
-
'type': 'bool', 'default': False},
|
|
6063
|
-
),
|
|
6064
|
-
'returns': {'type': 'list',
|
|
6065
|
-
'desc': 'List of (counter, value) tuples in sorted order.'}}},
|
|
6066
|
-
)
|
|
6067
|
-
_ismutable = True
|
|
6068
|
-
|
|
6069
|
-
def __init__(self, path=None):
|
|
6070
|
-
Prim.__init__(self, {}, path=path)
|
|
6071
|
-
self.counters = collections.defaultdict(int)
|
|
6072
|
-
self.locls.update(self.getObjLocals())
|
|
6073
|
-
|
|
6074
|
-
def getObjLocals(self):
|
|
6075
|
-
return {
|
|
6076
|
-
'inc': self.inc,
|
|
6077
|
-
'get': self.get,
|
|
6078
|
-
'sorted': self.sorted,
|
|
6079
|
-
}
|
|
6080
|
-
|
|
6081
|
-
async def __aiter__(self):
|
|
6082
|
-
for name, valu in self.counters.items():
|
|
6083
|
-
yield name, valu
|
|
6084
|
-
|
|
6085
|
-
def __len__(self):
|
|
6086
|
-
return len(self.counters)
|
|
6087
|
-
|
|
6088
|
-
async def inc(self, name, valu=1):
|
|
6089
|
-
valu = await toint(valu)
|
|
6090
|
-
self.counters[name] += valu
|
|
6091
|
-
|
|
6092
|
-
async def get(self, name):
|
|
6093
|
-
return self.counters.get(name, 0)
|
|
6094
|
-
|
|
6095
|
-
def value(self):
|
|
6096
|
-
return dict(self.counters)
|
|
6097
|
-
|
|
6098
|
-
async def iter(self):
|
|
6099
|
-
for item in tuple(self.counters.items()):
|
|
6100
|
-
yield item
|
|
6101
|
-
|
|
6102
|
-
async def sorted(self, byname=False, reverse=False):
|
|
6103
|
-
if byname:
|
|
6104
|
-
return list(sorted(self.counters.items(), reverse=reverse))
|
|
6105
|
-
else:
|
|
6106
|
-
return list(sorted(self.counters.items(), key=lambda x: x[1], reverse=reverse))
|
|
6107
|
-
|
|
6108
6139
|
@registry.registerLib
|
|
6109
6140
|
class LibLayer(Lib):
|
|
6110
6141
|
'''
|
|
@@ -6177,6 +6208,7 @@ class LibLayer(Lib):
|
|
|
6177
6208
|
todo = ('delLayer', (layriden,), {})
|
|
6178
6209
|
return await self.runt.dyncall('cortex', todo, gatekeys=gatekeys)
|
|
6179
6210
|
|
|
6211
|
+
@stormfunc(readonly=True)
|
|
6180
6212
|
async def _libLayerGet(self, iden=None):
|
|
6181
6213
|
|
|
6182
6214
|
iden = await tostr(iden, noneok=True)
|
|
@@ -6190,6 +6222,7 @@ class LibLayer(Lib):
|
|
|
6190
6222
|
|
|
6191
6223
|
return Layer(self.runt, ldef, path=self.path)
|
|
6192
6224
|
|
|
6225
|
+
@stormfunc(readonly=True)
|
|
6193
6226
|
async def _libLayerList(self):
|
|
6194
6227
|
todo = s_common.todo('getLayerDefs')
|
|
6195
6228
|
defs = await self.runt.dyncall('cortex', todo)
|
|
@@ -6489,6 +6522,7 @@ class Layer(Prim):
|
|
|
6489
6522
|
'getMirrorStatus': self.getMirrorStatus,
|
|
6490
6523
|
}
|
|
6491
6524
|
|
|
6525
|
+
@stormfunc(readonly=True)
|
|
6492
6526
|
async def liftByTag(self, tagname, formname=None):
|
|
6493
6527
|
tagname = await tostr(tagname)
|
|
6494
6528
|
formname = await tostr(formname, noneok=True)
|
|
@@ -6503,6 +6537,7 @@ class Layer(Prim):
|
|
|
6503
6537
|
async for _, buid, sode in layr.liftByTag(tagname, form=formname):
|
|
6504
6538
|
yield await self.runt.snap._joinStorNode(buid, {iden: sode})
|
|
6505
6539
|
|
|
6540
|
+
@stormfunc(readonly=True)
|
|
6506
6541
|
async def liftByProp(self, propname, propvalu=None, propcmpr='='):
|
|
6507
6542
|
|
|
6508
6543
|
propname = await tostr(propname)
|
|
@@ -6539,6 +6574,7 @@ class Layer(Prim):
|
|
|
6539
6574
|
async for _, buid, sode in layr.liftByPropValu(liftform, liftprop, cmprvals):
|
|
6540
6575
|
yield await self.runt.snap._joinStorNode(buid, {iden: sode})
|
|
6541
6576
|
|
|
6577
|
+
@stormfunc(readonly=True)
|
|
6542
6578
|
async def getMirrorStatus(self):
|
|
6543
6579
|
iden = self.valu.get('iden')
|
|
6544
6580
|
layr = self.runt.snap.core.getLayer(iden)
|
|
@@ -6632,6 +6668,7 @@ class Layer(Prim):
|
|
|
6632
6668
|
layr = self.runt.snap.core.getLayer(layriden)
|
|
6633
6669
|
return await layr.getFormCounts()
|
|
6634
6670
|
|
|
6671
|
+
@stormfunc(readonly=True)
|
|
6635
6672
|
async def _methGetTagCount(self, tagname, formname=None):
|
|
6636
6673
|
tagname = await tostr(tagname)
|
|
6637
6674
|
formname = await tostr(formname, noneok=True)
|
|
@@ -6640,6 +6677,7 @@ class Layer(Prim):
|
|
|
6640
6677
|
layr = self.runt.snap.core.getLayer(layriden)
|
|
6641
6678
|
return await layr.getTagCount(tagname, formname=formname)
|
|
6642
6679
|
|
|
6680
|
+
@stormfunc(readonly=True)
|
|
6643
6681
|
async def _methGetPropCount(self, propname, maxsize=None):
|
|
6644
6682
|
propname = await tostr(propname)
|
|
6645
6683
|
maxsize = await toint(maxsize, noneok=True)
|
|
@@ -6661,6 +6699,7 @@ class Layer(Prim):
|
|
|
6661
6699
|
|
|
6662
6700
|
return await layr.getPropCount(prop.form.name, prop.name, maxsize=maxsize)
|
|
6663
6701
|
|
|
6702
|
+
@stormfunc(readonly=True)
|
|
6664
6703
|
async def _methLayerEdits(self, offs=0, wait=True, size=None):
|
|
6665
6704
|
offs = await toint(offs)
|
|
6666
6705
|
wait = await tobool(wait)
|
|
@@ -6677,6 +6716,7 @@ class Layer(Prim):
|
|
|
6677
6716
|
if size is not None and size == count:
|
|
6678
6717
|
break
|
|
6679
6718
|
|
|
6719
|
+
@stormfunc(readonly=True)
|
|
6680
6720
|
async def getStorNode(self, nodeid):
|
|
6681
6721
|
nodeid = await tostr(nodeid)
|
|
6682
6722
|
layriden = self.valu.get('iden')
|
|
@@ -6684,6 +6724,7 @@ class Layer(Prim):
|
|
|
6684
6724
|
layr = self.runt.snap.core.getLayer(layriden)
|
|
6685
6725
|
return await layr.getStorNode(s_common.uhex(nodeid))
|
|
6686
6726
|
|
|
6727
|
+
@stormfunc(readonly=True)
|
|
6687
6728
|
async def getStorNodes(self):
|
|
6688
6729
|
layriden = self.valu.get('iden')
|
|
6689
6730
|
await self.runt.reqUserCanReadLayer(layriden)
|
|
@@ -6691,6 +6732,7 @@ class Layer(Prim):
|
|
|
6691
6732
|
async for item in layr.getStorNodes():
|
|
6692
6733
|
yield item
|
|
6693
6734
|
|
|
6735
|
+
@stormfunc(readonly=True)
|
|
6694
6736
|
async def getEdges(self):
|
|
6695
6737
|
layriden = self.valu.get('iden')
|
|
6696
6738
|
await self.runt.reqUserCanReadLayer(layriden)
|
|
@@ -6698,6 +6740,7 @@ class Layer(Prim):
|
|
|
6698
6740
|
async for item in layr.getEdges():
|
|
6699
6741
|
yield item
|
|
6700
6742
|
|
|
6743
|
+
@stormfunc(readonly=True)
|
|
6701
6744
|
async def getEdgesByN1(self, nodeid):
|
|
6702
6745
|
nodeid = await tostr(nodeid)
|
|
6703
6746
|
layriden = self.valu.get('iden')
|
|
@@ -6706,6 +6749,7 @@ class Layer(Prim):
|
|
|
6706
6749
|
async for item in layr.iterNodeEdgesN1(s_common.uhex(nodeid)):
|
|
6707
6750
|
yield item
|
|
6708
6751
|
|
|
6752
|
+
@stormfunc(readonly=True)
|
|
6709
6753
|
async def getEdgesByN2(self, nodeid):
|
|
6710
6754
|
nodeid = await tostr(nodeid)
|
|
6711
6755
|
layriden = self.valu.get('iden')
|
|
@@ -6714,6 +6758,7 @@ class Layer(Prim):
|
|
|
6714
6758
|
async for item in layr.iterNodeEdgesN2(s_common.uhex(nodeid)):
|
|
6715
6759
|
yield item
|
|
6716
6760
|
|
|
6761
|
+
@stormfunc(readonly=True)
|
|
6717
6762
|
async def _methLayerGet(self, name, defv=None):
|
|
6718
6763
|
return self.valu.get(name, defv)
|
|
6719
6764
|
|
|
@@ -6740,6 +6785,7 @@ class Layer(Prim):
|
|
|
6740
6785
|
valu = await self.runt.dyncall(layriden, todo, gatekeys=gatekeys)
|
|
6741
6786
|
self.valu[name] = valu
|
|
6742
6787
|
|
|
6788
|
+
@stormfunc(readonly=True)
|
|
6743
6789
|
async def _methLayerPack(self):
|
|
6744
6790
|
ldef = copy.deepcopy(self.valu)
|
|
6745
6791
|
pushs = ldef.get('pushs')
|
|
@@ -6756,6 +6802,7 @@ class Layer(Prim):
|
|
|
6756
6802
|
|
|
6757
6803
|
return ldef
|
|
6758
6804
|
|
|
6805
|
+
@stormfunc(readonly=True)
|
|
6759
6806
|
async def _methLayerRepr(self):
|
|
6760
6807
|
iden = self.valu.get('iden')
|
|
6761
6808
|
name = self.valu.get('name', 'unnamed')
|
|
@@ -6852,10 +6899,9 @@ class LibView(Lib):
|
|
|
6852
6899
|
async def _methViewGet(self, iden=None):
|
|
6853
6900
|
if iden is None:
|
|
6854
6901
|
iden = self.runt.snap.view.iden
|
|
6855
|
-
|
|
6856
|
-
vdef = await self.runt.dyncall('cortex', todo)
|
|
6902
|
+
vdef = await self.runt.snap.core.getViewDef(iden)
|
|
6857
6903
|
if vdef is None:
|
|
6858
|
-
raise s_exc.NoSuchView(mesg=iden)
|
|
6904
|
+
raise s_exc.NoSuchView(mesg=f'No view with {iden=}', iden=iden)
|
|
6859
6905
|
|
|
6860
6906
|
return View(self.runt, vdef, path=self.path)
|
|
6861
6907
|
|
|
@@ -7098,7 +7144,7 @@ class View(Prim):
|
|
|
7098
7144
|
view = self.runt.snap.core.getView(self.valu.get('iden'))
|
|
7099
7145
|
if view is None: # pragma: no cover
|
|
7100
7146
|
mesg = f'No view with iden: {self.valu.get("iden")}'
|
|
7101
|
-
raise s_exc.NoSuchView(mesg=mesg)
|
|
7147
|
+
raise s_exc.NoSuchView(mesg=mesg, iden=self.valu.get('iden'))
|
|
7102
7148
|
|
|
7103
7149
|
layers = await toprim(valu)
|
|
7104
7150
|
layers = tuple(str(x) for x in layers)
|
|
@@ -7351,6 +7397,14 @@ class LibTrigger(Lib):
|
|
|
7351
7397
|
if prop is not None:
|
|
7352
7398
|
tdef['prop'] = prop
|
|
7353
7399
|
|
|
7400
|
+
verb = tdef.pop('verb', None)
|
|
7401
|
+
if verb is not None:
|
|
7402
|
+
tdef['verb'] = verb
|
|
7403
|
+
|
|
7404
|
+
n2form = tdef.pop('n2form', None)
|
|
7405
|
+
if n2form is not None:
|
|
7406
|
+
tdef['n2form'] = n2form
|
|
7407
|
+
|
|
7354
7408
|
gatekeys = ((useriden, ('trigger', 'add'), viewiden),)
|
|
7355
7409
|
todo = ('addTrigger', (tdef,), {})
|
|
7356
7410
|
tdef = await self.dyncall(viewiden, todo, gatekeys=gatekeys)
|
|
@@ -7379,6 +7433,7 @@ class LibTrigger(Lib):
|
|
|
7379
7433
|
|
|
7380
7434
|
return iden
|
|
7381
7435
|
|
|
7436
|
+
@stormfunc(readonly=True)
|
|
7382
7437
|
async def _methTriggerList(self, all=False):
|
|
7383
7438
|
if all:
|
|
7384
7439
|
views = self.runt.snap.core.listViews()
|
|
@@ -7397,6 +7452,7 @@ class LibTrigger(Lib):
|
|
|
7397
7452
|
|
|
7398
7453
|
return triggers
|
|
7399
7454
|
|
|
7455
|
+
@stormfunc(readonly=True)
|
|
7400
7456
|
async def _methTriggerGet(self, iden):
|
|
7401
7457
|
trigger = None
|
|
7402
7458
|
try:
|
|
@@ -7479,6 +7535,7 @@ class Trigger(Prim):
|
|
|
7479
7535
|
'pack': self.pack,
|
|
7480
7536
|
}
|
|
7481
7537
|
|
|
7538
|
+
@stormfunc(readonly=True)
|
|
7482
7539
|
async def pack(self):
|
|
7483
7540
|
return copy.deepcopy(self.valu)
|
|
7484
7541
|
|
|
@@ -7519,7 +7576,7 @@ class Trigger(Prim):
|
|
|
7519
7576
|
todo = s_common.todo('getViewDef', viewiden)
|
|
7520
7577
|
vdef = await self.runt.dyncall('cortex', todo)
|
|
7521
7578
|
if vdef is None:
|
|
7522
|
-
raise s_exc.NoSuchView(mesg=viewiden)
|
|
7579
|
+
raise s_exc.NoSuchView(mesg=f'No view with iden={viewiden}', iden=viewiden)
|
|
7523
7580
|
|
|
7524
7581
|
trigview = self.valu.get('view')
|
|
7525
7582
|
self.runt.confirm(('view', 'read'), gateiden=viewiden)
|
|
@@ -7981,6 +8038,7 @@ class LibJsonStor(Lib):
|
|
|
7981
8038
|
'cachedel': self.cachedel,
|
|
7982
8039
|
})
|
|
7983
8040
|
|
|
8041
|
+
@stormfunc(readonly=True)
|
|
7984
8042
|
async def has(self, path):
|
|
7985
8043
|
|
|
7986
8044
|
if not self.runt.isAdmin():
|
|
@@ -7994,6 +8052,7 @@ class LibJsonStor(Lib):
|
|
|
7994
8052
|
fullpath = ('cells', self.runt.snap.core.iden) + path
|
|
7995
8053
|
return await self.runt.snap.core.hasJsonObj(fullpath)
|
|
7996
8054
|
|
|
8055
|
+
@stormfunc(readonly=True)
|
|
7997
8056
|
async def get(self, path, prop=None):
|
|
7998
8057
|
|
|
7999
8058
|
if not self.runt.isAdmin():
|
|
@@ -8054,6 +8113,7 @@ class LibJsonStor(Lib):
|
|
|
8054
8113
|
|
|
8055
8114
|
return await self.runt.snap.core.delJsonObjProp(fullpath, prop=prop)
|
|
8056
8115
|
|
|
8116
|
+
@stormfunc(readonly=True)
|
|
8057
8117
|
async def iter(self, path=None):
|
|
8058
8118
|
|
|
8059
8119
|
if not self.runt.isAdmin():
|
|
@@ -8071,6 +8131,7 @@ class LibJsonStor(Lib):
|
|
|
8071
8131
|
async for path, item in self.runt.snap.core.getJsonObjs(fullpath):
|
|
8072
8132
|
yield path, item
|
|
8073
8133
|
|
|
8134
|
+
@stormfunc(readonly=True)
|
|
8074
8135
|
async def cacheget(self, path, key, asof='now', envl=False):
|
|
8075
8136
|
|
|
8076
8137
|
if not self.runt.isAdmin():
|
|
@@ -8238,6 +8299,7 @@ class UserJson(Prim):
|
|
|
8238
8299
|
'iter': self.iter,
|
|
8239
8300
|
})
|
|
8240
8301
|
|
|
8302
|
+
@stormfunc(readonly=True)
|
|
8241
8303
|
async def has(self, path):
|
|
8242
8304
|
|
|
8243
8305
|
path = await toprim(path)
|
|
@@ -8250,6 +8312,7 @@ class UserJson(Prim):
|
|
|
8250
8312
|
|
|
8251
8313
|
return await self.runt.snap.core.hasJsonObj(fullpath)
|
|
8252
8314
|
|
|
8315
|
+
@stormfunc(readonly=True)
|
|
8253
8316
|
async def get(self, path, prop=None):
|
|
8254
8317
|
path = await toprim(path)
|
|
8255
8318
|
prop = await toprim(prop)
|
|
@@ -8304,6 +8367,7 @@ class UserJson(Prim):
|
|
|
8304
8367
|
|
|
8305
8368
|
return await self.runt.snap.core.delJsonObjProp(fullpath, prop=prop)
|
|
8306
8369
|
|
|
8370
|
+
@stormfunc(readonly=True)
|
|
8307
8371
|
async def iter(self, path=None):
|
|
8308
8372
|
|
|
8309
8373
|
path = await toprim(path)
|
|
@@ -8380,7 +8444,7 @@ class User(Prim):
|
|
|
8380
8444
|
),
|
|
8381
8445
|
'returns': {'type': 'boolean', 'desc': 'True if the rule is allowed, False otherwise.', }}},
|
|
8382
8446
|
{'name': 'getAllowedReason', 'desc': 'Return an allowed status and reason for the given perm.',
|
|
8383
|
-
'type': {'type': 'function', '_funcname': '
|
|
8447
|
+
'type': {'type': 'function', '_funcname': '_methGetAllowedReason',
|
|
8384
8448
|
'args': (
|
|
8385
8449
|
{'name': 'permname', 'type': 'str', 'desc': 'The permission string to check.', },
|
|
8386
8450
|
{'name': 'gateiden', 'type': 'str', 'desc': 'The authgate iden.', 'default': None, },
|
|
@@ -8459,7 +8523,7 @@ class User(Prim):
|
|
|
8459
8523
|
),
|
|
8460
8524
|
'returns': {'type': 'null', }}},
|
|
8461
8525
|
{'name': 'getRules', 'desc': 'Get the rules for the user and optional auth gate.',
|
|
8462
|
-
'type': {'type': 'function', '_funcname': '
|
|
8526
|
+
'type': {'type': 'function', '_funcname': '_methGetRules',
|
|
8463
8527
|
'args': (
|
|
8464
8528
|
{'name': 'gateiden', 'type': 'str',
|
|
8465
8529
|
'desc': 'The gate iden used for the rules.', 'default': None},
|
|
@@ -8494,7 +8558,7 @@ class User(Prim):
|
|
|
8494
8558
|
),
|
|
8495
8559
|
'returns': {'type': 'null', }}},
|
|
8496
8560
|
{'name': 'gates', 'desc': 'Return a list of auth gates that the user has rules for.',
|
|
8497
|
-
'type': {'type': 'function', '_funcname': '
|
|
8561
|
+
'type': {'type': 'function', '_funcname': '_methGates',
|
|
8498
8562
|
'args': (),
|
|
8499
8563
|
'returns': {'type': 'list',
|
|
8500
8564
|
'desc': 'A list of ``auth:gates`` that the user has rules for.', }}},
|
|
@@ -8577,7 +8641,7 @@ class User(Prim):
|
|
|
8577
8641
|
'get': self._methUserGet,
|
|
8578
8642
|
'pack': self._methUserPack,
|
|
8579
8643
|
'tell': self._methUserTell,
|
|
8580
|
-
'gates': self.
|
|
8644
|
+
'gates': self._methGates,
|
|
8581
8645
|
'notify': self._methUserNotify,
|
|
8582
8646
|
'roles': self._methUserRoles,
|
|
8583
8647
|
'allowed': self._methUserAllowed,
|
|
@@ -8587,15 +8651,16 @@ class User(Prim):
|
|
|
8587
8651
|
'delRule': self._methUserDelRule,
|
|
8588
8652
|
'popRule': self._methUserPopRule,
|
|
8589
8653
|
'setRoles': self._methUserSetRoles,
|
|
8590
|
-
'getRules': self.
|
|
8654
|
+
'getRules': self._methGetRules,
|
|
8591
8655
|
'setRules': self._methUserSetRules,
|
|
8592
8656
|
'setAdmin': self._methUserSetAdmin,
|
|
8593
8657
|
'setEmail': self._methUserSetEmail,
|
|
8594
8658
|
'setLocked': self._methUserSetLocked,
|
|
8595
8659
|
'setPasswd': self._methUserSetPasswd,
|
|
8596
|
-
'getAllowedReason': self.
|
|
8660
|
+
'getAllowedReason': self._methGetAllowedReason,
|
|
8597
8661
|
}
|
|
8598
8662
|
|
|
8663
|
+
@stormfunc(readonly=True)
|
|
8599
8664
|
async def _methUserPack(self):
|
|
8600
8665
|
return await self.value()
|
|
8601
8666
|
|
|
@@ -8634,7 +8699,8 @@ class User(Prim):
|
|
|
8634
8699
|
udef = await self.runt.snap.core.getUserDef(self.valu)
|
|
8635
8700
|
return udef.get(name)
|
|
8636
8701
|
|
|
8637
|
-
|
|
8702
|
+
@stormfunc(readonly=True)
|
|
8703
|
+
async def _methGates(self):
|
|
8638
8704
|
user = self.runt.snap.core.auth.user(self.valu)
|
|
8639
8705
|
retn = []
|
|
8640
8706
|
for gateiden in user.authgates.keys():
|
|
@@ -8642,10 +8708,12 @@ class User(Prim):
|
|
|
8642
8708
|
retn.append(Gate(self.runt, gate))
|
|
8643
8709
|
return retn
|
|
8644
8710
|
|
|
8711
|
+
@stormfunc(readonly=True)
|
|
8645
8712
|
async def _methUserRoles(self):
|
|
8646
8713
|
udef = await self.runt.snap.core.getUserDef(self.valu)
|
|
8647
8714
|
return [Role(self.runt, rdef['iden']) for rdef in udef.get('roles')]
|
|
8648
8715
|
|
|
8716
|
+
@stormfunc(readonly=True)
|
|
8649
8717
|
async def _methUserAllowed(self, permname, gateiden=None, default=False):
|
|
8650
8718
|
permname = await tostr(permname)
|
|
8651
8719
|
gateiden = await tostr(gateiden)
|
|
@@ -8655,7 +8723,8 @@ class User(Prim):
|
|
|
8655
8723
|
user = await self.runt.snap.core.auth.reqUser(self.valu)
|
|
8656
8724
|
return user.allowed(perm, gateiden=gateiden, default=default)
|
|
8657
8725
|
|
|
8658
|
-
|
|
8726
|
+
@stormfunc(readonly=True)
|
|
8727
|
+
async def _methGetAllowedReason(self, permname, gateiden=None, default=False):
|
|
8659
8728
|
permname = await tostr(permname)
|
|
8660
8729
|
gateiden = await tostr(gateiden)
|
|
8661
8730
|
default = await tobool(default)
|
|
@@ -8685,7 +8754,8 @@ class User(Prim):
|
|
|
8685
8754
|
self.runt.confirm(('auth', 'user', 'set', 'rules'), gateiden=gateiden)
|
|
8686
8755
|
await self.runt.snap.core.setUserRules(self.valu, rules, gateiden=gateiden)
|
|
8687
8756
|
|
|
8688
|
-
|
|
8757
|
+
@stormfunc(readonly=True)
|
|
8758
|
+
async def _methGetRules(self, gateiden=None):
|
|
8689
8759
|
gateiden = await tostr(gateiden, noneok=True)
|
|
8690
8760
|
user = self.runt.snap.core.auth.user(self.valu)
|
|
8691
8761
|
return user.getRules(gateiden=gateiden)
|
|
@@ -8709,7 +8779,7 @@ class User(Prim):
|
|
|
8709
8779
|
self.runt.confirm(('auth', 'user', 'set', 'rules'), gateiden=gateiden)
|
|
8710
8780
|
|
|
8711
8781
|
indx = await toint(indx)
|
|
8712
|
-
rules = list(await self.
|
|
8782
|
+
rules = list(await self._methGetRules(gateiden=gateiden))
|
|
8713
8783
|
|
|
8714
8784
|
if len(rules) <= indx:
|
|
8715
8785
|
mesg = f'User {self.valu} only has {len(rules)} rules.'
|
|
@@ -8772,7 +8842,7 @@ class Role(Prim):
|
|
|
8772
8842
|
'type': {'type': 'function', '_funcname': '_methRolePack', 'args': (),
|
|
8773
8843
|
'returns': {'type': 'dict', 'desc': 'The packed Role definition.', }}},
|
|
8774
8844
|
{'name': 'gates', 'desc': 'Return a list of auth gates that the role has rules for.',
|
|
8775
|
-
'type': {'type': 'function', '_funcname': '
|
|
8845
|
+
'type': {'type': 'function', '_funcname': '_methGates',
|
|
8776
8846
|
'args': (),
|
|
8777
8847
|
'returns': {'type': 'list',
|
|
8778
8848
|
'desc': 'A list of ``auth:gates`` that the role has rules for.', }}},
|
|
@@ -8803,7 +8873,7 @@ class Role(Prim):
|
|
|
8803
8873
|
),
|
|
8804
8874
|
'returns': {'type': 'list', 'desc': 'The rule which was removed.'}}},
|
|
8805
8875
|
{'name': 'getRules', 'desc': 'Get the rules for the role and optional auth gate.',
|
|
8806
|
-
'type': {'type': 'function', '_funcname': '
|
|
8876
|
+
'type': {'type': 'function', '_funcname': '_methGetRules',
|
|
8807
8877
|
'args': (
|
|
8808
8878
|
{'name': 'gateiden', 'type': 'str',
|
|
8809
8879
|
'desc': 'The gate iden used for the rules.', 'default': None},
|
|
@@ -8848,12 +8918,12 @@ class Role(Prim):
|
|
|
8848
8918
|
return {
|
|
8849
8919
|
'get': self._methRoleGet,
|
|
8850
8920
|
'pack': self._methRolePack,
|
|
8851
|
-
'gates': self.
|
|
8921
|
+
'gates': self._methGates,
|
|
8852
8922
|
'addRule': self._methRoleAddRule,
|
|
8853
8923
|
'delRule': self._methRoleDelRule,
|
|
8854
8924
|
'popRule': self._methRolePopRule,
|
|
8855
8925
|
'setRules': self._methRoleSetRules,
|
|
8856
|
-
'getRules': self.
|
|
8926
|
+
'getRules': self._methGetRules,
|
|
8857
8927
|
}
|
|
8858
8928
|
|
|
8859
8929
|
async def _derefGet(self, name):
|
|
@@ -8865,14 +8935,17 @@ class Role(Prim):
|
|
|
8865
8935
|
name = await tostr(name)
|
|
8866
8936
|
await self.runt.snap.core.setRoleName(self.valu, name)
|
|
8867
8937
|
|
|
8938
|
+
@stormfunc(readonly=True)
|
|
8868
8939
|
async def _methRoleGet(self, name):
|
|
8869
8940
|
rdef = await self.runt.snap.core.getRoleDef(self.valu)
|
|
8870
8941
|
return rdef.get(name)
|
|
8871
8942
|
|
|
8943
|
+
@stormfunc(readonly=True)
|
|
8872
8944
|
async def _methRolePack(self):
|
|
8873
8945
|
return await self.value()
|
|
8874
8946
|
|
|
8875
|
-
|
|
8947
|
+
@stormfunc(readonly=True)
|
|
8948
|
+
async def _methGates(self):
|
|
8876
8949
|
role = self.runt.snap.core.auth.role(self.valu)
|
|
8877
8950
|
retn = []
|
|
8878
8951
|
for gateiden in role.authgates.keys():
|
|
@@ -8880,7 +8953,8 @@ class Role(Prim):
|
|
|
8880
8953
|
retn.append(Gate(self.runt, gate))
|
|
8881
8954
|
return retn
|
|
8882
8955
|
|
|
8883
|
-
|
|
8956
|
+
@stormfunc(readonly=True)
|
|
8957
|
+
async def _methGetRules(self, gateiden=None):
|
|
8884
8958
|
gateiden = await tostr(gateiden, noneok=True)
|
|
8885
8959
|
role = self.runt.snap.core.auth.role(self.valu)
|
|
8886
8960
|
return role.getRules(gateiden=gateiden)
|
|
@@ -8911,7 +8985,7 @@ class Role(Prim):
|
|
|
8911
8985
|
|
|
8912
8986
|
indx = await toint(indx)
|
|
8913
8987
|
|
|
8914
|
-
rules = list(await self.
|
|
8988
|
+
rules = list(await self._methGetRules(gateiden=gateiden))
|
|
8915
8989
|
|
|
8916
8990
|
if len(rules) <= indx:
|
|
8917
8991
|
mesg = f'Role {self.valu} only has {len(rules)} rules.'
|
|
@@ -9404,6 +9478,7 @@ class LibCron(Lib):
|
|
|
9404
9478
|
self.runt.confirm(('cron', 'set'), gateiden=iden)
|
|
9405
9479
|
return await self.runt.snap.core.moveCronJob(self.runt.user.iden, iden, view)
|
|
9406
9480
|
|
|
9481
|
+
@stormfunc(readonly=True)
|
|
9407
9482
|
async def _methCronList(self):
|
|
9408
9483
|
todo = s_common.todo('listCronJobs')
|
|
9409
9484
|
gatekeys = ((self.runt.user.iden, ('cron', 'get'), None),)
|
|
@@ -9411,6 +9486,7 @@ class LibCron(Lib):
|
|
|
9411
9486
|
|
|
9412
9487
|
return [CronJob(self.runt, cdef, path=self.path) for cdef in defs]
|
|
9413
9488
|
|
|
9489
|
+
@stormfunc(readonly=True)
|
|
9414
9490
|
async def _methCronGet(self, prefix):
|
|
9415
9491
|
cdef = await self._matchIdens(prefix, ('cron', 'get'))
|
|
9416
9492
|
|
|
@@ -9498,6 +9574,7 @@ class CronJob(Prim):
|
|
|
9498
9574
|
|
|
9499
9575
|
return self
|
|
9500
9576
|
|
|
9577
|
+
@stormfunc(readonly=True)
|
|
9501
9578
|
async def _methCronJobPack(self):
|
|
9502
9579
|
return copy.deepcopy(self.valu)
|
|
9503
9580
|
|
|
@@ -9505,6 +9582,7 @@ class CronJob(Prim):
|
|
|
9505
9582
|
def _formatTimestamp(ts):
|
|
9506
9583
|
return datetime.datetime.fromtimestamp(ts, datetime.UTC).strftime('%Y-%m-%dT%H:%M')
|
|
9507
9584
|
|
|
9585
|
+
@stormfunc(readonly=True)
|
|
9508
9586
|
async def _methCronJobPprint(self):
|
|
9509
9587
|
user = self.valu.get('username')
|
|
9510
9588
|
view = self.valu.get('view')
|
|
@@ -9748,13 +9826,15 @@ async def toiter(valu, noneok=False):
|
|
|
9748
9826
|
return
|
|
9749
9827
|
|
|
9750
9828
|
if isinstance(valu, Prim):
|
|
9751
|
-
async
|
|
9752
|
-
|
|
9829
|
+
async with contextlib.aclosing(valu.iter()) as agen:
|
|
9830
|
+
async for item in agen:
|
|
9831
|
+
yield item
|
|
9753
9832
|
return
|
|
9754
9833
|
|
|
9755
9834
|
try:
|
|
9756
|
-
async
|
|
9757
|
-
|
|
9835
|
+
async with contextlib.aclosing(s_coro.agen(valu)) as agen:
|
|
9836
|
+
async for item in agen:
|
|
9837
|
+
yield item
|
|
9758
9838
|
except TypeError as e:
|
|
9759
9839
|
mesg = f'Value is not iterable: {valu!r}'
|
|
9760
9840
|
raise s_exc.StormRuntimeError(mesg=mesg) from e
|