spotify-paivittaja/levyraati.py

141 lines
4.9 KiB
Python

import spotipy
from spotipy.oauth2 import SpotifyOAuth
import requests
import re
import os
import datetime
from dotenv import load_dotenv
load_dotenv()
CLIENT_ID = os.getenv("SPOTIPY_CLIENT_ID")
CLIENT_SECRET = os.getenv("SPOTIPY_CLIENT_SECRET")
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")
def hae_wiki_sisalto():
"""Hakee MediaWiki-sivun raakatekstin APIn kautta."""
# Käytetään Session-oliota, jotta kirjautumiskeksit (cookies) pysyvät tallessa
session = requests.Session()
# Vaihe 1: Haetaan kirjautumistoken (login token)
token_params = {
"action": "query",
"meta": "tokens",
"type": "login",
"format": "json"
}
try:
response = session.get(url=WIKI_API_URL, params=token_params)
data = response.json()
login_token = data['query']['tokens']['logintoken']
# Vaihe 2: Kirjaudutaan sisään tunnuksilla ja tokenilla (POST-pyyntö)
login_params = {
"action": "login",
"lgname": WIKI_USERNAME,
"lgpassword": WIKI_PASSWORD,
"lgtoken": login_token,
"format": "json"
}
login_response = session.post(url=WIKI_API_URL, data=login_params)
login_data = login_response.json()
if login_data.get("login", {}).get("result") != "Success":
print(f"Wikin kirjautuminen epäonnistui: {login_data}")
return ""
print("Kirjauduttu Wikiin onnistuneesti!")
# Vaihe 3: Haetaan vihdoin itse sivun sisältö
page_params = {
"action": "query",
"prop": "revisions",
"rvprop": "content",
"rvslots": "main",
"titles": WIKI_PAGE_TITLE,
"format": "json"
}
page_response = session.get(url=WIKI_API_URL, params=page_params)
page_data = page_response.json()
pages = page_data["query"]["pages"]
page_id = list(pages.keys())[0]
if page_id == "-1":
print("Virhe: Wiki-sivua ei löytynyt!")
return ""
return pages[page_id]["revisions"][0]["slots"]["main"]["*"]
except Exception as e:
print(f"Virhe Wiki-yhteydessä: {e}")
return ""
def paivita_soittolista():
# 1. Haetaan teksti Wikistä
nykyinen_viikko_int = datetime.date.today().isocalendar()[1]
nykyinen_viikko = f"{nykyinen_viikko_int:02d}"
print(f"Kuluva viikko on {nykyinen_viikko}")
wiki_teksti = hae_wiki_sisalto()
if not wiki_teksti:
return
# 3. Eristetään kuluvan viikon osio tekstistä säännöllisellä lausekkeella (regex)
# Etsii esim. "== Viikko 10 ==" ja nappaa kaiken tekstin sen jälkeen
# aina seuraavaan "==" merkkiin asti tai sivun loppuun.
viikko_pattern = rf"==\s*Viikko {nykyinen_viikko}\s*==(.*?(?===|\Z))"
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
kuluvan_viikon_teksti = match.group(1)
# 4. Poimitaan suorat Spotify-linkit koodista
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__':
paivita_soittolista()