Skip to content

Commit fb2377e

Browse files
authored
Supports Waybar and Forces Config to standard locations (0.4.0) (#22) (#23) (#24)
* Forces config to sane ~/.config location. * Updates install docs. * Updates docs to support Waybar.
1 parent 86ec62e commit fb2377e

File tree

4 files changed

+84
-85
lines changed

4 files changed

+84
-85
lines changed

README.md

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Spotibar
22

3-
Polybar plugin for Spotify that uses the Spotify Web API. Note that this
4-
requires a Spotify premium account.
3+
Polybar/Waybar plugin for Spotify that uses the Spotify Web API. Note that
4+
this requires a Spotify premium account.
55

66
## Features:
77
- [x] Display currently playing artist/song
@@ -15,7 +15,7 @@ requires a Spotify premium account.
1515
![spotibar_Closed](https://user-images.githubusercontent.com/2671067/111181789-3aa6b000-85a6-11eb-8511-da536700438a.png)
1616

1717
## Usage/Experience:
18-
After installing and configuring `spotibar` to run on your Polybar as
18+
After installing and configuring `spotibar` to run on your status bar as
1919
described below, you should see the currently playing track/artist, interactive
2020
controls to go to the previous song, play/pause and go to the next track. The
2121
thing that justifies the little bit of extra work to set up this module is in
@@ -31,16 +31,17 @@ options.
3131

3232
Secondly, you need to install `spotibar` and run it's `init` processes:
3333
```
34-
python3 -m pip install spotibar
34+
pipx install spotibar
3535
spotibar --init
3636
```
3737

3838
During this install process, you will be directed to open a browser to allow Spotibar interact with your Spotify account. After accepting this, you will be redirected to a URL beginning with `http://127.0.0.1`. Copy this whole URL and paste it back into the init process when asked!
3939

4040
If you're getting errors, try removing spotibar and reinstalling under sudo permissions. If you get an error involving `libtk8.6.so`, install tk using your distro's package manager.
4141

42-
Once `spotibar` is installed and authenticated, you need to modify your
43-
polybar config as follows (or however suits your needs!):
42+
Once `spotibar` is installed and authenticated, you need to modify your status bar config as follows (or however suits your needs!):
43+
44+
### Polybar:
4445
```
4546
modules-right = <other modules> spotibar-currently-playing spotibar-previous-track spotibar-toggle-playback spotibar-next-track spotibar-add-to-playlist <other modules>
4647
@@ -84,6 +85,51 @@ click-right = spotibar --config-popup
8485
exec-if = [ $(spotibar --is-live) = "True" ]
8586
format-underline = #1db954
8687
format-padding = 2
88+
```
89+
90+
### Waybar:
91+
Note that this relies on `mediaplayer.py` to output the currently playing track. This behaviour can easily be modified (e.g. by using `spotibar --get-currently-playing`)
92+
93+
```
94+
"modules-center": ["custom/media", "custom/media-skip-backward", "custom/media-play-pause", "custom/media-skip-forward"],
95+
96+
"custom/media": {
97+
"format": "{icon} {}",
98+
"return-type": "json",
99+
"max-length": 40,
100+
"format-icons": {
101+
"spotify": "",
102+
"default": "🎜"
103+
},
104+
"escape": true,
105+
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null",
106+
"on-click-right": "spotibar --add-track-to-monthly-playlist"
107+
},
108+
109+
"custom/media-play-pause": {
110+
"format": "<span size='20pt'>\udb81\udc0e</span>",
111+
"on-click": "playerctl play-pause",
112+
},
113+
"custom/media-skip-backward": {
114+
"format": "<span size='20pt'>\udb81\udcab</span>",
115+
"on-click": "playerctl previous",
116+
},
117+
"custom/media-skip-forward": {
118+
"format": "<span size='20pt'>\udb81\udcac</span>",
119+
"on-click": "playerctl next",
120+
},
121+
122+
```
123+
124+
You should also modify your `~/.config/waybar/styles.css` to style the buttons added above. e.g.
125+
126+
```
127+
#custom-media-skip-backward,
128+
#custom-media-play-pause,
129+
#custom-media-skip-forward {
130+
padding: 0 6px;
131+
color: #ffffff;
132+
}
87133
```
88134

89135
Done! Enjoy! File (probably inevitable) bug reports as issues!

setup.py

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
1-
from setuptools import (
2-
find_packages,
3-
setup
4-
)
1+
from setuptools import find_packages, setup
52

6-
INSTALL_REQUIRES = [
7-
'pylast',
8-
'spotipy'
9-
]
3+
INSTALL_REQUIRES = ["pylast", "spotipy"]
104

115
setup(
12-
name='spotibar',
13-
description='Spotify plugin for Polybar',
14-
version='0.3.12',
15-
url='https://github.com/conor-f/spotibar',
16-
python_requires='>=3.6',
17-
packages=find_packages('src'),
18-
package_dir={'': 'src'},
6+
name="spotibar",
7+
description="Spotify plugin for Polybar",
8+
version="0.4.0",
9+
url="https://github.com/conor-f/spotibar",
10+
python_requires=">=3.6",
11+
packages=find_packages("src"),
12+
package_dir={"": "src"},
1913
install_requires=INSTALL_REQUIRES,
20-
entry_points={
21-
'console_scripts': [
22-
'spotibar = spotibar.client:main'
23-
]
24-
}
14+
entry_points={"console_scripts": ["spotibar = spotibar.client:main"]},
2515
)

src/spotibar/client.py

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,12 @@
1414

1515
class SpotibarClient:
1616
def __init__(self, *args, **kwargs):
17-
"""
18-
:kwarg config_file: String path relative to ~/ of a config file to load.
19-
"""
17+
""" """
2018
self.scope = "playlist-read-private playlist-modify-private user-read-playback-state user-modify-playback-state playlist-modify-public"
2119

22-
self.config_file = kwargs.get("config_file")
23-
24-
if not self.config_file:
25-
raise Exception("A config_file must be passed.")
20+
os.makedirs("~/.config/spotibar/", exist_ok=True)
2621

22+
self.config_file = "~/.config/spotibar/default.json"
2723
self.config = SpotibarConfig(config_file=self.config_file)
2824

2925
self.client_id = self.config.get("client_id", kwargs.get("client_id", None))
@@ -36,13 +32,7 @@ def __init__(self, *args, **kwargs):
3632

3733
self.redirect_uri = "http://127.0.0.1"
3834

39-
self.auth_cache = self.config.get(
40-
"auth_cache_path", kwargs.get(
41-
"auth_cache_path", "~/.spotibar_cache/auth_cache"
42-
)
43-
)
44-
45-
os.makedirs(os.path.dirname(self.auth_cache), exist_ok=True)
35+
self.auth_cache = "~/.cache/spotibar/auth_cache"
4636

4737
self.client = None
4838
self.lastfm_client = None
@@ -64,7 +54,7 @@ def get_client(self):
6454
client_id=self.client_id,
6555
client_secret=self.client_secret,
6656
redirect_uri=self.redirect_uri,
67-
cache_path=self.auth_cache,
57+
cache_path=os.path.expanduser(self.auth_cache),
6858
open_browser=False,
6959
)
7060
)
@@ -376,26 +366,16 @@ def first_run():
376366
response = input("\tSpotify client secret: ")
377367
config["client_secret"] = response
378368

