novatorem: Music-provider data into an SVG widget
This novatorem fork builds music-status widgets from provider data. A Flask orchestrator handles rendering, while Spotify and Last.fm have separate modules. Album artwork supplies both an image and colors for the SVG.
Repository languagesPython 81.61%5
Shares calculated from GitHub Linguist bytes.
| Language | % | Bytes |
|---|---|---|
| Python | 86,529 | |
| Jinja | 17,032 | |
| HTML | 1,741 | |
| Dockerfile | 677 | |
| Procfile | 47 |
Overview
Why it exists
Real-time dynamic GitHub profile README updater streaming live Spotify listening status.
Best fit
Live GitHub profile personalization and webhook integration.
Getting started
These commands come from the repository documentation. They were not run during this review.
Tasks declared in manifests
Repository references
The repository does not provide a detailed guide for these steps. Start with its README and the source walkthrough above.
Features and components 2
- Provider and presentation
- api/orchestrator.py owns the Flask application and rendering helpers. Provider modules sit alongside it. Configuration controls templates and palettes, keeping service-specific data access separate from SVG appearance.
- Artwork processing
- ImageData fetches artwork once per object and reuses the bytes for base64 output and ColorThief palettes. load_image_with_fallback tries artwork, then a placeholder, then default colors when image processing fails.
Architecture
The components and their connections remain available as text. The diagram adds an interactive view.
- Spotify or Last.fm
- Provider data
- Flask orchestrator
- Artwork and palette fallback
- SVG template response
Links verified in the repository.
Mermaid Interactive diagram (loads on open)
System overview of the components and connections verified in the repository.

flowchart LR
n0["Spotify or Last.fm"]
n1["Provider data"]
n2["Flask orchestrator"]
n3["Artwork and palette fallback"]
n4["SVG template response"]
n0 --> n1
n1 --> n2
n2 --> n3
n3 --> n4
Text version of the diagram
- Spotify or Last.fm → Provider data
- Provider data → Flask orchestrator
- Flask orchestrator → Artwork and palette fallback
- Artwork and palette fallback → SVG template response
Follow one path through the code
Follow ImageData._fetch into get_base64 and get_palette. Reusing bytes avoids repeated image downloads within that object; it is not a persistent cross-request cache.
Types and file structure
19 declared types, with 12 in the base-relationship overview.
Type diagram
classDiagram
direction TB
class t7697cb5ba057["TrackInfo"] {
}
class tce9a5c3a3832["ImageData"] {
__init__()
_fetch()
get_base64()
get_palette()
}
class t576319e97c4e["TrackInfo"] {
}
class tc5e631da8d1c["AudioFeatures"] {
beat_duration_ms()
to_dict()
}
class t4be5079b8ec0["SpotifyTokenManager"] {
__init__()
_get_auth_header()
_refresh_token()
get_token()
}
class t58ad657833a8["SpotifyConfig"] {
is_configured()
}
class tcb0edfe91d38["LastFmConfig"] {
is_configured()
}
class t3c92c85d61ad["SVGConfig"] {
}
class te1c73c384f8d["CompactSVGConfig"] {
}
class t9f095ad5e068["TemplateConfig"] {
}
class t97dfb1fa9ef2["MusicWidgetError"] {
__init__()
}
class t7be6e7ad4bde["ConfigurationError"] {
__init__()
}
class b8564c6f24b53["Exception"] {
<<unresolved_base>>
}
b8564c6f24b53 <|-- t97dfb1fa9ef2
t97dfb1fa9ef2 <|-- t7be6e7ad4bde
Unresolved bases remain labelled; full signatures are not reconstructed.
Type index
TrackInfo(class) ·api/lastfm.py:22ImageData(class) ·api/orchestrator.py:47Methods in the overview:
__init__, _fetch, get_base64, get_palette.TrackInfo(class) ·api/spotify.py:26AudioFeatures(class) ·api/spotify.py:40Methods in the overview:
beat_duration_ms, to_dict.SpotifyTokenManager(class) ·api/spotify.py:68Methods in the overview:
__init__, _get_auth_header, _refresh_token, get_token.SpotifyConfig(class) ·api/config.py:26Methods in the overview:
is_configured.LastFmConfig(class) ·api/config.py:44Methods in the overview:
is_configured.SVGConfig(class) ·api/config.py:67CompactSVGConfig(class) ·api/config.py:139TemplateConfig(class) ·api/config.py:239MusicWidgetError(class) ·api/exceptions.py:10Methods in the overview:
__init__.Declared bases:
Exception.ConfigurationError(class) ·api/exceptions.py:19Methods in the overview:
__init__.Declared bases:
MusicWidgetError.
Reference
14 / 14 eligible files read (29 in the tree); 0 oversized, 0 failed reads and 0 syntax diagnostics.
What the scan covers
Known dependency/build folders, credential files and binaries are excluded. The scan covers READMEs, recognized manifests and parser-supported source files.
Linguist statistics cover the whole repository and may include other languages.
File map
flowchart TD
root["novatorem"]
f0["api/lastfm.py"]
root --> f0
f1["api/orchestrator.py"]
root --> f1
f2["api/spotify.py"]
root --> f2
f3["README.md"]
root --> f3
f4["docker-compose.yml"]
root --> f4
f5["package.json"]
root --> f5
f6["requirements.txt"]
root --> f6
f7["start.py"]
root --> f7
f8["api/__init__.py"]
root --> f8
f9["api/config.py"]
root --> f9
f10["api/exceptions.py"]
root --> f10
f11["scripts/apply_spotify_secrets.py"]
root --> f11
f12["scripts/renew_spotify_token.py"]
root --> f12
f13["scripts/spotify_local_auth.py"]
root --> f13