aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Halle <niklas@niklashalle.net>2020-08-24 14:16:07 +0200
committerNiklas Halle <niklas@niklashalle.net>2020-08-24 14:16:07 +0200
commitad285fae6de18fc786051f725d68340539c8e2d9 (patch)
tree31bbc516ee4638972566e73c5524c22f5138a063
parent039132d2811f111fdd6ad777f681a6221d5cc829 (diff)
downloadn_frontend_signal-ad285fae6de18fc786051f725d68340539c8e2d9.tar.gz
n_frontend_signal-ad285fae6de18fc786051f725d68340539c8e2d9.zip
trying with pysignald HEAD
-rw-r--r--.gitmodules3
m---------libs/pysignald0
-rwxr-xr-xmain.py5
-rw-r--r--pysignald/__init__.py4
-rw-r--r--pysignald/__pycache__/__init__.cpython-37.pycbin203 -> 0 bytes
-rw-r--r--pysignald/__pycache__/main.cpython-37.pycbin6450 -> 0 bytes
-rw-r--r--pysignald/__pycache__/types.cpython-37.pycbin935 -> 0 bytes
-rw-r--r--pysignald/main.py212
-rw-r--r--pysignald/types.py24
9 files changed, 5 insertions, 243 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..aaac766
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "libs/pysignald"]
+ path = libs/pysignald
+ url = git@gitlab.com:stavros/pysignald.git
diff --git a/libs/pysignald b/libs/pysignald
new file mode 160000
+Subproject e87b2ece9255205bee339287bac6c13996ed32a
diff --git a/main.py b/main.py
index d883eff..fd3cd3b 100755
--- a/main.py
+++ b/main.py
@@ -3,10 +3,9 @@
import os
import sys
import getopt
-import json
import requests
-from signald import Signal
+from .libs.pysignald.signald import Signal
from configparser import ConfigParser
@@ -46,7 +45,7 @@ def startup(number):
# TODO: try catch
response = requests.post('http://localhost:18080',
- json={"command": match.group(1), "arguments": strip(match.group(2))})
+ json={"command": match.group(1), "arguments": match.group(2).strip()})
answer = ""
replies = response.json()['reply']
diff --git a/pysignald/__init__.py b/pysignald/__init__.py
deleted file mode 100644
index 959fbf5..0000000
--- a/pysignald/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# flake8: noqa
-__version__ = "0.0.6"
-
-from .main import Signal
diff --git a/pysignald/__pycache__/__init__.cpython-37.pyc b/pysignald/__pycache__/__init__.cpython-37.pyc
deleted file mode 100644
index dc56638..0000000
--- a/pysignald/__pycache__/__init__.cpython-37.pyc
+++ /dev/null
Binary files differ
diff --git a/pysignald/__pycache__/main.cpython-37.pyc b/pysignald/__pycache__/main.cpython-37.pyc
deleted file mode 100644
index 3325cc3..0000000
--- a/pysignald/__pycache__/main.cpython-37.pyc
+++ /dev/null
Binary files differ
diff --git a/pysignald/__pycache__/types.cpython-37.pyc b/pysignald/__pycache__/types.cpython-37.pyc
deleted file mode 100644
index 20b838c..0000000
--- a/pysignald/__pycache__/types.cpython-37.pyc
+++ /dev/null
Binary files differ
diff --git a/pysignald/main.py b/pysignald/main.py
deleted file mode 100644
index cfaa79c..0000000
--- a/pysignald/main.py
+++ /dev/null
@@ -1,212 +0,0 @@
-import json
-import random
-import re
-import socket
-from typing import Iterator, List # noqa
-
-from .types import Attachment, Message
-
-# We'll need to know the compiled RE object later.
-RE_TYPE = type(re.compile(""))
-
-
-def readlines(s: socket.socket) -> Iterator[bytes]:
- "Read a socket, line by line."
- buf = [] # type: List[bytes]
- while True:
- char = s.recv(1)
- if not char:
- raise ConnectionResetError("connection was reset")
-
- if char == b"\n":
- yield b"".join(buf)
- buf = []
- else:
- buf.append(char)
-
-
-class Signal:
- def __init__(self, username, socket_path="/var/run/signald/signald.sock"):
- self.username = username
- self.socket_path = socket_path
- self._chat_handlers = []
-
- def _get_id(self):
- "Generate a random ID."
- return "".join(random.choice("abcdefghijklmnopqrstuvwxyz0123456789") for _ in range(10))
-
- def _get_socket(self) -> socket.socket:
- "Create a socket, connect to the server and return it."
-
- # Support TCP sockets on the sly.
- if isinstance(self.socket_path, tuple):
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- else:
- s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- s.connect(self.socket_path)
- return s
-
- def _send_command(self, payload: dict, block: bool = False):
- s = self._get_socket()
- msg_id = self._get_id()
- payload["id"] = msg_id
- s.recv(1024) # Flush the buffer.
- s.send(json.dumps(payload).encode("utf8") + b"\n")
-
- if not block:
- return
-
- response = s.recv(4 * 1024)
- for line in response.split(b"\n"):
- if msg_id.encode("utf8") not in line:
- continue
-
- data = json.loads(line)
-
- if data.get("id") != msg_id:
- continue
-
- if data["type"] == "unexpected_error":
- raise ValueError("unexpected error occurred: " + str(line))
-
- def register(self, voice=False):
- """
- Register the given number.
-
- voice: Whether to receive a voice call or an SMS for verification.
- """
- payload = {"type": "register", "username": self.username, "voice": voice}
- self._send_command(payload)
-
- def verify(self, code: str):
- """
- Verify the given number by entering the code you received.
-
- code: The code Signal sent you.
- """
- payload = {"type": "verify", "username": self.username, "code": code}
- self._send_command(payload)
-
- def receive_messages(self) -> Iterator[Message]:
- "Keep returning received messages."
- s = self._get_socket()
- s.send(json.dumps({"type": "subscribe", "username": self.username}).encode("utf8") + b"\n")
-
- for line in readlines(s):
- try:
- message = json.loads(line.decode())
- except json.JSONDecodeError:
- print("Invalid JSON")
-
- #print("type: " + message.get("type"))
- if message.get("type") != "message": #or (
- #not message["data"]["isReceipt"] and message["data"].get("dataMessage") is None
- #):
- # If the message type isn't "message", or if it's a weird message whose
- # purpose I don't know, return. I think the weird message is a typing
- # notification.
- continue
-
- message = message["data"]
- data_message = message.get("dataMessage", {})
-
- yield Message(
- username=message["username"],
- source=message["source"],
- text=data_message.get("body"),
- source_device=message["sourceDevice"],
- timestamp=data_message.get("timestamp"),
- timestamp_iso=message["timestampISO"],
- expiration_secs=data_message.get("expiresInSeconds"),
-# is_receipt=message["isReceipt"],
- group_info=data_message.get("group", {}),
- attachments=[
- Attachment(
- content_type=attachment["contentType"],
- id=attachment["id"],
- size=attachment["size"],
- stored_filename=attachment["storedFilename"],
- )
- for attachment in data_message.get("attachments", [])
- ],
- )
-
- def send_message(self, recipient: str, text: str, block: bool = True) -> None:
- """
- Send a message.
-
- recipient: The recipient's phone number, in E.123 format.
- text: The text of the message to send.
- block: Whether to block while sending. If you choose not to block, you won't get an exception if there
- are any errors.
- """
- payload = {"type": "send", "username": self.username, "recipientAddress": recipient, "messageBody": text}
-# print(f"payload: {payload}")
- self._send_command(payload, block)
-
- def send_group_message(self, recipient_group_id: str, text: str, block: bool = False) -> None:
- """
- Send a group message.
-
- recipient_group_id: The base64 encoded group ID to send to.
- text: The text of the message to send.
- block: Whether to block while sending. If you choose not to block, you won't get an exception if
- there are any errors.
- """
- payload = {
- "type": "send",
- "username": self.username,
- "recipientGroupId": recipient_group_id,
- "messageBody": text,
- }
- self._send_command(payload, block)
-
- def chat_handler(self, regex, order=100):
- """
- A decorator that registers a chat handler function with a regex.
- """
- if not isinstance(regex, RE_TYPE):
- regex = re.compile(regex, re.I)
-
- def decorator(func):
- self._chat_handlers.append((order, regex, func))
- # Use only the first value to sort so that declaration order doesn't change.
- self._chat_handlers.sort(key=lambda x: x[0])
- return func
-
- return decorator
-
- def run_chat(self):
- """
- Start the chat event loop.
- """
- for message in self.receive_messages():
- if not message.text:
- continue
- #print("text: " + message.text)
- for _, regex, func in self._chat_handlers:
- match = re.search(regex, message.text)
- if not match:
- continue
-
- try:
- reply = func(message, match)
- except: # noqa - We don't care why this failed.
- continue
-
- if isinstance(reply, tuple):
- stop, reply = reply
- else:
- stop = True
-
- # In case a message came from a group chat
- group_id = message.group_info.get("groupId")
-
- if group_id:
- self.send_group_message(recipient_group_id=group_id, text=reply)
- else:
- self.send_message(recipient=message.source, text=reply)
-
- if stop:
- # We don't want to continue matching things.
- break
diff --git a/pysignald/types.py b/pysignald/types.py
deleted file mode 100644
index 1b605b3..0000000
--- a/pysignald/types.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import attr
-
-
-@attr.s
-class Attachment:
- content_type = attr.ib(type=str)
- id = attr.ib(type=str)
- size = attr.ib(type=int)
- stored_filename = attr.ib(type=str)
-
-
-@attr.s
-class Message:
- username = attr.ib(type=str)
- source = attr.ib(type=str)
- text = attr.ib(type=str)
- source_device = attr.ib(type=int, default=0)
- timestamp = attr.ib(type=int, default=None)
- timestamp_iso = attr.ib(type=str, default=None)
- expiration_secs = attr.ib(type=int, default=0)
- is_receipt = attr.ib(type=bool, default=False)
- attachments = attr.ib(type=list, default=[])
- quote = attr.ib(type=str, default=None)
- group_info = attr.ib(type=dict, default={})