379-
print("Where should we write this config?")
380-
response = input("\tFilepath: [~/.spotibar_config.json] ")
381-
382-
config_filepath = "~/.spotibar_config.json" if response == "" else response
383-
384-
print("Where should we cache your authentication tokens?")
385-
response = input("\tFilepath: [~/.spotibar_auth_cache] ")
386-
387-
auth_filepath = "~/.spotibar_auth_cache" if response == "" else response
388-
389369
spotibar_client = SpotibarClient(
390370
client_id=config["client_id"],
391371
client_secret=config["client_secret"],
392-
config_file=config_filepath,
393-
auth_cache_path=auth_filepath,
394372
)
395373
spotibar_client.auth()
396374

397375
try:
398-
with open(config_filepath, "w") as fh:
376+
os.makedirs(os.path.expanduser("~/.config/spotibar/"), exist_ok=True)
377+
os.makedirs(os.path.expanduser("~/.cache/spotibar/"), exist_ok=True)
378+
with open(os.path.expanduser("~/.config/spotibar/default.json"), "x") as fh:
399379
json.dump(config, fh)
400380

401381
except Exception as e:
@@ -413,12 +393,6 @@ def main():
413393
description="Entrypoint for Spotify/Polybar integration."
414394
)
415395

416-
parser.add_argument("--config-filepath", default="~/.spotibar_config.json")
417-
parser.add_argument(
418-
"--auth-filepath",
419-
default="~/.spotibar_cache/auth_cache"
420-
)
421-
422396
group = parser.add_mutually_exclusive_group()
423397
group.add_argument("--get-currently-playing", action="store_true")
424398
group.add_argument("--previous-track", action="store_true")
@@ -437,16 +411,10 @@ def main():
437411

