Add support for fonts

This commit is contained in:
lowlighter
2020-10-25 00:19:57 +02:00
parent cdbb0e5b87
commit a4e15807ad
11 changed files with 116 additions and 48 deletions

View File

@@ -66,8 +66,8 @@
const template = req.query.template || conf.settings.templates.default
if (!(template in Templates))
return res.sendStatus(404)
const {style, image} = conf.templates[template]
res.status(200).json({style, image})
const {style, image, fonts} = conf.templates[template]
res.status(200).json({style, image, fonts})
})
app.get("/action.flush", limiter, async (req, res) => {
const {token, user} = req.query

View File

@@ -104,10 +104,10 @@
//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 {data:{image, style, fonts}} = await axios.get(`/placeholder.svg?template=${template}`)
this.templates.loaded[template] = {image, style, fonts}
}
const {image = "", style = {}} = this.templates.loaded[this.templates.selected] || {}
const {image = "", style = "", fonts = ""} = this.templates.loaded[this.templates.selected] || {}
if (!image)
return this.templates.placeholder = "#"
//Proxifier
@@ -115,7 +115,7 @@
get(target, property) {
//Primitive conversion
if (property === Symbol.toPrimitive)
return () => ""
return () => "##"
//Iterables
if (property === Symbol.iterator)
return Reflect.get(target, property)
@@ -132,27 +132,29 @@
//Placeholder data
const data = {
style,
fonts,
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:`▇▇▇▇▇▇▇▇▇▇▇▇`}),
user:proxify({name:`############`, websiteUrl:`########################`}),
computed:proxify({
avatar:"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
registration:" years ago",
registration:"## years ago",
calendar:new Array(14).fill({color:"#ebedf0"}),
licenses:{favorite:`▇▇▇▇`},
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)}))},
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
console.log(new Set([...ejs.render(image, data)]))
this.templates.placeholder = this.serialize(ejs.render(image, data))
this.generated.content = ""
},

View File

@@ -19,7 +19,7 @@
const s = (value, end = "") => value > 1 ? {y:"ies", "":"s"}[end] : end
if ((!(template in Templates))||(!(template in conf.templates))||((conf.settings.templates.enabled.length)&&(!conf.settings.templates.enabled.includes(template))))
throw new Error("unsupported template")
const {query, image, style} = conf.templates[template]
const {query, image, style, fonts} = conf.templates[template]
//Query data from GitHub API
console.debug(`metrics/compute/${login} > query`)
@@ -45,7 +45,7 @@
//Eval rendering
console.debug(`metrics/compute/${login} > render`)
let rendered = await ejs.render(image, {...data, s, style}, {async:true})
let rendered = await ejs.render(image, {...data, s, style, fonts}, {async:true})
console.debug(`metrics/compute/${login} > render > success`)
//Optimize rendering

View File

@@ -54,18 +54,19 @@
`${templates}/${name}/query.graphql`,
`${templates}/${name}/image.svg`,
`${templates}/${name}/style.css`,
`${templates}/${name}/fonts.css`,
]
const [query, image, style] = await Promise.all(files.map(async file => `${await fs.promises.readFile(path.resolve(file))}`))
conf.templates[name] = {query, image, style}
const [query, image, style, fonts] = await Promise.all(files.map(async file => `${await fs.promises.readFile(path.resolve(file))}`))
conf.templates[name] = {query, image, style, fonts}
logger(`metrics/setup > load template [${name}] > success`)
//Debug
if (conf.settings.debug) {
Object.defineProperty(conf.templates, name, {
get() {
logger(`metrics/setup > reload template [${name}]`)
const [query, image, style] = files.map(file => `${fs.readFileSync(path.resolve(file))}`)
const [query, image, style, fonts] = files.map(file => `${fs.readFileSync(path.resolve(file))}`)
logger(`metrics/setup > reload template [${name}] > success`)
return {query, image, style}
return {query, image, style, fonts}
}
})
}

File diff suppressed because one or more lines are too long

View File

