Skip to content

Commit d473bba

Browse files
author
SM_SAYEED
committed
clips are backed by now by drive and github instead of drive + database
1 parent 6a6f0d5 commit d473bba

File tree

4 files changed

+145
-161
lines changed

4 files changed

+145
-161
lines changed

app.py

Lines changed: 51 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from werkzeug.utils import secure_filename
88
import datetime
99
import re
10-
10+
import csv
1111
# ========== SETTINGS ==========
1212
UPLOAD_FOLDER = 'uploads'
1313
DB_NAME = 'patterns-matter.db'
@@ -413,68 +413,26 @@ def extract_drive_id(link):
413413
return match.group(1)
414414
raise ValueError("Invalid Drive link")
415415

416-
@app.route('/clips', methods=['GET', 'POST'])
416+
@app.route('/clips')
417417
def public_clips():
418418
admin = session.get('admin', False)
419-
message = ""
420-
db_filename = None
421-
422-
if admin and request.method == 'POST':
423-
action = request.form.get('action', '')
424-
title = request.form.get('title', '').strip()
425-
description = request.form.get('description', '').strip()
426-
427-
if not title:
428-
message = "Title is required."
429-
elif action == 'upload_file':
430-
file = request.files.get('file')
431-
if not file or not allowed_music_file(file.filename):
432-
message = "Please upload a valid music or video file."
433-
else:
434-
filename = secure_filename(file.filename)
435-
upload_folder = os.path.join(app.config['UPLOAD_FOLDER'], 'clips')
436-
os.makedirs(upload_folder, exist_ok=True)
437-
filepath = os.path.join(upload_folder, filename)
438-
file.save(filepath)
439-
db_filename = 'clips/' + filename
440-
441-
elif action == 'drive_link':
442-
link = request.form.get('link', '').strip()
443-
try:
444-
file_id = extract_drive_id(link)
445-
preview_url = f"https://drive.google.com/file/d/{file_id}/preview"
446-
download_url = f"https://drive.google.com/uc?export=download&id={file_id}"
447-
db_filename = f"{preview_url}||{download_url}"
448-
except Exception as e:
449-
message = f"Invalid Google Drive link. ({e})"
450-
451-
if db_filename:
452-
try:
453-
with sqlite3.connect(DB_NAME) as conn:
454-
c = conn.cursor()
455-
c.execute(
456-
"INSERT INTO music_clips (filename, title, description) VALUES (?, ?, ?)",
457-
(db_filename, title, description)
458-
)
459-
conn.commit()
460-
message = "Clip added!"
461-
except Exception as e:
462-
message = "Error saving to database: " + str(e)
419+
clips = []
463420

464-
# Fetch all clips
465421
try:
466-
with sqlite3.connect(DB_NAME) as conn:
467-
c = conn.cursor()
468-
c.execute("SELECT id, filename, title, description FROM music_clips")
469-
clips = [
470-
(id, filename.replace('\\', '/'), title, description)
471-
for (id, filename, title, description) in c.fetchall()
472-
]
473-
except sqlite3.OperationalError:
422+
with open('drive_music.csv', encoding='utf-8') as f:
423+
reader = csv.DictReader(f)
424+
for row in reader:
425+
title = row.get('title', '').strip()
426+
description = row.get('description', '').strip()
427+
preview = row.get('preview_url', '').strip()
428+
download = row.get('download_url', '').strip()
429+
if preview and download:
430+
clips.append((preview, download, title, description))
431+
except Exception as e:
432+
print("Error reading drive_music.csv:", e)
474433
clips = []
475434

476-
return render_template('clips.html', clips=clips, admin=admin, message=message)
477-
435+
return render_template('clips.html', clips=clips, admin=admin)
478436

479437
@app.route('/dataset/<table>')
480438
def public_view(table):
@@ -569,6 +527,42 @@ def delete_dataset_file(property_name, tab, filename):
569527
conn.commit()
570528
return redirect(url_for('property_detail', property_name=property_name, tab=tab))
571529

