synapse 2.164.0__py311-none-any.whl → 2.166.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.

Files changed (89) hide show
  1. synapse/axon.py +3 -3
  2. synapse/cmds/cortex.py +1 -6
  3. synapse/common.py +7 -1
  4. synapse/cortex.py +145 -192
  5. synapse/datamodel.py +36 -1
  6. synapse/lib/agenda.py +87 -97
  7. synapse/lib/aha.py +51 -0
  8. synapse/lib/ast.py +22 -23
  9. synapse/lib/base.py +0 -6
  10. synapse/lib/boss.py +3 -0
  11. synapse/lib/cell.py +70 -39
  12. synapse/lib/certdir.py +9 -0
  13. synapse/lib/hiveauth.py +65 -12
  14. synapse/lib/httpapi.py +1 -0
  15. synapse/lib/modelrev.py +121 -33
  16. synapse/lib/modules.py +1 -0
  17. synapse/lib/nexus.py +64 -26
  18. synapse/lib/parser.py +2 -0
  19. synapse/lib/schemas.py +14 -0
  20. synapse/lib/snap.py +50 -4
  21. synapse/lib/storm.lark +4 -3
  22. synapse/lib/storm.py +96 -22
  23. synapse/lib/storm_format.py +1 -0
  24. synapse/lib/stormlib/aha.py +7 -1
  25. synapse/lib/stormlib/auth.py +13 -5
  26. synapse/lib/stormlib/cache.py +202 -0
  27. synapse/lib/stormlib/cortex.py +147 -8
  28. synapse/lib/stormlib/gen.py +53 -6
  29. synapse/lib/stormlib/math.py +1 -1
  30. synapse/lib/stormlib/model.py +11 -1
  31. synapse/lib/stormlib/spooled.py +109 -0
  32. synapse/lib/stormlib/vault.py +1 -1
  33. synapse/lib/stormtypes.py +113 -17
  34. synapse/lib/trigger.py +36 -47
  35. synapse/lib/types.py +29 -2
  36. synapse/lib/version.py +2 -2
  37. synapse/lib/view.py +80 -53
  38. synapse/models/economic.py +174 -5
  39. synapse/models/files.py +2 -0
  40. synapse/models/inet.py +77 -2
  41. synapse/models/infotech.py +12 -12
  42. synapse/models/orgs.py +72 -21
  43. synapse/models/person.py +40 -11
  44. synapse/models/risk.py +78 -24
  45. synapse/models/science.py +102 -0
  46. synapse/telepath.py +117 -35
  47. synapse/tests/test_cortex.py +84 -158
  48. synapse/tests/test_datamodel.py +22 -0
  49. synapse/tests/test_lib_agenda.py +52 -96
  50. synapse/tests/test_lib_aha.py +126 -4
  51. synapse/tests/test_lib_ast.py +412 -6
  52. synapse/tests/test_lib_cell.py +24 -8
  53. synapse/tests/test_lib_certdir.py +32 -0
  54. synapse/tests/test_lib_grammar.py +9 -1
  55. synapse/tests/test_lib_httpapi.py +0 -1
  56. synapse/tests/test_lib_jupyter.py +0 -1
  57. synapse/tests/test_lib_modelrev.py +41 -0
  58. synapse/tests/test_lib_nexus.py +38 -0
  59. synapse/tests/test_lib_storm.py +95 -5
  60. synapse/tests/test_lib_stormlib_cache.py +272 -0
  61. synapse/tests/test_lib_stormlib_cortex.py +71 -0
  62. synapse/tests/test_lib_stormlib_gen.py +37 -2
  63. synapse/tests/test_lib_stormlib_model.py +2 -0
  64. synapse/tests/test_lib_stormlib_spooled.py +190 -0
  65. synapse/tests/test_lib_stormlib_vault.py +12 -3
  66. synapse/tests/test_lib_stormsvc.py +0 -10
  67. synapse/tests/test_lib_stormtypes.py +60 -8
  68. synapse/tests/test_lib_trigger.py +20 -2
  69. synapse/tests/test_lib_types.py +17 -1
  70. synapse/tests/test_model_economic.py +114 -0
  71. synapse/tests/test_model_files.py +2 -0
  72. synapse/tests/test_model_inet.py +73 -1
  73. synapse/tests/test_model_infotech.py +2 -2
  74. synapse/tests/test_model_orgs.py +10 -1
  75. synapse/tests/test_model_risk.py +30 -2
  76. synapse/tests/test_model_science.py +59 -0
  77. synapse/tests/test_model_syn.py +0 -1
  78. synapse/tests/test_telepath.py +30 -7
  79. synapse/tests/test_tools_modrole.py +81 -0
  80. synapse/tests/test_tools_moduser.py +105 -0
  81. synapse/tools/modrole.py +59 -7
  82. synapse/tools/moduser.py +78 -10
  83. {synapse-2.164.0.dist-info → synapse-2.166.0.dist-info}/METADATA +2 -2
  84. {synapse-2.164.0.dist-info → synapse-2.166.0.dist-info}/RECORD +87 -83
  85. {synapse-2.164.0.dist-info → synapse-2.166.0.dist-info}/WHEEL +1 -1
  86. synapse/lib/provenance.py +0 -111
  87. synapse/tests/test_lib_provenance.py +0 -37
  88. {synapse-2.164.0.dist-info → synapse-2.166.0.dist-info}/LICENSE +0 -0
  89. {synapse-2.164.0.dist-info → synapse-2.166.0.dist-info}/top_level.txt +0 -0
