Docfile commited on
Commit
47c91f3
·
verified ·
1 Parent(s): c3315bf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -21
app.py CHANGED
@@ -12,7 +12,6 @@ app = Flask(__name__)
12
  app.secret_key = os.environ.get('FLASK_SECRET_KEY', 'une_cle_secrete_par_defaut_pour_dev')
13
 
14
  app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://Podcast_owner:npg_gFdMDLO9lVa0@ep-delicate-surf-a4v7wopn-pooler.us-east-1.aws.neon.tech/Podcast?sslmode=require'
15
-
16
  app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
17
 
18
  db = SQLAlchemy(app)
@@ -35,6 +34,16 @@ class Podcast(db.Model):
35
  def __repr__(self):
36
  return f'<Podcast {self.name}>'
37
 
 
 
 
 
 
 
 
 
 
 
38
  @app.route('/')
39
  def index():
40
  try:
@@ -122,27 +131,29 @@ def play_podcast_route(podcast_id):
122
  return jsonify({'audio_url': audio_url})
123
  else:
124
  logger.warning(f"Fichier cache {podcast.filename_cache} pour podcast {podcast.id} non trouvé. Re-téléchargement.")
125
- podcast.filename_cache = None
126
 
127
  final_cached_filepath = None
128
  try:
129
  parsed_url = urlparse(podcast.url)
130
  path_parts = os.path.splitext(parsed_url.path)
131
- extension = path_parts[1] if path_parts[1] else '.audio'
132
 
133
- base_filename = str(podcast.id)
134
 
135
  logger.info(f"Téléchargement de {podcast.url} pour le podcast ID {podcast.id}")
136
- response = requests.get(podcast.url, stream=True, timeout=(10, 60))
 
137
  response.raise_for_status()
138
 
 
139
  content_type = response.headers.get('Content-Type')
140
  if content_type:
141
  if 'mpeg' in content_type: extension = '.mp3'
142
  elif 'ogg' in content_type: extension = '.ogg'
143
  elif 'wav' in content_type: extension = '.wav'
144
  elif 'aac' in content_type: extension = '.aac'
145
- elif 'mp4' in content_type: extension = '.m4a'
146
 
147
  cached_filename_with_ext = f"{base_filename}{extension}"
148
  final_cached_filepath = os.path.join(AUDIO_CACHE_DIR, cached_filename_with_ext)
@@ -163,18 +174,21 @@ def play_podcast_route(podcast_id):
163
  return jsonify({'error': 'Le téléchargement du podcast a pris trop de temps.'}), 504
164
  except requests.exceptions.RequestException as e:
165
  logger.error(f"Erreur de téléchargement pour {podcast.url}: {e}")
 
 
 
 
166
  return jsonify({'error': f'Impossible de télécharger le podcast: {e}'}), 500
167
  except Exception as e:
168
- db.session.rollback()
169
  logger.error(f"Erreur inattendue lors du traitement du podcast {podcast.id}: {e}")
170
- return jsonify({'error': f'Erreur inattendue: {e}'}), 500
171
- finally:
172
  if final_cached_filepath and os.path.exists(final_cached_filepath) and (not podcast or podcast.filename_cache != os.path.basename(final_cached_filepath)):
173
- try:
174
- os.remove(final_cached_filepath)
175
- logger.info(f"Fichier partiel nettoyé : {final_cached_filepath}")
176
- except OSError as e_clean:
177
- logger.error(f"Erreur lors du nettoyage du fichier partiel {final_cached_filepath}: {e_clean}")
178
 
179
  @app.route('/audio_cache/<path:filename>')
180
  def serve_cached_audio(filename):
@@ -182,11 +196,7 @@ def serve_cached_audio(filename):
182
  return send_from_directory(AUDIO_CACHE_DIR, filename)
183
 
184
  if __name__ == '__main__':
185
- with app.app_context():
186
- try:
187
- db.create_all()
188
- logger.info("Tables de base de données vérifiées/créées (si elles n'existaient pas).")
189
- except Exception as e:
190
- logger.error(f"Erreur lors de la création des tables de la base de données: {e}")
191
- logger.error("Assurez-vous que votre serveur PostgreSQL est en cours d'exécution et que la base de données existe.")
192
  app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 5000)))
 
12
  app.secret_key = os.environ.get('FLASK_SECRET_KEY', 'une_cle_secrete_par_defaut_pour_dev')
13
 
14
  app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://Podcast_owner:npg_gFdMDLO9lVa0@ep-delicate-surf-a4v7wopn-pooler.us-east-1.aws.neon.tech/Podcast?sslmode=require'
 
15
  app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
16
 
