eva-shell 0.2.35__tar.gz → 0.2.37__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eva-shell
3
- Version: 0.2.35
3
+ Version: 0.2.37
4
4
  Summary: EVA ICS v4 shell
5
5
  Home-page: https://github.com/eva-ics/eva4
6
6
  Author: Bohemia Automation / Altertech
@@ -1,3 +1,3 @@
1
- __version__ = '0.2.35'
1
+ __version__ = '0.2.37'
2
2
 
3
3
  DEFAULT_REPOSITORY_URL = 'https://pub.bma.ai/eva4'
@@ -17,7 +17,7 @@ from .compl import ComplOIDtp, ComplSvcRpcMethod, ComplSvcRpcParams, ComplEdit
17
17
  from .client import call_rpc, DEFAULT_DB_SERVICE, DEFAULT_REPL_SERVICE
18
18
  from .client import DEFAULT_ACL_SERVICE, DEFAULT_AUTH_SERVICE
19
19
  from .client import DEFAULT_KIOSK_SERVICE, DEFAULT_GENERATOR_SERVICE
20
- from .client import DEFAULT_ACCOUNTING_SERVICE, DEFAULT_ALARM_SERVICE
20
+ from .client import DEFAULT_ACCOUNTING_SERVICE, DEFAULT_ALARM_SERVICE, DEFAULT_VIDEO_SERVICE
21
21
 
22
22
  ALARM_OP_CODES = [
23
23
  'TT', 'TL', 'LL', 'SS', 'SD', 'OS', 'CC', 'AA', 'US', 'RD', 'IS'
@@ -481,6 +481,10 @@ def append_svc_cli(root_sp):
481
481
  metavar='FILE',
482
482
  help='read call params payload form the file ("-" for stdin)'
483
483
  ).completer = ComplDeployFile()
484
+ p.add_argument('-o', '--output', metavar='FILE', help='output file')
485
+ p.add_argument('--passthrough',
486
+ action='store_true',
487
+ help='do not unpack the result (requires the output file)')
484
488
  p.add_argument('method', metavar='METHOD').completer = ComplSvcRpcMethod()
485
489
  p.add_argument(
486
490
  'params',
@@ -1179,6 +1183,94 @@ def append_cloud_cli(root_sp):
1179
1183
  help='update without any confirmations',
1180
1184
  action='store_true')
1181
1185
 