synapse/lib/types.py CHANGED
@@ -17,6 +17,7 @@ import synapse.lib.layer as s_layer
17
17
  import synapse.lib.config as s_config
18
18
  import synapse.lib.msgpack as s_msgpack
19
19
  import synapse.lib.grammar as s_grammar
20
+ import synapse.lib.stormtypes as s_stormtypes
20
21
 
21
22
  logger = logging.getLogger(__name__)
22
23
 
@@ -367,6 +368,7 @@ class Bool(Type):
367
368
  self.setNormFunc(int, self._normPyInt)
368
369
  self.setNormFunc(bool, self._normPyInt)
369
370
  self.setNormFunc(decimal.Decimal, self._normPyInt)
371
+ self.setNormFunc(s_stormtypes.Number, self._normNumber)
370
372
 
371
373
  def _normPyStr(self, valu):
372
374
 
@@ -387,6 +389,9 @@ class Bool(Type):
387
389
  def _normPyInt(self, valu):
388
390
  return int(bool(valu)), {}
389
391
 
392
+ def _normNumber(self, valu):
393
+ return int(bool(valu.valu)), {}
394
+
390
395
  def repr(self, valu):
391
396
  return repr(bool(valu)).lower()
392
397
 
@@ -887,6 +892,7 @@ class IntBase(Type):
887
892
  })
888
893
 
889
894
  self.setNormFunc(decimal.Decimal, self._normPyDecimal)
895
+ self.setNormFunc(s_stormtypes.Number, self._normNumber)
890
896
 
891
897
  def _storLiftRange(self, cmpr, valu):
892
898
  minv, minfo = self.norm(valu[0])
@@ -924,6 +930,9 @@ class IntBase(Type):
924
930
  def _normPyDecimal(self, valu):
925
931
  return self._normPyInt(int(valu))
926
932
 
933
+ def _normNumber(self, valu):
934
+ return self._normPyInt(int(valu.valu))
935
+
927
936
  class Int(IntBase):
928
937
 
