-
Notifications
You must be signed in to change notification settings - Fork 8
/
opensubtitles.js
119 lines (99 loc) · 3.18 KB
/
opensubtitles.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
'use strict'
const got = require('got')
const methods = require('./methods.json')
module.exports = class OS {
constructor(settings = {}) {
if (!settings.apikey) throw Error('requires an apikey')
this._authentication = {}
this._settings = {
apikey: settings.apikey,
endpoint: settings.endpoint || 'https://api.opensubtitles.com/api/v1',
headers: {
'Content-Type': 'application/json',
'Accept': '*/*',
'User-Agent': settings.useragent || 'opensubtitles.com' + ' v' + require('./package.json').version
}
}
this._construct()
}
login(auth) {
if (!auth.username || !auth.password) {
throw Error('requires a username and a password')
}
return this.user.login(auth).then((response) => {
this._authentication.user = response.user
this._authentication.token = response.token
return response
})
}
logout() {
if (!this._authentication.token) {
throw Error('not logged in')
}
return this.user.logout().then((response) => {
this._authentication = {} //reset
return response
})
}
// Creates methods for all requests
_construct() {
for (let url in methods) {
const urlParts = url.split('/')
const name = urlParts.pop() // key for function
let tmp = this
for (let p = 1; p < urlParts.length; ++p) { // acts like mkdir -p
tmp = tmp[urlParts[p]] || (tmp[urlParts[p]] = {})
}
tmp[name] = (() => {
const method = methods[url] // closure forces copy
return (params) => {
return this._call(method, params)
}
})()
}
}
// Parse url before api call
_parse(method, params = {}) {
let url = this._settings.endpoint + method.url.split('?')[0]
// ?Part
const queryParts = []
const queryPart = method.url.split('?')[1]
if (queryPart) {
const queryParams = queryPart.split('&')
for (let i in queryParams) {
const name = queryParams[i].split('=')[0]; // that ; is needed
(params[name] || params[name] === 0) && queryParts.push(`${name}=${encodeURIComponent(params[name])}`)
}
}
if (queryParts.length) url += '?' + queryParts.join('&')
return url
}
// Parse methods then hit API
_call(method, params = {}) {
const url = this._parse(method, params)
let req = {
method: method.method,
headers: Object.assign({}, this._settings.headers)
}
// HEADERS Authorization
if (method.opts && method.opts.auth) {
if (!this._authentication.token && !params.token) throw Error('requires a bearer token, login first')
req.headers['Authorization'] = 'Bearer ' + (this._authentication.token || params.token)
}
// HEADERS Api-Key
req.headers['Api-Key'] = this._settings.apikey
// JSON body
if (req.method !== 'GET') {
req.body = (method.body ? Object.assign({}, method.body) : {})
for (let k in params) {
if (k in req.body) req.body[k] = params[k]
}
for (let k in req.body) {
if (!req.body[k]) delete req.body[k]
}
req.body = JSON.stringify(req.body)
}
// Actual call
return got(url, req).then(response => JSON.parse(response.body))
}
}