1186
+ def append_video_cli(root_sp):
1187
+ ap_generator = root_sp.add_parser('video', help='video commands')
1188
+ sp_generator = ap_generator.add_subparsers(dest='_subc', help='sub command')
1189
+
1190
+ ap = sp_generator.add_parser('rec', help='video recordings')
1191
+ sp = ap.add_subparsers(dest='_subc2', help='sub command')
1192
+
1193
+ p = sp.add_parser('create', help='create a video recording')
1194
+ p.add_argument('i', metavar='source')
1195
+ p.add_argument('--keep',
1196
+ type=float,
1197
+ help='Keep (seconds)')
1198
+ p.add_argument('--enabled',
1199
+ help='Enable recording',
1200
+ action='store_true')
1201
+ p.add_argument(
1202
+ '-a',
1203
+ '--video-svc',
1204
+ help=f'video service (default: {DEFAULT_VIDEO_SERVICE})',
1205
+ default=DEFAULT_VIDEO_SERVICE).completer = ComplSvc('videosrv')
1206
+
1207
+ p = sp.add_parser('list', help='list video recordings')
1208
+ p.add_argument(
1209
+ '-a',
1210
+ '--video-svc',
1211
+ help=f'video service (default: {DEFAULT_VIDEO_SERVICE})',
1212
+ default=DEFAULT_VIDEO_SERVICE).completer = ComplSvc('videosrv')
1213
+
1214
+ p = sp.add_parser('edit', help='edit a video recording config')
1215
+ p.add_argument('i', metavar='source')
1216
+ p.add_argument(
1217
+ '-a',
1218
+ '--video-svc',
1219
+ help=f'video service (default: {DEFAULT_VIDEO_SERVICE})',
1220
+ default=DEFAULT_VIDEO_SERVICE).completer = ComplSvc('videosrv')
1221
+
1222
+ p = sp.add_parser('enable', help='enable (start) a video recording')
1223
+ p.add_argument('i', metavar='source')
1224
+ p.add_argument(
1225
+ '-a',
1226
+ '--video-svc',
1227
+ help=f'video service (default: {DEFAULT_VIDEO_SERVICE})',
1228
+ default=DEFAULT_VIDEO_SERVICE).completer = ComplSvc('videosrv')
1229
+
1230
+ p = sp.add_parser('disable', help='disable (stop) a video recording')
1231
+ p.add_argument('i', metavar='source')
1232
+ p.add_argument(
1233
+ '-a',
1234
+ '--video-svc',
1235
+ help=f'video service (default: {DEFAULT_VIDEO_SERVICE})',
1236
+ default=DEFAULT_VIDEO_SERVICE).completer = ComplSvc('videosrv')
1237
+
1238
+ p = sp.add_parser('destroy', help='destroy a video recording')
1239
+ p.add_argument('i', metavar='source')
1240
+ p.add_argument(
1241
+ '-a',
1242
+ '--video-svc',
1243
+ help=f'video service (default: {DEFAULT_VIDEO_SERVICE})',
1244
+ default=DEFAULT_VIDEO_SERVICE).completer = ComplSvc('videosrv')
1245
+
1246
+ p = sp.add_parser('export', help='export video recording config(s) to a deployment file')
1247
+ p.add_argument('i', metavar='MASK')
1248
+ p.add_argument(
1249
+ '-a',
1250
+ '--video-svc',
1251
+ help=f'video service (default: {DEFAULT_VIDEO_SERVICE})',
1252
+ default=DEFAULT_VIDEO_SERVICE).completer = ComplSvc('videosrv')
1253
+ p.add_argument('-o', '--output', metavar='FILE',
1254
+ help='output file').completer = ComplDeployFile()
1255
+
1256
+ p = sp.add_parser('deploy', help='deploy video recording(s) from a deployment file')
1257
+ p.add_argument(
1258
+ '-a',
1259
+ '--video-svc',
1260
+ help=f'video service (default: {DEFAULT_VIDEO_SERVICE})',
1261
+ default=DEFAULT_VIDEO_SERVICE).completer = ComplSvc('generator')
1262
+ p.add_argument('-f', '--file', metavar='FILE',
1263
+ help='deployment file').completer = ComplDeployFile()
1264
+
1265
+ p = sp.add_parser('undeploy',
1266
+ help='undeploy video recordings(s) using a deployment file')
1267
+ p.add_argument(
1268
+ '-a',
1269
+ '--video-svc',
1270
+ help=f'video service (default: {DEFAULT_VIDEO_SERVICE})',
1271
+ default=DEFAULT_VIDEO_SERVICE).completer = ComplSvc('generator')
1272
+ p.add_argument('-f', '--file', metavar='FILE',
1273
+ help='deployment file').completer = ComplDeployFile()
1182
1274
 
1183
1275
  def append_generator_cli(root_sp):
