{"id":22222350,"url":"https://github.com/misiektoja/lastfm_monitor","last_synced_at":"2026-01-17T15:36:34.113Z","repository":{"id":235265517,"uuid":"789940822","full_name":"misiektoja/lastfm_monitor","owner":"misiektoja","description":"Real-time tracking of Last.fm users music activity","archived":false,"fork":false,"pushed_at":"2026-01-12T02:05:06.000Z","size":6261,"stargazers_count":20,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-12T06:03:53.311Z","etag":null,"topics":["lastfm","lastfm-api","lastfm-monitor","music-activity","music-tracking","osint","pylast","python","scrobbling","spotify","spotipy"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/misiektoja.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-04-22T00:33:52.000Z","updated_at":"2026-01-12T02:03:11.000Z","dependencies_parsed_at":"2024-04-26T02:29:21.766Z","dependency_job_id":"34ae5223-304a-4482-a1ac-044b810255cb","html_url":"https://github.com/misiektoja/lastfm_monitor","commit_stats":null,"previous_names":["misiektoja/lastfm_monitor"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/misiektoja/lastfm_monitor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/misiektoja%2Flastfm_monitor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/misiektoja%2Flastfm_monitor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/misiektoja%2Flastfm_monitor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/misiektoja%2Flastfm_monitor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/misiektoja","download_url":"https://codeload.github.com/misiektoja/lastfm_monitor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/misiektoja%2Flastfm_monitor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28511700,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T13:38:16.342Z","status":"ssl_error","status_checked_at":"2026-01-17T13:37:44.060Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lastfm","lastfm-api","lastfm-monitor","music-activity","music-tracking","osint","pylast","python","scrobbling","spotify","spotipy"],"created_at":"2024-12-02T23:18:04.860Z","updated_at":"2026-01-17T15:36:34.088Z","avatar_url":"https://github.com/misiektoja.png","language":"Python","funding_links":[],"categories":["[↑](#-table-of-contents) Music Streaming Services"],"sub_categories":["[↑](#-table-of-contents) GitHub"],"readme":"# lastfm_monitor\n\nlastfm_monitor is a tool for real-time monitoring of **Last.fm users' music activity**.\n\n\u003ca id=\"features\"\u003e\u003c/a\u003e\n## Features\n\n- **Real-time tracking** of songs listened by Last.fm users (including detection of when a user gets online or offline)\n- Possibility to **automatically play songs** listened by the tracked user in your local Spotify client\n- Information about when a **user pauses or resumes playback** with the option to show a **track progress indicator**\n- Information about the **duration** the user listened to a song and whether the **song was skipped** and if it was **shorter or longer than the track duration**\n- **Tracking** of Last.fm user's **followers** and **followings** with notifications when users are added or removed\n- **Email notifications** for various events (user becomes active or inactive, specific or all songs, songs on loop, new entries appearing while user was offline, followers/followings changes, errors)\n- **Saving all listened songs** with timestamps to the **CSV file**\n- **Last.fm Wrapped tool** for generating Spotify Wrapped-style statistics (top artists, tracks, albums) from CSV data\n- **Clickable** **Last.fm**, **Apple Music**, **YouTube Music**, **Amazon Music**, **Deezer**, **Tidal**, **Genius Lyrics**, **AZLyrics**, **Tekstowo.pl**, **Musixmatch** and **Lyrics.com** search URLs printed in the console and included in email notifications (configurable per service)\n- Displaying **basic statistics for the user's playing session** (duration, time span, number of listened and skipped songs, songs on loop, paused playback time and number of pauses, songs played count)\n- Support for detecting **offline mode**\n- Support for detecting **Spotify's private mode** (not 100% accurate)\n- **Status persistence** - automatically saves the last activity status and the number and list of followings/followers to JSON files to track changes across restarts\n- **Flexible configuration** - support for config files, dotenv files, environment variables and command-line arguments\n- Possibility to **control the running copy** of the script via signals\n- **Functional, procedural Python** (minimal OOP)\n\n\u003cp align=\"center\"\u003e\n   \u003cimg src=\"https://raw.githubusercontent.com/misiektoja/lastfm_monitor/refs/heads/main/assets/lastfm_monitor.png\" alt=\"lastfm_monitor_screenshot\" width=\"90%\"/\u003e\n\u003c/p\u003e\n\n\u003ca id=\"table-of-contents\"\u003e\u003c/a\u003e\n## Table of Contents\n\n1. [Requirements](#requirements)\n2. [Installation](#installation)\n   * [Install from PyPI](#install-from-pypi)\n   * [Manual Installation](#manual-installation)\n   * [Upgrading](#upgrading)\n3. [Quick Start](#quick-start)\n4. [Configuration](#configuration)\n   * [Configuration File](#configuration-file)\n   * [Last.fm API Key and Shared Secret](#lastfm-api-key-and-shared-secret)\n   * [User Privacy Settings](#user-privacy-settings)\n   * [Spotify Client ID and Secret (optional)](#spotify-client-id-and-secret-optional)\n   * [SMTP Settings](#smtp-settings)\n   * [Storing Secrets](#storing-secrets)\n5. [Usage](#usage)\n   * [Monitoring Mode](#monitoring-mode)\n   * [Listing Mode](#listing-mode)\n   * [Email Notifications](#email-notifications)\n   * [CSV Export](#csv-export)\n   * [Last.fm Wrapped Tool](#lastfm-wrapped-tool)\n   * [Automatic Playback of Listened Tracks in the Spotify Client](#automatic-playback-of-listened-tracks-in-the-spotify-client)\n   * [Progress Indicator](#progress-indicator)\n   * [Getting Track Duration from Spotify](#getting-track-duration-from-spotify)\n   * [Private Mode Detection in Spotify](#private-mode-detection-in-spotify)\n   * [Check Intervals](#check-intervals)\n   * [Signal Controls (macOS/Linux/Unix)](#signal-controls-macoslinuxunix)\n   * [Coloring Log Output with GRC](#coloring-log-output-with-grc)\n6. [Change Log](#change-log)\n7. [License](#license)\n\n\u003ca id=\"requirements\"\u003e\u003c/a\u003e\n## Requirements\n\n* Python 3.9 or higher\n* Libraries: [pyLast](https://github.com/pylast/pylast), `requests`, `python-dateutil`, [Spotipy](https://github.com/spotipy-dev/spotipy), `python-dotenv`, `beautifulsoup4`\n\nTested on:\n\n* **macOS**: Ventura, Sonoma, Sequoia, Tahoe\n* **Linux**: Raspberry Pi OS (Bullseye, Bookworm, Trixie), Ubuntu 24/25, Rocky Linux 8.x/9.x, Kali Linux 2024/2025\n* **Windows**: 10, 11\n\nIt should work on other versions of macOS, Linux, Unix and Windows as well.\n\n\u003ca id=\"installation\"\u003e\u003c/a\u003e\n## Installation\n\n\u003ca id=\"install-from-pypi\"\u003e\u003c/a\u003e\n### Install from PyPI\n\n```sh\npip install lastfm_monitor\n```\n\n\u003ca id=\"manual-installation\"\u003e\u003c/a\u003e\n### Manual Installation\n\nDownload the *[lastfm_monitor.py](https://raw.githubusercontent.com/misiektoja/lastfm_monitor/refs/heads/main/lastfm_monitor.py)* file to the desired location.\n\nInstall dependencies via pip:\n\n```sh\npip install pylast requests python-dateutil spotipy python-dotenv beautifulsoup4\n```\n\nAlternatively, from the downloaded *[requirements.txt](https://raw.githubusercontent.com/misiektoja/lastfm_monitor/refs/heads/main/requirements.txt)*:\n\n```sh\npip install -r requirements.txt\n```\n\n\u003ca id=\"upgrading\"\u003e\u003c/a\u003e\n### Upgrading\n\nTo upgrade to the latest version when installed from PyPI:\n\n```sh\npip install lastfm_monitor -U\n```\n\nIf you installed manually, download the newest *[lastfm_monitor.py](https://raw.githubusercontent.com/misiektoja/lastfm_monitor/refs/heads/main/lastfm_monitor.py)* file to replace your existing installation.\n\n\u003ca id=\"quick-start\"\u003e\u003c/a\u003e\n## Quick Start\n\n- Grab your [Last.fm API Key and Shared Secret](#lastfm-api-key-and-shared-secret) and track the `lastfm_username` music activities:\n\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -u \"your_lastfm_api_key\" -w \"your_lastfm_api_secret\"\n```\n\nOr if you installed [manually](#manual-installation):\n\n```sh\npython3 lastfm_monitor.py \u003clastfm_username\u003e -u \"your_lastfm_api_key\" -w \"your_lastfm_api_secret\"\n```\n\nTo get the list of all supported command-line arguments / flags:\n\n```sh\nlastfm_monitor --help\n```\n\n\u003ca id=\"configuration\"\u003e\u003c/a\u003e\n## Configuration\n\n\u003ca id=\"configuration-file\"\u003e\u003c/a\u003e\n### Configuration File\n\nMost settings can be configured via command-line arguments.\n\nIf you want to have it stored persistently, generate a default config template and save it to a file named `lastfm_monitor.conf`:\n\n```sh\nlastfm_monitor --generate-config \u003e lastfm_monitor.conf\n\n```\n\nEdit the `lastfm_monitor.conf` file and change any desired configuration options (detailed comments are provided for each).\n\n**New in v2.3:** The configuration file includes options to enable/disable music service URLs (Last.fm, Spotify, Apple Music, YouTube Music, Amazon Music, Deezer, Tidal) and lyrics service URLs (Genius, AZLyrics, Tekstowo.pl, Musixmatch, Lyrics.com) in console and email outputs.\n\n\u003ca id=\"lastfm-api-key-and-shared-secret\"\u003e\u003c/a\u003e\n### Last.fm API Key and Shared Secret\n\n- Create your Last.fm `API key` and `Shared secret` at: [https://www.last.fm/api/account/create](https://www.last.fm/api/account/create)\n   - Or get your existing credentials from: [https://www.last.fm/api/accounts](https://www.last.fm/api/accounts)\n\n- Provide the `LASTFM_API_KEY` and `LASTFM_API_SECRET` secrets using one of the following methods:\n   - Pass it at runtime with `-u` / `--lastfm-api-key` and `-w` / `--lastfm-secret`\n   - Set it as an [environment variable](#storing-secrets) (e.g. `export LASTFM_API_KEY=...; export LASTFM_API_SECRET=...`)\n   - Add it to [.env file](#storing-secrets) (`LASTFM_API_KEY=...` and `LASTFM_API_SECRET=...`) for persistent use\n   - Fallback: hard-code it in the code or config file\n\nIf you store the `LASTFM_API_KEY` and `LASTFM_API_SECRET` in a dotenv file you can update their values and send a `SIGHUP` signal to the process to reload the file with the new secret values without restarting the tool. More info in [Storing Secrets](#storing-secrets) and [Signal Controls (macOS/Linux/Unix)](#signal-controls-macoslinuxunix).\n\n\u003ca id=\"user-privacy-settings\"\u003e\u003c/a\u003e\n### User Privacy Settings\n\nIn order to monitor Last.fm user activity, proper privacy settings need to be enabled on the monitored user account.\n\nThe user should go to [Last.fm Privacy Settings](https://www.last.fm/settings/privacy).\n\nThe **Hide recent listening information** setting should be disabled.\n\nOtherwise you will get this error message returned by the `pyLast` library: *'Login: User required to be logged in'*.\n\n\u003ca id=\"spotify-client-id-and-secret-optional\"\u003e\u003c/a\u003e\n### Spotify Client ID and Secret (optional)\n\nIf you want to obtain the [track duration from Spotify](#getting-track-duration-from-spotify) or use the [automatic playback functionality](#automatic-playback-of-listened-tracks-in-the-spotify-client), you need to get Spotify credentials to perform the Client Credentials OAuth flow.\n\n- Log in to Spotify Developer dashboard: https://developer.spotify.com/dashboard\n\n- Create a new app\n\n- For **Redirect URL**, use: http://127.0.0.1:1234\n\n- Select **Web API** as the intended API\n\n- Copy the **Client ID** and **Client Secret**\n\n- Provide the `SP_CLIENT_ID` and `SP_CLIENT_SECRET` secrets using one of the following methods:\n   - Pass it at runtime with `-z` / `--spotify-creds`\n      - Use `SP_CLIENT_ID`:`SP_CLIENT_SECRET` format - note the colon separator\n   - Set it as an [environment variable](#storing-secrets) (e.g. `export SP_CLIENT_ID=...; export SP_CLIENT_SECRET=...`)\n   - Add it to [.env file](#storing-secrets) (`SP_CLIENT_ID=...` and `SP_CLIENT_SECRET=...`) for persistent use\n   - Fallback: hard-code it in the code or config file\n\nExample:\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -z \"your_spotify_app_client_id:your_spotify_app_client_secret\"\n```\n\nThe tool takes care of refreshing the access token so it should remain valid indefinitely.\n\nIf you store the `SP_CLIENT_ID` and `SP_CLIENT_SECRET` in a dotenv file you can update their values and send a `SIGHUP` signal to reload the file with the new secret values without restarting the tool. More info in [Storing Secrets](#storing-secrets) and [Signal Controls (macOS/Linux/Unix)](#signal-controls-macoslinuxunix).\n\n\u003ca id=\"smtp-settings\"\u003e\u003c/a\u003e\n### SMTP Settings\n\nIf you want to use email notifications functionality, configure SMTP settings in the `lastfm_monitor.conf` file.\n\nVerify your SMTP settings by using `--send-test-email` flag (the tool will try to send a test email notification):\n\n```sh\nlastfm_monitor --send-test-email\n```\n\n\u003ca id=\"storing-secrets\"\u003e\u003c/a\u003e\n### Storing Secrets\n\nIt is recommended to store secrets like `LASTFM_API_KEY`, `LASTFM_API_SECRET`, `SP_CLIENT_ID`, `SP_CLIENT_SECRET` or `SMTP_PASSWORD` as either an environment variable or in a dotenv file.\n\nSet the needed environment variables using `export` on **Linux/Unix/macOS/WSL** systems:\n\n```sh\nexport LASTFM_API_KEY=\"your_lastfm_api_key\"\nexport LASTFM_API_SECRET=\"your_lastfm_api_secret\"\nexport SP_CLIENT_ID=\"your_spotify_app_client_id\"\nexport SP_CLIENT_SECRET=\"your_spotify_app_client_secret\"\nexport SMTP_PASSWORD=\"your_smtp_password\"\n```\n\nOn **Windows Command Prompt** use `set` instead of `export` and on **Windows PowerShell** use `$env`.\n\nAlternatively store them persistently in a dotenv file (recommended):\n\n```ini\nLASTFM_API_KEY=\"your_lastfm_api_key\"\nLASTFM_API_SECRET=\"your_lastfm_api_secret\"\nSP_CLIENT_ID=\"your_spotify_app_client_id\"\nSP_CLIENT_SECRET=\"your_spotify_app_client_secret\"\nSMTP_PASSWORD=\"your_smtp_password\"\n```\n\nBy default the tool will auto-search for dotenv file named `.env` in current directory and then upward from it.\n\nYou can specify a custom file with `DOTENV_FILE` or `--env-file` flag:\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e --env-file /path/.env-lastfm_monitor\n```\n\n You can also disable `.env` auto-search with `DOTENV_FILE = \"none\"` or `--env-file none`:\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e --env-file none\n```\n\nAs a fallback, you can also store secrets in the configuration file or source code.\n\n\u003ca id=\"usage\"\u003e\u003c/a\u003e\n## Usage\n\n\u003ca id=\"monitoring-mode\"\u003e\u003c/a\u003e\n### Monitoring Mode\n\nTo monitor specific user activity, just type Last.fm username as a command-line argument (`lastfm_username` in the example below):\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e\n```\n\nIf you have not set `LASTFM_API_KEY` and `LASTFM_API_SECRET` secrets, you can use `-u` and `-w` flags:\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -u \"your_lastfm_api_key\" -w \"your_lastfm_api_secret\"\n```\n\nIf you want to obtain the [track duration from Spotify](#getting-track-duration-from-spotify) or use the [automatic playback functionality](#automatic-playback-of-listened-tracks-in-the-spotify-client) and you have not set `SP_CLIENT_ID` and `SP_CLIENT_SECRET`, you can use `-z` flag:\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -z \"your_spotify_app_client_id:your_spotify_app_client_secret\"\n```\n\nBy default, the tool looks for a configuration file named `lastfm_monitor.conf` in:\n - current directory\n - home directory (`~`)\n - script directory\n\n If you generated a configuration file as described in [Configuration](#configuration), but saved it under a different name or in a different directory, you can specify its location using the `--config-file` flag:\n\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e --config-file /path/lastfm_monitor_new.conf\n```\n\nTo enable tracking of followers and/or followings changes:\n- set `TRACK_FOLLOWERS` and/or `TRACK_FOLLOWINGS` to `True`\n- or use the `--track-followers` and/or `--track-followings` flags\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e --track-followers --track-followings\n```\n\nThe tool runs until interrupted (`Ctrl+C`). Use `tmux` or `screen` for persistence.\n\nYou can monitor multiple Last.fm users by running multiple copies of the script.\n\nThe tool automatically saves its output to `lastfm_monitor_\u003cusername\u003e.log` file. It can be changed in the settings via `LF_LOGFILE` configuration option or disabled completely via `DISABLE_LOGGING` / `-d` flag.\n\nThe tool also saves the last activity information (artist, track, timestamp) to `lastfm_\u003cusername\u003e_last_activity.json` file and the number and list of followings and followers to `lastfm_\u003cusername\u003e_followings.json` and `lastfm_\u003cusername\u003e_followers.json` files (if tracking is enabled), so this data can be reused if the tool is restarted.\n\n\u003ca id=\"listing-mode\"\u003e\u003c/a\u003e\n### Listing Mode\n\nThere is another mode of the tool that prints the recently listened tracks for the user (`-l` flag).\n\nYou can also add the `-n` flag to specify how many tracks should be displayed, by default it shows the last 30 tracks:\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -l  -n 10\n```\n\n\u003cp align=\"center\"\u003e\n   \u003cimg src=\"https://raw.githubusercontent.com/misiektoja/lastfm_monitor/refs/heads/main/assets/lastfm_monitor_listing.png\" alt=\"lastfm_monitor_listing\" width=\"90%\"/\u003e\n\u003c/p\u003e\n\nIf you want to not only display, but also save the list of recently listened track to a CSV file, use the `-l` flag with `-b` indicating the CSV file. As before, you can add the `-n` flag to specify how many tracks should be displayed/saved:\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -l -n 10 -b lastfm_tracks_username.csv\n```\n\n\u003ca id=\"email-notifications\"\u003e\u003c/a\u003e\n### Email Notifications\n\nTo enable email notifications when a user becomes active:\n- set `ACTIVE_NOTIFICATION` to `True`\n- or use the `-a` flag\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -a\n```\n\nTo be informed when a user gets inactive:\n- set `INACTIVE_NOTIFICATION` to `True`\n- or use the `-i` flag\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -i\n```\n\nInactivity emails include recent songs from the session with skipped and continued track status. Configure the number of recent songs to include via the `INACTIVE_EMAIL_RECENT_SONGS_COUNT` configuration option.\n\nTo be notified when new entries appear when the user is offline:\n- set `OFFLINE_ENTRIES_NOTIFICATION` to `True`\n- or use the `-f` flag\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -f\n```\n\nTo get email notifications when a monitored track or album plays:\n- set `TRACK_NOTIFICATION` to `True`\n- or use the `-t` flag\n\nFor that feature you also need to create a file with a list of songs you want to track (one track or album per line). Specify the file using the `MONITOR_LIST_FILE` or `-s` flag:\n\nExample file `lastfm_tracks_username`:\n\n```\nwe fell in love in october\nLike a Stone\nHalf Believing\nSomething Changed\nI Will Be There\n```\n\nYou can comment out specific lines with # if needed.\n\nThen run the tool with `-t` and `-s` flags:\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -t -s lastfm_tracks_username\n```\n\nTo enable email notifications for every song listened by the user:\n- set `SONG_NOTIFICATION` to `True`\n- or use the `-j` flag\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -j\n```\n\nTo be notified when a user listens to the same song on loop:\n- set `SONG_ON_LOOP_NOTIFICATION` to `True`\n- or use the `-x` flag\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -x\n```\n\nTo disable sending an email on errors (enabled by default):\n- set `ERROR_NOTIFICATION` to `False`\n- or use the `-e` flag\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -e\n```\n\nTo be notified when a user's followers change:\n- set `FOLLOWERS_NOTIFICATION` to `True`\n- or use the `--notify-followers` flag\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e --track-followers --notify-followers\n```\n\nTo be notified when a user's followings (friends) change:\n- set `FOLLOWINGS_NOTIFICATION` to `True`\n- or use the `--notify-followings` flag\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e --track-followings --notify-followings\n```\n\nNotifications for changed followers and/or followings are only sent if tracking functionality is enabled (`--track-followers` and/or `--track-followings` flags).\n\nYou can also decide to use Last.fm or Spotify URL in \"Last played:\" / \"Track:\" field in HTML email notifications (see `USE_LASTFM_URL_IN_LAST_PLAYED` config option).\n\nMake sure you defined your SMTP settings earlier (see [SMTP settings](#smtp-settings)).\n\nExample email:\n\n\u003cp align=\"center\"\u003e\n   \u003cimg src=\"https://raw.githubusercontent.com/misiektoja/lastfm_monitor/refs/heads/main/assets/lastfm_monitor_email_notifications.png\" alt=\"lastfm_monitor_email_notifications\" width=\"90%\"/\u003e\n\u003c/p\u003e\n\n\u003ca id=\"csv-export\"\u003e\u003c/a\u003e\n### CSV Export\n\nIf you want to save all listened songs to a CSV file, set `CSV_FILE` or use `-b` flag:\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -b lastfm_tracks_username.csv\n```\n\nThe file will be automatically created if it does not exist.\n\n\u003ca id=\"lastfm-wrapped-tool\"\u003e\u003c/a\u003e\n### Last.fm Wrapped Tool\n\nThe *[lastfm_wrapped.py](https://raw.githubusercontent.com/misiektoja/lastfm_monitor/refs/heads/main/tools/lastfm_wrapped.py)* script generates Spotify Wrapped-style statistics from CSV files created by `lastfm_monitor.py`.\n\nIt analyzes your listening data and provides insights including top artists, tracks and albums for a specified time period.\n\n**Basic Usage:**\n\nBy default, it generates statistics for the current year (January 1 to November 15, similar to Spotify Wrapped):\n\n```sh\npython3 tools/lastfm_wrapped.py lastfm_tracks_username.csv\n```\n\n**Custom Date Range:**\n\nYou can specify a custom date range using `--from` and `--to` flags:\n\n```sh\npython3 tools/lastfm_wrapped.py lastfm_tracks_username.csv --from 2024-01-01 --to 2024-12-31\n```\n\n**Top N Items:**\n\nBy default, it shows the top 5 items in each category, just like Spotify Wrapped. You can change this with the `--top-n` flag:\n\n```sh\npython3 tools/lastfm_wrapped.py lastfm_tracks_username.csv --top-n 10\n```\n\n**Example Output:**\n\nThe tool displays:\n- Total scrobbles for the period\n- Top artists (by play count)\n- Top tracks (by play count)\n- Top albums (by play count)\n\n\u003ca id=\"automatic-playback-of-listened-tracks-in-the-spotify-client\"\u003e\u003c/a\u003e\n### Automatic Playback of Listened Tracks in the Spotify Client\n\nIf you want the tool to automatically play the tracks listened to by the user in your local Spotify client:\n- set `TRACK_SONGS` to `True`\n- or use the `-g` flag\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -g\n```\n\nYour Spotify client needs to be installed and running for this feature to work.\n\nIn order to use this functionality you need to have Spotipy installed as described [here](#installation) and properly defined Spotify client ID and secret values as described [here](#spotify-client-id-and-secret-optional).\n\nThe tool fully supports automatic playback on **Linux** and **macOS**. This means it will automatically play the changed track. It will also automatically pause and resume playback following the tracked user's actions. Additionally, it can pause or play an indicated track once the user becomes inactive (see the `SP_USER_GOT_OFFLINE_TRACK_ID` configuration option).\n\nFor **Windows**, it works in a semi-automatic way: if you have the Spotify client running and you are not listening to any song, then the first track will play automatically. However, subsequent tracks will be located in the client, but you will need to press the play button manually.\n\nYou can change the playback method per platform using the corresponding configuration option.\n\nFor **macOS** set `SPOTIFY_MACOS_PLAYING_METHOD` to one of the following values:\n-  \"**apple-script**\" (recommended, **default**)\n-  \"trigger-url\"\n\nFor **Linux** set `SPOTIFY_LINUX_PLAYING_METHOD` to one of the following values:\n- \"**dbus-send**\" (most common one, **default**)\n- \"qdbus\" (try if dbus-send does not work)\n- \"trigger-url\"\n\nFor **Windows** set `SPOTIFY_WINDOWS_PLAYING_METHOD` to one of the following values:\n- \"**start-uri**\" (recommended, **default**)\n- \"spotify-cmd\"\n- \"trigger-url\"\n\nThe recommended defaults should work for most people.\n\n\u003ca id=\"progress-indicator\"\u003e\u003c/a\u003e\n### Progress Indicator\n\nIf you want to see a real-time progress indicator showing the exact minute and second of the track the user is currently listening to:\n- set `PROGRESS_INDICATOR` to `True`\n- or use the `-p` flag\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -p\n```\n\n\u003cp align=\"center\"\u003e\n   \u003cimg src=\"https://raw.githubusercontent.com/misiektoja/lastfm_monitor/refs/heads/main/assets/lastfm_monitor_progress_indicator.png\" alt=\"lastfm_monitor_progress_indicator\" width=\"90%\"/\u003e\n\u003c/p\u003e\n\nFor this functionality to work correctly, it is suggested to set the active check interval (`LASTFM_ACTIVE_CHECK_INTERVAL` / `-k` flag) to a low value (such as 2-5 seconds).\n\n\u003ca id=\"getting-track-duration-from-spotify\"\u003e\u003c/a\u003e\n### Getting Track Duration from Spotify\n\nIf you want the tool to fetch the track duration from Spotify instead of Last.fm, which very often reports the wrong duration (or none at all):\n- set `USE_TRACK_DURATION_FROM_SPOTIFY` to `True`\n- or use the `-r` flag\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -r\n```\n\nIn order to use this functionality you need to have Spotipy installed as described [here](#installation) and properly defined Spotify client ID and secret values as described [here](#spotify-client-id-and-secret-optional).\n\nYou will be able to tell if the track duration comes from Spotify as it has an S* suffix at the end (e.g. **3 minutes 42 seconds S\\***), while those coming from Last.fm have an L* (e.g. **2 minutes 13 seconds L\\***).\n\nYou can disable showing the track duration marks (L* S*) via the `-q` flag.\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -r -q\n```\n\nDuration marks are not displayed if the functionality to retrieve track duration from Spotify is disabled.\n\n\u003ca id=\"private-mode-detection-in-spotify\"\u003e\u003c/a\u003e\n### Private Mode Detection in Spotify\n\nThe tool includes functionality to detect when private mode is potentially used in Spotify and even estimates the duration of its usage. It is enabled by default and is not configurable.\n\nIt is not 100% accurate. I have observed that when private mode is used, especially for extended periods, it often results in many duplicate entries being created in a Last.fm account after private mode is disabled. This leads to different tracks having the same start timestamp.\n\nI suspect this is related to a bug in Spotify and mainly occurs when the user has Spotify on multiple devices.\n\nHowever, keep in mind that this is not 100% accurate. I have observed duplicate entries even without private mode, but in such cases, the number of duplicate entries is limited. Therefore, do not treat it as something completely certain, but it is a pretty good indicator that private mode was used.\n\n\u003cp align=\"center\"\u003e\n   \u003cimg src=\"https://raw.githubusercontent.com/misiektoja/lastfm_monitor/refs/heads/main/assets/lastfm_monitor_private_mode.png\" alt=\"lastfm_monitor_private_mode\" width=\"90%\"/\u003e\n\u003c/p\u003e\n\n\u003ca id=\"check-intervals\"\u003e\u003c/a\u003e\n### Check Intervals\n\nIf you want to customize music polling intervals, use `-k` and `-c` flags (or corresponding configuration options):\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -k 2 -c 10\n```\n\n* `LASTFM_ACTIVE_CHECK_INTERVAL`, `-k`: check interval when the user is online, i.e. currently playing (seconds)\n* `LASTFM_CHECK_INTERVAL`, `-c`: check interval when the user is considered offline, i.e. not playing music (seconds)\n\nIf you want to change the time required to mark the user as inactive (the timer starts once the user stops playing the music), use `-o` flag (or `LASTFM_INACTIVITY_CHECK` configuration option):\n\n```sh\nlastfm_monitor \u003clastfm_username\u003e -o 120\n```\n\nFollowers/followings tracking functionality uses a separate check interval which you can set via `FRIENDS_CHECK_INTERVAL` configuration option or `--friends-check-interval` flag. This is independent from the music polling intervals.\n\nTo avoid false notifications caused by transient API glitches, changes are only confirmed after a number of consecutive checks (default: 3). You can configure this via `FRIENDS_CHANGE_COUNTER` option or `--friends-change-counter` flag. This setting also controls the threshold for suppressing repeated error messages.\n\nYou can also configure the retry timeout used when confirming transient changes or errors via `FRIENDS_RETRY_INTERVAL` configuration option or `--friends-retry-interval` flag.\n\n\u003ca id=\"signal-controls-macoslinuxunix\"\u003e\u003c/a\u003e\n### Signal Controls (macOS/Linux/Unix)\n\nThe tool has several signal handlers implemented which allow to change behavior of the tool without a need to restart it with new configuration options / flags.\n\nList of supported signals:\n\n| Signal | Description |\n| ----------- | ----------- |\n| USR1 | Toggle email notifications when user gets active/inactive or new offline entries show up (-a, -i, -f) |\n| USR2 | Toggle email notifications for every song (-j) |\n| URG  | Toggle showing of progress indicator (-p) |\n| CONT | Toggle email notifications for tracked songs (-t) |\n| PIPE | Toggle email notifications when user plays song on loop (-x) |\n| TRAP | Increase the inactivity check timer (by 30 seconds) (-o) |\n| ABRT | Decrease the inactivity check timer (by 30 seconds) (-o) |\n| HUP | Reload secrets from .env file |\n\nSend signals with `kill` or `pkill`, e.g.:\n\n```sh\npkill -USR1 -f \"lastfm_monitor \u003clastfm_username\u003e\"\n```\n\nAs Windows supports limited number of signals, this functionality is available only on Linux/Unix/macOS.\n\n\u003ca id=\"coloring-log-output-with-grc\"\u003e\u003c/a\u003e\n### Coloring Log Output with GRC\n\nYou can use [GRC](https://github.com/garabik/grc) to color logs.\n\nAdd to your GRC config (`~/.grc/grc.conf`):\n\n```\n# monitoring log file\n.*_monitor_.*\\.log\nconf.monitor_logs\n```\n\nNow copy the [conf.monitor_logs](https://raw.githubusercontent.com/misiektoja/lastfm_monitor/refs/heads/main/grc/conf.monitor_logs) to your `~/.grc/` and log files should be nicely colored when using `grc` tool.\n\nExample:\n\n```sh\ngrc tail -F -n 100 lastfm_monitor_\u003cusername\u003e.log\n```\n\n\u003ca id=\"change-log\"\u003e\u003c/a\u003e\n## Change Log\n\nSee [RELEASE_NOTES.md](https://github.com/misiektoja/lastfm_monitor/blob/main/RELEASE_NOTES.md) for details.\n\n\u003ca id=\"license\"\u003e\u003c/a\u003e\n## License\n\nLicensed under GPLv3. See [LICENSE](https://github.com/misiektoja/lastfm_monitor/blob/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmisiektoja%2Flastfm_monitor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmisiektoja%2Flastfm_monitor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmisiektoja%2Flastfm_monitor/lists"}