Add anilist plugin (#69)

This commit is contained in:
Simon Lecoq
2021-01-24 21:50:56 +01:00
committed by GitHub
parent 418b86d34c
commit 81b7414b2a
19 changed files with 828 additions and 7 deletions

View File

@@ -151,6 +151,7 @@
stargazers:{enabled:input.bool("plugin_stargazers")},
activity:{enabled:input.bool("plugin_activity")},
people:{enabled:input.bool("plugin_people")},
anilist:{enabled:input.bool("plugin_anilist")},
}
let q = Object.fromEntries(Object.entries(plugins).filter(([key, plugin]) => plugin.enabled).map(([key]) => [key, true]))
info("Plugins enabled", Object.entries(plugins).filter(([key, plugin]) => plugin.enabled).map(([key]) => key))
@@ -243,6 +244,17 @@
for (const option of ["identicons"])
info(`People ${option}`, q[`people.${option}`] = input.bool(`plugin_people_${option}`))
}
//Anilist
if (plugins.anilist.enabled) {
for (const option of ["limit"])
info(`Anilist ${option}`, q[`anilist.${option}`] = input.number(`plugin_anilist_${option}`))
for (const option of ["medias", "sections"])
info(`Anilist ${option}`, q[`anilist.${option}`] = input.array(`plugin_anilist_${option}`))
for (const option of ["shuffle"])
info(`Anilist ${option}`, q[`anilist.${option}`] = input.bool(`plugin_anilist_${option}`))
for (const option of ["user"])
info(`Anilist ${option}`, q[`anilist.${option}`] = input.string(`plugin_anilist_${option}`))
}
//Repositories to use
const repositories = input.number("repositories")

View File

