import moment from "moment"; import momenttz from "moment-timezone"; import xl from "excel4node"; import Pages from "./Pages"; import AlbumsModel from "../models/albums"; import ErrorEvent from "../libs/error"; /** * Classe permettant la gestion des albums d'un utilisateur */ class Albums extends Pages { static replaceSpecialChars(str) { if (!str) { return ""; } let final = str.toString(); const find = ["&", "<", ">"]; const replace = ["&", "<", ">"]; for (let i = 0; i < find.length; i += 1) { final = final.replace(new RegExp(find[i], "g"), replace[i]); } return final; } /** * Méthode permettant de convertir les rows en csv * @param {Array} rows * * @return {string} */ static async convertToCsv(rows) { let data = "Artiste;Titre;Genre;Styles;Pays;Année;Date de sortie;Format\n\r"; for (let i = 0; i < rows.length; i += 1) { const { artists_sort, title, genres, styles, country, year, released, formats, } = rows[i]; let format = ""; for (let j = 0; j < formats.length; j += 1) { format += `${format !== "" ? ", " : ""}${formats[j].name}`; } data += `${artists_sort};${title};${genres.join()};${styles.join()};${country};${year};${released};${format}\n\r`; } return data; } /** * Méthode permettant de convertir les rows en fichier xls * @param {Array} rows * * @return {Object} */ static async convertToXls(rows) { const wb = new xl.Workbook(); const ws = wb.addWorksheet("MusicTopus"); const headerStyle = wb.createStyle({ font: { color: "#FFFFFF", size: 11, }, fill: { type: "pattern", patternType: "solid", bgColor: "#595959", fgColor: "#595959", }, }); const style = wb.createStyle({ font: { color: "#000000", size: 11, }, numberFormat: "0000", }); const header = [ "Artiste", "Titre", "Genre", "Styles", "Pays", "Année", "Date de sortie", "Format", ]; for (let i = 0; i < header.length; i += 1) { ws.cell(1, i + 1) .string(header[i]) .style(headerStyle); } for (let i = 0; i < rows.length; i += 1) { const currentRow = i + 2; const { artists_sort, title, genres, styles, country, year, released, formats, } = rows[i]; let format = ""; for (let j = 0; j < formats.length; j += 1) { format += `${format !== "" ? ", " : ""}${formats[j].name}`; } ws.cell(currentRow, 1).string(artists_sort).style(style); ws.cell(currentRow, 2).string(title).style(style); ws.cell(currentRow, 3).string(genres.join()).style(style); ws.cell(currentRow, 4).string(styles.join()).style(style); if (country) { ws.cell(currentRow, 5).string(country).style(style); } if (year) { ws.cell(currentRow, 6).number(year).style(style); } if (released) { ws.cell(currentRow, 7) .date(momenttz.tz(released, "Europe/Paris").hour(12)) .style({ numberFormat: "dd/mm/yyyy" }); } ws.cell(currentRow, 8).string(format).style(style); } return wb; } /** * Méthode permettant de convertir les rows en csv pour importer dans MusicTopus * @param {Array} rows * * @return {string} */ static async convertToXml(rows) { let data = '\n\r'; for (let i = 0; i < rows.length; i += 1) { const { discogsId, year, released, uri, artists, artists_sort, labels, series, companies, formats, title, country, notes, identifiers, videos, genres, styles, tracklist, extraartists, images, thumb, } = rows[i]; let artistsList = ""; let labelList = ""; let serieList = ""; let companiesList = ""; let formatsList = ""; let identifiersList = ""; let videosList = ""; let genresList = ""; let stylesList = ""; let tracklistList = ""; let extraartistsList = ""; let imagesList = ""; for (let j = 0; j < artists.length; j += 1) { artistsList += ` ${Albums.replaceSpecialChars(artists[j].name)} ${Albums.replaceSpecialChars(artists[j].anv)} ${Albums.replaceSpecialChars(artists[j].join)} ${Albums.replaceSpecialChars(artists[j].role)} ${Albums.replaceSpecialChars( artists[j].tracks )} ${Albums.replaceSpecialChars(artists[j].id)} ${Albums.replaceSpecialChars( artists[j].resource_url )} ${Albums.replaceSpecialChars( artists[j].thumbnail_url )} `; } for (let j = 0; j < labels.length; j += 1) { labelList += ` `; } for (let j = 0; j < series.length; j += 1) { serieList += ` ${Albums.replaceSpecialChars(series[j].name)} ${Albums.replaceSpecialChars(series[j].catno)} ${Albums.replaceSpecialChars( series[j].entity_type )} ${Albums.replaceSpecialChars( series[j].entity_type_name )} ${Albums.replaceSpecialChars(series[j].id)} ${Albums.replaceSpecialChars( series[j].resource_url )} ${Albums.replaceSpecialChars( series[j].thumbnail_url )} `; } for (let j = 0; j < companies.length; j += 1) { companiesList += ` ${Albums.replaceSpecialChars(companies[j].name)} ${Albums.replaceSpecialChars(companies[j].catno)} ${Albums.replaceSpecialChars( companies[j].entity_type )} ${Albums.replaceSpecialChars( companies[j].entity_type_name )} ${Albums.replaceSpecialChars(companies[j].id)} ${Albums.replaceSpecialChars( companies[j].resource_url )} ${Albums.replaceSpecialChars( companies[j].thumbnail_url )} `; } for (let j = 0; j < formats.length; j += 1) { let descriptions = ""; if (formats[j].descriptions) { for ( let k = 0; k < formats[j].descriptions.length; k += 1 ) { descriptions += `${formats[j].descriptions[k]} `; } } formatsList += ` ${Albums.replaceSpecialChars(formats[j].name)} ${Albums.replaceSpecialChars(formats[j].qty)} ${Albums.replaceSpecialChars(formats[j].text)} ${descriptions} `; } for (let j = 0; j < identifiers.length; j += 1) { identifiersList += ` ${Albums.replaceSpecialChars(identifiers[j].type)} ${Albums.replaceSpecialChars( identifiers[j].value )} ${Albums.replaceSpecialChars( identifiers[j].description )} `; } for (let j = 0; j < videos.length; j += 1) { videosList += ` `; } for (let j = 0; j < genres.length; j += 1) { genresList += `${Albums.replaceSpecialChars( genres[j] )} `; } for (let j = 0; j < styles.length; j += 1) { stylesList += ` `; } for (let j = 0; j < tracklist.length; j += 1) { tracklistList += ` ${Albums.replaceSpecialChars(tracklist[j].title)} `; } for (let j = 0; j < extraartists.length; j += 1) { extraartistsList += ` ${Albums.replaceSpecialChars(extraartists[j].name)} ${Albums.replaceSpecialChars(extraartists[j].anv)} ${Albums.replaceSpecialChars(extraartists[j].join)} ${Albums.replaceSpecialChars(extraartists[j].role)} ${Albums.replaceSpecialChars( extraartists[j].tracks )} ${Albums.replaceSpecialChars(extraartists[j].id)} ${Albums.replaceSpecialChars( extraartists[j].resource_url )} ${Albums.replaceSpecialChars( extraartists[j].thumbnail_url )} `; } for (let j = 0; j < images.length; j += 1) { imagesList += ` ${Albums.replaceSpecialChars(images[j].uri)} ${Albums.replaceSpecialChars( images[j].resource_url )} ${Albums.replaceSpecialChars( images[j].resource_url )} `; } data += ` ${discogsId} ${Albums.replaceSpecialChars(title)} ${Albums.replaceSpecialChars(artists_sort)} ${artistsList} ${year} ${Albums.replaceSpecialChars(country)} ${released} ${uri} ${thumb} ${labelList} ${serieList} ${companiesList} ${formatsList} ${Albums.replaceSpecialChars(notes)} ${identifiersList} ${videosList} ${genresList} ${stylesList} ${tracklistList} ${extraartistsList} ${imagesList} `; } return `${data}`; } /** * Méthode permettant de convertir les rows en csv pour importer dans MusicTopus * @param {Array} rows * * @return {string} */ static async convertToMusicTopus(rows) { let data = "itemId;createdAt;updatedAt\n\r"; for (let i = 0; i < rows.length; i += 1) { const { discogsId, createdAt, updatedAt } = rows[i]; data += `${discogsId};${createdAt};${updatedAt}\n\r`; } data += "v1.0"; return data; } /** * Méthode permettant d'ajouter un album dans une collection * @param {Object} req * @return {Object} */ static async postAddOne(req) { const { body, user } = req; const data = { ...body, discogsId: body.id, User: user._id, }; data.released = data.released ? moment(data.released.replace("-00", "-01")) : null; delete data.id; const album = new AlbumsModel(data); return album.save(); } /** * Méthode permettant de récupérer les éléments distincts d'une collection * @param {String} field * @param {ObjectId} user * @return {Array} */ static async getAllDistincts(field, user) { const distincts = await AlbumsModel.find( { user, }, [], { sort: { [field]: 1, }, } ).distinct(field); return distincts; } /** * Méthode permettant de récupérer la liste des albums d'une collection * @return {Object} */ async getAll() { const { page, limit, exportFormat = "json", sort = "artists_sort", order = "asc", artists_sort, format, } = this.req.query; const where = {}; if (artists_sort) { where.artists_sort = artists_sort; } if (format) { where["formats.name"] = format; } const count = await AlbumsModel.count({ user: this.req.user._id, ...where, }); let params = { sort: { [sort]: order.toLowerCase() === "asc" ? 1 : -1, }, }; if (page && limit) { const skip = (page - 1) * limit; params = { ...params, skip, limit, }; } const rows = await AlbumsModel.find( { user: this.req.user._id, ...where, }, [], params ); switch (exportFormat) { case "csv": return Albums.convertToCsv(rows); case "xls": return Albums.convertToXls(rows); case "xml": return Albums.convertToXml(rows); case "musictopus": return Albums.convertToMusicTopus(rows); case "json": default: return { rows, count, }; } } /** * Méthode permettant de supprimer un élément d'une collection * @return {Boolean} */ async deleteOne() { const res = await AlbumsModel.findOneAndDelete({ user: this.req.user._id, _id: this.req.params.itemId, }); if (res) { return true; } throw new ErrorEvent(404, "Impossible de trouver cet album"); } /** * Méthode permettant de créer la page "ma-collection" */ async loadMyCollection() { const artists = await Albums.getAllDistincts( "artists_sort", this.req.user._id ); const formats = await Albums.getAllDistincts( "formats.name", this.req.user._id ); this.setPageContent("artists", artists); this.setPageContent("formats", formats); } /** * Méthode permettant d'afficher le détails d'un album */ async loadItem() { const { itemId: _id } = this.req.params; const { _id: User } = this.req.user; const item = await AlbumsModel.findOne({ _id, User, }); this.setPageContent("item", item); } } export default Albums;