929
938
  _opt_defs = (
@@ -996,6 +1005,7 @@ class Int(IntBase):
996
1005
  self.setNormFunc(str, self._normPyStr)
997
1006
  self.setNormFunc(int, self._normPyInt)
998
1007
  self.setNormFunc(bool, self._normPyBool)
1008
+ self.setNormFunc(float, self._normPyFloat)
999
1009
 
1000
1010
  def merge(self, oldv, newv):
1001
1011
 
@@ -1040,6 +1050,9 @@ class Int(IntBase):
1040
1050
 
1041
1051
  return valu, {}
1042
1052
 
1053
+ def _normPyFloat(self, valu):
1054
+ return self._normPyInt(int(valu))
1055
+
1043
1056
  def repr(self, norm):
1044
1057
 
1045
1058
  text = self.enumrepr.get(norm)
@@ -1132,6 +1145,7 @@ class Float(Type):
1132
1145
  self.setNormFunc(int, self._normPyInt)
1133
1146
  self.setNormFunc(float, self._normPyFloat)
1134
1147
  self.setNormFunc(decimal.Decimal, self._normPyInt)
1148
+ self.setNormFunc(s_stormtypes.Number, self._normNumber)
1135
1149
 
1136
1150
  def _normPyStr(self, valu):
1137
1151
 
@@ -1146,6 +1160,9 @@ class Float(Type):
1146
1160
  valu = float(valu)
1147
1161
  return self._normPyFloat(valu)
1148
1162
 
1163
+ def _normNumber(self, valu):
1164
+ return self._normPyFloat(float(valu.valu))
1165
+
1149
1166
  def _normPyFloat(self, valu):
1150
1167
 
1151
1168
  if self.minval is not None and not self.mincmp(valu, self.minval):
@@ -1185,6 +1202,7 @@ class Ival(Type):
1185
1202
  self.setNormFunc(list, self._normPyIter)
1186
1203
  self.setNormFunc(tuple, self._normPyIter)
1187
1204
  self.setNormFunc(decimal.Decimal, self._normPyInt)
1205
+ self.setNormFunc(s_stormtypes.Number, self._normNumber)
1188
1206
  self.storlifts.update({
1189
1207
  '@=': self._storLiftAt,
1190
1208
  })
@@ -1245,6 +1263,11 @@ class Ival(Type):
1245
1263
  maxv, info = self.timetype._normPyInt(minv + 1)
1246
1264
  return (minv, maxv), info
1247
1265
 
1266
+ def _normNumber(self, valu):
1267
+ minv, _ = self.timetype._normPyInt(valu.valu)
1268
+ maxv, info = self.timetype._normPyInt(minv + 1)
1269
+ return (minv, maxv), info
1270
+
1248
1271
  def _normRelStr(self, valu, relto=None):
1249
1272
  valu = valu.strip().lower()
1250
1273
  # assumes the relative string starts with a - or +
@@ -1631,6 +1654,7 @@ class Str(Type):
1631
1654
  self.setNormFunc(bool, self._normPyBool)
1632
1655
  self.setNormFunc(float, self._normPyFloat)
1633
1656
  self.setNormFunc(decimal.Decimal, self._normPyInt)
1657
+ self.setNormFunc(s_stormtypes.Number, self._normNumber)
1634
1658
 
1635
1659
  self.storlifts.update({
1636
1660
  '=': self._storLiftEq,
@@ -1696,6 +1720,9 @@ class Str(Type):
1696
1720
  def _normPyInt(self, valu):
1697
1721
  return self._normPyStr(str(valu))
1698
1722
 
1723
+ def _normNumber(self, valu):
1724
+ return self._normPyStr(str(valu.valu))
1725
+
1699
1726
  def _normPyFloat(self, valu):
1700
1727
  deci = s_common.hugectx.create_decimal(str(valu))
1701
1728
  return format(deci, 'f'), {}
@@ -1823,7 +1850,7 @@ class Tag(Str):
1823
1850
  mesg = f'Tag does not match tagre: [{s_grammar.tagre.pattern}]'
1824
1851
  raise s_exc.BadTypeValu(valu=norm, name=self.name, mesg=mesg)
1825
1852
 
1826
- return norm, {'subs': subs}
1853
+ return norm, {'subs': subs, 'toks': toks}
1827
1854
 
1828
1855
  def _normPyStr(self, text):
1829
1856
  toks = text.strip('#').split('.')
@@ -1901,7 +1928,7 @@ class Velocity(IntBase):
1901
1928
 
1902
1929
  unit = valu[offs:].strip()
1903
1930
  if not unit:
1904
- return base, {}
1931
+ return int(base), {}
1905
1932
 
1906
1933
  if unit.find('/') != -1:
1907
1934
  dist, dura = unit.split('/', 1)
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, 164, 0)
226
+ version = (2, 166, 0)
227
227
  verstring = '.'.join([str(x) for x in version])
228
- commit = '1c4ac22918ed63d1b33158245c75a30364a231e5'
228
+ commit = '09f8a7b3ad1f2ed5949e7d1a9dc7d17161fab932'
synapse/lib/view.py CHANGED
@@ -167,6 +167,18 @@ class View(s_nexus.Pusher): # type: ignore
167
167
  if byts is not None:
168
168
  return s_msgpack.un(byts)
169
169
 
170
+ async def getMergingViews(self):
171
+ if self.info.get('quorum') is None:
172
+ mesg = f'View ({self.iden}) does not require quorum voting.'
173
+ raise s_exc.BadState(mesg=mesg)
174
+
175
+ idens = []
176
+ for view in list(self.core.views.values()):
177
+ await asyncio.sleep(0)
178
+ if view.parent == self and view.getMergeRequest() is not None:
179
+ idens.append(view.iden)
180
+ return idens
181
+
170
182
  async def setMergeRequest(self, mergeinfo):
171
183
  self.reqParentQuorum()
172
184
  mergeinfo['iden'] = s_common.guid()
@@ -193,6 +205,27 @@ class View(s_nexus.Pusher): # type: ignore
193
205
  await self.core.feedBeholder('view:merge:request:set', {'view': self.iden, 'merge': mergeinfo})
194
206
  return mergeinfo
195
207
 
208
+ async def setMergeComment(self, comment):
209
+ return await self._push('merge:set:comment', s_common.now(), comment)
210
+
211
+ @s_nexus.Pusher.onPush('merge:set:comment')
212
+ async def _setMergeRequestComment(self, updated, comment):
213
+ self.reqParentQuorum()
214
+ merge = self.getMergeRequest()
215
+ if merge is None:
216
+ mesg = 'Cannot set the comment of a merge request that does not exist.'
217
+ raise s_exc.BadState(mesg=mesg)
218
+
219
+ merge['updated'] = updated
220
+ merge['comment'] = comment
221
+ s_schemas.reqValidMerge(merge)
222
+ lkey = self.bidn + b'merge:req'
223
+ self.core.slab.put(lkey, s_msgpack.en(merge), db='view:meta')
224
+
225
+ await self.core.feedBeholder('view:merge:set', {'view': self.iden, 'merge': merge})
226
+
227
+ return merge
228
+
196
229
  async def delMergeRequest(self):
197
230
  return await self._push('merge:del')
198
231
 
@@ -300,6 +333,30 @@ class View(s_nexus.Pusher): # type: ignore
300
333
 
301
334
  return vote
302
335
 
336
+ async def setMergeVoteComment(self, useriden, comment):
337
+ return await self._push('merge:vote:set:comment', s_common.now(), useriden, comment)
338
+
339
+ @s_nexus.Pusher.onPush('merge:vote:set:comment')
340
+ async def _setMergeVoteComment(self, tick, useriden, comment):
341
+ self.reqParentQuorum()
342
+
343
+ uidn = s_common.uhex(useriden)
344
+
345
+ lkey = self.bidn + b'merge:vote' + uidn
346
+ byts = self.core.slab.pop(lkey, db='view:meta')
347
+
348
+ if byts is None:
349
+ mesg = 'Cannot set the comment for a vote that does not exist.'
350
+ raise s_exc.BadState(mesg=mesg)
351
+
352
+ vote = s_msgpack.un(byts)
353
+ vote['updated'] = tick
354
+ vote['comment'] = comment
355
+ self.core.slab.put(lkey, s_msgpack.en(vote), db='view:meta')
356
+ await self.core.feedBeholder('view:merge:vote:set', {'view': self.iden, 'vote': vote})
357
+
358
+ return vote
359
+
303
360
  async def delMergeVote(self, useriden):
304
361
  return await self._push('merge:vote:del', useriden, s_common.now())
305
362
 
@@ -1327,87 +1384,57 @@ class View(s_nexus.Pusher): # type: ignore
1327
1384
  self._confirm(user, perm)
1328
1385
  await asyncio.sleep(0)
1329
1386
 
1330
- async def runTagAdd(self, node, tag, valu, view=None):
1387
+ async def runTagAdd(self, node, tag, valu):
1331
1388
 
1332
- # Run the non-glob callbacks, then the glob callbacks
1333
- funcs = itertools.chain(self.core.ontagadds.get(tag, ()), (x[1] for x in self.core.ontagaddglobs.get(tag)))
1334
- for func in funcs:
1335
- try:
1336
- await s_coro.ornot(func, node, tag, valu)
1337
- except asyncio.CancelledError: # pragma: no cover TODO: remove once >= py 3.8 only
1338
- raise
1339
- except Exception:
1340
- logger.exception('onTagAdd Error')
1341
-
1342
- if view is None:
1343
- view = self.iden
1389
+ if self.core.migration:
1390
+ return
1344
1391
 
1345
1392
  # Run any trigger handlers
1346
- await self.triggers.runTagAdd(node, tag, view=view)
1393
+ await self.triggers.runTagAdd(node, tag)
1347
1394
 
1348
- async def runTagDel(self, node, tag, valu, view=None):
1395
+ async def runTagDel(self, node, tag, valu):
1349
1396
 
1350
- funcs = itertools.chain(self.core.ontagdels.get(tag, ()), (x[1] for x in self.core.ontagdelglobs.get(tag)))
1351
- for func in funcs:
1352
- try:
1353
- await s_coro.ornot(func, node, tag, valu)
1354
- except asyncio.CancelledError: # pragma: no cover TODO: remove once >= py 3.8 only
1355
- raise
1356
- except Exception:
1357
- logger.exception('onTagDel Error')
1397
+ if self.core.migration:
1398
+ return
1358
1399
 
1359
- if view is None:
1360
- view = self.iden
1400
+ await self.triggers.runTagDel(node, tag)
1361
1401
 
1362
- await self.triggers.runTagDel(node, tag, view=view)
1402
+ async def runNodeAdd(self, node):
1363
1403
 
1364
- async def runNodeAdd(self, node, view=None):
1365
- if not node.snap.trigson:
1404
+ if self.core.migration:
1366
1405
  return
1367
1406
 
1368
- if view is None:
1369
- view = self.iden
1407
+ await self.triggers.runNodeAdd(node)
1370
1408
 
1371
- await self.triggers.runNodeAdd(node, view=view)
1409
+ async def runNodeDel(self, node):
1372
1410
 
1373
- async def runNodeDel(self, node, view=None):
1374
- if not node.snap.trigson:
1411
+ if self.core.migration:
1375
1412
  return
1376
1413
 
1377
- if view is None:
1378
- view = self.iden
1414
+ await self.triggers.runNodeDel(node)
1379
1415
 
1380
- await self.triggers.runNodeDel(node, view=view)
1381
-
1382
- async def runPropSet(self, node, prop, oldv, view=None):
1416
+ async def runPropSet(self, node, prop, oldv):
1383
1417
  '''
1384
1418
  Handle when a prop set trigger event fired
1385
1419
  '''
1386
- if not node.snap.trigson:
1420
+ if self.core.migration:
1387
1421
  return
1388
1422
 
1389
- if view is None:
1390
- view = self.iden
1423
+ await self.triggers.runPropSet(node, prop, oldv)
1391
1424
 
1392
- await self.triggers.runPropSet(node, prop, oldv, view=view)
1425
+ async def runEdgeAdd(self, n1, edge, n2):
1393
1426
 
1394
- async def runEdgeAdd(self, n1, edge, n2, view=None):
1395
- if not n1.snap.trigson:
1427
+ if self.core.migration:
1396
1428
  return
1397
1429
 
1398
- if view is None:
1399
- view = self.iden
1430
+ await self.triggers.runEdgeAdd(n1, edge, n2)
1400
1431
 
1401
- await self.triggers.runEdgeAdd(n1, edge, n2, view=view)
1432
+ async def runEdgeDel(self, n1, edge, n2):
1402
1433
 
1403
- async def runEdgeDel(self, n1, edge, n2, view=None):
1404
- if not n1.snap.trigson:
1434
+ if self.core.migration:
1405
1435
  return
1406
1436
 
1407
- if view is None:
1408
- view = self.iden
1409
-
1410
- await self.triggers.runEdgeDel(n1, edge, n2, view=view)
1437
+ await self.triggers.runEdgeDel(n1, edge, n2)
1411
1438
 
1412
1439
  async def addTrigger(self, tdef):
1413
1440
  '''
@@ -11,7 +11,7 @@ class EconModule(s_module.CoreModule):
11
11
  'doc': 'A Card Verification Value (CVV).'}),
12
12
 
13
13
  ('econ:pay:pin', ('str', {'regex': '^[0-9]{3,6}$'}), {
14
- 'doc': 'A Personal Identification Number.'}),
14
+ 'doc': 'A Personal Identification Number (PIN).'}),
15
15
 
16
16
  ('econ:pay:mii', ('int', {'min': 0, 'max': 9}), {
17
17
  'doc': 'A Major Industry Identifier (MII).'}),
@@ -41,6 +41,12 @@ class EconModule(s_module.CoreModule):
41
41
  ('econ:acct:balance', ('guid', {}), {
42
42
  'doc': 'A snapshot of the balance of an account at a point in time.'}),
43
43
 
44
+ ('econ:acct:receipt', ('guid', {}), {
45
+ 'doc': 'A receipt issued as proof of payment.'}),
46
+
47
+ ('econ:acct:invoice', ('guid', {}), {
48
+ 'doc': 'An invoice issued requesting payment.'}),
49
+
44
50
  ('econ:price', ('hugenum', {'norm': False}), {
45
51
  'doc': 'The amount of money expected, required, or given in payment for something',
46
52
  'ex': '2.20'}),
@@ -61,15 +67,34 @@ class EconModule(s_module.CoreModule):
61
67
  ('econ:fin:tick', ('guid', {}), {
62
68
  'doc': 'A sample of the price of a security at a single moment in time'}),
63
69
 
64
- # econ:acct:bill
65
- # econ:bank:us:aba:rtn ( ABA Routing Number )
66
- # econ:bank:us:account = (econ:bank:us:aba:rtn, acct)
67
- # econ:bank:swift:...
70
+ ('econ:bank:account:type:taxonomy', ('taxonomy', {}), {
71
+ 'doc': 'A bank account type taxonomy.'}),
72
+
73
+ ('econ:bank:account', ('guid', {}), {
74
+ 'doc': 'A bank account.'}),
75
+
76
+ ('econ:bank:balance', ('guid', {}), {
77
+ 'doc': 'A balance contained by a bank account at a point in time.'}),
78
+
79
+ ('econ:bank:statement', ('guid', {}), {
80
+ 'doc': 'A statement of bank account payment activity over a period of time.'}),
81
+
82
+ ('econ:bank:aba:rtn', ('str', {'regex': '[0-9]{9}'}), {
83
+ 'doc': 'An American Bank Association (ABA) routing transit number (RTN).'}),
84
+
85
+ ('econ:bank:iban', ('str', {'regex': '[A-Z]{2}[0-9]{2}[a-zA-Z0-9]{1,30}'}), {
86
+ 'doc': 'An International Bank Account Number.'}),
87
+
88
+ ('econ:bank:swift:bic', ('str', {'regex': '[A-Z]{6}[A-Z0-9]{5}'}), {
89
+ 'doc': 'A Society for Worldwide Interbank Financial Telecommunication (SWIFT) Business Identifier Code (BIC).'}),
68
90
  ),
69
91
 
70
92
  'edges': (
71
93
  (('econ:purchase', 'acquired', None), {
72
94
  'doc': 'The purchase was used to acquire the target node.'}),
95
+
96
+ (('econ:bank:statement', 'has', 'econ:acct:payment'), {
97
+ 'doc': 'The bank statement includes the payment.'}),
73
98
  ),
74
99
 
75
100
  'forms': (
@@ -105,6 +130,12 @@ class EconModule(s_module.CoreModule):
105
130
 
106
131
  ('pin', ('econ:pay:pin', {}), {
107
132
  'doc': 'The Personal Identification Number on the card.'}),
133
+
134
+ ('account', ('econ:bank:account', {}), {
135
+ 'doc': 'A bank account associated with the payment card.'}),
136
+
137
+ ('contact', ('ps:contact', {}), {
138
+ 'doc': 'The contact information associated with the payment card.'}),
108
139
  )),
109
140
 
110
141
  ('econ:purchase', {}, (
@@ -171,6 +202,9 @@ class EconModule(s_module.CoreModule):
171
202
  ('fee', ('econ:price', {}), {
172
203
  'doc': 'The transaction fee paid by the recipient to the payment processor.'}),
173
204
 
205
+ ('from:account', ('econ:bank:account', {}), {
206
+ 'doc': 'The bank account which made the payment.'}),
207
+
174
208
  ('from:pay:card', ('econ:pay:card', {}), {
175
209
  'doc': 'The payment card making the payment.'}),
176
210
 
@@ -183,6 +217,9 @@ class EconModule(s_module.CoreModule):
183
217
  ('from:contact', ('ps:contact', {}), {
184
218
  'doc': 'Contact information for the entity making the payment.'}),
185
219
 
220
+ ('to:account', ('econ:bank:account', {}), {
221
+ 'doc': 'The bank account which received the payment.'}),
222
+
186
223
  ('to:coinaddr', ('crypto:currency:address', {}), {
187
224
  'doc': 'The crypto currency address receiving the payment.'}),
188
225
 
@@ -210,6 +247,12 @@ class EconModule(s_module.CoreModule):
210
247
  ('crypto:transaction', ('crypto:currency:transaction', {}), {
211
248
  'doc': 'A crypto currency transaction that initiated the payment.'}),
212
249
 
250
+ ('invoice', ('econ:acct:invoice', {}), {
251
+ 'doc': 'The invoice that the payment applies to.'}),
252
+
253
+ ('receipt', ('econ:acct:receipt', {}), {
254
+ 'doc': 'The receipt that was issued for the payment.'}),
255
+
213
256
  )),
214
257
 
215
258
  ('econ:acct:balance', {}, (
@@ -296,5 +339,131 @@ class EconModule(s_module.CoreModule):
296
339
  ('price:high', ('econ:price', {}), {
297
340
  'doc': 'The high price of the security'}),
298
341
  )),
342
+
343
+ ('econ:acct:invoice', {}, (
344
+
345
+ ('issued', ('time', {}), {
346
+ 'doc': 'The time that the invoice was issued to the recipient.'}),
347
+
348
+ ('issuer', ('ps:contact', {}), {
349
+ 'doc': 'The contact information for the entity who issued the invoice.'}),
350
+
351
+ ('purchase', ('econ:purchase', {}), {
352
+ 'doc': 'The purchase that the invoice is requesting payment for.'}),
353
+
354
+ ('recipient', ('ps:contact', {}), {
355
+ 'doc': 'The contact information for the intended recipient of the invoice.'}),
356
+
357
+ ('due', ('time', {}), {
358
+ 'doc': 'The time by which the payment is due.'}),
359
+
360
+ ('paid', ('bool', {}), {
361
+ 'doc': 'Set to true if the invoice has been paid in full.'}),
362
+
363
+ ('amount', ('econ:price', {}), {
364
+ 'doc': 'The balance due.'}),
365
+
366
+ ('currency', ('econ:currency', {}), {
367
+ 'doc': 'The currency that the invoice specifies for payment.'}),
368
+ )),
369
+
370
+ ('econ:acct:receipt', {}, (
371
+
372
+ ('issued', ('time', {}), {
373
+ 'doc': 'The time the receipt was issued.'}),
374
+
375
+ ('purchase', ('econ:purchase', {}), {
376
+ 'doc': 'The purchase that the receipt confirms payment for.'}),
377
+
378
+ ('issuer', ('ps:contact', {}), {
379
+ 'doc': 'The contact information for the entity who issued the receipt.'}),
380
+
381
+ ('recipient', ('ps:contact', {}), {
382
+ 'doc': 'The contact information for the entity who received the receipt.'}),
383
+
384
+ ('currency', ('econ:currency', {}), {
385
+ 'doc': 'The currency that the receipt uses to specify the price.'}),
386
+
387
+ ('amount', ('econ:price', {}), {
388
+ 'doc': 'The price that the receipt confirms was paid.'}),
389
+ )),
390
+
391
+ ('econ:bank:aba:rtn', {}, (
392
+
393
+ ('bank', ('ou:org', {}), {
394
+ 'doc': 'The bank which was issued the ABA RTN.'}),
395
+
396
+ ('bank:name', ('ou:name', {}), {
397
+ 'doc': 'The name which is registered for this ABA RTN.'}),
398
+
399
+ )),
400
+
401
+ ('econ:bank:iban', {}, ()),
402
+
403
+ ('econ:bank:swift:bic', {}, (
404
+
405
+ ('business', ('ou:org', {}), {
406
+ 'doc': 'The business which is the registered owner of the SWIFT BIC.'}),
407
+
408
+ ('office', ('ps:contact', {}), {
409
+ 'doc': 'The branch or office which is specified in the last 3 digits of the SWIFT BIC.'}),
410
+ )),
411
+
412
+ ('econ:bank:account:type:taxonomy', {}, ()),
413
+ ('econ:bank:account', {}, (
414
+
415
+ ('type', ('econ:bank:account:type:taxonomy', {}), {
416
+ 'doc': 'The type of bank account.'}),
417
+
418
+ ('aba:rtn', ('econ:bank:aba:rtn', {}), {
419
+ 'doc': 'The ABA routing transit number for the bank which issued the account.'}),
420
+
421
+ ('number', ('str', {'regex': '[0-9]+'}), {
422
+ 'doc': 'The account number.'}),
423
+
424
+ ('iban', ('econ:bank:iban', {}), {
425
+ 'doc': 'The IBAN for the account.'}),
426
+
427
+ ('contact', ('ps:contact', {}), {
428
+ 'doc': 'The contact information associated with the bank account.'}),
429
+
430
+ ('issuer', ('ou:org', {}), {
431
+ 'doc': 'The bank which issued the account.'}),
432
+
433
+ ('issuer:name', ('ou:name', {}), {
434
+ 'doc': 'The name of the bank which issued the account.'}),
435
+
436
+ ('currency', ('econ:currency', {}), {
437
+ 'doc': 'The currency of the account balance.'}),
438
+
439
+ ('balance', ('econ:bank:balance', {}), {
440
+ 'doc': 'The most recently known bank balance information.'}),
441
+ )),
442
+
443
+ ('econ:bank:balance', {}, (
444
+
445
+ ('time', ('time', {}), {
446
+ 'doc': 'The time that the account balance was observed.'}),
447
+
448
+ ('amount', ('econ:price', {}), {
449
+ 'doc': 'The amount of currency available at the time.'}),
450
+
451
+ ('account', ('econ:bank:account', {}), {
452
+ 'doc': 'The bank account which contained the balance amount.'}),
453
+ )),
454
+ ('econ:bank:statement', {}, (
455
+
456
+ ('account', ('econ:bank:account', {}), {
457
+ 'doc': 'The bank account used to compute the statement.'}),
458
+
459
+ ('period', ('ival', {}), {
460
+ 'doc': 'The period that the statement includes.'}),
461
+
462
+ ('starting:balance', ('econ:price', {}), {
463
+ 'doc': 'The account balance at the beginning of the statement period.'}),
464
+
465
+ ('ending:balance', ('econ:price', {}), {
466
+ 'doc': 'The account balance at the end of the statement period.'}),
467
+ )),
299
468
  ),
300
469
  }),)
synapse/models/files.py CHANGED
@@ -256,6 +256,8 @@ class FileModule(s_module.CoreModule):
256
256
  'doc': 'MIME specific lat/long information extracted from metadata.'}),
257
257
  ('altitude', ('geo:altitude', {}), {
258
258
  'doc': 'MIME specific altitude information extracted from metadata.'}),
259
+ ('text', ('str', {'lower': True, 'onespace': True}), {
260
+ 'doc': 'The text contained within the image.'}),
259
261
  ),
260
262
  'doc': 'Properties common to image file formats.',
261
263
  'interfaces': ('file:mime:meta',),