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.
@@ -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
+ ![Cloudspin playing a lo-fi song under an evening sky](https://raw.githubusercontent.com/itsHarshDabas/Cloudspin/main/docs/evening.png)
38
+
39
+ | Phonk gets a storm | Synthwave gets the night, in the cover's colours |
40
+ | --- | --- |
41
+ | ![Thunderstorm scene](https://raw.githubusercontent.com/itsHarshDabas/Cloudspin/main/docs/storm.png) | ![Night scene](https://raw.githubusercontent.com/itsHarshDabas/Cloudspin/main/docs/night.png) |
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,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cloudspin = cloudspin.cli:main
@@ -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.