@@ -68,7 +68,7 @@
//Compute metrics
console.debug(`metrics/compute/${login} > compute`)
const computer = Templates[template].default || Templates[template]
await computer({login, q, dflags}, {conf, data, rest, graphql, plugins, queries}, {s, pending, imports:{plugins:Plugins, url, imgb64, axios, puppeteer, run, fs, os, paths, util, format, bytes, shuffle, htmlescape, urlexpand}})
await computer({login, q, dflags}, {conf, data, rest, graphql, plugins, queries}, {s, pending, imports:{plugins:Plugins, url, imgb64, axios, puppeteer, run, fs, os, paths, util, format, bytes, shuffle, htmlescape, urlexpand, __module}})
const promised = await Promise.all(pending)
//Check plugins errors
@@ -123,6 +123,11 @@
}
}
/** Returns module __dirname */
function __module(module) {
return paths.join(paths.dirname(url.fileURLToPath(module)))
}
/** Formatter */
function format(n, {sign = false} = {}) {
for (const {u, v} of [{u:"b", v:10**9}, {u:"m", v:10**6}, {u:"k", v:10**3}])

View File

@@ -925,6 +925,128 @@
})
}
}
//Anilist api
if (/^https:..graphql.anilist.co/.test(url)) {
//Initialization and media generator
const query = body.query
const media = ({type}) => ({
title:{romaji:faker.lorem.words(), english:faker.lorem.words(), native:faker.lorem.words()},
description:faker.lorem.paragraphs(),
type,
status:faker.random.arrayElement(["FINISHED", "RELEASING", "NOT_YET_RELEASED", "CANCELLED", "HIATUS"]),
episodes:100+faker.random.number(100),
volumes:faker.random.number(100),
chapters:100+faker.random.number(1000),
averageScore:faker.random.number(100),
countryOfOrigin:"JP",
genres:new Array(6).fill(null).map(_ => faker.lorem.word()),
coverImage:{medium:null},
startDate:{year:faker.date.past(20).getFullYear()}
})
//User statistics query
if (/^query Statistics /.test(query)) {
console.debug(`metrics/compute/mocks > mocking anilist api result > Statistics`)
return ({
status:200,
data:{
data:{
User:{
id:faker.random.number(100000),
name:faker.internet.userName(),
about:null,
statistics:{
anime:{
count:faker.random.number(1000),
minutesWatched:faker.random.number(100000),
episodesWatched:faker.random.number(10000),
genres:new Array(4).fill(null).map(_ => ({genre:faker.lorem.word()})),
},
manga:{
count:faker.random.number(1000),
chaptersRead:faker.random.number(100000),
volumesRead:faker.random.number(10000),
genres:new Array(4).fill(null).map(_ => ({genre:faker.lorem.word()})),
},
}
}
}
}
})
}
//Favorites characters
if (/^query FavoritesCharacters /.test(query)) {
console.debug(`metrics/compute/mocks > mocking anilist api result > Favorites characters`)
return ({
status:200,
data:{
data:{
User:{
favourites:{
characters:{
nodes:new Array(2+faker.random.number(16)).fill(null).map(_ => ({
name:{full:faker.name.findName(), native:faker.name.findName()},
image:{medium:null}
}),
),
pageInfo:{currentPage:1, hasNextPage:false}
}
}
}
}
}
})
}
//Favorites anime/manga query
if (/^query Favorites /.test(query)) {
console.debug(`metrics/compute/mocks > mocking anilist api result > Favorites`)
const type = /anime[(]/.test(query) ? "ANIME" : /manga[(]/.test(query) ? "MANGA" : "OTHER"
return ({
status:200,
data:{
data:{
User:{
favourites:{
[type.toLocaleLowerCase()]:{
nodes:new Array(16).fill(null).map(_ => media({type})),
pageInfo:{currentPage:1, hasNextPage:false},
}
}
}
}
}
})
}
//Medias query
if (/^query Medias /.test(query)) {
console.debug(`metrics/compute/mocks > mocking anilist api result > Medias`)
const type = body.variables.type
return ({
status:200,
data:{
data:{
MediaListCollection:{
lists:[
{
name:{ANIME:"Watching", MANGA:"Reading", OTHER:"Completed"}[type],
isCustomList:false,
entries:new Array(16).fill(null).map(_ => ({
status:faker.random.arrayElement(["CURRENT", "PLANNING", "COMPLETED", "DROPPED", "PAUSED", "REPEATING"]),
progress:faker.random.number(100),
progressVolumes: null,
score:0,
startedAt:{year:null, month:null, day:null},
completedAt:{year:null, month:null, day:null},
media:media({type})
})),
}
]
}
}
}
})
}
}
return target(...args)
}
})
@@ -1098,7 +1220,7 @@
}
}
//Last.fm api
if (/^https:..ws.audioscrobbler.com/.test(url)) {
if (/^https:..ws.audioscrobbler.com.*$/.test(url)) {
//Get recently played tracks
if (/user.getrecenttracks/.test(url)) {
console.debug(`metrics/compute/mocks > mocking lastfm api result > ${url}`)

View File

@@ -4,6 +4,7 @@
const {data:plugins} = await axios.get("/.plugins")
const {data:base} = await axios.get("/.plugins.base")
const {data:version} = await axios.get("/.version")
templates.sort((a, b) => (a.name.startsWith("@") ^ b.name.startsWith("@")) ? (a.name.startsWith("@") ? 1 : -1) : a.name.localeCompare(b.name))
//App
return new Vue({
//Initialization
@@ -76,6 +77,7 @@
stargazers:"✨ Stargazers over last weeks",
activity:"📰 Recent activity",
people:"🧑‍🤝‍🧑 Followers and followed",
anilist:"🌸 Anilist",
base:"🗃️ Base content",
"base.header":"Header",
"base.activity":"Account activity",
@@ -87,6 +89,7 @@
descriptions:{
"languages.ignored":{text:"Ignored languages", placeholder:"lang-0, lang-1, ..."},
"languages.skipped":{text:"Skipped repositories", placeholder:"repo-0, repo-1, ..."},
"languages.colors":{text:"Custom language colors", placeholder:"0:#ff0000, javascript:yellow, ..."},
"pagespeed.detailed":{text:"Detailed audit", type:"boolean"},
"pagespeed.screenshot":{text:"Audit screenshot", type:"boolean"},
"pagespeed.url":{text:"Url", placeholder:"(default to GitHub attached)"},
@@ -104,6 +107,7 @@
"isocalendar.duration":{text:"Duration", type:"select", values:["half-year", "full-year"]},
"projects.limit":{text:"Limit", type:"number", min:0, max:100},
"projects.repositories":{text:"Repositories projects", placeholder:"user/repo/projects/1, ..."},
"projects.descriptions":{text:"Projects descriptions", type:"boolean"},
"topics.mode":{text:"Mode", type:"select", values:["starred", "mastered"]},
"topics.sort":{text:"Sort by", type:"select", values:["starred", "activity", "stars", "random"]},
"topics.limit":{text:"Limit", type:"number", min:0, max:20},
@@ -117,6 +121,11 @@
"people.limit":{text:"Limit", type:"number", min:1, max:9999},
"people.types":{text:"Types", placeholder:"followers, following"},
"people.identicons":{text:"Use identicons", type:"boolean"},
"anilist.medias":{text:"Medias to display", placeholder:"anime, manga"},
"anilist.sections":{text:"Sections to display", placeholder:"favorites, watching, reading, characters"},
"anilist.limit":{text:"Limit", type:"number", min:0, max:9999},
"anilist.shuffle":{text:"Shuffle data", type:"boolean"},
"anilist.user":{text:"Username", placeholder:"(default to GitHub login)"},
},
"languages.ignored":"",
"languages.skipped":"",
@@ -149,6 +158,11 @@
"people.limit":28,
"people.types":"followers, following",
"people.identicons":false,
"anilist.medias":"anime, manga",
"anilist.sections":"favorites",
"anilist.limit":2,
"anilist.shuffle":true,
"anilist.user":"",
},
},
templates:{

View File

@@ -302,8 +302,10 @@
...(set.plugins.enabled.projects ? ({
projects:{
totalCount:options["projects.limit"]+faker.random.number(10),
descriptions:options["projects.descriptions"],
list:new Array(Number(options["projects.limit"])).fill(null).map(_ => ({
name:faker.lorem.sentence(),
description:faker.lorem.paragraph(),
updated:`${2+faker.random.number(8)} days ago`,
progress:{enabled:true, todo:faker.random.number(50), doing:faker.random.number(50), done:faker.random.number(50), get total() { return this.todo + this.doing + this.done } }
}))
@@ -403,6 +405,59 @@
return result
}
}) : null),
//Anilist
...(set.plugins.enabled.anilist ? ({
anilist:{
user:{
stats:{
anime:{
count:faker.random.number(1000),
minutesWatched:faker.random.number(100000),
episodesWatched:faker.random.number(10000),
genres:new Array(4).fill(null).map(_ => ({genre:faker.lorem.word()})),
},
manga:{
count:faker.random.number(1000),
chaptersRead:faker.random.number(100000),
volumesRead:faker.random.number(10000),
genres:new Array(4).fill(null).map(_ => ({genre:faker.lorem.word()})),
},
},
genres:new Array(4).fill(null).map(_ => ({genre:faker.lorem.word()})),
},
get lists() {
const media = (type) => ({
name:faker.lorem.words(),
type,
status:faker.random.arrayElement(["FINISHED", "RELEASING", "NOT_YET_RELEASED", "CANCELLED", "HIATUS"]),
release:faker.date.past(20).getFullYear(),
genres:new Array(6).fill(null).map(_ => faker.lorem.word()),
progress:faker.random.number(100),
description:faker.lorem.paragraphs(),
scores:{user:faker.random.number(100), community:faker.random.number(100)},
released:100+faker.random.number(1000),
artwork:"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
})
const sections = options["anilist.sections"].split(",").map(x => x.trim()).filter(x => x)
const medias = options["anilist.medias"].split(",").map(x => x.trim()).filter(x => x)
return {
...(medias.includes("anime") ? {anime:{
...(sections.includes("watching") ? {watching:new Array(Number(options["anilist.limit"])||4).fill(null).map(_ => media("ANIME"))} : {}),
...(sections.includes("favorites") ? {favorites:new Array(Number(options["anilist.limit"])||4).fill(null).map(_ => media("ANIME"))} : {}),
}} : {}),
...(medias.includes("manga") ? {manga:{
...(sections.includes("reading") ? {reading:new Array(Number(options["anilist.limit"])||4).fill(null).map(_ => media("MANGA"))} : {}),
...(sections.includes("favorites") ? {favorites:new Array(Number(options["anilist.limit"])||4).fill(null).map(_ => media("MANGA"))} : {}),
}} : {}),
}
},
characters:new Array(11).fill(null).map(_ => ({
name:faker.name.findName(),
artwork:"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
})),
sections:options["anilist.sections"].split(",").map(x => x.trim()).filter(x => x)
}
}) : null),
//Activity
...(set.plugins.enabled.activity ? ({
activity:{