-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Arterialist
committed
May 25, 2018
1 parent
ca26f71
commit 2592557
Showing
13 changed files
with
486 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
MANIFEST | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
*.spec | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*.cover | ||
.hypothesis/ | ||
.pytest_cache/ | ||
|
||
# Translations | ||
*.mo | ||
*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
db.sqlite3 | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
target/ | ||
|
||
# Jupyter Notebook | ||
.ipynb_checkpoints | ||
|
||
# pyenv | ||
.python-version | ||
|
||
# celery beat schedule file | ||
celerybeat-schedule | ||
|
||
# SageMath parsed files | ||
*.sage.py | ||
|
||
# Environments | ||
.env | ||
.venv | ||
env/ | ||
venv/ | ||
ENV/ | ||
env.bak/ | ||
venv.bak/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
.spyproject | ||
|
||
# Rope project settings | ||
.ropeproject | ||
|
||
# mkdocs documentation | ||
/site | ||
|
||
# mypy | ||
.mypy_cache/ |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
import socket | ||
import threading | ||
from json import JSONDecodeError | ||
|
||
from client import layers | ||
from client.models.packets import Packet | ||
from client.modules.default_modules import SendAsJSONModule | ||
|
||
# load modules | ||
loaded_modules = [SendAsJSONModule()] | ||
|
||
nickname = None | ||
local_port = None | ||
|
||
sock = None | ||
server_host = None | ||
server_port = None | ||
|
||
connected = False | ||
listening = False | ||
|
||
has_incoming_connection = False | ||
incoming_connection = None | ||
incoming_connection_address = None | ||
|
||
current_connection = None | ||
current_connection_address = None | ||
current_peer_id = None | ||
|
||
incoming_message_thread = None | ||
incoming_connection_thread = None | ||
message_sending_thread = None | ||
|
||
incoming_connection_callback = None | ||
new_message_callback = None | ||
|
||
|
||
def init_socket(): | ||
global sock, connected | ||
connected = False | ||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
|
||
|
||
def incoming_connections_listener(): | ||
global has_incoming_connection, incoming_connection, incoming_connection_address | ||
while 1: | ||
try: | ||
connection, address = sock.accept() | ||
incoming_connection = connection | ||
incoming_connection_address = address | ||
has_incoming_connection = True | ||
if incoming_connection_callback: | ||
incoming_connection_callback() | ||
except OSError: | ||
continue | ||
|
||
|
||
def p2p_new_message_listener(): | ||
global current_connection, connected | ||
while connected: | ||
data = current_connection.recv(4096) | ||
if data == b'': | ||
print('Connection closed') | ||
connected = False | ||
break | ||
try: | ||
recv_msg = Packet.from_json_obj(layers.socket_handle_received(current_connection, data.decode('utf8'), loaded_modules)) | ||
recv_msg.message.mine = False | ||
if new_message_callback: | ||
new_message_callback(recv_msg) | ||
print(recv_msg.__dict__) | ||
except UnicodeDecodeError: | ||
print('Corrupted message') | ||
except JSONDecodeError: | ||
print('Received non-JSON message (raw connection?)') | ||
except KeyError: | ||
print("Invalid JSON schema") | ||
|
||
|
||
def server_new_message_listener(): | ||
global current_connection | ||
while connected: | ||
data = current_connection.recv(4096) | ||
try: | ||
if new_message_callback: | ||
new_message_callback('\n' + data.decode('utf8')) | ||
print('\n' + data.decode('utf8')) | ||
except UnicodeDecodeError: | ||
print('Corrupted message') | ||
|
||
|
||
def socket_listen_off(): | ||
global listening | ||
sock.close() | ||
if incoming_connection_thread: | ||
incoming_connection_thread.join(0) | ||
init_socket() | ||
listening = False | ||
|
||
|
||
def socket_listen_on(): | ||
global sock, incoming_connection_thread, listening | ||
socket_listen_off() | ||
|
||
try: | ||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | ||
sock.bind(('', local_port)) | ||
except socket.error as e: | ||
print('Bind failed.') | ||
print(e) | ||
return | ||
|
||
sock.listen(256) | ||
|
||
incoming_connection_thread = threading.Thread(target=incoming_connections_listener) | ||
incoming_connection_thread.setDaemon(True) | ||
incoming_connection_thread.start() | ||
listening = True | ||
|
||
|
||
def p2p_connect(remote_host, remote_port): | ||
global current_connection, current_connection_address, incoming_message_thread, connected | ||
socket_listen_off() | ||
|
||
current_connection_address = (remote_host, remote_port) | ||
current_connection = sock | ||
try: | ||
sock.connect(current_connection_address) | ||
except ConnectionRefusedError: | ||
print('Client is offline') | ||
return | ||
|
||
connected = True | ||
incoming_message_thread = threading.Thread(target=p2p_new_message_listener) | ||
incoming_message_thread.setDaemon(True) | ||
incoming_message_thread.start() | ||
print('Connected to client') | ||
|
||
|
||
def server_connect(): | ||
global current_connection_address, current_connection, incoming_message_thread, connected | ||
socket_listen_off() | ||
|
||
current_connection_address = (server_host, server_port) | ||
current_connection = sock | ||
sock.connect(current_connection_address) | ||
|
||
connected = True | ||
incoming_message_thread = threading.Thread(target=server_new_message_listener) | ||
incoming_message_thread.setDaemon(True) | ||
incoming_message_thread.start() | ||
print('Connected to server') | ||
|
||
|
||
def accept_connection(): | ||
global current_connection, current_connection_address, connected, incoming_message_thread | ||
current_connection = incoming_connection | ||
current_connection_address = incoming_connection_address | ||
connected = True | ||
incoming_message_thread = threading.Thread(target=p2p_new_message_listener) | ||
incoming_message_thread.setDaemon(True) | ||
incoming_message_thread.start() | ||
|
||
|
||
def decline_connection(): | ||
global incoming_connection, incoming_connection_address | ||
incoming_connection.close() | ||
incoming_connection = None | ||
incoming_connection_address = None | ||
|
||
|
||
def send_message(message): | ||
# pass your modules here | ||
layers.socket_send_data(current_connection, message, loaded_modules) | ||
|
||
|
||
def disconnect(): | ||
global current_connection, incoming_message_thread, incoming_connection_thread, connected, current_peer_id | ||
connected = False | ||
|
||
current_peer_id = None | ||
|
||
if current_connection: | ||
current_connection.detach() | ||
current_connection.close() | ||
|
||
if incoming_message_thread: | ||
incoming_message_thread.join(0) | ||
if incoming_connection_thread: | ||
incoming_connection_thread.join(0) | ||
|
||
|
||
def finish(): | ||
global sock, current_connection, incoming_message_thread, incoming_connection_thread, connected | ||
|
||
connected = False | ||
sock.detach() | ||
sock.close() | ||
|
||
if current_connection: | ||
current_connection.detach() | ||
current_connection.close() | ||
|
||
if incoming_message_thread: | ||
incoming_message_thread.join(0) | ||
if incoming_connection_thread: | ||
incoming_connection_thread.join(0) | ||
|
||
exit(0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
""" | ||
this file is created to make functionality growth fast | ||
""" | ||
|
||
|
||
def socket_send_data(to, what, through=list()): | ||
for action in through: | ||
what = action.process(what) | ||
|
||
if to: | ||
to.sendall(what) | ||
|
||
|
||
def socket_handle_received(from_s, what, through=list()): | ||
for action in through: | ||
what = action.process_s(what, from_s) | ||
|
||
return what |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from client.models.base import Jsonable | ||
|
||
|
||
class Action(Jsonable): | ||
def __init__(self, action="new"): | ||
self.action = action | ||
|
||
|
||
class NewMessageAction(Action): | ||
def __init__(self): | ||
super().__init__(action="new") | ||
|
||
|
||
class EditMessageAction(Action): | ||
def __init__(self): | ||
super().__init__(action="edit") | ||
|
||
|
||
class ReplyMessageAction(Action): | ||
def __init__(self): | ||
super().__init__(action="reply") | ||
|
||
|
||
class ForwardMessageAction(Action): | ||
def __init__(self): | ||
super().__init__(action="forward") | ||
|
||
|
||
class DeleteMessageAction(Action): | ||
def __init__(self): | ||
super().__init__(action="delete") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import json | ||
|
||
|
||
class Jsonable: | ||
@staticmethod | ||
def from_json(json_string): | ||
obj = Jsonable() | ||
obj.__dict__ = json.loads(json_string) | ||
return obj | ||
|
||
@staticmethod | ||
def from_json_obj(json_obj): | ||
obj = Jsonable() | ||
obj.__dict__ = json_obj | ||
return obj | ||
|
||
def to_json(self): | ||
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True) |
Oops, something went wrong.