Füge Checkbox für Serien ohne klassische Staffeln hinzu und aktualisiere die Logik zur Episodensuche, um auch Jahresformate und "bisher X Folgen" zu unterstützen.
This commit is contained in:
@@ -10,7 +10,7 @@ from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
|
||||
QLabel, QMessageBox, QSpinBox, QComboBox, QTableWidget,
|
||||
QTableWidgetItem, QHeaderView, QDialog, QDialogButtonBox,
|
||||
QTextEdit, QGroupBox, QToolBar, QSplitter, QFormLayout,
|
||||
QListWidgetItem)
|
||||
QListWidgetItem, QCheckBox)
|
||||
from PyQt5.QtCore import Qt, QTimer
|
||||
|
||||
# Logging Konfiguration
|
||||
@@ -83,6 +83,11 @@ class NewSeriesDialog(QDialog):
|
||||
self.date_pref.addItems(["Bevorzuge Erstausstrahlung", "Bevorzuge TV", "Bevorzuge Streaming", "Bevorzuge deutsche Synchro"])
|
||||
settings_layout.addRow("Datum Präferenz:", self.date_pref)
|
||||
|
||||
# Checkbox für Serien ohne klassische Staffeln
|
||||
self.no_seasons_check = QCheckBox("Serie ohne klassische Staffeln")
|
||||
self.no_seasons_check.setToolTip("Aktivieren für Serien mit fortlaufender Nummerierung oder Jahresformat")
|
||||
settings_layout.addRow("", self.no_seasons_check)
|
||||
|
||||
settings_group.setLayout(settings_layout)
|
||||
layout.addWidget(settings_group)
|
||||
|
||||
@@ -145,7 +150,8 @@ class NewSeriesDialog(QDialog):
|
||||
'mode': self.staffel_mode.currentText(),
|
||||
'staffel': self.staffel_spin.value()
|
||||
},
|
||||
'date_preference': self.date_pref.currentText()
|
||||
'date_preference': self.date_pref.currentText(),
|
||||
'no_seasons': self.no_seasons_check.isChecked()
|
||||
}
|
||||
|
||||
class SeriesEditDialog(QDialog):
|
||||
@@ -224,6 +230,11 @@ class SeriesEditDialog(QDialog):
|
||||
self.date_pref.addItems(["Bevorzuge Erstausstrahlung", "Bevorzuge TV", "Bevorzuge Streaming", "Bevorzuge deutsche Synchro"])
|
||||
settings_layout.addRow("Datum Präferenz:", self.date_pref)
|
||||
|
||||
# Checkbox für Serien ohne klassische Staffeln
|
||||
self.no_seasons_check = QCheckBox("Serie ohne klassische Staffeln")
|
||||
self.no_seasons_check.setToolTip("Aktivieren für Serien mit fortlaufender Nummerierung oder Jahresformat")
|
||||
settings_layout.addRow("", self.no_seasons_check)
|
||||
|
||||
# Speichern Button für Einstellungen
|
||||
save_button = QPushButton("Einstellungen speichern")
|
||||
save_button.clicked.connect(self.save_settings)
|
||||
@@ -269,7 +280,8 @@ class SeriesEditDialog(QDialog):
|
||||
'mode': self.staffel_mode.currentText(),
|
||||
'staffel': self.staffel_spin.value()
|
||||
},
|
||||
'date_preference': self.date_pref.currentText()
|
||||
'date_preference': self.date_pref.currentText(),
|
||||
'no_seasons': self.no_seasons_check.isChecked()
|
||||
})
|
||||
|
||||
QMessageBox.information(self, "Erfolg", "Einstellungen wurden gespeichert!")
|
||||
@@ -328,6 +340,9 @@ class SeriesEditDialog(QDialog):
|
||||
if index >= 0:
|
||||
self.date_pref.setCurrentIndex(index)
|
||||
|
||||
# Keine Staffeln Checkbox laden
|
||||
self.no_seasons_check.setChecked(data.get('no_seasons', False))
|
||||
|
||||
def delete_series(self):
|
||||
"""Löscht die ausgewählte Serie"""
|
||||
current_item = self.series_list.currentItem()
|
||||
@@ -592,14 +607,25 @@ class SerienChecker(QMainWindow):
|
||||
# Alternative: Suche in der Episoden-Zeile
|
||||
episode_info = episode.find('div', {'itemprop': 'episodeNumber'})
|
||||
if episode_info and episode_info.text:
|
||||
folge = int(episode_info.text)
|
||||
# Staffel aus übergeordnetem Element
|
||||
staffel_info = episode.find_previous('h2', class_='header-2015')
|
||||
if staffel_info:
|
||||
staffel_match = re.search(r'Staffel (\d+)', staffel_info.text)
|
||||
if staffel_match:
|
||||
staffel = int(staffel_match.group(1))
|
||||
logging.debug(f"Gefundene Staffel/Folge aus Text: {staffel}/{folge}")
|
||||
# Prüfe auf "Folge X" Format
|
||||
folge_match = re.search(r'Folge (\d+)', episode_info.text)
|
||||
if folge_match:
|
||||
folge = int(folge_match.group(1))
|
||||
# Bei Serien ohne Staffeln setzen wir Staffel auf 1
|
||||
staffel = 1
|
||||
logging.debug(f"Gefundene Folge aus 'Folge X' Format: {folge}")
|
||||
else:
|
||||
try:
|
||||
folge = int(episode_info.text)
|
||||
# Staffel aus übergeordnetem Element
|
||||
staffel_info = episode.find_previous('h2', class_='header-2015')
|
||||
if staffel_info:
|
||||
staffel_match = re.search(r'Staffel (\d+)', staffel_info.text)
|
||||
if staffel_match:
|
||||
staffel = int(staffel_match.group(1))
|
||||
logging.debug(f"Gefundene Staffel/Folge aus Text: {staffel}/{folge}")
|
||||
except ValueError:
|
||||
logging.debug(f"Konnte Folge nicht aus Text extrahieren: {episode_info.text}")
|
||||
|
||||
# Suche nach deutschem Titel
|
||||
if episode_link:
|
||||
@@ -649,34 +675,74 @@ class SerienChecker(QMainWindow):
|
||||
soup = BeautifulSoup(response.text, 'html.parser')
|
||||
|
||||
staffel_links = []
|
||||
for link in soup.find_all('a', href=True):
|
||||
# Suche nach Staffel-Links und extrahiere die ID
|
||||
if 'staffel-' in link['href']:
|
||||
match = re.search(r'/staffel-(\d+)/(\d+)$', link['href'])
|
||||
if match:
|
||||
s_nr = int(match.group(1))
|
||||
serie_id = match.group(2)
|
||||
staffel_links.append((s_nr, serie_id))
|
||||
logging.debug(f"Gefundene Staffel: {s_nr} mit ID: {serie_id}")
|
||||
headers = soup.find_all('h2', class_='header-2015')
|
||||
|
||||
for header in headers:
|
||||
link = header.find('a', class_='fs-linkable')
|
||||
if not link or not link.get('href'):
|
||||
continue
|
||||
|
||||
href = link['href']
|
||||
# Prüfe auf normale Staffel-Links
|
||||
match = re.search(r'/staffel-(\d+)/(\d+)$', href)
|
||||
if match:
|
||||
s_nr = int(match.group(1))
|
||||
serie_id = match.group(2)
|
||||
staffel_links.append(('staffel', s_nr, serie_id))
|
||||
logging.debug(f"Gefundene Staffel: {s_nr} mit ID: {serie_id}")
|
||||
continue
|
||||
|
||||
# Prüfe auf "bisher X Folgen" oder Jahres-Format
|
||||
match = re.search(r'episodenguide/(\d+)/(\d+)$', href)
|
||||
if match:
|
||||
section_id = match.group(1)
|
||||
serie_id = match.group(2)
|
||||
# Prüfe den Text für die Art des Eintrags
|
||||
text = link.text.strip()
|
||||
if "bisher" in text and "Folgen" in text:
|
||||
logging.debug(f"Gefunden 'bisher X Folgen' mit ID: {serie_id}")
|
||||
staffel_links.append(('folgen', section_id, serie_id))
|
||||
elif text.isdigit(): # Jahresformat
|
||||
logging.debug(f"Gefunden Jahr {text} mit ID: {serie_id}")
|
||||
staffel_links.append(('jahr', section_id, serie_id))
|
||||
|
||||
if not staffel_links:
|
||||
logging.warning("Keine Staffeln gefunden!")
|
||||
logging.warning("Keine Staffeln oder Episodengruppen gefunden!")
|
||||
return None
|
||||
|
||||
if staffel_nr:
|
||||
# Suche nach der gewünschten Staffel
|
||||
for s_nr, serie_id in staffel_links:
|
||||
if s_nr == staffel_nr:
|
||||
# Suche nach der gewünschten Staffel (nur für normale Staffeln)
|
||||
for typ, nr, serie_id in staffel_links:
|
||||
if typ == 'staffel' and nr == staffel_nr:
|
||||
url = f"https://www.fernsehserien.de/{slug}/episodenguide/staffel-{staffel_nr}/{serie_id}"
|
||||
logging.debug(f"Generierte URL für spezifische Staffel: {url}")
|
||||
return url
|
||||
logging.warning(f"Staffel {staffel_nr} nicht gefunden!")
|
||||
return None
|
||||
else:
|
||||
# Nehme die neueste Staffel
|
||||
newest_staffel, serie_id = max(staffel_links, key=lambda x: x[0])
|
||||
url = f"https://www.fernsehserien.de/{slug}/episodenguide/staffel-{newest_staffel}/{serie_id}"
|
||||
logging.debug(f"Generierte URL für neueste Staffel ({newest_staffel}): {url}")
|
||||
# Nehme den neuesten Eintrag
|
||||
if not staffel_links:
|
||||
return None
|
||||
|
||||
# Sortiere nach Typ und dann nach Nummer/ID
|
||||
def sort_key(x):
|
||||
typ, nr, serie_id = x
|
||||
type_priority = {'staffel': 3, 'jahr': 2, 'folgen': 1}
|
||||
# Bei Staffeln nach Staffelnummer sortieren, sonst nach section_id
|
||||
if typ == 'staffel':
|
||||
return (type_priority.get(typ, 0), int(nr)) # nr ist hier die Staffelnummer
|
||||
else:
|
||||
return (type_priority.get(typ, 0), int(nr)) # nr ist hier die section_id
|
||||
|
||||
newest = max(staffel_links, key=sort_key)
|
||||
typ, nr, serie_id = newest
|
||||
|
||||
if typ == 'staffel':
|
||||
url = f"https://www.fernsehserien.de/{slug}/episodenguide/staffel-{nr}/{serie_id}"
|
||||
logging.debug(f"Generierte URL für neueste Staffel ({nr}): {url}")
|
||||
else:
|
||||
url = f"https://www.fernsehserien.de/{slug}/episodenguide/{nr}/{serie_id}"
|
||||
logging.debug(f"Generierte URL für Episodengruppe: {url}")
|
||||
return url
|
||||
|
||||
except Exception as e:
|
||||
@@ -728,21 +794,53 @@ class SerienChecker(QMainWindow):
|
||||
logging.error(error_msg)
|
||||
return
|
||||
|
||||
logging.debug(f"Hole Episoden von: {url}")
|
||||
response = requests.get(url)
|
||||
soup = BeautifulSoup(response.text, 'html.parser')
|
||||
|
||||
episodes = []
|
||||
for episode in soup.find_all('section', {'itemprop': 'episode'}):
|
||||
staffel, folge, titel = self.get_episode_info(episode)
|
||||
if all([staffel, folge, titel]):
|
||||
datum = self.get_premiere_date(episode)
|
||||
episodes.append({
|
||||
'date': datum,
|
||||
'staffel': staffel,
|
||||
'folge': folge,
|
||||
'titel': titel
|
||||
})
|
||||
page = 1
|
||||
# Prüfe ob die Serie als "ohne klassische Staffeln" markiert ist
|
||||
no_seasons = selected_data.get('no_seasons', False)
|
||||
|
||||
while True:
|
||||
current_url = f"{url}/{page}" if page > 1 and no_seasons else url
|
||||
logging.debug(f"Hole Episoden von: {current_url}")
|
||||
|
||||
try:
|
||||
response = requests.get(current_url)
|
||||
if response.status_code == 404:
|
||||
logging.debug(f"Seite {page} nicht gefunden, beende Suche")
|
||||
break
|
||||
|
||||
# Bei normalen Staffeln nur eine Seite laden
|
||||
if not no_seasons:
|
||||
logging.debug("Serie hat klassische Staffeln, lade nur aktuelle Seite")
|
||||
|
||||
response.raise_for_status() # Prüfe auf andere HTTP-Fehler
|
||||
soup = BeautifulSoup(response.text, 'html.parser')
|
||||
|
||||
# Prüfe ob die Seite Episoden enthält
|
||||
page_episodes = soup.find_all('section', {'itemprop': 'episode'})
|
||||
if not page_episodes:
|
||||
logging.debug(f"Keine Episoden auf Seite {page} gefunden, beende Suche")
|
||||
break
|
||||
|
||||
for episode in page_episodes:
|
||||
staffel, folge, titel = self.get_episode_info(episode)
|
||||
if all([staffel, folge, titel]):
|
||||
datum = self.get_premiere_date(episode)
|
||||
episodes.append({
|
||||
'date': datum,
|
||||
'staffel': staffel,
|
||||
'folge': folge,
|
||||
'titel': titel
|
||||
})
|
||||
|
||||
# Bei normalen Staffeln nach der ersten Seite aufhören
|
||||
if not no_seasons:
|
||||
break
|
||||
page += 1
|
||||
|
||||
except requests.RequestException as e:
|
||||
logging.error(f"Fehler beim Abrufen von Seite {page}: {str(e)}")
|
||||
break
|
||||
|
||||
if not episodes:
|
||||
self.episodes_table.setRowCount(1)
|
||||
@@ -760,8 +858,8 @@ class SerienChecker(QMainWindow):
|
||||
x['folge']
|
||||
))
|
||||
|
||||
# Zeige maximal 20 Episoden an
|
||||
episodes = episodes[:20]
|
||||
# Zeige alle gefundenen Episoden an
|
||||
# episodes = episodes[:20] # Alte Begrenzung entfernt
|
||||
|
||||
# Aktualisiere die Tabelle
|
||||
self.episodes_table.setRowCount(len(episodes))
|
||||
|
Reference in New Issue
Block a user