From 830f04d710b5d0eaacae400a174172ab2ca08ae5 Mon Sep 17 00:00:00 2001 From: Ingolf Wagner Date: Sun, 17 Nov 2024 05:02:15 +0700 Subject: [PATCH] :building_construction: create nix package --- .gitignore | 2 + default.nix | 21 ++++++++++ flake.nix | 12 +----- main.py | 76 ------------------------------------- setup.py | 21 ++++++++++ share-via-http.py | 97 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 143 insertions(+), 86 deletions(-) create mode 100644 .gitignore create mode 100644 default.nix delete mode 100644 main.py create mode 100644 setup.py create mode 100644 share-via-http.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e95139 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +qrcode.png +result \ No newline at end of file diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..059e7c0 --- /dev/null +++ b/default.nix @@ -0,0 +1,21 @@ +{ + pkgs ? import { }, +}: + +pkgs.python3Packages.buildPythonApplication rec { + pname = "your-package-name"; + version = "1.0"; + + src = ./.; + + # Specify the dependencies for the package + propagatedBuildInputs = [ + pkgs.python3Packages.qrcode + pkgs.python3Packages.pillow + ]; + + # Entry point of the application + # Adjust this path accordingly if share-via-http.py is located in a different directory + doCheck = false; + +} diff --git a/flake.nix b/flake.nix index cc29913..87fc5a3 100644 --- a/flake.nix +++ b/flake.nix @@ -31,17 +31,9 @@ ... }: { - # Per-system attributes can be defined here. The self' and inputs' - # module parameters provide easy access to attributes of the same - # system. + packages.default = self'.packages.share-via-http; + packages.share-via-http = pkgs.callPackage ./default.nix { }; - # Equivalent to inputs'.nixpkgs.legacyPackages.hello; - packages.default = pkgs.hello; }; - flake = { - # The usual flake attributes can be defined here, including system- - # agnostic ones like nixosModule and system-enumerating ones, although - # those are more easily expressed in perSystem. - }; }; } diff --git a/main.py b/main.py deleted file mode 100644 index b80ae98..0000000 --- a/main.py +++ /dev/null @@ -1,76 +0,0 @@ -import os -import argparse -import base64 -import http.server -import socket -import socketserver -import qrcode - -def get_current_ip_address(): - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.connect(("8.8.8.8", 80)) - ip_address = s.getsockname()[0] - s.close() - return ip_address - -# Define the command-line arguments -parser = argparse.ArgumentParser(description='Start a simple HTTP server with basic authentication.') -parser.add_argument('--port', type=int, default = 8000, help = 'Port to serve the directory over.') -parser.add_argument('--username', required=True, help='Username for basic authentication.') -parser.add_argument('--password', required=True, help='Password for basic authentication.') -parser.add_argument('--directory', default=os.getcwd(), help='Directory to serve. Defaults to the current directory.') -args = parser.parse_args() - -# Expand the directory path (e.g., if it contains ~) -expanded_directory = os.path.expanduser(args.directory) - -# Change the working directory to serve the specified directory -os.chdir(expanded_directory) - - - -# Define a request handler with basic authentication -class AuthHandler(http.server.SimpleHTTPRequestHandler): - def do_AUTHHEAD(self): - self.send_response(401) - self.send_header('WWW-Authenticate', 'Basic realm="Server Access"') - self.send_header('Content-type', 'text/html') - self.end_headers() - - def do_GET(self): - auth_header = self.headers.get('Authorization') - if auth_header is None or not self.check_auth(auth_header): - self.do_AUTHHEAD() - self.wfile.write(b'Not authenticated') - else: - super().do_GET() - - def check_auth(self, auth_header): - encoded_credentials = auth_header.split()[1] - decoded_credentials = base64.b64decode(encoded_credentials).decode('utf-8') - username, password = decoded_credentials.split(':') - return username == args.username and password == args.password - -def save_qr_code(url): - # Generate the QR code - qr = qrcode.QRCode( - version=1, - error_correction=qrcode.constants.ERROR_CORRECT_L, - box_size=10, - border=4, - ) - qr.add_data(url) - qr.make(fit=True) - # Create an image from the QR Code instance - img = qr.make_image(fill_color='black', back_color='white').convert('RGB') - # Save the image - img.save("qrcode.png") - -# Set up the server with the AuthHandler and the defined port -with socketserver.TCPServer(("", args.port), AuthHandler) as httpd: - print("qrcode.png is saved in the current directory.") - ip_address = get_current_ip_address() - print(f"http://{args.username}:{args.password}@{ip_address}:{args.port}/ < the page") - print(f"http://{args.username}:{args.password}@{ip_address}:{args.port}/qrcode.png < qrcode") - save_qr_code(f"http://{args.username}:{args.password}@{ip_address}:{args.port}/") - httpd.serve_forever() \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..561ce4b --- /dev/null +++ b/setup.py @@ -0,0 +1,21 @@ +from setuptools import setup, find_packages + +setup( + name="share-via-http", + version="1.0", + packages=find_packages(), + install_requires=[ + "qrcode[pil]", + ], + scripts=["share-via-http.py"], + python_requires=">=3.6", + author="Your Name", + author_email="contact@ingolf-wagner.d", + description="Starte a simple HTTP server to share files with basic_auth, generate a QR Code for quick url sharing", + url="http://example.org/", + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + ], +) diff --git a/share-via-http.py b/share-via-http.py new file mode 100644 index 0000000..6e6e2c4 --- /dev/null +++ b/share-via-http.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python + +import os +import argparse +import base64 +import http.server +import socket +import socketserver +import qrcode + + +def get_current_ip_address(): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("8.8.8.8", 80)) + ip_address = s.getsockname()[0] + s.close() + return ip_address + + +# Define the command-line arguments +parser = argparse.ArgumentParser( + description="Start a simple HTTP server with basic authentication." +) +parser.add_argument( + "--port", type=int, default=8000, help="Port to serve the directory over." +) +parser.add_argument( + "--username", required=True, help="Username for basic authentication." +) +parser.add_argument( + "--password", required=True, help="Password for basic authentication." +) +parser.add_argument( + "--directory", + default=os.getcwd(), + help="Directory to serve. Defaults to the current directory.", +) +args = parser.parse_args() + +# Expand the directory path (e.g., if it contains ~) +expanded_directory = os.path.expanduser(args.directory) + +# Change the working directory to serve the specified directory +os.chdir(expanded_directory) + + +# Define a request handler with basic authentication +class AuthHandler(http.server.SimpleHTTPRequestHandler): + def do_AUTHHEAD(self): + self.send_response(401) + self.send_header("WWW-Authenticate", 'Basic realm="Server Access"') + self.send_header("Content-type", "text/html") + self.end_headers() + + def do_GET(self): + auth_header = self.headers.get("Authorization") + if auth_header is None or not self.check_auth(auth_header): + self.do_AUTHHEAD() + self.wfile.write(b"Not authenticated") + else: + super().do_GET() + + def check_auth(self, auth_header): + encoded_credentials = auth_header.split()[1] + decoded_credentials = base64.b64decode(encoded_credentials).decode("utf-8") + username, password = decoded_credentials.split(":") + return username == args.username and password == args.password + + +def save_qr_code(url): + # Generate the QR code + qr = qrcode.QRCode( + version=1, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=10, + border=4, + ) + qr.add_data(url) + qr.make(fit=True) + # Create an image from the QR Code instance + img = qr.make_image(fill_color="black", back_color="white").convert("RGB") + # Save the image + img.save("qrcode.png") + + +# Set up the server with the AuthHandler and the defined port +with socketserver.TCPServer(("", args.port), AuthHandler) as httpd: + print("qrcode.png is saved in the current directory.") + ip_address = get_current_ip_address() + print( + f"http://{args.username}:{args.password}@{ip_address}:{args.port}/ < the page" + ) + print( + f"http://{args.username}:{args.password}@{ip_address}:{args.port}/qrcode.png < qrcode" + ) + save_qr_code(f"http://{args.username}:{args.password}@{ip_address}:{args.port}/") + httpd.serve_forever()