UNPKG

alfred-melon-youtube

Version:
134 lines (126 loc) 4.14 kB
const Melon = require('melon-chart-api'); const { searchVideos } = require('./apis/search'); const { listPlaylists, insertPlaylists, deletePlaylists } = require('./apis/playlists'); const { insertPlaylistItems } = require('./apis/playlistItems'); /** * getQueries * Fetches music chart data from Melon. * @param {string} date String representation of a date. * @param {number} cutLine Number of ranks to receieve. */ const getQueries = (data) => { const date = data.date; const cutLine = data.cutLine; return Melon(date, { cutLine }).weekly().then(chart => { const queries = chart.data.map(d => `${d.title} ${d.artist}`); return { dates: chart.dates, cutLine, queries, }; }); }; /** * getVideoIds * Requests Youtube search on queries. * @param {array} queries An array of items that contains "query" to search for. */ const getVideoIds = (data) => { const cb = (err, resp) => { const title = resp.items[0].snippet.title; return resp.items[0].id.videoId; }; return Promise.all(data.queries.map(query => searchVideos(query, cb))) .then(videoIds => { return { dates: data.dates, cutLine: data.cutLine, videoIds, }; }); }; /** * getPlaylistId * Finds a playlist ID and passes it along with data object. * @param {object} data Any object that contains data to pass on. */ const getPlaylistId = (data) => { const title = `Melon Chart Week of ${data.dates.start} - Top ${data.cutLine}`; const description = `Top ${data.cutLine} of Weekly Melon Music Chart ${data.dates.start} - ${data.dates.end}`; return findPlaylist(title) .then(playlistId => { if (playlistId) { // Do nothing, just return the ID. return playlistId; } // Make a new playlist with title. return createPlaylist(title, description); }) .then(playlistId => { return { playlistId, videoIds: data.videoIds, }; }); }; /** * findPlaylist * Searches for a playlist and returns its playlist ID. * NOTE: returns "undefined" is not found. * @param {string} title A title of playlist to search for. */ const findPlaylist = (title) => { return listPlaylists((err, resp) => { const items = resp.items.filter(p => p.snippet.title == title); if (items.length) { // Return the existing playlist ID. // Or should we do nothing and just return? return items[0].id } return undefined; }); }; /** * createPlaylist * Creates a new playlist and returns its playlist ID. * @param {string} title A title for new playlist. * @param {string} description A description for new playlist. */ const createPlaylist = (title, description) => { const callback = (err, resp) => resp; return insertPlaylists(title, description, callback) .then(resource => resource.id); }; /** * insertIntoPlaylist * Adds videos into the playlist. * @param {object} data An object that contains playlist ID and an array of video IDs. */ const insertIntoPlaylist = (data) => { const playlistId = data.playlistId; const videoIds = data.videoIds; return videoIds.map((videoId, index) => { // FIXME: Set "snippet.position" to ensure order. Need to change functions to take a hash params. // Limit 2 API calls per second. setTimeout(() => { return insertPlaylistItems(playlistId, videoId, () => console.log(`${videoId} is added to ${playlistId}.`)) }, 500 * index); }); }; /** * deletePlaylist * Deletes a playlist with given playlistId. * @param {object} data An object that contains playlist ID. */ const deletePlaylist = (data) => { const playlistId = data.playlistId; const callback = () => {}; return deletePlaylists(playlistId, callback); }; module.exports = { getQueries, getVideoIds, getPlaylistId, insertIntoPlaylist, deletePlaylist, }