1184
1276
  source_types = [
@@ -1585,6 +1677,7 @@ def init_ap():
1585
1677
  'lvar': [],
1586
1678
  'mirror': [],
1587
1679
  'node': [],
1680
+ 'video': [],
1588
1681
  'server': [],
1589
1682
  'spoint': [],
1590
1683
  'system': [],
@@ -1623,6 +1716,7 @@ def init_ap():
1623
1716
  if is_local_shell():
1624
1717
  append_mirror_cli(sp)
1625
1718
  append_node_cli(sp)
1719
+ append_video_cli(sp)
1626
1720
  if is_local_shell():
1627
1721
  append_server_cli(sp)
1628
1722
  append_spoint_cli(sp)
@@ -669,7 +669,14 @@ class CLI:
669
669
  call_rpc('svc.purge', dict(svcs=[i]))
670
670
  ok()
671
671
 
672
- def svc_call(self, i, file, method, params, trace=False):
672
+ def svc_call(self,
673
+ i,
674
+ file,
675
+ output,
676
+ passthrough,
677
+ method,
678
+ params,
679
+ trace=False):
673
680
  if file:
674
681
  import yaml
675
682
  payload = yaml.safe_load(read_file(file))
@@ -678,11 +685,22 @@ class CLI:
678
685
  for p in params:
679
686
  n, v = p.split('=', 1)
680
687
  payload[n] = format_value(v, advanced=True, name=n)
688
+ if passthrough and not output:
689
+ raise ValueError(
690
+ 'output file is required when passthrought is enabled')
681
691
  result = call_rpc(method,
682
692
  payload if payload else None,
683
693
  target=i,
684
- trace=trace)
685
- if current_command.json or isinstance(result, list):
694
+ trace=trace,
695
+ unpack_result=not passthrough)
696
+ if passthrough:
697
+ write_file(output, result, mode='wb')
698
+ ok()
699
+ elif output:
700
+ import json
701
+ write_file(output, json.dumps(result, indent=4, sort_keys=True))
702
+ ok()
703
+ elif current_command.json or isinstance(result, list):
686
704
  print_result(result)
687
705
  elif isinstance(result, dict):
688
706
  print_result(result, name_value=True)
@@ -1689,6 +1707,99 @@ class CLI:
1689
1707
  call_rpc('kiosk.dev_close', dict(i=i), target=kiosk_svc)
1690
1708
  ok()
1691
1709
 
1710
+ def video_rec_list(self, video_svc):
1711
+ data = call_rpc('rec.list', target=video_svc)
1712
+ print_result(data, cols=['oid', 'keep', 'enabled'])
1713
+
1714
+ def video_rec_create(self, i, keep, enabled, video_svc):
1715
+ payload = {
1716
+ 'oid': i,
1717
+ }
1718
+ if keep:
1719
+ payload['keep'] = keep
1720
+ if enabled:
1721
+ payload['enabled'] = enabled
1722
+ call_rpc('rec.deploy',
1723
+ dict(video_recordings=[payload]),
1724
+ target=video_svc)
1725
+ ok()
1726
+
1727
+ def video_rec_destroy(self, i, video_svc):
1728
+ payload = {
1729
+ 'oid': i,
1730
+ }
1731
+ call_rpc('rec.undeploy',
1732
+ dict(video_recordings=[payload]),
1733
+ target=video_svc)
1734
+ ok()
1735
+
1736
+ def video_rec_enable(self, i, video_svc):
1737
+ call_rpc('rec.enable', dict(i=i), target=video_svc)
1738
+ ok()
1739
+
1740
+ def video_rec_disable(self, i, video_svc):
1741
+ call_rpc('rec.disable', dict(i=i), target=video_svc)
1742
+ ok()
1743
+
1744
+ def video_rec_edit(self, i, video_svc):
1745
+
1746
+ def deploy(cfg, i):
1747
+ call_rpc('rec.deploy',
1748
+ dict(video_recordings=[cfg]),
1749
+ target=video_svc)
1750
+ print(f'video recording config re-deployed: {i}')
1751
+ print()
1752
+
1753
+ config = call_rpc('rec.get_config', dict(i=i), target=video_svc)
1754
+ edit_config(config,
1755
+ f'video.rec|{i}|config',
1756
+ deploy_fn=partial(deploy, i=i))
1757
+
1758
+ def video_rec_export(self, i, video_svc, output=None):
1759
+ c = 0
1760
+ configs = []
1761
+ for source in call_rpc('rec.list', target=video_svc):
1762
+ oid = source['oid']
1763
+ if (i.startswith('*') and oid.endswith(i[1:])) or \
1764
+ (i.endswith('*') and oid.startswith(i[:-1])) or \
1765
+ (i.startswith('*') and i.endswith('*') and i[1:-1] in oid) or \
1766
+ i == oid:
1767
+ c += 1
1768
+ config = call_rpc('rec.get_config',
1769
+ dict(i=oid),
1770
+ target=video_svc)
1771
+ configs.append(config)
1772
+ result = dict(video_recordings=configs)
1773
+ if current_command.json:
1774
+ print_result(result)
1775
+ else:
1776
+ import yaml
1777
+ dump = yaml.dump(result, default_flow_style=False)
1778
+ if output is None:
1779
+ print(dump)
1780
+ else:
1781
+ write_file(output, dump)
1782
+ print(f'{c} video recording configuration(s) exported')
1783
+ print()
1784
+
1785
+ def video_rec_deploy(self, video_svc, file=None):
1786
+ import yaml
1787
+ sources = yaml.safe_load(
1788
+ read_file(file).decode()).pop('video_recordings')
1789
+ call_rpc('rec.deploy', dict(video_recordings=sources), target=video_svc)
1790
+ print(f'{len(sources)} video recording configuration(s) deployed')
1791
+ print()
1792
+
1793
+ def video_rec_undeploy(self, video_svc, file=None):
1794
+ import yaml
1795
+ sources = yaml.safe_load(
1796
+ read_file(file).decode()).pop('video_recordings')
1797
+ call_rpc('rec.undeploy',
1798
+ dict(video_recordings=sources),
1799
+ target=video_svc)
1800
+ print(f'{len(sources)} video recording configuration(s) undeployed')
1801
+ print()
1802
+
1692
1803
  def generator_source_list(self, generator_svc):