@@ -1,14 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="<%= 0
+ (!!base.header)*86
+ (!!base.metadata)*42
+ ((!!base.activity)||(!!base.community))*150
+ (!!base.repositories)*100
+ ((!!computed.plugins.traffic)||(!!computed.plugins.lines))*18
+ (!!computed.plugins.followup)*72
+ (!!computed.plugins.pagespeed)*128
+ (!!computed.plugins.habits)*72
+ (!!base.header)*80
+ (!!base.metadata)*38
+ ((!!base.activity)||(!!base.community))*128
+ (!!base.repositories)*92
+ ((!!base.repositories)*((!!computed.plugins.traffic)||(!!computed.plugins.lines)))*16
+ (!!computed.plugins.followup)*68
+ (!!computed.plugins.pagespeed)*126
+ (!!computed.plugins.habits)*68
+ (!!computed.plugins.languages)*96
%>">
<defs><style><%= fonts %></style></defs>
<style>
<%= style %>
</style>

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -1,6 +1,6 @@
/* SVG global context */
svg {
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
font-family: 'Roboto';
font-size: 14px;
color: #777777;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,23 +1,23 @@
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="<%= 48
+ (!!base.header)*64
+ (!!base.metadata)*122
+ (!!base.activity)*146
+ (!!base.community)*120
+ (!!base.repositories)*188
+ (Object.entries(base).filter(([key, value]) => value).length)*8
+ (!!computed.plugins.traffic)*18
+ (!!computed.plugins.followup)*112
+ (!!computed.plugins.lines)*36
+ ((!!computed.plugins.traffic)+(!!computed.plugins.followup)+(!!computed.plugins.lines))*4
+ (!!computed.plugins.pagespeed)*132
+ (!!computed.plugins.languages)*172
+ (Object.entries(computed.plugins).filter(([key, value]) => value).length)*4
+ (!!base.header)*62
+ (!!base.metadata)*108
+ (!!base.activity)*108
+ (!!base.community)*94
+ (!!base.repositories)*142
+ ((!!base.repositories)*(!!computed.plugins.traffic))*18
+ ((!!base.repositories)*(!!computed.plugins.followup))*102
+ ((!!base.repositories)*(!!computed.plugins.lines))*34
+ (!!computed.plugins.pagespeed)*110
+ (!!computed.plugins.languages)*124
+ Math.max(0, (((!!base.metadata)+(!!base.header)+((!!base.activity)||(!!base.community))+(!!base.repositories)+(!!computed.plugins.pagespeed)+(!!computed.plugins.languages))-1))*20
%>">
<%
meta.$ = `<span class="ps1-path">${user.login}@metrics</span>:<span class="ps1-location">~</span>${computed.token.scopes.includes("repo") ? "#" : "$"}`
meta.animations = !meta.placeholder ? {stdin:.16, stdout:.28, length:(2+Object.keys(base).length+Object.keys(computed.plugins).length)} : {stdin:0, stdout:0, length:0}
%>
<defs><style><%= fonts %></style></defs>
<style>
<%= style %>
.stdin, .stdout {
@@ -57,8 +57,7 @@
<% if (base.metadata) { %>
<div class="banner"><%# -%>
GitHub metrics generator <%= meta.version %>
These generated metrics comes with ABSOLUTELY NO WARRANTY,
to the extent permitted by applicable law.
These generated metrics comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law.
Last generated: <%= new Date().toGMTString() %>
</div><% } -%>
@@ -66,8 +65,9 @@ Last generated: <%= new Date().toGMTString() %>
<% if (base.header) { %>
<div class="stdin"><%- meta.$ %> whoami</div><%# -%>
<div class="stdout"><%# -%>
<b><%= user.name || user.login %></b> registered=<%= computed.registration.match(/^.+? [ym]/)[0].replace(/ /g, "") %>, uid=<%= `${user.databaseId}`.substr(-4) %>, gid=<%= user.organizations.totalCount %>, followers=<%= user.followers.totalCount %>
<b><%= user.name || user.login %></b> registered=<%= computed.registration.match(/^.+? [ym]/)[0].replace(/ /g, "") %>, uid=<%= `${user.databaseId}`.substr(-4) %>, gid=<%= user.organizations.totalCount %>
contributed to <%= user.repositoriesContributedTo.totalCount %> repositor<%= s(user.repositoriesContributedTo.totalCount, "y") %> <b><% for (const [x, {color}] of Object.entries(computed.calendar)) { -%><span style="color:<%= color %>">#</span><% } %></b>
followed by <b><%= user.followers.totalCount %></b> user<%= s(user.followers.totalCount) %>
</div><% } -%>
<%# ============================================================= -%>
<% if ((base.activity)||(base.community)) { %>
@@ -152,7 +152,7 @@ dr-x LICENSE
<%# ============================================================= -%>
<% if (base.metadata) { -%>
<footer>Connection reset by 127.0.0.1</footer><%# -%>
<footer>Connection reset by <%= Math.floor(256*Math.random()) %>.<%= Math.floor(256*Math.random()) %>.<%= Math.floor(256*Math.random()) %>.<%= Math.floor(256*Math.random()) %></footer><%# -%>
<% } -%></pre>
</div>

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -1,6 +1,6 @@
/* SVG global context */
svg {
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
font-family: 'Courier Prime';
font-size: 14px;
color: #777777;
}
@@ -49,7 +49,7 @@
/* Terminal */
pre, .banner, .footer {
margin: 0;
font-family: monospace;
font-family: 'Courier Prime';
color: #DDDDDD;
white-space: break-spaces;
}
@@ -61,7 +61,6 @@
}
.banner, footer {
opacity: .7;
font-family: monospace;
}
/* Prompt */

View File

@@ -28,9 +28,10 @@
`${templates}/${name}/query.graphql`,
`${templates}/${name}/image.svg`,
`${templates}/${name}/style.css`,
`${templates}/${name}/fonts.css`,
]
const [query, image, style] = await Promise.all(files.map(async file => `${await fs.promises.readFile(path.resolve(file))}`))
assets[name] = {query, image, style}
const [query, image, style, fonts] = await Promise.all(files.map(async file => `${await fs.promises.readFile(path.resolve(file))}`))
assets[name] = {query, image, style, fonts}
}
code = code.replace(/<#assets>/g, Buffer.from(JSON.stringify(assets)).toString("base64"))