Skip to content

Commit

Permalink
Version 2.2 (new additions)
Browse files Browse the repository at this point in the history
- Smarter placeholders
- Merged placeholders with real templates to avoid maintening duplicates
- Moved style/js away from index.html and refactor
- Svg size is now computed again from templates
- Base metrics is now contained in special plugin "base", which can be disabled  part by part if you just want to include a plugin instead
- Reformatted a bit terminal template
- Test now look templates directory
  • Loading branch information
lowlighter committed Oct 24, 2020
1 parent 997deed commit 60d02a6
Show file tree
Hide file tree
Showing 22 changed files with 707 additions and 950 deletions.
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ inputs:
repositories:
description: Number of repositories to use to compute metrics
default: 100
base:
description: Base content to include in metrics (list of comma-separated sections name as string)
default: "header, activity, community, repositories, metadata"
plugin_pagespeed:
description: Enable Google PageSpeed metrics for account attached website
default: no
Expand Down
2 changes: 1 addition & 1 deletion action/dist/index.js

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions action/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@
console.debug = () => null
console.log(`Debug mode | ${debug}`)

//Base elements
let base = (core.getInput("base")||"").split(",").map(part => part.trim())
if (!base.length)
base = conf.settings.plugins.base.parts
for (const part of base)
q[`base.${part}`] = true
console.log(`Base elements | ${base.join(", ")}`)

