mirror of
https://github.com/Findus23/spotifystats.git
synced 2024-09-07 00:53:44 +02:00
initial commit
This commit is contained in:
commit
a59f2599bd
3 changed files with 99 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
.idea/
|
26
README.md
Normal file
26
README.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Spotify Stats
|
||||
|
||||
a very simple python script to analyse hours listened by day and most played songs
|
||||
|
||||
### How-To
|
||||
|
||||
- Request your account data from https://www.spotify.com/us/account/privacy/
|
||||
- confirm the E-Mail
|
||||
- up to 30 days later you will get a zip file containing a `MyData` folder containing files similar to those:
|
||||
- Follow.json
|
||||
- Payments.json
|
||||
- Playlist1.json
|
||||
- Read_Me_First.pdf
|
||||
- SearchQueries.json
|
||||
- StreamingHistory0.json
|
||||
- StreamingHistory1.json
|
||||
- Userdata.json
|
||||
- YourLibrary.json
|
||||
- download the `spotifystats.py` file
|
||||
- edit the `BASEDIR` path to your `MyData` folder
|
||||
- run `spotifystats.py`
|
||||
|
||||
### Dependencies
|
||||
|
||||
- python 3.7 or newer
|
||||
- matplotlib
|
72
spotifystats.py
Normal file
72
spotifystats.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
import json
|
||||
from collections import Counter
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
# minumum time a song needs to be played to count as "played"
|
||||
MIN_PLAY_TIME = 60 # seconds
|
||||
|
||||
# only show songs that were played at least this often in the top list
|
||||
MIN_PLAY_NUM = 3
|
||||
|
||||
# path to Spotify export
|
||||
BASEDIR = Path("/home/lukas/Nextcloud/MyData/")
|
||||
|
||||
|
||||
@dataclass
|
||||
class Song:
|
||||
end_time: str
|
||||
artist_name: str
|
||||
track_name: str
|
||||
ms_played: int
|
||||
|
||||
def datetime(self) -> datetime:
|
||||
return datetime.strptime(self.end_time, "%Y-%m-%d %H:%M")
|
||||
|
||||
def date(self):
|
||||
return self.datetime().date()
|
||||
|
||||
@property
|
||||
def min_played(self) -> float:
|
||||
return self.ms_played / 1000 / 60
|
||||
|
||||
|
||||
history = []
|
||||
|
||||
for file in BASEDIR.glob("StreamingHistory*.json"):
|
||||
with file.open() as f:
|
||||
data = json.load(f)
|
||||
for song in data:
|
||||
try:
|
||||
song_obj = Song(end_time=song["endTime"], artist_name=song["artistName"],
|
||||
track_name=song["trackName"], ms_played=song["msPlayed"])
|
||||
history.append(song_obj)
|
||||
except KeyError:
|
||||
print("this entry doesn't seem to be a song")
|
||||
continue
|
||||
|
||||
print(f"{len(history)} plays found")
|
||||
|
||||
bins = {}
|
||||
for song in history:
|
||||
if song.date() in bins:
|
||||
bins[song.date()] += song.min_played
|
||||
else:
|
||||
bins[song.date()] = song.min_played
|
||||
|
||||
plt.bar(bins.keys(), bins.values())
|
||||
plt.ylabel("minutes")
|
||||
|
||||
played_songs = []
|
||||
for song in history:
|
||||
if song.ms_played > MIN_PLAY_TIME * 1000:
|
||||
played_songs.append((song.artist_name, song.track_name))
|
||||
|
||||
for (artist, title), num_played in sorted(Counter(played_songs).most_common(), key=lambda c: [-c[1], c[0][0], c[0][1]]):
|
||||
if num_played >= MIN_PLAY_NUM:
|
||||
print(f"{num_played:>4} {artist}: {title}")
|
||||
|
||||
plt.show()
|
Loading…
Reference in a new issue