Ribot commited on
Commit
96682d9
·
verified ·
1 Parent(s): 50c8ca2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -85
app.py CHANGED
@@ -1,110 +1,113 @@
1
- import os
2
- import re
3
- import zipfile
4
- import requests
5
- import tempfile
6
  import subprocess
7
- import gradio as gr
8
- import shutil
 
 
 
9
 
10
- # Installation automatique des dépendances si nécessaire
11
  try:
12
- import bs4
 
 
 
 
 
13
  except ImportError:
14
- subprocess.run(["pip", "install", "-q", "gradio", "beautifulsoup4", "requests"])
15
-
 
 
 
 
 
 
 
 
16
  def sanitize_filename(name):
17
- # Rend le nom de fichier compatible avec tous les OS
18
- return re.sub(r"[^\w\-_.]", "_", name.strip())[:50]
19
 
 
20
  def extract_mp3_links_and_titles(html_text):
21
- # Expression pour trouver les URL MP3
22
- mp3_pattern = re.compile(r'https?://[^\s"\'<>]+\.mp3')
23
- mp3_links = mp3_pattern.findall(html_text)
24
-
25
- # Expression pour tenter d'extraire les titres associés
26
- item_pattern = re.compile(
27
- r'title:"\\?"([^"]+)\\?".*?url:"(https?://[^\s"\'<>]+\.mp3)"',
28
- re.DOTALL
29
- )
30
- titled_links = {match[1]: match[0] for match in item_pattern.findall(html_text)}
31
-
32
- results = []
33
- for link in mp3_links:
34
- title = titled_links.get(link, None)
35
- results.append((link, title))
36
- return results
37
-
38
- def download_and_zip_mp3s(url):
 
 
39
  try:
40
  response = requests.get(url)
41
  response.raise_for_status()
42
  except Exception as e:
43
- return f"Erreur de téléchargement de la page : {e}", None
44
 
45
  html_text = response.text
46
  mp3_entries = extract_mp3_links_and_titles(html_text)
47
 
48
  if not mp3_entries:
49
- return "Aucun lien .mp3 trouvé sur cette page.", None
50
 
51
- # package dans Zip
52
- def download_and_zip_mp3s(url):
53
- try:
54
- response = requests.get(url)
55
- response.raise_for_status()
56
- except Exception as e:
57
- return f"Erreur de téléchargement de la page : {e}", None
58
 
59
- html_text = response.text
60
- mp3_entries = extract_mp3_links_and_titles(html_text)
61
 
62
- if not mp3_entries:
63
- return "Aucun lien .mp3 trouvé sur cette page.", None
 
 
64
 
65
- temp_dir = tempfile.mkdtemp()
66
- try:
67
- zip_fd, zip_path = tempfile.mkstemp(suffix=".zip", prefix="episodes_")
68
- os.close(zip_fd) # On ferme le descripteur immédiatement
69
-
70
- with zipfile.ZipFile(zip_path, "w") as zipf:
71
- for idx, (mp3_url, title) in enumerate(mp3_entries, 1):
72
- if title:
73
- filename = f"{idx:02d}-{sanitize_filename(title)}.mp3"
74
- else:
75
- filename = f"{idx:02d}-episode.mp3"
76
- filepath = os.path.join(temp_dir, filename)
77
- try:
78
- print(f"Téléchargement : {mp3_url}")
79
- audio_resp = requests.get(mp3_url)
80
- audio_resp.raise_for_status()
81
- if len(audio_resp.content) < 30_000:
82
- print(f"Fichier trop petit, ignoré : {mp3_url}")
83
- continue
84
- with open(filepath, "wb") as f:
85
- f.write(audio_resp.content)
86
- zipf.write(filepath, arcname=filename)
87
- except Exception as e:
88
- print(f"Erreur lors du téléchargement de {mp3_url} : {e}")
89
- return "Téléchargement terminé avec succès.", zip_path
90
- finally:
91
- shutil.rmtree(temp_dir)
92
-
93
- def gradio_interface(url):
94
- message, zip_file = download_and_zip_mp3s(url)
95
- return message, zip_file
96
 
97
  # Interface Gradio
98
- demo = gr.Interface(
99
- fn=gradio_interface,
100
- inputs=gr.Textbox(label="URL de la page contenant des MP3"),
101
- outputs=[
102
- gr.Textbox(label="Message"),
103
- gr.File(label="Fichier ZIP")
104
- ],
105
- title="Extracteur MP3 Radio France (ou autre)",
106
- description="Collez une URL contenant des fichiers MP3, et récupérez-les dans un ZIP avec titres et numérotation."
107
- )
108
 
 
109
  if __name__ == "__main__":