438412
sys.exit(0)
439413

440-
spotibar_client = (
441-
SpotibarClient(
442-
config_file=args.config_filepath,
443-
require_clients=False,
444-
auth_cache_path=args.auth_filepath,
445-
) if args.is_live else SpotibarClient(
446-
config_file=args.config_filepath,
447-
auth_cache_path=args.auth_filepath,
448-
)
449-
)
414+
if args.is_live:
415+
spotibar_client = SpotibarClient(require_clients=False)
416+
else:
417+
spotibar_client = SpotibarClient()
450418

451419
if args.get_currently_playing:
452420
print(spotibar_client.get_currently_playing_string())

src/spotibar/config_helper.py

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,44 @@
44

55
class SpotibarConfig:
66
def __init__(self, *args, **kwargs):
7-
self.config_file = kwargs.get("config_file", ".spotibar_config.json")
8-
9-
self.path = os.path.expanduser("~") + "/" + self.config_file
10-
11-
# If we supply an absolute path, use that instead of expanding the home
12-
# dir.
13-
if self.config_file[0] == "/":
14-
self.path = self.config_file
7+
self.config_file = os.path.expanduser(
8+
kwargs.get("config_file", "~/.config/spotibar/default.json")
9+
)
1510

1611
def get(self, key, default):
17-
if not os.path.exists(self.path):
12+
if not os.path.exists(self.config_file):
1813
return default
1914
try:
20-
with open(self.path, "r") as fh:
15+
with open(self.config_file, "r") as fh:
2116
config = json.load(fh)
2217

2318
if key in config.keys():
2419
return config[key]
2520
else:
2621
return default
2722
except Exception as e:
28-
print(f"Problem reading from ~/{self.config_file}!")
23+
print(f"Problem reading from {self.config_file}!")
2924
print(e)
3025

3126
def set(self, key, value):
3227
config = None
3328

3429
try:
35-
with open(self.path, "r") as fh:
30+
with open(self.config_file, "r") as fh:
3631
config = json.load(fh)
3732
except Exception as e:
38-
print(f"Problem reading from ~/{self.config_file}!")
33+
print(f"Problem reading from {self.config_file}!")
3934
print(e)
4035

4136
return
4237

4338
config[key] = value
4439

4540
try:
46-
with open(self.path, "w") as fh:
41+
with open(self.config_file, "w") as fh:
4742
json.dump(config, fh)
4843
except Exception as e:
49-
print(f"Problem writing to ~/{self.config_file}!")
44+
print(f"Problem writing to {self.config_file}!")
5045
print(e)
5146

5247
return

0 commit comments

Comments
 (0)