spotify-paivittaja/levyraati.py

186 lines
6.1 KiB
Python

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()