Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9660d8d
Showing
20 changed files
with
323 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"presets": [ | ||
"es2015" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
root = true | ||
|
||
[*] | ||
encoding = utf-8 | ||
end_of_line = lf | ||
insert_final_newline = true | ||
|
||
[*.js] | ||
indent_style = tab |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
MAL_USER= | ||
MAL_PASS= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules/ | ||
dist/ | ||
docs/ | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"source": { | ||
"include": ["src"] | ||
}, | ||
"opts": { | ||
"template": "node_modules/docdash", | ||
"destination": "./docs/" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
src |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
#node-anime-list |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"name": "node-anime-list", | ||
"version": "0.1.0", | ||
"description": "Scrapper for MyAnimeList site", | ||
"main": "dist/index.js", | ||
"scripts": { | ||
"test": "xo src/* && ava test/**/*.test.js --require babel-register", | ||
"docs": "jsdoc -c .jsdocrc -r", | ||
"build": "babel src --out-dir dist", | ||
"prepublish": "npm run build" | ||
}, | ||
"keywords": [ | ||
"myanimelist", | ||
"mal", | ||
"scrap" | ||
], | ||
"author": "lubien <lubien1996@gmail.com> (http://lubien.me)", | ||
"license": "MIT", | ||
"dependencies": { | ||
"debug": "^2.2.0", | ||
"got": "^6.3.0", | ||
"xml2js-es6-promise": "^1.0.3" | ||
}, | ||
"devDependencies": { | ||
"ava": "^0.15.2", | ||
"babel": "^6.5.2", | ||
"babel-preset-es2015": "^6.9.0", | ||
"docdash": "^0.4.0", | ||
"dotenv": "^2.0.0", | ||
"jsdoc": "^3.4.0", | ||
"xo": "^0.16.0" | ||
}, | ||
"xo": { | ||
"rules": { | ||
"comma-dangle": ["error", "always-multiline"] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import generateAuthToken from '../utils/generate-auth-token'; | ||
|
||
const debug = require('debug')('node-anime-list:authenticable'); | ||
|
||
export default function authenticable(state) { | ||
state.authToken = generateAuthToken(state.username, state.password); | ||
return { | ||
getUser() { | ||
return state.username; | ||
}, | ||
|
||
setUser(username, password) { | ||
debug(`Setting '${username}' as user. Use pass = ${Boolean(password)}`); | ||
state.username = username; | ||
state.password = password; | ||
state.authToken = generateAuthToken(username, password); | ||
|
||
return this; | ||
}, | ||
|
||
verifyCredentials() { | ||
if (!state.username || !state.authToken) { | ||
debug('Tried to verify a null user'); | ||
throw new Error(`Can't verify a null user`); | ||
} | ||
|
||
debug(`Verifying credentials for '${state.username}'`); | ||
return this._requestApi('/account/verify_credentials.xml'); | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import xml2js from 'xml2js-es6-promise'; | ||
import request from '../utils/request'; | ||
import cleanApiData from '../utils/clean-api-data'; | ||
|
||
const debug = require('debug')('node-anime-list:requester'); | ||
|
||
export default function requester(state) { | ||
return { | ||
_requestHtml(url = '/', query = {}) { | ||
return request(state.authToken, url, query); | ||
}, | ||
|
||
_requestApi(url, query = {}) { | ||
debug('API request'); | ||
|
||
if (!state.username || !state.authToken) { | ||
debug('Not authenticated'); | ||
throw new Error('Must have username and password set to access the API'); | ||
} | ||
|
||
return request(state.authToken, `/api${url}`, query) | ||
.then(res => xml2js(res.body)) | ||
.then(parsedXml => Promise.resolve(cleanApiData(parsedXml))); | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
function searchable() { | ||
return { | ||
searchAnimes(name) { | ||
return this._requestApi(`/anime/search.xml`, {q: name}); | ||
}, | ||
|
||
searchMangas(name) { | ||
return this._requestApi(`/manga/search.xml`, {q: name}); | ||
}, | ||
}; | ||
} | ||
|
||
module.exports = searchable; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import authenticable from './composers/authenticable'; | ||
import searchable from './composers/searchable'; | ||
import requester from './composers/requester'; | ||
|
||
const debug = require('debug')('node-anime-list:mal'); | ||
|
||
export default function mal(username = '', password = '') { | ||
debug( | ||
`New mal client user '${username}'. Use password = ${Boolean(password)}` | ||
); | ||
|
||
const state = { | ||
username, | ||
password, | ||
authToken: '', | ||
}; | ||
|
||
return Object.assign({}, | ||
requester(state), | ||
authenticable(state), | ||
searchable(state) | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import flattenObject from './flatten-object'; | ||
|
||
/** | ||
* @module utils/cleanApiData | ||
* @description Cleans XML parsed JSON from MAL. | ||
* @requires utils/flattenObject | ||
* | ||
* @example | ||
* cleanApiData({ anime: { entry: [ { key: ['value'] } ] } }) | ||
* [ { key: 'value' } ] | ||
* | ||
* cleanApiData({ manga: { entry: [ { key: ['value'] } ] } }) | ||
* [ { key: 'value' } ] | ||
* | ||
* cleanApiData({ user: { key: ['value'] } }) | ||
* { key: 'value' } | ||
* | ||
* @param {object} data - MyAnimeList's API parsed XML | ||
* @return {object} - Good looking object | ||
*/ | ||
export default function cleanApiData(data) { | ||
if (data === null) { | ||
return data; | ||
} | ||
|
||
let newData = data.anime || data.manga || data.user || data; | ||
|
||
if (Array.isArray(newData.entry)) { | ||
newData.entry.map(flattenObject); | ||
newData = newData.entry; | ||
} else if (typeof newData === 'object') { | ||
newData = flattenObject(newData); | ||
} | ||
|
||
return newData; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* @module utils/flattenObject | ||
* @description Flatten XML parsed objects containing one | ||
* element arrays as values | ||
* | ||
* @example | ||
* flattenObject({a: [1], b: [2]}); | ||
* {a: 1, b: 2} | ||
* | ||
* flattenObject({username: ['lubien']}); | ||
* {username: 'lubien'} | ||
* | ||
* @param {object} obj - An object whose key's values are one element arrays | ||
* @return {object} - Flattened object | ||
*/ | ||
export default function flattenObject(obj) { | ||
const newObj = {}; | ||
|
||
for (const key of Object.keys(obj)) { | ||
newObj[key] = obj[key][0]; | ||
} | ||
|
||
return newObj; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default function generateAuthToken(username, password) { | ||
return new Buffer(`${username}:${password}`).toString('base64'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import got from 'got'; | ||
|
||
const debug = require('debug')('node-anime-list:request'); | ||
|
||
export default function request(authToken, url = '/', query = {}) { | ||
debug('Requesting %s with query', url, query); | ||
debug('Using auth:', `Basic ${authToken}`); | ||
return got(`http://myanimelist.net${url}`, { | ||
query, | ||
headers: { | ||
Authorization: `Basic ${authToken}`, | ||
}, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import test from 'ava'; | ||
import mal from '../../src'; | ||
import instance from '../instance'; | ||
import authenticable from '../../src/composers/authenticable'; | ||
|
||
test('Authenticable displays your username from state', t => { | ||
const state = {username: 'lubien'}; | ||
t.is(authenticable(state).getUser(), 'lubien'); | ||
}); | ||
|
||
test('You can reset the username and password', t => { | ||
const obj = authenticable({ | ||
username: 'lubien', | ||
password: '', | ||
}); | ||
|
||
obj.setUser('newuser', 'newpass'); | ||
t.is(obj.getUser(), 'newuser'); | ||
}); | ||
|
||
test('You can verify your auth', async t => { | ||
const credentials = await instance.verifyCredentials(); | ||
t.is(credentials.username, instance.getUser()); | ||
}); | ||
|
||
test('Verifying an dummy user will throw', async t => { | ||
try { | ||
await mal('dummy', 'dummy').verifyCredentials(); | ||
} catch (err) { | ||
t.pass(); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import test from 'ava'; | ||
import mal from '../../src'; | ||
import instance from '../instance'; | ||
|
||
test('Can request HTML from site', async t => { | ||
const homepage = await instance._requestHtml('/'); | ||
t.truthy(homepage); | ||
}); | ||
|
||
test('Can request XML from API', async t => { | ||
const search = await instance._requestApi('/anime/search.xml', { | ||
q: 'Full metal', | ||
}); | ||
t.truthy(search); | ||
}); | ||
|
||
test(`Can't request API without being authenticated`, async t => { | ||
try { | ||
const instanceWithoutAuth = mal(); | ||
|
||
await instanceWithoutAuth._requestApi('/anime/search.xml'); | ||
} catch (err) { | ||
t.pass(); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import test from 'ava'; | ||
import instance from '../instance'; | ||
|
||
test('Can search for animes', async t => { | ||
const results = await instance.searchAnimes('Full Metal'); | ||
t.truthy(results); | ||
}); | ||
|
||
test('Can search for mangas', async t => { | ||
const results = await instance.searchMangas('Full Metal'); | ||
t.truthy(results); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import path from 'path'; | ||
import dotenv from 'dotenv'; | ||
import mal from '../src'; | ||
|
||
dotenv.config({ | ||
silent: false, | ||
path: path.join(__dirname, '../.env'), | ||
}); | ||
|
||
const instance = mal( | ||
process.env.MAL_USER, | ||
process.env.MAL_PASS | ||
); | ||
|
||
module.exports = instance; |