17
  db = SQLAlchemy(app)
 
34
  def __repr__(self):
35
  return f'<Podcast {self.name}>'
36
 
37
+ # Moved db.create_all() here to ensure it runs on app initialization
38
+ with app.app_context():
39
+ try:
40
+ db.create_all()
41
+ logger.info("Tables de base de données vérifiées/créées (si elles n'existaient pas).")
42
+ except Exception as e:
43
+ logger.error(f"Erreur lors de la création des tables de la base de données: {e}")
44
+ # Depending on the severity, you might want to exit or re-raise the exception.
45
+ # For now, it logs the error, and the app will likely fail on subsequent DB operations if this fails.
46
+
47
  @app.route('/')
48
  def index():
49
  try:
 
131
  return jsonify({'audio_url': audio_url})
132
  else:
133
  logger.warning(f"Fichier cache {podcast.filename_cache} pour podcast {podcast.id} non trouvé. Re-téléchargement.")
134
+ podcast.filename_cache = None # Clear invalid cache entry
135
 
136
  final_cached_filepath = None
137
  try:
138
  parsed_url = urlparse(podcast.url)
139
  path_parts = os.path.splitext(parsed_url.path)
140
+ extension = path_parts[1] if path_parts[1] else '.audio' # Default extension
141
 
142
+ base_filename = str(podcast.id) # Use podcast ID for a unique, simple base name
143
 
144
  logger.info(f"Téléchargement de {podcast.url} pour le podcast ID {podcast.id}")
145
+ # Increased timeout for potentially large files; connect timeout, read timeout
146
+ response = requests.get(podcast.url, stream=True, timeout=(10, 60))
147
  response.raise_for_status()
148
 
149
+ # Try to get a better extension from Content-Type header
150
  content_type = response.headers.get('Content-Type')
151
  if content_type:
152
  if 'mpeg' in content_type: extension = '.mp3'
153
  elif 'ogg' in content_type: extension = '.ogg'
154
  elif 'wav' in content_type: extension = '.wav'
155
  elif 'aac' in content_type: extension = '.aac'
156
+ elif 'mp4' in content_type: extension = '.m4a' # Often audio in mp4 container
157
 
158
  cached_filename_with_ext = f"{base_filename}{extension}"
159
  final_cached_filepath = os.path.join(AUDIO_CACHE_DIR, cached_filename_with_ext)
 
174
  return jsonify({'error': 'Le téléchargement du podcast a pris trop de temps.'}), 504
175
  except requests.exceptions.RequestException as e:
176
  logger.error(f"Erreur de téléchargement pour {podcast.url}: {e}")
177
+ # Clean up partial download if it exists and wasn't successfully associated
178
+ if final_cached_filepath and os.path.exists(final_cached_filepath) and (not podcast or podcast.filename_cache != os.path.basename(final_cached_filepath)):
179
+ try: os.remove(final_cached_filepath); logger.info(f"Fichier partiel (RequestException) nettoyé : {final_cached_filepath}")
180
+ except OSError as e_clean: logger.error(f"Erreur nettoyage fichier partiel (RequestException) {final_cached_filepath}: {e_clean}")
181
  return jsonify({'error': f'Impossible de télécharger le podcast: {e}'}), 500
182
  except Exception as e:
183
+ db.session.rollback() # Rollback DB session on unexpected error
184
  logger.error(f"Erreur inattendue lors du traitement du podcast {podcast.id}: {e}")
185
+ # Clean up partial download similar to above
 
186
  if final_cached_filepath and os.path.exists(final_cached_filepath) and (not podcast or podcast.filename_cache != os.path.basename(final_cached_filepath)):
187
+ try: os.remove(final_cached_filepath); logger.info(f"Fichier partiel (Exception) nettoyé : {final_cached_filepath}")
188
+ except OSError as e_clean: logger.error(f"Erreur nettoyage fichier partiel (Exception) {final_cached_filepath}: {e_clean}")
189
+ return jsonify({'error': f'Erreur inattendue: {e}'}), 500
190
+ # The finally block for cleanup was a bit complex; simplified by handling cleanup in error cases.
191
+ # If successful, filename_cache is set, so it won't be cleaned.
192
 
193
  @app.route('/audio_cache/<path:filename>')
194
  def serve_cached_audio(filename):
 
196
  return send_from_directory(AUDIO_CACHE_DIR, filename)
197
 
198
  if __name__ == '__main__':
199
+ # The db.create_all() call is now above, so it's not needed here.
200
+ # The line `app.run(...):19:12 =====` from the problem description seems to have a typo.
201
+ # Corrected to a standard app.run() call.
 
 
 
 
202
  app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 5000)))