110
  demo.launch()
 
 
 
 
 
 
1
  import subprocess
2
+ import sys
3
+
4
+ # Installation automatique des dépendances
5
+ def install(package):
6
+ subprocess.check_call([sys.executable, "-m", "pip", "install", package])
7
 
 
8
  try:
9
+ import gradio as gr
10
+ import requests
11
+ import re
12
+ import os
13
+ import zipfile
14
+ from pathlib import Path
15
  except ImportError:
16
+ install("gradio")
17
+ install("requests")
18
+ import gradio as gr
19
+ import requests
20
+ import re
21
+ import os
22
+ import zipfile
23
+ from pathlib import Path
24
+
25
+ # Nettoyage du nom de fichier
26
  def sanitize_filename(name):
27
+ name = re.sub(r'[\\/*?:"<>|]', "", name)
28
+ return name.strip().replace(" ", "_")[:100]
29
 
30
+ # Extraction des liens MP3 + titres depuis HTML
31
  def extract_mp3_links_and_titles(html_text):
32
+ mp3_regex = re.compile(r'https://[^\s"]+?\.mp3')
33
+ title_regex = re.compile(r'title:\\"([^\\"]+)\\"')
34
+
35
+ urls = mp3_regex.findall(html_text)
36
+ titles = title_regex.findall(html_text)
37
+
38
+ # Supprimer les doublons d'URL tout en gardant l'ordre
39
+ seen = set()
40
+ unique_urls = []
41
+ for u in urls:
42
+ if u not in seen:
43
+ seen.add(u)
44
+ unique_urls.append(u)
45
+
46
+ # Compléter les titres manquants
47
+ titles += [""] * (len(unique_urls) - len(titles))
48
+ return list(zip(unique_urls, titles[:len(unique_urls)]))
49
+
50
+ # Fonction principale
51
+ def download_podcasts(url):
52
  try:
53
  response = requests.get(url)
54
  response.raise_for_status()
55
  except Exception as e:
56
+ return f"Erreur de récupération de la page : {e}", None
57
 
58
  html_text = response.text
59
  mp3_entries = extract_mp3_links_and_titles(html_text)
60
 
61
  if not mp3_entries:
62
+ return "Aucun fichier MP3 trouvé sur la page.", None
63
 
64
+ temp_dir = Path("temp_episodes")
65
+ temp_dir.mkdir(exist_ok=True)
66
+ zip_path = temp_dir / "episodes_radiofrance.zip"
 
 
 
 
67
 
68
+ used_filenames = set()
 
69
 
70
+ with zipfile.ZipFile(zip_path, "w") as zipf:
71
+ for idx, (mp3_url, title) in enumerate(mp3_entries, 1):
72
+ base_name = f"{idx:02d}-" + (sanitize_filename(title) if title else "episode")
73
+ filename = base_name + ".mp3"
74
 
75
+ # Assurer l'unicité du nom de fichier
76
+ counter = 1
77
+ while filename in used_filenames:
78
+ filename = f"{base_name}_{counter}.mp3"
79
+ counter += 1
80
+ used_filenames.add(filename)
81
+
82
+ try:
83
+ print(f"Téléchargement : {mp3_url}")
84
+ r = requests.get(mp3_url, stream=True)
85
+ r.raise_for_status()
86
+
87
+ mp3_path = temp_dir / filename
88
+ with open(mp3_path, "wb") as f:
89
+ for chunk in r.iter_content(chunk_size=8192):
90
+ f.write(chunk)
91
+
92
+ zipf.write(mp3_path, arcname=filename)
93
+ mp3_path.unlink() # Supprime le fichier après ajout au ZIP
94
+
95
+ except Exception as e:
96
+ print(f"Erreur lors du téléchargement de {mp3_url} : {e}")
97
+
98
+ return "Téléchargement terminé !", str(zip_path)
 
 
 
 
 
 
 
99
 
100
  # Interface Gradio
101
+ with gr.Blocks() as demo:
102
+ gr.Markdown("## 🎧 Téléchargeur de podcasts Radio France")
103
+ with gr.Row():
104
+ url_input = gr.Textbox(label="URL de la page", placeholder="Collez ici une URL d'une page de podcast")
105
+ download_btn = gr.Button("Télécharger les MP3 et générer un .zip")
106
+ status = gr.Textbox(label="Statut")
107
+ file_output = gr.File(label="Fichier ZIP à télécharger")
108
+
109
+ download_btn.click(download_podcasts, inputs=url_input, outputs=[status, file_output])
 
110
 
111
+ # Lancement (utile pour Hugging Face)
112
  if __name__ == "__main__":
113
  demo.launch()