rocksky 0.1.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 +7 -0
- data/CHANGELOG.md +8 -0
- data/LICENSE +21 -0
- data/README.md +224 -0
- data/exe/rocksky-console +33 -0
- data/lib/rocksky/client.rb +84 -0
- data/lib/rocksky/error.rb +58 -0
- data/lib/rocksky/http.rb +123 -0
- data/lib/rocksky/resources/actor.rb +60 -0
- data/lib/rocksky/resources/album.rb +22 -0
- data/lib/rocksky/resources/apikey.rb +28 -0
- data/lib/rocksky/resources/artist.rb +40 -0
- data/lib/rocksky/resources/base.rb +24 -0
- data/lib/rocksky/resources/charts.rb +33 -0
- data/lib/rocksky/resources/feed.rb +51 -0
- data/lib/rocksky/resources/graph.rb +34 -0
- data/lib/rocksky/resources/like.rb +26 -0
- data/lib/rocksky/resources/mirror.rb +22 -0
- data/lib/rocksky/resources/player.rb +73 -0
- data/lib/rocksky/resources/playlist.rb +45 -0
- data/lib/rocksky/resources/scrobble.rb +36 -0
- data/lib/rocksky/resources/shout.rb +58 -0
- data/lib/rocksky/resources/song.rb +38 -0
- data/lib/rocksky/resources/spotify.rb +37 -0
- data/lib/rocksky/resources/stats.rb +16 -0
- data/lib/rocksky/version.rb +3 -0
- data/lib/rocksky.rb +32 -0
- data/rocksky.gemspec +41 -0
- metadata +130 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.artist.*` endpoints.
|
|
4
|
+
class Artist < Base
|
|
5
|
+
# Fetch an artist by AT-URI.
|
|
6
|
+
def get_artist(uri:)
|
|
7
|
+
query("app.rocksky.artist.getArtist", uri: uri)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# List artists. `names` may be an Array of strings; it will be joined CSV-style.
|
|
11
|
+
def get_artists(limit: nil, offset: nil, names: nil, genre: nil)
|
|
12
|
+
query("app.rocksky.artist.getArtists",
|
|
13
|
+
limit: limit, offset: offset, names: names, genre: genre)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Albums by an artist.
|
|
17
|
+
def get_artist_albums(uri:)
|
|
18
|
+
query("app.rocksky.artist.getArtistAlbums", uri: uri)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Tracks by an artist.
|
|
22
|
+
def get_artist_tracks(uri:, limit: nil, offset: nil)
|
|
23
|
+
query("app.rocksky.artist.getArtistTracks",
|
|
24
|
+
uri: uri, limit: limit, offset: offset)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# All-time listeners for an artist.
|
|
28
|
+
def get_artist_listeners(uri:, limit: nil, offset: nil)
|
|
29
|
+
query("app.rocksky.artist.getArtistListeners",
|
|
30
|
+
uri: uri, limit: limit, offset: offset)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Recent listeners for an artist.
|
|
34
|
+
def get_artist_recent_listeners(uri:, limit: nil, offset: nil)
|
|
35
|
+
query("app.rocksky.artist.getArtistRecentListeners",
|
|
36
|
+
uri: uri, limit: limit, offset: offset)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# Shared plumbing for resource classes. Each subclass calls {#query} or
|
|
4
|
+
# {#procedure} with the lexicon NSID; the {Rocksky::HTTP} instance does the
|
|
5
|
+
# actual transport work.
|
|
6
|
+
class Base
|
|
7
|
+
attr_reader :http
|
|
8
|
+
|
|
9
|
+
def initialize(http)
|
|
10
|
+
@http = http
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
protected
|
|
14
|
+
|
|
15
|
+
def query(nsid, **params)
|
|
16
|
+
@http.query(nsid, params)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def procedure(nsid, params: {}, body: nil)
|
|
20
|
+
@http.procedure(nsid, params, body)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.charts.*` endpoints.
|
|
4
|
+
class Charts < Base
|
|
5
|
+
# Scrobble chart data.
|
|
6
|
+
def get_scrobbles_chart(did: nil, artist_uri: nil, album_uri: nil,
|
|
7
|
+
song_uri: nil, genre: nil, from: nil, to: nil)
|
|
8
|
+
query("app.rocksky.charts.getScrobblesChart",
|
|
9
|
+
did: did,
|
|
10
|
+
artisturi: artist_uri,
|
|
11
|
+
albumuri: album_uri,
|
|
12
|
+
songuri: song_uri,
|
|
13
|
+
genre: genre,
|
|
14
|
+
from: from,
|
|
15
|
+
to: to)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Top artists.
|
|
19
|
+
def get_top_artists(limit: nil, offset: nil, start_date: nil, end_date: nil)
|
|
20
|
+
query("app.rocksky.charts.getTopArtists",
|
|
21
|
+
limit: limit, offset: offset,
|
|
22
|
+
startDate: start_date, endDate: end_date)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Top tracks.
|
|
26
|
+
def get_top_tracks(limit: nil, offset: nil, start_date: nil, end_date: nil)
|
|
27
|
+
query("app.rocksky.charts.getTopTracks",
|
|
28
|
+
limit: limit, offset: offset,
|
|
29
|
+
startDate: start_date, endDate: end_date)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.feed.*` endpoints.
|
|
4
|
+
class Feed < Base
|
|
5
|
+
# Free-text search across the catalogue.
|
|
6
|
+
# `q` accepts a positional or `query:` keyword; both map to the lexicon's
|
|
7
|
+
# `query` parameter.
|
|
8
|
+
def search(q = nil, query: nil)
|
|
9
|
+
term = q || query
|
|
10
|
+
raise ArgumentError, "search needs a query string" if term.nil? || term.empty?
|
|
11
|
+
|
|
12
|
+
@http.query("app.rocksky.feed.search", query: term)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# List feed generators.
|
|
16
|
+
def get_feed_generators(size: nil)
|
|
17
|
+
query("app.rocksky.feed.getFeedGenerators", size: size)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Fetch a feed generator by URI.
|
|
21
|
+
def get_feed_generator(feed:)
|
|
22
|
+
query("app.rocksky.feed.getFeedGenerator", feed: feed)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Fetch feed contents.
|
|
26
|
+
def get_feed(feed:, limit: nil, cursor: nil)
|
|
27
|
+
query("app.rocksky.feed.getFeed", feed: feed, limit: limit, cursor: cursor)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Stories (recent highlights).
|
|
31
|
+
def get_stories(size: nil)
|
|
32
|
+
query("app.rocksky.feed.getStories", size: size)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Track recommendations for an actor.
|
|
36
|
+
def get_recommendations(did:, limit: nil)
|
|
37
|
+
query("app.rocksky.feed.getRecommendations", did: did, limit: limit)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Artist recommendations for an actor.
|
|
41
|
+
def get_artist_recommendations(did:, limit: nil)
|
|
42
|
+
query("app.rocksky.feed.getArtistRecommendations", did: did, limit: limit)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Album recommendations for an actor.
|
|
46
|
+
def get_album_recommendations(did:, limit: nil)
|
|
47
|
+
query("app.rocksky.feed.getAlbumRecommendations", did: did, limit: limit)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.graph.*` endpoints.
|
|
4
|
+
class Graph < Base
|
|
5
|
+
# Follow an account. `account` is a DID or handle.
|
|
6
|
+
def follow_account(account:)
|
|
7
|
+
procedure("app.rocksky.graph.followAccount", params: { account: account })
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Unfollow an account.
|
|
11
|
+
def unfollow_account(account:)
|
|
12
|
+
procedure("app.rocksky.graph.unfollowAccount", params: { account: account })
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Followers of an actor. `dids` may be a list; it will be CSV-encoded.
|
|
16
|
+
def get_followers(actor:, limit: nil, dids: nil, cursor: nil)
|
|
17
|
+
query("app.rocksky.graph.getFollowers",
|
|
18
|
+
actor: actor, limit: limit, dids: dids, cursor: cursor)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Accounts an actor follows.
|
|
22
|
+
def get_follows(actor:, limit: nil, dids: nil, cursor: nil)
|
|
23
|
+
query("app.rocksky.graph.getFollows",
|
|
24
|
+
actor: actor, limit: limit, dids: dids, cursor: cursor)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Followers of an actor that the viewer also knows.
|
|
28
|
+
def get_known_followers(actor:, limit: nil, cursor: nil)
|
|
29
|
+
query("app.rocksky.graph.getKnownFollowers",
|
|
30
|
+
actor: actor, limit: limit, cursor: cursor)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.like.*` endpoints. All require an authenticated client.
|
|
4
|
+
class Like < Base
|
|
5
|
+
# Like a song.
|
|
6
|
+
def like_song(uri:)
|
|
7
|
+
procedure("app.rocksky.like.likeSong", body: { uri: uri })
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Remove a like on a song.
|
|
11
|
+
def dislike_song(uri:)
|
|
12
|
+
procedure("app.rocksky.like.dislikeSong", body: { uri: uri })
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Like a shout.
|
|
16
|
+
def like_shout(uri:)
|
|
17
|
+
procedure("app.rocksky.like.likeShout", body: { uri: uri })
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Remove a like on a shout.
|
|
21
|
+
def dislike_shout(uri:)
|
|
22
|
+
procedure("app.rocksky.like.dislikeShout", body: { uri: uri })
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.mirror.*` endpoints. Require an authenticated client.
|
|
4
|
+
class Mirror < Base
|
|
5
|
+
# List configured mirror sources for the authenticated user.
|
|
6
|
+
def get_mirror_sources
|
|
7
|
+
query("app.rocksky.mirror.getMirrorSources")
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Configure a mirror source (e.g. Last.fm, ListenBrainz).
|
|
11
|
+
def put_mirror_source(provider:, enabled: nil, external_username: nil, api_key: nil)
|
|
12
|
+
body = {
|
|
13
|
+
provider: provider,
|
|
14
|
+
enabled: enabled,
|
|
15
|
+
externalUsername: external_username,
|
|
16
|
+
apiKey: api_key
|
|
17
|
+
}.compact
|
|
18
|
+
procedure("app.rocksky.mirror.putMirrorSource", body: body)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.player.*` endpoints — remote control of a Rocksky player.
|
|
4
|
+
class Player < Base
|
|
5
|
+
# Currently playing track.
|
|
6
|
+
def get_currently_playing(player_id: nil, actor: nil)
|
|
7
|
+
query("app.rocksky.player.getCurrentlyPlaying",
|
|
8
|
+
playerId: player_id, actor: actor)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Playback queue.
|
|
12
|
+
def get_playback_queue(player_id: nil)
|
|
13
|
+
query("app.rocksky.player.getPlaybackQueue", playerId: player_id)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Resume playback.
|
|
17
|
+
def play(player_id: nil)
|
|
18
|
+
procedure("app.rocksky.player.play", params: { playerId: player_id })
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Pause playback.
|
|
22
|
+
def pause(player_id: nil)
|
|
23
|
+
procedure("app.rocksky.player.pause", params: { playerId: player_id })
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Skip to next track.
|
|
27
|
+
def next(player_id: nil)
|
|
28
|
+
procedure("app.rocksky.player.next", params: { playerId: player_id })
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Go to previous track.
|
|
32
|
+
def previous(player_id: nil)
|
|
33
|
+
procedure("app.rocksky.player.previous", params: { playerId: player_id })
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Seek to position in milliseconds.
|
|
37
|
+
def seek(position:, player_id: nil)
|
|
38
|
+
procedure("app.rocksky.player.seek",
|
|
39
|
+
params: { playerId: player_id, position: position })
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Play a single file.
|
|
43
|
+
def play_file(file_id:, player_id: nil)
|
|
44
|
+
procedure("app.rocksky.player.playFile",
|
|
45
|
+
params: { playerId: player_id, fileId: file_id })
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Play a directory.
|
|
49
|
+
def play_directory(directory_id:, player_id: nil, shuffle: nil,
|
|
50
|
+
recurse: nil, position: nil)
|
|
51
|
+
procedure("app.rocksky.player.playDirectory",
|
|
52
|
+
params: {
|
|
53
|
+
playerId: player_id,
|
|
54
|
+
directoryId: directory_id,
|
|
55
|
+
shuffle: shuffle,
|
|
56
|
+
recurse: recurse,
|
|
57
|
+
position: position
|
|
58
|
+
})
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Append items to the queue. `items` is an Array of file identifiers.
|
|
62
|
+
def add_items_to_queue(items:, player_id: nil, position: nil, shuffle: nil)
|
|
63
|
+
procedure("app.rocksky.player.addItemsToQueue",
|
|
64
|
+
params: {
|
|
65
|
+
playerId: player_id,
|
|
66
|
+
items: items,
|
|
67
|
+
position: position,
|
|
68
|
+
shuffle: shuffle
|
|
69
|
+
})
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.playlist.*` endpoints.
|
|
4
|
+
class Playlist < Base
|
|
5
|
+
# Fetch a playlist.
|
|
6
|
+
def get_playlist(uri:)
|
|
7
|
+
query("app.rocksky.playlist.getPlaylist", uri: uri)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# List playlists.
|
|
11
|
+
def get_playlists(limit: nil, offset: nil)
|
|
12
|
+
query("app.rocksky.playlist.getPlaylists", limit: limit, offset: offset)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Create a playlist.
|
|
16
|
+
def create_playlist(name:, description: nil)
|
|
17
|
+
procedure("app.rocksky.playlist.createPlaylist",
|
|
18
|
+
params: { name: name, description: description })
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Remove a playlist.
|
|
22
|
+
def remove_playlist(uri:)
|
|
23
|
+
procedure("app.rocksky.playlist.removePlaylist", params: { uri: uri })
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Start a playlist.
|
|
27
|
+
def start_playlist(uri:, shuffle: nil, position: nil)
|
|
28
|
+
procedure("app.rocksky.playlist.startPlaylist",
|
|
29
|
+
params: { uri: uri, shuffle: shuffle, position: position })
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Insert files into a playlist.
|
|
33
|
+
def insert_files(uri:, files:, position: nil)
|
|
34
|
+
procedure("app.rocksky.playlist.insertFiles",
|
|
35
|
+
params: { uri: uri, files: files, position: position })
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Insert a directory into a playlist.
|
|
39
|
+
def insert_directory(uri:, directory:, position: nil)
|
|
40
|
+
procedure("app.rocksky.playlist.insertDirectory",
|
|
41
|
+
params: { uri: uri, directory: directory, position: position })
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.scrobble.*` endpoints.
|
|
4
|
+
class Scrobble < Base
|
|
5
|
+
# Create a new scrobble. Requires an authenticated client.
|
|
6
|
+
#
|
|
7
|
+
# Required: `title`, `artist`. Everything else is optional metadata that
|
|
8
|
+
# gets forwarded as-is to the lexicon's createScrobble body. Extra fields
|
|
9
|
+
# may be passed via `**extra`.
|
|
10
|
+
#
|
|
11
|
+
# Example:
|
|
12
|
+
#
|
|
13
|
+
# client.scrobble.create_scrobble(
|
|
14
|
+
# title: "In Bloom",
|
|
15
|
+
# artist: "Nirvana",
|
|
16
|
+
# album: "Nevermind",
|
|
17
|
+
# timestamp: Time.now.to_i
|
|
18
|
+
# )
|
|
19
|
+
def create_scrobble(title:, artist:, **extra)
|
|
20
|
+
body = { title: title, artist: artist }.merge(extra).compact
|
|
21
|
+
procedure("app.rocksky.scrobble.createScrobble", body: body)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Fetch a scrobble by URI.
|
|
25
|
+
def get_scrobble(uri:)
|
|
26
|
+
query("app.rocksky.scrobble.getScrobble", uri: uri)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# List scrobbles.
|
|
30
|
+
def get_scrobbles(did: nil, following: nil, limit: nil, offset: nil)
|
|
31
|
+
query("app.rocksky.scrobble.getScrobbles",
|
|
32
|
+
did: did, following: following, limit: limit, offset: offset)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.shout.*` endpoints.
|
|
4
|
+
class Shout < Base
|
|
5
|
+
# Create a shout.
|
|
6
|
+
def create_shout(message:, **extra)
|
|
7
|
+
body = { message: message }.merge(extra).compact
|
|
8
|
+
procedure("app.rocksky.shout.createShout", body: body)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Reply to a shout.
|
|
12
|
+
def reply_shout(shout_id:, message:)
|
|
13
|
+
procedure("app.rocksky.shout.replyShout",
|
|
14
|
+
body: { shoutId: shout_id, message: message })
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Remove a shout.
|
|
18
|
+
def remove_shout(id:)
|
|
19
|
+
procedure("app.rocksky.shout.removeShout", params: { id: id })
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Report a shout.
|
|
23
|
+
def report_shout(shout_id:, reason:)
|
|
24
|
+
procedure("app.rocksky.shout.reportShout",
|
|
25
|
+
body: { shoutId: shout_id, reason: reason })
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Shouts on a profile.
|
|
29
|
+
def get_profile_shouts(did:, limit: nil, offset: nil)
|
|
30
|
+
query("app.rocksky.shout.getProfileShouts",
|
|
31
|
+
did: did, limit: limit, offset: offset)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Shouts on an album.
|
|
35
|
+
def get_album_shouts(uri:, limit: nil, offset: nil)
|
|
36
|
+
query("app.rocksky.shout.getAlbumShouts",
|
|
37
|
+
uri: uri, limit: limit, offset: offset)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Shouts on an artist.
|
|
41
|
+
def get_artist_shouts(uri:, limit: nil, offset: nil)
|
|
42
|
+
query("app.rocksky.shout.getArtistShouts",
|
|
43
|
+
uri: uri, limit: limit, offset: offset)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Shouts on a track.
|
|
47
|
+
def get_track_shouts(uri:)
|
|
48
|
+
query("app.rocksky.shout.getTrackShouts", uri: uri)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Replies to a shout.
|
|
52
|
+
def get_shout_replies(uri:, limit: nil, offset: nil)
|
|
53
|
+
query("app.rocksky.shout.getShoutReplies",
|
|
54
|
+
uri: uri, limit: limit, offset: offset)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.song.*` endpoints.
|
|
4
|
+
class Song < Base
|
|
5
|
+
# Fetch a song by URI, MusicBrainz id, ISRC, or Spotify id.
|
|
6
|
+
def get_song(uri: nil, mbid: nil, isrc: nil, spotify_id: nil)
|
|
7
|
+
query("app.rocksky.song.getSong",
|
|
8
|
+
uri: uri, mbid: mbid, isrc: isrc, spotifyId: spotify_id)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# List songs.
|
|
12
|
+
def get_songs(limit: nil, offset: nil, genre: nil,
|
|
13
|
+
mbid: nil, isrc: nil, spotify_id: nil)
|
|
14
|
+
query("app.rocksky.song.getSongs",
|
|
15
|
+
limit: limit, offset: offset, genre: genre,
|
|
16
|
+
mbid: mbid, isrc: isrc, spotifyId: spotify_id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Recent listeners for a song.
|
|
20
|
+
def get_song_recent_listeners(uri:, limit: nil, offset: nil)
|
|
21
|
+
query("app.rocksky.song.getSongRecentListeners",
|
|
22
|
+
uri: uri, limit: limit, offset: offset)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Find an existing song by metadata.
|
|
26
|
+
def match_song(title:, artist:, mb_id: nil, isrc: nil)
|
|
27
|
+
query("app.rocksky.song.matchSong",
|
|
28
|
+
title: title, artist: artist, mbId: mb_id, isrc: isrc)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Create a song.
|
|
32
|
+
def create_song(title:, artist:, **extra)
|
|
33
|
+
body = { title: title, artist: artist }.merge(extra).compact
|
|
34
|
+
procedure("app.rocksky.song.createSong", body: body)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.spotify.*` endpoints — Spotify remote control for the
|
|
4
|
+
# authenticated user.
|
|
5
|
+
class Spotify < Base
|
|
6
|
+
# Currently playing on Spotify.
|
|
7
|
+
def get_currently_playing(actor: nil)
|
|
8
|
+
query("app.rocksky.spotify.getCurrentlyPlaying", actor: actor)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Resume Spotify playback.
|
|
12
|
+
def play
|
|
13
|
+
procedure("app.rocksky.spotify.play")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Pause Spotify playback.
|
|
17
|
+
def pause
|
|
18
|
+
procedure("app.rocksky.spotify.pause")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Skip to next track.
|
|
22
|
+
def next
|
|
23
|
+
procedure("app.rocksky.spotify.next")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Go to previous track.
|
|
27
|
+
def previous
|
|
28
|
+
procedure("app.rocksky.spotify.previous")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Seek to position in milliseconds.
|
|
32
|
+
def seek(position:)
|
|
33
|
+
procedure("app.rocksky.spotify.seek", params: { position: position })
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Rocksky
|
|
2
|
+
module Resources
|
|
3
|
+
# `app.rocksky.stats.*` endpoints.
|
|
4
|
+
class Stats < Base
|
|
5
|
+
# Per-user stats.
|
|
6
|
+
def get_stats(did:)
|
|
7
|
+
query("app.rocksky.stats.getStats", did: did)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Year-in-review ("Wrapped") data.
|
|
11
|
+
def get_wrapped(did:, year: nil)
|
|
12
|
+
query("app.rocksky.stats.getWrapped", did: did, year: year)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/rocksky.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require "rocksky/version"
|
|
2
|
+
require "rocksky/error"
|
|
3
|
+
require "rocksky/http"
|
|
4
|
+
require "rocksky/resources/base"
|
|
5
|
+
require "rocksky/resources/actor"
|
|
6
|
+
require "rocksky/resources/album"
|
|
7
|
+
require "rocksky/resources/apikey"
|
|
8
|
+
require "rocksky/resources/artist"
|
|
9
|
+
require "rocksky/resources/charts"
|
|
10
|
+
require "rocksky/resources/feed"
|
|
11
|
+
require "rocksky/resources/graph"
|
|
12
|
+
require "rocksky/resources/like"
|
|
13
|
+
require "rocksky/resources/mirror"
|
|
14
|
+
require "rocksky/resources/player"
|
|
15
|
+
require "rocksky/resources/playlist"
|
|
16
|
+
require "rocksky/resources/scrobble"
|
|
17
|
+
require "rocksky/resources/shout"
|
|
18
|
+
require "rocksky/resources/song"
|
|
19
|
+
require "rocksky/resources/spotify"
|
|
20
|
+
require "rocksky/resources/stats"
|
|
21
|
+
require "rocksky/client"
|
|
22
|
+
|
|
23
|
+
module Rocksky
|
|
24
|
+
# Build a new Rocksky client.
|
|
25
|
+
#
|
|
26
|
+
# client = Rocksky.new(token: ENV["ROCKSKY_TOKEN"])
|
|
27
|
+
#
|
|
28
|
+
# See {Rocksky::Client#initialize} for all options.
|
|
29
|
+
def self.new(**opts)
|
|
30
|
+
Client.new(**opts)
|
|
31
|
+
end
|
|
32
|
+
end
|
data/rocksky.gemspec
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require_relative "lib/rocksky/version"
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |spec|
|
|
4
|
+
spec.name = "rocksky"
|
|
5
|
+
spec.version = Rocksky::VERSION
|
|
6
|
+
spec.authors = ["Rocksky"]
|
|
7
|
+
spec.email = ["hi@rocksky.app"]
|
|
8
|
+
|
|
9
|
+
spec.summary = "Ruby client for the Rocksky XRPC API."
|
|
10
|
+
spec.description = "Idiomatic Ruby SDK for Rocksky (rocksky.app) — scrobbles, " \
|
|
11
|
+
"shouts, charts, playlists, and more."
|
|
12
|
+
spec.homepage = "https://github.com/tsirysndr/rocksky"
|
|
13
|
+
spec.license = "MIT"
|
|
14
|
+
|
|
15
|
+
spec.required_ruby_version = ">= 3.0.0"
|
|
16
|
+
|
|
17
|
+
spec.metadata = {
|
|
18
|
+
"homepage_uri" => spec.homepage,
|
|
19
|
+
"source_code_uri" => "https://github.com/tsirysndr/rocksky/tree/main/sdk/ruby",
|
|
20
|
+
"bug_tracker_uri" => "https://github.com/tsirysndr/rocksky/issues",
|
|
21
|
+
"documentation_uri" => "https://docs.rocksky.app",
|
|
22
|
+
"rubygems_mfa_required" => "true"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
spec.files = Dir[
|
|
26
|
+
"lib/**/*.rb",
|
|
27
|
+
"exe/*",
|
|
28
|
+
"*.gemspec",
|
|
29
|
+
"LICENSE",
|
|
30
|
+
"README.md",
|
|
31
|
+
"CHANGELOG.md"
|
|
32
|
+
]
|
|
33
|
+
spec.require_paths = ["lib"]
|
|
34
|
+
spec.bindir = "exe"
|
|
35
|
+
spec.executables = Dir["exe/*"].map { |f| File.basename(f) }
|
|
36
|
+
|
|
37
|
+
spec.add_development_dependency "irb", "~> 1.11"
|
|
38
|
+
spec.add_development_dependency "minitest", "~> 5.20"
|
|
39
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
40
|
+
spec.add_development_dependency "webmock", "~> 3.19"
|
|
41
|
+
end
|