diff --git a/Dockerfile~ b/Dockerfile~ deleted file mode 100644 index 624a64e..0000000 --- a/Dockerfile~ +++ /dev/null @@ -1,21 +0,0 @@ -# On part d'une version légère de Python -FROM python:3.9-slim - -# On définit le dossier de travail dans le conteneur -WORKDIR /app - -# On installe les dépendances -COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt - -# On copie le code -COPY . . - -# On crée le dossier pour le cache -RUN mkdir -p /data - -# On expose le port 5000 -EXPOSE 5000 - -# Commande de démarrage -CMD ["python", "app.py"] \ No newline at end of file diff --git a/app.py~ b/app.py~ deleted file mode 100644 index f4d62ab..0000000 --- a/app.py~ +++ /dev/null @@ -1,153 +0,0 @@ -import os, json, logging, requests, re, time -from datetime import datetime -from flask import Flask, render_template, redirect, url_for -from bs4 import BeautifulSoup -from apscheduler.schedulers.background import BackgroundScheduler - -app = Flask(__name__) -logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') -logger = logging.getLogger("CineSynthese") - -CACHE_FILE = "/data/movies_cache.json" -HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36'} - -def get_today_formats(): - now = datetime.now() - jours_courts = ["Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"] - day_short = jours_courts[now.weekday()] - return { - "cosmo_id": f"seance-{now.strftime('%Y-%m-%d')}", - "cratere_date": f"{day_short}. {now.day:02d}/{now.month:02d}" - } - -# --- 1. SCRAPER ABC --- -def scrape_abc(): - url = "https://abc-toulouse.fr/horaires.html" - movies = [] - try: - r = requests.get(url, headers=HEADERS, timeout=15) - soup = BeautifulSoup(r.content, 'html.parser') - movie_blocks = soup.find_all('div', class_='table_infos') - for block in movie_blocks: - title_tag = block.find('h2') - if not title_tag: continue - title = title_tag.get_text().strip() - img_tag = block.find('img') - img_url = "https://abc-toulouse.fr" + img_tag.get('src') if img_tag else "" - next_div = block.find_next_sibling() - showtimes_text = next_div.get_text(" ") if next_div else block.get_text(" ") - times = re.findall(r'(\d{2}:\d{2})', showtimes_text) - if times: - movies.append({"title": title, "img": img_url, "times": sorted(list(set(times))), "cinema": "ABC", "color": "#00bcd4"}) - except: logger.error("Fail ABC") - return movies - -# --- 2. SCRAPER LE CRATÈRE --- -def scrape_cratere(): - url_main = "https://www.cinemalecratere.fr/films" - target_date = get_today_formats()["cratere_date"] - movies_dict = {} - session = requests.Session() - try: - r = session.get(url_main, headers=HEADERS, timeout=15) - soup = BeautifulSoup(r.content, 'html.parser') - items = soup.find_all('div', attrs={'data-search': True}) - for item in items: - if target_date in item['data-search']: - title_tag = item.find('span', class_='uk-text-bold') - title = title_tag.get_text(strip=True) if title_tag else "Inconnu" - time_match = re.search(r'(\d{2}h\d{2})', item['data-search']) - show_time = time_match.group(0).replace('h', ':') if time_match else "Séance" - if title not in movies_dict: - img_url = "" - link_tag = item.find('a', href=True) - if link_tag: - r_det = session.get("https://www.cinemalecratere.fr" + link_tag['href'], timeout=10) - img_tag = BeautifulSoup(r_det.content, 'html.parser').find('img', class_='el-image') - if img_tag: - img_url = img_tag.get('src') - if not img_url.startswith('http'): img_url = "https://www.cinemalecratere.fr" + img_url - movies_dict[title] = {"title": title, "img": img_url, "times": [show_time], "cinema": "Le Cratère", "color": "#e62117"} - else: - if show_time not in movies_dict[title]["times"]: movies_dict[title]["times"].append(show_time) - except: logger.error("Fail Cratère") - return list(movies_dict.values()) - -# --- 3. SCRAPER COSMOGRAPH (REPRISE EXACTE DE TON CODE FONCTIONNEL) --- -def scrape_cosmo(): - BASE_URL = "https://www.american-cosmograph.fr" - url_horaires = f"{BASE_URL}/les-horaires.html" - target_id = get_today_formats()["cosmo_id"] - movies_today = [] - session = requests.Session() - try: - r = session.get(url_horaires, headers=HEADERS, timeout=15) - soup = BeautifulSoup(r.content, 'html.parser') - day_container = soup.find('div', id=target_id) - if not day_container: return [] - items = day_container.find_all('li', class_='heureReady') - for item in items: - title_tag = item.select_one('.filmTitle a') - if not title_tag: continue - title = title_tag.get_text(strip=True) - detail_path = title_tag.get('href') - time_tag = item.select_one('.horaire_debut') - time_raw = time_tag.get_text(strip=True) if time_tag else "" - show_time_match = re.search(r'\d{2}h\d{2}', time_raw) - show_time = show_time_match.group(0).replace('h', ':') if show_time_match else "Séance" - img_url = "" - if detail_path: - detail_url = f"{BASE_URL}{detail_path}" - try: - r_detail = session.get(detail_url, headers=HEADERS, timeout=10) - soup_detail = BeautifulSoup(r_detail.content, 'html.parser') - img_tag = soup_detail.find('img', class_='fc_field_image') - if img_tag: - img_url = img_tag.get('src') - if img_url and not img_url.startswith('http'): - img_url = f"{BASE_URL}{img_url}" - except: pass - movies_today.append({"title": title, "img": img_url, "times": [show_time], "cinema": "American Cosmograph", "color": "#ffc107"}) - time.sleep(0.1) - except: pass - - # Fusion des horaires pour le Cosmo - unique_movies = {} - for m in movies_today: - if m['title'] not in unique_movies: - unique_movies[m['title']] = m - else: - if m['times'][0] not in unique_movies[m['title']]['times']: - unique_movies[m['title']]['times'].append(m['times'][0]) - unique_movies[m['title']]['times'].sort() - return list(unique_movies.values()) - -# --- LOGIQUE MISE À JOUR --- -def update_all_data(): - logger.info("🕒 Mise à jour programmée...") - try: - data = scrape_abc() + scrape_cratere() + scrape_cosmo() - data = sorted(data, key=lambda x: x['times'][0] if x['times'] else "99:99") - payload = {"last_update": datetime.now().strftime("%d/%m/%Y à %H:%M"), "movies": data} - os.makedirs(os.path.dirname(CACHE_FILE), exist_ok=True) - with open(CACHE_FILE, 'w') as f: json.dump(payload, f) - return payload - except Exception as e: - logger.error(f"Erreur MAJ: {e}") - return None - -scheduler = BackgroundScheduler() -scheduler.add_job(func=update_all_data, trigger="cron", hour=0, minute=5) -scheduler.start() - -@app.route('/') -def index(): - if not os.path.exists(CACHE_FILE): - cache = update_all_data() - else: - with open(CACHE_FILE, 'r') as f: cache = json.load(f) - if isinstance(cache, list): cache = update_all_data() - return render_template('index.html', films=cache["movies"], updated=cache["last_update"]) - -if __name__ == '__main__': - app.run(host='0.0.0.0', port=5000) diff --git a/docker-compose.yml~ b/docker-compose.yml~ deleted file mode 100644 index 0fa5e70..0000000 --- a/docker-compose.yml~ +++ /dev/null @@ -1,10 +0,0 @@ -services: - cine-app: - build: . - container_name: cine_toulouse - ports: - - "5001:5000" - volumes: - # On lie le dossier ./data du NUC au dossier /data du conteneur - - ./data:/data - restart: unless-stopped \ No newline at end of file diff --git a/requirements.txt~ b/requirements.txt~ deleted file mode 100644 index 62c1945..0000000 --- a/requirements.txt~ +++ /dev/null @@ -1,5 +0,0 @@ -flask -requests -beautifulsoup4 -thefuzz -gunicorn