Coverage for src/pyselector/helpers.py: 82%

39 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-29 11:30 -0300

1# helpers.ey 

2 

3from __future__ import annotations 

4 

5import logging 

6import shutil 

7import subprocess 

8import sys 

9from typing import Iterable 

10from typing import Union 

11 

12from pyselector.interfaces import ExecutableNotFoundError 

13 

14ENCODE = sys.getdefaultencoding() 

15 

16 

17log = logging.getLogger(__name__) 

18 

19 

20def check_command(name: str, reference: str) -> str: 

21 command = shutil.which(name) 

22 if not command: 

23 raise ExecutableNotFoundError( 

24 f"command '{name}' not found in $PATH ({reference})" 

25 ) 

26 return command 

27 

28 

29def parse_bytes_line(b: bytes) -> str: 

30 return " ".join(b.decode(encoding="utf-8").split()) 

31 

32 

33def parse_multiple_bytes_lines(b: bytes) -> list[str]: 

34 multi = b.decode(encoding="utf-8").splitlines() 

35 return [" ".join(line.split()) for line in multi] 

36 

37 

38def get_clipboard_data() -> str: 

39 """Read clipboard to add a new bookmark.""" 

40 with subprocess.Popen( 

41 ["xclip", "-selection", "clipboard", "-o"], 

42 stdout=subprocess.PIPE, 

43 ) as proc: 

44 data = proc.stdout.read() 

45 return data.decode("utf-8") 

46 

47 

48def set_clipboard_data(url: str) -> None: 

49 """Copy selected bookmark to the system clipboard.""" 

50 data = bytes(url, "utf-8") 

51 with subprocess.Popen( 

52 ["xclip", "-selection", "clipboard"], 

53 stdin=subprocess.PIPE, 

54 ) as proc: 

55 proc.stdin.write(data) 

56 log.debug("copied '%s' to clipboard", url) 

57 

58 

59def _execute(args: list[str], items: Iterable[Union[str, int]]) -> tuple[bytes, int]: 

60 log.debug("executing: %s", args) 

61 with subprocess.Popen( 

62 args, 

63 stdout=subprocess.PIPE, 

64 stdin=subprocess.PIPE, 

65 ) as proc: 

66 items_str = list(map(str, items)) 

67 bytes_items = "\n".join(items_str).encode(encoding=ENCODE) 

68 selected, _ = proc.communicate(input=bytes_items) 

69 return_code = proc.wait() 

70 

71 if not selected: 

72 sys.exit(1) 

73 

74 return selected, return_code