diff --git a/source/app/web/statics/app.placeholder.js b/source/app/web/statics/app.placeholder.js
index ee47d62b..aedb04d0 100644
--- a/source/app/web/statics/app.placeholder.js
+++ b/source/app/web/statics/app.placeholder.js
@@ -743,6 +743,23 @@
},
})
: null),
+ //Starlists
+ ...(set.plugins.enabled.starlists
+ ? ({
+ starlists: {
+ lists: new Array(Number(options["starlists.limit"])).fill(null).map(_ => ({
+ link: faker.internet.url(),
+ name: `${faker.random.arrayElement(["đ", "đĨŗ", "đ§", "đ", "đ"])} ${faker.lorem.word()}`,
+ description: faker.lorem.sentence(),
+ count: faker.datatype.number(100),
+ repositories: new Array(Number(options["starlists.limit.repositories"])).fill(null).map((_, i) => ({
+ description: !i ? "đ 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 !" : faker.lorem.sentence(),
+ name: !i ? "lowlighter/metrics" : `${faker.random.word()}/${faker.random.word()}`,
+ }))
+ })),
+ },
+ })
+ : null),
//Repositories
...(set.plugins.enabled.repositories
? ({
diff --git a/source/plugins/starlists/README.md b/source/plugins/starlists/README.md
new file mode 100644
index 00000000..3c2234d0
--- /dev/null
+++ b/source/plugins/starlists/README.md
@@ -0,0 +1,25 @@
+### đĢ Starlists
+
+The *starlists* plugin displays your recently star lists.
+
+
+
+
+
+ |
+
+
+#### âšī¸ Examples workflows
+
+[âĄī¸ Available options for this plugin](metadata.yml)
+
+```yaml
+- uses: lowlighter/metrics@latest
+ with:
+ # ... other options
+ plugin_starlists: yes
+ plugin_starlists_limit: 16 # Limit to 16 entries
+ plugin_starlists_limit_repositories: 2 # Limit to 2 repositories per entries
+ plugin_starlists_ignored: list1, list2 # Ignored lists
+ plugin_starlists_only: list3 # Only display this list
+```
\ No newline at end of file
diff --git a/source/plugins/starlists/index.mjs b/source/plugins/starlists/index.mjs
new file mode 100644
index 00000000..4ec16ab3
--- /dev/null
+++ b/source/plugins/starlists/index.mjs
@@ -0,0 +1,55 @@
+//Setup
+export default async function({login, q, imports, data, account}, {enabled = false} = {}) {
+ //Plugin execution
+ try {
+ //Check if plugin is enabled and requirements are met
+ if ((!enabled)||(!q.starlists))
+ return null
+
+ //Load inputs
+ let {limit, ignored, only, "limit.repositories":_limit} = imports.metadata.plugins.starlists.inputs({data, account, q})
+
+ //Start puppeteer and navigate to star lists
+ console.debug(`metrics/compute/${login}/plugins > starlists > starting browser`)
+ const browser = await imports.puppeteer.launch()
+ console.debug(`metrics/compute/${login}/plugins > starlists > started ${await browser.version()}`)
+ const page = await browser.newPage()
+
+ //Fetch star lists
+ console.debug(`metrics/compute/${login}/plugins > starlists > fetching lists`)
+ await page.goto(`https://github.com/${login}?tab=stars`)
+ let lists = (await page.evaluate(() => [...document.querySelectorAll("[href^='/stars/lowlighter/lists']")].map(element => ({
+ link:element.href,
+ name:element.querySelector("h3")?.innerText ?? "",
+ description:element.querySelector("span")?.innerText ?? "",
+ count:Number(element.querySelector("div")?.innerText.match(/(?\d+)/)?.groups.count),
+ repositories:[]
+ }))))
+ const count = lists.length
+ lists = lists.slice(0, limit).filter(({name}) => (only.includes(name.toLocaleLowerCase())) || ((!only.length)&&((!name)||(!ignored.includes(name.toLocaleLowerCase())))))
+ console.debug(`metrics/compute/${login}/plugins > starlists > extracted ${lists.length} lists`)
+
+ //Fetch star list content
+ for (const list of lists) {
+ console.debug(`metrics/compute/${login}/plugins > starlists > fetching ${list.name}`)
+ await page.goto(list.link)
+ const repositories = await page.evaluate(() => [...document.querySelectorAll("#user-list-repositories > div")].map(element => ({
+ name:element.querySelector("div:first-child")?.innerText.replace(" / ", "/") ?? "",
+ description:element.querySelector(".py-1")?.innerText ?? ""
+ })))
+ list.repositories.push(...repositories)
+ list.repositories = list.repositories.slice(0, _limit)
+ }
+
+ //Close browser
+ console.debug(`metrics/compute/${login}/plugins > starlists > closing browser`)
+ await browser.close()
+
+ //Results
+ return {lists, count}
+ }
+ //Handle errors
+ catch (error) {
+ throw {error:{message:"An error occured", instance:error}}
+ }
+}
\ No newline at end of file
diff --git a/source/plugins/starlists/metadata.yml b/source/plugins/starlists/metadata.yml
new file mode 100644
index 00000000..4ffa1e4a
--- /dev/null
+++ b/source/plugins/starlists/metadata.yml
@@ -0,0 +1,46 @@
+name: "đĢ Starlists"
+category: github
+index: ~
+supports:
+ - user
+scopes: []
+inputs:
+
+ # Enable or disable plugin
+ plugin_starlists:
+ description: Display star lists
+ type: boolean
+ default: no
+
+ # Number of star lists to display
+ plugin_starlists_limit:
+ description: Number of star lists to display
+ type: number
+ default: 2
+ min: 1
+ max: 100
+
+ # Number of repositories to display per star lists
+ plugin_starlists_limit_repositories:
+ description: Number of repositories to display per star lists
+ type: number
+ default: 2
+ min: 0
+ max: 100
+
+ # List of star lists that will be ignored
+ plugin_starlists_ignored:
+ description: Star lists to skip
+ type: array
+ format: comma-separated
+ default: ""
+ example: đ list1, đĨŗ list2, ...
+
+ # List of star lists to display
+ # Using this option is equivalent of using "plugin_starlists_ignored" with all star lists but the ones listed
+ plugin_starlists_only:
+ description: Start lists to display
+ type: array
+ format: comma-separated
+ default: ""
+ example: đ list1, đĨŗ list2, ...
diff --git a/source/plugins/starlists/tests.yml b/source/plugins/starlists/tests.yml
new file mode 100644
index 00000000..c978d269
--- /dev/null
+++ b/source/plugins/starlists/tests.yml
@@ -0,0 +1,5 @@
+- name: Starlists plugin (default)
+ uses: lowlighter/metrics@latest
+ with:
+ token: MOCKED_TOKEN
+ plugin_starlists: yes
\ No newline at end of file
diff --git a/source/templates/classic/partials/_.json b/source/templates/classic/partials/_.json
index 5537703d..d7d3797b 100644
--- a/source/templates/classic/partials/_.json
+++ b/source/templates/classic/partials/_.json
@@ -20,6 +20,7 @@
"tweets",
"isocalendar",
"stars",
+ "starlists",
"stargazers",
"people",
"activity",
diff --git a/source/templates/classic/partials/starlists.ejs b/source/templates/classic/partials/starlists.ejs
new file mode 100644
index 00000000..2ab82d9e
--- /dev/null
+++ b/source/templates/classic/partials/starlists.ejs
@@ -0,0 +1,47 @@
+<% if (plugins.starlists) { %>
+
+
+
+ <%= plugins.starlists?.count ?? "" %> Star list<%= s(plugins.starlists?.count ?? 0) %>
+
+
+
+ <% if (plugins.starlists.error) { %>
+
+
+ <%= plugins.starlists.error.message %>
+
+ <% } else { %>
+ <% for (const {name, description, count, repositories} of plugins.starlists.lists) { %>
+
+
+
+ <%= name %>
+
+
<%= count %> repositor<%= s(count, "y") %>
+
<%= description %>
+
+ <% for (const repository of repositories) { %>
+
+
+
+
+
+ <%= repository.name %>
+
+
+
+
+ <%= repository.description %>
+
+
+
+ <% } %>
+
+
+ <% } %>
+ <% } %>
+
+
+
+<% } %>
\ No newline at end of file
diff --git a/source/templates/classic/style.css b/source/templates/classic/style.css
index baa781fc..8a242c3f 100644
--- a/source/templates/classic/style.css
+++ b/source/templates/classic/style.css
@@ -837,6 +837,31 @@
-webkit-box-orient: vertical;
}
+/* Star lists */
+ .starlist {
+ margin-left: 28px;
+ }
+ .starlist > .description, .starlist > .count {
+ margin-left: 32px;
+ }
+ .starlist > .count {
+ font-size: 12px;
+ color: #666666;
+ }
+ .starlist .repositories {
+ margin-left: -5px;
+ margin-bottom: 20px;
+ }
+ .starlist .repository {
+ margin: 6px 0 0;
+ }
+ .starlist .repository .description {
+ font-size: 11px;
+ }
+ .starlist .repository .name {
+ font-size: 14px;
+ }
+
/* Anilist */
.anilist {
display: flex;