Added support for custom request options

This commit is contained in:
freearhey 2021-04-02 20:12:27 +03:00
parent 6860beba28
commit ee4d3534d5
8 changed files with 2281 additions and 181 deletions

3
babel.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
presets: [['@babel/preset-env', { targets: { node: 'current' } }]]
}

2319
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -29,11 +29,16 @@
"commander": "^7.1.0",
"dayjs": "^1.10.4",
"glob": "^7.1.6",
"lodash.merge": "^4.6.2",
"tough-cookie": "^4.0.0",
"xml-js": "^1.6.11"
},
"devDependencies": {
"@babel/core": "^7.13.14",
"@babel/preset-env": "^7.13.12",
"babel-jest": "^26.6.3",
"eslint": "^7.22.0",
"jest": "^26.6.3"
"jest": "^26.6.3",
"jest-mock-axios": "^4.3.0"
}
}

View File

@ -18,7 +18,6 @@ async function main() {
const options = program.opts()
const config = utils.loadConfig(options.config)
const client = utils.createHttpClient(config)
const channels = utils.parseChannels(config.channels)
const utcDate = utils.getUTCDate()
const dates = Array.from({ length: config.days }, (_, i) => utcDate.add(i, 'd'))
@ -33,10 +32,9 @@ async function main() {
let programs = []
console.log('Parsing:')
for (let item of queue) {
const url = typeof config.url === 'function' ? config.url(item) : config.url
if (options.debug) console.time(' time')
const progs = await client
.get(url)
const progs = await utils
.fetchData(item, config)
.then(response => {
if (!item.channel.logo && config.logo) {
item.channel.logo = config.logo({

View File

@ -1,9 +1,10 @@
const fs = require('fs')
const path = require('path')
const axios = require('axios')
const axios = require('axios').default
const axiosCookieJarSupport = require('axios-cookiejar-support').default
const tough = require('tough-cookie')
const convert = require('xml-js')
const merge = require('lodash.merge')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
dayjs.extend(utc)
@ -31,20 +32,26 @@ utils.loadConfig = function (file) {
config.channels = path.join(path.dirname(file), config.channels)
return Object.assign(
{},
{
userAgent:
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 Edg/79.0.309.71',
const defaultConfig = {
days: 1,
cookie: '',
lang: 'en',
delay: 3000,
timeout: 5000,
output: 'guide.xml'
output: 'guide.xml',
request: {
method: 'GET',
headers: {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 Edg/79.0.309.71',
Cookie: ''
},
config
)
timeout: 5000,
withCredentials: true,
jar: new tough.CookieJar(),
responseType: 'arraybuffer'
}
}
return merge(defaultConfig, config)
}
utils.parseChannels = function (filename) {
@ -154,7 +161,7 @@ utils.convertToXMLTV = function ({ config, channels, programs }) {
}
utils.parsePrograms = function ({ response, item, config }) {
const options = Object.assign({}, item, config, {
const options = merge(item, config, {
content: response.data.toString(),
buffer: response.data
})
@ -177,17 +184,12 @@ utils.writeToFile = function (filename, data) {
fs.writeFileSync(path.resolve(filename), data)
}
utils.createHttpClient = function (config) {
return axios.create({
headers: {
'User-Agent': config.userAgent,
Cookie: config.cookie
},
timeout: config.timeout,
withCredentials: true,
jar: new tough.CookieJar(),
responseType: 'arraybuffer'
})
utils.fetchData = function (item, config) {
const options = config.request
options.url = typeof config.url === 'function' ? config.url(item) : config.url
options.data = typeof options.data === 'function' ? options.data(item) : options.data
return axios(options)
}
utils.getUTCDate = function () {

2
tests/__mocks__/axios.js Normal file
View File

@ -0,0 +1,2 @@
import mockAxios from 'jest-mock-axios'
export default mockAxios

View File

@ -2,6 +2,16 @@ module.exports = {
site: 'example.com',
channels: 'example.com.channels.xml',
url: () => 'http://example.com/20210319/1tv.json',
request: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Cookie: 'abc=123'
},
data() {
return { accountID: '123' }
}
},
parser: () => [],
logo: () => 'http://example.com/logos/1TV.png'
}

View File

@ -1,22 +1,28 @@
const utils = require('../src/utils')
import mockAxios from 'jest-mock-axios'
import utils from '../src/utils'
it('can load valid config.js', () => {
expect(Object.keys(utils.loadConfig('./tests/input/example.com.config.js')).sort()).toEqual(
[
'site',
'channels',
'url',
'logo',
'parser',
'cookie',
'days',
'delay',
'timeout',
'lang',
'output',
'userAgent'
].sort()
)
const config = utils.loadConfig('./tests/input/example.com.config.js')
expect(config).toMatchObject({
channels: 'tests/input/example.com.channels.xml',
days: 1,
delay: 3000,
lang: 'en',
output: 'guide.xml',
site: 'example.com'
})
expect(config.request).toMatchObject({
timeout: 5000,
headers: {
'Content-Type': 'application/json',
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 Edg/79.0.309.71',
Cookie: 'abc=123'
}
})
expect(typeof config.request.data).toEqual('function')
expect(typeof config.url).toEqual('function')
expect(typeof config.logo).toEqual('function')
})
it('can parse valid channels.xml', () => {
@ -70,3 +76,24 @@ it('can escape url', () => {
'http://example.com/logos/1TV.png?param1=val&param2=val'
)
})
it('can fetch data', () => {
const config = utils.loadConfig('./tests/input/example.com.config.js')
utils.fetchData({}, config).then(jest.fn).catch(jest.fn)
expect(mockAxios).toHaveBeenCalledWith(
expect.objectContaining({
data: { accountID: '123' },
headers: {
'Content-Type': 'application/json',
Cookie: 'abc=123',
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 Edg/79.0.309.71'
},
method: 'POST',
responseType: 'arraybuffer',
timeout: 5000,
url: 'http://example.com/20210319/1tv.json',
withCredentials: true
})
)
})