From 11cb6f042e38f1e1f34bc51ef5b4d6318bcfac2b Mon Sep 17 00:00:00 2001
From: Simon Lecoq <22963968+lowlighter@users.noreply.github.com>
Date: Sat, 2 Jan 2021 23:41:36 +0100
Subject: [PATCH] Add new plugin stars (#36)
---
README.md | 36 ++++++++++++++-
action.yml | 10 +++++
package.json | 2 +-
settings.example.json | 5 ++-
source/app/action/index.mjs | 6 +++
source/app/mocks.mjs | 37 ++++++++++++++++
source/app/web/statics/app.js | 2 +
source/plugins/stars/index.mjs | 36 +++++++++++++++
source/queries/starred.graphql | 31 +++++++++++++
source/templates/classic/image.svg | 70 ++++++++++++++++++++++++++++++
source/templates/classic/style.css | 47 ++++++++++++++++++++
tests/metrics.test.js | 3 ++
12 files changed, 281 insertions(+), 4 deletions(-)
create mode 100644 source/plugins/stars/index.mjs
create mode 100644 source/queries/starred.graphql
diff --git a/README.md b/README.md
index 011612f5..651bb863 100644
--- a/README.md
+++ b/README.md
@@ -147,16 +147,20 @@ But there's more with [plugins](https://github.com/lowlighter/metrics/tree/maste
+ | 🌟 Recently starred repositories |
🗃️ Header special features |
- |
+
+
+
+
+ |
|
- |
|
@@ -511,6 +515,7 @@ Used template defaults to the `classic` one.
| ✒️ |
💡 |
🎫 |
+ 🌟 |
| Classic |
@@ -528,6 +533,7 @@ Used template defaults to the `classic` one.
✔️ |
✔️ |
✔️ |
+ ✔️M |
| Terminal |
@@ -545,6 +551,7 @@ Used template defaults to the `classic` one.
❌ |
❌ |
✔️ |
+ ❌ |
| RepositoryR |
@@ -562,6 +569,7 @@ Used template defaults to the `classic` one.
❌ |
❌ |
❌ |
+ ❌ |
@@ -1249,6 +1257,30 @@ Add the following to your workflow :
+### 🌟 Stars
+
+ 🚧 This feature is available on @master
+
+The *stars* plugin displays your recently starred repositories.
+
+
+
+
+💬 About
+
+It will consume an additional GitHub request.
+
+Add the following to your workflow :
+```yaml
+- uses: lowlighter/metrics@latest
+ with:
+ # ... other options
+ plugin_stars: yes
+ plugin_stars_limit: 4
+```
+
+
+
### 🔧 Other options
A few additional options are available.
diff --git a/action.yml b/action.yml
index c971023e..44980521 100644
--- a/action.yml
+++ b/action.yml
@@ -347,6 +347,16 @@ inputs:
description: Number of tweets to display
default: 2
+ # Display recently starred repositories
+ plugin_stars:
+ description: Display recently starred repositories
+ default: no
+
+ # Number of recently starred repositories to display
+ plugin_stars_limit:
+ description: Number of recently starred repositories to display
+ default: 4
+
# ====================================================================================
# Options below are mostly used for testing
diff --git a/package.json b/package.json
index b93e52ed..28b4b84e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "metrics",
- "version": "3.0.0",
+ "version": "3.1.0-beta",
"description": "An image generator with 20+ metrics about your GitHub account such as activity, community, repositories, coding habits, website performances, music played, starred topics, etc. that you can put on your profile or elsewhere !",
"main": "index.mjs",
"scripts": {
diff --git a/settings.example.json b/settings.example.json
index 9a39682c..cca8e548 100644
--- a/settings.example.json
+++ b/settings.example.json
@@ -56,8 +56,11 @@
"enabled":false, "//":"Enable or disable personal projects display"
},
"tweets":{ "//":"Tweets plugin",
- "enabled":false, "//":"Enable or disable recent tweets display",
+ "enabled":false, "//":"Enable or disable recent tweets display",
"token":null, "//":"Twitter token (required when enabled)"
+ },
+ "stars":{ "//":"Stars plugin",
+ "enabled":true, "//":"Enable or disable recently starred repositories display"
}
}
}
\ No newline at end of file
diff --git a/source/app/action/index.mjs b/source/app/action/index.mjs
index 29d5861e..41fa6838 100644
--- a/source/app/action/index.mjs
+++ b/source/app/action/index.mjs
@@ -139,6 +139,7 @@
topics:{enabled:input.bool("plugin_topics")},
projects:{enabled:input.bool("plugin_projects")},
tweets:{enabled:input.bool("plugin_tweets")},
+ stars:{enabled:input.bool("plugin_stars")},
}
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))
@@ -208,6 +209,11 @@
for (const option of ["limit"])
info(`Tweets ${option}`, q[`tweets.${option}`] = input.number(`plugin_tweets_${option}`))
}
+ //Stars
+ if (plugins.posts.enabled) {
+ for (const option of ["limit"])
+ info(`Stars ${option}`, q[`stars.${option}`] = input.number(`plugin_stars_${option}`))
+ }
//Repositories to use
const repositories = input.number("repositories")
diff --git a/source/app/mocks.mjs b/source/app/mocks.mjs
index eea6672c..7a262d60 100644
--- a/source/app/mocks.mjs
+++ b/source/app/mocks.mjs
@@ -259,6 +259,43 @@
}
})
}
+ //Starred repositories query
+ if (/^query Starred /.test(query)) {
+ console.debug(`metrics/compute/mocks > mocking graphql api result > Starred`)
+ return ({
+ user:{
+ starredRepositories:{
+ edges:[
+ {
+ starredAt:"2020-10-16T18:53:16Z",
+ node:{
+ description:"📊 An image generator with 20+ metrics about your GitHub account such as activity, community, repositories, coding habits, website performances, music played, starred topics, etc. that you can put on your profile or elsewhere !",
+ forkCount:12,
+ isFork:false,
+ issues:{
+ totalCount: 12
+ },
+ nameWithOwner:"lowlighter/metrics",
+ openGraphImageUrl:"https://repository-images.githubusercontent.com/293860197/7fd72080-496d-11eb-8fe0-238b38a0746a",
+ pullRequests:{
+ totalCount:23
+ },
+ stargazerCount:120,
+ licenseInfo:{
+ nickname:null,
+ name:"MIT License"
+ },
+ primaryLanguage:{
+ color:"#f1e05a",
+ name:"JavaScript"
+ }
+ }
+ },
+ ]
+ }
+ }
+ })
+ }
//Unmocked call
return target(...args)
}
diff --git a/source/app/web/statics/app.js b/source/app/web/statics/app.js
index eeb5ab1e..726679eb 100644
--- a/source/app/web/statics/app.js
+++ b/source/app/web/statics/app.js
@@ -45,6 +45,7 @@
topics:"Starred topics",
projects:"Projects",
tweets:"Latest tweets",
+ stars:"Recently starred repositories",
"base.header":"Header",
"base.activity":"Account activity",
"base.community":"Community stats",
@@ -71,6 +72,7 @@
"topics.sort":"stars",
"topics.limit":12,
"tweets.limit":2,
+ "stars.limit":4,
},
},
templates:{
diff --git a/source/plugins/stars/index.mjs b/source/plugins/stars/index.mjs
new file mode 100644
index 00000000..d26450e6
--- /dev/null
+++ b/source/plugins/stars/index.mjs
@@ -0,0 +1,36 @@
+//Setup
+ export default async function ({login, graphql, q, queries, imports}, {enabled = false} = {}) {
+ //Plugin execution
+ try {
+ //Check if plugin is enabled and requirements are met
+ if ((!enabled)||(!q.stars))
+ return null
+ //Parameters override
+ let {"stars.limit":limit = 4} = q
+ //Limit
+ limit = Math.max(1, Math.min(100, Number(limit)))
+ //Retrieve user stars from graphql api
+ console.debug(`metrics/compute/${login}/plugins > stars > querying api`)
+ const {user:{starredRepositories:{edges:repositories}}} = await graphql(queries.starred({login, limit}))
+ //Format starred repositories
+ for (const edge of repositories) {
+ //Formats values
+ edge.node.stargazers = imports.format(edge.node.stargazerCount)
+ edge.node.forks = imports.format(edge.node.forkCount)
+ //Format date
+ const time = (Date.now()-new Date(edge.starredAt).getTime())/(24*60*60*1000)
+ let updated = new Date(edge.starredAt).toDateString().substring(4)
+ if (time < 1)
+ updated = `${Math.ceil(time*24)} hour${Math.ceil(time*24) >= 2 ? "s" : ""} ago`
+ else if (time < 30)
+ updated = `${Math.floor(time)} day${time >= 2 ? "s" : ""} ago`
+ edge.starred = updated
+ }
+ //Results
+ return {repositories}
+ }
+ //Handle errors
+ catch (error) {
+ throw {error:{message:"An error occured", instance:error}}
+ }
+ }
diff --git a/source/queries/starred.graphql b/source/queries/starred.graphql
new file mode 100644
index 00000000..21342557
--- /dev/null
+++ b/source/queries/starred.graphql
@@ -0,0 +1,31 @@
+query Starred {
+ user(login: "$login") {
+ starredRepositories(first: $limit, orderBy: {field: STARRED_AT, direction: DESC}) {
+ edges {
+ starredAt
+ node {
+ description
+ forkCount
+ isFork
+ issues {
+ totalCount
+ }
+ nameWithOwner
+ openGraphImageUrl
+ licenseInfo {
+ nickname
+ name
+ }
+ pullRequests {
+ totalCount
+ }
+ stargazerCount
+ primaryLanguage {
+ color
+ name
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/source/templates/classic/image.svg b/source/templates/classic/image.svg
index 241ee21c..9de19ff7 100644
--- a/source/templates/classic/image.svg
+++ b/source/templates/classic/image.svg
@@ -777,6 +777,76 @@
<% } %>
+ <% if (plugins.stars) { %>
+
+
+
+ Recently starred repositories
+
+
+
+ <% if (plugins.stars.error) { %>
+
+
+ <%= plugins.stars.error.message %>
+
+ <% } else { %>
+ <% for (const {starred, node:repository} of plugins.stars.repositories) { %>
+
+
+
+ <% if (repository.isFork) { %>
+
+ <% } else { %>
+
+ <% } %>
+
+ <%= repository.nameWithOwner %>
+ starred <%= starred %>
+
+
+
+ <%= repository.description %>
+
+
+ <% if (repository.primaryLanguage) { %>
+
+
+ <%= repository.primaryLanguage.name %>
+
+ <% } %>
+ <% if (repository.licenseInfo) { %>
+
+
+ <%= repository.licenseInfo.nickname ?? repository.licenseInfo.name %>
+
+ <% } %>
+
+
+ <%= repository.stargazers %>
+
+
+
+ <%= repository.forks %>
+
+
+
+ <%= repository.issues.totalCount %>
+
+
+
+ <%= repository.pullRequests.totalCount %>
+
+
+
+
+ <% } %>
+ <% } %>
+
+
+
+ <% } %>
+
<% if (base.metadata) { %>