cloudspin 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cloudspin/__init__.py +3 -0
- cloudspin/__main__.py +4 -0
- cloudspin/app.py +497 -0
- cloudspin/canvas.py +321 -0
- cloudspin/cli.py +98 -0
- cloudspin/color.py +78 -0
- cloudspin/config.py +105 -0
- cloudspin/library.py +140 -0
- cloudspin/mood.py +245 -0
- cloudspin/player.py +447 -0
- cloudspin/screens.py +130 -0
- cloudspin/sky.py +829 -0
- cloudspin/songlook.py +116 -0
- cloudspin/spectrum.py +83 -0
- cloudspin/themes.py +100 -0
- cloudspin/vinyl.py +182 -0
- cloudspin/weather.py +310 -0
- cloudspin/widgets.py +750 -0
- cloudspin-0.1.0.dist-info/METADATA +206 -0
- cloudspin-0.1.0.dist-info/RECORD +23 -0
- cloudspin-0.1.0.dist-info/WHEEL +4 -0
- cloudspin-0.1.0.dist-info/entry_points.txt +2 -0
- cloudspin-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: cloudspin
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A terminal music player that lives under a living sky: spinning vinyl, real weather, animated scenes.
|
|
5
|
+
Project-URL: Homepage, https://github.com/itsHarshDabas/Cloudspin
|
|
6
|
+
Project-URL: Issues, https://github.com/itsHarshDabas/Cloudspin/issues
|
|
7
|
+
Author: Harsh Dabas
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: mpv,music,player,terminal,textual,tui,weather
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
14
|
+
Classifier: Operating System :: MacOS
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Players
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: mutagen>=1.47
|
|
23
|
+
Requires-Dist: pillow>=10.0
|
|
24
|
+
Requires-Dist: textual>=8.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# Cloudspin
|
|
31
|
+
|
|
32
|
+
A music player for your terminal that lives under a sky. A record spins, the
|
|
33
|
+
weather for your city is written across the horizon, and the sky itself changes
|
|
34
|
+
with the song: phonk brings a thunderstorm, lo-fi settles into evening,
|
|
35
|
+
synthwave turns the stars on.
|
|
36
|
+
|
|
37
|
+

