Tee scriptistä modulaarisempi

This commit is contained in:
Toni Fadjukoff 2026-03-09 11:26:34 +00:00
parent 00c0fd5189
commit 6f77e4580c

View file

@ -1,30 +1,40 @@
import os
import re
import datetime
import requests
import spotipy import spotipy
from spotipy.oauth2 import SpotifyOAuth from spotipy.oauth2 import SpotifyOAuth
import requests
import re
import os
import datetime
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv() # --- KONFIGURAATIO ---
CLIENT_ID = os.getenv("SPOTIPY_CLIENT_ID") def lataa_asetukset():
CLIENT_SECRET = os.getenv("SPOTIPY_CLIENT_SECRET") """Lataa ympäristömuuttujat .env-tiedostosta."""
REDIRECT_URI = os.getenv("SPOTIPY_REDIRECT_URI") load_dotenv()
PLAYLIST_ID = os.getenv("PLAYLIST_ID") 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_API_URL = os.getenv("WIKI_API_URL") # --- WIKI-YHTEYS ---
WIKI_PAGE_TITLE = os.getenv("WIKI_PAGE_TITLE")
WIKI_USERNAME = os.getenv("WIKI_USERNAME")
WIKI_PASSWORD = os.getenv("WIKI_PASSWORD")
def hae_wiki_sisalto(): class WikiClient:
"""Hakee MediaWiki-sivun raakatekstin APIn kautta.""" """Luokka MediaWiki-rajapinnan kanssa toimimiseen."""
# Käytetään Session-oliota, jotta kirjautumiskeksit (cookies) pysyvät tallessa def __init__(self, api_url, username, password):
session = requests.Session() self.api_url = api_url
self.username = username
self.password = password
self.session = requests.Session()
# Vaihe 1: Haetaan kirjautumistoken (login token) def kirjaudu(self):
"""Kirjautuu Wikiin ja palauttaa True jos onnistuu."""
token_params = { token_params = {
"action": "query", "action": "query",
"meta": "tokens", "meta": "tokens",
@ -33,109 +43,144 @@ def hae_wiki_sisalto():
} }
try: try:
response = session.get(url=WIKI_API_URL, params=token_params) # Vaihe 1: Haetaan kirjautumistoken
data = response.json() response = self.session.get(url=self.api_url, params=token_params)
login_token = data['query']['tokens']['logintoken'] response.raise_for_status()
login_token = response.json()['query']['tokens']['logintoken']
# Vaihe 2: Kirjaudutaan sisään tunnuksilla ja tokenilla (POST-pyyntö) # Vaihe 2: Kirjaudutaan sisään
login_params = { login_params = {
"action": "login", "action": "login",
"lgname": WIKI_USERNAME, "lgname": self.username,
"lgpassword": WIKI_PASSWORD, "lgpassword": self.password,
"lgtoken": login_token, "lgtoken": login_token,
"format": "json" "format": "json"
} }
login_response = session.post(url=WIKI_API_URL, data=login_params) login_response = self.session.post(url=self.api_url, data=login_params)
login_data = login_response.json() login_response.raise_for_status()
if login_data.get("login", {}).get("result") != "Success":
print(f"Wikin kirjautuminen epäonnistui: {login_data}")
return ""
if login_response.json().get("login", {}).get("result") == "Success":
print("Kirjauduttu Wikiin onnistuneesti!") print("Kirjauduttu Wikiin onnistuneesti!")
return True
# Vaihe 3: Haetaan vihdoin itse sivun sisältö print(f"Wikin kirjautuminen epäonnistui: {login_response.json()}")
page_params = { 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", "action": "query",
"prop": "revisions", "prop": "revisions",
"rvprop": "content", "rvprop": "content",
"rvslots": "main", "rvslots": "main",
"titles": WIKI_PAGE_TITLE, "titles": otsikko,
"format": "json" "format": "json"
} }
page_response = session.get(url=WIKI_API_URL, params=page_params) try:
page_data = page_response.json() response = self.session.get(url=self.api_url, params=params)
response.raise_for_status()
pages = page_data["query"]["pages"] pages = response.json()["query"]["pages"]
page_id = list(pages.keys())[0] page_id = list(pages.keys())[0]
if page_id == "-1": if page_id == "-1":
print("Virhe: Wiki-sivua ei löytynyt!") print(f"Virhe: Wiki-sivua '{otsikko}' ei löytynyt!")
return "" return ""
return pages[page_id]["revisions"][0]["slots"]["main"]["*"] return pages[page_id]["revisions"][0]["slots"]["main"]["*"]
except Exception as e: except Exception as e:
print(f"Virhe Wiki-yhteydessä: {e}") print(f"Virhe sivun noudossa: {e}")
return "" return ""
def paivita_soittolista(): # --- TEKSTINKÄSITTELY ---
# 1. Haetaan teksti Wikistä
nykyinen_viikko_int = datetime.date.today().isocalendar()[1] def erista_viikon_osio(teksti, viikko_numero):
nykyinen_viikko = f"{nykyinen_viikko_int:02d}" """Eristää tietyn viikon osion koko sivun tekstistä (== Viikko X ==)."""
print(f"Kuluva viikko on {nykyinen_viikko}") viikko_str = f"{viikko_numero:02d}"
wiki_teksti = hae_wiki_sisalto() 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: if not wiki_teksti:
return return
# 3. Eristetään kuluvan viikon osio tekstistä säännöllisellä lausekkeella (regex) # 2. Oikean viikon osion eristäminen
# Etsii esim. "== Viikko 10 ==" ja nappaa kaiken tekstin sen jälkeen viikko_teksti = erista_viikon_osio(wiki_teksti, nykyinen_viikko)
# aina seuraavaan "==" merkkiin asti tai sivun loppuun. if not viikko_teksti:
viikko_pattern = rf"==\s*Viikko {nykyinen_viikko}\s*==(.*?(?===|\Z))" print(f"Huom: Viikon {nykyinen_viikko:02d} osiota ei löytynyt sivulta.")
match = re.search(viikko_pattern, wiki_teksti, re.IGNORECASE | re.DOTALL)
if not match:
print(f"\nWiki-sivulta ei löytynyt otsikkoa '== Viikko {nykyinen_viikko} =='. Soittolistaa ei päivitetty.")
return return
kuluvan_viikon_teksti = match.group(1) # 3. Linkkien kerääminen ja Spotifyn päivittäminen
spotify_linkit = poimi_spotify_linkit(viikko_teksti)
# 4. Poimitaan suorat Spotify-linkit koodista paivita_spotify_soittolista(spotify_linkit, asetukset)
track_urls = []
# Käydään wiki-teksti läpi rivi riviltä
for rivi in kuluvan_viikon_teksti.split('\n'):
# Etsitään vain rivit, joissa lukee if '' in rivi:
# Säännöllinen lauseke (regex), joka etsii http- tai https-alkuisen
# linkin heti avaavan hakasulkeen [ jälkeen
match = re.search(r'\[(https?://[^\s\]]+)', rivi)
if match:
url = match.group(1) # Napataan pelkkä linkki
if "spotify.com" in url.lower():
track_urls.append(url)
print(f"Löydettiin linkki: {url}")
else:
print(f"Ohitettiin muun palvelun linkki: {url}")
# 5. Tarkistetaan löytyikö mitään
if not track_urls:
print("\nYhtään Spotify-linkkiä ei löytynyt Wiki-sivulta. Soittolistaa ei päivitetty.")
return
# 6. Kirjaudutaan sisään
scope = "playlist-modify-private playlist-modify-public"
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=REDIRECT_URI,
scope=scope, open_browser=False))
# 7. Päivitetään soittolista
sp.playlist_replace_items(PLAYLIST_ID, track_urls[:100])
print("Soittolista päivitetty onnistuneesti!")
if __name__ == '__main__': if __name__ == '__main__':
paivita_soittolista() aja_paivitys()