-
Notifications
You must be signed in to change notification settings - Fork 1
/
music_skeleton.js
155 lines (138 loc) · 5.07 KB
/
music_skeleton.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
var SpotifyWebApi = require('spotify-web-api-node'),
serverConfig = require('./serverConfig.json'),
schemas = require('./schemas'),
mongoose = require('mongoose');
// credentials are optional
exports.recommendAndUpdate = function(accessToken, userId, eventId,
dancing=false, energetic=false, positive=false, instrumental=false) {
var spotifyApi = new SpotifyWebApi(serverConfig.oauth);
spotifyApi.setAccessToken(accessToken);
recommendAndUpdate(userId, eventId, spotifyApi,
dancing, energetic, positive, instrumental);
}
exports.createPlaylist = function(accessToken, userId, eventName, sluggedName){
var spotifyApi = new SpotifyWebApi(serverConfig.oauth);
spotifyApi.setAccessToken(accessToken);
spotifyApi.createPlaylist(userId, eventName + ' Crowdify', { 'public' : true })
.then(function(data) {
schemas.Event.update({"name": sluggedName}, {$set : {"playlistId": data.body.id}},
function (err) {
if (err) throw err;
});
console.log('Created playlist!');
}, function(err) {
console.log('Something went wrong in creating a playlist!', err);
});
}
// Given 5 seed track Ids, user and playlist Id,
// generate recommendations based on (max 5) seed tracks, then
// regenerate the playlist with these songs in it
function recommendAndUpdate (userId, eventId, spotifyApi,
dancing, energetic, positive, instrumental){
schemas.Event.findOne({name: eventId}, function(err, event){
seed_tracks = [].concat.apply([], event.songNames);
console.log(seed_tracks);
var seeds = generateSeeds(seed_tracks);
updatePlaylist(userId, event.playlistId, [], spotifyApi);
// console.log("seeds= ", seeds);
var start=0;
for (var i=0; i<seeds.length/5; ++i) {
getRecommendations(seeds.slice(start, start+5), spotifyApi,
dancing, energetic, positive, instrumental)
.then(function(recom) {
var songUris = recom.body.tracks.map(function(a) {return a.uri});
console.log(songUris);
addToPlaylist(userId, event.playlistId, songUris, spotifyApi);
},
function(err) {
console.log('Something went wrong in getting recommendations', err);
});
start += 5;
}
});
}
// Given up to 5 seed track Ids, returns a promise of an object containing some
// recommended songs
function getRecommendations(seed_tracks, spotifyApi,
dancing, energetic, positive, instrumental) {
var argument = {min_energy: 0.4,
seed_tracks: seed_tracks,
min_danceability: 0.0,
min_valence: 0.0,
min_instrumentalness: 0.0,
min_popularity: 50}
if (dancing) {
argument.min_danceability = 0.8
}
if (energetic) {
argument.min_energy = 0.85
}
if (positive) {
argument.min_valence = 0.9
}
if (instrumental) {
argument.min_instrumentalness = 0.9
}
var recommendations = spotifyApi.getRecommendations(argument);
return recommendations;
}
// Given a userId (i.e. username), playlistID, array of songURIs,
// adds songs onto the specified playlist
function addToPlaylist(userId, playlistId, songUris, spotifyApi){
spotifyApi.addTracksToPlaylist(userId, playlistId, songUris).
then(function(data) {console.log("Added songs to playlist!");},
function(err) {console.log("something went wrong in the playlist update", err);})
}
function updatePlaylist(userId, playlistId, songUris, spotifyApi){
spotifyApi.replaceTracksInPlaylist(userId, playlistId, songUris).
then(function(data) {console.log("Playlist updated!");},
function(err) {console.log("something went wrong in the playlist update", err);})
}
function getFromDb(fn0){
var Song = schemas.Songs;
// console.log("e");
function setSL(list) {
userSongsList = list;
}
function foo(fn) {
Song.find({}, function(err, songs) {
if (err) throw err;
// console.log(songs[0].songNames);
userSongsList = songs.map(function(item) {return item.songNames});
fn(userSongsList[0]);
});
}
foo(function(userSongsList) {
mongoose.connection.close();
fn0(userSongsList);
});
}
// getFromDb(function(myvar) {
// var seeds = generateSeeds(myvar)
// console.log(myvar);
// });
function countOccurences(songList) {
var songCount = songList.reduce(function (acc, curr) {
if (typeof acc[curr] == 'undefined') {
acc[curr] = 1;
} else {
acc[curr] += 1;
}
return acc;
}, {});
return songCount
}
// Generates a large array of seeds, take 5 at at time
function generateSeeds(songList, topN=20) {
var songCount = countOccurences(songList);
var keys = Object.keys(songCount)
var pairs = []
for (var i=0; i<keys.length; ++i) {
pairs.push([keys[i], songCount[keys[i]]])
}
pairs.sort(function(a, b){return 0.5 - Math.random()});
var sortedPairs = pairs.sort(function(a,b) {return b[1]-a[1]})
sortedPairs = sortedPairs.slice(0,topN)
var sortedSongs = sortedPairs.map(function(x) {return x[0]})
return sortedSongs
}