From 279eefb431b1a058e422957462f00eb8bc412ca7 Mon Sep 17 00:00:00 2001 From: louis chauvet Date: Mon, 12 Nov 2018 20:13:56 +0100 Subject: [PATCH] First commit for our chat --- .gitignore | 107 +++++++++++++++++++++++++++++++++++++++ LICENSE | 21 ++++++++ server/log_config.json | 53 ++++++++++++++++++++ server/main.py | 110 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 291 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 server/log_config.json create mode 100644 server/main.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ee759a4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,107 @@ +# 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/ + +# pycharm +.idea/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8c1bef4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Fomys + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/server/log_config.json b/server/log_config.json new file mode 100644 index 0000000..4686e03 --- /dev/null +++ b/server/log_config.json @@ -0,0 +1,53 @@ +{ + "version": 1, + "disable_existing_loggers": false, + "formatters": { + "simple": { + "format": "%(asctime)s :: %(name)s :: %(levelname)s :: %(message)s" + } + }, + "handlers": { + "console": { + "class": "logging.StreamHandler", + "level": "DEBUG", + "formatter": "simple", + "stream": "ext://sys.stdout" + }, + "info_file_handler": { + "class": "logging.handlers.RotatingFileHandler", + "level": "INFO", + "formatter": "simple", + "filename": "info.log", + "maxBytes": 1048576, + "backupCount": 20, + "encoding": "utf8" + }, + "error_file_handler": { + "class": "logging.handlers.RotatingFileHandler", + "level": "ERROR", + "formatter": "simple", + "filename": "errors.log", + "maxBytes": 1048576, + "backupCount": 20, + "encoding": "utf8" + } + }, + "loggers": { + "server": { + "level": "DEBUG", + "handlers": [ + "console", + "info_file_handler", + "error_file_handler" + ] + } + }, + "root": { + "level": "INFO", + "handlers": [ + "console", + "info_file_handler", + "error_file_handler" + ] + } +} \ No newline at end of file diff --git a/server/main.py b/server/main.py new file mode 100644 index 0000000..62e2566 --- /dev/null +++ b/server/main.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# coding: utf8 + +import json +import logging +import os +import socket + + +#### logging #### +# json decoder for int keys +import threading + + +class Decoder(json.JSONDecoder): + def decode(self, s, **kwargs): + result = super().decode(s) # result = super(Decoder, self).decode(s) for Python 2.x + return self._decode(result) + + def _decode(self, o): + if isinstance(o, str): + try: + return int(o) + except ValueError: + return o + elif isinstance(o, dict): + return {k: self._decode(v) for k, v in o.items()} + elif isinstance(o, list): + return [self._decode(v) for v in o] + else: + return o + + +def setup_logging(default_path='log_config.json', default_level=logging.INFO, env_key='LOG_CFG'): + """Setup logging configuration + """ + path = default_path + value = os.getenv(env_key, None) + if value: + path = value + if os.path.exists(path): + with open(path, 'rt') as f: + config = json.load(f) + logging.config.dictConfig(config) + else: + logging.basicConfig(level=default_level) + + +setup_logging() + +log_server = logging.getLogger('server') + +debug = log_server.debug +info = log_server.info +warning = log_server.warning +error = log_server.error +critical = log_server.critical + +#### Variables #### +host = '' +port = 8888 +user = { + "fomys": "fomys" +} +bufferTaille = 16384 + +#### Socket #### +main_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +main_socket.bind((host, port)) + +#### Threads #### +class clientThread(threading.Thread): + """Main thread, for each client""" + + def __init__(self, clientsocket, ip, port): + """Create clientThread object + + :param clentsocket: Client's socket + :param ip: Client's ip address + :param port: Client's connection port + :type clientsocket: socket.socket + :type ip: str + :type port: int + + :return: Nothing + :rtype: NoneType""" + debug("Creation du thread pour %s" % ip) + threading.Thread.__init__(self) # initialisation du thread + self.client = clientsocket + self.ip = ip + self.port = port + debug("Creation du thread pour %s reussie" % ip) + + def run(self): # main de la connection du client + """Run thread mainloop + + :return: Nothing + :rtype: NoneType""" + ### ICI ON MET LA BOUCLE PRINCIPALE DE CONNECTION + self.client.close() + + +if __name__ == "__main__": + clients = [] + while True: + main_socket.listen(1) # ecoutes des connections entrantes + clientsocket, (ip, port) = main_socket.accept() + newClient = clientThread(clientsocket, ip, port) + newClient.start() + clients.append(newClient)