From 5f0ed1295f012cbd8906e4626dc9fd642c543332 Mon Sep 17 00:00:00 2001 From: Davte Date: Sun, 12 Apr 2020 19:15:06 +0200 Subject: [PATCH] Organize as package --- README.md | 2 +- filebridging/__init__.py | 18 +++++++ {src => filebridging}/client.py | 16 +++++-- {src => filebridging}/server.py | 14 +++++- {src => filebridging}/utilities.py | 2 +- setup.py | 75 ++++++++++++++++++++++++++++++ src/__init__.py | 0 7 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 filebridging/__init__.py rename {src => filebridging}/client.py (97%) rename {src => filebridging}/server.py (95%) rename {src => filebridging}/utilities.py (100%) create mode 100644 setup.py delete mode 100644 src/__init__.py diff --git a/README.md b/README.md index 13083b5..e442bee 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # filebridging -Share files via a bridge server. \ No newline at end of file +Share files via a bridge server using TCP over SSL and aes-256-cbc encryption. diff --git a/filebridging/__init__.py b/filebridging/__init__.py new file mode 100644 index 0000000..fdc6956 --- /dev/null +++ b/filebridging/__init__.py @@ -0,0 +1,18 @@ +"""General information about this package. + +Python 3.8+ is needed to use this package. +```python3.8+ +from filebridging.client import Client +from filebridging.server import Server +help(Client) +help(Server) +``` +""" + +__author__ = "Davide Testa" +__email__ = "davide@davte.it" +__credits__ = [] +__license__ = "GNU General Public License v3.0" +__version__ = "0.0.1" +__maintainer__ = "Davide Testa" +__contact__ = "t.me/davte" diff --git a/src/client.py b/filebridging/client.py similarity index 97% rename from src/client.py rename to filebridging/client.py index 3de0260..0fabcf6 100644 --- a/src/client.py +++ b/filebridging/client.py @@ -1,3 +1,5 @@ +"""Receiver and sender client class.""" + import argparse import asyncio import collections @@ -8,7 +10,7 @@ import ssl import string import sys -import utilities +from . import utilities class Client: @@ -313,6 +315,9 @@ def get_action(action): def get_file_path(path, action='receive'): """Check that file `path` is correct and return it.""" + path = os.path.abspath( + os.path.expanduser(path) + ) if ( isinstance(path, str) and action == 'send' @@ -322,7 +327,7 @@ def get_file_path(path, action='receive'): elif ( isinstance(path, str) and action == 'receive' - and os.access(os.path.dirname(os.path.abspath(path)), os.W_OK) + and os.access(os.path.dirname(path), os.W_OK) ): return path elif path is not None: @@ -525,7 +530,12 @@ def main(): _ssl_context.load_verify_locations(certificate) client.set_ssl_context(_ssl_context) except ImportError: - logging.warning("Please consider using SSL.") + logging.warning( + "Please consider using SSL. To do so, add in `config.py` or " + "provide via Command Line Interface the path to a valid SSL " + "certificate. Example:\n\n" + "certificate = 'path/to/certificate.crt'" + ) # noinspection PyUnusedLocal certificate = None logging.info("Starting client...") diff --git a/src/server.py b/filebridging/server.py similarity index 95% rename from src/server.py rename to filebridging/server.py index 7c2dc6b..01131d3 100644 --- a/src/server.py +++ b/filebridging/server.py @@ -1,3 +1,8 @@ +"""Server class. + +May be a local server or a publicly reachable server. +""" + import argparse import asyncio import collections @@ -216,6 +221,7 @@ class Server: port=self.port, ) async with self.server: + logging.info("Running at `{s.host}:{s.port}`".format(s=self)) await self.server.serve_forever() @staticmethod @@ -297,7 +303,13 @@ def main(): _ssl_context.load_cert_chain(certificate, key) server.set_ssl_context(_ssl_context) except ImportError: - logging.warning("Please consider using SSL.") + logging.warning( + "Please consider using SSL. To do so, add in `config.py` or " + "provide via Command Line Interface the path to a valid SSL " + "key and certificate. Example:\n\n" + "key = 'path/to/secret.key'\n" + "certificate = 'path/to/certificate.crt'" + ) server.run() diff --git a/src/utilities.py b/filebridging/utilities.py similarity index 100% rename from src/utilities.py rename to filebridging/utilities.py index 84f73ed..a372cd5 100644 --- a/src/utilities.py +++ b/filebridging/utilities.py @@ -1,4 +1,5 @@ """Useful functions.""" + import logging import signal @@ -26,4 +27,3 @@ def timed_input(message: str = None, logging.info("Timeout!") signal.alarm(0) return given_input - diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..ac743d2 --- /dev/null +++ b/setup.py @@ -0,0 +1,75 @@ +"""Setup.""" + +import codecs +import os +import re +import setuptools +import sys + +if sys.version_info < (3, 8): + raise RuntimeError("Python3.8+ is needed to use this library") + +here = os.path.abspath(os.path.dirname(__file__)) + + +def read(*parts): + """Read file in `part.part.part.part.ext`. + + Start from `here` and follow the path given by `*parts` + """ + with codecs.open(os.path.join(here, *parts), 'r') as fp: + return fp.read() + + +def find_information(info, *file_path_parts): + """Read information in file.""" + version_file = read(*file_path_parts) + version_match = re.search( + r"^__{info}__ = ['\"]([^'\"]*)['\"]".format( + info=info + ), + version_file, + re.M + ) + if version_match: + return version_match.group(1) + raise RuntimeError("Unable to find version string.") + + +with open("README.md", "r") as readme_file: + long_description = readme_file.read() + +setuptools.setup( + name='filebridging', + version=find_information("version", "filebridging", "__init__.py"), + author=find_information("author", "filebridging", "__init__.py"), + author_email=find_information("email", "filebridging", "__init__.py"), + description=( + "Share files via a bridge server using TCP over SSL and aes-256-cbc " + "encryption." + ), + license=find_information("license", "filebridging", "__init__.py"), + long_description=long_description, + long_description_content_type="text/markdown", + url="https://gogs.davte.it/davte/filebridging", + packages=setuptools.find_packages(), + platforms=['any'], + install_requires=[], + classifiers=[ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Framework :: AsyncIO", + "Intended Audience :: End Users/Desktop", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Communications :: File Sharing", + ], + keywords=( + 'file share ' + 'tcp ssl tls end-to-end encryption ' + 'python asyncio async' + ), + include_package_data=True, +) diff --git a/src/__init__.py b/src/__init__.py deleted file mode 100644 index e69de29..0000000