530+
@app.route('/add_drive_clip', methods=['GET', 'POST'])
531+
def add_drive_clip():
532+
if not session.get('admin'):
533+
return redirect(url_for('login'))
534+
535+
message = ""
536+
if request.method == 'POST':
537+
link = request.form.get('link', '').strip()
538+
title = request.form.get('title', '').strip()
539+
description = request.form.get('description', '').strip()
540+
541+
def extract_drive_id(link):
542+
match = re.search(r'/d/([a-zA-Z0-9_-]+)', link)
543+
if match:
544+
return match.group(1)
545+
match = re.search(r'id=([a-zA-Z0-9_-]+)', link)
546+
if match:
547+
return match.group(1)
548+
return None
549+
550+
file_id = extract_drive_id(link)
551+
if file_id and title:
552+
preview_url = f"https://drive.google.com/file/d/{file_id}/preview"
553+
download_url = f"https://drive.google.com/uc?export=download&id={file_id}"
554+
try:
555+
with open('drive_music.csv', 'a', newline='', encoding='utf-8') as f:
556+
writer = csv.writer(f)
557+
writer.writerow([title, description, preview_url, download_url])
558+
message = "✅ Clip added successfully!"
559+
except Exception as e:
560+
message = f"❌ Error writing to CSV: {e}"
561+
else:
562+
message = "❌ Invalid link or missing title."
563+
564+
return render_template('add_drive_clip.html', message=message)
565+
572566
# --- Print routes for debugging (optional, can comment out) ---
573567
for rule in app.url_map.iter_rules():
574568
print(rule.endpoint, rule)

drive_music.csv

Whitespace-only changes.

templates/add_drive_clip.html

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Add Drive Clip | Patterns Matter</title>
5+
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
6+
<style>
7+
body {
8+
font-family: sans-serif;
9+
color: #f1f1f1;
10+
background: #1e1e1e;
11+
}
12+
.container {
13+
max-width: 600px;
14+
margin: 3em auto;
15+
background: #2d2d2d;
16+
padding: 2em;
17+
border-radius: 12px;
18+
box-shadow: 0 2px 10px #0005;
19+
}
20+
label {
21+
font-weight: bold;
22+
display: block;
23+
margin-top: 1.2em;
24+
}
25+
input[type="text"] {
26+
width: 100%;
27+
padding: 0.6em;
28+
border-radius: 6px;
29+
border: 1px solid #888;
30+
background: #111;
31+
color: #fff;
32+
}
33+
button {
34+
margin-top: 1.5em;
35+
padding: 0.6em 2em;
36+
background: #2a6;
37+
color: #fff;
38+
border: none;
39+
font-weight: bold;
40+
border-radius: 6px;
41+
cursor: pointer;
42+
}
43+
button:hover {
44+
background: #225c44;
45+
}
46+
.msg {
47+
margin-top: 1.5em;
48+
font-weight: bold;
49+
color: #ffc;
50+
}
51+
a { color: #6af; }
52+
</style>
53+
</head>
54+
<body>
55+
<div class="container">
56+
<h2>Add Google Drive Clip</h2>
57+
<form method="post">
58+
<label>Title:</label>
59+
<input type="text" name="title" required>
60+
61+
<label>Description:</label>
62+
<input type="text" name="description">
63+
64+
<label>Google Drive Share Link:</label>
65+
<input type="text" name="link" placeholder="https://drive.google.com/..." required>
66+
67+
<button type="submit">Add Clip</button>
68+
</form>
69+
70+
{% if message %}
71+
<div class="msg">{{ message }}</div>
72+
{% endif %}
73+
74+
<p style="margin-top:2em;"><a href="{{ url_for('public_clips') }}">← Back to Clips</a></p>
75+
</div>
76+
</body>
77+
</html>

templates/clips.html

Lines changed: 17 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -12,41 +12,13 @@
1212
box-shadow: 0 1px 6px #2224;
1313
color: #f1f1f1;
1414
}
15-
.upload-form input[type="file"], .upload-form input[type="text"] {
16-
margin: 0.7em 0.5em 0.7em 0;
17-
}
18-
.upload-form button[type="submit"] {
19-
background: #2a6;
20-
color: #fff;
21-
border-radius: 6px;
22-
padding: 0.4em 1.5em;
23-
font-weight: bold;
24-
border: none;
25-
cursor: pointer;
26-
}
27-
.upload-form button[type="submit"]:hover {
28-
background: #225c44;
29-
}
3015
.admin-link a {
3116
color: #fff;
3217
text-decoration: none;
3318
margin-left: 1em;
3419
font-weight: bold;
3520
}
3621
.admin-link a:hover { text-decoration: underline; }
37-
.delete-btn {
38-
background:#d33;
39-
color:#fff;
40-
border:none;
41-
padding:0.3em 1em;
42-
border-radius:6px;
43-
margin-left:1em;
44-
cursor:pointer;
45-
font-weight: bold;
46-
}
47-
.delete-btn:hover {
48-
background:#a22;
49-
}
5022
</style>
5123
</head>
5224
<body>
@@ -62,86 +34,27 @@
6234

6335
<h1>Music & Guitar Clips</h1>
6436

