mockspotify 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }