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. + +![Stars plugin](https://github.com/lowlighter/lowlighter/blob/master/metrics.plugin.stars.svg) + +
+💬 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) { %>