Mobrovac has submitted this change and it was merged.

Change subject: Make zotero.js an object
......................................................................


Make zotero.js an object

Convert zotero.js to ZoteroService.js
object.

Modify CitoidService.js to point to
an instance of a ZoteroService object.

Bug: T78389
Change-Id: I48158fc037277ee688ef35ab0db688a46aaf54d7
---
M lib/CitoidService.js
R lib/ZoteroService.js
M server.js
3 files changed, 90 insertions(+), 112 deletions(-)

Approvals:
  Mobrovac: Looks good to me, approved



diff --git a/lib/CitoidService.js b/lib/CitoidService.js
index 72b9334..73711dd 100644
--- a/lib/CitoidService.js
+++ b/lib/CitoidService.js
@@ -3,15 +3,13 @@
  */
 
 /* Import Modules */
-var crypto = require('crypto'),
-       urlParse = require('url'),
+var urlParse = require('url'),
        util = require('util');
 
 /* Import Local Modules */
 var unshorten = require('./unshorten.js'),
        scrape = require('./scrape.js'),
-       zoteroWebRequest = require('./zotero.js').zoteroWebRequest,
-       zoteroExportRequest = require('./zotero.js').zoteroExportRequest,
+       ZoteroService = require('./ZoteroService.js'),
        pubMedRequest = require('./pubMedRequest.js');
 
 /**
@@ -22,28 +20,23 @@
 function CitoidService(CitoidConfig, logger){
        this.CitoidConfig = CitoidConfig;
        this.log = logger;
-       this.zoteroURL = util.format('http://%s:%s/%s',
+       this.zoteroURL = util.format('http://%s:%s/',
                CitoidConfig.zoteroInterface, 
CitoidConfig.zoteroPort.toString());
+       this.zoteroService = new ZoteroService(this.zoteroURL, logger);
 }
 
 /**
  * Requests to the citoid service
  * @param  {String}   searchTerm   searchTerm metadata is being requested about
- * @param  {Object}   opts         zoteroWebRequest options object
+ * @param  {Object}   format       export format
  * @param  {Function} callback     callback (error, statusCode, body)
  */
 CitoidService.prototype.request = function(searchTerm, format, callback){
 
-       var citoidService = this,
-               sessionID = crypto.randomBytes(20).toString('hex'), //required 
zotero- not terribly important for this to be secure
-               opts = {
-                       zoteroURL:citoidService.zoteroURL,
-                       sessionID:sessionID,
-                       format:format
-               };
+       var citoidService = this;
 
        citoidService.distinguish(searchTerm, function(extractedID, 
runnerFunction){
-               runnerFunction(extractedID, opts, function(error, responseCode, 
body){
+               runnerFunction(extractedID, format, function(error, 
responseCode, body){
                        callback(error, responseCode, body);
                });
        });
@@ -52,17 +45,20 @@
 /**
  * Request citation metadata from a URL
  * @param  {String}   requestedURL URL metadata is being requested about
- * @param  {Object}   opts         zoteroWebRequest options object
+ * @param  {Object}   format       requested export format
  * @param  {Function} callback     callback (error, statusCode, body)
  */
-CitoidService.prototype.requestFromURL = function (requestedURL, opts, 
callback){
-       var log = this.log;
-       zoteroWebRequest(requestedURL, opts, function(error, response, body){
+CitoidService.prototype.requestFromURL = function (requestedURL, format, 
callback){
+       var self = this,
+               log = self.log,
+               zoteroWebRequest = 
this.zoteroService.zoteroWebRequest.bind(this.zoteroService);
+
+       zoteroWebRequest(requestedURL, format, function(error, response, body){
                log.info("Zotero request made for: " + requestedURL);
                if (error) {
                        log.error(error);
                        log.info("Falling back on native scraper.");
-                       scrapeHelper(requestedURL, opts, callback);
+                       self.scrapeHelper(requestedURL, format, callback);
                } else if (response) {
                        //501 indicates no translator available
                        //this is common- can indicate shortened url
@@ -76,18 +72,18 @@
                                unshorten(requestedURL, function(detected, 
expandedURL) {
                                        if (detected) {
                                                log.info("Redirect detected to 
"+ expandedURL);
-                                               zoteroWebRequest(expandedURL, 
opts, function(error, response, body){
+                                               zoteroWebRequest(expandedURL, 
format, function(error, response, body){
                                                        if (response && !error 
&& response.statusCode === 200){
                                                                
log.info("Successfully retrieved and translated body from Zotero");
                                                                callback(null, 
200, body);
                                                        } else {
                                                                log.info("No 
Zotero response available; falling back on native scraper.");
-                                                               
scrapeHelper(requestedURL, opts, callback);
+                                                               
self.scrapeHelper(requestedURL, format, callback);
                                                        }
                                                });
                                        } else {
                                                log.info("No redirect detected; 
falling back on native scraper.");
-                                               scrapeHelper(requestedURL, 
opts, callback);
+                                               self.scrapeHelper(requestedURL, 
format, callback);
                                        }
                                });
                        } else if (response.statusCode === 200){
@@ -96,11 +92,11 @@
                        } else {
                                //other response codes such as 500, 300
                                log.info("Falling back on native scraper.");
-                               scrapeHelper(requestedURL, opts, callback);
+                               self.scrapeHelper(requestedURL, format, 
callback);
                        }
                } else {
                        log.info("Falling back on native scraper.");
-                       scrapeHelper(requestedURL, opts, callback);
+                       self.scrapeHelper(requestedURL, format, callback);
                }
        });
 };
@@ -108,29 +104,29 @@
 /**
  * Request citation metadata from a DOI
  * @param  {String}   requestedDOI DOI pointing to URL metadata is being 
requested about
- * @param  {Object}   opts         zoteroWebRequest options object
+ * @param  {Object}   format       requested export format
  * @param  {Function} callback     callback (error, statusCode, body)
  */
-CitoidService.prototype.requestFromDOI = function (requestedDOI, opts, 
callback){
+CitoidService.prototype.requestFromDOI = function (requestedDOI, format, 
callback){
        var doiLink = 'http://dx.doi.org/'+ requestedDOI;
        //TODO: optimise this (can skip some steps in requestFromURL)
-       this.requestFromURL(doiLink, opts, callback);
+       this.requestFromURL(doiLink, format, callback);
 };
 
 /**
  * Request citation metadata from a PubMed identifier. Supports PMID, PMCID, 
Manuscript ID and versioned identifiers
  * @param  {String}   requestedPubMedID  PubMed identifier for which metadata 
is being requested. PMCID identifiers must begin with 'PMC'
- * @param  {Object}   opts               zoteroWebRequest options object
+ * @param  {Object}   format             requested export format
  * @param  {Function} callback           callback (error, statusCode, body)
  */
-CitoidService.prototype.requestFromPubMedID = function(requestedPubMedID, 
opts, callback){
+CitoidService.prototype.requestFromPubMedID = function(requestedPubMedID, 
format, callback){
     pubMedRequest(requestedPubMedID, function(error, obj){
                if(error){
                        callback(error, null, null);
                } else {
                        var doi = obj.records[0].doi;
                        this.log.info("Got DOI " + doi);
-                       this.requestFromDOI(doi, opts, callback);
+                       this.requestFromDOI(doi, format, callback);
                }
        });
 };
@@ -180,15 +176,16 @@
  * sends response to Zotero if it's a format Zotero can convert to.
  * Currently only exports bibtex.
  * @param  {String}   url      requested URL
- * @param  {Object}   opts     request options object
+ * @param  {Object}   format   requested export format
  * @param  {Function} callback callback(error, responseCode, citation)
  */
-function scrapeHelper(url, opts, callback) {
-       if (opts.format === 'bibtex') {
+CitoidService.prototype.scrapeHelper = function(url, format, callback) {
+       var zoteroExportRequest = 
this.zoteroService.zoteroExportRequest.bind(this.zoteroService);
+       if (format === 'bibtex') {
                scrape(url, function(error, responseCode, citation) {
-                       zoteroExportRequest(citation[0], opts, function(err, 
resCode, body) {
+                       zoteroExportRequest(citation[0], format, function(err, 
resCode, body) {
                                if (resCode !== 200){
-                                       body = "Unable to serve this format at 
this time";
+                                       body = "Unable to serve "+ format +" 
format at this time";
                                        resCode = 404; // 404 error if cannot 
translate into alternate format
                                } else if (responseCode !== 200){
                                        resCode = 520; // 520 error if the 
scraper couldn't scrape from url
@@ -199,8 +196,6 @@
        } else {
                scrape(url, callback);
        }
-}
+};
 
-module.exports = {
-       CitoidService: CitoidService,
-};
\ No newline at end of file
+module.exports = CitoidService;
diff --git a/lib/zotero.js b/lib/ZoteroService.js
similarity index 75%
rename from lib/zotero.js
rename to lib/ZoteroService.js
index 16fbbf2..0cc4a0c 100644
--- a/lib/zotero.js
+++ b/lib/ZoteroService.js
@@ -6,31 +6,41 @@
  */
 
 /* Import Modules */
-var request = require('request'),
-       async = require('async'),
-       util = require('util'),
+var    async = require('async'),
+       crypto = require('crypto'),
+       request = require('request'),
        pubMedRequest = require('./pubMedRequest.js');
+
+function ZoteroService(zoteroURL, logger){
+       this.log = logger;
+       this.baseURL = zoteroURL;
+       this.webURL = zoteroURL + 'web';
+       this.exportURL = zoteroURL + 'export';
+}
 
 /**
  * Requests to Zotero server endpoint /web
  * @param  {String}   requestedURL url being requested
- * @param  {Object}   opts         options for request
+ * @param  {Object}   format         options for request
  * @param  {Function} callback     callback(error, response, body)
  */
-var zoteroWebRequest = function(requestedURL, opts, callback){
-       var options = {
-               url: util.format(opts.zoteroURL, 'web'),
+ZoteroService.prototype.zoteroWebRequest = function(requestedURL, format, 
callback){
+
+       var zoteroService = this,
+               sessionID = crypto.randomBytes(20).toString('hex'),
+               options = {
+               url: this.webURL,
                method: 'POST',
                json: {
                        "url": requestedURL,
-                       "sessionid": opts.sessionID
+                       "sessionid": sessionID
                }
        };
 
        request(options, function (error, response, body) {
                if (!error && response.statusCode === 200) {
-                       selectFormatFcn(opts.format, function(convert){
-                               convert(requestedURL, opts, body, 
function(modifiedBody){
+                       zoteroService.selectFormatFcn(format, function(convert){
+                               convert(requestedURL, format, body, 
function(modifiedBody){
                                        callback(error, response, modifiedBody);
                                });
                        });
@@ -44,15 +54,15 @@
 /**
  * Request to Zotero server endpoint /export
  * @param  {Object}   citation     Zotero JSON citation to be converted
- * @param  {Object}   opts         options for request
+ * @param  {Object}   format         options for request
  * @param  {Function} callback     callback(error, responseCode, body)
  */
-var zoteroExportRequest = function(citation, opts, callback){
+ZoteroService.prototype.zoteroExportRequest = function(citation, format, 
callback){
        var options = {
-               url: util.format(opts.zoteroURL, 'export'),
+               url: this.exportURL,
                method: 'POST',
                body: JSON.stringify([citation]),
-               qs: {format: opts.format},
+               qs: {format: format},
                headers: {
                        'content-type': 'application/json'
                }
@@ -72,14 +82,15 @@
  * @param  {String}   format   string describing format
  * @param  {Function} callback callback(desiredFunctionHere)
  */
-var selectFormatFcn = function (format, callback){
-       var formatFcns = {
-               'mwDeprecated':convertToMWDeprecatedAsync,
-               'mediawiki':convertToMediawikiAsync,
-               'zotero':convertToZoteroAsync,
-               'bibtex':convertToBibtexAsync
+ZoteroService.prototype.selectFormatFcn = function (format, callback){
+       var self = this,
+               formatFcns = {
+               'mwDeprecated':self.convertToMWDeprecatedAsync,
+               'mediawiki':self.convertToMediawikiAsync,
+               'zotero':self.convertToZoteroAsync,
+               'bibtex':self.convertToBibtexAsync
                };
-       callback(formatFcns[format]);
+       callback(formatFcns[format].bind(self));
 };
 
 /* Specific Conversion Methods */
@@ -87,11 +98,11 @@
 /**
  * Takes Zotero output and standardises it
  * @param  {String}   url      URL provided by user
- * @param  {Object}   opts     opts object for Zotero requests
+ * @param  {Object}   format   requested format
  * @param  {Array}    body     Array of citation objects
  * @param  {Function} callback callback(arrayOfCitationObjs)
  */
-var convertToZoteroAsync = function (url, opts, body, callback){
+ZoteroService.prototype.convertToZoteroAsync = function(url, format, body, 
callback){
        var citation = body[0];
        if (citation instanceof Array){
                citation = citation[0];
@@ -112,12 +123,13 @@
 /**
  * Takes Zotero output, standardises, and exports to BibTex
  * @param  {String}   url      URL provided by user
- * @param  {Object}   opts     opts object for Zotero requests
+ * @param  {Object}   format   requested format
  * @param  {Array}    body     Array of citation objects
  * @param  {Function} callback callback(arrayOfCitationObjs)
  */
-var convertToBibtexAsync = function(url, opts, body, callback){
-       var citation = body[0];
+ZoteroService.prototype.convertToBibtexAsync = function(url, format, body, 
callback){
+       var zoteroService = this,
+               citation = body[0];
        if (citation instanceof Array) {
                citation = citation[0];
        }
@@ -129,23 +141,22 @@
                fixURL, //must go directly after unnamed function that hands it 
url
                fixAccessDate,
                function(citation, cb){
-                       zoteroExportRequest(citation, opts, function(error, 
responseCode, body){
+                       zoteroService.zoteroExportRequest(citation, format, 
function(error, responseCode, body){
                                cb(error, body);
                        });
        }], function (err, citation) {
                callback(citation);
        });
-
 };
 
 /**
  * Takes Zotero output and converts to 'mediawiki' format
  * @param  {String}   url      URL provided by user
- * @param  {Object}   opts     opts object for Zotero requests
+ * @param  {Object}   format   requested format
  * @param  {Array}    body     Array of citation objects
  * @param  {Function} callback callback(arrayOfCitationObjs)
  */
-var convertToMediawikiAsync = function (url, opts, body, callback){
+ZoteroService.prototype.convertToMediawikiAsync = function(url, format, body, 
callback){
        var citation = body[0];
        if (citation instanceof Array){
                citation = citation[0];
@@ -164,17 +175,16 @@
        ], function (err, citation) {
                callback([citation]);
        });
-
 };
 
 /**
  * Takes Zotero output and converts to 'mwDeprecated' format
  * @param  {String}   url      URL provided by user
- * @param  {Object}   opts     opts object for Zotero requests
+ * @param  {Object}   format   requested format
  * @param  {Array}    body     Array of citation objects
  * @param  {Function} callback callback(arrayOfCitationObjs)
  */
-var convertToMWDeprecatedAsync = function (url, opts, body, callback){
+ZoteroService.prototype.convertToMWDeprecatedAsync = function(url, format, 
body, callback){
        var zotCreators, creatorFieldName,
                creatorTypeCount = {},
                citation = body[0];
@@ -226,7 +236,7 @@
  * @param  {Object}   citation     citation object
  * @param  {Function} callback     callback on citation object
  */
-var replaceCreators = function(citation, callback){
+ function replaceCreators(citation, callback){
        if (citation.creators) {
                var creatorArray, creatorFieldName,
                        zotCreators = citation.creators;
@@ -245,14 +255,14 @@
                delete citation.creators; //remove creators field
        }
        callback(null, citation);
-};
+}
 
 /**
  * Add PMID and PMCID fields from the extra field or through DOI lookup
  * @param  {Object}   citation citation object to add PMID
  * @param  {Function} callback callback (error, citation)
  */
-var addPubMedIdentifiers = function(citation, callback){
+function addPubMedIdentifiers(citation, callback){
        if (citation.extra) {
                //get pmid from extra fields
                var extraFields = citation.extra.split('\n');
@@ -281,7 +291,7 @@
        } else {
                callback(null, citation);
        }
-};
+}
 
 /**
  * Add URL provided by user if none in Zotero response
@@ -289,31 +299,31 @@
  * @param  {Object}   citation citation object to add PMID
  * @param  {Function} callback callback (error, citation)
  */
-var fixURL = function(url, citation, callback){
+function fixURL(url, citation, callback){
        if (!citation.url){
                citation.url = url;
        }
        callback(null, citation);
-};
+}
 
 /**
  * Replace Zotero output of CURRENT_TIMESTAMP with ISO time
  * @param  {Object}   citation     citation object
  * @param  {Function} callback     callback on citation object
  */
-var fixAccessDate = function(citation, callback){
+function fixAccessDate(citation, callback){
        if (!citation.accessDate || (citation.accessDate === 
"CURRENT_TIMESTAMP")){
                citation.accessDate = (new Date()).toISOString().substring(0, 
10);
        }
        callback(null, citation);
-};
+}
 
 /**
  * Convert String of ISSNs into an Array of ISSNs
  * @param  {Object}   citation     citation object
  * @param  {Function} callback     callback on citation object
  */
-var fixISSN = function(citation, callback){
+function fixISSN(citation, callback){
        var match, i, reISSN,
                issn = citation.ISSN;
 
@@ -332,14 +342,14 @@
                }
        }
        callback(null, citation);
-};
+}
 
 /**
  * Convert String of ISBNs into an Array of ISBNs
  * @param  {Object}   citation     citation object
  * @param  {Function} callback     callback on citation object
  */
-var fixISBN = function(citation, callback){
+function fixISBN(citation, callback){
        var match, i, reISBN,
                isbn = citation.ISBN;
 
@@ -358,35 +368,8 @@
                }
        }
        callback(null, citation);
-};
-
-/* Test response alterations without having to use server */
-var testJSON = function(){
-       var sampleBody = require("../test_files/4_input.json");
-       console.log("before:");
-       console.log(JSON.stringify(sampleBody));
-       console.log("after:");
-       selectFormatFcn("mwDeprecated", function(convert){
-               convert("http://example.com";, null, sampleBody, 
function(modifiedBody){
-                       console.log(JSON.stringify(modifiedBody));
-               });
-       });
-
-       //test PMID lookup
-       addPubMedIdentifiers({"DOI": "10.1371/journal.pcbi.1002947"}, function 
(error, modifiedCitation){
-               console.log("Test lookup of PMID by DOI: PMID=" + 
modifiedCitation.PMID + ", PMCID=" + modifiedCitation.PMCID);
-               console.log("Expected: PMID=23555203, PMCID=PMC3605911");
-       });
-};
-
-/* Test methods in main */
-if (require.main === module) {
-       testJSON();
 }
 
 /* Exports */
-module.exports = {
-       zoteroWebRequest: zoteroWebRequest,
-    zoteroExportRequest: zoteroExportRequest
-};
+module.exports = ZoteroService;
 
diff --git a/server.js b/server.js
index b364eac..72aa82f 100644
--- a/server.js
+++ b/server.js
@@ -17,7 +17,7 @@
        argv = opts.argv;
 
 /* Import Local Modules */
-var CitoidService  = require('./lib/CitoidService.js').CitoidService;
+var CitoidService  = require('./lib/CitoidService.js');
 
 /* Import Local Settings */
 var settingsFile = path.resolve(process.cwd(), argv.c),

-- 
To view, visit https://gerrit.wikimedia.org/r/192197
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I48158fc037277ee688ef35ab0db688a46aaf54d7
Gerrit-PatchSet: 16
Gerrit-Project: mediawiki/services/citoid
Gerrit-Branch: master
Gerrit-Owner: Mvolz <mv...@wikimedia.org>
Gerrit-Reviewer: Jforrester <jforres...@wikimedia.org>
Gerrit-Reviewer: Mobrovac <mobro...@wikimedia.org>
Gerrit-Reviewer: Mvolz <mv...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to