mockspotify 0.0.1

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,168 @@
1
+ /*
2
+ * API for libmockspotify
3
+ *
4
+ */
5
+
6
+
7
+ #ifndef LIBMOCKSPOTIFY_API_H
8
+ #define LIBMOCKSPOTIFY_API_H
9
+
10
+ #include <stdlib.h>
11
+ #include <string.h>
12
+ #include <stdio.h>
13
+ #include <libspotify/api.h>
14
+ #include "util.h"
15
+
16
+ /*** Mock structures ***/
17
+
18
+ struct sp_session {
19
+ char username[1024];
20
+ sp_session_config config;
21
+ void *userdata;
22
+ sp_connectionstate connectionstate;
23
+ };
24
+
25
+ struct sp_album {
26
+ char name[1024];
27
+ sp_artist *artist;
28
+ int year;
29
+ byte cover[20];
30
+ int type;
31
+ int loaded;
32
+ bool available;
33
+ };
34
+
35
+ struct sp_albumbrowse {
36
+ sp_album *album;
37
+ int loaded;
38
+ };
39
+
40
+ struct sp_artist {
41
+ char name[1024];
42
+ int loaded;
43
+ };
44
+
45
+ struct sp_artistbrowse {
46
+ sp_artist *artist;
47
+ int loaded;
48
+ };
49
+
50
+ struct sp_image {
51
+ byte image_id[20];
52
+ sp_imageformat format;
53
+ size_t data_size;
54
+ byte *data;
55
+ sp_error error;
56
+ };
57
+
58
+ struct sp_playlist {
59
+ char name[1024];
60
+ sp_track *track[32];
61
+ int num_tracks;
62
+ sp_playlist_callbacks *callbacks;
63
+ void *userdata;
64
+ };
65
+
66
+ struct sp_search {
67
+ int loaded;
68
+ int total_tracks;
69
+ int num_tracks;
70
+ int num_artists;
71
+ int num_albums;
72
+ sp_track *track[20];
73
+ sp_album *album[20];
74
+ sp_artist *artist[20];
75
+ char *query;
76
+ char *did_you_mean;
77
+ int error;
78
+ };
79
+
80
+ struct sp_track {
81
+ char name[1024];
82
+ int num_artists;
83
+ sp_artist *artists[16];
84
+ sp_album *album;
85
+ int duration;
86
+ int popularity;
87
+ int disc;
88
+ int index;
89
+ sp_error error;
90
+ int loaded;
91
+ int starred;
92
+ };
93
+
94
+ struct sp_user {
95
+ bool loaded;
96
+ char *canonical_name;
97
+ char *display_name;
98
+ char *full_name;
99
+ char *picture;
100
+ sp_relation_type relation;
101
+ };
102
+
103
+ struct sp_link {
104
+ char data[1024];
105
+ };
106
+
107
+ /*** Mock events ***/
108
+
109
+ typedef enum event_type {
110
+ // SESSION EVENTS
111
+ MOCK_LOGGED_IN = 0,
112
+ MOCK_LOGGED_OUT = 1,
113
+ MOCK_METADATA_UPDATED = 2,
114
+ MOCK_CONNECTION_ERROR = 3,
115
+
116
+ // PLAYLIST EVENTS
117
+ MOCK_PLAYLIST_TRACKS_ADDED = 20,
118
+ MOCK_PLAYLIST_TRACKS_MOVED = 21,
119
+ MOCK_PLAYLIST_TRACKS_REMOVED = 22,
120
+ MOCK_PLAYLIST_RENAMED = 23,
121
+ MOCK_PLAYLIST_STATE_CHANGED = 24,
122
+ MOCK_PLAYLIST_UPDATE_IN_PROGRESS = 25,
123
+ MOCK_PLAYLIST_METADATA_UPDATED = 26,
124
+ MOCK_PLAYLIST_TRACK_CREATED_CHANGED = 27,
125
+ MOCK_PLAYLIST_TRACK_MESSAGE_CHANGED = 28,
126
+ MOCK_PLAYLIST_TRACK_SEEN_CHANGED = 29,
127
+ MOCK_PLAYLIST_DESCRIPTION_CHANGED = 30,
128
+ MOCK_PLAYLIST_SUBSCRIBERS_CHANGED = 31,
129
+ MOCK_PLAYLIST_IMAGE_CHANGED = 32,
130
+
131
+ // CONTAINER EVENTS
132
+ MOCK_CONTAINER_LOADED = 40,
133
+ MOCK_CONTAINER_PLAYLIST_ADDED = 41,
134
+ MOCK_CONTAINER_PLAYLIST_MOVED = 42,
135
+ MOCK_CONTAINER_PLAYLIST_REMOVED = 43
136
+ } event_type;
137
+
138
+ void
139
+ mocksp_playlist_event(event_type event, sp_playlist *p);
140
+
141
+ /*** Mock object creation ***/
142
+
143
+ sp_album *
144
+ mocksp_album_create(char *name, sp_artist *artist, int year, byte *cover,
145
+ int type, int loaded, int available);
146
+
147
+ sp_albumbrowse *
148
+ mocksp_albumbrowse_create(sp_album *album, bool loaded);
149
+
150
+ sp_artist *
151
+ mocksp_artist_create(const char *name, int loaded);
152
+
153
+ sp_artistbrowse *
154
+ mocksp_artistbrowse_create(sp_artist *artist, bool loaded);
155
+
156
+ sp_playlist *
157
+ mocksp_playlist_create(char *name);
158
+
159
+ sp_track *
160
+ mocksp_track_create(char *name, int num_artists, sp_artist ** artists,
161
+ sp_album * album, int duration, int popularity,
162
+ int disc, int index, sp_error error, int loaded);
163
+
164
+ sp_user *
165
+ mocksp_user_create(char *canonical_name, char *display_name, char *full_name,
166
+ char *picture, sp_relation_type relation, bool loaded);
167
+
168
+ #endif /* LIBMOCKSPOTIFY_API_H */
data/src/link.c ADDED
@@ -0,0 +1,77 @@
1
+ #include <string.h>
2
+ #include "libmockspotify.h"
3
+
4
+ /*** Spotify API ***/
5
+ void
6
+ sp_link_add_ref(sp_link * link)
7
+ {
8
+ }
9
+
10
+ void
11
+ sp_link_release(sp_link * link)
12
+ {
13
+ }
14
+
15
+ sp_link *
16
+ sp_link_create_from_string(const char *link)
17
+ {
18
+ /* unless the link starts with spotify: it is invalid */
19
+ if ( ! STARTS_WITH(link, "spotify:"))
20
+ {
21
+ return NULL;
22
+ }
23
+
24
+ sp_link *lnk = ALLOC(sp_link);
25
+ snprintf(lnk->data, 1024 /* max size of data in sp_link */, "%s", link);
26
+ return lnk;
27
+ }
28
+
29
+ sp_link *
30
+ sp_link_create_from_user(sp_user *user)
31
+ {
32
+ char *link = ALLOC_N(char, 1024);
33
+ snprintf(link, "spotify:user:%s", user->canonical_name);
34
+ return sp_link_create_from_string(link);
35
+ }
36
+
37
+ int
38
+ sp_link_as_string(sp_link *link, char *buffer, int buffer_size)
39
+ {
40
+ strncpy(buffer, link->data, buffer_size);
41
+
42
+ if (buffer_size > 0)
43
+ {
44
+ buffer[buffer_size - 1] = '\0';
45
+ }
46
+
47
+ return (int) strlen(link->data);
48
+ }
49
+
50
+ sp_linktype
51
+ sp_link_type(sp_link *link)
52
+ {
53
+ #define LINK_IS(type) (strstr(link->data, ":" #type))
54
+ #define LINK_CASE_FOR(string, type) if (LINK_IS(string)) { return SP_LINKTYPE_##type; }
55
+
56
+ LINK_CASE_FOR(search, SEARCH);
57
+ LINK_CASE_FOR(track, TRACK);
58
+ LINK_CASE_FOR(album, ALBUM);
59
+ LINK_CASE_FOR(artist, ARTIST);
60
+ LINK_CASE_FOR(image, IMAGE);
61
+
62
+ // Order of these three is significant
63
+ LINK_CASE_FOR(playlist, PLAYLIST);
64
+ LINK_CASE_FOR(starred, STARRED);
65
+ LINK_CASE_FOR(user, PROFILE);
66
+
67
+ return SP_LINKTYPE_INVALID;
68
+ }
69
+
70
+ sp_user *
71
+ sp_link_as_user(sp_link *link)
72
+ {
73
+ char *username = ALLOC_N(char, 1024);
74
+ strncpy(username, link->data, 1024);
75
+ sp_user *user = mocksp_user_create(username, NULL, NULL, NULL, SP_RELATION_TYPE_UNKNOWN, 1);
76
+ return user;
77
+ }
data/src/playlist.c ADDED
@@ -0,0 +1,165 @@
1
+ #include <stdlib.h>
2
+ #include <string.h>
3
+ #include "libmockspotify.h"
4
+
5
+ /*** MockSpotify API ***/
6
+
7
+ void
8
+ mocksp_playlist_event(event_type event, sp_playlist *p)
9
+ {
10
+ sp_artist *artist = mocksp_artist_create("foo_", 1);
11
+ sp_album *album = mocksp_album_create("bar_", artist, 2011,
12
+ (byte *) "01234567890123456789", 0, 1, 1);
13
+ sp_user *user = mocksp_user_create("foo", "", "", "", 0, 0);
14
+ sp_track *tracks[3] = {
15
+ mocksp_track_create("foo", 1, &artist, album, 0, 0, 0, 0, 0, 1),
16
+ mocksp_track_create("bar", 1, &artist, album, 0, 0, 0, 0, 0, 1),
17
+ mocksp_track_create("baz", 1, &artist, album, 0, 0, 0, 0, 0, 1)
18
+ };
19
+ int nums[3] = { 0, 1, 2 };
20
+
21
+ switch (event) {
22
+ case MOCK_PLAYLIST_TRACKS_ADDED:
23
+ if (p->callbacks->tracks_added)
24
+ p->callbacks->tracks_added(p, tracks, 3, 0, p->userdata);
25
+ break;
26
+ case MOCK_PLAYLIST_TRACKS_MOVED:
27
+ if (p->callbacks->tracks_moved)
28
+ p->callbacks->tracks_moved(p, nums, 3, 0, p->userdata);
29
+ break;
30
+ case MOCK_PLAYLIST_TRACKS_REMOVED:
31
+ if (p->callbacks->tracks_removed)
32
+ p->callbacks->tracks_removed(p, nums, 3, p->userdata);
33
+ break;
34
+
35
+ case MOCK_PLAYLIST_RENAMED:
36
+ if (p->callbacks->playlist_renamed)
37
+ p->callbacks->playlist_renamed(p, p->userdata);
38
+ break;
39
+
40
+ case MOCK_PLAYLIST_STATE_CHANGED:
41
+ if (p->callbacks->playlist_state_changed)
42
+ p->callbacks->playlist_state_changed(p, p->userdata);
43
+ break;
44
+
45
+ case MOCK_PLAYLIST_UPDATE_IN_PROGRESS:
46
+ if (p->callbacks->playlist_update_in_progress)
47
+ p->callbacks->playlist_update_in_progress(p, 1, p->userdata);
48
+ break;
49
+
50
+ case MOCK_PLAYLIST_METADATA_UPDATED:
51
+ if (p->callbacks->playlist_metadata_updated)
52
+ p->callbacks->playlist_metadata_updated(p, p->userdata);
53
+ break;
54
+
55
+ case MOCK_PLAYLIST_TRACK_CREATED_CHANGED:
56
+ if (p->callbacks->track_created_changed)
57
+ p->callbacks->track_created_changed(p, 1, user, 123, p->userdata);
58
+ break;
59
+
60
+ case MOCK_PLAYLIST_TRACK_MESSAGE_CHANGED:
61
+ if (p->callbacks->track_message_changed)
62
+ p->callbacks->track_message_changed(p, 1, "foo", p->userdata);
63
+ break;
64
+
65
+ case MOCK_PLAYLIST_TRACK_SEEN_CHANGED:
66
+ if (p->callbacks->track_seen_changed)
67
+ p->callbacks->track_seen_changed(p, 1, 0, p->userdata);
68
+ break;
69
+
70
+ case MOCK_PLAYLIST_DESCRIPTION_CHANGED:
71
+ if (p->callbacks->description_changed)
72
+ p->callbacks->description_changed(p, "foo", p->userdata);
73
+ break;
74
+
75
+ case MOCK_PLAYLIST_SUBSCRIBERS_CHANGED:
76
+ if (p->callbacks->subscribers_changed)
77
+ p->callbacks->subscribers_changed(p, p->userdata);
78
+ break;
79
+
80
+ case MOCK_PLAYLIST_IMAGE_CHANGED:
81
+ if (p->callbacks->image_changed)
82
+ p->callbacks->image_changed(p, (byte *) "01234567890123456789",
83
+ p->userdata);
84
+ break;
85
+
86
+ default:
87
+ break;
88
+ }
89
+ }
90
+
91
+ /*** Spotify API ***/
92
+
93
+ void
94
+ sp_playlist_add_ref(sp_playlist *p)
95
+ {
96
+ }
97
+
98
+ void
99
+ sp_playlist_release(sp_playlist *p)
100
+ {
101
+ }
102
+
103
+ void
104
+ sp_playlist_set_autolink_tracks(sp_playlist *p, bool set)
105
+ {
106
+ }
107
+
108
+ bool
109
+ sp_playlist_is_loaded(sp_playlist *p)
110
+ {
111
+ return 1;
112
+ }
113
+
114
+ const char *
115
+ sp_playlist_name(sp_playlist *p)
116
+ {
117
+ return p->name;
118
+ }
119
+
120
+ sp_error
121
+ sp_playlist_rename(sp_playlist *p, const char *new_name)
122
+ {
123
+ strcpy(p->name, new_name);
124
+ return SP_ERROR_OK;
125
+ }
126
+
127
+ sp_track *
128
+ sp_playlist_track(sp_playlist *p, int index)
129
+ {
130
+ return p->track[index];
131
+ }
132
+
133
+ int
134
+ sp_playlist_num_tracks(sp_playlist *p)
135
+ {
136
+ return p->num_tracks;
137
+ }
138
+
139
+ void
140
+ sp_playlist_add_callbacks(sp_playlist *p, sp_playlist_callbacks *cb,
141
+ void *userdata)
142
+ {
143
+ p->callbacks = cb;
144
+ p->userdata = userdata;
145
+ }
146
+
147
+ void
148
+ sp_playlist_remove_callbacks(sp_playlist *p, sp_playlist_callbacks *cb,
149
+ void *userdata)
150
+ {
151
+ p->callbacks = NULL;
152
+ }
153
+
154
+ bool
155
+ sp_playlist_is_collaborative(sp_playlist *p)
156
+ {
157
+ return 0;
158
+ }
159
+
160
+ sp_error
161
+ sp_playlist_remove_tracks(sp_playlist *p, const int *tracks, int num_tracks)
162
+ {
163
+ // TODO
164
+ return SP_ERROR_OK;
165
+ }
data/src/search.c ADDED
@@ -0,0 +1,128 @@
1
+ #include <stdlib.h>
2
+ #include <string.h>
3
+ #include "libmockspotify.h"
4
+
5
+ /*** Spotify API ***/
6
+
7
+ void
8
+ sp_search_add_ref(sp_search *search)
9
+ {
10
+ }
11
+
12
+ void
13
+ sp_search_release(sp_search *search)
14
+ {
15
+ }
16
+
17
+ sp_search *
18
+ sp_search_create(sp_session *session, const char *query, int track_offset,
19
+ int track_count, int album_offset, int album_count,
20
+ int artist_offset, int artist_count,
21
+ search_complete_cb *callback, void *userdata)
22
+ {
23
+ sp_search *search = malloc(sizeof(sp_search));
24
+
25
+ if (!strncmp(query, "!loaded", 7))
26
+ search->loaded = 0;
27
+ if (!strncmp(query, "loaded", 6))
28
+ search->loaded = 1;
29
+ search->num_tracks = 4;
30
+ search->num_albums = 3;
31
+ search->num_artists = 2;
32
+ search->total_tracks = 24;
33
+ search->query = malloc(strlen(query) + 1);
34
+ strcpy(search->query, query);
35
+ search->error = 3;
36
+ search->did_you_mean = "did_you_mean";
37
+ search->artist[0] = mocksp_artist_create("foo", 1);
38
+ search->artist[1] = mocksp_artist_create("bar", 1);
39
+ search->album[0] = mocksp_album_create("baz", search->artist[0], 2001,
40
+ (byte *) "01234567890123456789",
41
+ 1, 1, 1);
42
+ search->album[1] = mocksp_album_create("qux", search->artist[1], 2002,
43
+ (byte *) "01234567890123456789",
44
+ 1, 1, 1);
45
+ search->album[2] = mocksp_album_create("quux", search->artist[0], 2003,
46
+ (byte *) "01234567890123456789",
47
+ 1, 1, 1);
48
+ search->track[0] =
49
+ mocksp_track_create("corge", 1, search->artist, search->album[0],
50
+ 99, 72, 1, 1, 0, 1);
51
+ search->track[1] =
52
+ mocksp_track_create("grault", 1, search->artist, search->album[1],
53
+ 98, 72, 1, 1, 0, 1);
54
+ search->track[2] =
55
+ mocksp_track_create("garply", 1, search->artist, search->album[2],
56
+ 97, 72, 1, 1, 0, 1);
57
+ search->track[3] =
58
+ mocksp_track_create("waldo", 1, search->artist, search->album[0],
59
+ 96, 72, 1, 1, 0, 1);
60
+ callback(search, userdata);
61
+ return search;
62
+ }
63
+
64
+ bool
65
+ sp_search_is_loaded(sp_search *s)
66
+ {
67
+ return s->loaded;
68
+ }
69
+
70
+ int
71
+ sp_search_num_artists(sp_search *s)
72
+ {
73
+ return s->num_artists;
74
+ }
75
+
76
+ int
77
+ sp_search_num_albums(sp_search *s)
78
+ {
79
+ return s->num_albums;
80
+ }
81
+
82
+ int
83
+ sp_search_num_tracks(sp_search *s)
84
+ {
85
+ return s->num_tracks;
86
+ }
87
+
88
+ int
89
+ sp_search_total_tracks(sp_search *s)
90
+ {
91
+ return s->total_tracks;
92
+ }
93
+
94
+ sp_artist *
95
+ sp_search_artist(sp_search *s, int i)
96
+ {
97
+ return s->artist[i];
98
+ }
99
+
100
+ sp_album *
101
+ sp_search_album(sp_search *s, int i)
102
+ {
103
+ return s->album[i];
104
+ }
105
+
106
+ sp_track *
107
+ sp_search_track(sp_search *s, int i)
108
+ {
109
+ return s->track[i];
110
+ }
111
+
112
+ const char *
113
+ sp_search_query(sp_search *s)
114
+ {
115
+ return s->query;
116
+ }
117
+
118
+ sp_error
119
+ sp_search_error(sp_search *s)
120
+ {
121
+ return s->error;
122
+ }
123
+
124
+ const char *
125
+ sp_search_did_you_mean(sp_search *s)
126
+ {
127
+ return s->did_you_mean;
128
+ }
data/src/session.c ADDED
@@ -0,0 +1,73 @@
1
+ #include "libmockspotify.h"
2
+
3
+ /*** Spotify API ***/
4
+
5
+ sp_error
6
+ sp_session_create(const sp_session_config * config, sp_session ** sess)
7
+ {
8
+ if (memcmp(config->application_key, "appkey_good", config->application_key_size))
9
+ return SP_ERROR_BAD_APPLICATION_KEY;
10
+
11
+ *sess = ALLOC(sp_session);
12
+ sp_session *session = *sess;
13
+
14
+ session->config.cache_location = malloc(strlen(config->cache_location) + 1);
15
+ session->config.settings_location = malloc(strlen(config->settings_location) + 1);
16
+ session->config.application_key = malloc(config->application_key_size);
17
+ session->config.user_agent = malloc(strlen(config->user_agent) + 1);
18
+ session->config.callbacks = ALLOC(sp_session_callbacks);
19
+ session->config.userdata = config->userdata;
20
+
21
+ session->config.api_version = config->api_version;
22
+ strcpy((char *)session->config.cache_location, config->cache_location);
23
+ strcpy((char *)session->config.settings_location, config->settings_location);
24
+ memcpy((char *)session->config.application_key, config->application_key, config->application_key_size);
25
+ strcpy((char *)session->config.user_agent, config->user_agent);
26
+ memcpy((char *)session->config.callbacks, config->callbacks, sizeof(sp_session_callbacks));
27
+ session->config.userdata = config->userdata;
28
+
29
+ // TODO: v0.0.8 (and earlier) directly call `notify_main_thread` callback here, before returning
30
+ if (config->callbacks->notify_main_thread)
31
+ config->callbacks->notify_main_thread(NULL);
32
+
33
+ return SP_ERROR_OK;
34
+ }
35
+
36
+ void
37
+ sp_session_process_events(sp_session *session, int *next_timeout)
38
+ {
39
+ *next_timeout = 60000;
40
+ }
41
+
42
+ sp_connectionstate
43
+ sp_session_connectionstate(sp_session *session)
44
+ {
45
+ return session->connectionstate;
46
+ }
47
+
48
+ void *
49
+ sp_session_userdata(sp_session *session)
50
+ {
51
+ return session->config.userdata;
52
+ }
53
+
54
+ void
55
+ sp_session_login(sp_session *session, const char *username, const char *password)
56
+ {
57
+ session->connectionstate = SP_CONNECTION_STATE_LOGGED_IN;
58
+ }
59
+
60
+ void
61
+ sp_session_logout(sp_session *session)
62
+ {
63
+ session->connectionstate = SP_CONNECTION_STATE_LOGGED_OUT;
64
+ }
65
+
66
+ sp_user *
67
+ sp_session_user(sp_session *session)
68
+ {
69
+ char *username = ALLOC_N(char, 1024);
70
+ strncpy(username, session->username, 1024);
71
+ sp_user *user = mocksp_user_create(username, NULL, NULL, NULL, SP_RELATION_TYPE_NONE, 1);
72
+ return user;
73
+ }