Ribot commited on
Commit
52a320c
·
verified ·
1 Parent(s): 463a9c6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -35
app.py CHANGED
@@ -5,6 +5,20 @@ import os
5
  import zipfile
6
  import tempfile
7
  from urllib.parse import urljoin
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  def process_url(url):
10
  try:
@@ -17,54 +31,56 @@ def process_url(url):
17
  except Exception as e:
18
  return None, f"Erreur de connexion : {str(e)}"
19
 
20
- # Nouvelle méthode de détection des MP3
21
- mp3_links = []
 
 
22
 
23
- # 1. Recherche dans les balises script
24
- scripts = re.findall(r'<script.*?>(.*?)</script>', response.text, re.DOTALL)
25
- for script in scripts:
26
- matches = re.findall(r'(https://[^\s"\']+?\.mp3)', script)
27
- mp3_links.extend(matches)
28
-
29
- # 2. Recherche dans les attributs HTML
30
- html_matches = re.findall(r'(?:href|src|rl|contentUrl)\s*=\s*["\'](.*?\.mp3.*?)["\']', response.text)
31
- mp3_links.extend([urljoin(url, m.split('";')[0]) for m in html_matches])
32
 
33
- # 3. Suppression des paramètres et dédoublonnage
34
- clean_links = []
35
- seen = set()
36
- for link in mp3_links:
37
- clean = link.split('?')[0].split('";')[0]
38
- if clean not in seen:
39
- seen.add(clean)
40
- clean_links.append(clean)
41
 
42
- if not clean_links:
43
- return None, "Aucun MP3 trouvé - Essayez avec l'URL complète d'une série"
44
 
45
- # Téléchargement
46
  temp_dir = tempfile.mkdtemp()
47
  filenames = []
48
 
49
- for idx, mp3_url in enumerate(clean_links, 1):
50
  try:
51
- filename = f"{idx:02d}_{os.path.basename(mp3_url)}"
52
- filepath = os.path.join(temp_dir, filename)
 
53
 
54
  with requests.get(mp3_url, headers=headers, stream=True, timeout=10) as r:
55
  r.raise_for_status()
56
- with open(filepath, 'wb') as f:
57
  for chunk in r.iter_content(chunk_size=8192):
58
  f.write(chunk)
59
- filenames.append(filepath)
 
 
 
 
 
 
 
60
  except Exception as e:
61
  continue
62
 
63
  if not filenames:
64
- return None, "Tous les téléchargements ont échoué"
65
 
66
  # Création du ZIP
67
- zip_path = os.path.join(temp_dir, 'radiofrance_podcast.zip')
68
  with zipfile.ZipFile(zip_path, 'w') as zipf:
69
  for file in filenames:
70
  zipf.write(file, arcname=os.path.basename(file))
@@ -77,16 +93,16 @@ def download_podcast(url):
77
  raise gr.Error(error)
78
  return zip_path
79
 
80
- with gr.Blocks(title="RadioFrance Podcaster") as app:
81
- gr.Markdown("## 🎧 Téléchargement de podcasts Radio France")
82
  with gr.Row():
83
  url_input = gr.Textbox(
84
- label="URL de la série podcast",
85
- placeholder="Ex: https://www.radiofrance.fr/.../mon-podcast",
86
  max_lines=1
87
  )
88
- btn = gr.Button("Télécharger les épisodes", variant="primary")
89
- output = gr.File(label="Fichier ZIP contenant les MP3")
90
 
91
  examples = gr.Examples(
92
  examples=[[
 
5
  import zipfile
6
  import tempfile
7
  from urllib.parse import urljoin
8
+ from mutagen.mp3 import MP3
9
+ from mutagen.id3 import ID3, TIT2
10
+
11
+ def get_clean_title(filepath):
12
+ try:
13
+ audio = MP3(filepath, ID3=ID3)
14
+ if 'TIT2' in audio:
15
+ title = audio['TIT2'].text[0]
16
+ # Nettoyage des caractères spéciaux
17
+ title = re.sub(r'[\\/*?:"<>|]', "", title).strip()
18
+ return title
19
+ except Exception as e:
20
+ print(f"Erreur lecture métadonnées : {str(e)}")
21
+ return os.path.basename(filepath).split('.')[0]
22
 
23
  def process_url(url):
24
  try:
 
31
  except Exception as e:
32
  return None, f"Erreur de connexion : {str(e)}"
33
 
34
+ # Extraction ciblée des épisodes
35
+ soup = BeautifulSoup(response.text, 'html.parser')
36
+ main_content = soup.find('main') or soup
37
+ episodes = main_content.find_all('article', class_=re.compile(r'episode|podcast'))
38
 
39
+ mp3_links = []
40
+ for episode in episodes:
41
+ script_tag = episode.find('script', type='application/ld+json')
42
+ if script_tag:
43
+ match = re.search(r'"contentUrl"\s*:\s*"([^"]+?\.mp3)', script_tag.string)
44
+ if match:
45
+ mp3_url = urljoin(url, match.group(1).split('?')[0])
46
+ mp3_links.append(mp3_url)
 
47
 
48
+ # Filtrage des doublons
49
+ mp3_links = list(dict.fromkeys(mp3_links))[:4] # Limite aux 4 premiers épisodes
 
 
 
 
 
 
50
 
51
+ if not mp3_links:
52
+ return None, "Aucun épisode principal trouvé"
53
 
 
54
  temp_dir = tempfile.mkdtemp()
55
  filenames = []
56
 
57
+ for idx, mp3_url in enumerate(mp3_links, 1):
58
  try:
59
+ # Téléchargement original
60
+ original_name = os.path.basename(mp3_url).split('?')[0]
61
+ temp_path = os.path.join(temp_dir, f"temp_{idx}_{original_name}")
62
 
63
  with requests.get(mp3_url, headers=headers, stream=True, timeout=10) as r:
64
  r.raise_for_status()
65
+ with open(temp_path, 'wb') as f:
66
  for chunk in r.iter_content(chunk_size=8192):
67
  f.write(chunk)
68
+
69
+ # Renommage avec métadonnées
70
+ clean_title = get_clean_title(temp_path)
71
+ final_name = f"{idx:02d} - {clean_title}.mp3"
72
+ final_path = os.path.join(temp_dir, final_name)
73
+ os.rename(temp_path, final_path)
74
+
75
+ filenames.append(final_path)
76
  except Exception as e:
77
  continue
78
 
79
  if not filenames:
80
+ return None, "Échec du téléchargement des épisodes"
81
 
82
  # Création du ZIP
83
+ zip_path = os.path.join(temp_dir, 'podcast_episodes.zip')
84
  with zipfile.ZipFile(zip_path, 'w') as zipf:
85
  for file in filenames:
86
  zipf.write(file, arcname=os.path.basename(file))
 
93
  raise gr.Error(error)
94
  return zip_path
95
 
96
+ with gr.Blocks(title="Podcast Clean Downloader") as app:
97
+ gr.Markdown("## 🎙️ Téléchargeur Intelligent de Podcasts")
98
  with gr.Row():
99
  url_input = gr.Textbox(
100
+ label="URL Radio France",
101
+ placeholder="Collez ici l'URL de la série podcast...",
102
  max_lines=1
103
  )
104
+ btn = gr.Button("Générer le ZIP des épisodes", variant="primary")
105
+ output = gr.File(label="Télécharger les épisodes")
106
 
107
  examples = gr.Examples(
108
  examples=[[