Skip to content

Commit e022b2f

Browse files
authored
Add files via upload
1 parent c909083 commit e022b2f

1 file changed

Lines changed: 388 additions & 0 deletions

File tree

Lines changed: 388 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,388 @@
1+
# ==========================================================
2+
# ShareFlow - Startup File Sharing SaaS
3+
# Modern Cloud File Distribution Platform
4+
# ==========================================================
5+
6+
import os
7+
import uuid
8+
import sqlite3
9+
from datetime import datetime
10+
11+
from flask import (
12+
Flask, request, redirect, url_for,
13+
render_template_string, session,
14+
send_from_directory
15+
)
16+
17+
from werkzeug.security import generate_password_hash, check_password_hash
18+
from werkzeug.utils import secure_filename
19+
20+
21+
# =================== CONFIG ===================
22+
23+
APP_NAME = "ShareFlow"
24+
APP_VERSION = "1.0"
25+
26+
UPLOAD_FOLDER = "storage"
27+
DATABASE = "shareflow.db"
28+
29+
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
30+
31+
32+
# =================== APP ===================
33+
34+
app = Flask(__name__)
35+
app.secret_key = "dev-secret"
36+
37+
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER
38+
39+
40+
# =================== DATABASE ===================
41+
42+
def db():
43+
conn = sqlite3.connect(DATABASE)
44+
conn.row_factory = sqlite3.Row
45+
return conn
46+
47+
48+
def init_db():
49+
50+
conn = db()
51+
52+
conn.execute("""
53+
CREATE TABLE IF NOT EXISTS users(
54+
id INTEGER PRIMARY KEY,
55+
username TEXT UNIQUE,
56+
password TEXT
57+
)
58+
""")
59+
60+
conn.execute("""
61+
CREATE TABLE IF NOT EXISTS files(
62+
id TEXT PRIMARY KEY,
63+
user_id INTEGER,
64+
filename TEXT,
65+
path TEXT,
66+
size INTEGER,
67+
downloads INTEGER,
68+
created TEXT
69+
)
70+
""")
71+
72+
conn.commit()
73+
conn.close()
74+
75+
76+
# =================== USER ===================
77+
78+
def current_user():
79+
80+
if "user_id" not in session:
81+
return None
82+
83+
conn = db()
84+
85+
user = conn.execute(
86+
"SELECT * FROM users WHERE id=?",
87+
(session["user_id"],)
88+
).fetchone()
89+
90+
conn.close()
91+
92+
return user
93+
94+
95+
# =================== AUTH ===================
96+
97+
@app.route("/register", methods=["GET","POST"])
98+
def register():
99+
100+
if request.method == "POST":
101+
102+
username = request.form["username"]
103+
password = generate_password_hash(request.form["password"])
104+
105+
conn = db()
106+
107+
conn.execute(
108+
"INSERT INTO users(username,password) VALUES(?,?)",
109+
(username,password)
110+
)
111+
112+
conn.commit()
113+
conn.close()
114+
115+
return redirect("/login")
116+
117+
return """
118+
<h2>Register</h2>
119+
<form method="post">
120+
<input name="username">
121+
<input name="password" type="password">
122+
<button>Register</button>
123+
</form>
124+
"""
125+
126+
127+
@app.route("/login", methods=["GET","POST"])
128+
def login():
129+
130+
if request.method == "POST":
131+
132+
username = request.form["username"]
133+
password = request.form["password"]
134+
135+
conn = db()
136+
137+
user = conn.execute(
138+
"SELECT * FROM users WHERE username=?",
139+
(username,)
140+
).fetchone()
141+
142+
conn.close()
143+
144+
if user and check_password_hash(user["password"],password):
145+
146+
session["user_id"] = user["id"]
147+
148+
return redirect("/dashboard")
149+
150+
return """
151+
<h2>Login</h2>
152+
<form method="post">
153+
<input name="username">
154+
<input name="password" type="password">
155+
<button>Login</button>
156+
</form>
157+
"""
158+
159+
160+
# =================== DASHBOARD ===================
161+
162+
@app.route("/")
163+
@app.route("/dashboard")
164+
def dashboard():
165+
166+
user = current_user()
167+
168+
if not user:
169+
return redirect("/login")
170+
171+
conn = db()
172+
173+
files = conn.execute(
174+
"SELECT * FROM files WHERE user_id=?",
175+
(user["id"],)
176+
).fetchall()
177+
178+
conn.close()
179+
180+
return render_template_string(DASHBOARD_HTML, files=files)
181+
182+
183+
# =================== UPLOAD ===================
184+
185+
@app.route("/upload", methods=["POST"])
186+
def upload():
187+
188+
user = current_user()
189+
190+
if not user:
191+
return redirect("/login")
192+
193+
file = request.files["file"]
194+
195+
filename = secure_filename(file.filename)
196+
197+
file_id = str(uuid.uuid4())[:10]
198+
199+
path = os.path.join(
200+
UPLOAD_FOLDER,
201+
file_id + "_" + filename
202+
)
203+
204+
file.save(path)
205+
206+
size = os.path.getsize(path)
207+
208+
conn = db()
209+
210+
conn.execute("""
211+
INSERT INTO files
212+
VALUES(?,?,?,?,?,?,?)
213+
""",(
214+
file_id,
215+
user["id"],
216+
filename,
217+
path,
218+
size,
219+
0,
220+
datetime.now()
221+
))
222+
223+
conn.commit()
224+
conn.close()
225+
226+
return redirect("/dashboard")
227+
228+
229+
# =================== DOWNLOAD ===================
230+
231+
@app.route("/f/<file_id>")
232+
def download(file_id):
233+
234+
conn = db()
235+
236+
file = conn.execute(
237+
"SELECT * FROM files WHERE id=?",
238+
(file_id,)
239+
).fetchone()
240+
241+
conn.close()
242+
243+
if not file:
244+
return "File not found"
245+
246+
conn = db()
247+
248+
conn.execute(
249+
"UPDATE files SET downloads = downloads + 1 WHERE id=?",
250+
(file_id,)
251+
)
252+
253+
conn.commit()
254+
conn.close()
255+
256+
directory = os.path.dirname(file["path"])
257+
filename = os.path.basename(file["path"])
258+
259+
return send_from_directory(directory, filename, as_attachment=True)
260+
261+
262+
# =================== DELETE ===================
263+
264+
@app.route("/delete/<file_id>")
265+
def delete(file_id):
266+
267+
conn = db()
268+
269+
file = conn.execute(
270+
"SELECT * FROM files WHERE id=?",
271+
(file_id,)
272+
).fetchone()
273+
274+
if file:
275+
276+
try:
277+
os.remove(file["path"])
278+
except:
279+
pass
280+
281+
conn.execute(
282+
"DELETE FROM files WHERE id=?",
283+
(file_id,)
284+
)
285+
286+
conn.commit()
287+
288+
conn.close()
289+
290+
return redirect("/dashboard")
291+
292+
293+
# =================== UI ===================
294+
295+
DASHBOARD_HTML = """
296+
<!DOCTYPE html>
297+
<html>
298+
299+
<head>
300+
301+
<title>ShareFlow</title>
302+
303+
<script src="https://cdn.tailwindcss.com"></script>
304+
305+
</head>
306+
307+
<body class="bg-gray-100">
308+
309+
<div class="max-w-4xl mx-auto p-8">
310+
311+
<h1 class="text-3xl font-bold mb-6">ShareFlow Dashboard</h1>
312+
313+
<form
314+
action="/upload"
315+
method="post"
316+
enctype="multipart/form-data"
317+
class="mb-6 p-6 bg-white rounded shadow">
318+
319+
<input type="file" name="file" class="mb-3">
320+
321+
<button class="bg-blue-500 text-white px-4 py-2 rounded">
322+
Upload File
323+
</button>
324+
325+
</form>
326+
327+
<div class="bg-white shadow rounded">
328+
329+
<table class="w-full">
330+
331+
<tr class="border-b">
332+
<th class="p-3 text-left">File</th>
333+
<th>Size</th>
334+
<th>Downloads</th>
335+
<th>Share</th>
336+
<th></th>
337+
</tr>
338+
339+
{% for f in files %}
340+
341+
<tr class="border-b">
342+
343+
<td class="p-3">{{f.filename}}</td>
344+
345+
<td>{{(f.size/1024/1024)|round(2)}} MB</td>
346+
347+
<td>{{f.downloads}}</td>
348+
349+
<td>
350+
<a class="text-blue-600"
351+
href="/f/{{f.id}}">
352+
link
353+
</a>
354+
</td>
355+
356+
<td>
357+
<a class="text-red-500"
358+
href="/delete/{{f.id}}">
359+
delete
360+
</a>
361+
</td>
362+
363+
</tr>
364+
365+
{% endfor %}
366+
367+
</table>
368+
369+
</div>
370+
371+
</div>
372+
373+
</body>
374+
375+
</html>
376+
"""
377+
378+
379+
# =================== START ===================
380+
381+
if __name__ == "__main__":
382+
383+
init_db()
384+
385+
print("ShareFlow starting...")
386+
print("http://127.0.0.1:5000")
387+
388+
app.run(debug=True)

0 commit comments

Comments
 (0)