Khaneja commited on
Commit
fbc4e93
·
1 Parent(s): f373b09

feat: intelligent filename construction using yt-dlp metadata (Artist, Track, Channel)

Browse files
Files changed (2) hide show
  1. app.py +34 -6
  2. templates/index.html +5 -0
app.py CHANGED
@@ -60,11 +60,23 @@ def run_download(job_id, url, format_choice, format_id):
60
  job["status"] = "done"
61
  job["file"] = chosen
62
  ext = os.path.splitext(chosen)[1]
63
- title = job.get("title", "").strip()
64
- # Sanitize title for filename
65
- if title:
66
- safe_title = "".join(c for c in title if c not in r'\/:*?"<>|').strip()[:20].strip()
67
- job["filename"] = f"{safe_title}{ext}" if safe_title else os.path.basename(chosen)
 
 
 
 
 
 
 
 
 
 
 
 
68
  else:
69
  job["filename"] = os.path.basename(chosen)
70
  except subprocess.TimeoutExpired:
@@ -131,11 +143,16 @@ def get_info():
131
  })
132
  audio_formats.sort(key=lambda x: x["abr"], reverse=True)
133
 
 
 
 
134
  return jsonify({
135
  "title": info.get("title", ""),
136
  "thumbnail": info.get("thumbnail", ""),
137
  "duration": info.get("duration"),
138
  "uploader": info.get("uploader", ""),
 
 
139
  "formats": formats,
140
  "audioFormats": audio_formats,
141
  })
@@ -152,12 +169,23 @@ def start_download():
152
  format_choice = data.get("format", "video")
153
  format_id = data.get("format_id")
154
  title = data.get("title", "")
 
 
 
155
 
156
  if not url:
157
  return jsonify({"error": "No URL provided"}), 400
158
 
159
  job_id = uuid.uuid4().hex[:10]
160
- jobs[job_id] = {"status": "downloading", "url": url, "title": title}
 
 
 
 
 
 
 
 
161
 
162
  thread = threading.Thread(target=run_download, args=(job_id, url, format_choice, format_id))
163
  thread.daemon = True
 
60
  job["status"] = "done"
61
  job["file"] = chosen
62
  ext = os.path.splitext(chosen)[1]
63
+
64
+ is_audio = job.get("format_choice") == "audio"
65
+ artist = job.get("artist", "")
66
+ track = job.get("track", "")
67
+ uploader = job.get("uploader", "")
68
+ title = job.get("title", "")
69
+
70
+ if is_audio and artist and track:
71
+ raw_name = f"{artist} - {track}"
72
+ elif uploader and title:
73
+ raw_name = f"{uploader} - {title}"
74
+ else:
75
+ raw_name = title.strip()
76
+
77
+ if raw_name:
78
+ safe_name = "".join(c for c in raw_name if c not in r'\/:*?"<>|').strip()[:80].strip()
79
+ job["filename"] = f"{safe_name}{ext}" if safe_name else os.path.basename(chosen)
80
  else:
81
  job["filename"] = os.path.basename(chosen)
82
  except subprocess.TimeoutExpired:
 
143
  })
144
  audio_formats.sort(key=lambda x: x["abr"], reverse=True)
145
 
146
+ art = info.get("artist")
147
+ artist_str = ", ".join(art) if isinstance(art, list) else str(art or "").strip()
148
+
149
  return jsonify({
150
  "title": info.get("title", ""),
151
  "thumbnail": info.get("thumbnail", ""),
152
  "duration": info.get("duration"),
153
  "uploader": info.get("uploader", ""),
154
+ "artist": artist_str,
155
+ "track": str(info.get("track") or "").strip(),
156
  "formats": formats,
157
  "audioFormats": audio_formats,
158
  })
 
169
  format_choice = data.get("format", "video")
170
  format_id = data.get("format_id")
171
  title = data.get("title", "")
172
+ artist = data.get("artist", "")
173
+ track = data.get("track", "")
174
+ uploader = data.get("uploader", "")
175
 
176
  if not url:
177
  return jsonify({"error": "No URL provided"}), 400
178
 
179
  job_id = uuid.uuid4().hex[:10]
180
+ jobs[job_id] = {
181
+ "status": "downloading",
182
+ "url": url,
183
+ "title": title,
184
+ "artist": artist,
185
+ "track": track,
186
+ "uploader": uploader,
187
+ "format_choice": format_choice
188
+ }
189
 
190
  thread = threading.Thread(target=run_download, args=(job_id, url, format_choice, format_id))
191
  thread.daemon = True
templates/index.html CHANGED
@@ -595,6 +595,8 @@
595
  thumbnail: data.thumbnail || '',
596
  duration: data.duration,
597
  uploader: data.uploader || '',
 
 
598
  formats: data.formats || [],
599
  selectedFormatId: data.formats?.[0]?.id || null,
600
  audioFormats: data.audioFormats || [],
@@ -739,6 +741,9 @@
739
  format: currentFormat,
740
  format_id: payloadFormatId,
741
  title: c.title || '',
 
 
 
742
  }),
743
  });
744
  const data = await res.json();
 
595
  thumbnail: data.thumbnail || '',
596
  duration: data.duration,
597
  uploader: data.uploader || '',
598
+ artist: data.artist || '',
599
+ track: data.track || '',
600
  formats: data.formats || [],
601
  selectedFormatId: data.formats?.[0]?.id || null,
602
  audioFormats: data.audioFormats || [],
 
741
  format: currentFormat,
742
  format_id: payloadFormatId,
743
  title: c.title || '',
744
+ artist: c.artist || '',
745
+ track: c.track || '',
746
+ uploader: c.uploader || ''
747
  }),
748
  });
749
  const data = await res.json();