pyx3270 0.1.2__py3-none-any.whl → 0.1.3__py3-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.
pyx3270/__init__.py CHANGED
@@ -16,5 +16,5 @@ from pyx3270.emulator import X3270
16
16
  from pyx3270.offline import PyX3270Manager
17
17
 
18
18
  __author__ = 'MatheusLPolidoro'
19
- __version__ = '0.1.2'
19
+ __version__ = '0.1.3'
20
20
  __all__ = ['X3270', 'replay', 'record', 'PyX3270Manager']
pyx3270/bin/start.bin CHANGED
Binary file
pyx3270/bin/start.bin.bak CHANGED
Binary file
pyx3270/emulator.py CHANGED
@@ -5,12 +5,14 @@ import os
5
5
  import re
6
6
  import socket
7
7
  import subprocess
8
+ import sys
8
9
  from contextlib import closing
9
10
  from functools import cache
11
+ from importlib.resources import files
10
12
  from logging import getLogger
11
13
  from time import sleep, time
12
14
  from typing import Literal
13
- from pyx3270.x3270_commands import x3270_command
15
+
14
16
  from pyx3270.exceptions import (
15
17
  CommandError,
16
18
  FieldTruncateError,
@@ -25,10 +27,25 @@ from pyx3270.iemulator import (
25
27
  AbstractExecutableApp,
26
28
  )
27
29
  from pyx3270.logging_config import LOGGING_CONFIG
30
+ from pyx3270.x3270_commands import x3270_command
28
31
 
29
32
  logger = getLogger(__name__)
30
33
 
31
- BINARY_FOLDER = os.path.join(os.path.dirname(__file__), 'bin')
34
+
35
+ def get_binary_path(*parts):
36
+ # Se estiver rodando como executável PyInstaller
37
+ if hasattr(sys, '_MEIPASS'):
38
+ return os.path.join(sys._MEIPASS, 'pyx3270', 'bin', *parts)
39
+
40
+ # Se estiver rodando como pacote instalado normalmente
41
+ try:
42
+ bin_dir = files('pyx3270').joinpath('bin')
43
+ return str(bin_dir.joinpath(*parts))
44
+ except Exception as e:
45
+ raise FileNotFoundError(f'Não foi possível localizar o binário: {e}')
46
+
47
+
48
+ BINARY_FOLDER = get_binary_path()
32
49
  MODEL_TYPE = Literal['2', '3', '4', '5']
33
50
  MODEL_DIMENSIONS = {
34
51
  '2': {
@@ -196,7 +213,7 @@ class Command(AbstractCommand):
196
213
  error_msg = msg.decode('utf-8')
197
214
 
198
215
  if (
199
- 'keyboard locked' in error_msg.lower()
216
+ 'keyboard locked' in error_msg.lower()
200
217
  or 'canceled' in error_msg.lower()
201
218
  ):
202
219
  logger.error(f'Teclado travado detectado: {error_msg}')
@@ -303,7 +320,7 @@ class Wc3270App(ExecutableApp):
303
320
  'start',
304
321
  '/wait',
305
322
  '""',
306
- f'"{os.path.join(BINARY_FOLDER, "windows/wc3270")}"',
323
+ f'"{get_binary_path("windows", "wc3270")}"',
307
324
  ] + self.args
308
325
  self.args.extend(['-scriptport', str(self.script_port), host])
309
326
  logger.debug(f'Argumentos completos: {self.args}')
@@ -353,7 +370,7 @@ class Wc3270App(ExecutableApp):
353
370
 
354
371
  class Ws3270App(ExecutableApp):
355
372
  args = [
356
- os.path.join(BINARY_FOLDER, 'windows/ws3270'),
373
+ f'"{get_binary_path("windows", "ws3270")}"',
357
374
  '-xrm',
358
375
  'ws3270.unlockDelay:False',
359
376
  ]
@@ -365,8 +382,7 @@ class Ws3270App(ExecutableApp):
365
382
 
366
383
  class X3270App(ExecutableApp):
367
384
  args = [
368
- os.path.join(BINARY_FOLDER, 'linux/x3270'),
369
- # 'x3270',
385
+ get_binary_path('linux', 'x3270'),
370
386
  '-xrm',
371
387
  'x3270.unlockDelay:False',
372
388
  '-script',
@@ -379,7 +395,7 @@ class X3270App(ExecutableApp):
379
395
 
380
396
  class S3270App(ExecutableApp):
381
397
  args = [
382
- os.path.join(BINARY_FOLDER, 'linux/s3270'),
398
+ get_binary_path('linux', 's3270'),
383
399
  '-xrm',
384
400
  's3270.unlockDelay:False',
385
401
  ]
@@ -397,6 +413,7 @@ class X3270Cmd(AbstractEmulatorCmd):
397
413
  def __getattr__(self, name):
398
414
  def x3270_builtin_func(*args, **kwargs):
399
415
  return x3270_command(self, name, *args, **kwargs)
416
+
400
417
  return x3270_builtin_func
401
418
 
402
419
  def clear_screen(self) -> None:
@@ -812,7 +829,7 @@ class X3270(AbstractEmulator, X3270Cmd):
812
829
  host: str,
813
830
  port: int | str,
814
831
  tls: bool = True,
815
- mode_3270: bool = True
832
+ mode_3270: bool = True,
816
833
  ) -> None:
817
834
  logger.info(f'Conectando ao host: {host}:{port} (tls={tls})')
818
835
  self.host = host
@@ -0,0 +1,5 @@
1
+ import os
2
+
3
+
4
+ def get_hook_dirs():
5
+ return [os.path.dirname(__file__)]
@@ -0,0 +1,26 @@
1
+ import os
2
+ from PyInstaller.utils.hooks import get_package_paths
3
+
4
+ print(">> Hook pyx3270 executado")
5
+
6
+ # Caminho do pacote instalado
7
+ package_path, _ = get_package_paths('pyx3270')
8
+
9
+ # Caminho da pasta bin dentro do pacote
10
+ bin_dir = os.path.join(package_path, 'pyx3270', 'bin')
11
+
12
+ datas = []
13
+
14
+ if os.path.isdir(bin_dir):
15
+ for root, _, files in os.walk(bin_dir):
16
+ for file in files:
17
+ full_path = os.path.join(root, file)
18
+ # Caminho relativo a partir da pasta bin (ex: windows/wc3270.exe)
19
+ rel_path = os.path.relpath(full_path, bin_dir)
20
+ # Corrige o destino para ser uma pasta, não um arquivo
21
+ target_dir = os.path.join('pyx3270', 'bin', os.path.dirname(rel_path))
22
+ datas.append((full_path, target_dir))
23
+ else:
24
+ print(f">> Pasta bin não encontrada em: {bin_dir}")
25
+
26
+ __all__ = ['datas']
pyx3270/offline.py CHANGED
@@ -28,7 +28,7 @@ class PyX3270Manager:
28
28
  stdout=subprocess.DEVNULL,
29
29
  stderr=subprocess.DEVNULL,
30
30
  text=True,
31
- bufsize=0
31
+ bufsize=0,
32
32
  )
33
33
 
34
34
  def _exec(self, command: str) -> None:
@@ -40,11 +40,11 @@ class PyX3270Manager:
40
40
 
41
41
  logger.info(f'[+] Enviando comando offline: {command}')
42
42
  try:
43
- self.process.stdin.write(f"{command}\n")
43
+ self.process.stdin.write(f'{command}\n')
44
44
  self.process.stdin.flush()
45
45
  sleep(0.05)
46
46
  except Exception as e:
47
- logger.error(f"Erro ao enviar comando: {e}")
47
+ logger.error(f'Erro ao enviar comando: {e}')
48
48
  return
49
49
  self.emu.pf(1)
50
50
  sleep(0.1)
pyx3270/server.py CHANGED
@@ -216,7 +216,7 @@ def record_handler(
216
216
  )
217
217
  save = False
218
218
  screens.append(buffer)
219
- record_data(full_block, record_dir, counter)
219
+ counter += record_data(full_block, record_dir, counter)
220
220
 
221
221
  except (ConnectionResetError, OSError, NotConnectedException):
222
222
  logger.info('[!] Conexão encerrada pelo servidor ou erro de rede.')
pyx3270/x3270_commands.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import functools
2
- from typing import Any
3
2
  import warnings
3
+ from typing import Any
4
+
4
5
 
5
6
  def x3270_builtins_class(cls):
6
7
  """Decorador de classe que aplica x3270_builtins a todos os métodos."""
@@ -17,6 +18,7 @@ def _wrap_method(method):
17
18
  @functools.wraps(method)
18
19
  def wrapper(self, *args, **kwargs):
19
20
  return x3270_command(self, method.__name__, *args, **kwargs)
21
+
20
22
  return wrapper
21
23
 
22
24
 
@@ -29,7 +31,7 @@ def x3270_command(em, func, *args, **kwargs):
29
31
  warnings.warn(
30
32
  f'`{func}` foi descontinuada, use `send_string`'
31
33
  f' com argumento `password=True`.',
32
- DeprecationWarning
34
+ DeprecationWarning,
33
35
  )
34
36
  return em.send_string(*args, **kwargs, password=True)
35
37
 
@@ -37,7 +39,7 @@ def x3270_command(em, func, *args, **kwargs):
37
39
  if not all_args_str:
38
40
  warnings.warn(
39
41
  f'`{func}` foi descontinuada, use `send_pf` com argumento.',
40
- DeprecationWarning
42
+ DeprecationWarning,
41
43
  )
42
44
  all_args_str = func[-1]
43
45
 
@@ -47,7 +49,7 @@ def x3270_command(em, func, *args, **kwargs):
47
49
 
48
50
  if func == 'connect' and (len(args) + len(kwargs)) > 1:
49
51
  return em.connect_host(*args, **kwargs)
50
-
52
+
51
53
  try:
52
54
  cmd = em._exec_command(f'{func}({all_args_str})'.encode('utf8'))
53
55
  try:
@@ -83,7 +85,9 @@ class X3270Commands:
83
85
  def compose(
84
86
  self,
85
87
  ) -> Any: ... # Interpreta as próximas duas teclas conforme o mapa.
86
- def connect(self, host: str, port: str | None = None) -> Any: ... # Conecta ao host.
88
+ def connect(
89
+ self, host: str, port: str | None = None
90
+ ) -> Any: ... # Conecta ao host.
87
91
  def cursorselect(
88
92
  self,
89
93
  ) -> Any: ... # Seleciona local do cursor como caneta luminosa.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyx3270
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Uma interface comum utilizada para automações de terminais 3270 da IBM.
5
5
  Author-email: MatheusLPolidoro <mattpolidoro4@gmail.com>
6
6
  Project-URL: Documentation, https://matheuslpolidoro.github.io/pyx3270/
@@ -1,33 +1,35 @@
1
1
  docs/gen_tree.py,sha256=DQbnAfFVeeMT2mZMzByKVdM1Qm_O0q3mRrzKqKfSQ5M,11374
2
- pyx3270/__init__.py,sha256=bsBQIbLWS178qZHTY-JjkhXXEH5lPGAXn3-sUVelSXE,1226
2
+ pyx3270/__init__.py,sha256=lj-5NGfO6AmSKLTxftIw6eYjlYwg48h3vIKULZp77Os,1226
3
3
  pyx3270/__main__.py,sha256=YyGX6Wbn7bgOvXjHIeGf8Z2so8MEtXXMRcaJnqR8tU4,70
4
4
  pyx3270/cli.py,sha256=_Vrmg-p1i889q9zS-k7IBS6_OHDMWtTt2b6-Mx5Esdk,4571
5
- pyx3270/emulator.py,sha256=F_yzaBTljIlHHmXPkSUQajsKU9kSCVb_CsN4A3SrraY,31376
5
+ pyx3270/emulator.py,sha256=zDKKYf8Ghz39zGVita1VI6aOAdB6rzYIUu86RJLJkUo,31827
6
6
  pyx3270/exceptions.py,sha256=TtM9LugE5m4E01vI9PnzCE-BRMqigiWvoeGTLTDDbfo,607
7
7
  pyx3270/iemulator.py,sha256=tVEFNlZMSww2LsfdXZgmg2XJtT716uGvOHyU7G_UXBU,3081
8
8
  pyx3270/logging_config.py,sha256=k5sYSlaAe-_hkMR2V37eXRiQ4aPNRm6R7az1iEZ4IH4,1667
9
- pyx3270/offline.py,sha256=Wh6matJqi3piGGjZgM2YTDlRAWQw772f6D_RKX3Icwc,2880
9
+ pyx3270/offline.py,sha256=_ye3KC3FIkOEwSS0EykG4hdWSuu7zgJhl4dvI5-gCVw,2881
10
10
  pyx3270/py.typed,sha256=eSgqDZOdQoML2kw4FABXkFkJeM2184WI1ojN8ed6k4Q,50
11
- pyx3270/server.py,sha256=6BqqPy1hGuwBukF4PFb2MYW-p6Qsl7Atux2V4XPAr8o,14159
11
+ pyx3270/server.py,sha256=57KufyvPAIEbKmIKdVvvoZ9eJgDqo1OPg02MMvY41IE,14170
12
12
  pyx3270/state.py,sha256=8MHyzT89IHWrXmVgbiSxvsfKSLQhsaZsXj4OOediPxA,72
13
13
  pyx3270/tn3270.py,sha256=-trKVI3uimpte6_IzYjwGv4UpGIEacKjI1knQFunNi0,6640
14
- pyx3270/x3270_commands.py,sha256=1Z84Hth3tUJiHZP1dVwhParsz92iJSMon2JyURkvMmU,9074
15
- pyx3270/bin/start.bin,sha256=PX1-T7RZoAcjYizAukHdy_YELB8iWijUGUBTM0B8k1s,831
16
- pyx3270/bin/start.bin.bak,sha256=yS2kIBpOXH_81QMLV2a6hL11wPkxwVLeKlBrU3K9YFI,831
14
+ pyx3270/x3270_commands.py,sha256=A65TZmjYakx9U8iiw60InxgVHkFc6XN2mYiFYiJQV8Y,9088
15
+ pyx3270/bin/start.bin,sha256=v1thzPr4nUjqNMlSPT9P9aY4RJuRa4mvE0b9es-cfvQ,831
16
+ pyx3270/bin/start.bin.bak,sha256=PX1-T7RZoAcjYizAukHdy_YELB8iWijUGUBTM0B8k1s,831
17
17
  pyx3270/bin/linux/s3270,sha256=urcrOyQdksRHZwngLRnSLqrRyUDGhwvvL6xfy6uzbyk,1063944
18
18
  pyx3270/bin/linux/x3270,sha256=udKhVgQZDEu6_QQ37GeoH4zZwFQaw0x7OYw80Kh6-58,1719552
19
19
  pyx3270/bin/windows/wc3270.exe,sha256=gYE5ge5cgLlwkd1R5GG2WWAlQt_veXCydb8rARtP3lI,3570888
20
20
  pyx3270/bin/windows/ws3270.exe,sha256=eearMtLt-VtQrODep-PMxLZglVR5gb7-Le6OX3-tw_E,2904696
21
+ pyx3270/hook/__init__.py,sha256=y0FL6nUHAtFJY2o_PWl1LxbvHPcwaA_Uj-tZJTlNeuc,77
22
+ pyx3270/hook/hook-pyx3270.py,sha256=7H8yyquJ_WykUksTsA5dWTjW_xgWtvVgkG-o0a8yzqA,882
21
23
  site/gen_tree.py,sha256=DQbnAfFVeeMT2mZMzByKVdM1Qm_O0q3mRrzKqKfSQ5M,11374
22
24
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
25
  tests/conftest.py,sha256=eFhdOo-a-hlbx61S2c6JUcFOHVzlf3OpCTJW-4VM0Ls,8134
24
26
  tests/test_cli.py,sha256=JW0PBFxvux0J5ZFlzhSPiIie5NqQ2Q3dti_rZt_0HtA,3200
25
27
  tests/test_emulator.py,sha256=fpmKiGN1pyEN470XstCG8EsEpnaqFrBQ76tSp5_Sdas,69346
26
28
  tests/test_exceptions.py,sha256=pvpwEUFEEju2CgBR3QPpm6wspiwzP1jp5K7gX9Pagrw,1226
27
- tests/test_offline.py,sha256=OuKBp8EZby_BAi-fQoxga-eztSPH94M8iiAZTxuXH6E,5571
29
+ tests/test_offline.py,sha256=bkwHMoevAl3UEj8UmclM4adSm0kujjNNX83Dlx1nBpM,5572
28
30
  tests/test_server.py,sha256=FlJ_gEhRtoESc1m9EKCfJRXeGJnMRyoUtKF1VkOYhBY,23608
29
- pyx3270-0.1.2.dist-info/METADATA,sha256=EyH85TZYjDiWjXn5eu5eMlEKZAwc5N-vWtjiM4PBRrE,3417
30
- pyx3270-0.1.2.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
31
- pyx3270-0.1.2.dist-info/entry_points.txt,sha256=Bcoy79ZDcPN0ESfhD6TCa0R5eDbKYuMX7duLPzrVqMQ,49
32
- pyx3270-0.1.2.dist-info/top_level.txt,sha256=ptTDzZHpMHYKlnFM01XeuAnLhdlYO2NZQeER6hp3euA,24
33
- pyx3270-0.1.2.dist-info/RECORD,,
31
+ pyx3270-0.1.3.dist-info/METADATA,sha256=fCyDAXvoiWc_qFOqZxO99ur9GmRq0w0-gwTyZ735iLg,3417
32
+ pyx3270-0.1.3.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
33
+ pyx3270-0.1.3.dist-info/entry_points.txt,sha256=9kg9FaegDY2FXCVplltQGAmMiWia1LnnsPF7c1uQpa0,105
34
+ pyx3270-0.1.3.dist-info/top_level.txt,sha256=ptTDzZHpMHYKlnFM01XeuAnLhdlYO2NZQeER6hp3euA,24
35
+ pyx3270-0.1.3.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ [console_scripts]
2
+ pyx3270 = pyx3270.__main__:app
3
+
4
+ [pyinstaller40]
5
+ hook-dirs = pyx3270.hook:get_hook_dirs
tests/test_offline.py CHANGED
@@ -30,7 +30,7 @@ def test_pyx3270_manager_init_and_terminate(mock_popen, x3270_cmd_instance):
30
30
  stdout=subprocess.DEVNULL,
31
31
  stderr=subprocess.DEVNULL,
32
32
  text=True,
33
- bufsize=0
33
+ bufsize=0,
34
34
  )
35
35
  assert manager.process == mock_process
36
36
 
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- pyx3270 = pyx3270.__main__:app