1693
1804
  data = call_rpc('source.list', target=generator_svc)
1694
1805
  print_result(data, cols=['name', 'kind', 'active'])
@@ -16,9 +16,11 @@ DEFAULT_ACL_SERVICE = 'eva.aaa.acl'
16
16
  DEFAULT_AUTH_SERVICE = 'eva.aaa.localauth'
17
17
  DEFAULT_KIOSK_SERVICE = 'eva.kioskman.default'
18
18
  DEFAULT_GENERATOR_SERVICE = 'eva.generator.default'
19
+ DEFAULT_VIDEO_SERVICE = 'eva.videosrv.default'
19
20
  DEFAULT_ACCOUNTING_SERVICE = 'eva.aaa.accounting'
20
21
  DEFAULT_ALARM_SERVICE = 'eva.alarm.default'
21
22
 
23
+
22
24
  def print_trace_msg(msg):
23
25
  level = msg['l']
24
26
  print('[', end='')
@@ -53,7 +55,7 @@ def connect():
53
55
  common.rpc.on_frame = on_frame
54
56
 
55
57
 
56
- def call_rpc(method, params=None, target='eva.core', trace=False):
58
+ def call_rpc(method, params=None, target='eva.core', trace=False, unpack_result=True):
57
59
  common.bus_conn_no += 1
58
60
  connect()
59
61
  if current_command.debug:
@@ -85,5 +87,7 @@ def call_rpc(method, params=None, target='eva.core', trace=False):
85
87
  print()
86
88
  if result.is_empty():
87
89
  return None
88
- else:
90
+ elif unpack_result:
89
91
  return unpack(result.get_payload())
92
+ else:
93
+ return result.get_payload()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eva-shell
3
- Version: 0.2.35
3
+ Version: 0.2.37
4
4
  Summary: EVA ICS v4 shell
5
5
  Home-page: https://github.com/eva-ics/eva4
6
6
  Author: Bohemia Automation / Altertech
@@ -1,4 +1,4 @@
1
- __version__ = '0.2.35'
1
+ __version__ = '0.2.37'
2
2
 
3
3
  import setuptools
4
4
 
File without changes
File without changes
File without changes
File without changes