Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 59 additions & 3 deletions pytg/receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
import threading
import socket # connect to telegram cli.
import json
import stat
import os
import logging
from sys import exit
from collections import deque
from types import GeneratorType
from errno import EINTR, ECONNREFUSED
Expand Down Expand Up @@ -45,15 +48,54 @@ class Receiver(object):
_new_messages = threading.Semaphore(0)
_queue_access = threading.Lock()

def __init__(self, host="localhost", port=4458, append_json=False):
def __init__(self, host="localhost", port=4458, sock=None, append_json=False):
"""
:param append_json: if the dict should contain the original json.
"""
self.host = host
self.port = port
self.sock = sock
self.append_json = append_json
self.s = None # socket.

self.use_sock = False
self.use_tcp = False

# unix socket will be the default connection method
if sock:
if not isinstance(sock, str) and\
not isinstance(sock, bytes) and\
not isinstance(sock, bytearray):
raise TypeError("Supplied sock path is not a address type")

if not stat.S_ISSOCK(os.stat(sock).st_mode):
raise OSError("Supplied sock path is not a valid socket")

self.sock = sock
self.use_sock = True
print("Receiver is using unix domain socket at: {}".format(sock))

elif host and port:
if not isinstance(port, int):
raise TypeError("port is no int")

with socket.socket() as s:
error = s.connect_ex((host, port))
if error:
print("{}:{} address is not a valid network socket, "\
"faling with error {}"\
.format(host, port, error))
else:
self.use_tcp = True
self.host = host
self.port = port
print("Receiver is using network socket at: {}:{}"
.format(host,port))

if not self.use_sock and not self.use_tcp:
print("No valid connection to telegram-cli found")
exit()

def queued_messages(self):
"""
Informs how many messages are still in the queue, waiting to be processed.
Expand Down Expand Up @@ -93,9 +135,23 @@ def stop(self):

def _receiver(self):
while not self._do_quit: # retry connection
self.s = socket.socket() # errors?
self.s = socket.socket()

# network socket
if self.use_tcp:
self.s = socket.socket()

# unix-domain socket
elif self.use_sock:
self.s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

# connection
try:
self.s.connect((self.host, self.port))
if self.use_tcp:
self.s.connect((self.host, self.port))
elif self.use_sock:
self.s.connect(self.sock)

except socket.error as error:
self.s.close()
if error.errno == ECONNREFUSED and not self._do_quit:
Expand Down
68 changes: 59 additions & 9 deletions pytg/sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from collections import OrderedDict # keep the the functions dict in order
from errno import ECONNREFUSED, EINTR # socket errors
from socket import error as socket_error # socket errors
from sys import exit
import stat
import os

from DictObject import DictObject # pack the result as object.
from luckydonaldUtils.encoding import to_unicode as u
Expand Down Expand Up @@ -224,19 +227,55 @@ class Sender(object):
_do_quit = False
default_answer_timeout = 1.0 # how long it should wait for a answer. DANGER: if set to None it will block!

def __init__(self, host, port):
def __init__(self, host="localhost", port=4458, sock=None):
"""
Create a new Sender object. Specify host and port.
Create a new Sender object. Specify host and port of unix-socket path

:param host: host ip
:param port:
:param port: port
or
:param sock: socket path
:return:
"""
if not isinstance(port, int):
raise TypeError("port is no int")
self.use_sock = False
self.use_tcp = False

# unix socket will be the default connection method
if sock:
if not isinstance(sock, str) and\
not isinstance(sock, bytes) and\
not isinstance(sock, bytearray):
raise TypeError("Supplied sock path is not a address type")

if not stat.S_ISSOCK(os.stat(sock).st_mode):
raise OSError("Supplied sock path is not a valid socket")

self.sock = sock
self.use_sock = True
print("Sender is using unix domain socket at: {}".format(sock))

elif host and port:
if not isinstance(port, int):
raise TypeError("port is no int")

with socket.socket() as s:
error = s.connect_ex((host, port))
if error:
print("{}:{} address is not a valid network socket, "\
"faling with error {}"\
.format(host, port, error))
else:
self.use_tcp = True
self.host = host
self.port = port
print("Sender is using network socket at: {}:{}"
.format(host,port))

if not self.use_sock and not self.use_tcp:
print("No valid connection to telegram-cli found")
exit()

self.s = None
self.host = host
self.port_out = port
self.debug = False
self._socked_used = threading.Semaphore(1) # start unblocked.
atexit.register(self.terminate)
Expand Down Expand Up @@ -470,9 +509,20 @@ def _do_send(self, command, answer_timeout=default_answer_timeout, retry_connect
if self.s:
self.s.close()
self.s = None
self.s = socket.socket()
# network socket
if self.use_tcp:
self.s = socket.socket()

# unix-domain socket
elif self.use_sock:
self.s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

# connection
try:
self.s.connect((self.host, self.port_out))
if self.use_tcp:
self.s.connect((self.host, self.port))
elif self.use_sock:
self.s.connect(self.sock)
except socket_error as error:
self.s.close()
if error.errno == ECONNREFUSED and not self._do_quit:
Expand Down