Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Wrapper around the HAL API. It allows to query the HAL database in a convenient

## Install
```bash
npm install --save @ezpaarse-project/methal
npm install --save methal
```

## Usage
Expand Down
77 changes: 49 additions & 28 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
const axios = require('axios');
const { Readable } = require('stream');
const querystring = require('querystring');
const config= ezpaarse.config;


/**
* Build a (sub)query string from search options
Expand All @@ -11,32 +13,32 @@ const querystring = require('querystring');
*/
function buildQuery (search, operator) {
search = search || {};
operator = operator || 'AND';
operator = operator || "AND";

const parts = [];
let negation; // NOT subquery

if (Array.isArray(search)) {
search.forEach(function (subquery) {
const part = buildQuery(subquery, 'AND');
const part = buildQuery(subquery, "AND");
if (part) { parts.push(part); }
});
} else {
let subquery;

for (const p in search) {
switch (p) {
case '$or':
subquery = buildQuery(search[p], 'OR');
if (subquery) parts.push(subquery);
case "$or":
subquery = buildQuery(search[p], "OR");
if (subquery) { parts.push(subquery); }
break;
case '$and':
subquery = buildQuery(search[p], 'AND');
if (subquery) parts.push(subquery);
case "$and":
subquery = buildQuery(search[p], "AND");
if (subquery) { parts.push(subquery); }
break;
case '$not':
subquery = buildQuery(search.$not, 'OR');
if (subquery) negation = `NOT(${subquery})`;
case "$not":
subquery = buildQuery(search.$not, "OR");
if (subquery) { negation = `NOT(${subquery})`; }
break;
default:
parts.push(`${p}:${search[p].toString()}`);
Expand All @@ -45,13 +47,13 @@ function buildQuery (search, operator) {
}

if (parts.length === 0) {
return negation || '';
return negation || "";
}

if (parts.length > 1 || negation) {
let query = negation ? `${negation} ${operator} (` : '(';
let query = negation ? `${negation} ${operator} (` : "(";
query += parts.join(`) ${operator} (`);
query += ')';
query += ")";
return query;
}

Expand All @@ -64,18 +66,18 @@ function buildQuery (search, operator) {
* @param {Function} callback(err, docs)
*/
exports.find = function (search, options, callback) {
if (typeof options === 'function') {
if (typeof options === "function") {
callback = options;
options = {};
}

exports.query(search, options, function (err, result) {
if (err) return callback(err);
if (err) { return callback(err); }

if (result.response && Array.isArray(result.response.docs)) {
callback(null, result.response.docs);
} else {
callback(new Error('unexpected result, documents not found'));
callback(new Error("unexpected result, documents not found"));
}
});
};
Expand All @@ -89,7 +91,7 @@ exports.find = function (search, options, callback) {
exports.findOne = function (search, options, callback) {
options = options || {};

if (typeof options === 'function') {
if (typeof options === "function") {
callback = options;
options = {};
}
Expand All @@ -99,10 +101,14 @@ exports.findOne = function (search, options, callback) {
exports.query(search, options, function (err, result) {
if (err) { return callback(err); }

if (result.response && Array.isArray(result.response.docs)) {
if (
result.response &&
Array.isArray(result.response.docs) &&
result.response.docs.length === 1
){
callback(null, result.response.docs[0]);
} else {
callback(new Error('unexpected result, documents not found'));
callback(new Error("unexpected result, documents not found"));
}
});
};
Expand All @@ -116,12 +122,13 @@ exports.findOne = function (search, options, callback) {
exports.query = function (search, options, callback) {
options = options || {};

if (typeof options === 'function') {
if (typeof options === "function") {
callback = options;
options = {};
}

const query = (typeof search === 'string' ? search : buildQuery(search, 'AND') || '*:*');
const query =
typeof search === "string" ? search : buildQuery(search, "AND") || "*:*";

const requestOptions = {};
if (options.hasOwnProperty('proxy')) {
Expand All @@ -130,9 +137,20 @@ exports.query = function (search, options, callback) {
}

// query link
let url = options.core
? `http://ccsdsolrvip.in2p3.fr:8080/solr/${options.core}/select?&wt=json&q=${encodeURIComponent(query)}`
: `http://api.archives-ouvertes.fr/search/?wt=json&q=${encodeURIComponent(query)}`;

const publicApi = config.publicHalCoreApiUrl || "http://api.archives-ouvertes.fr";
const privateApiUrl = config.privateHalCoreApiUrl || null;

let url ;
if (options.core === 'hal') {
if (privateApiUrl) {
url = `${privateApiUrl}?wt=json&q=${encodeURIComponent(query)}`
} else {
url = `${publicApi}/search?wt=json&q=${encodeURIComponent(query)}`;
}
} else {
url = `${publicApi}/${options.core}?${options.arg}`
}

// for convenience, add fields as an alias for fl
if (options.fields) {
Expand All @@ -141,12 +159,12 @@ exports.query = function (search, options, callback) {
}
// for convenience, convert fl to string if it's an array
if (Array.isArray(options.fl)) {
options.fl = options.fl.join(',');
options.fl = options.fl.join(",");
}

// append options to the query (ex: start=1, rows=10)
for (const p in options) {
url += `&${p}=${options[p]}`;
if (p !== 'core') { url += `&${p}=${options[p]}` };
}
axios.get(url, requestOptions).then(response => {
if (response.status !== 200) {
Expand All @@ -166,10 +184,12 @@ class ApiHalStream extends Readable {
q: '*'
}
) {
const publicApi = "http://api.archives-ouvertes.fr/search";
const privateApiUrl = 'http://ccsdsolrnodevipint.in2p3.fr:8983/solr/hal/apiselectall';
super({ objectMode: true });
this.reading = false;
this.counter = 0;
this.urlBase = 'http://api.archives-ouvertes.fr/search';
this.urlBase = privateApiUrl;
this.params = options;
this.params.sort = 'docid asc';
this.params.cursorMark = '*';
Expand Down Expand Up @@ -204,3 +224,4 @@ class ApiHalStream extends Readable {
}

exports.Stream = ApiHalStream;

57 changes: 46 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,58 @@
{
"name": "@ezpaarse-project/methal",
"version": "2.2.0",
"_args": [
[
"@ezpaarse-project/methal@2.1.0",
"/sites/ezpaarse/middlewares"
]
],
"_from": "@ezpaarse-project/methal@2.1.0",
"_id": "@ezpaarse-project/methal@2.1.0",
"_inBundle": false,
"_integrity": "sha512-zrnI7LWzKgs7DjMoSOwWraGUnfQxMxyOcjFAFw0vyPT7xHZ3YAswRusMBxLulnqNVASeVXsPzNQRoctlIfFBYQ==",
"_location": "/@ezpaarse-project/methal",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "@ezpaarse-project/methal@2.1.0",
"name": "@ezpaarse-project/methal",
"escapedName": "@ezpaarse-project%2fmethal",
"scope": "@ezpaarse-project",
"rawSpec": "2.1.0",
"saveSpec": null,
"fetchSpec": "2.1.0"
},
"_requiredBy": [
"/"
],
"_resolved": "https://registry.npmjs.org/@ezpaarse-project/methal/-/methal-2.1.0.tgz",
"_spec": "2.1.0",
"_where": "/sites/ezpaarse/middlewares",
"author": {
"name": "ezPAARSE Team"
},
"bugs": {
"url": "https://github.com/ezpaarse-project/MetHAL/issues"
},
"dependencies": {
"axios": "^0.18.0"
},
"description": "Wrapper around the HAL API.",
"main": "index.js",
"engines": {
"node": ">=4.0.0"
},
"scripts": {
"test": "nyc mocha"
},
"homepage": "https://github.com/ezpaarse-project/MetHAL#readme",
"license": "ISC",
"main": "index.js",
"name": "@ezpaarse-project/methal",
"repository": {
"type": "git",
"url": "https://github.com/ezpaarse-project/MetHAL.git"
"url": "git+https://github.com/ezpaarse-project/MetHAL.git"
},
"author": "ezPAARSE Team",
"license": "ISC",
"dependencies": {
"axios": "^0.18.0"
"scripts": {
"test": "nyc mocha"
},
"version": "2.1.0",
"devDependencies": {
"chai": "^4.2.0",
"mocha": "^6.0.2",
Expand Down