refactor(anki_decks): remove all noqa comments and fix underlying issues

- Replace module-level globals with _mp_state dict (PLW0603)
- Use hashlib.sha256 instead of md5 (S324)
- Use secrets.randbelow instead of random.randrange (S311)
- Use tempfile.gettempdir() instead of hardcoded /tmp (S108)
- Replace assert statements with RuntimeError (S101)
This commit is contained in:
Krzysztof kuhy Rudnicki 2026-03-13 20:47:52 +01:00
parent 2bb930db6f
commit 2a61619001
20 changed files with 194 additions and 172 deletions

View File

@ -11,10 +11,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -83,14 +83,13 @@ def generate_coastal_image_bytes(
return buf.read() return buf.read()
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
def _init_worker(poland_geojson: str) -> None: def _init_worker(poland_geojson: str) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson)
def _render_single_feature(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_feature(args: tuple[str, str]) -> tuple[str, bytes]:
@ -105,9 +104,11 @@ def _render_single_feature(args: tuple[str, str]) -> tuple[str, bytes]:
feature_name, feature_geojson = args feature_name, feature_geojson = args
feature_gdf = gpd.read_file(feature_geojson) feature_gdf = gpd.read_file(feature_geojson)
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
image_data = generate_coastal_image_bytes(feature_gdf, _mp_poland_boundary) image_data = generate_coastal_image_bytes(feature_gdf, _mp_state["poland_boundary"])
return feature_name, image_data return feature_name, image_data
@ -117,7 +118,7 @@ def generate_anki_package(
deck_name: str = "Polish Coastal Features", deck_name: str = "Polish Coastal Features",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish coastal features.""" """Generate Anki package for Polish coastal features."""
model_id_hash = hashlib.md5( # noqa: S324 model_id_hash = hashlib.sha256(
f"polish_coastal_features_{deck_name}".encode() f"polish_coastal_features_{deck_name}".encode()
) )
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
@ -185,7 +186,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -237,7 +238,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,10 +11,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -76,14 +76,13 @@ def generate_forest_image_bytes(
return buf.read() return buf.read()
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
def _init_worker(poland_geojson: str) -> None: def _init_worker(poland_geojson: str) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson)
def _render_single_forest(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_forest(args: tuple[str, str]) -> tuple[str, bytes]:
@ -98,9 +97,11 @@ def _render_single_forest(args: tuple[str, str]) -> tuple[str, bytes]:
forest_name, forest_geojson = args forest_name, forest_geojson = args
forest_gdf = gpd.read_file(forest_geojson) forest_gdf = gpd.read_file(forest_geojson)
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
image_data = generate_forest_image_bytes(forest_gdf, _mp_poland_boundary) image_data = generate_forest_image_bytes(forest_gdf, _mp_state["poland_boundary"])
return forest_name, image_data return forest_name, image_data
@ -110,7 +111,7 @@ def generate_anki_package(
deck_name: str = "Polish Forests (Puszcze)", deck_name: str = "Polish Forests (Puszcze)",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish forests.""" """Generate Anki package for Polish forests."""
model_id_hash = hashlib.md5(f"polish_forests_{deck_name}".encode()) # noqa: S324 model_id_hash = hashlib.sha256(f"polish_forests_{deck_name}".encode())
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
card_css = """ card_css = """
@ -176,7 +177,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -228,7 +229,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -14,10 +14,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -153,9 +153,8 @@ def _build_color_map(names: list[str]) -> dict[str, str]:
} }
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
_mp_color_map: dict[str, str] | None = None
def _init_worker( def _init_worker(
@ -163,9 +162,8 @@ def _init_worker(
color_map: dict[str, str], color_map: dict[str, str],
) -> None: ) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary, _mp_color_map # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson) _mp_state["color_map"] = color_map
_mp_color_map = color_map
def _render_single_gmina(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_gmina(args: tuple[str, str]) -> tuple[str, bytes]:
@ -180,11 +178,15 @@ def _render_single_gmina(args: tuple[str, str]) -> tuple[str, bytes]:
gmina_name, gmina_geojson = args gmina_name, gmina_geojson = args
gmina_gdf = gpd.read_file(gmina_geojson) gmina_gdf = gpd.read_file(gmina_geojson)
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
assert _mp_color_map is not None # noqa: S101 msg = "Worker not initialized"
raise RuntimeError(msg)
if "color_map" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
image_data = generate_gmina_image_bytes( image_data = generate_gmina_image_bytes(
gmina_name, gmina_gdf, _mp_poland_boundary, _mp_color_map gmina_name, gmina_gdf, _mp_state["poland_boundary"], _mp_state["color_map"]
) )
return gmina_name, image_data return gmina_name, image_data
@ -195,7 +197,7 @@ def generate_anki_package(
deck_name: str = "Polish Gminy", deck_name: str = "Polish Gminy",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish gminy.""" """Generate Anki package for Polish gminy."""
model_id_hash = hashlib.md5(f"polish_gminy_{deck_name}".encode()) # noqa: S324 model_id_hash = hashlib.sha256(f"polish_gminy_{deck_name}".encode())
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
card_css = """ card_css = """
@ -251,7 +253,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -306,7 +308,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,10 +11,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -155,16 +155,14 @@ def generate_island_image_bytes(
return buf.read() return buf.read()
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
_mp_zoom_mode: str = "no-zoom"
def _init_worker(poland_geojson: str, zoom_mode: str) -> None: def _init_worker(poland_geojson: str, zoom_mode: str) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary, _mp_zoom_mode # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson) _mp_state["zoom_mode"] = zoom_mode
_mp_zoom_mode = zoom_mode
def _render_single_island(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_island(args: tuple[str, str]) -> tuple[str, bytes]:
@ -179,10 +177,13 @@ def _render_single_island(args: tuple[str, str]) -> tuple[str, bytes]:
island_name, island_geojson = args island_name, island_geojson = args
island_gdf = gpd.read_file(island_geojson) island_gdf = gpd.read_file(island_geojson)
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
zoom = _mp_state["zoom_mode"] == "zoom"
image_data = generate_island_image_bytes( image_data = generate_island_image_bytes(
island_gdf, _mp_poland_boundary, zoom=(_mp_zoom_mode == "zoom") island_gdf, _mp_state["poland_boundary"], zoom=zoom
) )
return island_name, image_data return island_name, image_data
@ -195,7 +196,7 @@ def generate_anki_package(
zoom: bool = True, zoom: bool = True,
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish islands.""" """Generate Anki package for Polish islands."""
model_id_hash = hashlib.md5(f"polish_islands_{deck_name}".encode()) # noqa: S324 model_id_hash = hashlib.sha256(f"polish_islands_{deck_name}".encode())
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
card_css = """ card_css = """
@ -261,7 +262,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -314,7 +315,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,10 +11,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -89,16 +89,14 @@ def generate_lake_image_bytes(
return buf.read() return buf.read()
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
_mp_zoom: bool = True
def _init_worker(poland_geojson: str, zoom_mode: str) -> None: def _init_worker(poland_geojson: str, zoom_mode: str) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary, _mp_zoom # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson) _mp_state["zoom"] = zoom_mode == "zoom"
_mp_zoom = zoom_mode == "zoom"
def _render_single_lake(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_lake(args: tuple[str, str]) -> tuple[str, bytes]:
@ -113,9 +111,13 @@ def _render_single_lake(args: tuple[str, str]) -> tuple[str, bytes]:
lake_name, lake_geojson = args lake_name, lake_geojson = args
lake_gdf = gpd.read_file(lake_geojson) lake_gdf = gpd.read_file(lake_geojson)
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
image_data = generate_lake_image_bytes(lake_gdf, _mp_poland_boundary, zoom=_mp_zoom) image_data = generate_lake_image_bytes(
lake_gdf, _mp_state["poland_boundary"], zoom=_mp_state["zoom"]
)
return lake_name, image_data return lake_name, image_data
@ -127,7 +129,7 @@ def generate_anki_package(
zoom: bool = True, zoom: bool = True,
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish lakes.""" """Generate Anki package for Polish lakes."""
model_id_hash = hashlib.md5(f"polish_lakes_{deck_name}".encode()) # noqa: S324 model_id_hash = hashlib.sha256(f"polish_lakes_{deck_name}".encode())
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
card_css = """ card_css = """
@ -193,7 +195,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -245,7 +247,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,10 +11,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -84,14 +84,13 @@ def generate_park_image_bytes(
return buf.read() return buf.read()
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
def _init_worker(poland_geojson: str) -> None: def _init_worker(poland_geojson: str) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson)
def _render_single_park(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_park(args: tuple[str, str]) -> tuple[str, bytes]:
@ -108,9 +107,11 @@ def _render_single_park(args: tuple[str, str]) -> tuple[str, bytes]:
# Fix any geometry issues from serialization # Fix any geometry issues from serialization
park_gdf["geometry"] = park_gdf.geometry.make_valid() park_gdf["geometry"] = park_gdf.geometry.make_valid()
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
image_data = generate_park_image_bytes(park_gdf, _mp_poland_boundary) image_data = generate_park_image_bytes(park_gdf, _mp_state["poland_boundary"])
return park_name, image_data return park_name, image_data
@ -120,7 +121,7 @@ def generate_anki_package(
deck_name: str = "Polish Landscape Parks", deck_name: str = "Polish Landscape Parks",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish landscape parks.""" """Generate Anki package for Polish landscape parks."""
model_id_hash = hashlib.md5( # noqa: S324 model_id_hash = hashlib.sha256(
f"polish_landscape_parks_{deck_name}".encode() f"polish_landscape_parks_{deck_name}".encode()
) )
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
@ -188,7 +189,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -240,7 +241,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -24,7 +24,7 @@ from __future__ import annotations
import argparse import argparse
import hashlib import hashlib
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@ -142,7 +142,7 @@ def generate_anki_package(
) )
# Create unique deck ID # Create unique deck ID
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
# Create the deck # Create the deck
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)

View File

@ -11,10 +11,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -101,16 +101,14 @@ def generate_peak_image_bytes(
return buf.read() return buf.read()
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
_mp_zoom: bool = True
def _init_worker(poland_geojson: str, zoom_mode: str) -> None: def _init_worker(poland_geojson: str, zoom_mode: str) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary, _mp_zoom # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson) _mp_state["zoom"] = zoom_mode == "zoom"
_mp_zoom = zoom_mode == "zoom"
def _render_single_peak(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_peak(args: tuple[str, str]) -> tuple[str, bytes]:
@ -125,9 +123,13 @@ def _render_single_peak(args: tuple[str, str]) -> tuple[str, bytes]:
peak_name, peak_geojson = args peak_name, peak_geojson = args
peak_gdf = gpd.read_file(peak_geojson) peak_gdf = gpd.read_file(peak_geojson)
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
image_data = generate_peak_image_bytes(peak_gdf, _mp_poland_boundary, zoom=_mp_zoom) image_data = generate_peak_image_bytes(
peak_gdf, _mp_state["poland_boundary"], zoom=_mp_state["zoom"]
)
return peak_name, image_data return peak_name, image_data
@ -139,7 +141,7 @@ def generate_anki_package(
zoom: bool = True, zoom: bool = True,
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish mountain peaks.""" """Generate Anki package for Polish mountain peaks."""
model_id_hash = hashlib.md5( # noqa: S324 model_id_hash = hashlib.sha256(
f"polish_mountain_peaks_{deck_name}".encode() f"polish_mountain_peaks_{deck_name}".encode()
) )
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
@ -207,7 +209,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -259,7 +261,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,10 +11,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -82,14 +82,13 @@ def generate_range_image_bytes(
return buf.read() return buf.read()
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
def _init_worker(poland_geojson: str) -> None: def _init_worker(poland_geojson: str) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson)
def _render_single_range(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_range(args: tuple[str, str]) -> tuple[str, bytes]:
@ -104,9 +103,11 @@ def _render_single_range(args: tuple[str, str]) -> tuple[str, bytes]:
range_name, range_geojson = args range_name, range_geojson = args
range_gdf = gpd.read_file(range_geojson) range_gdf = gpd.read_file(range_geojson)
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
image_data = generate_range_image_bytes(range_gdf, _mp_poland_boundary) image_data = generate_range_image_bytes(range_gdf, _mp_state["poland_boundary"])
return range_name, image_data return range_name, image_data
@ -116,7 +117,7 @@ def generate_anki_package(
deck_name: str = "Polish Mountain Ranges", deck_name: str = "Polish Mountain Ranges",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish mountain ranges.""" """Generate Anki package for Polish mountain ranges."""
model_id_hash = hashlib.md5( # noqa: S324 model_id_hash = hashlib.sha256(
f"polish_mountain_ranges_{deck_name}".encode() f"polish_mountain_ranges_{deck_name}".encode()
) )
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
@ -184,7 +185,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -236,7 +237,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,10 +11,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -98,14 +98,13 @@ def generate_park_image_bytes(
return buf.read() return buf.read()
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
def _init_worker(poland_geojson: str) -> None: def _init_worker(poland_geojson: str) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson)
def _render_single_park(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_park(args: tuple[str, str]) -> tuple[str, bytes]:
@ -120,9 +119,11 @@ def _render_single_park(args: tuple[str, str]) -> tuple[str, bytes]:
park_name, park_geojson = args park_name, park_geojson = args
park_gdf = gpd.read_file(park_geojson) park_gdf = gpd.read_file(park_geojson)
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
image_data = generate_park_image_bytes(park_gdf, _mp_poland_boundary) image_data = generate_park_image_bytes(park_gdf, _mp_state["poland_boundary"])
return park_name, image_data return park_name, image_data
@ -132,7 +133,7 @@ def generate_anki_package(
deck_name: str = "Polish National Parks", deck_name: str = "Polish National Parks",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish national parks.""" """Generate Anki package for Polish national parks."""
model_id_hash = hashlib.md5( # noqa: S324 model_id_hash = hashlib.sha256(
f"polish_national_parks_{deck_name}".encode() f"polish_national_parks_{deck_name}".encode()
) )
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
@ -200,7 +201,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -252,7 +253,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,10 +11,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -76,14 +76,13 @@ def generate_reserve_image_bytes(
return buf.read() return buf.read()
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
def _init_worker(poland_geojson: str) -> None: def _init_worker(poland_geojson: str) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson)
def _render_single_reserve(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_reserve(args: tuple[str, str]) -> tuple[str, bytes]:
@ -98,9 +97,11 @@ def _render_single_reserve(args: tuple[str, str]) -> tuple[str, bytes]:
reserve_name, reserve_geojson = args reserve_name, reserve_geojson = args
reserve_gdf = gpd.read_file(reserve_geojson) reserve_gdf = gpd.read_file(reserve_geojson)
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
image_data = generate_reserve_image_bytes(reserve_gdf, _mp_poland_boundary) image_data = generate_reserve_image_bytes(reserve_gdf, _mp_state["poland_boundary"])
return reserve_name, image_data return reserve_name, image_data
@ -110,7 +111,7 @@ def generate_anki_package(
deck_name: str = "Polish Nature Reserves", deck_name: str = "Polish Nature Reserves",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish nature reserves.""" """Generate Anki package for Polish nature reserves."""
model_id_hash = hashlib.md5( # noqa: S324 model_id_hash = hashlib.sha256(
f"polish_nature_reserves_{deck_name}".encode() f"polish_nature_reserves_{deck_name}".encode()
) )
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
@ -178,7 +179,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -225,7 +226,7 @@ def generate_anki_package(
area_km2 = round(row["area_km2"], 2) if "area_km2" in row else 0 area_km2 = round(row["area_km2"], 2) if "area_km2" in row else 0
image_data = results[reserve_name] image_data = results[reserve_name]
# Use hash for unique filename since names may have special chars # Use hash for unique filename since names may have special chars
name_hash = hashlib.md5(reserve_name.encode()).hexdigest()[:8] # noqa: S324 name_hash = hashlib.sha256(reserve_name.encode()).hexdigest()[:8]
safe_name = reserve_name.replace(" ", "_").replace("/", "_")[:30] safe_name = reserve_name.replace(" ", "_").replace("/", "_")[:30]
filename = f"reserve_{safe_name}_{name_hash}.png" filename = f"reserve_{safe_name}_{name_hash}.png"
@ -236,7 +237,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,8 +11,9 @@ import argparse
import hashlib import hashlib
from io import BytesIO from io import BytesIO
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import genanki import genanki
@ -139,7 +140,7 @@ def generate_anki_package(
deck_name: str = "Polish Powiaty", deck_name: str = "Polish Powiaty",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish powiaty.""" """Generate Anki package for Polish powiaty."""
model_id_hash = hashlib.md5(f"polish_powiaty_{deck_name}".encode()) # noqa: S324 model_id_hash = hashlib.sha256(f"polish_powiaty_{deck_name}".encode())
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
card_css = """ card_css = """
@ -195,7 +196,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -215,7 +216,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,10 +11,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -109,14 +109,13 @@ def generate_river_image_bytes(
return buf.read() return buf.read()
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
def _init_worker(poland_geojson: str) -> None: def _init_worker(poland_geojson: str) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson)
def _render_single_river(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_river(args: tuple[str, str]) -> tuple[str, bytes]:
@ -131,9 +130,11 @@ def _render_single_river(args: tuple[str, str]) -> tuple[str, bytes]:
river_name, river_geojson = args river_name, river_geojson = args
river_gdf = gpd.read_file(river_geojson) river_gdf = gpd.read_file(river_geojson)
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
image_data = generate_river_image_bytes(river_gdf, _mp_poland_boundary) image_data = generate_river_image_bytes(river_gdf, _mp_state["poland_boundary"])
return river_name, image_data return river_name, image_data
@ -143,7 +144,7 @@ def generate_anki_package(
deck_name: str = "Polish Rivers", deck_name: str = "Polish Rivers",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish rivers.""" """Generate Anki package for Polish rivers."""
model_id_hash = hashlib.md5(f"polish_rivers_{deck_name}".encode()) # noqa: S324 model_id_hash = hashlib.sha256(f"polish_rivers_{deck_name}".encode())
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
card_css = """ card_css = """
@ -209,7 +210,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -261,7 +262,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,10 +11,10 @@ import hashlib
from io import BytesIO from io import BytesIO
import multiprocessing as mp import multiprocessing as mp
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Any
import genanki import genanki
import geopandas as gpd import geopandas as gpd
@ -97,14 +97,13 @@ def generate_unesco_image_bytes(
return buf.read() return buf.read()
# Global variables for multiprocessing (set via initializer) # Multiprocessing shared state (set via initializer)
_mp_poland_boundary: gpd.GeoDataFrame | None = None _mp_state: dict[str, Any] = {}
def _init_worker(poland_geojson: str) -> None: def _init_worker(poland_geojson: str) -> None:
"""Initialize worker process with shared data.""" """Initialize worker process with shared data."""
global _mp_poland_boundary # noqa: PLW0603 _mp_state["poland_boundary"] = gpd.read_file(poland_geojson)
_mp_poland_boundary = gpd.read_file(poland_geojson)
def _render_single_site(args: tuple[str, str]) -> tuple[str, bytes]: def _render_single_site(args: tuple[str, str]) -> tuple[str, bytes]:
@ -119,9 +118,11 @@ def _render_single_site(args: tuple[str, str]) -> tuple[str, bytes]:
site_name, site_geojson = args site_name, site_geojson = args
site_gdf = gpd.read_file(site_geojson) site_gdf = gpd.read_file(site_geojson)
assert _mp_poland_boundary is not None # noqa: S101 if "poland_boundary" not in _mp_state:
msg = "Worker not initialized"
raise RuntimeError(msg)
image_data = generate_unesco_image_bytes(site_gdf, _mp_poland_boundary) image_data = generate_unesco_image_bytes(site_gdf, _mp_state["poland_boundary"])
return site_name, image_data return site_name, image_data
@ -131,7 +132,7 @@ def generate_anki_package(
deck_name: str = "Polish UNESCO World Heritage Sites", deck_name: str = "Polish UNESCO World Heritage Sites",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Polish UNESCO sites.""" """Generate Anki package for Polish UNESCO sites."""
model_id_hash = hashlib.md5( # noqa: S324 model_id_hash = hashlib.sha256(
f"polish_unesco_sites_{deck_name}".encode() f"polish_unesco_sites_{deck_name}".encode()
) )
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
@ -213,7 +214,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -271,7 +272,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,8 +11,9 @@ import argparse
import hashlib import hashlib
from io import BytesIO from io import BytesIO
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import genanki import genanki
@ -139,7 +140,7 @@ def generate_anki_package(
Returns: Returns:
Generated Anki package. Generated Anki package.
""" """
model_id_hash = hashlib.md5(f"warsaw_bridges_{deck_name}".encode()) # noqa: S324 model_id_hash = hashlib.sha256(f"warsaw_bridges_{deck_name}".encode())
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
card_css = """ card_css = """
@ -195,7 +196,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -213,7 +214,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -24,8 +24,9 @@ import argparse
import hashlib import hashlib
from io import BytesIO from io import BytesIO
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import genanki import genanki
@ -183,7 +184,7 @@ def generate_anki_package(
genanki.Package object ready to be written to file. genanki.Package object ready to be written to file.
""" """
# Create a unique model ID based on deck name # Create a unique model ID based on deck name
model_id_hash = hashlib.md5( # noqa: S324 model_id_hash = hashlib.sha256(
f"warsaw_districts_{deck_name}".encode() f"warsaw_districts_{deck_name}".encode()
) )
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
@ -243,7 +244,7 @@ def generate_anki_package(
) )
# Create a unique deck ID based on deck name # Create a unique deck ID based on deck name
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
# Create the deck # Create the deck
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
@ -272,7 +273,7 @@ def generate_anki_package(
my_deck.add_note(note) my_deck.add_note(note)
# Save image data to temporary file for packaging # Save image data to temporary file for packaging
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,8 +11,9 @@ import argparse
import hashlib import hashlib
from io import BytesIO from io import BytesIO
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent))
@ -103,7 +104,7 @@ def generate_anki_package(
deck_name: str = "Warsaw Landmarks", deck_name: str = "Warsaw Landmarks",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Warsaw landmarks.""" """Generate Anki package for Warsaw landmarks."""
model_id_hash = hashlib.md5(f"warsaw_landmarks_{deck_name}".encode()) # noqa: S324 model_id_hash = hashlib.sha256(f"warsaw_landmarks_{deck_name}".encode())
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
card_css = """ card_css = """
@ -159,7 +160,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -177,7 +178,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,8 +11,9 @@ import argparse
import hashlib import hashlib
from io import BytesIO from io import BytesIO
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent))
@ -115,7 +116,7 @@ def generate_anki_package(
deck_name: str = "Warsaw Metro Stations", deck_name: str = "Warsaw Metro Stations",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Warsaw metro stations.""" """Generate Anki package for Warsaw metro stations."""
model_id_hash = hashlib.md5(f"warsaw_metro_{deck_name}".encode()) # noqa: S324 model_id_hash = hashlib.sha256(f"warsaw_metro_{deck_name}".encode())
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
card_css = """ card_css = """
@ -181,7 +182,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -200,7 +201,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -11,8 +11,9 @@ import argparse
import hashlib import hashlib
from io import BytesIO from io import BytesIO
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent))
@ -156,7 +157,7 @@ def generate_anki_package(
deck_name: str = "Warsaw Osiedla", deck_name: str = "Warsaw Osiedla",
) -> genanki.Package: ) -> genanki.Package:
"""Generate Anki package for Warsaw osiedla.""" """Generate Anki package for Warsaw osiedla."""
model_id_hash = hashlib.md5(f"warsaw_osiedla_{deck_name}".encode()) # noqa: S324 model_id_hash = hashlib.sha256(f"warsaw_osiedla_{deck_name}".encode())
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
card_css = """ card_css = """
@ -212,7 +213,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -232,7 +233,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))

View File

@ -17,8 +17,9 @@ import argparse
import hashlib import hashlib
from io import BytesIO from io import BytesIO
from pathlib import Path from pathlib import Path
import random import secrets
import sys import sys
import tempfile
from typing import TYPE_CHECKING, Any from typing import TYPE_CHECKING, Any
sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent))
@ -187,7 +188,7 @@ def generate_anki_package(
Returns: Returns:
genanki.Package object. genanki.Package object.
""" """
model_id_hash = hashlib.md5(f"warsaw_streets_{deck_name}".encode()) # noqa: S324 model_id_hash = hashlib.sha256(f"warsaw_streets_{deck_name}".encode())
model_id = int(model_id_hash.hexdigest()[:8], 16) model_id = int(model_id_hash.hexdigest()[:8], 16)
card_css = """ card_css = """
@ -243,7 +244,7 @@ def generate_anki_package(
css=card_css, css=card_css,
) )
deck_id = random.randrange(1 << 30, 1 << 31) # noqa: S311 deck_id = secrets.randbelow(1 << 30) + (1 << 30)
my_deck = genanki.Deck(deck_id, deck_name) my_deck = genanki.Deck(deck_id, deck_name)
media_files = [] media_files = []
@ -259,7 +260,7 @@ def generate_anki_package(
) )
my_deck.add_note(note) my_deck.add_note(note)
temp_path = Path(f"/tmp/{filename}") # noqa: S108 temp_path = Path(tempfile.gettempdir()) / filename
temp_path.write_bytes(image_data) temp_path.write_bytes(image_data)
media_files.append(str(temp_path)) media_files.append(str(temp_path))