Search, chat and research over parliamentary speeches and documents
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

90 lines
2.6 KiB

"""
Laddar ned motioner från riksdagens öppna data som ZIP-arkiv med JSON-filer.
Arkiven är uppdelade i fyraårsperioder (förankrade vid 1998; allt före ligger
i 1990-1997) och uppdateras dagligen:
https://data.riksdagen.se/dataset/dokument/mot-{range}.json.zip
Varje arkiv innehåller en JSON-fil per motion (dokumentstatus-kuvert med
metadata + fulltext som HTML). Extraheras till motioner/mot-{range}/.
Backfill (alla perioder 1990→): python scripts/download_motions.py
Används av sync_motions.py för daglig uppdatering av aktuell period.
"""
import logging
import os
import sys
from io import BytesIO
from urllib.request import urlopen
from zipfile import ZipFile
os.chdir("/home/lasse/riksdagen")
sys.path.append("/home/lasse/riksdagen")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
)
logger = logging.getLogger(__name__)
RANGES = [
"1990-1997",
"1998-2001",
"2002-2005",
"2006-2009",
"2010-2013",
"2014-2017",
"2018-2021",
"2022-2025",
]
URL_TEMPLATE = "https://data.riksdagen.se/dataset/dokument/mot-{r}.json.zip"
MOTIONS_DIR = "motioner"
def get_current_range(session_year: int) -> str:
"""Fyraårsperiod förankrad vid 1998; allt före 1998 ligger i 1990-1997."""
if session_year < 1998:
return "1990-1997"
start = session_year - ((session_year - 1998) % 4)
return f"{start}-{start + 3}"
def download_range(r: str, force: bool = False) -> str:
"""
Laddar ned och extraherar arkivet för en period till motioner/mot-{r}/.
Hoppar över om mappen redan är ifylld, om inte force=True (töms först).
"""
dir_path = os.path.join(MOTIONS_DIR, f"mot-{r}")
if os.path.exists(dir_path) and os.listdir(dir_path):
if not force:
logger.info(f"Skipping {dir_path}, already exists and is not empty.")
return dir_path
for f in os.listdir(dir_path):
os.remove(os.path.join(dir_path, f))
os.makedirs(dir_path, exist_ok=True)
url = URL_TEMPLATE.format(r=r)
logger.info(f"Downloading {url}{dir_path}")
with urlopen(url) as resp:
with ZipFile(BytesIO(resp.read())) as zf:
zf.extractall(dir_path)
count = len(os.listdir(dir_path))
logger.info(f"Extracted {count} files to {dir_path}")
return dir_path
def download_all(force: bool = False) -> None:
for r in RANGES:
download_range(r, force=force)
if __name__ == "__main__":
if len(sys.argv) > 1:
download_range(sys.argv[1], force="--force" in sys.argv)
else:
download_all()