KdeConnect.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import subprocess
  2. import re
  3. from pydantic import BaseModel
  4. class InvalidArgument(Exception):
  5. pass
  6. class InvalidDevice(Exception):
  7. pass
  8. class KDEConnectError(Exception):
  9. pass
  10. class KDEDevice(BaseModel):
  11. id: str
  12. name: str
  13. paired: bool
  14. reachable: bool
  15. class KDEConnect:
  16. device: KDEDevice
  17. def __init__(self, device_name=None, device_id=None):
  18. if device_name is None and device_id is None:
  19. raise InvalidArgument("device_name or device_id need to be provided")
  20. try:
  21. # Verify kdeconnect is available
  22. KDEConnect.run_kde_command(["-v"])
  23. except FileNotFoundError as e:
  24. raise KDEConnectError("KDEconnect-cli is not available on this computer")
  25. # verify the device exist
  26. devices = KDEConnect.get_device_list()
  27. device = None
  28. for d in devices:
  29. if (d.name == device_name) or (d.id == device_id):
  30. device = d
  31. break
  32. if device is None:
  33. raise InvalidDevice(f"No device found with id {device_id} or name {device_name}")
  34. if not device.paired:
  35. raise InvalidDevice(f"Device {device.name} is not paired with this computer")
  36. if not device.reachable:
  37. raise InvalidDevice(f"Device {device.name} is not reachable by this computer")
  38. self.device = device
  39. def send_sms(self, phone_number: str, sms_content: str):
  40. # Compact phone number by removing space
  41. phone = re.sub("[^+0-9]", "", phone_number)
  42. command = ["-d", self.device.id, "--send-sms", sms_content, "--destination", phone]
  43. KDEConnect.run_kde_command(command)
  44. @staticmethod
  45. def run_kde_command(args: list[str]) -> str:
  46. command: list[str] = ["kdeconnect-cli"]
  47. command.extend(args)
  48. process: CompletedProcess = subprocess.run(command, capture_output=True)
  49. if process.stderr != b"":
  50. print(f"[Err] {process.stderr.decode('utf-8')}")
  51. return process.stdout.decode("utf-8")
  52. @staticmethod
  53. def get_device_list() -> list[KDEDevice]:
  54. """Return the list of devices known by kde connect of this computer"""
  55. KDEConnect.run_kde_command(["--refresh"])
  56. output: list[KDEDevice] = []
  57. device_entries: list[str] = KDEConnect.run_kde_command(["-l"]).strip().split("\n")
  58. for device_str in device_entries:
  59. result = re.search("^- ([^:]+): ([a-z0-9_]{36})", device_str)
  60. reachable = "reachable" in device_str
  61. paired = "paired" in device_str
  62. device = KDEDevice(
  63. name=result.group(1),
  64. id=result.group(2),
  65. reachable=reachable,
  66. paired=paired,
  67. )
  68. output.append(device)
  69. return output
  70. if __name__ == "__main__":
  71. kde = KDEConnect(device_name="Redmi 7A")
  72. kde.send_sms("0776907462", ("160" * 53) + "\n" + "b")
  73. kde.send_sms("0776907462", "162" * 54)
  74. kde.send_sms("0776907462", "simple message")
  75. kde.send_sms("+33776907462", "+33 number")
  76. kde.send_sms("+33 77 690 746 2", "spaced number")
  77. kde.send_sms("0776907462", "Multiline sms\nthis is a second line")
  78. kde.send_sms(
  79. "0776907462",
  80. """Lorem ipsum dolor sit amet,
  81. consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
  82. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
  83. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
  84. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.""",
  85. )