userbymahadi commited on
Commit
d3ca045
·
verified ·
1 Parent(s): b318de8

Upload 2 files

Browse files
Files changed (2) hide show
  1. Dockerfile +1 -18
  2. app.py +29 -130
Dockerfile CHANGED
@@ -1,33 +1,16 @@
1
  FROM python:3.9-slim
2
 
3
- # Rclone প্রয়োজনীয় টুলস ইনস্টল
4
- RUN apt-get update && apt-get install -y rclone procps && rm -rf /var/lib/apt/lists/*
5
 
6
  WORKDIR /home/user/app
7
 
8
- COPY requirements.txt .
9
- RUN pip install --no-cache-dir -r requirements.txt
10
-
11
  COPY . .
12
 
13
- # এন্ট্রি পয়েন্ট স্ক্রিপ্ট তৈরি
14
  RUN echo '#!/bin/bash\n\
15
  mkdir -p /config/rclone\n\
16
- # সিক্রেট ডাটা চেক\n\
17
- if [ -z "$RCLONE_CONF_DATA" ]; then\n\
18
- echo "ERROR: RCLONE_CONF_DATA is empty! Set it in Secrets."\n\
19
- exit 1\n\
20
- fi\n\
21
- \n\
22
  echo "$RCLONE_CONF_DATA" > /config/rclone/rclone.conf\n\
23
- \n\
24
- # ব্যাকগ্রাউন্ডে Rclone চালু (Port 8080)\n\
25
- rclone serve webdav gdrive: --addr :8080 --user "$FTP_USER" --pass "$FTP_PASS" --config /config/rclone/rclone.conf --vfs-cache-mode full &\n\
26
- \n\
27
- # মেইন পাইথন গেটওয়ে চালু\n\
28
  exec python app.py\n\
29
  ' > /entrypoint.sh && chmod +x /entrypoint.sh
30
 
31
  EXPOSE 7860
32
-
33
  CMD ["/entrypoint.sh"]
 
1
  FROM python:3.9-slim
2
 
3
+ RUN apt-get update && apt-get install -y rclone && rm -rf /var/lib/apt/lists/*
 
4
 
5
  WORKDIR /home/user/app
6
 
 
 
 
7
  COPY . .
8
 
 
9
  RUN echo '#!/bin/bash\n\
10
  mkdir -p /config/rclone\n\
 
 
 
 
 
 
11
  echo "$RCLONE_CONF_DATA" > /config/rclone/rclone.conf\n\
 
 
 
 
 
12
  exec python app.py\n\
13
  ' > /entrypoint.sh && chmod +x /entrypoint.sh
14
 
15
  EXPOSE 7860
 
16
  CMD ["/entrypoint.sh"]
app.py CHANGED
@@ -1,136 +1,35 @@
1
  import os
2
- import requests
3
- import traceback
4
- from flask import Flask, render_template_string, request, Response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- app = Flask(__name__)
7
-
8
- # CONFIGURATION
9
- WEBDAV_URL = "http://127.0.0.1:8080"
10
- USER = os.getenv("FTP_USER", "admin")
11
- PASS = os.getenv("FTP_PASS", "123456")
12
-
13
- # MODERN UI DESIGN (Premium NoteLM Theme)
14
- HTML_TEMPLATE = """
15
- <!DOCTYPE html>
16
- <html lang="en">
17
- <head>
18
- <meta charset="UTF-8">
19
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
20
- <title>NoteLM Premium Drive</title>
21
- <script src="https://cdn.tailwindcss.com"></script>
22
- <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
23
- <style>
24
- body { background: #0b0f1a; color: #e2e8f0; font-family: 'Segoe UI', sans-serif; }
25
- .glass-card { background: rgba(23, 32, 51, 0.7); backdrop-filter: blur(16px); border: 1px solid rgba(255, 255, 255, 0.08); box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.5); }
26
- .accent-gradient { background: linear-gradient(135deg, #6366f1 0%, #a855f7 100%); }
27
- .status-dot { height: 8px; width: 8px; border-radius: 50%; display: inline-block; animation: pulse 2s infinite; }
28
- @keyframes pulse { 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7); } 70% { transform: scale(1); box-shadow: 0 0 0 10px rgba(34, 197, 94, 0); } 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); } }
29
- </style>
30
- </head>
31
- <body class="min-h-screen p-4 md:p-10 flex flex-col items-center">
32
- <div class="w-full max-w-5xl">
33
- <div class="glass-card rounded-2xl p-6 mb-8 flex justify-between items-center">
34
- <div class="flex items-center gap-4">
35
- <div class="accent-gradient p-3 rounded-xl shadow-lg">
36
- <i class="fa-solid fa-server text-white text-xl"></i>
37
- </div>
38
- <div>
39
- <h1 class="text-2xl font-bold tracking-tight">NoteLM <span class="text-indigo-400">Cloud</span></h1>
40
- <p class="text-xs text-gray-500 uppercase tracking-widest font-semibold">Secure Storage Gateway</p>
41
- </div>
42
- </div>
43
- <div class="flex items-center gap-3 bg-black/20 px-4 py-2 rounded-full border border-white/5">
44
- <span class="status-dot bg-green-500"></span>
45
- <span class="text-xs font-medium text-green-400">System Online</span>
46
- </div>
47
- </div>
48
-
49
- <div class="glass-card rounded-2xl overflow-hidden shadow-2xl">
50
- <div class="p-6 border-b border-white/5 flex justify-between items-center">
51
- <h3 class="font-bold text-lg">Connected Devices</h3>
52
- <button class="text-xs bg-indigo-500/10 hover:bg-indigo-500/20 text-indigo-400 px-4 py-2 rounded-lg transition border border-indigo-500/20">
53
- <i class="fa-solid fa-sync-alt mr-2"></i>Refresh
54
- </button>
55
- </div>
56
- <div class="overflow-x-auto">
57
- <table class="w-full text-left">
58
- <thead class="bg-white/5 text-gray-400 text-[11px] uppercase tracking-wider">
59
- <tr>
60
- <th class="px-6 py-4">Resource</th>
61
- <th class="px-6 py-4">Protocol</th>
62
- <th class="px-6 py-4">Security</th>
63
- <th class="px-6 py-4 text-center">Status</th>
64
- </tr>
65
- </thead>
66
- <tbody class="divide-y divide-white/5">
67
- <tr class="hover:bg-white/[0.02] transition-colors">
68
- <td class="px-6 py-5 flex items-center gap-3">
69
- <i class="fa-brands fa-google-drive text-blue-400 text-lg"></i>
70
- <span class="text-sm font-medium">Google Drive Root</span>
71
- </td>
72
- <td class="px-6 py-5">
73
- <span class="bg-blue-500/10 text-blue-400 text-[10px] px-2 py-1 rounded-md font-bold border border-blue-500/20">WEBDAV / FTP</span>
74
- </td>
75
- <td class="px-6 py-5 text-sm text-gray-400">AES-256 Encrypted</td>
76
- <td class="px-6 py-5 text-center">
77
- <i class="fa-solid fa-circle-check text-green-500"></i>
78
- </td>
79
- </tr>
80
- </tbody>
81
- </table>
82
- </div>
83
- </div>
84
-
85
- <footer class="mt-10 text-center">
86
- <p class="text-gray-600 text-[10px] uppercase tracking-[0.3em]">Encrypted Bridge by Mahadi • 2026</p>
87
- </footer>
88
- </div>
89
- </body>
90
- </html>
91
- """
92
-
93
- @app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PROPFIND', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK'])
94
- @app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE', 'PROPFIND', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK'])
95
- def proxy_gateway(path):
96
  try:
97
- # যদি ব্রাউজার থেকে স্বাভাবিক ভিজিট করা হয় (GET Request)
98
- if request.method == 'GET' and 'PROPFIND' not in request.headers and not path:
99
- print(f"[TRACK] Browser access detected. Serving UI.")
100
- return render_template_string(HTML_TEMPLATE)
101
-
102
- # WebDAV রিকোয়েস্ট হ্যান্ডেল করা (App থেকে আসা)
103
- target_url = f"{WEBDAV_URL}/{path}"
104
- print(f"[TRACK] Proxying {request.method} request to: {target_url}")
105
-
106
- # হেডার থেকে 'host' বাদ দিয়ে কপি করা
107
- headers = {key: value for (key, value) in request.headers if key.lower() != 'host'}
108
-
109
- # Rclone এ রিকোয়েস্ট পাঠানো
110
- response = requests.request(
111
- method=request.method,
112
- url=target_url,
113
- headers=headers,
114
- data=request.get_data(),
115
- cookies=request.cookies,
116
- allow_redirects=False,
117
- auth=(USER, PASS),
118
- stream=True # বড় ফাইলের জন্য স্ট্রীমিং জরুরি
119
- )
120
-
121
- # রেসপন্স হেডার ফিল্টার করা
122
- excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
123
- resp_headers = [(name, value) for (name, value) in response.raw.headers.items()
124
- if name.lower() not in excluded_headers]
125
-
126
- print(f"[TRACK] Success: {response.status_code}")
127
- return Response(response.iter_content(chunk_size=1024), response.status_code, resp_headers)
128
-
129
  except Exception as e:
130
- # এরর ট্র্যাকিং (Error Capture)
131
- error_msg = traceback.format_exc()
132
- print(f"--- ERROR CAPTURED --- \n{error_msg}\n-----------------------")
133
- return f"NoteLM Gateway Error: {str(e)}", 500
134
 
135
  if __name__ == "__main__":
136
- app.run(host='0.0.0.0', port=7860, debug=False)
 
 
 
1
  import os
2
+ import subprocess
3
+ import time
4
+
5
+ def start_services():
6
+ # সিক্রেট থেকে তথ্য নেওয়া
7
+ USER = os.getenv("FTP_USER", "admin")
8
+ PASS = os.getenv("FTP_PASS", "123456")
9
+ RCLONE_CONF = "/config/rclone/rclone.conf"
10
+
11
+ print("[SYSTEM] Starting Rclone WebDAV & Modern UI...")
12
+
13
+ # Rclone কমান্ড যা একই সাথে WebDAV এবং Web UI চালাবে
14
+ # --baseurl ব্যবহার করা হয়েছে যাতে Hugging Face এ পাথ ঠিক থাকে
15
+ cmd = [
16
+ "rclone", "serve", "webdav", "gdrive:",
17
+ "--addr", ":7860",
18
+ "--user", USER,
19
+ "--pass", PASS,
20
+ "--config", RCLONE_CONF,
21
+ "--vfs-cache-mode", "full",
22
+ "--ui", # এটি আধুনিক GUI এনাবেল করবে
23
+ "--ui-no-auth", # মূল লিঙ্কে ঢোকার জন্য UI আলাদা পাসওয়ার্ড চাইবে না (সিকিউরিটি মেইন পাসওয়ার্ডেই থাকবে)
24
+ ]
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  try:
27
+ process = subprocess.Popen(cmd)
28
+ process.wait()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  except Exception as e:
30
+ print(f"[ERROR] Service crashed: {str(e)}")
 
 
 
31
 
32
  if __name__ == "__main__":
33
+ # rclone.conf তৈরি হওয়ার জন্য ১ সেকেন্ড অপেক্ষা
34
+ time.sleep(1)
35
+ start_services()