Add activity plugin (#41)
This commit is contained in:
136
source/plugins/activity/index.mjs
Normal file
136
source/plugins/activity/index.mjs
Normal file
@@ -0,0 +1,136 @@
|
||||
//Setup
|
||||
export default async function ({login, rest, imports, q}, {enabled = false} = {}) {
|
||||
//Plugin execution
|
||||
try {
|
||||
//Check if plugin is enabled and requirements are met
|
||||
if ((!enabled)||(!q.activity))
|
||||
return null
|
||||
|
||||
//Parameters override
|
||||
let {"activity.limit":limit = 5, "activity.days":days = 7, "activity.filter":filter = "all"} = q
|
||||
//Events
|
||||
limit = Math.max(1, Math.min(100, Number(limit)))
|
||||
//Days
|
||||
days = Number(days) > 0 ? Number(days) : Infinity
|
||||
//Filtered events
|
||||
filter = decodeURIComponent(filter).split(",").map(x => x.trim().toLocaleLowerCase()).filter(x => x)
|
||||
|
||||
//Get user recent activity
|
||||
console.debug(`metrics/compute/${login}/plugins > activity > querying api`)
|
||||
const {data:events} = await rest.activity.listEventsForAuthenticatedUser({username:login, per_page:100})
|
||||
console.debug(`metrics/compute/${login}/plugins > activity > ${events.length} events loaded`)
|
||||
//Extract activity events
|
||||
const activity = events
|
||||
.filter(({actor}) => actor.login === login)
|
||||
.filter(({created_at}) => Number.isFinite(days) ? new Date(created_at) > new Date(Date.now()-days*24*60*60*1000) : true)
|
||||
.map(({type, payload, repo:{name:repo}}) => {
|
||||
//See https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events/github-event-types#memberevent
|
||||
switch (type) {
|
||||
//Commented on a commit
|
||||
case "CommitCommentEvent":{
|
||||
if (!["created"].includes(payload.action))
|
||||
return null
|
||||
const {comment:{user:{login:user}, commit_id:sha, body:content}} = payload
|
||||
return {type:"comment", on:"commit", repo, content, user, mobile:null, number:sha.substring(0, 7), title:""}
|
||||
}
|
||||
//Created a git branch or tag
|
||||
case "CreateEvent":{
|
||||
const {ref:name, ref_type:type} = payload
|
||||
return {type:"ref/create", repo, ref:{name, type}}
|
||||
}
|
||||
//Deleted a git branch or tag
|
||||
case "DeleteEvent":{
|
||||
const {ref:name, ref_type:type} = payload
|
||||
return {type:"ref/delete", repo, ref:{name, type}}
|
||||
}
|
||||
//Forked repository
|
||||
case "ForkEvent":{
|
||||
return {type:"fork", repo}
|
||||
}
|
||||
//Wiki editions
|
||||
case "GollumEvent":{
|
||||
const {pages} = payload
|
||||
return {type:"wiki", repo, pages:pages.map(({title}) => title)}
|
||||
}
|
||||
//Commented on an issue
|
||||
case "IssueCommentEvent":{
|
||||
if (!["created"].includes(payload.action))
|
||||
return null
|
||||
const {issue:{user:{login:user}, title, number}, comment:{body:content, performed_via_github_app:mobile}} = payload
|
||||
return {type:"comment", on:"issue", repo, content, user, mobile, number, title}
|
||||
}
|
||||
//Issue event
|
||||
case "IssuesEvent":{
|
||||
if (!["opened", "closed", "reopened"].includes(payload.action))
|
||||
return null
|
||||
const {action, issue:{user:{login:user}, title, number}} = payload
|
||||
return {type:"issue", repo, action, user, number, title}
|
||||
}
|
||||
//Activity from repository collaborators
|
||||
case "MemberEvent":{
|
||||
if (!["added"].includes(payload.action))
|
||||
return null
|
||||
const {member:{login:user}} = payload
|
||||
return {type:"member", repo, user}
|
||||
}
|
||||
//Made repository public
|
||||
case "PublicEvent":{
|
||||
return {type:"public", repo}
|
||||
}
|
||||
//Pull requests events
|
||||
case "PullRequestEvent":{
|
||||
if (!["opened", "closed"].includes(payload.action))
|
||||
return null
|
||||
const {action, pull_request:{title, number, additions:added, deletions:deleted, changed_files:changed}} = payload
|
||||
return {type:"pr", repo, action, title, number, lines:{added, deleted}, files:{changed}}
|
||||
}
|
||||
//Reviewed a pull request
|
||||
case "PullRequestReviewEvent":{
|
||||
const {review:{state:review}, pull_request:{user:{login:user}, number, title}} = payload
|
||||
return {type:"review", repo, review, user, number, title}
|
||||
}
|
||||
//Commented on a pull request
|
||||
case "PullRequestReviewCommentEvent":{
|
||||
if (!["created"].includes(payload.action))
|
||||
return null
|
||||
const {pull_request:{user:{login:user}, title, number}, comment:{body:content, performed_via_github_app:mobile}} = payload
|
||||
return {type:"comment", on:"pr", repo, content, user, mobile, number, title}
|
||||
}
|
||||
//Pushed commits
|
||||
case "PushEvent":{
|
||||
const {size, commits, ref} = payload
|
||||
return {type:"push", repo, size, branch:ref.match(/refs.heads.(?<branch>.*)/)?.groups?.branch ?? null, commits:commits.map(({sha, message}) => ({sha:sha.substring(0, 7), message}))}
|
||||
}
|
||||
//Released
|
||||
case "ReleaseEvent":{
|
||||
if (!["published"].includes(payload.action))
|
||||
return null
|
||||
const {action, release:{name, prerelease, draft}} = payload
|
||||
return {type:"release", repo, action, name, prerelease, draft}
|
||||
}
|
||||
//Starred a repository
|
||||
case "WatchEvent":{
|
||||
if (!["started"].includes(payload.action))
|
||||
return null
|
||||
const {action} = payload
|
||||
return {type:"star", repo, action}
|
||||
}
|
||||
//Unknown event
|
||||
default:{
|
||||
return null
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter(event => event)
|
||||
.filter(event => filter.includes("all") || filter.includes(event.type))
|
||||
.slice(0, limit)
|
||||
|
||||
//Results
|
||||
return {events:activity}
|
||||
}
|
||||
//Handle errors
|
||||
catch (error) {
|
||||
throw {error:{message:"An error occured", instance:error}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
//Events
|
||||
from = Math.max(1, Math.min(1000, Number(from)))
|
||||
//Days
|
||||
days = Math.max(1, Math.min(30, Number(from)))
|
||||
days = Math.max(1, Math.min(30, Number(days)))
|
||||
//Initialization
|
||||
const habits = {facts, charts, commits:{hour:NaN, hours:{}, day:NaN, days:{}}, indents:{style:"", spaces:0, tabs:0}, linguist:{available:false, ordered:[], languages:{}}}
|
||||
const pages = Math.ceil(from/100)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
await Promise.all(["performance", "accessibility", "best-practices", "seo"].map(async category => {
|
||||
//Perform audit
|
||||
console.debug(`metrics/compute/${login}/plugins > pagespeed > performing audit ${category}`)
|
||||
const request = await imports.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?category=${category}&url=${url}&key=${token}`)
|
||||
const request = await imports.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?category=${category}&url=${url}${token ? `&key=${token}` : ""}`)
|
||||
console.debug(request.data)
|
||||
const {score, title} = request.data.lighthouseResult.categories[category]
|
||||
scores.set(category, {score, title})
|
||||
@@ -34,7 +34,7 @@
|
||||
//Detailed metrics
|
||||
if (detailed) {
|
||||
console.debug(`metrics/compute/${login}/plugins > pagespeed > performing detailed audit`)
|
||||
const request = await imports.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?&url=${url}&key=${token}`)
|
||||
const request = await imports.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?&url=${url}${token ? `&key=${token}` : ""}`)
|
||||
console.debug(request.data)
|
||||
Object.assign(result.metrics, ...request.data.lighthouseResult.audits.metrics.details.items)
|
||||
console.debug(`metrics/compute/${login}/plugins > pagespeed > performed detailed audit (status code ${request.status})`)
|
||||
|
||||
Reference in New Issue
Block a user