import os import re import datetime import requests import spotipy from spotipy.oauth2 import SpotifyOAuth from dotenv import load_dotenv # --- KONFIGURAATIO --- def lataa_asetukset(): """Lataa ympäristömuuttujat .env-tiedostosta.""" load_dotenv() return { "SPOTIPY_CLIENT_ID": os.getenv("SPOTIPY_CLIENT_ID"), "SPOTIPY_CLIENT_SECRET": os.getenv("SPOTIPY_CLIENT_SECRET"), "SPOTIPY_REDIRECT_URI": os.getenv("SPOTIPY_REDIRECT_URI"), "PLAYLIST_ID": os.getenv("PLAYLIST_ID"), "WIKI_API_URL": os.getenv("WIKI_API_URL"), "WIKI_PAGE_TITLE": os.getenv("WIKI_PAGE_TITLE"), "WIKI_USERNAME": os.getenv("WIKI_USERNAME"), "WIKI_PASSWORD": os.getenv("WIKI_PASSWORD"), } # --- WIKI-YHTEYS --- class WikiClient: """Luokka MediaWiki-rajapinnan kanssa toimimiseen.""" def __init__(self, api_url, username, password): self.api_url = api_url self.username = username self.password = password self.session = requests.Session() def kirjaudu(self): """Kirjautuu Wikiin ja palauttaa True jos onnistuu.""" token_params = { "action": "query", "meta": "tokens", "type": "login", "format": "json" } try: # Vaihe 1: Haetaan kirjautumistoken response = self.session.get(url=self.api_url, params=token_params) response.raise_for_status() login_token = response.json()['query']['tokens']['logintoken'] # Vaihe 2: Kirjaudutaan sisään login_params = { "action": "login", "lgname": self.username, "lgpassword": self.password, "lgtoken": login_token, "format": "json" } login_response = self.session.post(url=self.api_url, data=login_params) login_response.raise_for_status() if login_response.json().get("login", {}).get("result") == "Success": print("Kirjauduttu Wikiin onnistuneesti!") return True print(f"Wikin kirjautuminen epäonnistui: {login_response.json()}") return False except Exception as e: print(f"Virhe Wiki-kirjautumisessa: {e}") return False def hae_sivun_sisalto(self, otsikko): """Hakee annetun sivun raakatekstin.""" params = { "action": "query", "prop": "revisions", "rvprop": "content", "rvslots": "main", "titles": otsikko, "format": "json" } try: response = self.session.get(url=self.api_url, params=params) response.raise_for_status() pages = response.json()["query"]["pages"] page_id = list(pages.keys())[0] if page_id == "-1": print(f"Virhe: Wiki-sivua '{otsikko}' ei löytynyt!") return "" return pages[page_id]["revisions"][0]["slots"]["main"]["*"] except Exception as e: print(f"Virhe sivun noudossa: {e}") return "" # --- TEKSTINKÄSITTELY --- def erista_viikon_osio(teksti, viikko_numero): """Eristää tietyn viikon osion koko sivun tekstistä (== Viikko X ==).""" viikko_str = f"{viikko_numero:02d}" pattern = rf"==\s*Viikko {viikko_str}\s*==(.*?(?===|\Z))" match = re.search(pattern, teksti, re.IGNORECASE | re.DOTALL) if match: return match.group(1).strip() return None def poimi_spotify_linkit(teksti): """Etsii tekstistä Spotify-kappaleiden linkit hakasulkeiden sisältä.""" linkit = [] for rivi in teksti.split('\n'): # Etsitään [http...] muotoisia linkkejä match = re.search(r'\[(https?://[^\s\]]+)', rivi) if match: url = match.group(1) if "spotify.com" in url.lower(): linkit.append(url) print(f"Löydetty Spotify-linkki: {url}") else: print(f"Ohitettu muu linkki: {url}") return linkit # --- SPOTIFY-PÄIVITYS --- def paivita_spotify_soittolista(linkit, asetukset): """Päivittää Spotify-soittolistan annetuilla linkeillä.""" if not linkit: print("\nEi päivitettäviä linkkejä. Soittolistaa ei muutettu.") return False scope = "playlist-modify-private playlist-modify-public" try: sp = spotipy.Spotify(auth_manager=SpotifyOAuth( client_id=asetukset["SPOTIPY_CLIENT_ID"], client_secret=asetukset["SPOTIPY_CLIENT_SECRET"], redirect_uri=asetukset["SPOTIPY_REDIRECT_URI"], scope=scope, open_browser=False )) # Spotify sallii enintään 100 kappaletta per kutsu sp.playlist_replace_items(asetukset["PLAYLIST_ID"], linkit[:100]) print(f"Soittolista päivitetty onnistuneesti ({len(linkit[:100])} kappaletta).") return True except Exception as e: print(f"Virhe Spotifyn päivityksessä: {e}") return False # --- PÄÄOHJELMA --- def aja_paivitys(): """Suorittaa koko päivitysprosessin vaihe kerrallaan.""" asetukset = lataa_asetukset() nykyinen_viikko = datetime.date.today().isocalendar()[1] print(f"--- Aloitetaan päivitys (Viikko {nykyinen_viikko:02d}) ---") # 1. Wiki-yhteys ja sisällön haku wiki = WikiClient( asetukset["WIKI_API_URL"], asetukset["WIKI_USERNAME"], asetukset["WIKI_PASSWORD"] ) if not wiki.kirjaudu(): return wiki_teksti = wiki.hae_sivun_sisalto(asetukset["WIKI_PAGE_TITLE"]) if not wiki_teksti: return # 2. Oikean viikon osion eristäminen viikko_teksti = erista_viikon_osio(wiki_teksti, nykyinen_viikko) if not viikko_teksti: print(f"Huom: Viikon {nykyinen_viikko:02d} osiota ei löytynyt sivulta.") return # 3. Linkkien kerääminen ja Spotifyn päivittäminen spotify_linkit = poimi_spotify_linkit(viikko_teksti) paivita_spotify_soittolista(spotify_linkit, asetukset) if __name__ == '__main__': aja_paivitys()