/*global define */ define(['jquery', 'underscore', 'backbone'], function($, _, Backbone) { 'use strict'; /** * @class Metrics * @classdesc A single result from the DataONE Metrics Service * @classcategory Models * @extends Backbone.Model * @constructor */ var Metrics = Backbone.Model.extend( /** @lends Metrics.prototype */{ /** * The name of this Model * @type {string} */ type: "Metrics", defaults: { metricRequest: null, startDate: null, endDate: null, results: null, resultDetails: null, pid_list: null, url: null, filterType: null, // metrics and metric Facets returned as response from the user // datatype: array citations: null, views: null, downloads: null, months: null, country: null, years: null, repository: null, award: null, datasets: null, // Total counts for metrics totalCitations: null, totalViews: null, totalDownloads: null, // flag to send POST request to the metrics service useMetricsPost: false, // colelctionQuery for Portal Objects filterQueryObject: null, forwardCollectionQuery: false, metricsRequiredFields: { metricName: true, pid_list: true } }, metricRequest: { "metricsPage": { "total": 0, "start": 0, "count": 0 }, "metrics": [ "citations", "downloads", "views" ], "filterBy": [ { "filterType": "", "values": [], "interpretAs": "list" }, { "filterType": "month", "values": [], "interpretAs": "range" } ], "groupBy": [ "month" ] }, /** * Initializing the Model objects pid and the metricName variables. * @param {object} options */ initialize: function(options) { if((options) && options.pid_list !== 'undefined') { this.set("pid_list", options.pid_list); this.set("filterType", options.type); } this.set("startDate", "01/01/2012"); // overwrite forwardCollectionQuery flag this.set("forwardCollectionQuery", MetacatUI.appModel.get("metricsForwardCollectionQuery")); // url for the model that is used to for the fetch() call this.url = MetacatUI.appModel.get("metricsUrl"); }, /** * Overriding the Model's fetch function. */ fetch: function(){ var fetchOptions = {}; this.metricRequest.filterBy[0].filterType = this.get("filterType"); this.metricRequest.filterBy[0].values = this.get("pid_list"); // TODO: Set the startDate and endDate based on the datePublished and current date // respctively. this.metricRequest.filterBy[1].values = []; this.metricRequest.filterBy[1].values.push(this.get("startDate")); this.metricRequest.filterBy[1].values.push(this.getCurrentDate()); // set custom request settings if we're forwarding a CollectionQuery for a portal if ( this.get("forwardCollectionQuery") && this.get("filterType") === "portal" && this.get("filterQueryObject") != undefined && typeof this.get("filterQueryObject") === "object") { var filterQueryObject = this.get("filterQueryObject"); if (filterQueryObject.filterType != undefined && filterQueryObject.filterType == "query") { if (Array.isArray(filterQueryObject.values) && filterQueryObject.values.length > 0 ) { // check if query object exists var queryInserted = this.metricRequest.filterBy.indexOf(filterQueryObject); // Performing HTTP POST? if(this.get("useMetricsPost")) { // insert query object if (queryInserted < 0) { this.metricRequest.filterBy.push(filterQueryObject); } fetchOptions = _.extend({ data:JSON.stringify(this.metricRequest), type:"POST", timeout:300000 }); } else { // insert query object var collectionQuery = filterQueryObject.values[0]; if (collectionQuery.length < 1000 && queryInserted < 0) { this.metricRequest.filterBy.push(filterQueryObject); } // set the fetch options for var model = this; fetchOptions = _.extend({ data:"metricsRequest="+JSON.stringify(this.metricRequest), timeout:300000, // on error recursively call fetch, but this time use POST error: function(response){ model.set("useMetricsPost", "true"); model.fetch(); } }); } } } } // check if we need to set fetchOptions if (Object.keys(fetchOptions).length === 0) { if ( this.get("useMetricsPost") ) { fetchOptions = _.extend({ data:JSON.stringify(this.metricRequest), type:"POST", timeout:300000 }); } else { fetchOptions = _.extend({ data:"metricsRequest="+JSON.stringify(this.metricRequest), timeout:300000, }); } } //This calls the Backbone fetch() function but with our custom fetch options. return Backbone.Model.prototype.fetch.call(this, fetchOptions); }, /** * Get's a string version of today's date * @return {string} */ getCurrentDate: function() { var today = new Date(); var dd = today.getDate(); var mm = today.getMonth()+1; //January is 0! var yyyy = today.getFullYear(); if(dd<10){ dd='0'+dd; } if(mm<10){ mm='0'+mm; } var today = mm+'/'+dd+'/'+yyyy; return today; }, /** * Parsing the response for setting the Model's member variables. */ parse: function(response){ var metricsObject = { "metricRequest": response.metricsRequest, "citations": response.results.citations, "views": response.results.views, "downloads": response.results.downloads, "months": response.results.months, "country": response.results.country, "resultDetails": response.resultDetails, "datasets": response.results.datasets } if (response.results.citations != null) { metricsObject["totalCitations"] = response.results.citations.reduce(function(acc, val) { return acc + val; }, 0) } else { metricsObject["totalCitations"] = 0 } if (response.results.downloads != null) { metricsObject["totalDownloads"] = response.results.downloads.reduce(function(acc, val) { return acc + val; }, 0) } else { metricsObject["totalDownloads"] = 0 } if (response.results.views != null) { metricsObject["totalViews"] = response.results.views.reduce(function(acc, val) { return acc + val; }, 0) } else { metricsObject["totalViews"] = 0 } //trim off the leading zeros and their corresponding months if (response.results.months != null) { // iterate all the metrics objects and remove the entry if the counts are 0 for (var i = 0 ; i < metricsObject["months"].length; i++) { if ( metricsObject["citations"] != null && metricsObject["views"] != null && metricsObject["downloads"] != null ) { if (( metricsObject["citations"][i] == 0 ) && ( metricsObject["views"][i] == 0 ) && ( metricsObject["downloads"][i] == 0 )) { metricsObject["months"].splice(i,1); metricsObject["citations"].splice(i,1); metricsObject["views"].splice(i,1); metricsObject["downloads"].splice(i,1); // if country facet was part of the request; update object; if ( metricsObject["country"] != null) { metricsObject["country"].splice(i,1) } // modified array size; decrement the counter; i--; } else { break; } } } } return metricsObject; }, }); return Metrics; });