Download app/tars_instancia.py from OpenTARS/openTARS: direct link, hf CLI and curl.
- Browser
- Download file 6.01 kB
-
https://huggingface.co/OpenTARS/openTARS/resolve/main/app/tars_instancia.py
- Command line
-
hf download hf://OpenTARS/openTARS/app/tars_instancia.py
-
curl -L -o tars_instancia.py https://huggingface.co/OpenTARS/openTARS/resolve/main/app/tars_instancia.py
6.01 kB
| """ | |
| Instância única da janela do openTARS (só biblioteca padrão: carrega em | |
| milissegundos). | |
| Abrir o openTARS de novo (menu, atalho global) não cria uma segunda | |
| janela brigando pelo mesmo histórico: o novo processo manda um recado | |
| pra instância que já está aberta ("mostrar" ou "rapido") e sai na hora. | |
| É isso que deixa o atalho global instantâneo. | |
| - um cadeado (flock) diz quem é a instância: some sozinho se ela cair; | |
| - o recado vai por um socket Unix na pasta de runtime do usuário | |
| ($XDG_RUNTIME_DIR, só ele acessa), um por tela (DISPLAY). | |
| - 5.2, Windows (sem flock nem socket Unix): o cadeado é o msvcrt.locking e o recado vai por TCP em 127.0.0.1, numa porta | |
| sorteada que fica num arquivo da pasta do usuário junto com um segredo; recado sem o segredo é ignorado. | |
| """ | |
| import os | |
| import re | |
| import secrets | |
| import socket | |
| import threading | |
| from pathlib import Path | |
| try: | |
| import fcntl | |
| except ImportError: # Windows | |
| fcntl = None | |
| import msvcrt | |
| WINDOWS = fcntl is None | |
| COMANDOS = ("mostrar", "rapido", "acoes", "residente") | |
| def _pasta(): | |
| if WINDOWS: | |
| pasta = Path(os.environ.get("LOCALAPPDATA") or Path.home()) / "opentars" | |
| pasta.mkdir(parents=True, exist_ok=True) | |
| return pasta | |
| base = os.environ.get("XDG_RUNTIME_DIR") | |
| if base and os.path.isdir(base) and os.access(base, os.W_OK): | |
| return Path(base) | |
| pasta = Path(f"/tmp/opentars-{os.getuid()}") | |
| pasta.mkdir(mode=0o700, exist_ok=True) | |
| return pasta | |
| def _caminhos(): | |
| tela = os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY") or "sem-tela" | |
| tela = re.sub(r"[^A-Za-z0-9_.-]", "_", tela) | |
| pasta = _pasta() | |
| return pasta / f"opentars-{tela}.sock", pasta / f"opentars-{tela}.lock" | |
| def enviar(comando, id_inicio=None, timeout=1.5): | |
| """Manda o recado pra instância aberta. True se ela respondeu.""" | |
| caminho_socket, _ = _caminhos() | |
| linha = comando if not id_inicio else f"{comando}\t{id_inicio}" | |
| try: | |
| if WINDOWS: | |
| porta, segredo = caminho_socket.read_text(encoding="utf-8").split() | |
| linha = f"{segredo}\t{linha}" | |
| with socket.socket(socket.AF_INET if WINDOWS else socket.AF_UNIX, socket.SOCK_STREAM) as s: | |
| s.settimeout(timeout) | |
| s.connect(("127.0.0.1", int(porta)) if WINDOWS else str(caminho_socket)) | |
| s.sendall(linha.encode("utf-8", "replace") + b"\n") | |
| return s.recv(8).startswith(b"ok") | |
| except (OSError, ValueError): | |
| return False | |
| class Servidor: | |
| """Segura o cadeado e atende os recados das próximas aberturas.""" | |
| def __init__(self): | |
| self._arquivo_trava = None | |
| self._socket = None | |
| self._ao_receber = None | |
| self._segredo = "" | |
| self.caminho_socket, self.caminho_trava = _caminhos() | |
| def travar(self): | |
| """True se este processo é a instância (ninguém mais segura o cadeado).""" | |
| try: | |
| arquivo = open(self.caminho_trava, "a+") | |
| except OSError: | |
| return True # sem como travar: segue sem instância única | |
| try: | |
| if WINDOWS: | |
| msvcrt.locking(arquivo.fileno(), msvcrt.LK_NBLCK, 1) | |
| else: | |
| fcntl.flock(arquivo.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) | |
| except OSError: | |
| arquivo.close() | |
| return False | |
| self._arquivo_trava = arquivo | |
| return True | |
| def escutar(self, ao_receber): | |
| """ao_receber(comando, id_inicio) roda numa thread separada.""" | |
| self._ao_receber = ao_receber | |
| try: | |
| self.caminho_socket.unlink() | |
| except OSError: | |
| pass | |
| try: | |
| if WINDOWS: | |
| s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
| s.bind(("127.0.0.1", 0)) | |
| self._segredo = secrets.token_hex(16) | |
| self.caminho_socket.write_text(f"{s.getsockname()[1]} {self._segredo}", encoding="utf-8") | |
| else: | |
| s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) | |
| s.bind(str(self.caminho_socket)) | |
| os.chmod(self.caminho_socket, 0o600) | |
| s.listen(4) | |
| except OSError: | |
| return False | |
| self._socket = s | |
| threading.Thread(target=self._atender, daemon=True).start() | |
| return True | |
| def _atender(self): | |
| while self._socket is not None: | |
| try: | |
| conexao, _ = self._socket.accept() | |
| except OSError: | |
| return | |
| with conexao: | |
| try: | |
| conexao.settimeout(1.0) | |
| dados = b"" | |
| while not dados.endswith(b"\n") and len(dados) < 1024: | |
| pedaco = conexao.recv(256) | |
| if not pedaco: | |
| break | |
| dados += pedaco | |
| texto = dados.decode("utf-8", "replace").strip() | |
| if WINDOWS: | |
| segredo, _, texto = texto.partition("\t") | |
| if not secrets.compare_digest(segredo, self._segredo): | |
| continue | |
| comando, _, id_inicio = texto.partition("\t") | |
| if comando in COMANDOS: | |
| conexao.sendall(b"ok\n") | |
| if self._ao_receber: | |
| self._ao_receber(comando, id_inicio or None) | |
| except Exception: # um erro no tratamento de UM recado não pode matar a escuta pra sempre | |
| continue | |
| def fechar(self): | |
| s, self._socket = self._socket, None | |
| if s is not None: | |
| try: | |
| s.close() | |
| self.caminho_socket.unlink() | |
| except OSError: | |
| pass | |
| if self._arquivo_trava is not None: | |
| try: | |
| self._arquivo_trava.close() | |
| except OSError: | |
| pass | |
| self._arquivo_trava = None | |