rocksky 0.6.0 → 0.8.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 +1 -1
- 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 +58 -0
- 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: 0b8b76d8708ad8f7131598c1440f644a6e037f5f83d15438c64b9b855e41cbca
|
|
4
|
+
data.tar.gz: 746d5eaad86c2ecc50fc8e24b64e34c06619df8f7446258d5974e84050df9088
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8978ba1c65543698e7af1790d8e2eb0e9c38048b6b1d15c15abc8482681ea13238bda48fb810ef122a6de59ba42ed1983522d336df809c3277c50650f5c6330a
|
|
7
|
+
data.tar.gz: 3e573bd6311727ae239f95de13b0dcc38b77bd8aa0a1d3d7c74e08c0e97d7747d3de144f076a9956a6445c10de3bac1e2598d7da51dc62871287cfd07811e57a
|
data/README.md
CHANGED
|
@@ -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.5.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": "f0a2965681967c261cd9b11ddf3ccf33fbc813cd4551cad35316f25e988c9e2c",
|
|
6
|
+
"aarch64-linux-gnu": "345f0545415ea86a9b1d6f397c36f1810ce78140c7b1db3eee4bdb7b9299f4f2",
|
|
7
|
+
"x86_64-apple-darwin": "d2568ab8c781851023c9922f7b7853adbd7af40bfa606814ef6abcd541510eb7",
|
|
8
|
+
"x86_64-linux-gnu": "9b6b17d884207a3fb79b0c89d7db4d24817ca01a947616ffafdde9f47f1f4931",
|
|
9
|
+
"x86_64-unknown-freebsd": "aba544031f8e146086a0ea5628382bcf19c9f6a3311cbb6586fa8661ca5da914",
|
|
10
|
+
"x86_64-unknown-netbsd": "483a0b272e080f596709812eb55cbe983332cf3f40ae3fa15ed7e0179df21636"
|
|
11
11
|
}
|
|
12
12
|
}
|
data/lib/rocksky/version.rb
CHANGED
data/lib/rocksky.rb
CHANGED
|
@@ -27,6 +27,9 @@ 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_update_seen(const char*, const char*, const char*)",
|
|
31
|
+
"char* rocksky_library_get(const char*, const char*, const char*, const char*)",
|
|
32
|
+
"char* rocksky_library_post(const char*, const char*, const char*, const char*)",
|
|
30
33
|
"char* rocksky_match_song(const char*, const char*, const char*, const char*, const char*)",
|
|
31
34
|
"char* rocksky_top_tracks_interval(const char*, unsigned int, unsigned int, const char*, unsigned int, const char*, const char*)",
|
|
32
35
|
"char* rocksky_top_artists_interval(const char*, unsigned int, unsigned int, const char*, unsigned int, const char*, const char*)",
|
|
@@ -42,6 +45,8 @@ module Rocksky
|
|
|
42
45
|
"char* rocksky_agent_like(void*, const char*, const char*)",
|
|
43
46
|
"char* rocksky_agent_follow(void*, const char*)",
|
|
44
47
|
"char* rocksky_agent_shout(void*, const char*, const char*, const char*)",
|
|
48
|
+
"char* rocksky_agent_shout_with_gif(void*, const char*, const char*, const char*, const char*)",
|
|
49
|
+
"char* rocksky_agent_reply_shout_with_gif(void*, const char*, const char*, const char*, const char*, const char*, const char*)",
|
|
45
50
|
"char* rocksky_agent_refresh_session(void*)"
|
|
46
51
|
].each { |sig| extern sig }
|
|
47
52
|
end
|
|
@@ -100,6 +105,30 @@ module Rocksky
|
|
|
100
105
|
unwrap(C.rocksky_get(base.to_s, nsid, JSON.generate(params), token.to_s))
|
|
101
106
|
end
|
|
102
107
|
|
|
108
|
+
# ---- notifications (auth-gated; +token+ required) ----
|
|
109
|
+
|
|
110
|
+
# The authenticated viewer's unread-notification count. Returns
|
|
111
|
+
# { "count" => Integer }.
|
|
112
|
+
def self.unread_count(token:, base: nil)
|
|
113
|
+
get("app.rocksky.notification.getUnreadCount", {}, base: base, token: token)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# The authenticated viewer's notifications, most recent first. +limit+ defaults
|
|
117
|
+
# to 30 server-side; +cursor+ paginates. Returns
|
|
118
|
+
# { "notifications" => [...], "unreadCount" => Integer, "cursor" => String? }.
|
|
119
|
+
def self.notifications(token:, limit: nil, cursor: nil, base: nil)
|
|
120
|
+
params = {}
|
|
121
|
+
params[:limit] = limit unless limit.nil?
|
|
122
|
+
params[:cursor] = cursor unless cursor.nil?
|
|
123
|
+
get("app.rocksky.notification.listNotifications", params, base: base, token: token)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Mark notifications as viewed. +ids+ is an array of notification ids, or an
|
|
127
|
+
# empty array to mark *all* as viewed. Returns { "unreadCount" => Integer }.
|
|
128
|
+
def self.update_seen(token:, ids: [], base: nil)
|
|
129
|
+
unwrap(C.rocksky_update_seen(base.to_s, token.to_s, JSON.generate(ids)))
|
|
130
|
+
end
|
|
131
|
+
|
|
103
132
|
# Resolve full canonical metadata for a bare title + artist (matchSong).
|
|
104
133
|
def self.match_song(title, artist, mb_id: nil, isrc: nil, base: nil)
|
|
105
134
|
unwrap(C.rocksky_match_song(base.to_s, title, artist, mb_id.to_s, isrc.to_s))
|
|
@@ -198,6 +227,24 @@ module Rocksky
|
|
|
198
227
|
Rocksky.unwrap(C.rocksky_agent_shout(@ptr, subject_uri, subject_cid, message))
|
|
199
228
|
end
|
|
200
229
|
|
|
230
|
+
# Post a shout with an optional GIF/sticker/clip attachment. Pass at least
|
|
231
|
+
# one of +message+ / +gif+. +gif+ is a Hash with camelCase keys ("url"
|
|
232
|
+
# required, plus "previewUrl", "alt", "width", "height").
|
|
233
|
+
def shout_with_gif(subject_uri, subject_cid, message: nil, gif: nil)
|
|
234
|
+
Rocksky.unwrap(C.rocksky_agent_shout_with_gif(
|
|
235
|
+
@ptr, subject_uri, subject_cid, message.to_s, gif ? JSON.generate(gif) : ""
|
|
236
|
+
))
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Reply to a shout with an optional GIF/sticker/clip attachment. Semantics
|
|
240
|
+
# match #shout_with_gif, plus a parent strong-ref (+parent_uri+/+parent_cid+).
|
|
241
|
+
def reply_shout_with_gif(subject_uri, subject_cid, parent_uri, parent_cid, message: nil, gif: nil)
|
|
242
|
+
Rocksky.unwrap(C.rocksky_agent_reply_shout_with_gif(
|
|
243
|
+
@ptr, subject_uri, subject_cid, parent_uri, parent_cid,
|
|
244
|
+
message.to_s, gif ? JSON.generate(gif) : ""
|
|
245
|
+
))
|
|
246
|
+
end
|
|
247
|
+
|
|
201
248
|
def refresh_session
|
|
202
249
|
Rocksky.unwrap(C.rocksky_agent_refresh_session(@ptr))
|
|
203
250
|
end
|
|
@@ -210,4 +257,15 @@ module Rocksky
|
|
|
210
257
|
@ptr = Fiddle::Pointer.new(0)
|
|
211
258
|
end
|
|
212
259
|
end
|
|
260
|
+
|
|
261
|
+
# Build an authenticated app.rocksky.library.* (uploaded-music) client. The
|
|
262
|
+
# token is required — every library method is auth-gated.
|
|
263
|
+
#
|
|
264
|
+
# lib = Rocksky.library(token)
|
|
265
|
+
# lib.get_song(song_id)
|
|
266
|
+
def self.library(token, base: nil)
|
|
267
|
+
Library.new(token, base: base)
|
|
268
|
+
end
|
|
213
269
|
end
|
|
270
|
+
|
|
271
|
+
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.8.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
|