//Additional plugins
const plugins = {
lines:{enabled:bool(core.getInput("plugin_lines"))},
Expand Down
7 changes: 5 additions & 2 deletions src/app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,12 @@
const actions = {flush:new Map()}
app.get("/", limiter, (req, res) => res.sendFile(`${conf.statics}/index.html`))
app.get("/index.html", limiter, (req, res) => res.sendFile(`${conf.statics}/index.html`))
app.get("/app.js", limiter, (req, res) => res.sendFile(`${conf.statics}/app.js`))
app.get("/style.css", limiter, (req, res) => res.sendFile(`${conf.statics}/style.css`))
app.get("/favicon.ico", limiter, (req, res) => res.sendStatus(204))
app.get("/plugins.list", limiter, (req, res) => res.status(200).json(enabled))
app.get("/templates.list", limiter, (req, res) => res.status(200).json(templates))
app.get("/plugins.base.parts.list", limiter, (req, res) => res.status(200).json(conf.settings.plugins.base.parts))
app.get("/ejs.min.js", limiter, (req, res) => res.sendFile(`${conf.node_modules}/ejs/ejs.min.js`))
app.get("/axios.min.js", limiter, (req, res) => res.sendFile(`${conf.node_modules}/axios/dist/axios.min.js`))
app.get("/axios.min.map", limiter, (req, res) => res.sendFile(`${conf.node_modules}/axios/dist/axios.min.map`))
Expand All @@ -57,8 +60,8 @@
const template = req.query.template || conf.settings.templates.default
if (!(template in Templates))
return res.sendStatus(404)
const {style, placeholder} = conf.templates[template]
res.status(200).json({style, placeholder})
const {style, image} = conf.templates[template]
res.status(200).json({style, image})
})
app.get("/action.flush", limiter, async (req, res) => {
const {token, user} = req.query
Expand Down
151 changes: 151 additions & 0 deletions src/html/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
;(async function() {
//Init
const url = new URLSearchParams(window.location.search)
const {data:templates} = await axios.get("/templates.list")
const {data:plugins} = await axios.get("/plugins.list")
const {data:base} = await axios.get("/plugins.base.parts.list")
//App
return new Vue({
//Initialization
el:"main",
async mounted() {
await this.load()
},
//Data initialization
data:{
user:url.get("user") || "",
palette:url.get("palette") || "light",
plugins:{
base,
list:plugins,
enabled:{base:Object.fromEntries(base.map(key => [key, true]))},
descriptions:{
pagespeed:"Website performances",
languages:"Most used languages",
followup:"Issues and pull requests",
traffic:"Pages views",
lines:"Lines of code changed",
habits:"Coding habits",
selfskip:"Skip metrics commits",
"base.header":"Header",
"base.activity":"Account activity",
"base.community":"Community stats",
"base.repositories":"Repositories metrics",
"base.metadata":"Metadata",
},
},
templates:{
list:templates,
selected:url.get("template") || templates[0],
loaded:{},
placeholder:"",
descriptions:{
classic:"Classic template",
terminal:"Terminal template",
},
},
generated:{
pending:false,
content:"",
error:false,
},
},
//Computed data
computed:{
//User's repository
repo() {
return `https://github.com/${this.user}/${this.user}`
},
//Endpoint to use for computed metrics
url() {
const plugins = Object.entries(this.plugins.enabled)
.flatMap(([key, value]) => key === "base" ? Object.entries(value).map(([key, value]) => [`base.${key}`, value]) : [[key, value]])
.filter(([key, value]) => /^base[.]\w+$/.test(key) ? !value : value)
.map(([key, value]) => `${key}=${+value}`)
const params = [...(this.templates.selected !== templates[0] ? [`template=${this.templates.selected}`] : []), ...plugins].join("&")
return `${window.location.protocol}//${window.location.host}/${this.user}${params.length ? `?${params}` : ""}`
},
},
//Methods
methods:{
//Load and render image
async load() {
//Load template
const template = this.templates.selected
if (!this.templates.loaded[template]) {
const {data:{image, style}} = await axios.get(`/placeholder.svg?template=${template}`)
this.templates.loaded[template] = {image, style}
}
const {image = "", style = {}} = this.templates.loaded[this.templates.selected] || {}
if (!image)
return this.templates.placeholder = "#"
//Proxifier
const proxify = (target) => typeof target === "object" ? new Proxy(target, {
get(target, property) {
//Primitive conversion
if (property === Symbol.toPrimitive)
return () => "▇"
//Iterables
if (property === Symbol.iterator)
return Reflect.get(target, property)
//Plugins should not be proxified by default as they can be toggled by user
if (/^plugins$/.test(property))
return Reflect.get(target, property)
//Consider no errors on plugins
if (/^error/.test(property))
return undefined
//Proxify recursively
return proxify(property in target ? Reflect.get(target, property) : {})
}
}) : target
//Placeholder data
const data = {
style,
s(_, letter) { return letter === "y" ? "ies" : "s" },
base:this.plugins.enabled.base,
meta:{version:"0.0.0", author:"lowlighter", placeholder:true},
user:proxify({name:`▇▇▇▇`, websiteUrl:`▇▇▇▇▇▇▇▇▇▇▇▇`}),
computed:proxify({
avatar:"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
registration:"▇ years ago",
calendar:new Array(14).fill({color:"#ebedf0"}),
licenses:{favorite:`▇▇▇▇`},
plugins:Object.fromEntries(Object.entries(this.plugins.enabled).filter(([key, enabled]) => (key !== "base")&&(enabled)).map(([key]) => {
return [key, proxify({
pagespeed:{scores:["Performance", "Accessibility", "Best Practices", "SEO"].map(title => ({title, score:NaN}))},
followup:{issues:{count:0}, pr:{count:0}},
habits:{indents:{style:`▇▇▇`}},
languages:{favorites:new Array(7).fill(null).map((_, x) => ({x, name:`▇▇▇▇`, color:"#ebedf0", value:1/(x+1)}))},
}[key]||{})]
})),
token:{scopes:[]},
}),
}
//Render placeholder
this.templates.placeholder = this.serialize(ejs.render(image, data))
this.generated.content = ""
},
//Generate metrics and flush cache
async generate() {
//Avoid requests spamming
if (this.generated.pending)
return
this.generated.pending = true
//Compute metrics
try {
await axios.get(`/action.flush?&token=${(await axios.get(`/action.flush?user=${this.user}`)).data.token}`)
this.generated.content = this.serialize((await axios.get(this.url)).data)
} catch {
this.generated.error = true
}
finally {
this.generated.pending = false
}
},
//Serialize svg
serialize(svg) {
return `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(svg)))}`
},
},
})
})()
Loading

0 comments on commit 60d02a6

Please sign in to comment.