This repository has been archived by the owner on Aug 3, 2024. It is now read-only.
forked from GetDKAN/recline
-
Notifications
You must be signed in to change notification settings - Fork 0
/
backend.ckan_get.js
172 lines (156 loc) · 4.98 KB
/
backend.ckan_get.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
this.recline = this.recline || {};
this.recline.Backend = this.recline.Backend || {};
this.recline.Backend.Ckan = this.recline.Backend.Ckan || {};
(function(my) {
// ## CKAN Backend
//
// This provides connection to the CKAN DataStore (v2)
//
// General notes
//
// We need 2 things to make most requests:
//
// 1. CKAN API endpoint
// 2. ID of resource for which request is being made
//
// There are 2 ways to specify this information.
//
// EITHER (checked in order):
//
// * Every dataset must have an id equal to its resource id on the CKAN instance
// * The dataset has an endpoint attribute pointing to the CKAN API endpoint
//
// OR:
//
// Set the url attribute of the dataset to point to the Resource on the CKAN instance. The endpoint and id will then be automatically computed.
my.__type__ = 'ckan_get';
// private - use either jQuery or Underscore Deferred depending on what is available
var Deferred = _.isUndefined(this.jQuery) ? _.Deferred : jQuery.Deferred;
// Default CKAN API endpoint used for requests (you can change this but it will affect every request!)
//
// DEPRECATION: this will be removed in v0.7. Please set endpoint attribute on dataset instead
my.API_ENDPOINT = 'http://datahub.io/api';
// ### fetch
my.fetch = function(dataset) {
var wrapper;
if (dataset.endpoint) {
wrapper = my.DataStore(dataset.endpoint);
} else {
var out = my._parseCkanResourceUrl(dataset.url);
dataset.id = out.resource_id;
wrapper = my.DataStore(out.endpoint);
}
var dfd = new Deferred();
var jqxhr = wrapper.search({resource_id: dataset.id, limit: 0});
jqxhr.done(function(results) {
// map ckan types to our usual types ...
var fields = _.map(results.result.fields, function(field) {
field.type = field.type in CKAN_TYPES_MAP ? CKAN_TYPES_MAP[field.type] : field.type;
return field;
});
var out = {
fields: fields,
useMemoryStore: false
};
dfd.resolve(out);
});
return dfd.promise();
};
// only put in the module namespace so we can access for tests!
my._normalizeQuery = function(queryObj, dataset) {
var actualQuery = {
resource_id: dataset.id,
q: queryObj.q,
filters: {},
limit: queryObj.size || 10,
offset: queryObj.from || 0
};
if (queryObj.sort && queryObj.sort.length > 0) {
var _tmp = _.map(queryObj.sort, function(sortObj) {
return sortObj.field + ' ' + (sortObj.order || '');
});
actualQuery.sort = _tmp.join(',');
}
if (queryObj.filters && queryObj.filters.length > 0) {
_.each(queryObj.filters, function(filter) {
if (filter.type === "term") {
actualQuery.filters[filter.field] = filter.term;
}
});
}
return actualQuery;
};
my.query = function(queryObj, dataset) {
var wrapper;
if (dataset.endpoint) {
wrapper = my.DataStore(dataset.endpoint);
} else {
var out = my._parseCkanResourceUrl(dataset.url);
dataset.id = out.resource_id;
wrapper = my.DataStore(out.endpoint);
}
var actualQuery = my._normalizeQuery(queryObj, dataset);
var dfd = new Deferred();
var jqxhr = wrapper.search(actualQuery);
jqxhr.done(function(results) {
var out = {
total: results.result.total,
hits: results.result.records
};
dfd.resolve(out);
});
return dfd.promise();
};
// ### DataStore
//
// Simple wrapper around the CKAN DataStore API
//
// @param endpoint: CKAN api endpoint (e.g. http://datahub.io/api)
my.DataStore = function(endpoint) {
var that = {endpoint: endpoint || my.API_ENDPOINT};
function objToQuery(obj) {
var str = '';
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
if (typeof obj[p] !== 'object') {
str += '&' + p + '=' + obj[p] ;
}
}
}
return str;
}
that.search = function(data) {
// This is the only difference between this and the ckan, it uses GET
// instead of POST.
var filters = "";
if (data.filters) {
for (var filter in data.filters) {
filters = "&filters[" + filter + "]=" + data.filters[filter];
}
}
var searchUrl = that.endpoint + '/3/action/datastore_search?=' + objToQuery(data) + filters;
var jqxhr = jQuery.ajax({
url: searchUrl,
type: 'GET',
});
return jqxhr;
};
return that;
};
// Parse a normal CKAN resource URL and return API endpoint etc
//
// Normal URL is something like http://demo.ckan.org/dataset/some-dataset/resource/eb23e809-ccbb-4ad1-820a-19586fc4bebd
my._parseCkanResourceUrl = function(url) {
parts = url.split('/');
var len = parts.length;
return {
resource_id: parts[len-1],
endpoint: parts.slice(0,[len-4]).join('/') + '/api'
};
};
var CKAN_TYPES_MAP = {
'int4': 'integer',
'int8': 'integer',
'float8': 'float'
};
}(this.recline.Backend.Ckan));