|
|
38
|
+
|
|
39
|
+
| Phonk gets a storm | Synthwave gets the night, in the cover's colours |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
|  |  |
|
|
42
|
+
|
|
43
|
+
## What it does
|
|
44
|
+
|
|
45
|
+
- Plays local files, folders, radio streams and links through `mpv`.
|
|
46
|
+
- Paste a link while it's running (press `o`) and it starts playing.
|
|
47
|
+
- Shows live weather and a six-day forecast from [Open-Meteo](https://open-meteo.com) (free, no API key).
|
|
48
|
+
- Draws an animated sky: sun, moon with the real phase, stars, drifting clouds, rain, snow, fog and lightning.
|
|
49
|
+
- Picks the sky to suit the song, or follows the real weather, or stays on a scene you pin.
|
|
50
|
+
- Takes its colours from the sky, from the song's cover art, or from a theme you write.
|
|
51
|
+
- Spins a record whose label is the album cover, with a tonearm that tracks through the song.
|
|
52
|
+
- Works with the mouse: click the buttons, drag the progress line, click a song in Up next, scroll for volume.
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
Cloudspin is not on PyPI, the AUR or npm yet. Until it is, install it from this repository:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
pipx install git+https://github.com/itsHarshDabas/Cloudspin
|
|
60
|
+
# or
|
|
61
|
+
uv tool install git+https://github.com/itsHarshDabas/Cloudspin
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
You also need `mpv` for sound. Two more tools are optional:
|
|
65
|
+
|
|
66
|
+
| Tool | Why |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| `mpv` | Plays the music. Without it Cloudspin runs silently. |
|
|
69
|
+
| `ffmpeg` | Lets Cloudspin listen to songs that have no genre tag, to guess a sky. |
|
|
70
|
+
| `yt-dlp` | Lets mpv play YouTube, SoundCloud and similar links. |
|
|
71
|
+
|
|
72
|
+
On Arch: `sudo pacman -S mpv ffmpeg yt-dlp`.
|
|
73
|
+
|
|
74
|
+
Needs Python 3.11 or newer, Linux or macOS, and a terminal with truecolor
|
|
75
|
+
(kitty, foot, Alacritty, WezTerm, Ghostty, iTerm2 and most others).
|
|
76
|
+
|
|
77
|
+
## Use
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
cloudspin # plays ~/Music
|
|
81
|
+
cloudspin ~/Music/phonk # a folder
|
|
82
|
+
cloudspin song.flac other.mp3 # files
|
|
83
|
+
cloudspin https://example.com/stream.mp3 # a link
|
|
84
|
+
cloudspin --city "New Delhi" # set the city once; it is remembered
|
|
85
|
+
cloudspin --demo # look around without any music or sound
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Keys
|
|
89
|
+
|
|
90
|
+
| Key | Does |
|
|
91
|
+
| --- | --- |
|
|
92
|
+
| `space` | Play or pause |
|
|
93
|
+
| `n` `p` | Next song, previous song |
|
|
94
|
+
| `←` `→` | Skip 5 seconds (`Shift` for 30) |
|
|
95
|
+
| `+` `-` | Volume |
|
|
96
|
+
| `s` | Shuffle |
|
|
97
|
+
| `r` | Repeat: off, all, one |
|
|
98
|
+
| `o` | Open a link, file or folder and play it |
|
|
99
|
+
| `w` | Sky: follow the song, follow the weather, or pin a scene |
|
|
100
|
+
| `t` | Colours: follow the sky, follow the cover art, or a theme |
|
|
101
|
+
| `c` | Choose the city |
|
|
102
|
+
| `u` | Switch °C and °F |
|
|
103
|
+
| `?` | Show the keys |
|
|
104
|
+
| `q` | Quit |
|
|
105
|
+
|
|
106
|
+
## How the sky picks a scene
|
|
107
|
+
|
|
108
|
+
With the sky set to follow the song (the default), Cloudspin looks for a
|
|
109
|
+
scene in this order and uses the first one it finds:
|
|
110
|
+
|
|
111
|
+
1. **Your rules.** Words you map to scenes in the config file.
|
|
112
|
+
2. **The tags.** The genre tag, then sky words in the title or album.
|
|
113
|
+
`phonk`, `metal` and `dubstep` storm; `lofi`, `jazz` and `acoustic` get the
|
|
114
|
+
evening; `synthwave` and `r&b` get the night; `blues` rains; `dream pop`
|
|
115
|
+
fogs over; `christmas` snows; `pop` and `dance` get a sunny day. A song
|
|
116
|
+
called "Midnight Rain" needs no tag at all.
|
|
117
|
+
3. **A short listen.** If `ffmpeg` is installed, 30 seconds of the song are
|
|
118
|
+
measured for loudness, tempo, bass and brightness. Loud, fast and
|
|
119
|
+
bass-heavy becomes a storm; quiet and slow becomes night.
|
|
120
|
+
4. **The real weather**, if nothing above says anything.
|
|
121
|
+
|
|
122
|
+
The caption in the top right corner of the sky always says which scene is
|
|
123
|
+
showing and why, for example `Thunderstorm, tagged Drift phonk`.
|
|
124
|
+
|
|
125
|
+
The scenes are `storm`, `rain`, `evening`, `night`, `day`, `dawn`, `snow`,
|
|
126
|
+
`fog` and `overcast`.
|
|
127
|
+
|
|
128
|
+
## Settings
|
|
129
|
+
|
|
130
|
+
Settings live in `~/.config/cloudspin/config.toml`. Everything is optional.
|
|
131
|
+
|
|
132
|
+
```toml
|
|
133
|
+
city = "New Delhi"
|
|
134
|
+
units = "metric" # or "imperial"
|
|
135
|
+
sky = "song" # "song", "weather", or a scene name to pin
|
|
136
|
+
colors = "sky" # "sky", "cover", a built-in theme, or one of yours
|
|
137
|
+
music = "~/Music"
|
|
138
|
+
volume = 70
|
|
139
|
+
fps = 24 # lower this on a slow terminal or over SSH
|
|
140
|
+
|
|
141
|
+
# Send particular artists, albums or words to a scene.
|
|
142
|
+
[moods]
|
|
143
|
+
"kordhell" = "storm"
|
|
144
|
+
"study mix" = "evening"
|
|
145
|
+
|
|
146
|
+
# Your own colours. Only `accent` is required.
|
|
147
|
+
[themes.neon]
|
|
148
|
+
accent = "#39ff88"
|
|
149
|
+
accent2 = "#00c2ff"
|
|
150
|
+
background = "#07100c"
|
|
151
|
+
disc = "#39ff88" # the record label, when the song has no cover art
|
|
152
|
+
disc2 = "#ffffff"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Built-in themes: `sky`, `cover`, `amber`, `orchid`, `lagoon`, `moss`, `rose`, `mono`.
|
|
156
|
+
|
|
157
|
+
## Good to know
|
|
158
|
+
|
|
159
|
+
- **The bars are generative.** The spectrum moves with the play state, the
|
|
160
|
+
volume and a tempo chosen per song. It is not a live analysis of the audio.
|
|
161
|
+
- **The listen is a guess.** Step 3 above is a heuristic that has only been
|
|
162
|
+
checked against synthetic test audio. Tags and your own rules are exact;
|
|
163
|
+
use `[moods]` when it gets a song wrong.
|
|
164
|
+
- **Links need mpv.** Plain audio URLs and radio streams work with mpv alone.
|
|
165
|
+
Sites like YouTube also need `yt-dlp`.
|
|
166
|
+
- **Windows is not supported** except through WSL: playback control uses a
|
|
167
|
+
Unix socket.
|
|
168
|
+
- **MPRIS** (media keys, `playerctl`, Waybar) works if you have the
|
|
169
|
+
`mpv-mpris` plugin installed for mpv; Cloudspin loads your normal mpv config.
|
|
170
|
+
|
|
171
|
+
## Packaging status
|
|
172
|
+
|
|
173
|
+
| Channel | Status |
|
|
174
|
+
| --- | --- |
|
|
175
|
+
| Git (`pipx`, `uv`) | Works today |
|
|
176
|
+
| PyPI and npm | Published by `.github/workflows/release.yml` when a `v*` tag is pushed. Setup steps are at the top of that file. |
|
|
177
|
+
| AUR | `packaging/aur/PKGBUILD` is written; it builds from the PyPI release |
|
|
178
|
+
| Homebrew | Not started |
|
|
179
|
+
|
|
180
|
+
The npm package is a small launcher that runs the Python app through `uv` or `pipx`.
|
|
181
|
+
|
|
182
|
+
## Develop
|
|
183
|
+
|
|
184
|
+
```sh
|
|
185
|
+
git clone https://github.com/itsHarshDabas/Cloudspin && cd Cloudspin
|
|
186
|
+
python -m venv .venv && . .venv/bin/activate
|
|
187
|
+
pip install -e ".[dev]"
|
|
188
|
+
pytest
|
|
189
|
+
python scripts/screenshot.py out.png --song 2 # render the app to a PNG, no terminal needed
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
The code is small and split by job:
|
|
193
|
+
|
|
194
|
+
| File | Job |
|
|
195
|
+
| --- | --- |
|
|
196
|
+
| `sky.py` | The procedural sky and landscape |
|
|
197
|
+
| `canvas.py` | Half-block pixel drawing |
|
|
198
|
+
| `vinyl.py`, `spectrum.py` | The record and the bars |
|
|
199
|
+
| `mood.py` | Choosing a scene for a song |
|
|
200
|
+
| `weather.py` | Open-Meteo and sun and moon maths |
|
|
201
|
+
| `player.py` | mpv control and the queue |
|
|
202
|
+
| `widgets.py`, `app.py` | The interface |
|
|
203
|
+
|
|
204
|
+
## Licence
|
|
205
|
+
|
|
206
|
+
MIT
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
cloudspin/__init__.py,sha256=aQ5kyLuD1RcYczbKvN99YlgBE72RF03fGw1wO6Azkes,95
|
|
2
|
+
cloudspin/__main__.py,sha256=MHKZ_ae3fSLGTLUUMOx15fWdeOnJSHhq-zslRP5F5Lc,79
|
|
3
|
+
cloudspin/app.py,sha256=hZAZFSfA536dxOczf_hFaNwRbROYzxExrTUD_tsUmdc,19763
|
|
4
|
+
cloudspin/canvas.py,sha256=Kz-aapw_5CoDGTZyKFR1Txv1ZL4ZtuVI1j7QzUSnfCw,11455
|
|
5
|
+
cloudspin/cli.py,sha256=FQy6Fj5JCbNbkRdSQnZmussGX_4BF9FLwI7rX4iVSKE,3954
|
|
6
|
+
cloudspin/color.py,sha256=ZgVPwITBhKgDgPFP7fEDgmsI4EiQmQ3xIJijuetJKbI,2295
|
|
7
|
+
cloudspin/config.py,sha256=WAV4pAUTlqJkympm0JVYL1F_8859ASoj-i1REKERfnY,4060
|
|
8
|
+
cloudspin/library.py,sha256=cNbsnDHcCoFsIHuHjdNtnC0wxlnt_Z2_E3-GqDV-YkY,4546
|
|
9
|
+
cloudspin/mood.py,sha256=yBhe9oLngLtkl4g_-9Dq98Lz6f16g0LDAXhkS4t6Cbk,10152
|
|
10
|
+
cloudspin/player.py,sha256=GJPNg83mqOFBjhXFgFTFU_Qd6G3OYOOFugbnKbVfJ2U,15233
|
|
11
|
+
cloudspin/screens.py,sha256=OBMC_7uuaMYWN4apXRlrlD04lqRQrcVAxFI3EmzCW9c,3900
|
|
12
|
+
cloudspin/sky.py,sha256=qtx3BG7axHfanJBVev_MFsKBceXw4tPvGzsQt6cqD4o,33939
|
|
13
|
+
cloudspin/songlook.py,sha256=wxMYmQHLkTvOlv_QEbsDWCf0xlNKl9fkUyg67O5UCm8,3982
|
|
14
|
+
cloudspin/spectrum.py,sha256=30CLB3fEjmfM7vr0EaMJ4_njJmLRlwgr810zTT5W6OU,3057
|
|
15
|
+
cloudspin/themes.py,sha256=ghPsmtKPlLVaVTmbnhoSp3_l-els95zlk6eHa5yagY8,3200
|
|
16
|
+
cloudspin/vinyl.py,sha256=dbNAR5u7ObZxYU6vksgAsyyTLLhHt4Cpyvt7YIVFlDI,7638
|
|
17
|
+
cloudspin/weather.py,sha256=xt03r904ikPR3VUdfJe-7UlE1cP9gmXxVPX-1nNYzBY,12235
|
|
18
|
+
cloudspin/widgets.py,sha256=jlo21ZU9d0mmbn4LQ7ky77yxleccAMTB-rCTpLuEnyM,28105
|
|
19
|
+
cloudspin-0.1.0.dist-info/METADATA,sha256=Z2M4ZKCC3n8bXvOZt7HW868kHT3gweaX4MNUAq7e5Xk,7905
|
|
20
|
+
cloudspin-0.1.0.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
21
|
+
cloudspin-0.1.0.dist-info/entry_points.txt,sha256=ns7ZSSAW3RSDnxtj5F0si85ZyGwny9QnByU-HvCMOy4,49
|
|
22
|
+
cloudspin-0.1.0.dist-info/licenses/LICENSE,sha256=mMoe-B3GqNGxc65D1KctAN6g5mp8w71QaS6dD3A8akM,1068
|
|
23
|
+
cloudspin-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Harsh Dabas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|