65-
{% if session.admin %}
66-
<div class="upload-form" style="margin-bottom:2em;">
67-
<h3>Upload a Music/Video File</h3>
68-
<form action="{{ url_for('public_clips') }}" method="post" enctype="multipart/form-data">
69-
<input type="hidden" name="action" value="upload_file">
70-
<p><input type="file" name="file" required></p>
71-
<p><input type="text" name="title" placeholder="Title" required></p>
72-
<p><input type="text" name="description" placeholder="Description"></p>
73-
<p><button type="submit">Upload Clip</button></p>
74-
</form>
75-
</div>
76-
77-
<div class="upload-form" style="margin-bottom:2em;">
78-
<h3>Add a Clip from Google Drive</h3>
79-
<form action="{{ url_for('public_clips') }}" method="post">
80-
<input type="hidden" name="action" value="drive_link">
81-
<p><input type="text" name="title" placeholder="Title" required></p>
82-
<p><input type="text" name="description" placeholder="Description"></p>
83-
<p><input type="text" name="link" placeholder="Paste Google Drive Share Link Here" style="width: 100%;" required></p>
84-
<p>
85-
<label><strong>Type:</strong></label>
86-
<select name="media_type" required>
87-
<option value="audio">Audio (.mp3)</option>
88-
<option value="video">Video (.mp4)</option>
89-
</select>
90-
</p>
91-
<p><button type="submit">Add Drive Content</button></p>
92-
</form>
93-
</div>
94-
95-
{% if message %}
96-
<div style="color:green;">{{ message }}</div>
37+
{% if admin %}
38+
<p style="margin-top: 1em;">
39+
<a href="{{ url for ('add_drive_clip')}}" style="color: #6af; font-weight:bold;">
40+
➕ Add Drive Clip via Form
41+
</a> |
42+
</p>
9743
{% endif %}
98-
{% endif %}
99-
100-
{% if clips and clips|length > 0 %}
101-
{% for id, filename, title, description in clips %}
102-
{% set is_drive = 'drive.google.com' in filename %}
103-
{% set is_split = '||' in filename %}
104-
{% if is_split %}
105-
{% set preview_url = filename.split('||')[0] %}
106-
{% set download_url = filename.split('||')[1] %}
107-
{% else %}
108-
{% set preview_url = url_for('uploaded_file', filename=filename) %}
109-
{% set download_url = url_for('uploaded_file', filename=filename) %}
110-
{% endif %}
111-
112-
<div class="section">
113-
<b>{{ title }}</b><br>
114-
<small>{{ description }}</small><br>
115-
116-
{% if is_drive %}
117-
<iframe src="{{ preview_url }}" width="380" height="240" allow="autoplay" allowfullscreen style="margin-top:0.7em;"></iframe>
118-
{% else %}
119-
{% set is_video = filename.endswith('.mp4') or filename.endswith('.webm') or filename.endswith('.mov') %}
120-
{% set is_audio = filename.endswith('.mp3') or filename.endswith('.wav') or filename.endswith('.m4a') or filename.endswith('.ogg') %}
121-
{% if is_video %}
122-
<video controls width="380" style="margin-top:0.7em;">
123-
<source src="{{ preview_url }}">
124-
Your browser does not support the video tag.
125-
</video>
126-
{% elif is_audio %}
127-
<audio controls style="margin-top:0.7em; width: 260px;">
128-
<source src="{{ preview_url }}">
129-
Your browser does not support the audio element.
130-
</audio>
131-
{% endif %}
132-
{% endif %}
44+
45+
{% if clips %}
46+
{% for preview, download, title, description in clips %}
47+
<div class="section">
48+
<b>{{ title }}</b><br>
49+
<small>{{ description }}</small><br>
13350

134-
<br>
135-
<a href="{{ download_url }}" target="_blank">Download</a>
136-
{% if admin %}
137-
<form action="{{ url_for('delete_clip', clip_id=id) }}" method="post" style="display:inline;" onsubmit="return confirm('Are you sure you want to delete this clip?');">
138-
<button type="submit" class="delete-btn">Delete</button>
139-
</form>
140-
{% endif %}
141-
</div>
51+
<iframe src="{{ preview }}" width="380" height="240" allow="autoplay" allowfullscreen style="margin-top:0.7em;"></iframe>
52+
<br>
53+
<a href="{{ download }}" target="_blank">Download</a>
54+
</div>
14255
{% endfor %}
14356
{% else %}
144-
<p>No music clips uploaded yet. Please check back later!</p>
57+
<p>No music clips listed in <code>drive_music.csv</code></p>
14558
{% endif %}
14659

14760
<div style="margin-top:2em;">

0 commit comments

Comments
 (0)