commit 52c173696e4903a102fa00d65b043b56ba618790 Author: patrickkfkan Date: Wed Jan 20 04:37:31 2021 +0800 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..14f0bd7 --- /dev/null +++ b/README.md @@ -0,0 +1,157 @@ +# bandcamp-fetch + +A JS library for scraping Bandcamp content; inspired by [bandcamp-scraper](https://github.com/masterT/bandcamp-scraper). + +# Installation + +``` +npm i bandcamp-fetch --save +``` + +# Usage + +``` +const bcfetch = require('bandcamp-fetch'); + +bcfetch.discover(...).then( results => { + ... +}); +``` + +# API + +Each function returns a Promise which resolves to the fetched data. + +### discover([params], [options]) + +[**Example**](examples/discover.js) ([output](examples/discover_output.txt)) + +Fetches albums through Bandcamp Discover. + +- `params` (optional) - object specifying params to be passed to Bandcamp Discover + - genre + - subgenre: only valid when genre is something other than 'all' + - location + - sortBy + - artistRecommendationType: only valid when sortBy is 'rec' (artist recommended) + - format + - time + - page + + All properties are optional. Possible values for each property can be obtained with the `getDiscoverOptions()` function. + +- `options` (optional) - object specifying options to be used when formulating results: + - albumImageFormat: name, Id or object referring to an image format. + - artistImageFormat + + All properties are optional. Image formats can be obtained with the `getImageFormats()` function. + +### getDiscoverOptions() + +[**Example**](examples/getDiscoverOptions.js) ([output](examples/getDiscoverOptions_output.txt)) + +Fetches Bandcamp Discover options that can be passed back to `discover()`. + +### getImageFormats([filter]) + +[**Example**](examples/getImageFormats.js) ([output](examples/getImageFormats_output.txt)) + +Fetches the list of image formats used in Bandcamp. + +- `filter` (optional) - 'artist' or 'album'. If specified, narrows down the result to include only formats applicable to the specified value. + +### getImageFormat(idOrName) + +Fetches the image format that matches Id or name. If none is found, the result will be `null`. + +### getArtistOrLabelInfo(artistOrLabelUrl, [options]) + +[**Example**](examples/getArtistOrLabelInfo.js) ([output](examples/getArtistOrLabelInfo_output.txt)) + +Fetches information about an artist or label. + +- `artistOrLabelUrl` +- `options` (optional) + - imageFormat + +### getLabelArtists(labelUrl, [options]) + +[**Example**](examples/getLabelArtists.js) ([output](examples/getLabelArtists_output.txt)) + +Fetches the list of artists belonging to a label. + +- `labelUrl` +- `options` (optional) + - imageFormat + +### getDiscography(artistOrLabelUrl, [options]) + +[**Example**](examples/getDiscography.js) ([output](examples/getDiscography_output.txt)) + +Fetches the list of albums and standalone tracks belonging to an artist or label. + +- `artistOrLabelUrl` +- `options` (optional) + - imageFormat + +### getAlbumInfo(albumUrl, [options]) + +[**Example**](examples/getAlbumInfo.js) ([output](examples/getAlbumInfo_output.txt)) + +Fetches information about an album. + +- `albumUrl` +- `options` (optional) + - albumImageFormat + - artistImageFormat + - includeRawData + +### getTrackInfo(trackUrl, [options]) + +[**Example**](examples/getTrackInfo.js) ([output](examples/getTrackInfo_output.txt)) + +Fetches information about a track. + +- `trackUrl` +- `options` (optional) + - albumImageFormat + - artistImageFormat + - includeRawData + +### getAlbumHighlightsByTag(tagUrl, [options]) + +[**Example**](examples/getAlbumHighlightsByTag.js) ([output](examples/getAlbumHighlightsByTag_output.txt)) + +Fetches album highlights for the tag referred to by `tagUrl`. The result is an array of album collections, with each collection corresponding to a highlight category such as 'new and notable' and 'all-time best selling'. + +- `tagUrl` + + Tag URLs can be obtained with the `getTags()` function. + +- `options` (optional) + - imageFormat + +### getTags() + +[**Example**](examples/getTags.js) ([output](examples/getTags_output.txt)) + +Fetches Bandcamp tags. The result is an object with the following properties: +- `tags`: non-location tags +- `locations`: location tags + +### search(params, [options]) + +[**Example**](examples/search.js) ([output](examples/search_output.txt)) + +Searches for `params.query`. + +- `params` + - query: search string + - page (1 if omitted) +- `options` (optional) + - albumImageFormat + - artistImageFormat + +# License + +MIT \ No newline at end of file diff --git a/examples/discover.js b/examples/discover.js new file mode 100644 index 0000000..3f7693a --- /dev/null +++ b/examples/discover.js @@ -0,0 +1,15 @@ +const bcfetch = require('../'); +const util = require('util'); + +const params = { + genre: 'ambient' +} + +const options = { + albumImageFormat: 2, + artistImageFormat: 'bio_featured' +}; + +bcfetch.discover(params, options).then( results => { + console.log(util.inspect(results, false, null, false)); +}); \ No newline at end of file diff --git a/examples/discover_output.txt b/examples/discover_output.txt new file mode 100644 index 0000000..a41a01e --- /dev/null +++ b/examples/discover_output.txt @@ -0,0 +1,722 @@ +{ items: + [ { type: 'album', + name: 'Everywhere at the end of time', + url: 'https://thecaretaker.bandcamp.com/album/everywhere-at-the-end-of-time', + imageUrl: 'https://f4.bcbits.com/img/a2383326070_2.jpg', + genre: 'ambient', + artist: + { name: 'The Caretaker', + url: 'https://thecaretaker.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/8262351_28.jpg' }, + location: 'Manchester, UK', + featuredTrack: + { name: 'A1 - It\'s just a burning memory', + duration: 212.213, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/5374bf89169c62150232c9813a977c9a/mp3-128/1541188837?p=0&ts=1611151374&t=d4b9fc9a799d3720f3e9307750404967f36e6225&token=1611151374_77c7a8e297b50cdbe717954c4ae045d8e6abbc6f' } } }, + { type: 'album', + name: 'The Home Diaries', + url: 'https://whitelabrecs.bandcamp.com/album/the-home-diaries', + imageUrl: 'https://f4.bcbits.com/img/a4148627509_2.jpg', + genre: 'ambient', + artist: + { name: 'Whitelabrecs', + url: 'https://whitelabrecs.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21206991_28.jpg' }, + location: 'England, UK', + featuredTrack: + { name: 'The Sea Is Where You Go To Reminise When You Are Far From Home', + duration: 250.625, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/313b08011eeae85eeb1709387ba61634/mp3-128/2956653363?p=0&ts=1611151374&t=85e32aee2516f8b634567263da5e8dded45c3599&token=1611151374_84126e426fb988a6cdcefb9d459ef3927b32f90c' } } }, + { type: 'album', + name: 'Carven Throne/Many Pillared Halls/Runes of Power', + url: 'https://redhorngate.bandcamp.com/album/carven-throne-many-pillared-halls-runes-of-power', + imageUrl: 'https://f4.bcbits.com/img/a2650268956_2.jpg', + genre: 'ambient', + artist: + { name: 'Redhorn Gate', + url: 'https://redhorngate.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/18207165_28.jpg' }, + location: 'Chicago, Illinois', + featuredTrack: + { name: 'Carven Throne (Demo I)', + duration: 334.527, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/0224cd593a0c54248c4cf332b8762254/mp3-128/398398555?p=0&ts=1611151374&t=064e46173ad73ede81510b16176b2ef254647d29&token=1611151374_bb1258713cdbefb445a7dcca0f2b257c6047de4d' } } }, + { type: 'album', + name: 'What The Fog', + url: 'https://dauw.bandcamp.com/album/what-the-fog', + imageUrl: 'https://f4.bcbits.com/img/a3249583106_2.jpg', + genre: 'ambient', + artist: + { name: 'Allred & Broderick', + url: 'https://dauw.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/15508445_28.jpg' }, + location: 'Ghent, Belgium', + featuredTrack: + { name: 'The Foghorn', + duration: 558.798, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/fcbdbe91d8023e8130d8aed839f03973/mp3-128/2149716342?p=0&ts=1611151374&t=10cdb4e5997002a674ec874a1510147c72d55cf3&token=1611151374_0cf719eb6e48360d39c873fc35be3a8066df0d6f' } } }, + { type: 'album', + name: 'sui', + url: 'https://seilrecords.bandcamp.com/album/sui', + imageUrl: 'https://f4.bcbits.com/img/a3124837381_2.jpg', + genre: 'ambient', + artist: + { name: 'morimoto naoki', + url: 'https://seilrecords.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/16003094_28.jpg' }, + location: 'Frankfurt, Germany', + featuredTrack: + { name: 'ever', + duration: 190.906, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/8051594f183529dd48415622604ca728/mp3-128/2626430241?p=0&ts=1611151374&t=b13f57116368f665b61d39ed420314a6a3aef74d&token=1611151374_ff8f111fca1cfcfee94c7eefd04c3ff165c14e03' } } }, + { type: 'album', + name: 'Cryonics', + url: 'https://neotantra.bandcamp.com/album/cryonics', + imageUrl: 'https://f4.bcbits.com/img/a2683334513_2.jpg', + genre: 'ambient', + artist: + { name: 'Motionfield', + url: 'https://neotantra.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/18200996_28.jpg' }, + location: 'UK', + featuredTrack: + { name: 'Cryonics Part 2', + duration: 345.625, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/e55c7dcae4f5a80fd82f09757f437c60/mp3-128/183610895?p=0&ts=1611151374&t=2c4c1e7c00ae130ebbd3443734046d7e744bcdf3&token=1611151374_d85f158ecab939cbfde9319665d2a699da54801a' } } }, + { type: 'album', + name: 'Mirrors', + url: 'https://mickchillage.bandcamp.com/album/mirrors', + imageUrl: 'https://f4.bcbits.com/img/a889789274_2.jpg', + genre: 'ambient', + artist: + { name: 'Mick Chillage', + url: 'https://mickchillage.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/20194684_28.jpg' }, + location: 'Dublin, Ireland', + featuredTrack: + { name: 'Digitalis Solaris', + duration: 270.564, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/4b0e8fcde2532d0bc9fc44dc8b9fdbc8/mp3-128/1820786368?p=0&ts=1611151374&t=95ce8500ce933fb3fb05d7a038b7f6ed5c5d2ec6&token=1611151374_386529ede82f9934c1640afddc7c4fe4b87f6f95' } } }, + { type: 'album', + name: 'Meditations', + url: 'https://thelovelymoon.bandcamp.com/album/meditations', + imageUrl: 'https://f4.bcbits.com/img/a395256957_2.jpg', + genre: 'ambient', + artist: + { name: 'The Lovely Moon', + url: 'https://thelovelymoon.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/20816132_28.jpg' }, + location: 'Manchester, UK', + featuredTrack: + { name: 'As The Sun Rises', + duration: 605.84, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/b226315ccb557f309aa5c1e5b25d3ea9/mp3-128/2809751360?p=0&ts=1611151374&t=299440aa84d21e8c209cea34c09f13303f981baa&token=1611151374_f7d5c1d20a196f00f32ee45c2755087b3d2e2704' } } }, + { type: 'album', + name: 'There is no one in here', + url: 'https://annesulikowski.bandcamp.com/album/there-is-no-one-in-here', + imageUrl: 'https://f4.bcbits.com/img/a121612230_2.jpg', + genre: 'ambient', + artist: + { name: 'Anne Sulikowski', + url: 'https://annesulikowski.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21838525_28.jpg' }, + location: 'Hamilton, Ontario', + featuredTrack: + { name: 'Doe Lake Road', + duration: 327.794, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/4a3f5e32cf64d884a6e12b5bc06452af/mp3-128/673677427?p=0&ts=1611151374&t=81f77cd41ac762013e7a9d30e3f100b2e1a7780e&token=1611151374_a40010f362f418dbf68949f4f46283c1a6cc3f1b' } } }, + { type: 'album', + name: 'Repetition Hymns', + url: 'https://pitp.bandcamp.com/album/repetition-hymns', + imageUrl: 'https://f4.bcbits.com/img/a3883081516_2.jpg', + genre: 'ambient', + artist: + { name: 'Black Swan', + url: 'https://pitp.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21692848_28.jpg' }, + location: 'Indianapolis, Indiana', + featuredTrack: + { name: 'Closer', + duration: 238.001, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/1ab5fcfe575733e26be9764544addb7c/mp3-128/1664475933?p=0&ts=1611151374&t=7bef05a878d828c20891dacc320b81593f769773&token=1611151374_2324e9abeeec8af1d6fe488034792ea169cd5095' } } }, + { type: 'album', + name: 'Dark Ambient of 2020', + url: 'https://cryochamber.bandcamp.com/album/dark-ambient-of-2020', + imageUrl: 'https://f4.bcbits.com/img/a2990833741_2.jpg', + genre: 'ambient', + artist: + { name: 'Cryo Chamber', + url: 'https://cryochamber.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/4516843_28.jpg' }, + location: 'Oregon', + featuredTrack: + { name: 'Dark Ambient of 2020', + duration: 3035.2, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/954bdafc37202d6694a6ba257a5ce70b/mp3-128/4088858281?p=0&ts=1611151374&t=8d10ca3e728fefd6950e255805ac0e08c4f7202b&token=1611151374_ad61fc318ad5a36a9ff01e9b27e5ba0a98ecd9dc' } } }, + { type: 'album', + name: 'đ…đšđ«đžđŹđ­đ°đšđšđ„', + url: 'https://chooyu.bandcamp.com/album/--8', + imageUrl: 'https://f4.bcbits.com/img/a1725509283_2.jpg', + genre: 'ambient', + artist: + { name: '𝑳𝒖𝒂', + url: 'https://chooyu.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/20951429_28.jpg' }, + location: 'Bangkok, Thailand', + featuredTrack: + { name: 'đ–đžđ„đœđšđŠđž 𝐭𝐹 𝐩đČ đ‰đźđ§đ đ„đž', + duration: 500.975, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/80f947088e9b69aac07150094dae2b4e/mp3-128/1519962854?p=0&ts=1611151374&t=4c174480e9e3ebc102153a012ce86126e6ba70fd&token=1611151374_889dd8295e8c911db60ab8757dddf6849451882e' } } }, + { type: 'album', + name: 'Ocean Sounds & Coastal Ambience Of Iceland', + url: 'https://freetousesounds.bandcamp.com/album/ocean-sounds-coastal-ambience-of-iceland', + imageUrl: 'https://f4.bcbits.com/img/a1337359482_2.jpg', + genre: 'ambient', + artist: + { name: 'freetousesounds', + url: 'https://freetousesounds.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/20334833_28.jpg' }, + location: 'Los Angeles, California', + featuredTrack: + { name: 'Ocean, Extreme Powerful, Dangerous, Loud, Crushing, Windy, Black Sand, Sólheimasandur, North Atlantic Ocean, Iceland, 19232, 01', + duration: 178.612, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/4e0e9782fffc3b7edc0ecba01a3a731b/mp3-128/207386469?p=0&ts=1611151374&t=7ba608a7b185d51ec0c66aae61ac993499368265&token=1611151374_139051ea89e252c65bdca8660fe227d71e2c491e' } } }, + { type: 'album', + name: 'Salos', + url: 'https://stroomtv.bandcamp.com/album/salos', + imageUrl: 'https://f4.bcbits.com/img/a1405463013_2.jpg', + genre: 'ambient', + artist: + { name: 'Merope', + url: 'https://stroomtv.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21913014_28.jpg' }, + location: 'Belgium', + featuredTrack: + { name: 'Ei Dvipa', + duration: 254.347, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/36bcaefc801ea8a324e20f3a0feecfb2/mp3-128/717332475?p=0&ts=1611151374&t=b4cfee166bc5a90e4acff8d0f8506c0df1bc6721&token=1611151374_21c28a78278704087149cebb0046aeb336c64846' } } }, + { type: 'album', + name: 'New York City Sound Effects & Soundscape Vol 01', + url: 'https://freetousesounds.bandcamp.com/album/new-york-city-sound-effects-soundscape-vol-01', + imageUrl: 'https://f4.bcbits.com/img/a3238622388_2.jpg', + genre: 'ambient', + artist: + { name: 'freetousesounds', + url: 'https://freetousesounds.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/20334833_28.jpg' }, + location: 'Los Angeles, California', + featuredTrack: + { name: 'New York City Traffic Rush Hour & Cars Honking', + duration: 190, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/42b0d3d341f76216ee037aa5c40512f5/mp3-128/3357134447?p=0&ts=1611151374&t=61f3d598865c3a665ad8f2f7877ff9579588eb5b&token=1611151374_d48d24eb0aaf0049864a9794938d26b6cb7ad987' } } }, + { type: 'album', + name: 'Nusquam', + url: 'https://cryochamber.bandcamp.com/album/nusquam', + imageUrl: 'https://f4.bcbits.com/img/a3815523368_2.jpg', + genre: 'ambient', + artist: + { name: 'Aegri Somnia', + url: 'https://cryochamber.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/4516843_28.jpg' }, + location: 'Oregon', + featuredTrack: + { name: 'Throne', + duration: 254.841, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/4b1c42ec5ceb4dace3c006702136044d/mp3-128/2167154214?p=0&ts=1611151374&t=35ff521f09b3ee5d73fc6bbd452059efe7f74357&token=1611151374_ab0d05ec60b9a78c97b75067aa25b8e8bb1b2354' } } }, + { type: 'album', + name: 'Massage Sonore', + url: 'https://puresoundexperience.bandcamp.com/album/massage-sonore', + imageUrl: 'https://f4.bcbits.com/img/a1169135489_2.jpg', + genre: 'ambient', + artist: + { name: 'Pure Sound Experience', + url: 'https://puresoundexperience.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21988910_28.jpg' }, + location: 'France', + featuredTrack: + { name: 'Ondes BĂȘta', + duration: 594.428, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/fa1a66c1c8c31e0c48bcd429dc1c0b6e/mp3-128/3549888682?p=0&ts=1611151374&t=f26b78aaf63aa0f4af003ce11074f4f2697b5235&token=1611151374_8c9c05718136917ffe7dfa114b938b6526160bfe' } } }, + { type: 'album', + name: 'An empty bliss beyond this World', + url: 'https://thecaretaker.bandcamp.com/album/an-empty-bliss-beyond-this-world', + imageUrl: 'https://f4.bcbits.com/img/a4087775263_2.jpg', + genre: 'ambient', + artist: + { name: 'The Caretaker', + url: 'https://thecaretaker.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/8262351_28.jpg' }, + location: 'Manchester, UK', + featuredTrack: + { name: 'All you are going to want to do is get back there', + duration: 226.236, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/153845156a25011e0d4e3939103f8f02/mp3-128/1186879202?p=0&ts=1611151374&t=37e41784a012947111199f933d6561b26f6df177&token=1611151374_480a6064bb83ad142fd84799140f572c5782dcd0' } } }, + { type: 'album', + name: 'Silver Ladders', + url: 'https://marylattimoreharpist.bandcamp.com/album/silver-ladders', + imageUrl: 'https://f4.bcbits.com/img/a354576578_2.jpg', + genre: 'ambient', + artist: + { name: 'Mary Lattimore', + url: 'https://marylattimoreharpist.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/7493584_28.jpg' }, + location: 'Los Angeles, California', + featuredTrack: + { name: 'Silver Ladders', + duration: 225.934, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/d0f9df41cd89c026f79cfa17e8abfd76/mp3-128/1353268702?p=0&ts=1611151374&t=d1b8765b64845f8679f95d17a6e4e01e7f9173bc&token=1611151374_0b1c523e1b080ca33277f83a9ce5f8592deaf5c3' } } }, + { type: 'album', + name: 'Rusted Tone Recordings: Sampler Vol. 4', + url: 'https://rustedtonerecordings.bandcamp.com/album/rusted-tone-recordings-sampler-vol-4', + imageUrl: 'https://f4.bcbits.com/img/a1765051423_2.jpg', + genre: 'ambient', + artist: + { name: 'Various Artists', + url: 'https://rustedtonerecordings.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/15450473_28.jpg' }, + location: 'Farnham, UK', + featuredTrack: + { name: 'The Indian Ocean', + duration: 345, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/bd9e87557af18d79e0ad87fe03efff57/mp3-128/915522376?p=0&ts=1611151374&t=61738e408743fbd41d24d5c5a6ae9f764fd93251&token=1611151374_a184c0403f4747edb50327cd9be31cfd914aa2ad' } } }, + { type: 'album', + name: 'Walking', + url: 'https://nichts.bandcamp.com/album/walking', + imageUrl: 'https://f4.bcbits.com/img/a5572629_2.jpg', + genre: 'ambient', + artist: + { name: 'Docetism', + url: 'https://nichts.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/10608206_28.jpg' }, + location: 'Poland', + featuredTrack: + { name: 'Walking', + duration: 217.095, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/9c768a196692706422cb1f0e9300b153/mp3-128/3767313375?p=0&ts=1611151374&t=832dfdf7ca58df6ca71b6232a23e4aa47a7ad793&token=1611151374_00234290460870f6475c364afc7ec12494256259' } } }, + { type: 'album', + name: 'Because of a Flower', + url: 'https://anaroxanne.bandcamp.com/album/because-of-a-flower-2', + imageUrl: 'https://f4.bcbits.com/img/a3771205071_2.jpg', + genre: 'ambient', + artist: + { name: 'Ana Roxanne', + url: 'https://anaroxanne.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21548943_28.jpg' }, + location: 'New York, New York', + featuredTrack: + { name: 'Camille', + duration: 304.145, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/bf283c0edfd192d8d3d7550fff5fb387/mp3-128/692142981?p=0&ts=1611151374&t=19f4658eebcd8f4160308e7abcdfdcd111e80ed0&token=1611151374_a222c1ef0533bd86a0cefd43707327a8dab927ff' } } }, + { type: 'album', + name: 'Flora y Fauna', + url: 'https://neotantra.bandcamp.com/album/flora-y-fauna', + imageUrl: 'https://f4.bcbits.com/img/a489075639_2.jpg', + genre: 'ambient', + artist: + { name: 'Bålsam', + url: 'https://neotantra.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/18200996_28.jpg' }, + location: 'UK', + featuredTrack: + { name: 'Above the World', + duration: 384, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/f0959f1c1d3f9e4b791f1cc42a7f90bc/mp3-128/4185639205?p=0&ts=1611151374&t=6fd7704297bfa746ed1a8a5569381aaa5a5d6417&token=1611151374_8b42f46d7efe9382eee2121c0460e08fefa1a1bc' } } }, + { type: 'album', + name: 'Peel', + url: 'https://kmru.bandcamp.com/album/peel', + imageUrl: 'https://f4.bcbits.com/img/a125806975_2.jpg', + genre: 'ambient', + artist: + { name: 'KMRU', + url: 'https://kmru.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21505126_28.jpg' }, + location: 'Nairobi, Kenya', + featuredTrack: + { name: 'Why Are You Here', + duration: 910, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/72737f58e10638084bddc2e07d06fd37/mp3-128/46335344?p=0&ts=1611151374&t=32e0a9ec7452421f0c2c25011e244a7e9e7f9717&token=1611151374_1f2ed57db54f085b65fe89e9f6baaf6e5d00ce83' } } }, + { type: 'album', + name: 'Opacity Field', + url: 'https://hiraeth-records.bandcamp.com/album/opacity-field', + imageUrl: 'https://f4.bcbits.com/img/a1483512827_2.jpg', + genre: 'ambient', + artist: + { name: 'AURAGRAPH', + url: 'https://hiraeth-records.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/22632423_28.jpg' }, + location: 'Netherlands', + featuredTrack: + { name: 'Acid Disco', + duration: 260.5, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/2ecd09939a7cc3339d093c0730a2cdc8/mp3-128/1906343459?p=0&ts=1611151374&t=249c5010df4c64aa37cd623f2815dd8fa0baeca6&token=1611151374_63e7f2f256932320f0fa038612404bbcf3266f21' } } }, + { type: 'album', + name: 'Vedurnan', + url: 'https://thefogweaver.bandcamp.com/album/vedurnan', + imageUrl: 'https://f4.bcbits.com/img/a1463011715_2.jpg', + genre: 'ambient', + artist: + { name: 'Fogweaver', + url: 'https://thefogweaver.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/22596481_28.jpg' }, + location: 'Colorado', + featuredTrack: + { name: 'Farther West than West', + duration: 209.675, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/4a9f38db71261f19d312e4cd901a0277/mp3-128/3607911317?p=0&ts=1611151374&t=9a30f32ae0b0616c622cbfdcd039ac0d38878303&token=1611151374_157244a4cda950b96aa32c991241434bb455e74d' } } }, + { type: 'album', + name: 'In the Kingdom of Fog', + url: 'https://thefogweaver.bandcamp.com/album/in-the-kingdom-of-fog', + imageUrl: 'https://f4.bcbits.com/img/a2433211123_2.jpg', + genre: 'ambient', + artist: + { name: 'Fog Castle/Foglord/Fogweaver', + url: 'https://thefogweaver.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/22596481_28.jpg' }, + location: 'Colorado', + featuredTrack: + { name: 'Dreams of the Mist', + duration: 379.57, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/a8a178e59b7c4a6d82143027e8210db6/mp3-128/3070205225?p=0&ts=1611151374&t=c59dafdf37ab33ee292500e1e854db132c2f59c4&token=1611151374_4aaaa8f7b81e32686aaa128a7abacb7d0a3ae6e5' } } }, + { type: 'album', + name: 'Rá»ȘNG', + url: 'https://chooyu.bandcamp.com/album/r-ng', + imageUrl: 'https://f4.bcbits.com/img/a4170058320_2.jpg', + genre: 'ambient', + artist: + { name: 'Lá»­a', + url: 'https://chooyu.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/20951429_28.jpg' }, + location: 'Bangkok, Thailand', + featuredTrack: + { name: 'TĂŽi tháș„y', + duration: 209.403, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/1235d0699ad6f285fc3f0e7ec3e53074/mp3-128/1286391663?p=0&ts=1611151374&t=f9d5575eb32957b67db96f96cf8f1487e0c34431&token=1611151374_b00a607ec7c1ff82c6df07f4fa2803a7f5e8df0b' } } }, + { type: 'album', + name: 'Collider', + url: 'https://moanc.bandcamp.com/album/collider', + imageUrl: 'https://f4.bcbits.com/img/a2285160149_2.jpg', + genre: 'ambient', + artist: + { name: 'Moa', + url: 'https://moanc.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/23233520_28.jpg' }, + location: 'Charlotte, North Carolina', + featuredTrack: + { name: 'Hardest Part', + duration: 250.307, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/b8db5efae5786609fd40eec0a08d1562/mp3-128/1080013852?p=0&ts=1611151374&t=013afaf8ddb75c3d1552527b12e99bd5818866e6&token=1611151374_999608403bcade00e6b73106ae6a4b02607d5b15' } } }, + { type: 'album', + name: 'Silesco', + url: 'https://lontanoseries.bandcamp.com/album/silesco', + imageUrl: 'https://f4.bcbits.com/img/a2793131279_2.jpg', + genre: 'ambient', + artist: + { name: 'Thme', + url: 'https://lontanoseries.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/14016527_28.jpg' }, + location: 'Sardinia, Italy', + featuredTrack: + { name: 'A1. Dreamed, Spoken', + duration: 146, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/7da0f38afed9d550859f0cb873913b0a/mp3-128/439754540?p=0&ts=1611151374&t=214562da861c807607fc4bdb4df6fe04f53ed209&token=1611151374_c60d0e3172a65fd614dd26f4c6a594ee98ccdad8' } } }, + { type: 'album', + name: 'Hexen', + url: 'https://winterblood78.bandcamp.com/album/hexen', + imageUrl: 'https://f4.bcbits.com/img/a3343790811_2.jpg', + genre: 'ambient', + artist: + { name: 'Winterblood', + url: 'https://winterblood78.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/23052888_28.jpg' }, + location: 'Florence, Italy', + featuredTrack: + { name: 'Nebelnacht', + duration: 172.905, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/f8b30586dca74a0fdabef0c5309ff382/mp3-128/594833670?p=0&ts=1611151374&t=72c2826647f63e7437ef0285e494c7f1fba9d329&token=1611151374_c9990dfbe4956573f78eea693ca989f10b7e7dae' } } }, + { type: 'album', + name: 'Process', + url: 'https://pitp.bandcamp.com/album/process', + imageUrl: 'https://f4.bcbits.com/img/a4030809999_2.jpg', + genre: 'ambient', + artist: + { name: 'Tobias Karlehag', + url: 'https://pitp.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21692848_28.jpg' }, + location: 'Indianapolis, Indiana', + featuredTrack: + { name: 'Stay', + duration: 463.253, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/b746825fb97cd8f803eb80b0875a28d1/mp3-128/1941423248?p=0&ts=1611151374&t=5df0b5d349a0945b55dea7b6bdeb98be246bfb14&token=1611151374_27620866bd268ce4bc475796a2acea9e80182fcc' } } }, + { type: 'album', + name: 'Music From A Sinking World', + url: 'https://mforsleep.bandcamp.com/album/music-from-a-sinking-world', + imageUrl: 'https://f4.bcbits.com/img/a2528134504_2.jpg', + genre: 'ambient', + artist: + { name: 'Music For Sleep', + url: 'https://mforsleep.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/20057001_28.jpg' }, + location: 'Sardinia, Italy', + featuredTrack: + { name: 'A Quiet Storm', + duration: 392, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/f381c8ea18bf3a662b531fb7b50aba6e/mp3-128/1861266637?p=0&ts=1611151374&t=aac8381c70faccca47f50efaf25b83bd107d49ae&token=1611151374_a615a06948ce4dafeb02bbe0bb201f5d96deb650' } } }, + { type: 'album', + name: 'Goddess', + url: 'https://arthuros.bandcamp.com/album/goddess', + imageUrl: 'https://f4.bcbits.com/img/a1760436312_2.jpg', + genre: 'ambient', + artist: + { name: 'ARTHUROS', + url: 'https://arthuros.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/23189436_28.jpg' }, + location: 'Greece', + featuredTrack: + { name: 'Resisting Her Spell', + duration: 233.149, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/c660b0b8187f8f94e51c6dfae0bdf446/mp3-128/4026839189?p=0&ts=1611151374&t=9af054d9b5a1114837272b2e6106fe0d7de5c29a&token=1611151374_9b6c400d30c3d760d0cd33420c6c3ee24cff5b8b' } } }, + { type: 'album', + name: 'Amongst A Landscape Of Spiritual Reckoning', + url: 'https://forestrobots.bandcamp.com/album/amongst-a-landscape-of-spiritual-reckoning', + imageUrl: 'https://f4.bcbits.com/img/a1870742952_2.jpg', + genre: 'ambient', + artist: + { name: 'Forest Robots', + url: 'https://forestrobots.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/23199417_28.jpg' }, + location: 'California', + featuredTrack: + { name: 'All Great Things Must Grow Through Dirt First', + duration: 240, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/c39655f16732dd17629967b41ed6776c/mp3-128/1811867660?p=0&ts=1611151374&t=a97a2b6eddcf466a9819d5ede6ddf80c1a18e043&token=1611151374_caeb4e6824877859772a74e94dfeab0695f2ef2e' } } }, + { type: 'album', + name: 'Everything Difficult Must Disappear Forever', + url: 'https://wingsofanangel.bandcamp.com/album/everything-difficult-must-disappear-forever', + imageUrl: 'https://f4.bcbits.com/img/a65737799_2.jpg', + genre: 'ambient', + artist: + { name: 'Wings Of An Angel', + url: 'https://wingsofanangel.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21939320_28.jpg' }, + location: 'Israel', + featuredTrack: + { name: 'Here\'s A New Koan For You: Has Anybody Seen A Bodiless Antelope?', + duration: 655.135, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/bde0be0c4eed1bb6dd6b1b675d3d5509/mp3-128/1536268030?p=0&ts=1611151374&t=45a86b89a24cc479ce7978bc486d4f4ac119b03e&token=1611151374_d31a52418b4951607e60136a9e275734a18ddfc8' } } }, + { type: 'album', + name: 'Defining Gravity For Beginners', + url: 'https://wingsofanangel.bandcamp.com/album/defining-gravity-for-beginners', + imageUrl: 'https://f4.bcbits.com/img/a3286777751_2.jpg', + genre: 'ambient', + artist: + { name: 'Wings Of An Angel & Scott Lawlor', + url: 'https://wingsofanangel.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21939320_28.jpg' }, + location: 'Israel', + featuredTrack: + { name: 'A Promise Of Life-Affirming Wisdom', + duration: 1169.48, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/48411cfa88f9da06e47121b8a3716cf2/mp3-128/637769740?p=0&ts=1611151374&t=6e76bbe47c52f50cff42c3b7d126e1d113747a65&token=1611151374_d2ac7ccf39ea2fd7fb499aa47d068a09a7056db0' } } }, + { type: 'album', + name: 'Imagination Never Fails', + url: 'https://erang.bandcamp.com/album/imagination-never-fails', + imageUrl: 'https://f4.bcbits.com/img/a3899131032_2.jpg', + genre: 'ambient', + artist: + { name: 'Erang', + url: 'https://erang.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21273498_28.jpg' }, + location: 'France', + featuredTrack: + { name: 'Imagination Never Fails', + duration: 135.893, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/b93c8ffbaa9a696702fbb0f9ef7bb752/mp3-128/2307936647?p=0&ts=1611151374&t=b8596333f0585c37daa7f952ff5ec8baba848fb0&token=1611151374_a7b4ba0f6048580b335a7b3c6ae6622b4bb305f9' } } }, + { type: 'album', + name: 'Almond Drive', + url: 'https://rustedtonerecordings.bandcamp.com/album/almond-drive', + imageUrl: 'https://f4.bcbits.com/img/a1746379860_2.jpg', + genre: 'ambient', + artist: + { name: 'James Osland', + url: 'https://rustedtonerecordings.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/15450473_28.jpg' }, + location: 'Farnham, UK', + featuredTrack: + { name: 'In A Place That Was Dear To Me', + duration: 266.375, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/d9829ad4f01344293b901d3e885fdd92/mp3-128/2369259595?p=0&ts=1611151374&t=7d99c3f3c590a275aff865f9240c3c8b833ef268&token=1611151374_3a77b173f62f343ddc58d5c2795cd45283ce7468' } } }, + { type: 'album', + name: 'Iridescence Of Clouds', + url: 'https://astrangelyisolatedplace.bandcamp.com/album/iridescence-of-clouds', + imageUrl: 'https://f4.bcbits.com/img/a2740388042_2.jpg', + genre: 'ambient', + artist: + { name: 'Illuvia', + url: 'https://astrangelyisolatedplace.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/20131968_28.jpg' }, + location: 'Los Angeles, California', + featuredTrack: + { name: 'State of Emergence', + duration: 500.233, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/81e98046592daa1d527e4dc1cb85f044/mp3-128/4030451661?p=0&ts=1611151374&t=40c36f96d6e197b3b03b410d6f50256065b403f9&token=1611151374_8816dd264aac90cd83c080c20d5a964f86dd8b13' } } }, + { type: 'album', + name: 'Keepers of the Fungal Order', + url: 'https://hideousgomphidius.bandcamp.com/album/keepers-of-the-fungal-order', + imageUrl: 'https://f4.bcbits.com/img/a3794506141_2.jpg', + genre: 'ambient', + artist: + { name: 'Hideous Gomphidius', + url: 'https://hideousgomphidius.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/21013131_28.jpg' }, + location: null, + featuredTrack: + { name: 'Dwellers Beneath Rotten Wood', + duration: 228, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/79ed93e99050eb23864e1f4061a064f2/mp3-128/1401822728?p=0&ts=1611151374&t=dbe03cd8e860d4e286ea9e2833a51085c6dbc4c8&token=1611151374_b19684bb95b8bdb822022cf64f2444abfdddd1ab' } } }, + { type: 'album', + name: 'Enchantment of the Ring', + url: 'https://secretstairways.bandcamp.com/album/enchantment-of-the-ring', + imageUrl: 'https://f4.bcbits.com/img/a1412722947_2.jpg', + genre: 'ambient', + artist: + { name: 'Secret Stairways', + url: 'https://secretstairways.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/9388425_28.jpg' }, + location: null, + featuredTrack: + { name: 'What Lies Beyond the Door', + duration: 281.067, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/1e232c848d957bb021159c02215f0081/mp3-128/1956652066?p=0&ts=1611151374&t=cd0f4811778b4ccdbf6304590eadb34bb55b6c2f&token=1611151374_e11d9bee7d5e452d6e8256df55e877f9800ce0fb' } } }, + { type: 'album', + name: 'Shadow of Life (album)', + url: 'https://outofhell.bandcamp.com/album/shadow-of-life-album', + imageUrl: 'https://f4.bcbits.com/img/a1018533835_2.jpg', + genre: 'ambient', + artist: + { name: 'Out of Hell', + url: 'https://outofhell.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/17020626_28.jpg' }, + location: 'Sweden', + featuredTrack: + { name: 'The Stars, Like Dust', + duration: 293, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/53751b1046b2c77c7a8c24b2c6ca195a/mp3-128/1127401119?p=0&ts=1611151374&t=031fdededb217f178edd0edfe7fa4900b65c3747&token=1611151374_70bd6d5aae932a91717a8c06fd95818530bf6ab0' } } }, + { type: 'album', + name: 'Strange Gravity', + url: 'https://ambientelectronic.bandcamp.com/album/strange-gravity', + imageUrl: 'https://f4.bcbits.com/img/a518264345_2.jpg', + genre: 'ambient', + artist: + { name: 'Craig Padilla & Marvin Allen', + url: 'https://ambientelectronic.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/10309899_28.jpg' }, + location: 'Portland, Oregon', + featuredTrack: + { name: 'The Revelation', + duration: 407.688, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/3bb6174d31505258372842389dc58c8d/mp3-128/4180400289?p=0&ts=1611151374&t=349a7b3c59175ba54ac00c37f15ca563105e5c94&token=1611151374_197c2d0d854298141cc18f7673295b3376b22ccb' } } }, + { type: 'album', + name: 'Stand Before Me, Oh My Soul', + url: 'https://fabioorsi.bandcamp.com/album/stand-before-me-oh-my-soul', + imageUrl: 'https://f4.bcbits.com/img/a3994971674_2.jpg', + genre: 'ambient', + artist: + { name: 'Fabio Orsi', + url: 'https://fabioorsi.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/20400869_28.jpg' }, + location: 'Puglia, Italy', + featuredTrack: + { name: 'My Awesome Drugs Propaganda', + duration: 417.986, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/c11d7a0754548d1bfa98085ad257deca/mp3-128/563091300?p=0&ts=1611151374&t=0781e233f6d7858d3643a04f395f4a8fcf2cd0fa&token=1611151374_7efdc2154da8a2b2fce0ea07408a5e2934f92e54' } } }, + { type: 'album', + name: 'One Day Early', + url: 'https://lowflung.bandcamp.com/album/one-day-early', + imageUrl: 'https://f4.bcbits.com/img/a302942841_2.jpg', + genre: 'ambient', + artist: + { name: 'Low Flung', + url: 'https://lowflung.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/12318341_28.jpg' }, + location: 'Sydney, Australia', + featuredTrack: + { name: 'Untitled One', + duration: 1673.28, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/8560f9eed0f267d8d20d8ed279663cb8/mp3-128/2280575291?p=0&ts=1611151374&t=f823d1275935654dd87e24450601469cd4c18c44&token=1611151374_f4466a7acd15f29ab1c72449bd461014e19af205' } } }, + { type: 'album', + name: 'Chapter Eleven (1976 - 1987)', + url: 'https://robertturman.bandcamp.com/album/chapter-eleven-1976-1987', + imageUrl: 'https://f4.bcbits.com/img/a3810541717_2.jpg', + genre: 'ambient', + artist: + { name: 'Robert Turman', + url: 'https://robertturman.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/22379563_28.jpg' }, + location: 'Oberlin, Ohio', + featuredTrack: + { name: 'Rotator', + duration: 217.09, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/2644cb58f90be4e7d39b7364cbc33185/mp3-128/1076264049?p=0&ts=1611151374&t=d22da9a12a543867a38b90238a8889097628f8f7&token=1611151374_cdfdc0f1a8a694af9d733a89d3e1f5fef35f7256' } } }, + { type: 'album', + name: 'Jar', + url: 'https://seilrecords.bandcamp.com/album/jar', + imageUrl: 'https://f4.bcbits.com/img/a830866516_2.jpg', + genre: 'ambient', + artist: + { name: 'KMRU', + url: 'https://seilrecords.bandcamp.com', + imageUrl: 'https://f4.bcbits.com/img/16003094_28.jpg' }, + location: 'Frankfurt, Germany', + featuredTrack: + { name: 'degree of change', + duration: 256.007, + streamUrl: + { 'mp3-128': 'https://t4.bcbits.com/stream/d0d9e4652aa528d42928db22598be4be/mp3-128/894428376?p=0&ts=1611151374&t=633c16d3d6e5724a4a22211d3143302050e37714&token=1611151374_4403cabc1696e7bfa5a7c650c345b1403284e017' } } } ], + total: 1075 } diff --git a/examples/getAlbumHighlightsByTag.js b/examples/getAlbumHighlightsByTag.js new file mode 100644 index 0000000..11985e6 --- /dev/null +++ b/examples/getAlbumHighlightsByTag.js @@ -0,0 +1,12 @@ +const bcfetch = require('../'); +const util = require('util'); + +const tagUrl = 'https://bandcamp.com/tag/noise'; + +const options = { + imageFormat: 'art_app_large', +} + +bcfetch.getAlbumHighlightsByTag(tagUrl, options).then( results => { + console.log(util.inspect(results, false, null, false)); +}); \ No newline at end of file diff --git a/examples/getAlbumHighlightsByTag_output.txt b/examples/getAlbumHighlightsByTag_output.txt new file mode 100644 index 0000000..ad2b2d6 --- /dev/null +++ b/examples/getAlbumHighlightsByTag_output.txt @@ -0,0 +1,567 @@ +[ { name: 'new_releases', + title: 'new and notable', + items: + [ { type: 'album', + name: 'BREAK CORPS 2', + url: 'https://normcorps.bandcamp.com/album/break-corps-2', + imageUrl: 'https://f4.bcbits.com/img/a1905425283_16.jpg', + genre: 'electronic', + artist: { name: 'Norm Corps', url: 'https://normcorps.bandcamp.com' }, + featuredTrack: + { name: 'Gadget Naval', + streamUrl: 'https://t4.bcbits.com/stream/0d03d1a0bb93519bfc2281e3ad43f6dd/mp3-128/2493837349?p=0&ts=1611151388&t=0ee9f3273b587e5423fa99a70d0645ef669ebc17&token=1611151388_8d30109f51d88f539fcc7ee58f226f793337a195' } }, + { type: 'album', + name: 'A Body Of Errors', + url: 'https://thesoftmoon.bandcamp.com/album/a-body-of-errors', + imageUrl: 'https://f4.bcbits.com/img/a1976823612_16.jpg', + genre: 'alternative', + artist: + { name: 'Luis Vasquez', + url: 'https://thesoftmoon.bandcamp.com' }, + featuredTrack: + { name: 'Interno', + streamUrl: 'https://t4.bcbits.com/stream/b05bb8ffdc4ee277881cd6dec010b96f/mp3-128/1602280507?p=0&ts=1611151388&t=99558a031964bc99e08abb5d053629abc4e75513&token=1611151388_c301e42fb47d37d25ff4d8ceb70dc652856d51a6' } }, + { type: 'album', + name: 'au moins il pleut', + url: 'https://aumoinsilpleut.bandcamp.com/album/au-moins-il-pleut', + imageUrl: 'https://f4.bcbits.com/img/a1094115303_16.jpg', + genre: 'alternative', + artist: + { name: 'artistes variĂ©s', + url: 'https://aumoinsilpleut.bandcamp.com' }, + featuredTrack: + { name: 'paresse et satisfaction', + streamUrl: 'https://t4.bcbits.com/stream/956f8b3235db2db9268212661b65eee6/mp3-128/3855653851?p=0&ts=1611151388&t=b75512776d5fd8d2c4cc1becbed9619ff2688ce8&token=1611151388_495123fdfe26cb0c12f9ac5b0d63c3b2096387ca' } }, + { type: 'album', + name: 'Smoke \'Em If You Got \'Em', + url: 'https://tonguedepressor.bandcamp.com/album/smoke-em-if-you-got-em-4', + imageUrl: 'https://f4.bcbits.com/img/a1057381642_16.jpg', + genre: 'experimental', + artist: + { name: 'TONGUE DEPRESSOR', + url: 'https://tonguedepressor.bandcamp.com' }, + featuredTrack: + { name: 'SIDE A - 0\'00" - 26\'30"', + streamUrl: 'https://t4.bcbits.com/stream/2a4c4c83b328652e139149a84111c95a/mp3-128/2307680245?p=0&ts=1611151388&t=510f35a575752ccab91a7b6dd43221c9e72d008d&token=1611151388_5fc630c07270d1cdea96bad8eadb81f419e038b9' } }, + { type: 'album', + name: 'BRUTE ERR/ATA', + url: 'https://terminalblisscult.bandcamp.com/album/brute-err-ata-2', + imageUrl: 'https://f4.bcbits.com/img/a1903788750_16.jpg', + genre: 'punk', + artist: + { name: 'TERMINAL BLISS', + url: 'https://terminalblisscult.bandcamp.com' }, + featuredTrack: + { name: 'Clean Bill Of Wealth', + streamUrl: 'https://t4.bcbits.com/stream/1b6e0f9591eca9d9c286dd6017ac4867/mp3-128/4053604001?p=0&ts=1611151388&t=653c7cdde0c874da1cd2c92c6c676a6b3f2d97d0&token=1611151388_9dd56b4c0e8203fa311d1b6b54d613efc7f52330' } }, + { type: 'album', + name: 'In Ferneaux', + url: 'https://blanckmass.bandcamp.com/album/in-ferneaux', + imageUrl: 'https://f4.bcbits.com/img/a1426746037_16.jpg', + genre: 'experimental', + artist: { name: 'Blanck Mass', url: 'https://blanckmass.bandcamp.com' }, + featuredTrack: + { name: 'Starstuff (Single Edit)', + streamUrl: 'https://t4.bcbits.com/stream/ea4b67b9e77ad1b44a41549e46e1af75/mp3-128/604433231?p=0&ts=1611151388&t=99f2563af6fa1665ce5d2fca8364678206d618f2&token=1611151388_aa1b5a0dd79fb5cb2d6ce7ecaafb47a8e9c325c5' } }, + { type: 'album', + name: 'Fuck Content', + url: 'https://gregpuciato.bandcamp.com/album/fuck-content', + imageUrl: 'https://f4.bcbits.com/img/a2496494553_16.jpg', + genre: 'alternative', + artist: + { name: 'Greg Puciato', + url: 'https://gregpuciato.bandcamp.com' }, + featuredTrack: + { name: 'Absence as a Presence', + streamUrl: 'https://t4.bcbits.com/stream/c5dbf10042b7ad6f7b317c8639492c79/mp3-128/237635145?p=0&ts=1611151388&t=75cf70b33c8cb5f6c6e70e04b6befacfded9d180&token=1611151388_e6b79f758d07a4ebdc764d0f90f6c68752220209' } }, + { type: 'album', + name: 'Dozethrone Bloody Dozethrone', + url: 'https://dozethrone.bandcamp.com/album/dozethrone-bloody-dozethrone', + imageUrl: 'https://f4.bcbits.com/img/a3435519694_16.jpg', + genre: 'metal', + artist: { name: 'Dozethrone', url: 'https://dozethrone.bandcamp.com' }, + featuredTrack: + { name: 'Dozethrone Bloody Dozethrone', + streamUrl: 'https://t4.bcbits.com/stream/67e7eaedf5b934cf5402250c623aa777/mp3-128/477310339?p=0&ts=1611151388&t=ab8cd10289c9e6bfc9c63dd726c0a09fcdc7947f&token=1611151388_536269bec19b9e4a3f9cb6f5d06a6446c74a1cfc' } }, + { type: 'album', + name: 'Will Guthrie - live ateliers claus', + url: 'https://willguthrie.bandcamp.com/album/will-guthrie-live-ateliers-claus', + imageUrl: 'https://f4.bcbits.com/img/a2867002110_16.jpg', + genre: 'experimental', + artist: + { name: 'Will Guthrie', + url: 'https://willguthrie.bandcamp.com' }, + featuredTrack: + { name: 'Stolka MF', + streamUrl: 'https://t4.bcbits.com/stream/1699da56c1ccd697cabafdd8a28fb52c/mp3-128/2101140438?p=0&ts=1611151388&t=c2b51aae3d886349b8ae2aeaa19ef7b19ab4f68c&token=1611151388_bb93c2d9b512623de3488cdf07515187ae504758' } }, + { type: 'album', + name: 'Into the deep EP', + url: 'https://aliensproduction.bandcamp.com/album/into-the-deep-ep', + imageUrl: 'https://f4.bcbits.com/img/a3207738434_16.jpg', + genre: 'electronic', + artist: { name: 'Triode', url: 'https://aliensproduction.bandcamp.com' }, + featuredTrack: + { name: 'Carbon', + streamUrl: 'https://t4.bcbits.com/stream/ef792959aec380116f7686023f5be2d7/mp3-128/2286509810?p=0&ts=1611151388&t=a010551859c12bb92666982d4246c366129f97cd&token=1611151388_b1776d198bdb649b6580f53902ff9bbc7aefe8ed' } }, + { type: 'album', + name: 'The Black Stone – Music For Lovecraftian Summonings', + url: 'https://eighthtowerrecords.bandcamp.com/album/the-black-stone-music-for-lovecraftian-summonings', + imageUrl: 'https://f4.bcbits.com/img/a245639994_16.jpg', + genre: 'ambient', + artist: + { name: 'Various Artists', + url: 'https://eighthtowerrecords.bandcamp.com' }, + featuredTrack: + { name: 'Mombi Yuleman - Dreaming of Innsmouth', + streamUrl: 'https://t4.bcbits.com/stream/79a4f933d2bd2c7207b87b90337ef30e/mp3-128/914191382?p=0&ts=1611151388&t=dd599678bed60bc4cdb4eeb75198d8a9892f1094&token=1611151388_449b3203f65621c0702477555fc5c8486b98edc8' } }, + { type: 'album', + name: 'coffee in the evening', + url: 'https://noahbarbosa.bandcamp.com/album/coffee-in-the-evening', + imageUrl: 'https://f4.bcbits.com/img/a2025262681_16.jpg', + genre: 'electronic', + artist: + { name: 'Noah Barbosa', + url: 'https://noahbarbosa.bandcamp.com' }, + featuredTrack: + { name: 'coffee in the evening', + streamUrl: 'https://t4.bcbits.com/stream/45a3d3b3f7faa5b4360536e60afa6192/mp3-128/3533457376?p=0&ts=1611151388&t=89599acaad3d601e77d7a8708b8941bbf256ca5f&token=1611151388_0fae7d43bb8ad55526879a584df2c81c878b9cc0' } }, + { type: 'album', + name: 'pauper', + url: 'https://pauper-amsterdam.bandcamp.com/album/pauper', + imageUrl: 'https://f4.bcbits.com/img/a2120619949_16.jpg', + genre: 'punk', + artist: { name: 'Pauper', url: 'https://pauper-amsterdam.bandcamp.com' }, + featuredTrack: + { name: 'Stranger', + streamUrl: 'https://t4.bcbits.com/stream/9158d1add25945eb5cedf31e0f92f32a/mp3-128/855661955?p=0&ts=1611151388&t=d355fc058edfe35177b2ec83942893c086a5f83f&token=1611151388_87b1369d675eddaa3e94994f95c96c87b79c88c2' } }, + { type: 'album', + name: 'Shadow of Life (album)', + url: 'https://outofhell.bandcamp.com/album/shadow-of-life-album', + imageUrl: 'https://f4.bcbits.com/img/a1018533835_16.jpg', + genre: 'ambient', + artist: { name: 'Out of Hell', url: 'https://outofhell.bandcamp.com' }, + featuredTrack: + { name: 'The Stars, Like Dust', + streamUrl: 'https://t4.bcbits.com/stream/53751b1046b2c77c7a8c24b2c6ca195a/mp3-128/1127401119?p=0&ts=1611151388&t=5979a456d1b272a48939b373c984bdc1c782b73a&token=1611151388_5523f7a7ba40a4e05554a560cd22aa8b837c64ef' } }, + { type: 'album', + name: 'Machines of Deliverance', + url: 'https://webuildmachines.com/album/machines-of-deliverance', + imageUrl: 'https://f4.bcbits.com/img/a2944902242_16.jpg', + genre: 'electronic', + artist: { name: 'Various Artists', url: 'https://webuildmachines.com' }, + featuredTrack: + { name: 'Headless Horseman - Shift in Time', + streamUrl: 'https://t4.bcbits.com/stream/cb9100bb5e790f0d31b21dd167849d70/mp3-128/2630460704?p=0&ts=1611151388&t=3a0d2be1dd790902981fe895c2bfff3f09fce0e3&token=1611151388_043509c3d68018dd06febd9f1c2c941129a858dc' } } ] }, + { name: 'trending_vinyl', + title: 'featured noise vinyl', + items: + [ { type: 'album', + name: 'BRUTE ERR/ATA', + url: 'https://terminalblisscult.bandcamp.com/album/brute-err-ata-2', + imageUrl: 'https://f4.bcbits.com/img/a1903788750_16.jpg', + genre: 'punk', + artist: + { name: 'TERMINAL BLISS', + url: 'https://terminalblisscult.bandcamp.com' }, + featuredTrack: + { name: 'Clean Bill Of Wealth', + streamUrl: 'https://t4.bcbits.com/stream/1b6e0f9591eca9d9c286dd6017ac4867/mp3-128/4053604001?p=0&ts=1611151388&t=653c7cdde0c874da1cd2c92c6c676a6b3f2d97d0&token=1611151388_9dd56b4c0e8203fa311d1b6b54d613efc7f52330' } }, + { type: 'album', + name: 'A Body Of Errors', + url: 'https://thesoftmoon.bandcamp.com/album/a-body-of-errors', + imageUrl: 'https://f4.bcbits.com/img/a1976823612_16.jpg', + genre: 'alternative', + artist: + { name: 'Luis Vasquez', + url: 'https://thesoftmoon.bandcamp.com' }, + featuredTrack: + { name: 'Interno', + streamUrl: 'https://t4.bcbits.com/stream/b05bb8ffdc4ee277881cd6dec010b96f/mp3-128/1602280507?p=0&ts=1611151388&t=99558a031964bc99e08abb5d053629abc4e75513&token=1611151388_c301e42fb47d37d25ff4d8ceb70dc652856d51a6' } }, + { type: 'album', + name: 'ex·tem·po·re', + url: 'https://tripleeye.bandcamp.com/album/ex-tem-po-re', + imageUrl: 'https://f4.bcbits.com/img/a452837024_16.jpg', + genre: 'punk', + artist: { name: 'Whaler', url: 'https://tripleeye.bandcamp.com' }, + featuredTrack: + { name: 'Minilith', + streamUrl: 'https://t4.bcbits.com/stream/38b3d8f700522adc19372a25f0da4b58/mp3-128/2171161548?p=0&ts=1611151388&t=e25e5f43e9862b871aa3428935d1eab8f2352777&token=1611151388_5cbec3e50932930d9ae8e31a21940a5ff695e070' } }, + { type: 'album', + name: 'Polaroid Malibu', + url: 'https://echoplain.bandcamp.com/album/polaroid-malibu', + imageUrl: 'https://f4.bcbits.com/img/a3837905561_16.jpg', + genre: 'alternative', + artist: { name: 'Echoplain', url: 'https://echoplain.bandcamp.com' }, + featuredTrack: + { name: 'All eyes on me', + streamUrl: 'https://t4.bcbits.com/stream/c4847beead94a3f62a5d570ec48412ce/mp3-128/4210687765?p=0&ts=1611151388&t=7edab7c36cc37b65620f5e449bf4588a06da9e12&token=1611151388_3d16fc1aa21e1fbec6a2e02e57fa0a6cbfd329b0' } }, + { type: 'album', + name: 'Hypnagogic Drauma', + url: 'https://10shun.bandcamp.com/album/hypnagogic-drauma', + imageUrl: 'https://f4.bcbits.com/img/a3550663424_16.jpg', + genre: 'experimental', + artist: { name: 'Tenshun , Bonzo', url: 'https://10shun.bandcamp.com' }, + featuredTrack: + { name: 'Hypnagogic by Tenshun', + streamUrl: 'https://t4.bcbits.com/stream/ef2e06d8a3cac2157aa0a98b28d39db1/mp3-128/3768099428?p=0&ts=1611151388&t=398fde85f63951d7c0ca48994da71d7418012f8f&token=1611151388_ca2d71675eb8b52d8be104ddeb20d46d70b6ac2a' } }, + { type: 'album', + name: 'Machines of Deliverance', + url: 'https://webuildmachines.com/album/machines-of-deliverance', + imageUrl: 'https://f4.bcbits.com/img/a2944902242_16.jpg', + genre: 'electronic', + artist: { name: 'Various Artists', url: 'https://webuildmachines.com' }, + featuredTrack: + { name: 'Headless Horseman - Shift in Time', + streamUrl: 'https://t4.bcbits.com/stream/cb9100bb5e790f0d31b21dd167849d70/mp3-128/2630460704?p=0&ts=1611151388&t=3a0d2be1dd790902981fe895c2bfff3f09fce0e3&token=1611151388_043509c3d68018dd06febd9f1c2c941129a858dc' } }, + { type: 'album', + name: 'Monokultur - Ormens VĂ€g', + url: 'https://mammasmysteriskajukebox.bandcamp.com/album/monokultur-ormens-v-g', + imageUrl: 'https://f4.bcbits.com/img/a3837479101_16.jpg', + genre: 'folk', + artist: + { name: 'Monokultur', + url: 'https://mammasmysteriskajukebox.bandcamp.com' }, + featuredTrack: + { name: 'Decennium', + streamUrl: 'https://t4.bcbits.com/stream/7d0224b39adbc29c01a167c2e287fa31/mp3-128/881104855?p=0&ts=1611151388&t=04e486aaf87c2a32ca14ad6f20d42f69e155c078&token=1611151388_15f0c706c390f40b9bb6155d96ae74429adb4a34' } }, + { type: 'album', + name: 'Losing Circles', + url: 'https://yewrecordings.bandcamp.com/album/losing-circles', + imageUrl: 'https://f4.bcbits.com/img/a1309457418_16.jpg', + genre: 'experimental', + artist: + { name: 'Marcia Bassett / Thomas Dimuzio', + url: 'https://yewrecordings.bandcamp.com' }, + featuredTrack: + { name: 'Admonition', + streamUrl: 'https://t4.bcbits.com/stream/21c14b5fb1d03bb254cfbea941660ca1/mp3-128/3256371150?p=0&ts=1611151388&t=0c157ea923a9e2cda414bc8b2de6b919b4a965d8&token=1611151388_c597109f9fab001cae64ab2c069319a7ba5bed1f' } }, + { type: 'album', + name: 'Loopsel / The Spiral', + url: 'https://mammasmysteriskajukebox.bandcamp.com/album/loopsel-the-spiral', + imageUrl: 'https://f4.bcbits.com/img/a1046160659_16.jpg', + genre: 'folk', + artist: + { name: 'Loopsel', + url: 'https://mammasmysteriskajukebox.bandcamp.com' }, + featuredTrack: + { name: 'För din skull / Bones', + streamUrl: 'https://t4.bcbits.com/stream/5b04fa985e2082235490dd8e186b62be/mp3-128/519449477?p=0&ts=1611151388&t=c6a7ce759ed45f0df364a3a27a53f59408e1d668&token=1611151388_328f0e421265ab3041b64d0fef9ccb78f0d95695' } }, + { type: 'album', + name: 'Teenage Gizzard', + url: 'https://auroracentralrecords.bandcamp.com/album/teenage-gizzard', + imageUrl: 'https://f4.bcbits.com/img/a1413497139_16.jpg', + genre: 'experimental', + artist: + { name: 'King Gizzard & The Lizard Wizard', + url: 'https://auroracentralrecords.bandcamp.com' }, + featuredTrack: + { name: 'Hey There', + streamUrl: 'https://t4.bcbits.com/stream/2cff93ae1737703925975c3da6fa80e4/mp3-128/1242501892?p=0&ts=1611151388&t=008b8fc3205a4b3dd72b4bdb2c83110255ce91a9&token=1611151388_1981fb4573ac5c527458ae2f82cdb5ad3b75c9ac' } }, + { type: 'album', + name: 'Violence', + url: 'https://garymundykleistwahr.bandcamp.com/album/violence', + imageUrl: 'https://f4.bcbits.com/img/a1587294544_16.jpg', + genre: 'experimental', + artist: + { name: 'S.P.I.T.E', + url: 'https://garymundykleistwahr.bandcamp.com' }, + featuredTrack: + { name: 'Violence Part I', + streamUrl: 'https://t4.bcbits.com/stream/cfb9ac7b1cfae3cf89e493951cd6a2ee/mp3-128/2499418273?p=0&ts=1611151388&t=37f1b30ce74c780479e506c3ed69d0f7b99d8e35&token=1611151388_b36a1ac1354d8eed21d893b73026e8e542127845' } }, + { type: 'album', + name: 'BOYS', + url: 'https://cower.bandcamp.com/album/boys', + imageUrl: 'https://f4.bcbits.com/img/a3146999189_16.jpg', + genre: 'alternative', + artist: { name: 'COWER', url: 'https://cower.bandcamp.com' }, + featuredTrack: + { name: 'Park Jogger', + streamUrl: 'https://t4.bcbits.com/stream/de025a63e1774b1f364c4a9cdf6cd717/mp3-128/1693583315?p=0&ts=1611151388&t=00615eab5696e554b90485aaa150c8b70770f277&token=1611151388_8d17bd3cad638140783072220139bca38ffe3201' } }, + { type: 'album', + name: 'Niepokoje goƛcinne', + url: 'https://dymrecordings.bandcamp.com/album/niepokoje-go-cinne', + imageUrl: 'https://f4.bcbits.com/img/a313114941_16.jpg', + genre: 'experimental', + artist: + { name: 'wrong dials aka wd30', + url: 'https://dymrecordings.bandcamp.com' }, + featuredTrack: + { name: 'A', + streamUrl: 'https://t4.bcbits.com/stream/806a57afce0242f4a6f247194ba2fd5c/mp3-128/3659919355?p=0&ts=1611151388&t=eb9a9e0a6636a7f0006fd38fb03486c22f9b03f1&token=1611151388_9c013a8bd9f62bb82fca4458496922a6adda5212' } }, + { type: 'album', + name: 'Gyatso (Praxis 59/SAS001)', + url: 'https://praxisrecords.bandcamp.com/album/gyatso-praxis-59-sas001', + imageUrl: 'https://f4.bcbits.com/img/a1005729580_16.jpg', + genre: 'electronic', + artist: { name: '16-17', url: 'https://praxisrecords.bandcamp.com' }, + featuredTrack: + { name: 'Intravenous', + streamUrl: 'https://t4.bcbits.com/stream/4f7efcf0328ec2ad14677edf9511cc34/mp3-128/1160265803?p=0&ts=1611151388&t=617a2dcb817238eaae2688bb1039916057043dde&token=1611151388_c2140db4be5fea3093ebf45ad5219018b8f1e9b9' } }, + { type: 'album', + name: 'MMXX - 15 : LOST & FOUND', + url: 'https://matiere-memoire.bandcamp.com/album/mmxx-15-lost-found', + imageUrl: 'https://f4.bcbits.com/img/a2811114784_16.jpg', + genre: '', + artist: + { name: 'Hampus Lindwall', + url: 'https://matiere-memoire.bandcamp.com' }, + featuredTrack: + { name: 'MMXX - 15 : LOST & FOUND', + streamUrl: 'https://t4.bcbits.com/stream/de64d682805a6902dd84238052b7c244/mp3-128/1774017034?p=0&ts=1611151388&t=728332e3d203c951c0a6199f85b501f51975cdb2&token=1611151388_6f529276b20a5532110bff909d122c85a2a0985b' } } ] }, + { name: 'top_sellers', + title: 'all-time best selling noise', + items: + [ { type: 'album', + name: 'Peaceful as Hell', + url: 'https://blackdresses.bandcamp.com/album/peaceful-as-hell', + imageUrl: 'https://f4.bcbits.com/img/a3575771155_16.jpg', + genre: 'electronic', + artist: + { name: 'Black Dresses', + url: 'https://blackdresses.bandcamp.com' }, + featuredTrack: + { name: 'BEAUTIFUL FRIENDSHIP', + streamUrl: 'https://t4.bcbits.com/stream/8d5064f6c97778093c531428ca3efa06/mp3-128/1285558574?p=0&ts=1611151388&t=a06b5bcb94b7211db2273fefb520ece5dd6ba0c3&token=1611151388_a514ea7d2093bca06501af0eda15c1aae5ba4ada' } }, + { type: 'album', + name: 'Sounds Of France | France Sound Effects Library', + url: 'https://freetousesounds.bandcamp.com/album/sounds-of-france-france-sound-effects-library', + imageUrl: 'https://f4.bcbits.com/img/a2198695097_16.jpg', + genre: 'ambient', + artist: + { name: 'freetousesounds', + url: 'https://freetousesounds.bandcamp.com' }, + featuredTrack: + { name: 'Sound Compilation Sounds Of France', + streamUrl: 'https://t4.bcbits.com/stream/c6ea66c07c69bff1b0aa0a8b92439ec4/mp3-128/2634037464?p=0&ts=1611151388&t=cffd2aa563f732e1a2e908db6881df60771af0e0&token=1611151388_2217d0ce660b2b3a94de36b4473872e1536ed39b' } }, + { type: 'album', + name: 'Physically Sick 3', + url: 'https://physicallysick3.bandcamp.com/album/physically-sick-3', + imageUrl: 'https://f4.bcbits.com/img/a3764976661_16.jpg', + genre: 'electronic', + artist: + { name: 'Physically Sick 3', + url: 'https://physicallysick3.bandcamp.com' }, + featuredTrack: + { name: 'Body + Mind', + streamUrl: 'https://t4.bcbits.com/stream/a0b0d150e95c01e3abab2f67337dd9d0/mp3-128/2387878535?p=0&ts=1611151388&t=4ec4fa666ec2129c67bba308cc62a22571aeb960&token=1611151388_7a27f378f733003048815556c00194dcb7f77173' } }, + { type: 'album', + name: '1995', + url: 'https://music.businesscasual.biz/album/1995', + imageUrl: 'https://f4.bcbits.com/img/a1681009058_16.jpg', + genre: 'electronic', + artist: { name: '☒', url: 'https://music.businesscasual.biz' }, + featuredTrack: + { name: 'Moon Way (feat. Chemical Hypnotist)', + streamUrl: 'https://t4.bcbits.com/stream/f796fd140e5e99346511e207225800f3/mp3-128/2165960685?p=0&ts=1611151388&t=f8284e287fcc9f1811384ef67bffe46a80c8c2d7&token=1611151388_b5e9b0794149c6bd3d51b7dff61054f18a0bacd3' } }, + { type: 'album', + name: 'Atmospheric Horror Music Vol. 2', + url: 'https://2mellomakes.bandcamp.com/album/atmospheric-horror-music-vol-2', + imageUrl: 'https://f4.bcbits.com/img/a3751173803_16.jpg', + genre: 'hip-hop/rap', + artist: { name: '2 Mello', url: 'https://2mellomakes.bandcamp.com' }, + featuredTrack: + { name: 'Noise Investigation', + streamUrl: 'https://t4.bcbits.com/stream/b0ca80017b663bbf83f404f4d4c739a6/mp3-128/3971350643?p=0&ts=1611151388&t=b9def4cc34d08e0f8aacccbdfe656192b6370b55&token=1611151388_9f3a44bbe312fcf0f2cd1c11d87698129133da3a' } }, + { type: 'album', + name: 'Losing Grip on Reality', + url: 'https://geometriclullaby.bandcamp.com/album/losing-grip-on-reality', + imageUrl: 'https://f4.bcbits.com/img/a1041180441_16.jpg', + genre: 'electronic', + artist: + { name: 'Fiebertraum', + url: 'https://geometriclullaby.bandcamp.com' }, + featuredTrack: + { name: 'Dancing in the Crypt of Sorrow', + streamUrl: 'https://t4.bcbits.com/stream/49264f911c3f9b2841b2d852e820a053/mp3-128/4271360547?p=0&ts=1611151388&t=9ed7e30388349c235187eaa6ebd56b487288461d&token=1611151388_da373520bcf3273be82ba45aa5220b6eb83eedc6' } }, + { type: 'album', + name: 'Frost', + url: 'https://father.2006.kr/album/frost', + imageUrl: 'https://f4.bcbits.com/img/a1620504707_16.jpg', + genre: 'electronic', + artist: { name: 'No Death & 아ëČ„ì§€', url: 'https://father.2006.kr' }, + featuredTrack: + { name: 'Frost', + streamUrl: 'https://t4.bcbits.com/stream/ae9cb73d5aabe35a677891f0248e93c6/mp3-128/1332838237?p=0&ts=1611151388&t=e888ca8338088812a6ec1caf4058afe91e9c9e69&token=1611151388_4c52f048f0ff9c7ce2a13f9dcc0c7cf70a8e1d16' } }, + { type: 'album', + name: 'DEF VESPER', + url: 'https://blackpus.bandcamp.com/album/def-vesper', + imageUrl: 'https://f4.bcbits.com/img/a2379820301_16.jpg', + genre: 'rock', + artist: { name: 'Black Pus', url: 'https://blackpus.bandcamp.com' }, + featuredTrack: + { name: 'APOCALYPSE JOYRIDE', + streamUrl: 'https://t4.bcbits.com/stream/4d690b4b6d9d52d3ad1b9849e8fba4ee/mp3-128/3591787364?p=0&ts=1611151388&t=8947b61aef8d0188fb90f50ffd6e5868b4ecaa1b&token=1611151388_17bad7edf46bd638e91a5604f3a85cbc98308168' } }, + { type: 'album', + name: 'The Bug Ft Dis Fig, In Blue', + url: 'https://thebugmusic.bandcamp.com/album/the-bug-ft-dis-fig-in-blue', + imageUrl: 'https://f4.bcbits.com/img/a1403157577_16.jpg', + genre: 'experimental', + artist: { name: 'The Bug', url: 'https://thebugmusic.bandcamp.com' }, + featuredTrack: + { name: 'You', + streamUrl: 'https://t4.bcbits.com/stream/27a50f7d9746cb4da8ff8f1bb46022d5/mp3-128/245840704?p=0&ts=1611151388&t=d0094d18559d94e27f52a13fd3b77c34b11e2634&token=1611151388_40f01888cdc673d1cfa8df4739f6a6f73590aa48' } }, + { type: 'album', + name: '2R0I2P0', + url: 'https://borismerzbow.bandcamp.com/album/2r0i2p0', + imageUrl: 'https://f4.bcbits.com/img/a2247379779_16.jpg', + genre: 'metal', + artist: + { name: 'Boris & Merzbow', + url: 'https://borismerzbow.bandcamp.com' }, + featuredTrack: + { name: 'Away from You', + streamUrl: 'https://t4.bcbits.com/stream/036c3524aba59efa8930d7a460ad7522/mp3-128/1179903000?p=0&ts=1611151388&t=5bda9162452a40f6a3f6192c58eff003e4545e39&token=1611151388_58b6b54d1f020e1689be0cedc32bd11c3178bf2a' } }, + { type: 'album', + name: 'Immersion', + url: 'https://primitivemandoom.bandcamp.com/album/immersion', + imageUrl: 'https://f4.bcbits.com/img/a160033873_16.jpg', + genre: 'metal', + artist: + { name: 'Primitive Man', + url: 'https://primitivemandoom.bandcamp.com' }, + featuredTrack: + { name: 'The Lifer', + streamUrl: 'https://t4.bcbits.com/stream/a8ff1cb2dce2ab48d4185759f890bcc8/mp3-128/3378123275?p=0&ts=1611151388&t=2d8ba3423e83b45e16cfa3ecae2f4426b38cf057&token=1611151388_1c8b4412e31731b5f7dc9c856f6114936485d858' } }, + { type: 'album', + name: 'Atlas Vending', + url: 'https://metz.bandcamp.com/album/atlas-vending', + imageUrl: 'https://f4.bcbits.com/img/a1721167726_16.jpg', + genre: 'punk', + artist: { name: 'METZ', url: 'https://metz.bandcamp.com' }, + featuredTrack: + { name: 'A Boat to Drown In', + streamUrl: 'https://t4.bcbits.com/stream/5696b1c267d56b81bdf70782c28f6e18/mp3-128/1716209931?p=0&ts=1611151388&t=ebf54d1c94b79d13ee5386c82ebafc8c8c4e3fdd&token=1611151388_bc57f47d537830880be23bda3a6750fb10489d30' } }, + { type: 'album', + name: 'CLEPSYDRA', + url: 'https://moormother.bandcamp.com/album/clepsydra', + imageUrl: 'https://f4.bcbits.com/img/a275758065_16.jpg', + genre: 'experimental', + artist: { name: 'Moor Mother', url: 'https://moormother.bandcamp.com' }, + featuredTrack: + { name: 'TRUE LIES OF HISTORY feat OLOF MELANDER', + streamUrl: 'https://t4.bcbits.com/stream/cfcf1c5ac95cc2066dd9e1b814311bfd/mp3-128/1336744965?p=0&ts=1611151388&t=e446da91477a342433b022418b7dfb42db39f0f0&token=1611151388_acf5d557f1763c76a565d277f43186bb21cf1562' } }, + { type: 'album', + name: 'FACE THE DARKNESS', + url: 'https://blackieallcapswithspaces.bandcamp.com/album/face-the-darkness', + imageUrl: 'https://f4.bcbits.com/img/a3654575079_16.jpg', + genre: 'hip-hop/rap', + artist: + { name: 'B L A C K I E... All Caps, With Spaces', + url: 'https://blackieallcapswithspaces.bandcamp.com' }, + featuredTrack: + { name: 'WHILE THEY TRY TO KILL EACH OTHER', + streamUrl: 'https://t4.bcbits.com/stream/66a24db71fdf836dc8f88f8db9487263/mp3-128/3200429347?p=0&ts=1611151388&t=5e5f2e7b6db216fe023a01fd1818d9667a193778&token=1611151388_bd7835470ef5c4323dd9669e3e2c4dc75419c635' } }, + { type: 'album', + name: 'Careful', + url: 'https://boyharsher.bandcamp.com/album/careful', + imageUrl: 'https://f4.bcbits.com/img/a1131250781_16.jpg', + genre: 'electronic', + artist: { name: 'Boy Harsher', url: 'https://boyharsher.bandcamp.com' }, + featuredTrack: + { name: 'Fate', + streamUrl: 'https://t4.bcbits.com/stream/a3333d562264f54384205d89fb4d4dc0/mp3-128/1162083825?p=0&ts=1611151388&t=bdf2730ba723bd58cd42005b5034a6f58fc86b65&token=1611151388_b63d347bc9da82f5d33e2042ffcb8ac24a379ac6' } }, + { type: 'album', + name: 'artless', + url: 'https://ifidieinmississippi.bandcamp.com/album/artless-2', + imageUrl: 'https://f4.bcbits.com/img/a3831177236_16.jpg', + genre: 'acoustic', + artist: + { name: 'if i die in mississippi', + url: 'https://ifidieinmississippi.bandcamp.com' }, + featuredTrack: + { name: 'this could be us but u playin\'', + streamUrl: 'https://t4.bcbits.com/stream/ef39ec6bbd8da6d9a875825d34614ea4/mp3-128/4056986611?p=0&ts=1611151388&t=3dcea21b1f1e414d69214b3932d8b69db528fff2&token=1611151388_9ef94607f65f4fb68ac3cb707334fa10dfc77e6a' } } ] }, + { name: 'fan_reviews', + title: 'recommendations from fans', + items: + [ { type: 'album', + name: 'Fuck Content', + url: 'https://gregpuciato.bandcamp.com/album/fuck-content', + imageUrl: 'https://f4.bcbits.com/img/a2496494553_16.jpg', + genre: 'alternative', + artist: + { name: 'Greg Puciato', + url: 'https://gregpuciato.bandcamp.com' }, + featuredTrack: + { name: 'Absence as a Presence', + streamUrl: 'https://t4.bcbits.com/stream/c5dbf10042b7ad6f7b317c8639492c79/mp3-128/237635145?p=0&ts=1611151388&t=75cf70b33c8cb5f6c6e70e04b6befacfded9d180&token=1611151388_e6b79f758d07a4ebdc764d0f90f6c68752220209' } }, + { type: 'album', + name: 'residue', + url: 'https://father.2006.kr/album/residue', + imageUrl: 'https://f4.bcbits.com/img/a2325745156_16.jpg', + genre: 'electronic', + artist: { name: '아ëČ„ì§€', url: 'https://father.2006.kr' }, + featuredTrack: + { name: 'low level of despair', + streamUrl: 'https://t4.bcbits.com/stream/d3ac51ea6a9a9f53392495fe370fd80b/mp3-128/4198130533?p=0&ts=1611151388&t=04c7a8efe443f1be35a5232ebbe32ab077c1fe84&token=1611151388_f22ba6e5424c3efe577d1e492d08664c3d07f953' } }, + { type: 'album', + name: 'BREAK CORPS 2', + url: 'https://normcorps.bandcamp.com/album/break-corps-2', + imageUrl: 'https://f4.bcbits.com/img/a1905425283_16.jpg', + genre: 'electronic', + artist: { name: 'Norm Corps', url: 'https://normcorps.bandcamp.com' }, + featuredTrack: + { name: 'Gadget Naval', + streamUrl: 'https://t4.bcbits.com/stream/0d03d1a0bb93519bfc2281e3ad43f6dd/mp3-128/2493837349?p=0&ts=1611151388&t=0ee9f3273b587e5423fa99a70d0645ef669ebc17&token=1611151388_8d30109f51d88f539fcc7ee58f226f793337a195' } }, + { type: 'album', + name: 'VOID (EP)', + url: 'https://gotmilkblood.bandcamp.com/album/void-ep', + imageUrl: 'https://f4.bcbits.com/img/a1280416850_16.jpg', + genre: 'electronic', + artist: { name: 'MILKBLOOD', url: 'https://gotmilkblood.bandcamp.com' }, + featuredTrack: + { name: 'SICK OF BEING HONEST', + streamUrl: 'https://t4.bcbits.com/stream/d74abce2c1d1fd77a98aa1d4fec34a29/mp3-128/830280898?p=0&ts=1611151388&t=607dc898f46dd70f2906e25cd4b54efb37981023&token=1611151388_d9c264ad8fcbabb94fd5c51494eea745b2cb71ca' } }, + { type: 'album', + name: 'BRASS', + url: 'https://moormother.bandcamp.com/album/brass', + imageUrl: 'https://f4.bcbits.com/img/a2253407346_16.jpg', + genre: 'experimental', + artist: + { name: 'Moor Mother & billy woods', + url: 'https://moormother.bandcamp.com' }, + featuredTrack: + { name: 'Furies', + streamUrl: 'https://t4.bcbits.com/stream/cf95483d67638d7e92ae76f01453634a/mp3-128/3627852126?p=0&ts=1611151388&t=796038117ee93593053041b90a4d3ce0709a6905&token=1611151388_2330ad09021cd4a938a91b6f92212a13dfc8cb5b' } }, + { type: 'album', + name: 'The Black Stone – Music For Lovecraftian Summonings', + url: 'https://eighthtowerrecords.bandcamp.com/album/the-black-stone-music-for-lovecraftian-summonings', + imageUrl: 'https://f4.bcbits.com/img/a245639994_16.jpg', + genre: 'ambient', + artist: + { name: 'Various Artists', + url: 'https://eighthtowerrecords.bandcamp.com' }, + featuredTrack: + { name: 'Mombi Yuleman - Dreaming of Innsmouth', + streamUrl: 'https://t4.bcbits.com/stream/79a4f933d2bd2c7207b87b90337ef30e/mp3-128/914191382?p=0&ts=1611151388&t=dd599678bed60bc4cdb4eeb75198d8a9892f1094&token=1611151388_449b3203f65621c0702477555fc5c8486b98edc8' } }, + { type: 'album', + name: 'Cobra\'s Crude Christmas Carols', + url: 'https://deathbedtapes.bandcamp.com/album/cobras-crude-christmas-carols', + imageUrl: 'https://f4.bcbits.com/img/a3605108864_16.jpg', + genre: 'experimental', + artist: + { name: 'King Cobra', + url: 'https://deathbedtapes.bandcamp.com' }, + featuredTrack: + { name: 'Intro', + streamUrl: 'https://t4.bcbits.com/stream/927672af3c4b24da14fd7afeeca542e7/mp3-128/2382694294?p=0&ts=1611151388&t=b17a50fd52686e9be2b623ceabd7fbebe7c94067&token=1611151388_b72e301a8ac9753e5513148d20aedd9aa11724f8' } }, + { type: 'album', + name: 'Black Moon Lilith in Pisces in the 4th House', + url: 'https://bighedva.bandcamp.com/album/black-moon-lilith-in-pisces-in-the-4th-house', + imageUrl: 'https://f4.bcbits.com/img/a1795842606_16.jpg', + genre: 'experimental', + artist: { name: 'Johanna Hedva', url: 'https://bighedva.bandcamp.com' }, + featuredTrack: + { name: 'O Death', + streamUrl: 'https://t4.bcbits.com/stream/f205f8a884c3a0f22514fc92415405b8/mp3-128/3928674484?p=0&ts=1611151388&t=6d4c9449c8a13c9fb43eab83e4bcf1ce175f6800&token=1611151388_f4f16bfb1465156b15d4665e1de8debeac2bfd3e' } }, + { type: 'album', + name: 'Cosmic Slime', + url: 'https://deadneanderthals.bandcamp.com/album/cosmic-slime', + imageUrl: 'https://f4.bcbits.com/img/a1701339380_16.jpg', + genre: 'experimental', + artist: + { name: 'Dead Neanderthals', + url: 'https://deadneanderthals.bandcamp.com' }, + featuredTrack: + { name: 'Cosmic Slime', + streamUrl: 'https://t4.bcbits.com/stream/7b9551a318517e507591c46a750d057a/mp3-128/1370439344?p=0&ts=1611151388&t=caa545eb94899ddd0ee0cad0eb7b1a57dc1debdd&token=1611151388_b89e58f2fa7d14deef6777a6b72111db29de239a' } } ] } ] diff --git a/examples/getAlbumInfo.js b/examples/getAlbumInfo.js new file mode 100644 index 0000000..6662642 --- /dev/null +++ b/examples/getAlbumInfo.js @@ -0,0 +1,14 @@ +const bcfetch = require('../'); +const util = require('util'); + +const albumUrl = 'https://musique.coeurdepirate.com/album/blonde'; + +const options = { + albumImageFormat: 'art_app_large', + artistImageFormat: 'bio_featured', + includeRawData: false +} + +bcfetch.getAlbumInfo(albumUrl, options).then( results => { + console.log(util.inspect(results, false, null, false)); +}); \ No newline at end of file diff --git a/examples/getAlbumInfo_output.txt b/examples/getAlbumInfo_output.txt new file mode 100644 index 0000000..cb11e39 --- /dev/null +++ b/examples/getAlbumInfo_output.txt @@ -0,0 +1,90 @@ +{ type: 'album', + name: 'Blonde', + url: 'https://musique.coeurdepirate.com/album/blonde', + numTracks: 12, + imageUrl: 'https://f4.bcbits.com/img/a1328452291_16.jpg', + keywords: 'Pop, amour, coeur de pirate, french, french pop, grosse boĂźte, montreal, piano pop, MontrĂ©al', + description: 'AprĂšs avoir immortalisĂ© tout un pan de son adolescence dans les chansons pop douces-amĂšres d\'un premier album homonyme, Coeur de pirate s\'attaque aux diffĂ©rentes Ă©tapes de la relation amoureuse, d\'oĂč le titre de l\'album, en rĂ©fĂ©rence avant tout, Ă  la copine, Ă  l\'amoureuse. L\'album a Ă©tĂ© enregistrĂ© Ă  l\'Ă©tĂ© 2011 Ă  l\'Hotel2Tango sous la gouverne d\'Howard Bilerman, corĂ©alisateur avec BĂ©atrice Martin.', + releaseDate: '07 Nov 2011 00:00:00 GMT', + artist: + { name: 'CƓur de pirate', + url: 'https://musique.coeurdepirate.com', + description: 'CƓur de Pirate is the solo project of singer BĂ©atrice Martin. She has been playing piano since age 3 and released her acclaimed debut album in 2008. After touring extensively, she was nominated for and won several awards in Canada and France.\n\nLabel: Dare To Care Records \nmanagement@daretocarerecords.com', + imageUrl: 'https://f4.bcbits.com/img/0021821004_28.jpg' }, + releases: + [ { name: 'Blonde - CD', + url: 'https://coeurdepirate.bandcamp.com/album/blonde', + format: 'CDFormat', + description: 'Blonde - Édition rĂ©guliĂšre comprend le tĂ©lĂ©chargement gratuit de l\'album digital. Veuillez allouer 3 jours ouvrables pour que la version physique vous soit postĂ©e.\nPour les commandes hors-Canada, vous devez compter de 2 Ă  4 semaines pour recevoir votre achat.', + imageUrl: null }, + { name: 'Blonde - Vinyle', + url: 'https://coeurdepirate.bandcamp.com/album/blonde', + format: 'VinylFormat', + description: 'L\'Ă©dition vinyle de Blonde comprend les 12 pistes de l\'Ă©dition rĂ©guliĂšre, ainsi qu\'une affichette 12x24 po. L\'achat comprend le tĂ©lĂ©chargement gratuit de l\'album en version rĂ©guliĂšre.\nVeuillez allouer 3 jours ouvrables pour que la version physique vous soit postĂ©e.', + imageUrl: null }, + { name: 'Blonde', + url: 'https://musique.coeurdepirate.com/album/blonde#download', + format: 'DigitalFormat', + description: 'Includes high-quality download in MP3, FLAC and more. Paying supporters also get unlimited streaming via the free Bandcamp app.', + imageUrl: 'https://f4.bcbits.com/img/a1328452291_16.jpg' } ], + tracks: + [ { position: 1, + name: 'LĂšve les voiles', + url: 'https://musique.coeurdepirate.com/track/l-ve-les-voiles', + duration: 72.7333, + streamUrl: 'https://t4.bcbits.com/stream/4ec5267c795d34d71d84b8d9e6373477/mp3-128/4183427253?p=0&ts=1611151401&t=ae63fda98a26b9010977d09bed9ec75cedf74a54&token=1611151401_448f6a61deab3e97c1be87d49ebac16e7619188b' }, + { position: 2, + name: 'Adieu', + url: 'https://musique.coeurdepirate.com/track/adieu', + duration: 147.627, + streamUrl: 'https://t4.bcbits.com/stream/bdf4f2f59952f78effcbbf3ff63300db/mp3-128/3647767496?p=0&ts=1611151401&t=4ff01d05808644e1db254512af81213be2f64ee7&token=1611151401_a8dbb67e35b45fd1f7d1ebe460dd42d5b481f81f' }, + { position: 3, + name: 'Danse et danse', + url: 'https://musique.coeurdepirate.com/track/danse-et-danse', + duration: 190.413, + streamUrl: 'https://t4.bcbits.com/stream/8d4d755d9f351caf16529342096c3de6/mp3-128/1276790164?p=0&ts=1611151401&t=2c5bbe1c6af333ab8040c91b4747b6f325f3c73b&token=1611151401_6456f5d27b07a7fd270a297626fbe8b2f5f62795' }, + { position: 4, + name: 'Golden Baby', + url: 'https://musique.coeurdepirate.com/track/golden-baby', + duration: 187.027, + streamUrl: 'https://t4.bcbits.com/stream/af5533da023515d8c6c28dd834b7872f/mp3-128/365646139?p=0&ts=1611151401&t=a2701c3ccce0ed5ba3d4a18a972ff20c71963811&token=1611151401_d4e8d9e46b8fc9ae7c3f710b94dc77b78de9bdef' }, + { position: 5, + name: 'Ava', + url: 'https://musique.coeurdepirate.com/track/ava', + duration: 196.88, + streamUrl: 'https://t4.bcbits.com/stream/5133f1cab7fa8da200f1392690aca50e/mp3-128/1796143680?p=0&ts=1611151401&t=55815b9bf4823160d850a0a9bad1e1c3a650b275&token=1611151401_15448b3762e35174dd9dcdfe7c8494967a84ffeb' }, + { position: 6, + name: 'Loin d\'ici', + url: 'https://musique.coeurdepirate.com/track/loin-dici', + duration: 163.827, + streamUrl: 'https://t4.bcbits.com/stream/8a3166238fe996999f457459c592f7c7/mp3-128/260996437?p=0&ts=1611151401&t=8db66464d39c3eb723450b038c70a54290fcbe44&token=1611151401_b31108652c0965609ba8362e36006e19b0c3f09c' }, + { position: 7, + name: 'Les amours dĂ©vouĂ©es', + url: 'https://musique.coeurdepirate.com/track/les-amours-d-vou-es', + duration: 147.947, + streamUrl: 'https://t4.bcbits.com/stream/a62a0cd6f5b871e7559627b34f996552/mp3-128/4086570201?p=0&ts=1611151401&t=15d9327bf587d6b7f0165eb2bb94d8c06a748b47&token=1611151401_ee7fb4c3745cdbdca7ef4f0802fad7c55fb8ef8d' }, + { position: 8, + name: 'Place de la RĂ©publique', + url: 'https://musique.coeurdepirate.com/track/place-de-la-r-publique', + duration: 251.227, + streamUrl: 'https://t4.bcbits.com/stream/f7f5df6de9007b9415e120d8083cd973/mp3-128/1239774913?p=0&ts=1611151401&t=3c7be6b9fc12c9e734397836390feb8493010af4&token=1611151401_f72e75c8843981bdd2d67e18864b74d39ee06534' }, + { position: 9, + name: 'Cap Diamant', + url: 'https://musique.coeurdepirate.com/track/cap-diamant', + duration: 163.293, + streamUrl: 'https://t4.bcbits.com/stream/732fc4dbcd8ca3cc2cc477d773f99206/mp3-128/3259278294?p=0&ts=1611151401&t=99c0ba4d569c21fd6f9605b46dee8fa3d24422d8&token=1611151401_18f9144b94f0a9eb8b13fec58b695263388e0ebd' }, + { position: 10, + name: 'Verseau', + url: 'https://musique.coeurdepirate.com/track/verseau', + duration: 233.813, + streamUrl: 'https://t4.bcbits.com/stream/a4e97e8b436b8e2ad1a2c598f5cd0a48/mp3-128/496320675?p=0&ts=1611151401&t=71a50cf8af657c5c5296d34d50a63ecc56d95ea1&token=1611151401_a6abf7e155dd88259de5fb4478bdeb12cfad124f' }, + { position: 11, + name: 'Saint-Laurent', + url: 'https://musique.coeurdepirate.com/track/saint-laurent', + duration: 194.787, + streamUrl: 'https://t4.bcbits.com/stream/5f87e431eaaf515564c006de4c888e91/mp3-128/2437695881?p=0&ts=1611151401&t=cdcb0228abc4553c41b960dc9bccfcd389c213ef&token=1611151401_6908727bfc3c4a3a72d601630b2e5ac717b99598' }, + { position: 12, + name: 'La petite mort', + url: 'https://musique.coeurdepirate.com/track/la-petite-mort', + duration: 229.627, + streamUrl: 'https://t4.bcbits.com/stream/b257ccb8aca3ea864cbb2774e9d8d2be/mp3-128/525064765?p=0&ts=1611151401&t=44a70c2a253eb4bde67370ac826ba2307df4fd87&token=1611151401_6f7c486ae9695db8e10d02da07a174c3c6a02dfb' } ] } diff --git a/examples/getArtistOrLabelInfo.js b/examples/getArtistOrLabelInfo.js new file mode 100644 index 0000000..c836285 --- /dev/null +++ b/examples/getArtistOrLabelInfo.js @@ -0,0 +1,21 @@ +const bcfetch = require('../'); +const util = require('util'); + +const artistUrl = 'https://musique.coeurdepirate.com'; +const labelUrl = 'https://daretocarerecords.bandcamp.com'; + +const options = { + imageFormat: 'art_app_large', +} + +bcfetch.getArtistOrLabelInfo(artistUrl, options).then( results => { + console.log('Artist URL: ' + artistUrl); + console.log(util.inspect(results, false, null, false)); + console.log(); +}); + +bcfetch.getArtistOrLabelInfo(labelUrl, options).then( results => { + console.log('Label URL: ' + labelUrl); + console.log(util.inspect(results, false, null, false)); + console.log(); +}); \ No newline at end of file diff --git a/examples/getArtistOrLabelInfo_output.txt b/examples/getArtistOrLabelInfo_output.txt new file mode 100644 index 0000000..93b474b --- /dev/null +++ b/examples/getArtistOrLabelInfo_output.txt @@ -0,0 +1,19 @@ +Label URL: https://daretocarerecords.bandcamp.com +{ type: 'label', + name: 'Dare To Care Records', + url: 'https://daretocarerecords.bandcamp.com', + description: 'La boutique fait relĂąche pour la pĂ©riode des FĂȘtes. De retour le 4 janvier 2021!', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0020958150_16.jpg' } + +Artist URL: https://musique.coeurdepirate.com +{ type: 'artist', + name: 'CƓur de pirate', + url: 'https://musique.coeurdepirate.com', + description: 'CƓur de Pirate is the solo project of singer BĂ©atrice Martin. She has been playing piano since age 3 and released her acclaimed debut album in 2008. After touring extensively, she was nominated for and won several awards in Canada and France.\n\nLabel: Dare To Care Records \nmanagement@daretocarerecords.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0021821004_16.jpg', + label: + { name: 'Dare To Care Records', + url: 'https://daretocarerecords.bandcamp.com' } } + diff --git a/examples/getDiscography.js b/examples/getDiscography.js new file mode 100644 index 0000000..165de2e --- /dev/null +++ b/examples/getDiscography.js @@ -0,0 +1,21 @@ +const bcfetch = require('../'); +const util = require('util'); + +const artistUrl = 'https://musique.coeurdepirate.com'; +const labelUrl = 'https://randsrecords.bandcamp.com'; + +const options = { + imageFormat: 'art_app_large', +} + +bcfetch.getDiscography(artistUrl, options).then( results => { + console.log('Artist URL: ' + artistUrl); + console.log(util.inspect(results, false, null, false)); + console.log(); +}); + +bcfetch.getDiscography(labelUrl, options).then( results => { + console.log('Label URL: ' + labelUrl); + console.log(util.inspect(results, false, null, false)); + console.log(); +}); \ No newline at end of file diff --git a/examples/getDiscography_output.txt b/examples/getDiscography_output.txt new file mode 100644 index 0000000..dc2a08e --- /dev/null +++ b/examples/getDiscography_output.txt @@ -0,0 +1,575 @@ +Artist URL: https://musique.coeurdepirate.com +[ { url: 'https://musique.coeurdepirate.com/track/tes-belle', + type: 'track', + name: 'T\'es belle', + imageUrl: 'https://f4.bcbits.com/img/a0774650359_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/track/ne-mappelle-pas', + type: 'track', + name: 'Ne m\'appelle pas', + imageUrl: 'https://f4.bcbits.com/img/a2603960871_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/en-cas-de-temp-te-ce-jardin-sera-ferm', + type: 'album', + name: 'en cas de tempĂȘte, ce jardin sera fermĂ©.', + imageUrl: 'https://f4.bcbits.com/img/a0248413645_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/somnambule', + type: 'album', + name: 'Somnambule', + imageUrl: 'https://f4.bcbits.com/img/a1903816474_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/pr-monition-2', + type: 'album', + name: 'PrĂ©monition', + imageUrl: 'https://f4.bcbits.com/img/a2454271957_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/chansons-tristes-pour-no-l', + type: 'album', + name: 'Chansons tristes pour NoĂ«l', + imageUrl: 'https://f4.bcbits.com/img/a2476670277_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/roses', + type: 'album', + name: 'Roses', + imageUrl: 'https://f4.bcbits.com/img/a3347055233_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/carry-on-2', + type: 'album', + name: 'Carry On', + imageUrl: 'https://f4.bcbits.com/img/a4277887982_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/oublie-moi-carry-on', + type: 'album', + name: 'Oublie​-​moi (Carry On)', + imageUrl: 'https://f4.bcbits.com/img/a0891943451_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/child-of-light', + type: 'album', + name: 'Child of Light', + imageUrl: 'https://f4.bcbits.com/img/a3984758353_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/trauma', + type: 'album', + name: 'Trauma', + imageUrl: 'https://f4.bcbits.com/img/a3799110102_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/blonde', + type: 'album', + name: 'Blonde', + imageUrl: 'https://f4.bcbits.com/img/a1328452291_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/comme-des-enfants-version-originale-et-remix-par-le-matos', + type: 'album', + name: 'Comme des enfants (Version originale et remix par Le Matos)', + imageUrl: 'https://f4.bcbits.com/img/a1250129776_16.jpg', + artist: 'CƓur de pirate' }, + { url: 'https://musique.coeurdepirate.com/album/coeur-de-pirate', + type: 'album', + name: 'Coeur de pirate', + imageUrl: 'https://f4.bcbits.com/img/a2201751482_16.jpg', + artist: 'CƓur de pirate' } ] + +Label URL: https://randsrecords.bandcamp.com +[ { url: 'https://paulwhite.bandcamp.com/album/smile-see-the-light', + type: 'album', + name: 'Smile (See The Light)', + imageUrl: 'https://f4.bcbits.com/img/a0078770650_16.jpg', + artist: 'Paul White feat. Iyamah & Remi' }, + { url: 'https://saminterface.bandcamp.com/album/pink-dolphins-ep', + type: 'album', + name: 'Pink Dolphins EP', + imageUrl: 'https://f4.bcbits.com/img/a0822271284_16.jpg', + artist: 'Sam Interface' }, + { url: 'https://forestdrivewest.bandcamp.com/album/terminus-ep', + type: 'album', + name: 'Terminus EP', + imageUrl: 'https://f4.bcbits.com/img/a3636491375_16.jpg', + artist: 'Forest Drive West' }, + { url: 'https://lone.bandcamp.com/album/lone-x-kettama', + type: 'album', + name: 'Lone x KETTAMA', + imageUrl: 'https://f4.bcbits.com/img/a3844432643_16.jpg', + artist: 'Lone x KETTAMA' }, + { url: 'https://specialrequest187.bandcamp.com/album/spectral-frequency', + type: 'album', + name: 'Spectral Frequency', + imageUrl: 'https://f4.bcbits.com/img/a2096829253_16.jpg', + artist: 'Special Request' }, + { url: 'https://randsrecords.bandcamp.com/album/rv-trax-vol-5', + type: 'album', + name: 'RV Trax, Vol. 5', + imageUrl: 'https://f4.bcbits.com/img/a2129309811_16.jpg', + artist: 'R&S Records' }, + { url: 'https://randsrecords.bandcamp.com/album/in-order-to-care-deleted', + type: 'album', + name: 'In Order To Care (DELETED)', + imageUrl: 'https://f4.bcbits.com/img/a1662919219_16.jpg', + artist: 'R&S Records' }, + { url: 'https://architecturalrecs.bandcamp.com/album/planet-is-but-a-dream', + type: 'album', + name: 'Planet Is But A Dream', + imageUrl: 'https://f4.bcbits.com/img/a2801260386_16.jpg', + artist: 'Architectural' }, + { url: 'https://futurebeatalliance.bandcamp.com/album/never-forever', + type: 'album', + name: 'Never Forever', + imageUrl: 'https://f4.bcbits.com/img/a4088803645_16.jpg', + artist: 'Future Beat Alliance' }, + { url: 'https://yansima.bandcamp.com/album/tweede-cans', + type: 'album', + name: 'Tweede Cans', + imageUrl: 'https://f4.bcbits.com/img/a1336844977_16.jpg', + artist: 'Yansima' }, + { url: 'https://more-time.bandcamp.com/album/r-s-presents-more-time-records-vol-1', + type: 'album', + name: 'R&S presents: More Time Records Vol 1', + imageUrl: 'https://f4.bcbits.com/img/a0703436468_16.jpg', + artist: 'More Time' }, + { url: 'https://spacedimensioncontroller.bandcamp.com/album/love-beyond-the-intersect', + type: 'album', + name: 'Love Beyond The Intersect', + imageUrl: 'https://f4.bcbits.com/img/a4057499431_16.jpg', + artist: 'Space Dimension Controller' }, + { url: 'https://bartaub.bandcamp.com/album/marble-ya-betta-jam', + type: 'album', + name: 'Marble / Ya Betta Jam', + imageUrl: 'https://f4.bcbits.com/img/a1656383403_16.jpg', + artist: 'BĂ€rtaub' }, + { url: 'https://randsrecords.bandcamp.com/album/rv-trax-vol-4', + type: 'album', + name: 'RV Trax Vol 4', + imageUrl: 'https://f4.bcbits.com/img/a2374816883_16.jpg', + artist: 'Various Artists' }, + { url: 'https://afriqua.bandcamp.com/album/colored', + type: 'album', + name: 'Colored', + imageUrl: 'https://f4.bcbits.com/img/a3931309346_16.jpg', + artist: 'Afriqua' }, + { url: 'https://sportinglife.bandcamp.com/album/black-diamond-ep', + type: 'album', + name: 'Black Diamond EP', + imageUrl: 'https://f4.bcbits.com/img/a1752543133_16.jpg', + artist: 'Sporting Life' }, + { url: 'https://djrum.bandcamp.com/album/hard-to-say-tournesol', + type: 'album', + name: 'Hard to Say / Tournesol', + imageUrl: 'https://f4.bcbits.com/img/a1414096599_16.jpg', + artist: 'Djrum' }, + { url: 'https://randsrecords.bandcamp.com/album/neverlasting-love', + type: 'album', + name: 'Neverlasting Love', + imageUrl: 'https://f4.bcbits.com/img/a3334302883_16.jpg', + artist: 'East Of Oceans' }, + { url: 'https://adakaleh.bandcamp.com/album/chemare-cosmic', + type: 'album', + name: 'Chemare cosmică', + imageUrl: 'https://f4.bcbits.com/img/a4225860793_16.jpg', + artist: 'Ada Kaleh' }, + { url: 'https://6siss.bandcamp.com/album/prisma', + type: 'album', + name: 'Prisma', + imageUrl: 'https://f4.bcbits.com/img/a3746802060_16.jpg', + artist: '6SISS' }, + { url: 'https://afriqua.bandcamp.com/album/jumpteenth', + type: 'album', + name: 'Jumpteenth', + imageUrl: 'https://f4.bcbits.com/img/a3540548131_16.jpg', + artist: 'Afriqua' }, + { url: 'https://lostsoulsofsaturn.bandcamp.com/album/lost-souls-of-saturn', + type: 'album', + name: 'Lost Souls Of Saturn', + imageUrl: 'https://f4.bcbits.com/img/a3766159075_16.jpg', + artist: 'Lost Souls Of Saturn' }, + { url: 'https://yaksound.bandcamp.com/album/termina-ep', + type: 'album', + name: 'Termina EP', + imageUrl: 'https://f4.bcbits.com/img/a2700459812_16.jpg', + artist: 'Yak' }, + { url: 'https://lostsoulsofsaturn.bandcamp.com/album/the-awakening-inc-james-holden-remix', + type: 'album', + name: 'The Awakening [inc James Holden remix]', + imageUrl: 'https://f4.bcbits.com/img/a0319633005_16.jpg', + artist: 'Lost Souls Of Saturn' }, + { url: 'https://spacedimensioncontroller.bandcamp.com/album/reseq-ep', + type: 'album', + name: 'ReSEQ EP', + imageUrl: 'https://f4.bcbits.com/img/a2561252353_16.jpg', + artist: 'Space Dimension Controller' }, + { url: 'https://benhayes.bandcamp.com/album/see-sun-ep', + type: 'album', + name: 'See Sun EP', + imageUrl: 'https://f4.bcbits.com/img/a2177273264_16.jpg', + artist: 'Ben Hayes' }, + { url: 'https://lakker.bandcamp.com/album/poca', + type: 'album', + name: 'Época', + imageUrl: 'https://f4.bcbits.com/img/a3481268406_16.jpg', + artist: 'Lakker' }, + { url: 'https://lostsoulsofsaturn.bandcamp.com/album/holes-in-the-holoverse-ep-inc-wolfgang-tillmans-remix', + type: 'album', + name: 'Holes In The Holoverse EP [inc Wolfgang Tillmans remix]', + imageUrl: 'https://f4.bcbits.com/img/a3422639050_16.jpg', + artist: 'Lost Souls Of Saturn' }, + { url: 'https://randsrecords.bandcamp.com/album/rv-trax-vol-3', + type: 'album', + name: 'RV Trax Vol 3', + imageUrl: 'https://f4.bcbits.com/img/a1395065717_16.jpg', + artist: 'R&S Records' }, + { url: 'https://benhayes.bandcamp.com/album/ready-yet-feat-nubya-garcia', + type: 'album', + name: 'Ready Yet (feat Nubya Garcia)', + imageUrl: 'https://f4.bcbits.com/img/a3751006084_16.jpg', + artist: 'Ben Hayes' }, + { url: 'https://shcaa.bandcamp.com/album/an-ungrateful-death', + type: 'album', + name: 'An Ungrateful Death', + imageUrl: 'https://f4.bcbits.com/img/a2877713528_16.jpg', + artist: 'Shcaa' }, + { url: 'https://nicolasjaar.bandcamp.com/album/nymphs-triple-lp', + type: 'album', + name: 'Nymphs - Triple LP', + imageUrl: 'https://f4.bcbits.com/img/a3174238166_16.jpg', + artist: 'Nicolas Jaar' }, + { url: 'https://gabriels.bandcamp.com/album/loyalty', + type: 'album', + name: 'Loyalty', + imageUrl: 'https://f4.bcbits.com/img/a0407526073_16.jpg', + artist: 'Gabriels' }, + { url: 'https://hermetics.bandcamp.com/album/techgnosis-ep', + type: 'album', + name: 'Techgnosis EP', + imageUrl: 'https://f4.bcbits.com/img/a3133044058_16.jpg', + artist: 'Hermetics' }, + { url: 'https://lone.bandcamp.com/album/ambivert-tools-one-four-japan-cd', + type: 'album', + name: 'Ambivert Tools One-Four Japan CD', + imageUrl: 'https://f4.bcbits.com/img/a2292587669_16.jpg', + artist: 'Lone' }, + { url: 'https://marielito.bandcamp.com/album/2000-2005', + type: 'album', + name: '2000-2005', + imageUrl: 'https://f4.bcbits.com/img/a3837740573_16.jpg', + artist: 'Mariel Ito' }, + { url: 'https://paulwhite.bandcamp.com/album/returning-rival-consoles-remix', + type: 'album', + name: 'Returning (Rival Consoles Remix)', + imageUrl: 'https://f4.bcbits.com/img/a3475848676_16.jpg', + artist: 'Paul White' }, + { url: 'https://lone.bandcamp.com/album/ambivert-tools-volume-four', + type: 'album', + name: 'Ambivert Tools Volume Four', + imageUrl: 'https://f4.bcbits.com/img/a2380250227_16.jpg', + artist: 'Lone' }, + { url: 'https://maghreban.bandcamp.com/album/monster-vip', + type: 'album', + name: 'Monster VIP', + imageUrl: 'https://f4.bcbits.com/img/a2159211960_16.jpg', + artist: 'The Maghreban' }, + { url: 'https://djrum.bandcamp.com/album/portrait-with-firewood', + type: 'album', + name: 'Portrait With Firewood', + imageUrl: 'https://f4.bcbits.com/img/a1924727225_16.jpg', + artist: 'Djrum' }, + { url: 'https://randsrecords.bandcamp.com/album/rv-trax-vol-2', + type: 'album', + name: 'RV Trax Vol 2', + imageUrl: 'https://f4.bcbits.com/img/a0843418465_16.jpg', + artist: 'Various Artists' }, + { url: 'https://paulwhite.bandcamp.com/album/ice-cream-man', + type: 'album', + name: 'Ice Cream Man', + imageUrl: 'https://f4.bcbits.com/img/a0488414899_16.jpg', + artist: 'Paul White Feat. Shungudzo' }, + { url: 'https://benjamindamage.bandcamp.com/album/malfunction', + type: 'album', + name: 'Malfunction', + imageUrl: 'https://f4.bcbits.com/img/a1569426334_16.jpg', + artist: 'Benjamin Damage' }, + { url: 'https://afriqua.bandcamp.com/album/vice-principle-ep', + type: 'album', + name: 'Vice/Principle EP', + imageUrl: 'https://f4.bcbits.com/img/a1112113317_16.jpg', + artist: 'Afriqua' }, + { url: 'https://talaboman.bandcamp.com/album/the-night-land-remixed', + type: 'album', + name: 'The Night Land Remixed', + imageUrl: 'https://f4.bcbits.com/img/a1841699442_16.jpg', + artist: 'Talaboman' }, + { url: 'https://paulwhite.bandcamp.com/album/rejuvenate', + type: 'album', + name: 'Rejuvenate', + imageUrl: 'https://f4.bcbits.com/img/a3202037917_16.jpg', + artist: 'Paul White' }, + { url: 'https://maghreban.bandcamp.com/album/revenge-dance-mix', + type: 'album', + name: 'Revenge - Dance Mix', + imageUrl: 'https://f4.bcbits.com/img/a2572455723_16.jpg', + artist: 'The Maghreban feat. Rutendo Machiridza' }, + { url: 'https://karimsahraoui.bandcamp.com/album/plenitude-ep', + type: 'album', + name: 'Plenitude EP', + imageUrl: 'https://f4.bcbits.com/img/a2450943221_16.jpg', + artist: 'Karim Sahraoui' }, + { url: 'https://maghreban.bandcamp.com/album/01deas', + type: 'album', + name: '01DEAS', + imageUrl: 'https://f4.bcbits.com/img/a4016273020_16.jpg', + artist: 'The Maghreban' }, + { url: 'https://blondes.bandcamp.com/album/quality-of-life-struction-remix', + type: 'album', + name: 'Quality Of Life (Struction Remix)', + imageUrl: 'https://f4.bcbits.com/img/a0167516807_16.jpg', + artist: 'Blondes' }, + { url: 'https://music.maartenvandervleuten.com/album/maarten-van-der-vleuten-presents-integrity-outrage', + type: 'album', + name: 'Maarten van der Vleuten Presents Integrity - Outrage', + imageUrl: 'https://f4.bcbits.com/img/a1909170598_16.jpg', + artist: 'Maarten van der Vleuten' }, + { url: 'https://lone.bandcamp.com/album/ambivert-tools-volume-three', + type: 'album', + name: 'Ambivert Tools Volume Three', + imageUrl: 'https://f4.bcbits.com/img/a3303507735_16.jpg', + artist: 'Lone' }, + { url: 'https://acidmondays.bandcamp.com/album/universal-rhythm', + type: 'album', + name: 'Universal Rhythm', + imageUrl: 'https://f4.bcbits.com/img/a2763790377_16.jpg', + artist: 'Acid Mondays' }, + { url: 'https://randsrecords.bandcamp.com/album/rv-trax', + type: 'album', + name: 'RV Trax', + imageUrl: 'https://f4.bcbits.com/img/a2057042953_16.jpg', + artist: 'Various Artists' }, + { url: 'https://afriqua.bandcamp.com/album/aleph-ep', + type: 'album', + name: 'Aleph EP', + imageUrl: 'https://f4.bcbits.com/img/a3629577728_16.jpg', + artist: 'Afriqua' }, + { url: 'https://djrum.bandcamp.com/album/broken-glass-arch', + type: 'album', + name: 'Broken Glass Arch', + imageUrl: 'https://f4.bcbits.com/img/a4267147376_16.jpg', + artist: 'Djrum' }, + { url: 'https://benjamindamage.bandcamp.com/album/montreal-ep', + type: 'album', + name: 'Montreal EP', + imageUrl: 'https://f4.bcbits.com/img/a2262177785_16.jpg', + artist: 'Benjamin Damage' }, + { url: 'https://blondes.bandcamp.com/track/kdm-barker-baumecker-remix', + type: 'track', + name: 'KDM (Barker & Baumecker remix)', + imageUrl: 'https://f4.bcbits.com/img/a4008618888_16.jpg', + artist: 'Blondes' }, + { url: 'https://lostsoulsofsaturn.bandcamp.com/album/bint-el-khandaq-vs-mashrou-leila', + type: 'album', + name: 'Bint El Khandaq (vs Mashrou\' Leila)', + imageUrl: 'https://f4.bcbits.com/img/a2811752237_16.jpg', + artist: 'Lost Souls Of Saturn' }, + { url: 'https://lone.bandcamp.com/album/ambivert-tools-volume-two', + type: 'album', + name: 'Ambivert Tools Volume Two', + imageUrl: 'https://f4.bcbits.com/img/a0296687793_16.jpg', + artist: 'Lone' }, + { url: 'https://blondes.bandcamp.com/album/warmth', + type: 'album', + name: 'Warmth', + imageUrl: 'https://f4.bcbits.com/img/a2313765301_16.jpg', + artist: 'Blondes' }, + { url: 'https://unknownarchetype.bandcamp.com/album/into-ether', + type: 'album', + name: 'Into Ether', + imageUrl: 'https://f4.bcbits.com/img/a2044920027_16.jpg', + artist: 'Unknown Archetype' }, + { url: 'https://adakaleh.bandcamp.com/album/palatul-de-cle-tar', + type: 'album', + name: 'Palatul de cleßtar', + imageUrl: 'https://f4.bcbits.com/img/a3022230788_16.jpg', + artist: 'Ada Kaleh' }, + { url: 'https://michelemininni.bandcamp.com/album/rave-oscillations-vortex-stasi', + type: 'album', + name: 'Rave Oscillations / Vortex Stasi', + imageUrl: 'https://f4.bcbits.com/img/a2445110003_16.jpg', + artist: 'Michele Mininni' }, + { url: 'https://slackk.bandcamp.com/album/a-little-light', + type: 'album', + name: 'A Little Light', + imageUrl: 'https://f4.bcbits.com/img/a2384206037_16.jpg', + artist: 'Slackk' }, + { url: 'https://lone.bandcamp.com/album/ambivert-tools-volume-one', + type: 'album', + name: 'Ambivert Tools Volume One', + imageUrl: 'https://f4.bcbits.com/img/a0389879254_16.jpg', + artist: 'Lone' }, + { url: 'https://sportinglife.bandcamp.com/album/slam-dunk-remixes', + type: 'album', + name: 'Slam Dunk Remixes', + imageUrl: 'https://f4.bcbits.com/img/a2896007633_16.jpg', + artist: 'Sporting Life' }, + { url: 'https://spacedimensioncontroller.bandcamp.com/album/exostack', + type: 'album', + name: 'EXOSTACK', + imageUrl: 'https://f4.bcbits.com/img/a2211118179_16.jpg', + artist: 'Space Dimension Controller' }, + { url: 'https://talaboman.bandcamp.com/album/the-night-land', + type: 'album', + name: 'The Night Land', + imageUrl: 'https://f4.bcbits.com/img/a0709795804_16.jpg', + artist: 'Talaboman' }, + { url: 'https://paulwhite.bandcamp.com/album/accelerator', + type: 'album', + name: 'Accelerator', + imageUrl: 'https://f4.bcbits.com/img/a3525288854_16.jpg', + artist: 'Paul White ft Danny Brown' }, + { url: 'https://unknownarchetype.bandcamp.com/album/tripp-ep', + type: 'album', + name: 'TRIPP EP', + imageUrl: 'https://f4.bcbits.com/img/a0827482149_16.jpg', + artist: 'Unknown Archetype' }, + { url: 'https://sportinglife.bandcamp.com/album/slam-dunk-vinyl-lp', + type: 'album', + name: 'Slam Dunk - Vinyl LP', + imageUrl: 'https://f4.bcbits.com/img/a2750684373_16.jpg', + artist: 'Sporting Life' }, + { url: 'https://paulwhite.bandcamp.com/album/everything-youve-forgotten-free-beat-tape', + type: 'album', + name: 'Everything You\'ve Forgotten (Free Beat Tape)', + imageUrl: 'https://f4.bcbits.com/img/a0945396280_16.jpg', + artist: 'Paul White' }, + { url: 'https://randsrecords.bandcamp.com/album/meditation-will-manifest', + type: 'album', + name: 'Meditation Will Manifest', + imageUrl: 'https://f4.bcbits.com/img/a0983137742_16.jpg', + artist: 'Josh Wink' }, + { url: 'https://secondstoreyappleblim.bandcamp.com/album/gimme-6', + type: 'album', + name: 'Gimme 6', + imageUrl: 'https://f4.bcbits.com/img/a0962233606_16.jpg', + artist: 'Second Storey & Appleblim' }, + { url: 'https://sportinglife.bandcamp.com/album/slam-dunk-vol-iii', + type: 'album', + name: 'Slam Dunk Vol.III', + imageUrl: 'https://f4.bcbits.com/img/a3532028448_16.jpg', + artist: 'Sporting Life' }, + { url: 'https://struction.bandcamp.com/album/gef-ge', + type: 'album', + name: 'GefĂŒge', + imageUrl: 'https://f4.bcbits.com/img/a3602953469_16.jpg', + artist: 'Struction' }, + { url: 'https://sportinglife.bandcamp.com/album/slam-dunk-vol-ii', + type: 'album', + name: 'Slam Dunk Vol. II', + imageUrl: 'https://f4.bcbits.com/img/a4186689811_16.jpg', + artist: 'Sporting Life' }, + { url: 'https://sportinglife.bandcamp.com/album/slam-dunk-vol-i', + type: 'album', + name: 'Slam Dunk Vol. I', + imageUrl: 'https://f4.bcbits.com/img/a2825265641_16.jpg', + artist: 'Sporting Life' }, + { url: 'https://nonkeen.bandcamp.com/album/oddments-of-the-gamble', + type: 'album', + name: 'oddments of the gamble', + imageUrl: 'https://f4.bcbits.com/img/a1221269537_16.jpg', + artist: 'nonkeen' }, + { url: 'https://lakker.bandcamp.com/album/alex-smoke-remixes', + type: 'album', + name: 'Alex Smoke Remixes', + imageUrl: 'https://f4.bcbits.com/img/a0742598748_16.jpg', + artist: 'Lakker' }, + { url: 'https://lone.bandcamp.com/album/levitate', + type: 'album', + name: 'Levitate', + imageUrl: 'https://f4.bcbits.com/img/a3368931730_16.jpg', + artist: 'Lone' }, + { url: 'https://lakker.bandcamp.com/album/struggle-emerge', + type: 'album', + name: 'Struggle & Emerge', + imageUrl: 'https://f4.bcbits.com/img/a0074389183_16.jpg', + artist: 'Lakker' }, + { url: 'https://nonkeen.bandcamp.com/album/33-45', + type: 'album', + name: '33/45', + imageUrl: 'https://f4.bcbits.com/img/a0331869290_16.jpg', + artist: 'nonkeen' }, + { url: 'https://slackk.bandcamp.com/album/aviary-ep', + type: 'album', + name: 'Aviary EP', + imageUrl: 'https://f4.bcbits.com/img/a1674870329_16.jpg', + artist: 'Slackk' }, + { url: 'https://nonkeen.bandcamp.com/album/the-gamble', + type: 'album', + name: 'the gamble', + imageUrl: 'https://f4.bcbits.com/img/a0161412892_16.jpg', + artist: 'nonkeen' }, + { url: 'https://alexsmoke.bandcamp.com/album/love-over-will', + type: 'album', + name: 'Love Over Will', + imageUrl: 'https://f4.bcbits.com/img/a1635300453_16.jpg', + artist: 'Alex Smoke' }, + { url: 'https://bluedaisy.bandcamp.com/track/pure-anarchy', + type: 'track', + name: 'Pure Anarchy', + imageUrl: 'https://f4.bcbits.com/img/a3471736964_16.jpg', + artist: 'Blue Daisy' }, + { url: 'https://primitiveworld.bandcamp.com/album/purple-caps-ep', + type: 'album', + name: 'Purple Caps EP', + imageUrl: 'https://f4.bcbits.com/img/a1182531443_16.jpg', + artist: 'Primitive World' }, + { url: 'https://taleofus.bandcamp.com/album/north-star-silent-space', + type: 'album', + name: 'North Star / Silent Space', + imageUrl: 'https://f4.bcbits.com/img/a3260776828_16.jpg', + artist: 'Tale Of Us' }, + { url: 'https://moire.bandcamp.com/album/gel-ep', + type: 'album', + name: 'Gel EP', + imageUrl: 'https://f4.bcbits.com/img/a0481708077_16.jpg', + artist: 'MoirĂ©' }, + { url: 'https://nicolasjaar.bandcamp.com/album/fight', + type: 'album', + name: 'Fight', + imageUrl: 'https://f4.bcbits.com/img/a1781921428_16.jpg', + artist: 'Nicolas Jaar' }, + { url: 'https://bluedaisy.bandcamp.com/album/darker-than-blue', + type: 'album', + name: 'Darker Than Blue', + imageUrl: 'https://f4.bcbits.com/img/a0003951232_16.jpg', + artist: 'Blue Daisy' }, + { url: 'https://sportinglife.bandcamp.com/album/55-5s', + type: 'album', + name: '55 5\'s', + imageUrl: 'https://f4.bcbits.com/img/a0558215035_16.jpg', + artist: 'Sporting Life' }, + { url: 'https://lakker.bandcamp.com/album/tundra-remixed', + type: 'album', + name: 'Tundra Remixed', + imageUrl: 'https://f4.bcbits.com/img/a4192171830_16.jpg', + artist: 'Lakker' }, + { url: 'https://lone.bandcamp.com/album/lemurian-2015-re-issue', + type: 'album', + name: 'Lemurian (2015 Re-Issue)', + imageUrl: 'https://f4.bcbits.com/img/a1897898710_16.jpg', + artist: 'Lone' }, + { url: 'https://slackk.bandcamp.com/album/backwards-light-ep', + type: 'album', + name: 'Backwards Light EP', + imageUrl: 'https://f4.bcbits.com/img/a2575436869_16.jpg', + artist: 'Slackk' }, + { url: 'https://lakker.bandcamp.com/album/tundra', + type: 'album', + name: 'Tundra', + imageUrl: 'https://f4.bcbits.com/img/a2862016036_16.jpg', + artist: 'Lakker' }, + { url: 'https://secondstoreyappleblim.bandcamp.com/album/also', + type: 'album', + name: 'ALSO', + imageUrl: 'https://f4.bcbits.com/img/a2896003816_16.jpg', + artist: 'Second Storey & Appleblim' }, + { url: 'https://tessela.bandcamp.com/album/bottom-out', + type: 'album', + name: 'Bottom Out', + imageUrl: 'https://f4.bcbits.com/img/a2168663857_16.jpg', + artist: 'Tessela' }, + ... 69 more items ] + diff --git a/examples/getDiscoverOptions.js b/examples/getDiscoverOptions.js new file mode 100644 index 0000000..df5e318 --- /dev/null +++ b/examples/getDiscoverOptions.js @@ -0,0 +1,6 @@ +const bcfetch = require('../'); +const util = require('util'); + +bcfetch.getDiscoverOptions().then( results => { + console.log(util.inspect(results, false, null, false)); +}); \ No newline at end of file diff --git a/examples/getDiscoverOptions_output.txt b/examples/getDiscoverOptions_output.txt new file mode 100644 index 0000000..fcaaf6f --- /dev/null +++ b/examples/getDiscoverOptions_output.txt @@ -0,0 +1,350 @@ +{ genres: + [ { value: 'all', name: 'all' }, + { value: 'electronic', name: 'electronic' }, + { value: 'rock', name: 'rock' }, + { value: 'metal', name: 'metal' }, + { value: 'alternative', name: 'alternative' }, + { value: 'hip-hop-rap', name: 'hip-hop/rap' }, + { value: 'experimental', name: 'experimental' }, + { value: 'punk', name: 'punk' }, + { value: 'folk', name: 'folk' }, + { value: 'pop', name: 'pop' }, + { value: 'ambient', name: 'ambient' }, + { value: 'soundtrack', name: 'soundtrack' }, + { value: 'world', name: 'world' }, + { value: 'jazz', name: 'jazz' }, + { value: 'acoustic', name: 'acoustic' }, + { value: 'funk', name: 'funk' }, + { value: 'r-b-soul', name: 'r&b/soul' }, + { value: 'devotional', name: 'devotional' }, + { value: 'classical', name: 'classical' }, + { value: 'reggae', name: 'reggae' }, + { value: 'podcasts', name: 'podcasts' }, + { value: 'country', name: 'country' }, + { value: 'spoken-word', name: 'spoken word' }, + { value: 'comedy', name: 'comedy' }, + { value: 'blues', name: 'blues' }, + { value: 'kids', name: 'kids' }, + { value: 'audiobooks', name: 'audiobooks' }, + { value: 'latin', name: 'latin' } ], + subgenres: + [ metal: [ { value: 'all-metal', name: 'all metal' }, + { value: 'hardcore', name: 'hardcore' }, + { value: 'black-metal', name: 'black metal' }, + { value: 'death-metal', name: 'death metal' }, + { value: 'thrash-metal', name: 'thrash metal' }, + { value: 'grindcore', name: 'grindcore' }, + { value: 'doom', name: 'doom' }, + { value: 'post-hardcore', name: 'post hardcore' }, + { value: 'progressive-metal', name: 'progressive metal' }, + { value: 'metalcore', name: 'metalcore' }, + { value: 'sludge-metal', name: 'sludge metal' }, + { value: 'heavy-metal', name: 'heavy metal' }, + { value: 'deathcore', name: 'deathcore' }, + { value: 'noise', name: 'noise' } ], + country: [ { value: 'all-country', name: 'all country' }, + { value: 'bluegrass', name: 'bluegrass' }, + { value: 'country-rock', name: 'country rock' }, + { value: 'americana', name: 'americana' }, + { value: 'country-folk', name: 'country folk' }, + { value: 'alt-country', name: 'alt-country' }, + { value: 'country-blues', name: 'country blues' }, + { value: 'western', name: 'western' }, + { value: 'singer-songwriter', name: 'singer-songwriter' }, + { value: 'outlaw', name: 'outlaw' }, + { value: 'honky-tonk', name: 'honky-tonk' }, + { value: 'roots', name: 'roots' }, + { value: 'hillbilly', name: 'hillbilly' } ], + blues: [ { value: 'all-blues', name: 'all blues' }, + { value: 'rhythm-blues', name: 'rhythm & blues' }, + { value: 'blues-rock', name: 'blues rock' }, + { value: 'country-blues', name: 'country blues' }, + { value: 'boogie-woogie', name: 'boogie-woogie' }, + { value: 'delta-blues', name: 'delta blues' }, + { value: 'americana', name: 'americana' }, + { value: 'electric-blues', name: 'electric blues' }, + { value: 'gospel', name: 'gospel' }, + { value: 'bluegrass', name: 'bluegrass' } ], + ambient: [ { value: 'all-ambient', name: 'all ambient' }, + { value: 'chill-out', name: 'chill-out' }, + { value: 'drone', name: 'drone' }, + { value: 'dark-ambient', name: 'dark ambient' }, + { value: 'electronic', name: 'electronic' }, + { value: 'soundscapes', name: 'soundscapes' }, + { value: 'field-recordings', name: 'field recordings' }, + { value: 'atmospheric', name: 'atmospheric' }, + { value: 'meditation', name: 'meditation' }, + { value: 'noise', name: 'noise' }, + { value: 'new-age', name: 'new age' }, + { value: 'idm', name: 'idm' }, + { value: 'industrial', name: 'industrial' } ], + reggae: [ { value: 'all-reggae', name: 'all reggae' }, + { value: 'dub', name: 'dub' }, + { value: 'ska', name: 'ska' }, + { value: 'roots', name: 'roots' }, + { value: 'dancehall', name: 'dancehall' }, + { value: 'rocksteady', name: 'rocksteady' }, + { value: 'ragga', name: 'ragga' }, + { value: 'lovers-rock', name: 'lovers rock' } ], + alternative: [ { value: 'all-alternative', name: 'all alternative' }, + { value: 'indie-rock', name: 'indie rock' }, + { value: 'industrial', name: 'industrial' }, + { value: 'shoegaze', name: 'shoegaze' }, + { value: 'grunge', name: 'grunge' }, + { value: 'goth', name: 'goth' }, + { value: 'dream-pop', name: 'dream pop' }, + { value: 'emo', name: 'emo' }, + { value: 'math-rock', name: 'math rock' }, + { value: 'britpop', name: 'britpop' }, + { value: 'jangle-pop', name: 'jangle pop' } ], + acoustic: [ { value: 'all-acoustic', name: 'all acoustic' }, + { value: 'folk', name: 'folk' }, + { value: 'singer-songwriter', name: 'singer-songwriter' }, + { value: 'rock', name: 'rock' }, + { value: 'pop', name: 'pop' }, + { value: 'guitar', name: 'guitar' }, + { value: 'americana', name: 'americana' }, + { value: 'electro-acoustic', name: 'electro-acoustic' }, + { value: 'instrumental', name: 'instrumental' }, + { value: 'piano', name: 'piano' }, + { value: 'bluegrass', name: 'bluegrass' }, + { value: 'roots', name: 'roots' } ], + world: [ { value: 'all-world', name: 'all world' }, + { value: 'latin', name: 'latin' }, + { value: 'roots', name: 'roots' }, + { value: 'african', name: 'african' }, + { value: 'tropical', name: 'tropical' }, + { value: 'tribal', name: 'tribal' }, + { value: 'brazilian', name: 'brazilian' }, + { value: 'celtic', name: 'celtic' }, + { value: 'world-fusion', name: 'world fusion' }, + { value: 'cumbia', name: 'cumbia' }, + { value: 'gypsy', name: 'gypsy' }, + { value: 'new-age', name: 'new age' }, + { value: 'balkan', name: 'balkan' }, + { value: 'reggaeton', name: 'reggaeton' } ], + electronic: [ { value: 'all-electronic', name: 'all electronic' }, + { value: 'house', name: 'house' }, + { value: 'electronica', name: 'electronica' }, + { value: 'downtempo', name: 'downtempo' }, + { value: 'techno', name: 'techno' }, + { value: 'electro', name: 'electro' }, + { value: 'dubstep', name: 'dubstep' }, + { value: 'beats', name: 'beats' }, + { value: 'dance', name: 'dance' }, + { value: 'idm', name: 'idm' }, + { value: 'drum-bass', name: 'drum & bass' }, + { value: 'breaks', name: 'breaks' }, + { value: 'trance', name: 'trance' }, + { value: 'glitch', name: 'glitch' }, + { value: 'chiptune', name: 'chiptune' }, + { value: 'chillwave', name: 'chillwave' }, + { value: 'dub', name: 'dub' }, + { value: 'edm', name: 'edm' }, + { value: 'instrumental', name: 'instrumental' }, + { value: 'witch-house', name: 'witch house' }, + { value: 'garage', name: 'garage' }, + { value: 'juke', name: 'juke' }, + { value: 'footwork', name: 'footwork' }, + { value: 'vaporwave', name: 'vaporwave' }, + { value: 'synthwave', name: 'synthwave' } ], + devotional: [ { value: 'all-devotional', name: 'all devotional' }, + { value: 'christian', name: 'christian' }, + { value: 'gospel', name: 'gospel' }, + { value: 'meditation', name: 'meditation' }, + { value: 'spiritual', name: 'spiritual' }, + { value: 'worship', name: 'worship' }, + { value: 'inspirational', name: 'inspirational' } ], + punk: [ { value: 'all-punk', name: 'all punk' }, + { value: 'hardcore-punk', name: 'hardcore punk' }, + { value: 'garage', name: 'garage' }, + { value: 'pop-punk', name: 'pop punk' }, + { value: 'punk-rock', name: 'punk rock' }, + { value: 'post-punk', name: 'post-punk' }, + { value: 'post-hardcore', name: 'post-hardcore' }, + { value: 'thrash', name: 'thrash' }, + { value: 'crust-punk', name: 'crust punk' }, + { value: 'folk-punk', name: 'folk punk' }, + { value: 'emo', name: 'emo' }, + { value: 'ska', name: 'ska' }, + { value: 'no-wave', name: 'no wave' } ], + kids: [ { value: 'all-kids', name: 'all kids' }, + { value: 'family-music', name: 'family music' }, + { value: 'educational', name: 'educational' }, + { value: 'music-therapy', name: 'music therapy' }, + { value: 'lullaby', name: 'lullaby' }, + { value: 'baby', name: 'baby' } ], + comedy: [ { value: 'all-comedy', name: 'all comedy' }, + { value: 'improv', name: 'improv' }, + { value: 'stand-up', name: 'stand-up' } ], + rock: [ { value: 'all-rock', name: 'all rock' }, + { value: 'indie', name: 'indie' }, + { value: 'prog-rock', name: 'prog rock' }, + { value: 'post-rock', name: 'post-rock' }, + { value: 'rock-roll', name: 'rock & roll' }, + { value: 'psychedelic-rock', name: 'psychedelic rock' }, + { value: 'hard-rock', name: 'hard rock' }, + { value: 'garage-rock', name: 'garage rock' }, + { value: 'surf-rock', name: 'surf rock' }, + { value: 'instrumental', name: 'instrumental' }, + { value: 'math-rock', name: 'math rock' }, + { value: 'rockabilly', name: 'rockabilly' } ], + classical: [ { value: 'all-classical', name: 'all classical' }, + { value: 'orchestral', name: 'orchestral' }, + { value: 'neo-classical', name: 'neo-classical' }, + { value: 'chamber-music', name: 'chamber music' }, + { value: 'classical-piano', name: 'classical piano' }, + { value: 'contemporary-classical', + name: 'contemporary classical' }, + { value: 'baroque', name: 'baroque' }, + { value: 'opera', name: 'opera' }, + { value: 'choral', name: 'choral' }, + { value: 'modern-classical', name: 'modern classical' }, + { value: 'avant-garde', name: 'avant garde' } ], + latin: [ { value: 'all-latin', name: 'all latin' }, + { value: 'brazilian', name: 'brazilian' }, + { value: 'cumbia', name: 'cumbia' }, + { value: 'tango', name: 'tango' }, + { value: 'latin-rock', name: 'latin rock' }, + { value: 'flamenco', name: 'flamenco' }, + { value: 'salsa', name: 'salsa' }, + { value: 'reggaeton', name: 'reggaeton' }, + { value: 'merengue', name: 'merengue' }, + { value: 'bolero', name: 'bolero' }, + { value: 'mĂ©xico-d.f.', name: 'mĂ©xico d.f.' }, + { value: 'bachata', name: 'bachata' } ], + folk: [ { value: 'all-folk', name: 'all folk' }, + { value: 'singer-songwriter', name: 'singer-songwriter' }, + { value: 'folk-rock', name: 'folk rock' }, + { value: 'indie-folk', name: 'indie folk' }, + { value: 'pop-folk', name: 'pop folk' }, + { value: 'traditional', name: 'traditional' }, + { value: 'experimental-folk', name: 'experimental folk' }, + { value: 'roots', name: 'roots' } ], + jazz: [ { value: 'all-jazz', name: 'all jazz' }, + { value: 'fusion', name: 'fusion' }, + { value: 'big-band', name: 'big band' }, + { value: 'nu-jazz', name: 'nu jazz' }, + { value: 'modern-jazz', name: 'modern jazz' }, + { value: 'swing', name: 'swing' }, + { value: 'free-jazz', name: 'free jazz' }, + { value: 'soul-jazz', name: 'soul jazz' }, + { value: 'latin-jazz', name: 'latin jazz' }, + { value: 'vocal-jazz', name: 'vocal jazz' }, + { value: 'bebop', name: 'bebop' }, + { value: 'spiritual-jazz', name: 'spiritual jazz' } ], + 'spoken-word': [ { value: 'all-spoken-word', name: 'all spoken word' }, + { value: 'poetry', name: 'poetry' }, + { value: 'inspirational', name: 'inspirational' }, + { value: 'storytelling', name: 'storytelling' }, + { value: 'self-help', name: 'self-help' } ], + 'hip-hop-rap': [ { value: 'all-hip-hop-rap', name: 'all hip-hop/rap' }, + { value: 'rap', name: 'rap' }, + { value: 'underground-hip-hop', name: 'underground hip-hop' }, + { value: 'instrumental-hip-hop', name: 'instrumental hip-hop' }, + { value: 'trap', name: 'trap' }, + { value: 'conscious-hip-hop', name: 'conscious hip-hop' }, + { value: 'boom-bap', name: 'boom-bap' }, + { value: 'beat-tape', name: 'beat-tape' }, + { value: 'hardcore', name: 'hardcore' }, + { value: 'grime', name: 'grime' } ], + experimental: [ { value: 'all-experimental', name: 'all experimental' }, + { value: 'noise', name: 'noise' }, + { value: 'drone', name: 'drone' }, + { value: 'avant-garde', name: 'avant garde' }, + { value: 'experimental-rock', name: 'experimental rock' }, + { value: 'improvisation', name: 'improvisation' }, + { value: 'sound-art', name: 'sound art' }, + { value: 'musique-concrete', name: 'musique concrete' } ], + 'r-b-soul': [ { value: 'all-r-b-soul', name: 'all r&b/soul' }, + { value: 'soul', name: 'soul' }, + { value: 'r-b', name: 'r&b' }, + { value: 'neo-soul', name: 'neo-soul' }, + { value: 'gospel', name: 'gospel' }, + { value: 'contemporary-r-b', name: 'contemporary r&b' }, + { value: 'motown', name: 'motown' }, + { value: 'urban', name: 'urban' } ], + pop: [ { value: 'all-pop', name: 'all pop' }, + { value: 'indie-pop', name: 'indie pop' }, + { value: 'synth-pop', name: 'synth pop' }, + { value: 'power-pop', name: 'power pop' }, + { value: 'new-wave', name: 'new wave' }, + { value: 'dream-pop', name: 'dream pop' }, + { value: 'noise-pop', name: 'noise pop' }, + { value: 'experimental-pop', name: 'experimental pop' }, + { value: 'electro-pop', name: 'electro pop' }, + { value: 'adult-contemporary', name: 'adult contemporary' }, + { value: 'jangle-pop', name: 'jangle pop' }, + { value: 'j-pop', name: 'j-pop' } ], + funk: [ { value: 'all-funk', name: 'all funk' }, + { value: 'funk-jam', name: 'funk jam' }, + { value: 'deep-funk', name: 'deep funk' }, + { value: 'funk-rock', name: 'funk rock' }, + { value: 'jazz-funk', name: 'jazz funk' }, + { value: 'boogie', name: 'boogie' }, + { value: 'g-funk', name: 'g-funk' }, + { value: 'rare-groove', name: 'rare groove' }, + { value: 'electro', name: 'electro' }, + { value: 'go-go', name: 'go-go' } ], + soundtrack: [ { value: 'all-soundtrack', name: 'all soundtrack' }, + { value: 'film-music', name: 'film music' }, + { value: 'video-game-music', name: 'video game music' } ] ], + sortBys: + [ { value: 'top', name: 'best-selling' }, + { value: 'new', name: 'new arrivals' }, + { value: 'rec', name: 'artist-recommended' } ], + artistRecommendationTypes: + [ { value: 'most', name: 'most' }, + { value: 'latest', name: 'latest' } ], + locations: + [ { value: '0', name: 'artists from anywhere' }, + { value: '2759794', name: 'amsterdam' }, + { value: '4180439', name: 'atlanta' }, + { value: '4671654', name: 'austin' }, + { value: '4347778', name: 'baltimore' }, + { value: '2950159', name: 'berlin' }, + { value: '4930956', name: 'boston' }, + { value: '5110302', name: 'brooklyn' }, + { value: '3435907', name: 'buenos aires' }, + { value: '4887398', name: 'chicago' }, + { value: '5419384', name: 'denver' }, + { value: '4990729', name: 'detroit' }, + { value: '2964574', name: 'dublin' }, + { value: '3333231', name: 'glasgow' }, + { value: '2643743', name: 'london' }, + { value: '5368361', name: 'los angeles' }, + { value: '3117735', name: 'madrid' }, + { value: '2643123', name: 'manchester' }, + { value: '2158177', name: 'melbourne' }, + { value: '3530597', name: 'mexico city' }, + { value: '4164138', name: 'miami' }, + { value: '5037649', name: 'minneapolis' }, + { value: '6077243', name: 'montreal' }, + { value: '4644585', name: 'nashville' }, + { value: '4335045', name: 'new orleans' }, + { value: '5128581', name: 'new york city' }, + { value: '5378538', name: 'oakland' }, + { value: '2988507', name: 'paris' }, + { value: '4560349', name: 'philadelphia' }, + { value: '5746545', name: 'portland' }, + { value: '5391959', name: 'san francisco' }, + { value: '5809844', name: 'seattle' }, + { value: '2147714', name: 'sydney' }, + { value: '6167865', name: 'toronto' }, + { value: '6173331', name: 'vancouver' }, + { value: '4140963', name: 'washington, dc' } ], + formats: + [ { value: 'all', name: 'any format' }, + { value: 'digital', name: 'digital' }, + { value: 'vinyl', name: 'vinyl' }, + { value: 'cd', name: 'compact disc' }, + { value: 'cassette', name: 'cassette' } ], + times: + [ { value: -1, name: 'today', title: 'last 24 hours' }, + { value: 0, name: 'this week', title: 'week of Jan 17' }, + { value: 648, name: 'last week', title: 'week of Jan 10' }, + { value: 647, name: '2 weeks ago', title: 'week of Jan 03' }, + { value: 646, name: '3 weeks ago', title: 'week of Dec 27' }, + { value: 645, name: '4 weeks ago', title: 'week of Dec 20' }, + { value: 644, name: '5 weeks ago', title: 'week of Dec 13' }, + { value: 643, name: '6 weeks ago', title: 'week of Dec 06' } ] } diff --git a/examples/getImageFormats.js b/examples/getImageFormats.js new file mode 100644 index 0000000..8775168 --- /dev/null +++ b/examples/getImageFormats.js @@ -0,0 +1,13 @@ +const bcfetch = require('../'); + +bcfetch.getImageFormats('album').then( results => { + console.log('Album image formats:'); + console.log(results); + console.log(); +}); + +bcfetch.getImageFormats('artist').then( results => { + console.log('Artist image formats:'); + console.log(results); + console.log(); +}); \ No newline at end of file diff --git a/examples/getImageFormats_output.txt b/examples/getImageFormats_output.txt new file mode 100644 index 0000000..40ca106 --- /dev/null +++ b/examples/getImageFormats_output.txt @@ -0,0 +1,172 @@ +Artist image formats: +[ { file_format: 'JPEG', + height: 1024, + width: 1024, + name: 'bio_screen', + id: 20, + resize_algo: 'fit' }, + { file_format: 'JPEG', + height: 180, + width: 120, + name: 'bio_thumb', + id: 21, + resize_algo: 'fit' }, + { file_format: 'JPEG', + height: 25, + width: 25, + name: 'bio_navbar', + id: 22, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 300, + width: 300, + name: 'bio_phone', + id: 23, + resize_algo: 'fit' }, + { file_format: 'JPEG', + height: 300, + width: 300, + name: 'bio_licensing', + id: 24, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 700, + quality: 70, + width: 700, + name: 'bio_app', + id: 25, + resize_algo: 'fit' }, + { file_format: 'JPEG', + height: 600, + width: 800, + name: 'bio_subscribe', + id: 26, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 402, + width: 715, + name: 'bio_subscribe2', + id: 27, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 432, + width: 768, + name: 'bio_featured', + id: 28, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 75, + width: 100, + name: 'bio_autocomplete', + id: 29, + resize_algo: 'thumb' } ] + +Album image formats: +[ { file_format: 'JPEG', + height: 350, + width: 350, + name: 'art_thumb', + id: 2, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 100, + width: 100, + name: 'art_thumbthumb', + id: 3, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 300, + width: 300, + name: 'art_embedded_metadata', + id: 4, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 700, + width: 700, + name: 'art_embedded_metadata_large', + id: 5, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 100, + width: 100, + name: 'art_embedded_player', + id: 6, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 150, + width: 150, + name: 'art_embedded_player_large', + id: 7, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 124, + width: 124, + name: 'art_tags', + id: 8, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 210, + width: 210, + name: 'art_tags_large', + id: 9, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 172, + width: 172, + name: 'art_tag_search', + id: 11, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 138, + width: 138, + name: 'art_artist_index', + id: 12, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 380, + width: 380, + name: 'art_solo_feature', + id: 13, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 368, + width: 368, + name: 'art_feature', + id: 14, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 135, + width: 135, + name: 'art_feed_new_release', + id: 15, + resize_algo: 'thumb' }, + { file_format: 'JPEG', + height: 700, + quality: 70, + width: 700, + minsize: { format: 5, size: 30000 }, + name: 'art_app_large', + id: 16, + resize_algo: 'thumb' }, + { anim_ok: true, + file_format: 'JPEG', + height: 350, + width: 350, + name: 'art_thumb_anim_ok', + id: 67, + resize_algo: 'thumb' }, + { anim_ok: true, + file_format: 'JPEG', + height: 210, + width: 210, + name: 'art_tags_large_anim_ok', + id: 68, + resize_algo: 'thumb' }, + { anim_ok: true, + file_format: 'JPEG', + height: 700, + width: 700, + name: 'art_embedded_metadata_large_anim_ok', + id: 69, + resize_algo: 'thumb' } ] + diff --git a/examples/getLabelArtists.js b/examples/getLabelArtists.js new file mode 100644 index 0000000..3d08eca --- /dev/null +++ b/examples/getLabelArtists.js @@ -0,0 +1,12 @@ +const bcfetch = require('../'); +const util = require('util'); + +const labelUrl = 'https://daretocarerecords.bandcamp.com'; + +const options = { + imageFormat: 'art_app_large', +} + +bcfetch.getLabelArtists(labelUrl, options).then( results => { + console.log(util.inspect(results, false, null, false)); +}); \ No newline at end of file diff --git a/examples/getLabelArtists_output.txt b/examples/getLabelArtists_output.txt new file mode 100644 index 0000000..67fd0b4 --- /dev/null +++ b/examples/getLabelArtists_output.txt @@ -0,0 +1,104 @@ +[ { name: 'CƓur de pirate', + url: 'https://musique.coeurdepirate.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0021821004_16.jpg' }, + { name: 'The Blaze Velluto Collection', + url: 'https://theblazevellutocollection.bandcamp.com', + location: 'QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0022085949_16.jpg' }, + { name: 'KROY', + url: 'https://kroy.bandcamp.com', + location: 'Montreal, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0017735723_16.jpg' }, + { name: 'Organ Mood', + url: 'https://organmood.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0016365385_16.jpg' }, + { name: 'CHOCOLAT', + url: 'https://chocolatmtl.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0011527165_16.jpg' }, + { name: 'feu doux', + url: 'https://feudoux.bandcamp.com', + location: 'Montreal, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0016651601_16.jpg' }, + { name: 'Hanorah', + url: 'https://hanorah.ca', + location: 'Montreal, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0015375929_16.jpg' }, + { name: 'Ellemetue', + url: 'https://ellemetue.bandcamp.com', + location: 'Montreal, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0012637987_16.jpg' }, + { name: 'Les Marmottes Aplaties', + url: 'https://lesmarmottesaplaties.bandcamp.com', + location: 'Montreal, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0012723168_16.jpg' }, + { name: 'Game of Death', + url: 'https://gameofdeath.bandcamp.com', + location: 'Montreal, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0012274465_16.jpg' }, + { name: 'Socalled', + url: 'https://socalledmtl.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0011527257_16.jpg' }, + { name: 'Kandle', + url: 'https://kandle.bandcamp.com', + location: 'Vancouver, British Columbia', + imageUrl: 'https://f4.bcbits.com/img/0013923647_16.jpg' }, + { name: 'Fontarabie', + url: 'https://fontarabie.bandcamp.com', + location: 'Montreal, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004132067_16.jpg' }, + { name: 'We Are Wolves', + url: 'https://wearewolves.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0017252056_16.jpg' }, + { name: 'Pawa Up First', + url: 'https://pawaupfirst.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0001430480_16.jpg' }, + { name: 'En terrains connus - Trame sonore du film', + url: 'https://enterrainsconnus.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004131874_16.jpg' }, + { name: 'Marie-Jo ThĂ©rio', + url: 'https://marie-jotherio.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004131992_16.jpg' }, + { name: 'Sevensproject', + url: 'https://sevensproject.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004131879_16.jpg' }, + { name: 'The Last Assassins', + url: 'https://thelastassassins.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004131899_16.jpg' }, + { name: 'La descente du coude', + url: 'https://ladescenteducoude.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004131700_16.jpg' }, + { name: 'CLAASS', + url: 'https://claass.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004131884_16.jpg' }, + { name: 'MontrĂ©al Spirit', + url: 'https://montrealspirit.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004132000_16.jpg' }, + { name: 'The Fallout Project', + url: 'https://thefalloutproject.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004131966_16.jpg' }, + { name: 'Early Summer Campfire Songs', + url: 'https://earlysummercampfiresongs.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004131983_16.jpg' }, + { name: 'Armistice', + url: 'https://armistice.bandcamp.com', + location: 'MontrĂ©al, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004131888_16.jpg' }, + { name: 'Malajube', + url: 'https://malajube.bandcamp.com', + location: 'Montreal, QuĂ©bec', + imageUrl: 'https://f4.bcbits.com/img/0004163029_16.jpg' } ] diff --git a/examples/getTags.js b/examples/getTags.js new file mode 100644 index 0000000..21bd7ed --- /dev/null +++ b/examples/getTags.js @@ -0,0 +1,6 @@ +const bcfetch = require('../'); +const util = require('util'); + +bcfetch.getTags().then( results => { + console.log(util.inspect(results, false, null, false)); +}); \ No newline at end of file diff --git a/examples/getTags_output.txt b/examples/getTags_output.txt new file mode 100644 index 0000000..a136fd6 --- /dev/null +++ b/examples/getTags_output.txt @@ -0,0 +1,259 @@ +{ tags: + [ { name: 'electronic', + url: 'https://bandcamp.com/tag/electronic' }, + { name: 'experimental', + url: 'https://bandcamp.com/tag/experimental' }, + { name: 'rock', url: 'https://bandcamp.com/tag/rock' }, + { name: 'alternative', + url: 'https://bandcamp.com/tag/alternative' }, + { name: 'hip-hop/rap', + url: 'https://bandcamp.com/tag/hip-hop-rap' }, + { name: 'ambient', url: 'https://bandcamp.com/tag/ambient' }, + { name: 'metal', url: 'https://bandcamp.com/tag/metal' }, + { name: 'punk', url: 'https://bandcamp.com/tag/punk' }, + { name: 'indie', url: 'https://bandcamp.com/tag/indie' }, + { name: 'noise', url: 'https://bandcamp.com/tag/noise' }, + { name: 'ambient', url: 'https://bandcamp.com/tag/ambient' }, + { name: 'techno', url: 'https://bandcamp.com/tag/techno' }, + { name: 'pop', url: 'https://bandcamp.com/tag/pop' }, + { name: 'indie rock', + url: 'https://bandcamp.com/tag/indie-rock' }, + { name: 'pop', url: 'https://bandcamp.com/tag/pop' }, + { name: 'instrumental', + url: 'https://bandcamp.com/tag/instrumental' }, + { name: 'hip hop', url: 'https://bandcamp.com/tag/hip-hop' }, + { name: 'experimental', + url: 'https://bandcamp.com/tag/experimental' }, + { name: 'electronic', + url: 'https://bandcamp.com/tag/electronic' }, + { name: 'rock', url: 'https://bandcamp.com/tag/rock' }, + { name: 'acoustic', url: 'https://bandcamp.com/tag/acoustic' }, + { name: 'folk', url: 'https://bandcamp.com/tag/folk' }, + { name: 'rap', url: 'https://bandcamp.com/tag/rap' }, + { name: 'drone', url: 'https://bandcamp.com/tag/drone' }, + { name: 'folk', url: 'https://bandcamp.com/tag/folk' }, + { name: 'electronica', + url: 'https://bandcamp.com/tag/electronica' }, + { name: 'psychedelic', + url: 'https://bandcamp.com/tag/psychedelic' }, + { name: 'house', url: 'https://bandcamp.com/tag/house' }, + { name: 'singer-songwriter', + url: 'https://bandcamp.com/tag/singer-songwriter' }, + { name: 'hardcore', url: 'https://bandcamp.com/tag/hardcore' }, + { name: 'lo-fi', url: 'https://bandcamp.com/tag/lo-fi' }, + { name: 'industrial', + url: 'https://bandcamp.com/tag/industrial' }, + { name: 'jazz', url: 'https://bandcamp.com/tag/jazz' }, + { name: 'dark ambient', + url: 'https://bandcamp.com/tag/dark-ambient' }, + { name: 'alternative rock', + url: 'https://bandcamp.com/tag/alternative-rock' }, + { name: 'jazz', url: 'https://bandcamp.com/tag/jazz' }, + { name: 'punk', url: 'https://bandcamp.com/tag/punk' }, + { name: 'hip-hop', url: 'https://bandcamp.com/tag/hip-hop' }, + { name: 'experimental electronic', + url: 'https://bandcamp.com/tag/experimental-electronic' }, + { name: 'indie pop', url: 'https://bandcamp.com/tag/indie-pop' }, + { name: 'world', url: 'https://bandcamp.com/tag/world' }, + { name: 'beats', url: 'https://bandcamp.com/tag/beats' }, + { name: 'electro', url: 'https://bandcamp.com/tag/electro' }, + { name: 'black metal', + url: 'https://bandcamp.com/tag/black-metal' }, + { name: 'soundtrack', + url: 'https://bandcamp.com/tag/soundtrack' }, + { name: 'post-rock', url: 'https://bandcamp.com/tag/post-rock' }, + { name: 'lofi', url: 'https://bandcamp.com/tag/lofi' }, + { name: 'techno', url: 'https://bandcamp.com/tag/techno' }, + { name: 'acoustic', url: 'https://bandcamp.com/tag/acoustic' }, + { name: 'punk rock', url: 'https://bandcamp.com/tag/punk-rock' }, + { name: 'soul', url: 'https://bandcamp.com/tag/soul' }, + { name: 'alternative', + url: 'https://bandcamp.com/tag/alternative' }, + { name: 'post-punk', url: 'https://bandcamp.com/tag/post-punk' }, + { name: 'shoegaze', url: 'https://bandcamp.com/tag/shoegaze' }, + { name: 'house', url: 'https://bandcamp.com/tag/house' }, + { name: 'soundtrack', + url: 'https://bandcamp.com/tag/soundtrack' }, + { name: 'deep house', + url: 'https://bandcamp.com/tag/deep-house' }, + { name: 'death metal', + url: 'https://bandcamp.com/tag/death-metal' }, + { name: 'downtempo', url: 'https://bandcamp.com/tag/downtempo' }, + { name: 'funk', url: 'https://bandcamp.com/tag/funk' }, + { name: 'dance', url: 'https://bandcamp.com/tag/dance' }, + { name: 'indie', url: 'https://bandcamp.com/tag/indie' }, + { name: 'avant-garde', + url: 'https://bandcamp.com/tag/avant-garde' }, + { name: 'blues', url: 'https://bandcamp.com/tag/blues' }, + { name: 'minimal', url: 'https://bandcamp.com/tag/minimal' }, + { name: 'idm', url: 'https://bandcamp.com/tag/idm' }, + { name: 'progressive', + url: 'https://bandcamp.com/tag/progressive' }, + { name: 'vaporwave', url: 'https://bandcamp.com/tag/vaporwave' }, + { name: 'emo', url: 'https://bandcamp.com/tag/emo' }, + { name: 'improvisation', + url: 'https://bandcamp.com/tag/improvisation' }, + { name: 'dub', url: 'https://bandcamp.com/tag/dub' }, + { name: 'trap', url: 'https://bandcamp.com/tag/trap' }, + { name: 'synthpop', url: 'https://bandcamp.com/tag/synthpop' }, + { name: 'synthwave', url: 'https://bandcamp.com/tag/synthwave' }, + { name: 'underground', + url: 'https://bandcamp.com/tag/underground' }, + { name: 'garage', url: 'https://bandcamp.com/tag/garage' }, + { name: 'indie folk', + url: 'https://bandcamp.com/tag/indie-folk' }, + { name: 'hip hop', url: 'https://bandcamp.com/tag/hip-hop' }, + { name: 'underground hip hop', + url: 'https://bandcamp.com/tag/underground-hip-hop' }, + { name: 'drum & bass', + url: 'https://bandcamp.com/tag/drum-bass' }, + { name: 'synth', url: 'https://bandcamp.com/tag/synth' }, + { name: 'folk rock', url: 'https://bandcamp.com/tag/folk-rock' }, + { name: 'r&b', url: 'https://bandcamp.com/tag/r-b' }, + { name: 'rap', url: 'https://bandcamp.com/tag/rap' }, + { name: 'dubstep', url: 'https://bandcamp.com/tag/dubstep' }, + { name: 'metal', url: 'https://bandcamp.com/tag/metal' }, + { name: 'piano', url: 'https://bandcamp.com/tag/piano' }, + { name: 'pop rock', url: 'https://bandcamp.com/tag/pop-rock' }, + { name: 'americana', url: 'https://bandcamp.com/tag/americana' }, + { name: 'ambient electronic', + url: 'https://bandcamp.com/tag/ambient-electronic' }, + { name: 'instrumental hip-hop', + url: 'https://bandcamp.com/tag/instrumental-hip-hop' }, + { name: 'chillout', url: 'https://bandcamp.com/tag/chillout' }, + { name: 'funk', url: 'https://bandcamp.com/tag/funk' }, + { name: 'guitar', url: 'https://bandcamp.com/tag/guitar' }, + { name: 'pop punk', url: 'https://bandcamp.com/tag/pop-punk' }, + { name: 'hardcore punk', + url: 'https://bandcamp.com/tag/hardcore-punk' }, + { name: 'chill', url: 'https://bandcamp.com/tag/chill' }, + { name: 'progressive rock', + url: 'https://bandcamp.com/tag/progressive-rock' }, + { name: 'electronic music', + url: 'https://bandcamp.com/tag/electronic-music' }, + { name: 'soundscape', + url: 'https://bandcamp.com/tag/soundscape' }, + ... 298 more items ], + locations: + [ { name: 'United Kingdom', + url: 'https://bandcamp.com/tag/united-kingdom' }, + { name: 'California', + url: 'https://bandcamp.com/tag/california' }, + { name: 'Canada', url: 'https://bandcamp.com/tag/canada' }, + { name: 'Germany', url: 'https://bandcamp.com/tag/germany' }, + { name: 'England', url: 'https://bandcamp.com/tag/england' }, + { name: 'France', url: 'https://bandcamp.com/tag/france' }, + { name: 'New York', url: 'https://bandcamp.com/tag/new-york' }, + { name: 'USA', url: 'https://bandcamp.com/tag/usa' }, + { name: 'Australia', url: 'https://bandcamp.com/tag/australia' }, + { name: 'Spain', url: 'https://bandcamp.com/tag/spain' }, + { name: 'Russia', url: 'https://bandcamp.com/tag/russia' }, + { name: 'Los Angeles', + url: 'https://bandcamp.com/tag/los-angeles' }, + { name: 'Italy', url: 'https://bandcamp.com/tag/italy' }, + { name: 'Texas', url: 'https://bandcamp.com/tag/texas' }, + { name: 'Illinois', url: 'https://bandcamp.com/tag/illinois' }, + { name: 'Ontario', url: 'https://bandcamp.com/tag/ontario' }, + { name: 'Pennsylvania', + url: 'https://bandcamp.com/tag/pennsylvania' }, + { name: 'London', url: 'https://bandcamp.com/tag/london' }, + { name: 'Japan', url: 'https://bandcamp.com/tag/japan' }, + { name: 'Berlin', url: 'https://bandcamp.com/tag/berlin' }, + { name: 'Argentina', url: 'https://bandcamp.com/tag/argentina' }, + { name: 'Washington', + url: 'https://bandcamp.com/tag/washington' }, + { name: 'Chicago', url: 'https://bandcamp.com/tag/chicago' }, + { name: 'Florida', url: 'https://bandcamp.com/tag/florida' }, + { name: 'Massachusetts', + url: 'https://bandcamp.com/tag/massachusetts' }, + { name: 'Brazil', url: 'https://bandcamp.com/tag/brazil' }, + { name: 'Ohio', url: 'https://bandcamp.com/tag/ohio' }, + { name: 'Michigan', url: 'https://bandcamp.com/tag/michigan' }, + { name: 'Oregon', url: 'https://bandcamp.com/tag/oregon' }, + { name: 'Netherlands', + url: 'https://bandcamp.com/tag/netherlands' }, + { name: 'QuĂ©bec', url: 'https://bandcamp.com/tag/qu%C3%A9bec' }, + { name: 'Sweden', url: 'https://bandcamp.com/tag/sweden' }, + { name: 'VIC', url: 'https://bandcamp.com/tag/vic' }, + { name: 'Mexico', url: 'https://bandcamp.com/tag/mexico' }, + { name: 'Toronto', url: 'https://bandcamp.com/tag/toronto' }, + { name: 'Seattle', url: 'https://bandcamp.com/tag/seattle' }, + { name: 'Portland', url: 'https://bandcamp.com/tag/portland' }, + { name: 'Melbourne', url: 'https://bandcamp.com/tag/melbourne' }, + { name: 'British Columbia', + url: 'https://bandcamp.com/tag/british-columbia' }, + { name: 'Georgia', url: 'https://bandcamp.com/tag/georgia' }, + { name: 'North Carolina', + url: 'https://bandcamp.com/tag/north-carolina' }, + { name: 'Belgium', url: 'https://bandcamp.com/tag/belgium' }, + { name: 'Colorado', url: 'https://bandcamp.com/tag/colorado' }, + { name: 'New Jersey', + url: 'https://bandcamp.com/tag/new-jersey' }, + { name: 'UK', url: 'https://bandcamp.com/tag/uk' }, + { name: 'Poland', url: 'https://bandcamp.com/tag/poland' }, + { name: 'Philadelphia', + url: 'https://bandcamp.com/tag/philadelphia' }, + { name: 'Tennessee', url: 'https://bandcamp.com/tag/tennessee' }, + { name: 'Virginia', url: 'https://bandcamp.com/tag/virginia' }, + { name: 'Minnesota', url: 'https://bandcamp.com/tag/minnesota' }, + { name: 'San Francisco', + url: 'https://bandcamp.com/tag/san-francisco' }, + { name: 'Boston', url: 'https://bandcamp.com/tag/boston' }, + { name: 'Portugal', url: 'https://bandcamp.com/tag/portugal' }, + { name: 'Montreal', url: 'https://bandcamp.com/tag/montreal' }, + { name: 'Île-de-France', + url: 'https://bandcamp.com/tag/%C3%8Ele-de-france' }, + { name: 'Austin', url: 'https://bandcamp.com/tag/austin' }, + { name: 'Finland', url: 'https://bandcamp.com/tag/finland' }, + { name: 'NSW', url: 'https://bandcamp.com/tag/nsw' }, + { name: 'Paris', url: 'https://bandcamp.com/tag/paris' }, + { name: 'Switzerland', + url: 'https://bandcamp.com/tag/switzerland' }, + { name: 'Maryland', url: 'https://bandcamp.com/tag/maryland' }, + { name: 'Arizona', url: 'https://bandcamp.com/tag/arizona' }, + { name: 'New Zealand', + url: 'https://bandcamp.com/tag/new-zealand' }, + { name: 'Atlanta', url: 'https://bandcamp.com/tag/atlanta' }, + { name: 'Missouri', url: 'https://bandcamp.com/tag/missouri' }, + { name: 'Scotland', url: 'https://bandcamp.com/tag/scotland' }, + { name: 'Vancouver', url: 'https://bandcamp.com/tag/vancouver' }, + { name: 'Wisconsin', url: 'https://bandcamp.com/tag/wisconsin' }, + { name: 'Chile', url: 'https://bandcamp.com/tag/chile' }, + { name: 'Greece', url: 'https://bandcamp.com/tag/greece' }, + { name: 'Indiana', url: 'https://bandcamp.com/tag/indiana' }, + { name: 'CT', url: 'https://bandcamp.com/tag/ct' }, + { name: 'Brooklyn', url: 'https://bandcamp.com/tag/brooklyn' }, + { name: 'Denmark', url: 'https://bandcamp.com/tag/denmark' }, + { name: 'Denver', url: 'https://bandcamp.com/tag/denver' }, + { name: 'NRW', url: 'https://bandcamp.com/tag/nrw' }, + { name: 'Minneapolis', + url: 'https://bandcamp.com/tag/minneapolis' }, + { name: 'Austria', url: 'https://bandcamp.com/tag/austria' }, + { name: 'Ireland', url: 'https://bandcamp.com/tag/ireland' }, + { name: 'Detroit', url: 'https://bandcamp.com/tag/detroit' }, + { name: 'Sydney', url: 'https://bandcamp.com/tag/sydney' }, + { name: 'Norway', url: 'https://bandcamp.com/tag/norway' }, + { name: 'Nashville', url: 'https://bandcamp.com/tag/nashville' }, + { name: 'IDF', url: 'https://bandcamp.com/tag/idf' }, + { name: 'Ukraine', url: 'https://bandcamp.com/tag/ukraine' }, + { name: 'Barcelona', url: 'https://bandcamp.com/tag/barcelona' }, + { name: 'CABA', url: 'https://bandcamp.com/tag/caba' }, + { name: 'Buenos Aires', + url: 'https://bandcamp.com/tag/buenos-aires' }, + { name: 'Israel', url: 'https://bandcamp.com/tag/israel' }, + { name: 'Connecticut', + url: 'https://bandcamp.com/tag/connecticut' }, + { name: 'Tokyo', url: 'https://bandcamp.com/tag/tokyo' }, + { name: 'Hungary', url: 'https://bandcamp.com/tag/hungary' }, + { name: 'Alberta', url: 'https://bandcamp.com/tag/alberta' }, + { name: 'San Diego', url: 'https://bandcamp.com/tag/san-diego' }, + { name: 'Community of Madrid', + url: 'https://bandcamp.com/tag/community-of-madrid' }, + { name: 'District of Columbia', + url: 'https://bandcamp.com/tag/district-of-columbia' }, + { name: 'Oakland', url: 'https://bandcamp.com/tag/oakland' }, + { name: 'Madrid', url: 'https://bandcamp.com/tag/madrid' }, + { name: 'Louisiana', url: 'https://bandcamp.com/tag/louisiana' }, + { name: 'Pittsburgh', + url: 'https://bandcamp.com/tag/pittsburgh' }, + ... 240 more items ] } diff --git a/examples/getTrackInfo.js b/examples/getTrackInfo.js new file mode 100644 index 0000000..44705a8 --- /dev/null +++ b/examples/getTrackInfo.js @@ -0,0 +1,14 @@ +const bcfetch = require('../'); +const util = require('util'); + +const trackUrl = 'https://musique.coeurdepirate.com/track/tes-belle'; + +const options = { + albumImageFormat: 'art_app_large', + artistImageFormat: 'bio_featured', + includeRawData: false +} + +bcfetch.getTrackInfo(trackUrl, options).then( results => { + console.log(util.inspect(results, false, null, false)); +}); \ No newline at end of file diff --git a/examples/getTrackInfo_output.txt b/examples/getTrackInfo_output.txt new file mode 100644 index 0000000..b65f72d --- /dev/null +++ b/examples/getTrackInfo_output.txt @@ -0,0 +1,13 @@ +{ type: 'track', + name: 'T\'es belle', + url: 'https://musique.coeurdepirate.com/track/tes-belle', + imageUrl: 'https://f4.bcbits.com/img/a774650359_16.jpg', + releaseDate: '01 Oct 2020 00:00:00 GMT', + duration: 176.373, + streamUrl: 'https://t4.bcbits.com/stream/63315678db5ea41d2f0417ac7d4f5ca3/mp3-128/3387079907?p=0&ts=1611151469&t=d9b822c203cb56acfe548e2a54be7e4c03acdb46&token=1611151469_e03428ec2305b2551717b7e4b08b490f5fcca355', + artist: + { name: 'CƓur de pirate', + url: 'https://musique.coeurdepirate.com', + description: 'CƓur de Pirate is the solo project of singer BĂ©atrice Martin. She has been playing piano since age 3 and released her acclaimed debut album in 2008. After touring extensively, she was nominated for and won several awards in Canada and France.\n\nLabel: Dare To Care Records \nmanagement@daretocarerecords.com', + imageUrl: 'https://f4.bcbits.com/img/0021821004_28.jpg' }, + album: null } diff --git a/examples/search.js b/examples/search.js new file mode 100644 index 0000000..9647617 --- /dev/null +++ b/examples/search.js @@ -0,0 +1,16 @@ +const bcfetch = require('../'); +const util = require('util'); + +const params = { + query: 'Coeur de pirate', + page: 1 +} + +const options = { + albumImageFormat: 'art_app_large', + artistImageFormat: 'bio_featured', +} + +bcfetch.search(params, options).then( results => { + console.log(util.inspect(results, false, null, false)); +}); \ No newline at end of file diff --git a/examples/search_output.txt b/examples/search_output.txt new file mode 100644 index 0000000..fcac30d --- /dev/null +++ b/examples/search_output.txt @@ -0,0 +1,118 @@ +{ items: + [ { type: 'artist', + name: 'CƓur de pirate', + url: 'https://musique.coeurdepirate.com', + imageUrl: 'https://f4.bcbits.com/img/0021821004_28.jpg', + location: 'MontrĂ©al, QuĂ©bec', + genre: 'Pop', + tags: 'french, Pop, piano pop, french pop' }, + { type: 'album', + name: 'Blonde', + url: 'https://musique.coeurdepirate.com/album/blonde', + imageUrl: 'https://f4.bcbits.com/img/a1328452291_16.jpg', + artist: 'CƓur de pirate', + numTracks: 12, + duration: 2160, + releasedDate: '07 November 2011', + tags: 'QuĂ©bec, montreal, Pop, french pop, piano pop, coeur de pirate, Canada, MontrĂ©al, amour, grosse boĂźte, french' }, + { type: 'track', + name: 'Danse et danse', + url: 'https://promodaretocare.bandcamp.com/track/danse-et-danse', + imageUrl: 'https://f4.bcbits.com/img/a2578420227_16.jpg', + artist: 'Coeur de pirate', + album: 'Compilation de NoĂ«l 2012', + releasedDate: '01 December 2012', + tags: 'Grosse BoĂźte, piano, Pop, french, MontrĂ©al' }, + { type: 'track', + name: 'Coeur de pirate', + url: 'https://sergemonette.bandcamp.com/track/coeur-de-pirate', + imageUrl: 'https://f4.bcbits.com/img/a3469921391_16.jpg', + artist: 'Monette', + album: 'Sonnez l\'Ă©veil', + releasedDate: '28 March 2020', + tags: 'folk rock, ONfr, AFO, ontario, franco, francophone' }, + { type: 'track', + name: 'Adieu (Lincoln Remix)', + url: 'https://lincolnplease.bandcamp.com/track/adieu-lincoln-remix', + imageUrl: 'https://f4.bcbits.com/img/a3583685498_16.jpg', + artist: 'CƓur de pirate', + releasedDate: '02 December 2014', + tags: 'San Diego, Electronic, groove, Dance, future, Funk, piano, United States, bass, dark, House, California, Hip Hop' }, + { type: 'track', + name: 'Comme des enfants', + url: 'https://mpourmontreal.bandcamp.com/track/comme-des-enfants', + imageUrl: 'https://f4.bcbits.com/img/a2364532545_16.jpg', + artist: 'Coeur de Pirate', + album: 'Franco M SiriusXM - Compilation 2006-2015', + releasedDate: '06 November 2015' }, + { type: 'track', + name: 'T\'es belle - Coeur de pirate', + url: 'https://pianovoix.bandcamp.com/track/tes-belle-coeur-de-pirate', + imageUrl: 'https://f4.bcbits.com/img/a3645401914_16.jpg', + artist: 'pianovoix', + releasedDate: '15 October 2020', + tags: 'chanson française, piano, IDF, France, Pop, Paris' }, + { type: 'track', + name: 'Francis (Coeur de Pirate cover)', + url: 'https://jeneiffel.bandcamp.com/track/francis-coeur-de-pirate-cover', + imageUrl: 'https://f4.bcbits.com/img/a0532659386_16.jpg', + artist: 'Jen Eiffel', + album: 'Covers', + releasedDate: '26 March 2014' }, + { type: 'track', + name: 'Jeter un sort (feat. Coeur de pirate)', + url: 'https://alexnevsky.bandcamp.com/track/jeter-un-sort-feat-coeur-de-pirate', + imageUrl: 'https://f4.bcbits.com/img/a3550838341_16.jpg', + artist: 'Alex Nevsky', + album: 'Nos Eldorados', + releasedDate: '11 November 2016' }, + { type: 'track', + name: 'Dans Tes RĂȘves (avec Coeur De Pirate)', + url: 'https://commealatelevision.bandcamp.com/track/dans-tes-r-ves-avec-coeur-de-pirate', + imageUrl: 'https://f4.bcbits.com/img/a1983632539_16.jpg', + artist: 'Omnikrom', + album: 'Comme Ă  la tĂ©lĂ©vision', + releasedDate: '15 May 2010' }, + { type: 'track', + name: 'Coeur De Pirate - Wicked Games Remix', + url: 'https://globalvortex.bandcamp.com/track/coeur-de-pirate-wicked-games-remix', + imageUrl: 'https://f4.bcbits.com/img/a0417515816_16.jpg', + artist: 'OneTwoKno', + album: 'Red Light Special lp', + releasedDate: '02 January 2012' }, + { type: 'track', + name: 'CƓur de pirate (Feat. L\'enfant sous acide)', + url: 'https://dharma-asso.bandcamp.com/track/c-ur-de-pirate-feat-lenfant-sous-acide', + imageUrl: 'https://f4.bcbits.com/img/a2750257976_16.jpg', + artist: 'Joey GlĂŒten', + album: 'NOODZ', + releasedDate: '25 July 2020' }, + { type: 'track', + name: '06. Coeur de Pirate - Adieu (Horny F Remix)', + url: 'https://hornyf.bandcamp.com/track/06-coeur-de-pirate-adieu-horny-f-remix', + imageUrl: 'https://f4.bcbits.com/img/a2202690740_16.jpg', + artist: 'Horny F', + album: 'Horny F Remixes LP Vol.1', + releasedDate: '10 February 2013' }, + { type: 'track', + name: 'C\'Ă©tait Salement Romantique (Coeur de Pirate)', + url: 'https://a-crow.bandcamp.com/track/c-tait-salement-romantique-coeur-de-pirate', + imageUrl: 'https://f4.bcbits.com/img/a1215277442_16.jpg', + artist: 'A-Crow', + releasedDate: '02 October 2018', + tags: 'Rock, Kentucky, United States, Paris' }, + { type: 'track', + name: 'Peace Sign - Lights + Coeur de Pirate Cover', + url: 'https://thesteadylungs.bandcamp.com/track/peace-sign-lights-coeur-de-pirate-cover', + imageUrl: 'https://f4.bcbits.com/img/a1448091967_16.jpg', + artist: 'The Steady Lungs', + album: 'Demos and Other Nice Stuff', + releasedDate: '23 January 2013' }, + { type: 'track', + name: 'Crier tout bas', + url: 'https://montrealsymphonique.bandcamp.com/track/crier-tout-bas', + imageUrl: 'https://f4.bcbits.com/img/a3972424743_16.jpg', + artist: 'CƓur de pirate, Orchestre symphonique de MontrĂ©al', + album: 'MontrĂ©al Symphonique', + releasedDate: '03 November 2017' } ], + totalPages: 1 } diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..73b62f7 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,181 @@ +const fetch = require('node-fetch'); +const utils = require('./utils.js'); +const parser = require('./parser.js'); + +const cache = {}; + +async function discover(params, options = {}) { + const imageConstants = await _getImageConstants(); + const opts = { + imageBaseUrl: imageConstants.baseUrl, + albumImageFormat: await _parseImageFormatArg(options.albumImageFormat, 9), + artistImageFormat: await _parseImageFormatArg(options.artistImageFormat, 21) + }; + + const url = utils.getDiscoverUrl(params); + return fetch(url) + .then( res => res.json() ) + .then( json => parser.parseDiscoverResults(json, opts) ); +} + +async function getDiscoverOptions() { + const url = utils.getSiteUrl(); + return fetch(url) + .then( res => res.text() ) + .then( html => parser.parseDiscoverOptions(html) ); +} + +async function getImageFormat(idOrName) { + const imageConstants = await _getImageConstants(); + let result = null; + imageConstants.formats.every( format => { + if ( (typeof idOrName === 'string' && format.name === idOrName) || + (Number.isInteger(idOrName) && format.id === idOrName) ) { + result = format; + return false; + } + return true; + }); + return result; +} + +async function getImageFormats(filter = '') { + return _getImageConstants().then( constants => { + if (filter === 'album') { + return constants.formats.filter( c => c.name.startsWith('art_') ); + } + else if (filter === 'artist') { + return constants.formats.filter( c => c.name.startsWith('bio_') ); + } + else { + return constants.formats; + } + }); +} + +async function _getImageConstants() { + if (cache.imageConstants !== undefined) { + return cache.imageConstants; + } + const url = utils.getSiteUrl(); + return fetch(url) + .then( res => res.text() ) + .then( html => { + cache.imageConstants = parser.parseImageConstants(html); + return cache.imageConstants; + }); +} + +async function _parseImageFormatArg(arg, defaultId = null) { + let result; + if (typeof arg === 'string' || Number.isInteger(arg)) { + result = await getImageFormat(arg); + } + else if (typeof arg === 'object') { + result = arg; + } + else { + result = null; + } + if (result === null && defaultId !== null) { + result = await getImageFormat(defaultId); + } + return result; +}; + +async function getAlbumInfo(albumUrl, options = {}) { + const opts = { + albumImageFormat: await _parseImageFormatArg(options.albumImageFormat), + artistImageFormat: await _parseImageFormatArg(options.artistImageFormat), + includeRawData: options.includeRawData ? true : false + }; + return fetch(albumUrl) + .then( res => res.text() ) + .then( html => parser.parseAlbumInfo(html, opts) ); +} + +async function getTrackInfo(trackUrl, options = {}) { + const imageConstants = await _getImageConstants(); + const opts = { + imageBaseUrl: imageConstants.baseUrl, + albumImageFormat: await _parseImageFormatArg(options.albumImageFormat), + artistImageFormat: await _parseImageFormatArg(options.artistImageFormat), + includeRawData: options.includeRawData ? true : false + }; + return fetch(trackUrl) + .then( res => res.text() ) + .then( html => parser.parseTrackInfo(html, opts) ); +} + +async function getDiscography(artistOrLabelUrl, options = {}) { + const opts = { + artistOrLabelUrl, + imageFormat: await _parseImageFormatArg(options.imageFormat) + }; + return fetch(utils.getUrl('music', artistOrLabelUrl)) + .then( res => res.text() ) + .then( html => parser.parseDiscography(html, opts) ); +} + +async function getArtistOrLabelInfo(artistOrLabelUrl, options = {}) { + const opts = { + artistOrLabelUrl, + imageFormat: await _parseImageFormatArg(options.imageFormat) + }; + return fetch(artistOrLabelUrl) + .then( res => res.text() ) + .then( html => parser.parseArtistOrLabelInfo(html, opts) ); +} + +async function getLabelArtists(labelUrl, options = {}) { + const opts = { + labelUrl, + imageFormat: await _parseImageFormatArg(options.imageFormat) + }; + return fetch(utils.getUrl('artists', labelUrl)) + .then( res => res.text() ) + .then( html => parser.parseLabelArtists(html, opts) ); +} + +async function search(params, options = {}) { + const opts = { + albumImageFormat: await _parseImageFormatArg(options.albumImageFormat), + artistImageFormat: await _parseImageFormatArg(options.artistImageFormat) + }; + return fetch(utils.getSearchUrl(params)) + .then( res => res.text() ) + .then( html => parser.parseSearchResults(html, opts) ); +} + +async function getAlbumHighlightsByTag(tagUrl, options = {}) { + const imageConstants = await _getImageConstants(); + const opts = { + imageBaseUrl: imageConstants.baseUrl, + imageFormat: await _parseImageFormatArg(options.imageFormat, 9) + }; + + return fetch(tagUrl) + .then( res => res.text() ) + .then( html => parser.parseAlbumHighlightsByTag(html, opts) ); +} + +async function getTags() { + return fetch(utils.getUrl('tags')) + .then( res => res.text() ) + .then( html => parser.parseTags(html) ); +} + +module.exports = { + discover, + getDiscoverOptions, + getImageFormats, + getImageFormat, + getAlbumInfo, + getTrackInfo, + getDiscography, + getArtistOrLabelInfo, + getLabelArtists, + search, + getAlbumHighlightsByTag, + getTags +}; \ No newline at end of file diff --git a/lib/parser.js b/lib/parser.js new file mode 100644 index 0000000..43ebd27 --- /dev/null +++ b/lib/parser.js @@ -0,0 +1,562 @@ +const cheerio = require('cheerio'); +const {decode} = require('html-entities'); +const utils = require('./utils.js'); +const {URL} = require('url'); + +// https://github.com/masterT/bandcamp-scraper/blob/master/lib/htmlParser.js +function assignProps(objFrom, objTo, propNames) { + propNames.forEach( propName => { + objTo[propName] = objFrom[propName]; + }) + return objTo; +} + +function parseDiscoverResults(json, opts) { + if (typeof json === 'object' && Array.isArray(json.items)) { + const results = { + items: [] + }; + json.items.forEach(function (item) { + if (item.type === 'a') { + const album = { + type: 'album', + name: item.primary_text, + url: '', + imageUrl: '', + genre: item.genre_text, + artist: { + name: item.secondary_text + }, + location: item.location_text, + featuredTrack: '' + }; + if (item.url_hints) { + album.artist.url = item.url_hints.custom_domain || 'https://' + item.url_hints.subdomain + '.bandcamp.com'; + } + if (album.artist.url) { + album.url = album.artist.url + '/album/' + item.url_hints.slug; + } + if (item.art_id) { + album.imageUrl = opts.imageBaseUrl + '/img/a' + item.art_id + '_' + opts.albumImageFormat.id + '.jpg'; + } + if (item.featured_track) { + album.featuredTrack = { + name: item.featured_track.title, + duration: item.featured_track.duration || null, + streamUrl: item.featured_track.file || null + }; + } + if (item.bio_image) { + album.artist.imageUrl = opts.imageBaseUrl + '/img/' + item.bio_image.image_id + '_' + opts.artistImageFormat.id + '.jpg'; + } + results.items.push(album); + } + }) + results.total = json.total_count; + return results; + } + else { + console.log('Failed to parse discover results'); + return null; + } +} + +function parseDiscoverOptions(html) { + const $ = cheerio.load(html); + const blob = $('#pagedata[data-blob]').attr('data-blob'); + const parsed = JSON.parse(blob); + if (typeof parsed === 'object' && + typeof parsed.discover_2015 === 'object' && + typeof parsed.discover_2015.options === 'object') { + const options = parsed.discover_2015.options + const result = { + genres: [], + subgenres: [], + sortBys: [], + artistRecommendationTypes: [], + locations: [], + formats: [], + times: [] + } + if (Array.isArray(options.r)) { + result.artistRecommendationTypes = options.r.map( r => assignProps(r, {}, ['value', 'name']) ); + } + if (Array.isArray(options.l)) { + result.locations = options.l.map( l => assignProps(l, {}, ['value', 'name']) ); + } + if (Array.isArray(options.w)) { + result.times = options.w.map( w => assignProps(w, {}, ['value', 'name', 'title']) ); + } + if (Array.isArray(options.f)) { + result.formats = options.f.map( f => assignProps(f, {}, ['value', 'name']) ); + } + if (Array.isArray(options.s)) { + result.sortBys = options.s.map( s => assignProps(s, {}, ['value', 'name']) ); + } + if (typeof options.t === 'object') { + for (const [genre, subgenres] of Object.entries(options.t)) { + if (Array.isArray(subgenres)) { + result.subgenres[genre] = subgenres.map(function (sg) { + return assignProps(sg, {}, ['value', 'name']) + }) + } + } + } + if (Array.isArray(options.g)) { + result.genres = options.g.map( g => assignProps(g, {}, ['value', 'name']) ); + } + return result; + } + else { + console.log('Failed to parse discover options'); + return null; + } +} + +function parseImageConstants(html) { + const $ = cheerio.load(html); + const vars = decode($('script[data-vars]').attr('data-vars')); + const parsed = JSON.parse(vars); + if (typeof parsed === 'object' && parsed.client_template_globals) { + return { + baseUrl: parsed.client_template_globals.image_siteroot_https, + formats: parsed.client_template_globals.image_formats + }; + } + else { + console.log('Failed to parse image constants'); + return null; + } +} + +function parseAlbumInfo(html, opts) { + const $ = cheerio.load(html); + const rawBasic = $('script[type="application/ld+json"]').html(); + const rawExtra = decode($('script[data-tralbum]').attr('data-tralbum')); + + const basic = JSON.parse(rawBasic); + const extra = JSON.parse(rawExtra); + if (typeof extra === 'object' && typeof basic === 'object') { + const album = { + type: 'album', + name: basic.name, + url: basic['@id'], + numTracks: basic.numTracks, + imageUrl: utils.reformatImageUrl(basic.image, opts.albumImageFormat), + keywords: basic.keywords, + description: basic.description, + releaseDate: extra.album_release_date, + artist: { + name: basic.byArtist.name, + url: basic.byArtist['@id'], + description: basic.byArtist.description, + imageUrl: utils.reformatImageUrl(basic.byArtist.image, opts.artistImageFormat) + }, + releases: [], + tracks: [] + }; + if (Array.isArray(basic.albumRelease)) { + basic.albumRelease.forEach( release => { + album.releases.push({ + name: release.name, + url: release.url, + format: release.musicReleaseFormat, + description: release.description, + imageUrl: utils.reformatImageUrl(release.image, opts.albumImageFormat) + }); + }); + } + if (Array.isArray(basic.track.itemListElement)) { + const _getStreamUrl = (url) => { + let file = null; + if (Array.isArray(extra.trackinfo)) { + extra.trackinfo.every( track => { + if (url.endsWith(track.title_link)) { + file = track.file['mp3-128']; + return false; + } + return true; + }); + } + return file; + } + basic.track.itemListElement.forEach( track => { + album.tracks.push({ + position: track.position, + name: track.item.name, + url: track.item.url, + duration: track.item.duration_secs, + streamUrl: _getStreamUrl(track.item.url) + }); + }); + } + if (opts.includeRawData) { + album.raw = { basic, extra }; + } + + return album; + } + else { + console.log('Failed to parse album info'); + return null; + } +} + +function parseTrackInfo(html, opts) { + const $ = cheerio.load(html); + const rawBasic = $('script[type="application/ld+json"]').html(); + const rawExtra = decode($('script[data-tralbum]').attr('data-tralbum')); + + const basic = JSON.parse(rawBasic); + const extra = JSON.parse(rawExtra); + if (typeof extra === 'object' && typeof basic === 'object') { + const track = { + type: 'track', + name: basic.name, + url: basic.url, + imageUrl: opts.imageBaseUrl + '/img/a' + extra.art_id + '_' + opts.albumImageFormat.id + '.jpg', + releaseDate: extra.current.release_date, + duration: basic.duration_secs, + streamUrl: extra.trackinfo[0].file['mp3-128'], + artist: { + name: basic.byArtist.name, + url: basic.byArtist['@id'], + description: basic.byArtist.description, + imageUrl: utils.reformatImageUrl(basic.byArtist.image, opts.artistImageFormat) + }, + album: null + } + if (basic.inAlbum) { + track.album = { + name: basic.inAlbum.name, + url: basic.inAlbum['@id'], + releaseDate: extra.album_release_date + } + track.releaseDate = extra.album_release_date; + } + if (opts.includeRawData) { + track.raw = { basic, extra }; + } + + return track; + } + else { + console.log('Failed to parse track info'); + return null; + } +} + +function parseDiscography(html, opts) { + const $ = cheerio.load(html); + const allLinks = $('a'); + const items = {}; + const isLabel = $('a[href="/artists"]').length; + const defaultArtistName = $('#band-name-location').find('.title').text(); + allLinks.each( (index, link) => { + link = $(link); + const href = link.attr('href'); + if (typeof href !== 'string' || href === '') { + return true; + } + let host, pathname; + // regex taken from: + // https://github.com/masterT/bandcamp-scraper/blob/master/lib/htmlParser.js + if (/^\/(track|album)\/(.+)$/.exec(href)) { // relative url starting with '/track' or '/album' + host = opts.artistOrLabelUrl; + pathname = href; + } + else { // full url (label discography) + try { + const _url = utils.splitUrl(href); + if (/^\/(track|album)\/(.+)$/.exec(_url.path)) { + host = _url.base; + pathname = _url.path; + } + } catch (e) { + return true; + } + } + if (host !== undefined && pathname !== undefined) { + const url = utils.getUrl(pathname, host); + if (items[url] === undefined) { + items[url] = { + type: pathname.startsWith('/track/') ? 'track' : 'album' + }; + } + // Link element wraps around img and title + const img = link.find('img'); + if (img.length) { + let imgSrc = img.attr('data-original') || img.attr('src'); + items[url].imageUrl = utils.reformatImageUrl(imgSrc, opts.imageFormat); + } + const title = link.find('.title'); + if (title.length) { + // For labels, title element contains artist name (when it doesn't, then artist = label). + // For artists, title element may also contain an artist name which overrides the default + const artistName = title.find('.artist-override'); + if (artistName.length) { + const artist = artistName.text().trim(); + artistName.remove(); + items[url].artist = artist; + } + else { + items[url].artist = defaultArtistName; + } + items[url].name = title.text().trim(); + } + + if (!img.length && !title.length) { + items[url].name = link.text().trim(); + } + } + }); + const results = []; + for (const [url, props] of Object.entries(items)) { + const item = { + url, + type: props.type, + name: props.name || '', + imageUrl: props.imageUrl || null, + artist: props.artist || defaultArtistName + }; + results.push(item); + } + return results; +} + +function parseArtistOrLabelInfo(html, opts) { + const $ = cheerio.load(html); + + let bioText = $('#bio-text'); + let bioTextMore = bioText.find('.peekaboo-text'); + let description; + if (bioTextMore.length) { + bioTextMore.find('.lightweightBreak').remove(); + bioText.find('.peekaboo-text, .peekaboo-link').remove(); + description = (bioText.html().trim() + ' ' + bioTextMore.html()).trim(); + } + else { + description = bioText.html().trim(); + } + description = utils.stripLineBreaks(description); + description = utils.brToNewLine(description); + description = utils.stripTags(description); + description = decode(description); + + let isLabel = $('a[href="/artists"]').length; + let label = null; + if (!isLabel) { + let labelLink = $('a.back-to-label-link'); + if (labelLink.length) { + let linkText = labelLink.find('.back-link-text').html(); + label = { + name: utils.substrAfter(linkText, '
') || utils.substrBefore(linkText, ' ă«æˆ»ă‚‹') || utils.substrBefore(linkText, ' ăźă‚ąă‚€ăƒ†ăƒ ă‚’ă‚‚ăŁăšèŽă'), + url: utils.splitUrl(labelLink.attr('href')).base + }; + } + } + + const result = { + type: isLabel ? 'label' : 'artist', + name: $('#band-name-location').find('.title').text(), + url: opts.artistOrLabelUrl, + description: description, + location: $('#band-name-location').find('.location').text(), + imageUrl: utils.reformatImageUrl($('img.band-photo').attr('src'), opts.imageFormat) + }; + if (!isLabel) { + result.label = label; + } + return result; +} + +function parseLabelArtists(html, opts) { + const $ = cheerio.load(html); + const artistsList = $('li.artists-grid-item'); + const results = []; + artistsList.each( (index, artistListItem) => { + artistListItem = $(artistListItem); + const img = artistListItem.find('img'); + const imgSrc = img.attr('data-original') || img.attr('src'); + const artist = { + name: artistListItem.find('.artists-grid-name').text(), + url: utils.splitUrl(artistListItem.find('a').attr('href')).base, + location: artistListItem.find('.artists-grid-location').text(), + imageUrl: utils.reformatImageUrl(imgSrc, opts.imageFormat) + }; + results.push(artist); + }); + return results; +} + +function parseSearchResults(html, opts) { + const $ = cheerio.load(html); + const resultsList = $('li.searchresult'); + const results = []; + resultsList.each( (index, resultListItem) => { + resultListItem = $(resultListItem); + const resultInfo = resultListItem.find('.result-info'); + const resultType = resultInfo.children('.itemtype').text().trim().toLowerCase(); + const imgSrc = $('.art img', resultListItem).attr('src'); + const heading = $('.heading a', resultInfo); + const result = { + type: resultType, + name: heading.text().trim(), + url: resultInfo.find('.itemurl').text().trim(), + imageUrl: utils.reformatImageUrl(imgSrc, resultType === 'album' || resultType === 'track' ? opts.albumImageFormat : opts.artistImageFormat) + }; + resultInfo.find('.subhead, .genre, .tags, .released, .length').each( (index, info) => { + info = $(info); + if (info.hasClass('subhead')) { + if (resultType === 'artist' || resultType === 'label') { + result.location = info.text().trim(); + } + else if (resultType === 'album' || resultType === 'track') { + const infoText = info.text(); + const artist = utils.substrAfter(infoText, 'by '); + if (artist) { + result.artist = artist.trim(); + + if (resultType === 'track') { + let album = utils.substrBefore(infoText, ' by'); + if (album) { + album = utils.substrAfter(album, 'from '); + if (album) { + result.album = album.trim(); + } + } + } + } + } + return true; + } + if (info.hasClass('genre')) { + const genre = utils.substrAfter(info.text(), 'genre: '); + if (genre) { + result.genre = genre.trim(); + } + return true; + } + if (info.hasClass('tags')) { + const tags = utils.substrAfter(info.text(), 'tags:'); + if (tags) { + result.tags = utils.stripLineBreaks(utils.stripMultipleWhitespaces(tags)).trim(); + } + return true; + } + if (info.hasClass('released')) { + const released = utils.substrAfter(info.text(), 'released '); + if (released) { + result.releasedDate = released.trim(); + } + return true; + } + if (info.hasClass('length')) { + const lengthParts = info.text().split(','); + const tracksText = lengthParts[0]; + const minutesText = lengthParts[1]; + const numTracks = tracksText ? utils.substrBefore(tracksText, 'tracks') : null; + if (numTracks) { + result.numTracks = parseInt(numTracks, 10); + } + const minutes = minutesText ? utils.substrBefore(minutesText, 'minutes') : null; + if (minutes) { + result.duration = parseInt(minutes, 10) * 60; + } + } + }); + results.push(result); + }); + + let totalPages = parseInt($('.pagelist').find('.pagenum').last().text(), 10); + if (isNaN(totalPages)) { + totalPages = 1; + } + + return { + items: results, + totalPages + }; +} + +function parseAlbumHighlightsByTag(html, opts) { + const $ = cheerio.load(html); + const blob = decode($('#pagedata[data-blob]').attr('data-blob')); + const parsed = JSON.parse(blob); + const collections = []; + if (typeof parsed === 'object' && parsed.hub && + parsed.hub.tabs && parsed.hub.tabs[0].collections) { + + parsed.hub.tabs[0].collections.forEach( collection => { + const collectionRes = { + name: collection.name, + title: collection.render.title, + items: [] + }; + collection.items.forEach( item => { + if (item.item_type === 'a') { + const album = { + type: 'album', + name: item.title, + url: item.tralbum_url, + imageUrl: '', + genre: item.genre, + artist: { + name: item.artist, + url: item.band_url + } + }; + if (item.art_id) { + album.imageUrl = opts.imageBaseUrl + '/img/a' + item.art_id + '_' + opts.imageFormat.id + '.jpg'; + } + if (item.featured_track_title) { + album.featuredTrack = { + name: item.featured_track_title, + streamUrl: item.audio_url['mp3-128'] + }; + } + collectionRes.items.push(album); + } + }); + if (collectionRes.items.length) { + collections.push(collectionRes); + } + }); + } + return collections; +} + +function parseTags(html) { + const $ = cheerio.load(html); + const _parseCloud = (id) => { + const cloud = $(`#${id}`); + const tagsInCloud = []; + cloud.find('a.tag').each( (index, link) => { + link = $(link); + tagsInCloud.push({ + name: link.text(), + url: utils.getUrl(link.attr('href')) + }); + }); + return tagsInCloud; + }; + + return { + tags: _parseCloud('tags_cloud'), + locations: _parseCloud('locations_cloud') + }; +} + +module.exports = { + parseDiscoverResults, + parseDiscoverOptions, + parseImageConstants, + parseAlbumInfo, + parseTrackInfo, + parseDiscography, + parseArtistOrLabelInfo, + parseLabelArtists, + parseSearchResults, + parseAlbumHighlightsByTag, + parseTags +}; \ No newline at end of file diff --git a/lib/utils.js b/lib/utils.js new file mode 100644 index 0000000..0ed0274 --- /dev/null +++ b/lib/utils.js @@ -0,0 +1,124 @@ +const querystring = require('querystring'); +const {URL} = require('url'); + +function getUrl(href, baseUrl) { + if (baseUrl === undefined) { + baseUrl = getSiteUrl(); + } + return new URL(href, baseUrl).toString(); +} + +function getSiteUrl() { + return 'https://bandcamp.com'; +} + +function getDiscoverUrl(params = {}) { + const qs = { + s: params.sortBy || 'top', + p: params.page || 0, + }; + if (params.genre) { + qs.g = params.genre; + + if (params.subgenre) { + qs.t = params.subgenre; + } + } + if (params.location !== undefined) { + qs.gn = params.location; + } + if (params.format) { + qs.f = params.format; + } + if (qs.s === 'rec' && params.artistRecommendationType) { + qs.r = params.artistRecommendationType; + } + if (params.time !== undefined) { + qs.w = params.time; + } + return getSiteUrl() + '/api/discover/3/get_web?' + querystring.encode(qs); +} + +function reformatImageUrl(imageUrl, imageFormat) { + if (typeof imageUrl === 'string' && imageFormat !== null) { + // regex taken from: + // https://github.com/masterT/bandcamp-scraper/blob/master/lib/htmlParser.js + return imageUrl.replace(/_\d{1,3}\./, `_${imageFormat.id}.`); + } + else if (typeof imageUrl === 'string') { + return imageUrl; + } + else { + return null; + } +} + +function stripTags(str) { + // https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/ + return str.replace(/(<([^>]+)>)/gi, ''); +} + +function stripLineBreaks(str) { + return str.replace(/(\r\n|\n|\r)/gm, ' '); +} + +function brToNewLine(str) { + // https://stackoverflow.com/questions/5959415/jquery-javascript-regex-replace-br-with-n + return str.replace(//gi, '\n'); +} + +function substrAfter(str, after) { + let afterIndex = str.indexOf(after); + if (afterIndex >= 0) { + return str.substr(afterIndex + after.length); + } + else { + return null; + } +} + +function substrBefore(str, before) { + let beforeIndex = str.indexOf(before); + if (beforeIndex >= 0) { + return str.substr(0, beforeIndex); + } + else { + return null; + } +} + +function splitUrl(url) { + const _url = new URL(url); + return { + base: _url.protocol + '//' + _url.host, + path: _url.pathname, + query: _url.search + }; +} + +function getSearchUrl(params = {}) { + const qs = { + q: params.query, + page: params.page || 1, + }; + return getSiteUrl() + '/search?' + querystring.encode(qs); +} + +function stripMultipleWhitespaces(str) { + return str.replace(/\s+/g, ' '); +} + +module.exports = { + getUrl, + getSiteUrl, + getDiscoverUrl, + reformatImageUrl, + stripTags, + stripLineBreaks, + brToNewLine, + substrAfter, + substrBefore, + splitUrl, + getSearchUrl, + stripMultipleWhitespaces +}; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..0898ef3 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "bandcamp-fetch", + "version": "0.1.0a-20210119", + "description": "JS library for scraping Bandcamp content", + "main": "lib/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/patrickkfkan/bandcamp-fetch.git" + }, + "keywords": [ + "bandcamp", + "scrape", + "scraper", + "discover", + "album", + "track", + "artist" + ], + "author": "Patrick Kan", + "license": "MIT", + "dependencies": { + "cheerio": "^1.0.0-rc.5", + "html-entities": "^2.0.2", + "node-fetch": "^2.6.1" + } +}