rocksky 0.5.0 → 0.7.0
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.
- checksums.yaml +4 -4
- data/README.md +6 -3
- data/lib/rocksky/library.rb +232 -0
- data/lib/rocksky/manifest.json +7 -7
- data/lib/rocksky/version.rb +1 -1
- data/lib/rocksky.rb +21 -3
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 04a23ddf1b0b2c3207cb576fa5809509520ffe2caa5af6edd45c8e8d56f6a873
|
|
4
|
+
data.tar.gz: e3477fabe8cded03dadb16353781143f9c70722c7e38196154a4c01e47a54583
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 14b72030dbe0dd39f5b277af0729913f71739c89e62d57c89b46abb8bc23300f991bcb6e8b5ee485197886058d372c57e31a27d92b5fd53d3b2e2d644e50d859
|
|
7
|
+
data.tar.gz: 83c8ce3c29d4b90f2baa3f9111fe1207099bb89435aa142edbbbd3bef2a13af9ba19ec2d997b4544b72e2e972958ebe98f78083aff6a0d167d8756d76294c1b4
|
data/README.md
CHANGED
|
@@ -14,7 +14,7 @@ gem install rocksky
|
|
|
14
14
|
Or in a Gemfile:
|
|
15
15
|
|
|
16
16
|
```ruby
|
|
17
|
-
gem "rocksky", "~> 0.
|
|
17
|
+
gem "rocksky", "~> 0.7"
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
The gem is pure-Ruby; the native library is fetched from the GitHub release on
|
|
@@ -92,11 +92,14 @@ below). Then `scrobble(track)` (fans out to artist/album/song/scrobble),
|
|
|
92
92
|
`refresh_session`, and `close` (release the native handle).
|
|
93
93
|
|
|
94
94
|
**Two scrobble paths** — `scrobble(track)` takes full metadata, while
|
|
95
|
-
`scrobble_match(
|
|
95
|
+
`scrobble_match(params)` takes a single Hash with camelCase string keys —
|
|
96
|
+
required `"title"`/`"artist"`, optional `"album"` (override), `"mbId"`/`"isrc"`
|
|
97
|
+
(match anchors), `"timestamp"` (scrobbled-at Unix seconds) — matching a bare
|
|
96
98
|
title + artist first, then writes.
|
|
97
99
|
|
|
98
100
|
```ruby
|
|
99
|
-
agent.scrobble_match("Chaser", "Calibro 35",
|
|
101
|
+
agent.scrobble_match("title" => "Chaser", "artist" => "Calibro 35",
|
|
102
|
+
"album" => "Jazzploitation")
|
|
100
103
|
```
|
|
101
104
|
|
|
102
105
|
**Dedup + realtime** — with `dedup_path:` set at login, `agent.sync_repo`
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rocksky
|
|
4
|
+
# Authenticated client for the app.rocksky.library.* API — the Subsonic /
|
|
5
|
+
# navidrome-compatible surface over a user's uploaded music. Every method
|
|
6
|
+
# requires auth, so a token is mandatory at construction (see Rocksky.library).
|
|
7
|
+
# Optional params are Ruby keyword args (nil = omitted); wire keys stay
|
|
8
|
+
# camelCase. Returns the parsed JSON payload.
|
|
9
|
+
class Library
|
|
10
|
+
def initialize(token, base: nil)
|
|
11
|
+
raise Error, "app.rocksky.library.* requires an access token" if token.nil? || token.to_s.empty?
|
|
12
|
+
|
|
13
|
+
@token = token.to_s
|
|
14
|
+
@base = base.to_s
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# app.rocksky.library.ping
|
|
18
|
+
def ping()
|
|
19
|
+
query("app.rocksky.library.ping", {})
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# app.rocksky.library.getLicense
|
|
23
|
+
def get_license()
|
|
24
|
+
query("app.rocksky.library.getLicense", {})
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# app.rocksky.library.getMusicFolders
|
|
28
|
+
def get_music_folders()
|
|
29
|
+
query("app.rocksky.library.getMusicFolders", {})
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# app.rocksky.library.getScanStatus
|
|
33
|
+
def get_scan_status()
|
|
34
|
+
query("app.rocksky.library.getScanStatus", {})
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# app.rocksky.library.startScan
|
|
38
|
+
def start_scan()
|
|
39
|
+
query("app.rocksky.library.startScan", {})
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# app.rocksky.library.getUser
|
|
43
|
+
def get_user()
|
|
44
|
+
query("app.rocksky.library.getUser", {})
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# app.rocksky.library.getArtists
|
|
48
|
+
def get_artists()
|
|
49
|
+
query("app.rocksky.library.getArtists", {})
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# app.rocksky.library.getIndexes
|
|
53
|
+
def get_indexes()
|
|
54
|
+
query("app.rocksky.library.getIndexes", {})
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# app.rocksky.library.getArtist
|
|
58
|
+
def get_artist(id)
|
|
59
|
+
query("app.rocksky.library.getArtist", { id: id })
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# app.rocksky.library.getArtistInfo
|
|
63
|
+
def get_artist_info(id)
|
|
64
|
+
query("app.rocksky.library.getArtistInfo", { id: id })
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# app.rocksky.library.getAlbum
|
|
68
|
+
def get_album(id)
|
|
69
|
+
query("app.rocksky.library.getAlbum", { id: id })
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# app.rocksky.library.getAlbumList
|
|
73
|
+
def get_album_list(type, size: nil, offset: nil, from_year: nil, to_year: nil, genre: nil)
|
|
74
|
+
query("app.rocksky.library.getAlbumList", { type: type, size: size, offset: offset, fromYear: from_year, toYear: to_year, genre: genre })
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# app.rocksky.library.getAlbumInfo
|
|
78
|
+
def get_album_info(id)
|
|
79
|
+
query("app.rocksky.library.getAlbumInfo", { id: id })
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# app.rocksky.library.getSong
|
|
83
|
+
def get_song(id)
|
|
84
|
+
query("app.rocksky.library.getSong", { id: id })
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# app.rocksky.library.getRandomSongs
|
|
88
|
+
def get_random_songs(size: nil, genre: nil, from_year: nil, to_year: nil)
|
|
89
|
+
query("app.rocksky.library.getRandomSongs", { size: size, genre: genre, fromYear: from_year, toYear: to_year })
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# app.rocksky.library.getSongsByGenre
|
|
93
|
+
def get_songs_by_genre(genre, count: nil, offset: nil)
|
|
94
|
+
query("app.rocksky.library.getSongsByGenre", { genre: genre, count: count, offset: offset })
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# app.rocksky.library.getSimilarSongs
|
|
98
|
+
def get_similar_songs(id, count: nil)
|
|
99
|
+
query("app.rocksky.library.getSimilarSongs", { id: id, count: count })
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# app.rocksky.library.getTopSongs
|
|
103
|
+
def get_top_songs(artist, count: nil)
|
|
104
|
+
query("app.rocksky.library.getTopSongs", { artist: artist, count: count })
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# app.rocksky.library.getLyrics
|
|
108
|
+
def get_lyrics(artist: nil, title: nil)
|
|
109
|
+
query("app.rocksky.library.getLyrics", { artist: artist, title: title })
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# app.rocksky.library.getMusicDirectory
|
|
113
|
+
def get_music_directory(id)
|
|
114
|
+
query("app.rocksky.library.getMusicDirectory", { id: id })
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# app.rocksky.library.getGenres
|
|
118
|
+
def get_genres()
|
|
119
|
+
query("app.rocksky.library.getGenres", {})
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# app.rocksky.library.search
|
|
123
|
+
def search(query, artist_count: nil, artist_offset: nil, album_count: nil, album_offset: nil, song_count: nil, song_offset: nil)
|
|
124
|
+
query("app.rocksky.library.search", { query: query, artistCount: artist_count, artistOffset: artist_offset, albumCount: album_count, albumOffset: album_offset, songCount: song_count, songOffset: song_offset })
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# app.rocksky.library.getStarred
|
|
128
|
+
def get_starred()
|
|
129
|
+
query("app.rocksky.library.getStarred", {})
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# app.rocksky.library.star
|
|
133
|
+
def star(id, album_id: nil, artist_id: nil)
|
|
134
|
+
procedure("app.rocksky.library.star", { id: id, albumId: album_id, artistId: artist_id })
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# app.rocksky.library.unstar
|
|
138
|
+
def unstar(id, album_id: nil, artist_id: nil)
|
|
139
|
+
procedure("app.rocksky.library.unstar", { id: id, albumId: album_id, artistId: artist_id })
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# app.rocksky.library.getPlaylists
|
|
143
|
+
def get_playlists()
|
|
144
|
+
query("app.rocksky.library.getPlaylists", {})
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# app.rocksky.library.getPlaylist
|
|
148
|
+
def get_playlist(id)
|
|
149
|
+
query("app.rocksky.library.getPlaylist", { id: id })
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# app.rocksky.library.createPlaylist
|
|
153
|
+
def create_playlist(name)
|
|
154
|
+
procedure("app.rocksky.library.createPlaylist", { name: name })
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# app.rocksky.library.updatePlaylist
|
|
158
|
+
def update_playlist(playlist_id, name: nil, comment: nil, song_id_to_add: nil, song_index_to_remove: nil)
|
|
159
|
+
procedure("app.rocksky.library.updatePlaylist", { playlistId: playlist_id, name: name, comment: comment, songIdToAdd: song_id_to_add, songIndexToRemove: song_index_to_remove })
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# app.rocksky.library.deletePlaylist
|
|
163
|
+
def delete_playlist(id)
|
|
164
|
+
procedure("app.rocksky.library.deletePlaylist", { id: id })
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# app.rocksky.library.deleteSong
|
|
168
|
+
def delete_song(id)
|
|
169
|
+
procedure("app.rocksky.library.deleteSong", { id: id })
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# app.rocksky.library.deleteAlbum
|
|
173
|
+
def delete_album(id)
|
|
174
|
+
procedure("app.rocksky.library.deleteAlbum", { id: id })
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# app.rocksky.library.scrobble
|
|
178
|
+
def scrobble(id, time: nil, submission: nil)
|
|
179
|
+
procedure("app.rocksky.library.scrobble", { id: id, time: time, submission: submission })
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# app.rocksky.library.updateNowPlaying
|
|
183
|
+
def update_now_playing(id)
|
|
184
|
+
procedure("app.rocksky.library.updateNowPlaying", { id: id })
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# app.rocksky.library.getNowPlaying
|
|
188
|
+
def get_now_playing()
|
|
189
|
+
query("app.rocksky.library.getNowPlaying", {})
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# app.rocksky.library.getPlayQueue
|
|
193
|
+
def get_play_queue()
|
|
194
|
+
query("app.rocksky.library.getPlayQueue", {})
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# app.rocksky.library.savePlayQueue
|
|
198
|
+
def save_play_queue(id: nil, current: nil, position: nil)
|
|
199
|
+
procedure("app.rocksky.library.savePlayQueue", { id: id, current: current, position: position })
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# app.rocksky.library.getStreamUrl
|
|
203
|
+
def get_stream_url(id, max_bit_rate: nil, format: nil)
|
|
204
|
+
query("app.rocksky.library.getStreamUrl", { id: id, maxBitRate: max_bit_rate, format: format })
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# app.rocksky.library.getDownloadUrl
|
|
208
|
+
def get_download_url(id)
|
|
209
|
+
query("app.rocksky.library.getDownloadUrl", { id: id })
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# app.rocksky.library.getCoverArtUrl
|
|
213
|
+
def get_cover_art_url(id, size: nil)
|
|
214
|
+
query("app.rocksky.library.getCoverArtUrl", { id: id, size: size })
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# app.rocksky.library.getInternetRadioStations
|
|
218
|
+
def get_internet_radio_stations()
|
|
219
|
+
query("app.rocksky.library.getInternetRadioStations", {})
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
private
|
|
223
|
+
|
|
224
|
+
def query(nsid, params = {})
|
|
225
|
+
Rocksky.unwrap(C.rocksky_library_get(@base, @token, nsid, JSON.generate(params.compact)))
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def procedure(nsid, body = {})
|
|
229
|
+
Rocksky.unwrap(C.rocksky_library_post(@base, @token, nsid, JSON.generate(body.compact)))
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
data/lib/rocksky/manifest.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"repo": "tsirysndr/rocksky",
|
|
3
|
-
"tag": "bindings-v0.
|
|
3
|
+
"tag": "bindings-v0.4.0",
|
|
4
4
|
"checksums": {
|
|
5
|
-
"aarch64-apple-darwin": "
|
|
6
|
-
"aarch64-linux-gnu": "
|
|
7
|
-
"x86_64-apple-darwin": "
|
|
8
|
-
"x86_64-linux-gnu": "
|
|
9
|
-
"x86_64-unknown-freebsd": "
|
|
10
|
-
"x86_64-unknown-netbsd": "
|
|
5
|
+
"aarch64-apple-darwin": "cd828960ba30880c121eca655a890625360c8b6f3d7d1e15ecbfeda9934c1496",
|
|
6
|
+
"aarch64-linux-gnu": "43d52700719ca325a7cc4bf24ae6e8eef8e71bdf532968bcc029f067e09e660f",
|
|
7
|
+
"x86_64-apple-darwin": "54749d2c37bd2f4f487a24b91ab935a6806f359e2bf8b52ec192d4421524aed0",
|
|
8
|
+
"x86_64-linux-gnu": "6750513f2a592637c436e28113aaa4e2cc2890829b337a3dcf999b40bbd7d924",
|
|
9
|
+
"x86_64-unknown-freebsd": "f1fa22d790c30dee2d4418e5a781338d4aeffbd334db48bc5d70bc94b88f23db",
|
|
10
|
+
"x86_64-unknown-netbsd": "4bb233727e965c45187cfa254206a25756c2c2fdc25e64df39f84f5d5eeb01d5"
|
|
11
11
|
}
|
|
12
12
|
}
|
data/lib/rocksky/version.rb
CHANGED
data/lib/rocksky.rb
CHANGED
|
@@ -27,6 +27,8 @@ module Rocksky
|
|
|
27
27
|
"char* rocksky_top_tracks(const char*, unsigned int, unsigned int)",
|
|
28
28
|
"char* rocksky_global_stats(const char*)",
|
|
29
29
|
"char* rocksky_get(const char*, const char*, const char*, const char*)",
|
|
30
|
+
"char* rocksky_library_get(const char*, const char*, const char*, const char*)",
|
|
31
|
+
"char* rocksky_library_post(const char*, const char*, const char*, const char*)",
|
|
30
32
|
"char* rocksky_match_song(const char*, const char*, const char*, const char*, const char*)",
|
|
31
33
|
"char* rocksky_top_tracks_interval(const char*, unsigned int, unsigned int, const char*, unsigned int, const char*, const char*)",
|
|
32
34
|
"char* rocksky_top_artists_interval(const char*, unsigned int, unsigned int, const char*, unsigned int, const char*, const char*)",
|
|
@@ -36,7 +38,7 @@ module Rocksky
|
|
|
36
38
|
"void* rocksky_agent_login(const char*, const char*, const char*, const char*, const char*)",
|
|
37
39
|
"void rocksky_agent_free(void*)",
|
|
38
40
|
"char* rocksky_agent_scrobble(void*, const char*)",
|
|
39
|
-
"char* rocksky_agent_scrobble_match(void*, const char
|
|
41
|
+
"char* rocksky_agent_scrobble_match(void*, const char*)",
|
|
40
42
|
"char* rocksky_agent_sync_repo(void*)",
|
|
41
43
|
"char* rocksky_agent_hydrate_from_jetstream(void*)",
|
|
42
44
|
"char* rocksky_agent_like(void*, const char*, const char*)",
|
|
@@ -166,8 +168,13 @@ module Rocksky
|
|
|
166
168
|
|
|
167
169
|
# Scrobble from just a title + artist (album optional, plus optional mb_id /
|
|
168
170
|
# isrc anchors): resolve full metadata via matchSong, then fan out.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
+
# Scrobble from just a title + artist. +input+ is a Hash with camelCase keys:
|
|
172
|
+
# required "title"/"artist"; optional "album", "mbId", "isrc" (match anchors),
|
|
173
|
+
# and "timestamp" (scrobbled-at Unix seconds, default now).
|
|
174
|
+
#
|
|
175
|
+
# agent.scrobble_match("title" => "Chaser", "artist" => "Calibro 35")
|
|
176
|
+
def scrobble_match(input)
|
|
177
|
+
Rocksky.unwrap(C.rocksky_agent_scrobble_match(@ptr, JSON.generate(input)))
|
|
171
178
|
end
|
|
172
179
|
|
|
173
180
|
# Download the caller's repo and (re)build the local dedup index (needs a
|
|
@@ -205,4 +212,15 @@ module Rocksky
|
|
|
205
212
|
@ptr = Fiddle::Pointer.new(0)
|
|
206
213
|
end
|
|
207
214
|
end
|
|
215
|
+
|
|
216
|
+
# Build an authenticated app.rocksky.library.* (uploaded-music) client. The
|
|
217
|
+
# token is required — every library method is auth-gated.
|
|
218
|
+
#
|
|
219
|
+
# lib = Rocksky.library(token)
|
|
220
|
+
# lib.get_song(song_id)
|
|
221
|
+
def self.library(token, base: nil)
|
|
222
|
+
Library.new(token, base: base)
|
|
223
|
+
end
|
|
208
224
|
end
|
|
225
|
+
|
|
226
|
+
require_relative "rocksky/library"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rocksky
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rocksky
|
|
@@ -80,6 +80,7 @@ files:
|
|
|
80
80
|
- README.md
|
|
81
81
|
- exe/rocksky-console
|
|
82
82
|
- lib/rocksky.rb
|
|
83
|
+
- lib/rocksky/library.rb
|
|
83
84
|
- lib/rocksky/manifest.json
|
|
84
85
|
- lib/rocksky/native.rb
|
|
85
86
|
- lib/rocksky/version.rb
|