UNPKG

@economia/feed-to-json-promise

Version:

Feed to Json: RSS and Atom feed parser

219 lines (185 loc) 4.33 kB
class RssParser { /** * @param {Object} options */ constructor (options = {}) { this.options = options } /** * @returns {Object} */ get options () { return this._options || { count: null } } /** * @param {Object} options */ set options (options) { this._options = Object.assign({}, this.options, options) } /** * @param {Object} data * @returns {Object} */ parse (data) { const channel = this.parseChannel(data) channel.image = this.parseChannelImage(data) channel.items = this.parseItems(data) return channel } /** * @param {Object} data * @returns {Object} */ parseChannel (data) { return this.extractStructure([ 'title', 'description', 'link' ], data) } /** * @param {Object} data * @returns {Object} */ parseChannelImage (data) { return data.image ? this.parseImage(data.image[0]) : undefined } /** * @param {Object} data * @returns {Array} */ parseItems (data) { const source = data.item || [] const count = this.options.count || source.length return source.slice(0, count).map(item => this.parseItem(item)) } /** * @param {Object} data * @returns {Object} */ parseItem (data) { const { extraParsedItemFields = [] } = this.options const item = this.extractStructure([ 'title', 'description', 'link', {target: 'pubDate', as: 'date'}, ...extraParsedItemFields ], data) item.guid = this.parseGuid(data) item.categories = this.parseCategories(data) item.thumbnail = this.parseThumbnail(data) item.media = this.parseMedia(data) return item } /** * @param {Object} data * @returns {Array} */ parseCategories (data) { let categories if (data['category']) { categories = data['category'].map(category => this.extractValueFromObject(category)) } return categories } /** * @param {Object} data * @returns {String} */ parseGuid (data) { let guid if (data['guid']) { guid = this.extractValueFromObject(data['guid'][0]) } return guid } /** * @param data * @returns {Object} */ parseThumbnail (data) { let thumbnail if (data['media:thumbnail']) { thumbnail = this.parseImage(data['media:thumbnail'][0]) } if (data['media:group'] && data['media:group'][0]['media:thumbnail']) { thumbnail = this.parseImage(data['media:group'][0]['media:thumbnail'][0]) } return thumbnail } /** * @param {Object} data * @returns {Array} */ parseMedia (data) { let media = [] if (data['enclosure']) { media = data['enclosure'] } if (data['media:content']) { media = data['media:content'] } if (data['media:group'] && data['media:group'][0]['media:content']) { media = data['media:group'][0]['media:content'] } return media.map(element => this.parseImage(element)) } /** * @param {Object} data * @returns {Object} */ parseImage (data) { return this.extractStructure([ 'url', 'title', 'description', 'width', 'height', 'type', {target: 'media:height', as: 'height'}, {target: 'media:width', as: 'width'}, {target: 'media:description', as: 'description'}, {target: 'media:url', as: 'url'} ], data) } /** * @param {Array} structure * @param {Object} data * @returns {Object} */ extractStructure (structure, data) { const result = {} structure.forEach(attribute => { let inputKey = attribute let resultKey = attribute if (attribute instanceof Object) { inputKey = attribute.target resultKey = attribute.as } if (!result[resultKey]) { result[resultKey] = this.extractAttribute(inputKey, data) } }) return result } /** * @param {String} attribute * @param {Object} input * @param empty * @returns {*} */ extractAttribute (attribute, input, empty) { return input[attribute] ? input[attribute][0] : empty } /** * @param {*} input * @returns {String} */ extractValueFromObject (input) { if (input instanceof Object) { return input['_'] } return input } } module.exports = RssParser