Repository navigation
Expand file tree
/
Copy pathapp.py
More file actions
124 lines (102 loc) · 4.01 KB
/
Copy pathapp.py
File metadata and controls
124 lines (102 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/env python3
import argparse
import os
import socket
import uuid
import threading
import requests
from flask import (
Flask, render_template, request, redirect,
url_for, send_from_directory, jsonify
)
from werkzeug.utils import secure_filename
from discovery import DiscoveryService
BASE_DIR = os.path.dirname(__file__)
RECEIVED_DIR = os.path.join(BASE_DIR, "received_files")
os.makedirs(RECEIVED_DIR, exist_ok=True)
app = Flask(__name__)
app.config["MAX_CONTENT_LENGTH"] = 1024 * 1024 * 1024 # Limite globale à 1 Go par requête
MY_ID = str(uuid.uuid4())
def get_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
except OSError:
ip = "127.0.0.1"
finally:
s.close()
return ip
def parse_args():
parser = argparse.ArgumentParser(description="LAN Share V2.0")
parser.add_argument("--port", type=int, default=5000, help="Port HTTP (défaut: 5000)")
parser.add_argument("--name", default=None, help="Nom d'affichage réseau")
return parser.parse_args()
args = parse_args()
APP_PORT = args.port
MY_NAME = args.name or socket.gethostname()
MY_IP = get_local_ip()
# Démarrage du service réseau de découverte
discovery = DiscoveryService(my_id=MY_ID, name=MY_NAME, ip=MY_IP, port=APP_PORT)
discovery.start()
def send_file_thread(peer_url, file_path, filename, mimetype):
"""Effectue l'envoi HTTP POST en tâche de fond pour libérer l'UI immédiatement."""
try:
with open(file_path, 'rb') as f:
files = {"file": (filename, f, mimetype)}
requests.post(peer_url, files=files, timeout=60)
except requests.RequestException as e:
print(f"[-] Échec du transfert vers {peer_url}: {e}")
@app.route("/")
def index():
files = sorted(os.listdir(RECEIVED_DIR))
return render_template("index.html", my_name=MY_NAME, my_ip=MY_IP, files=files)
@app.route("/api/peers")
def api_peers():
return jsonify(discovery.get_peers())
@app.route("/send", methods=["POST"])
def send_file():
target_id = request.form.get("target")
uploaded_files = request.files.getlist("file")
if not uploaded_files or (len(uploaded_files) == 1 and uploaded_files[0].filename == ""):
return jsonify({"error": "Aucun fichier sélectionné"}), 400
peers = discovery.get_peers()
for uploaded in uploaded_files:
if uploaded.filename == "":
continue
filename = secure_filename(uploaded.filename)
save_path = os.path.join(RECEIVED_DIR, filename)
# Sauvegarde locale intermédiaire
uploaded.save(save_path)
# Si un pair est ciblé, on initie l'envoi asynchrone
if target_id and target_id in peers:
peer = peers[target_id]
url = f"http://{peer['ip']}:{peer['port']}/receive"
threading.Thread(
target=send_file_thread,
args=(url, save_path, filename, uploaded.mimetype),
daemon=True
).start()
return jsonify({"status": "Success"}), 200
@app.route("/receive", methods=["POST"])
def receive_file():
uploaded = request.files.get("file")
if uploaded and uploaded.filename:
filename = secure_filename(uploaded.filename)
uploaded.save(os.path.join(RECEIVED_DIR, filename))
return "OK", 200
return "Bad request", 400
@app.route("/delete/<filename>", methods=["POST"])
def delete_file(filename):
safe_name = secure_filename(filename)
file_path = os.path.join(RECEIVED_DIR, safe_name)
if os.path.exists(file_path):
os.remove(file_path)
return jsonify({"status": "Fichier supprimé"}), 200
return jsonify({"error": "Fichier introuvable"}), 404
@app.route("/download/<path:filename>")
def download_file(filename):
return send_from_directory(RECEIVED_DIR, filename, as_attachment=True)
if __name__ == "__main__":
print(f"[*] LAN Share opérationnel sur http://{MY_IP}:{APP_PORT}")
app.run(host="0.0.0.0", port=APP_PORT, threaded=True)