Add support for fonts
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 = ""
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
31
src/templates/classic/fonts.css
Normal file
31
src/templates/classic/fonts.css
Normal file
File diff suppressed because one or more lines are too long
@@ -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 |
@@ -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;
|
||||
}
|
||||
|
||||
31
src/templates/terminal/fonts.css
Normal file
31
src/templates/terminal/fonts.css
Normal file
File diff suppressed because one or more lines are too long
@@ -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 |
@@ -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 */
|
||||
|
||||
@@ -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"))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user