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 { /** * Méthode permettant de convertir les rows en csv * @param {Array} rows * * @return {string} */ static async convertToCsv(rows) { let data = ""; 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 {string} */ 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 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 "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;