Add activity plugin (#41)
This commit is contained in:
189
README.md
189
README.md
@@ -127,7 +127,7 @@ But there's more with [plugins](https://github.com/lowlighter/metrics/tree/maste
|
||||
</tr>
|
||||
<tr>
|
||||
<th><a href="https://github.com/lowlighter/metrics#-habits">💡 Coding Habits plugin</a></th>
|
||||
<th><a href="https://github.com/lowlighter/metrics#-gists">🎫 Gists plugin</a></th>
|
||||
<th><a href="https://github.com/lowlighter/metrics#-activity">📰 Activity plugin</a></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
@@ -141,8 +141,8 @@ But there's more with [plugins](https://github.com/lowlighter/metrics/tree/maste
|
||||
</details>
|
||||
</td>
|
||||
<td>
|
||||
<a href="https://github.com/lowlighter/metrics#-gists">
|
||||
<img src="https://github.com/lowlighter/lowlighter/blob/master/metrics.plugin.gists.svg" alt="" width="400">
|
||||
<a href="https://github.com/lowlighter/metrics#-activity">
|
||||
<img src="https://github.com/lowlighter/lowlighter/blob/master/metrics.plugin.activity.svg" alt="" width="400">
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -163,16 +163,20 @@ But there's more with [plugins](https://github.com/lowlighter/metrics/tree/maste
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><a href="https://github.com/lowlighter/metrics#-gists">🎫 Gists plugin</a></th>
|
||||
<th><a href="https://github.com/lowlighter/metrics#%EF%B8%8F-base-content">🗃️ Header special features</a></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://github.com/lowlighter/metrics#-gists">
|
||||
<img src="https://github.com/lowlighter/lowlighter/blob/master/metrics.plugin.gists.svg" alt="" width="400">
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="https://github.com/lowlighter/metrics#%EF%B8%8F-base-content">
|
||||
<img src="https://github.com/lowlighter/lowlighter/blob/master/metrics.header.svg" alt="" width="400">
|
||||
</a>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" align="center">
|
||||
@@ -223,8 +227,6 @@ Try it now at [metrics.lecoq.io](https://metrics.lecoq.io/) with your GitHub use
|
||||
Because some plugins require additional configuration and setup, some of them are not available at [metrics.lecoq.io](https://metrics.lecoq.io/).
|
||||
For a fully-featured experience, consider using this as a [GitHub Action](https://github.com/marketplace/actions/github-metrics-as-svg-image) instead!
|
||||
|
||||
[](https://github.com/lowlighter/downtime)
|
||||
|
||||
# 📜 How to use?
|
||||
|
||||
## ⚙️ Using GitHub Action on your profile repository (~5 min setup)
|
||||
@@ -526,66 +528,70 @@ Used template defaults to the `classic` one.
|
||||
<th><span title="Tweets">🐤</span></th>
|
||||
<th><span title="Posts">✒️</span></th>
|
||||
<th><span title="Habits">💡</span></th>
|
||||
<th><span title="Gists">🎫</span></th>
|
||||
<th><span title="Activity">📰</span></th>
|
||||
<th><span title="Stars">🌟</span></th>
|
||||
<th><span title="Stargazers">✨</span></th>
|
||||
<th><span title="Gists">🎫</span></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Classic</th>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td data-for="base">✔️</td>
|
||||
<td data-for="pagespeed">✔️</td>
|
||||
<td data-for="isocalendar">✔️</td>
|
||||
<td data-for="music">✔️</td>
|
||||
<td data-for="languages">✔️</td>
|
||||
<td data-for="followup">✔️</td>
|
||||
<td data-for="topics">✔️</td>
|
||||
<td data-for="projects">✔️</td>
|
||||
<td data-for="lines">✔️</td>
|
||||
<td data-for="traffic">✔️</td>
|
||||
<td data-for="tweets">✔️</td>
|
||||
<td data-for="posts">✔️</td>
|
||||
<td data-for="habits">✔️</td>
|
||||
<th><span title="Available on @master">✔️<sup>M</sup></span></th>
|
||||
<td data-for="stars">✔️</td>
|
||||
<td data-for="stargazers">✔️</td>
|
||||
<td data-for="gists">✔️</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Terminal</th>
|
||||
<td><span title="'Available for hire' and 'Cake day' are not displayed">✔️<sup>P</sup></span></td>
|
||||
<td>✔️</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>✔️</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td data-for="base"><span title="'Available for hire' and 'Cake day' are not displayed">✔️<sup>P</sup></span></td>
|
||||
<td data-for="pagespeed">✔️</td>
|
||||
<td data-for="isocalendar">❌</td>
|
||||
<td data-for="music">❌</td>
|
||||
<td data-for="languages">✔️</td>
|
||||
<td data-for="followup">✔️</td>
|
||||
<td data-for="topics">❌</td>
|
||||
<td data-for="projects">❌</td>
|
||||
<td data-for="lines">✔️</td>
|
||||
<td data-for="traffic">✔️</td>
|
||||
<td data-for="tweets">❌</td>
|
||||
<td data-for="posts">❌</td>
|
||||
<td data-for="habits">❌</td>
|
||||
<td data-for="activity">❌</td>
|
||||
<td data-for="stars">❌</td>
|
||||
<td data-for="stargazers">❌</td>
|
||||
<td data-for="gists">✔️</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Repository<sup>R</sup></th>
|
||||
<td>✔️</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>✔️</td>
|
||||
<td>❌</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>✔️</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>✔️</td>
|
||||
<td data-for="base">✔️</td>
|
||||
<td data-for="pagespeed">❌</td>
|
||||
<td data-for="isocalendar">❌</td>
|
||||
<td data-for="music">❌</td>
|
||||
<td data-for="languages">❌</td>
|
||||
<td data-for="followup">✔️</td>
|
||||
<td data-for="topics">❌</td>
|
||||
<td data-for="projects">✔️</td>
|
||||
<td data-for="lines">✔️</td>
|
||||
<td data-for="traffic">✔️</td>
|
||||
<td data-for="tweets">❌</td>
|
||||
<td data-for="posts">❌</td>
|
||||
<td data-for="habits">❌</td>
|
||||
<td data-for="activity">❌</td>
|
||||
<td data-for="stars">❌</td>
|
||||
<td data-for="stargazers">✔️</td>
|
||||
<td data-for="gists">❌</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -1254,23 +1260,57 @@ By default, dates are based on the Greenwich meridian (England time). In order t
|
||||
|
||||
</details>
|
||||
|
||||
### 🎫 Gists
|
||||
### 📰 Activity
|
||||
|
||||
The *gists* plugin displays your [gists](https://gist.github.com) metrics.
|
||||
🚧 This plugin is available as pre-release on @master branch (unstable)
|
||||
|
||||

|
||||
The *activity* plugin displays your recent activity in GitHub.
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>💬 About</summary>
|
||||
|
||||
It will consume an additional GitHub request per gist fetched.
|
||||
It will consume an additional GitHub request.
|
||||
|
||||
Add the following to your workflow :
|
||||
```yaml
|
||||
- uses: lowlighter/metrics@latest
|
||||
- uses: lowlighter/metrics@master
|
||||
with:
|
||||
# ... other options
|
||||
plugin_gists: yes
|
||||
plugin_activity: yes
|
||||
plugin_activity_limit: 5
|
||||
plugin_activity_days: 14 # Max age for events, set to 0 for unlimited
|
||||
```
|
||||
|
||||
Metrics use data from [GitHub events](https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events/github-event-types) and is able to track the following events :
|
||||
|
||||
| Event | Description |
|
||||
| ------------ | ----------------------------------------------- |
|
||||
| `push` | Push of commits |
|
||||
| `issue` | Opening/Reopening/Closing of issues |
|
||||
| `pr` | Opening/Closing of pull requests |
|
||||
| `ref/create` | Creation of git tags or git branches |
|
||||
| `ref/delete` | Deletion of git tags or git branches |
|
||||
| `release` | Publication of new releases |
|
||||
| `review` | Review of pull requests |
|
||||
| `comment` | Comments on commits, issues and pull requests |
|
||||
| `wiki` | Edition of wiki pages |
|
||||
| `fork` | Forking of repositories |
|
||||
| `star` | Starring of repositories |
|
||||
| `public` | Repositories made public |
|
||||
| `member` | Addition of new collaborator in repository |
|
||||
|
||||
It is possible to filter the type of events you want to display by using `plugin_activity_filter` option.
|
||||
Use the special value `"all"` (default value) to track all events.
|
||||
|
||||
Add the following to your workflow :
|
||||
```yaml
|
||||
- uses: lowlighter/metrics@master
|
||||
with:
|
||||
# ... other options
|
||||
plugin_activity: yes
|
||||
plugin_activity_filter: issue, pr
|
||||
```
|
||||
|
||||
</details>
|
||||
@@ -1318,6 +1358,27 @@ Add the following to your workflow :
|
||||
|
||||
</details>
|
||||
|
||||
### 🎫 Gists
|
||||
|
||||
The *gists* plugin displays your [gists](https://gist.github.com) metrics.
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>💬 About</summary>
|
||||
|
||||
It will consume an additional GitHub request per gist fetched.
|
||||
|
||||
Add the following to your workflow :
|
||||
```yaml
|
||||
- uses: lowlighter/metrics@latest
|
||||
with:
|
||||
# ... other options
|
||||
plugin_gists: yes
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### 🔧 Other options
|
||||
|
||||
A few additional options are available.
|
||||
@@ -1353,6 +1414,9 @@ It is possible to adjust the padding by adding the following to your workflow :
|
||||
|
||||
Both positive and negative values are accepted, but you must specify a percentage.
|
||||
|
||||
If you specify a single value, it'll be used as for both width and height padding.
|
||||
When two values are specified separated by a comma, the first one will be used for width and the second for height.
|
||||
|
||||
#### 💱 Convert output to PNG/JPEG
|
||||
|
||||
It is possible to convert output from SVG to PNG or JPEG images by adding the following to your workflow :
|
||||
@@ -1390,3 +1454,4 @@ Read [CONTRIBUTING.md](CONTRIBUTING.md) for more information about this.
|
||||
* [jstrieb/github-stats](https://github.com/jstrieb/github-stats)
|
||||
* [ankurparihar/readme-pagespeed-insights](https://github.com/ankurparihar/readme-pagespeed-insights)
|
||||
* [jasonlong/isometric-contributions](https://github.com/jasonlong/isometric-contributions)
|
||||
* [jamesgeorge007/github-activity-readme](https://github.com/jamesgeorge007/github-activity-readme)
|
||||
|
||||
79
action.yml
79
action.yml
@@ -4,58 +4,61 @@
|
||||
inputs:
|
||||
|
||||
# Personal user token
|
||||
# No additional scopes are needed, unless if you want to include private repositories metrics or use the traffic plugin
|
||||
# No additional scopes are needed unless you want to include private repositories metrics
|
||||
# Some plugins may also require additional scopes
|
||||
token:
|
||||
description: GitHub Personal Token
|
||||
required: true
|
||||
|
||||
# Set to "${{ secrets.GITHUB_TOKEN }}"
|
||||
committer_token:
|
||||
description: Token used for commits
|
||||
description: GitHub Token used to commit metrics
|
||||
default: ""
|
||||
|
||||
# User to compute metrics
|
||||
# Defaults to the owner of "token"
|
||||
# GitHub username
|
||||
# Optional, as it defaults "token"'s owner
|
||||
user:
|
||||
description: GitHub username
|
||||
default: ""
|
||||
|
||||
# Filepath of generated metrics (relative to repository root)
|
||||
# Output path for generated metrics, relative to repository's root
|
||||
filename:
|
||||
description: Path of SVG image output
|
||||
default: github-metrics.svg
|
||||
|
||||
# Optimize SVG image with SVGO (minify and remove useless attributes and spaces)
|
||||
# Optimize SVG image with SVGO
|
||||
# It minifies and removes useless attributes
|
||||
# Some templates may not support this option
|
||||
optimize:
|
||||
description: Optimize SVG image
|
||||
description: SVG optimization
|
||||
default: yes
|
||||
|
||||
# Set timezone used by metrics
|
||||
# Timezone used by metrics
|
||||
# See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
# Some plugins will use this setting to calibrate dates
|
||||
# Some plugins will use it to calibrate dates
|
||||
config_timezone:
|
||||
description: Timezone used by metrics
|
||||
description: Timezone used
|
||||
default: ""
|
||||
|
||||
# Specify output type
|
||||
# Metrics output type
|
||||
# Supported values are :
|
||||
# - svg (support animations and transparency)
|
||||
# - png (support transparency)
|
||||
# - jpeg
|
||||
# - svg
|
||||
# - png (does not support animations)
|
||||
# - jpeg (does not support animations and transparency)
|
||||
config_output:
|
||||
description: Output image type
|
||||
default: svg
|
||||
|
||||
# Enable or disable SVG animations
|
||||
# Enable or disable SVG CSS animations
|
||||
config_animations:
|
||||
description: Enable or disable SVG animations
|
||||
description: SVG CSS animations
|
||||
default: yes
|
||||
|
||||
# Add bottom padding (percentage)
|
||||
# This can used to add padding if generated image is cropped or on the contrary, remove empty space
|
||||
# Configure padding for output image (percentage)
|
||||
# It can be used to add padding to generated metrics if rendering is cropped or has too much empty space
|
||||
# You can specify one value (for both width and height) and two values (one for width and one for height, seperated by a comma)
|
||||
config_padding:
|
||||
description: Configure bottom padding
|
||||
description: Image padding
|
||||
default: 6%
|
||||
|
||||
# Number of repositories to use for metrics
|
||||
@@ -363,6 +366,40 @@ inputs:
|
||||
description: Display stargazers evolution over the last two weeks
|
||||
default: no
|
||||
|
||||
# Display recent activity
|
||||
plugin_activity:
|
||||
description: Display recent activity
|
||||
default: no
|
||||
|
||||
# Number of activity events to display
|
||||
# Capped to 100
|
||||
plugin_activity_limit:
|
||||
description: Number of activity events to display
|
||||
default: 5
|
||||
|
||||
# Disacard older events
|
||||
# Use 0 to display activity whatever the date
|
||||
plugin_activity_days:
|
||||
description: Maximum activity event age
|
||||
default: 14
|
||||
|
||||
# Events type to display
|
||||
# Pass a string of comma-separated values
|
||||
# Supported values are
|
||||
# - "comment" for all kind of comments (commits, issue and pr)
|
||||
# - "ref/create" and "ref/delete" for tag and branch creation/deletion
|
||||
# - "release" for new published releases
|
||||
# - "wiki" for wiki edition
|
||||
# - "push" for pushed commits
|
||||
# - "issue" and "pr" for issues and pull requests
|
||||
# - "review" for pull requests review
|
||||
# - "public" for repositories made public
|
||||
# - "fork" and "star" for forked and starred repositories
|
||||
# - "member" for accepted repository invitations
|
||||
plugin_activity_filter:
|
||||
description: Events to display
|
||||
default: all
|
||||
|
||||
# ====================================================================================
|
||||
# Options below are mostly used for testing
|
||||
|
||||
@@ -417,7 +454,7 @@ branding:
|
||||
|
||||
# The action will parse its name to check if it's the official action or if it's a forked one
|
||||
# On the official action, it'll use the docker image published on GitHub registry when using a released version, allowing faster runs
|
||||
# On a forked action, it'll rebuild the docker image from Dockerfile
|
||||
# On a forked action, it'll rebuild the docker image from Dockerfile to take into account changes you made
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
@@ -458,7 +495,7 @@ runs:
|
||||
set +e
|
||||
METRICS_IS_RELEASED=$(expr $(expr match $METRICS_VERSION .*-beta) == 0)
|
||||
set -e
|
||||
echo "Unreleased: $METRICS_IS_RELEASED"
|
||||
echo "Is released version: $METRICS_IS_RELEASED"
|
||||
# Rebuild image for unreleased version
|
||||
if [[ $METRICS_IS_RELEASED ]]; then
|
||||
echo "Using released version $METRICS_TAG, will pull docker image from GitHub registry"
|
||||
|
||||
@@ -64,6 +64,9 @@
|
||||
},
|
||||
"stargazers":{ "//":"Stargazers plugin",
|
||||
"enabled":false, "//":"Enable or disable stargazers charts display"
|
||||
},
|
||||
"activity":{ "//":"Activity plugin",
|
||||
"enabled":false, "//":"Enable or disable recent activity display"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,6 +141,7 @@
|
||||
tweets:{enabled:input.bool("plugin_tweets")},
|
||||
stars:{enabled:input.bool("plugin_stars")},
|
||||
stargazers:{enabled:input.bool("plugin_stargazers")},
|
||||
activity:{enabled:input.bool("plugin_activity")},
|
||||
}
|
||||
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))
|
||||
@@ -215,6 +216,13 @@
|
||||
for (const option of ["limit"])
|
||||
info(`Stars ${option}`, q[`stars.${option}`] = input.number(`plugin_stars_${option}`))
|
||||
}
|
||||
//Activity
|
||||
if (plugins.activity.enabled) {
|
||||
for (const option of ["limit", "days"])
|
||||
info(`Activity ${option}`, q[`activity.${option}`] = input.number(`plugin_activity_${option}`))
|
||||
for (const option of ["filter"])
|
||||
info(`Activity ${option}`, q[`activity.${option}`] = input.array(`plugin_activity_${option}`))
|
||||
}
|
||||
|
||||
//Repositories to use
|
||||
const repositories = input.number("repositories")
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
console.debug(`metrics/compute/${login} > render`)
|
||||
let rendered = await ejs.render(image, {...data, s, style, fonts}, {async:true})
|
||||
//Apply resizing
|
||||
const {resized, mime} = await svgresize(rendered, {padding:q["config.padding"], convert})
|
||||
const {resized, mime} = await svgresize(rendered, {paddings:q["config.padding"], convert})
|
||||
rendered = resized
|
||||
|
||||
//Additional SVG transformations
|
||||
@@ -180,16 +180,16 @@
|
||||
}
|
||||
|
||||
/** Render svg */
|
||||
async function svgresize(svg, {padding = "6%", convert} = {}) {
|
||||
async function svgresize(svg, {paddings = "6%", convert} = {}) {
|
||||
//Instantiate browser if needed
|
||||
if (!svgresize.browser) {
|
||||
svgresize.browser = await puppeteer.launch({headless:true, executablePath:process.env.PUPPETEER_BROWSER_PATH, args:["--no-sandbox", "--disable-extensions", "--disable-setuid-sandbox", "--disable-dev-shm-usage"]})
|
||||
console.debug(`metrics/svgresize > started ${await svgresize.browser.version()}`)
|
||||
}
|
||||
//Format padding
|
||||
padding = ((Number(`${padding}`.substring(0, padding.length-1))||0)/100)
|
||||
console.debug(`metrics/svgresize > padding ${(100*padding).toFixed(2)}%`)
|
||||
padding += 1
|
||||
const [pw = 1, ph] = paddings.split(",").map(padding => `${padding}`.substring(0, padding.length-1)).map(value => 1+Number(value)/100)
|
||||
const padding = {width:pw, height:ph ?? pw}
|
||||
console.debug(`metrics/svgresize > padding width*${padding.width}, height*${padding.height}`)
|
||||
//Render through browser and resize height
|
||||
const page = await svgresize.browser.newPage()
|
||||
await page.setContent(svg, {waitUntil:"load"})
|
||||
@@ -201,8 +201,8 @@
|
||||
document.querySelector("svg").classList.add("no-animations")
|
||||
//Get bounds and resize
|
||||
let {y:height, width} = document.querySelector("svg #metrics-end").getBoundingClientRect()
|
||||
height = Math.ceil(height*padding)
|
||||
width = Math.ceil(width)
|
||||
height = Math.ceil(height*padding.height)
|
||||
width = Math.ceil(width*padding.width)
|
||||
//Resize svg
|
||||
document.querySelector("svg").setAttribute("height", height)
|
||||
//Enable animations
|
||||
@@ -270,6 +270,7 @@
|
||||
projects:{list:[...new Array(2).fill(null).map(() => ({name:"########", updated:"########", progress:{enabled:true, todo:"##", doing:"##", done:"##", total:"##"}}))]},
|
||||
tweets:{profile:{username:"########", verified:false}, list:[...new Array(2).fill(null).map(() => ({text:"###### ###### ####### ######".repeat(4), created_at:Date.now()}))]},
|
||||
stars:{repositories:[...new Array(2).fill({node:{nameWithOwner:"########/########", description:"###### ###### ####### ######".repeat(4)}})]},
|
||||
activity:{events:[{type:"comment", on:"pr"}, {type:"public"}, {type:"release"}, {type:"issue"}]}
|
||||
}[key]??{})]
|
||||
)),
|
||||
})
|
||||
|
||||
@@ -434,32 +434,316 @@
|
||||
status:"200 OK",
|
||||
"x-oauth-scopes":"repo",
|
||||
},
|
||||
data:page < 1 ? new Array(10).fill(null).map(() =>
|
||||
(false ? {
|
||||
id:"10000000001",
|
||||
type:"IssueCommentEvent",
|
||||
} : {
|
||||
data:page < 1 ? [] : [
|
||||
{
|
||||
id:"10000000000",
|
||||
type:"PushEvent",
|
||||
type:"CommitCommentEvent",
|
||||
actor:{
|
||||
id:22963968,
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo: {
|
||||
id:293860197,
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload: {
|
||||
ref:"refs/heads/master",
|
||||
commits: [
|
||||
payload:{
|
||||
comment:{
|
||||
user:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
path:"README.md",
|
||||
commit_id:"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
body:"This is a commit comment",
|
||||
}
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
url:"https://api.github.com/repos/lowlighter/metrics/commits/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
id:"10000000001",
|
||||
type:"PullRequestReviewCommentEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload:{
|
||||
action:"created",
|
||||
comment:{
|
||||
user:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
body:"This is pull request review comment",
|
||||
},
|
||||
pull_request:{
|
||||
title:"Pull request example",
|
||||
number:1,
|
||||
user:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
body:"",
|
||||
}
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000002",
|
||||
type:"IssuesEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload:{
|
||||
action:"closed",
|
||||
issue:{
|
||||
number:2,
|
||||
title:"Issue example",
|
||||
user:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
body:"Hello this is an example",
|
||||
performed_via_github_app: null
|
||||
}
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000003",
|
||||
type:"GollumEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/lowlighter",
|
||||
},
|
||||
payload:{
|
||||
pages:[
|
||||
{
|
||||
page_name:"Home",
|
||||
title:"Home",
|
||||
summary:null,
|
||||
action:"created",
|
||||
sha:"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
}
|
||||
]
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString()
|
||||
})
|
||||
) : []
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000004",
|
||||
type:"IssueCommentEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload:{
|
||||
action:"created",
|
||||
issue:{
|
||||
number:3,
|
||||
title:"Issue example",
|
||||
user:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
labels:[
|
||||
{
|
||||
name:"question",
|
||||
color:"d876e3",
|
||||
}
|
||||
],
|
||||
state:"open",
|
||||
},
|
||||
comment:{
|
||||
body:"Hello world !",
|
||||
performed_via_github_app: null
|
||||
}
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000005",
|
||||
type:"ForkEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
id:327522930,
|
||||
name:"lowlighter/gracidea",
|
||||
},
|
||||
payload:{
|
||||
forkee:{
|
||||
name:"gracidea",
|
||||
full_name:"lowlighter/gracidea",
|
||||
}
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000006",
|
||||
type:"PullRequestReviewEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload:{
|
||||
action:"created",
|
||||
review:{
|
||||
user:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
state:"approved",
|
||||
},
|
||||
pull_request:{
|
||||
state:"open",
|
||||
number:4,
|
||||
locked:false,
|
||||
title:"Pull request example",
|
||||
user:{
|
||||
login:"user",
|
||||
},
|
||||
}
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000007",
|
||||
type:"ReleaseEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload:{
|
||||
action:"published",
|
||||
release:{
|
||||
tag_name:"v3.1",
|
||||
name:"Version 3.1",
|
||||
draft: false,
|
||||
prerelease: true,
|
||||
}
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000008",
|
||||
type:"CreateEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload:{
|
||||
ref:"feat-new-plugin",
|
||||
ref_type:"branch",
|
||||
master_branch:"master",
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"100000000009",
|
||||
type:"WatchEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/gracidea",
|
||||
},
|
||||
payload:{action:"started"},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000010",
|
||||
type:"DeleteEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload:{
|
||||
ref:"feat-plugin-merged",
|
||||
ref_type:"branch",
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000011",
|
||||
type:"PushEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload:{
|
||||
size:1,
|
||||
ref:"refs/heads/master",
|
||||
commits:[
|
||||
{
|
||||
sha:"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
message:"Commit example",
|
||||
}
|
||||
]
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000012",
|
||||
type:"PullRequestEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload:{
|
||||
action:"opened",
|
||||
number:5,
|
||||
pull_request:{
|
||||
state:"open",
|
||||
title:"Pull request example",
|
||||
additions:210,
|
||||
deletions:126,
|
||||
changed_files:10,
|
||||
}
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000013",
|
||||
type:"MemberEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload:{
|
||||
member:{
|
||||
login:"botlighter",
|
||||
},
|
||||
action:"added"
|
||||
},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id:"10000000014",
|
||||
type:"PublicEvent",
|
||||
actor:{
|
||||
login:"lowlighter",
|
||||
},
|
||||
repo:{
|
||||
name:"lowlighter/metrics",
|
||||
},
|
||||
payload:{},
|
||||
created_at:new Date(Date.now()-Math.floor(-Math.random()*14)*Math.floor(-Math.random()*24)*60*60*1000).toISOString(),
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
const actions = {flush:new Map()}
|
||||
app.get("/", limiter, (req, res) => res.sendFile(`${conf.statics}/index.html`))
|
||||
app.get("/index.html", limiter, (req, res) => res.sendFile(`${conf.statics}/index.html`))
|
||||
app.get("/favicon.ico", limiter, (req, res) => res.sendFile(`${conf.statics}/favicon.png`))
|
||||
app.get("/.favicon.png", limiter, (req, res) => res.sendFile(`${conf.statics}/favicon.png`))
|
||||
app.get("/.opengraph.png", limiter, (req, res) => res.sendFile(`${conf.statics}/opengraph.png`))
|
||||
app.get("/.version", limiter, (req, res) => res.status(200).send(conf.package.version))
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
tweets:"🐤 Latest tweets",
|
||||
stars:"🌟 Recently starred repositories",
|
||||
stargazers:"✨ Stargazers over last weeks",
|
||||
activity:"📰 Recent activity",
|
||||
"base.header":`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M0 8a8 8 0 1116 0v5.25a.75.75 0 01-1.5 0V8a6.5 6.5 0 10-13 0v5.25a.75.75 0 01-1.5 0V8zm5.5 4.25a.75.75 0 01.75-.75h3.5a.75.75 0 010 1.5h-3.5a.75.75 0 01-.75-.75zM3 6.75C3 5.784 3.784 5 4.75 5h6.5c.966 0 1.75.784 1.75 1.75v1.5A1.75 1.75 0 0111.25 10h-6.5A1.75 1.75 0 013 8.25v-1.5zm1.47-.53a.75.75 0 011.06 0l.97.97.97-.97a.75.75 0 011.06 0l.97.97.97-.97a.75.75 0 111.06 1.06l-1.5 1.5a.75.75 0 01-1.06 0L8 7.81l-.97.97a.75.75 0 01-1.06 0l-1.5-1.5a.75.75 0 010-1.06z"></path></svg>
|
||||
Header`,
|
||||
@@ -95,6 +96,7 @@
|
||||
"topics.limit":12,
|
||||
"tweets.limit":2,
|
||||
"stars.limit":4,
|
||||
"activity.limit":5,
|
||||
},
|
||||
},
|
||||
templates:{
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Plugins options -->
|
||||
<div class="step" v-if="(plugins.enabled.tweets)||(plugins.enabled.music)||(plugins.enabled.pagespeed)||(plugins.enabled.languages)||(plugins.enabled.habits)||(plugins.enabled.posts)||(plugins.enabled.isocalendar)||(plugins.enabled.projects)||(plugins.enabled.topics)">
|
||||
<div class="step" v-if="(plugins.enabled.tweets)||(plugins.enabled.music)||(plugins.enabled.pagespeed)||(plugins.enabled.languages)||(plugins.enabled.habits)||(plugins.enabled.posts)||(plugins.enabled.isocalendar)||(plugins.enabled.projects)||(plugins.enabled.topics)||(plugins.enabled.activity)">
|
||||
<h2>🔧 Configure plugins</h2>
|
||||
<div class="options">
|
||||
<div class="options-group" v-if="plugins.enabled.tweets">
|
||||
@@ -231,6 +231,13 @@
|
||||
<input type="text" v-model="plugins.options['projects.repositories']" @change="load" :disabled="generated.pending">
|
||||
</label>
|
||||
</div>
|
||||
<div class="options-group" v-if="plugins.enabled.activity">
|
||||
<h4>{{ plugins.descriptions.activity }}</h4>
|
||||
<label>
|
||||
Number of activity events to display
|
||||
<input type="number" v-model="plugins.options['activity.limit']" min="1" max="10" @change="load" :disabled="generated.pending">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
136
source/plugins/activity/index.mjs
Normal file
136
source/plugins/activity/index.mjs
Normal file
@@ -0,0 +1,136 @@
|
||||
//Setup
|
||||
export default async function ({login, rest, imports, q}, {enabled = false} = {}) {
|
||||
//Plugin execution
|
||||
try {
|
||||
//Check if plugin is enabled and requirements are met
|
||||
if ((!enabled)||(!q.activity))
|
||||
return null
|
||||
|
||||
//Parameters override
|
||||
let {"activity.limit":limit = 5, "activity.days":days = 7, "activity.filter":filter = "all"} = q
|
||||
//Events
|
||||
limit = Math.max(1, Math.min(100, Number(limit)))
|
||||
//Days
|
||||
days = Number(days) > 0 ? Number(days) : Infinity
|
||||
//Filtered events
|
||||
filter = decodeURIComponent(filter).split(",").map(x => x.trim().toLocaleLowerCase()).filter(x => x)
|
||||
|
||||
//Get user recent activity
|
||||
console.debug(`metrics/compute/${login}/plugins > activity > querying api`)
|
||||
const {data:events} = await rest.activity.listEventsForAuthenticatedUser({username:login, per_page:100})
|
||||
console.debug(`metrics/compute/${login}/plugins > activity > ${events.length} events loaded`)
|
||||
//Extract activity events
|
||||
const activity = events
|
||||
.filter(({actor}) => actor.login === login)
|
||||
.filter(({created_at}) => Number.isFinite(days) ? new Date(created_at) > new Date(Date.now()-days*24*60*60*1000) : true)
|
||||
.map(({type, payload, repo:{name:repo}}) => {
|
||||
//See https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events/github-event-types#memberevent
|
||||
switch (type) {
|
||||
//Commented on a commit
|
||||
case "CommitCommentEvent":{
|
||||
if (!["created"].includes(payload.action))
|
||||
return null
|
||||
const {comment:{user:{login:user}, commit_id:sha, body:content}} = payload
|
||||
return {type:"comment", on:"commit", repo, content, user, mobile:null, number:sha.substring(0, 7), title:""}
|
||||
}
|
||||
//Created a git branch or tag
|
||||
case "CreateEvent":{
|
||||
const {ref:name, ref_type:type} = payload
|
||||
return {type:"ref/create", repo, ref:{name, type}}
|
||||
}
|
||||
//Deleted a git branch or tag
|
||||
case "DeleteEvent":{
|
||||
const {ref:name, ref_type:type} = payload
|
||||
return {type:"ref/delete", repo, ref:{name, type}}
|
||||
}
|
||||
//Forked repository
|
||||
case "ForkEvent":{
|
||||
return {type:"fork", repo}
|
||||
}
|
||||
//Wiki editions
|
||||
case "GollumEvent":{
|
||||
const {pages} = payload
|
||||
return {type:"wiki", repo, pages:pages.map(({title}) => title)}
|
||||
}
|
||||
//Commented on an issue
|
||||
case "IssueCommentEvent":{
|
||||
if (!["created"].includes(payload.action))
|
||||
return null
|
||||
const {issue:{user:{login:user}, title, number}, comment:{body:content, performed_via_github_app:mobile}} = payload
|
||||
return {type:"comment", on:"issue", repo, content, user, mobile, number, title}
|
||||
}
|
||||
//Issue event
|
||||
case "IssuesEvent":{
|
||||
if (!["opened", "closed", "reopened"].includes(payload.action))
|
||||
return null
|
||||
const {action, issue:{user:{login:user}, title, number}} = payload
|
||||
return {type:"issue", repo, action, user, number, title}
|
||||
}
|
||||
//Activity from repository collaborators
|
||||
case "MemberEvent":{
|
||||
if (!["added"].includes(payload.action))
|
||||
return null
|
||||
const {member:{login:user}} = payload
|
||||
return {type:"member", repo, user}
|
||||
}
|
||||
//Made repository public
|
||||
case "PublicEvent":{
|
||||
return {type:"public", repo}
|
||||
}
|
||||
//Pull requests events
|
||||
case "PullRequestEvent":{
|
||||
if (!["opened", "closed"].includes(payload.action))
|
||||
return null
|
||||
const {action, pull_request:{title, number, additions:added, deletions:deleted, changed_files:changed}} = payload
|
||||
return {type:"pr", repo, action, title, number, lines:{added, deleted}, files:{changed}}
|
||||
}
|
||||
//Reviewed a pull request
|
||||
case "PullRequestReviewEvent":{
|
||||
const {review:{state:review}, pull_request:{user:{login:user}, number, title}} = payload
|
||||
return {type:"review", repo, review, user, number, title}
|
||||
}
|
||||
//Commented on a pull request
|
||||
case "PullRequestReviewCommentEvent":{
|
||||
if (!["created"].includes(payload.action))
|
||||
return null
|
||||
const {pull_request:{user:{login:user}, title, number}, comment:{body:content, performed_via_github_app:mobile}} = payload
|
||||
return {type:"comment", on:"pr", repo, content, user, mobile, number, title}
|
||||
}
|
||||
//Pushed commits
|
||||
case "PushEvent":{
|
||||
const {size, commits, ref} = payload
|
||||
return {type:"push", repo, size, branch:ref.match(/refs.heads.(?<branch>.*)/)?.groups?.branch ?? null, commits:commits.map(({sha, message}) => ({sha:sha.substring(0, 7), message}))}
|
||||
}
|
||||
//Released
|
||||
case "ReleaseEvent":{
|
||||
if (!["published"].includes(payload.action))
|
||||
return null
|
||||
const {action, release:{name, prerelease, draft}} = payload
|
||||
return {type:"release", repo, action, name, prerelease, draft}
|
||||
}
|
||||
//Starred a repository
|
||||
case "WatchEvent":{
|
||||
if (!["started"].includes(payload.action))
|
||||
return null
|
||||
const {action} = payload
|
||||
return {type:"star", repo, action}
|
||||
}
|
||||
//Unknown event
|
||||
default:{
|
||||
return null
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter(event => event)
|
||||
.filter(event => filter.includes("all") || filter.includes(event.type))
|
||||
.slice(0, limit)
|
||||
|
||||
//Results
|
||||
return {events:activity}
|
||||
}
|
||||
//Handle errors
|
||||
catch (error) {
|
||||
throw {error:{message:"An error occured", instance:error}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
//Events
|
||||
from = Math.max(1, Math.min(1000, Number(from)))
|
||||
//Days
|
||||
days = Math.max(1, Math.min(30, Number(from)))
|
||||
days = Math.max(1, Math.min(30, Number(days)))
|
||||
//Initialization
|
||||
const habits = {facts, charts, commits:{hour:NaN, hours:{}, day:NaN, days:{}}, indents:{style:"", spaces:0, tabs:0}, linguist:{available:false, ordered:[], languages:{}}}
|
||||
const pages = Math.ceil(from/100)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
await Promise.all(["performance", "accessibility", "best-practices", "seo"].map(async category => {
|
||||
//Perform audit
|
||||
console.debug(`metrics/compute/${login}/plugins > pagespeed > performing audit ${category}`)
|
||||
const request = await imports.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?category=${category}&url=${url}&key=${token}`)
|
||||
const request = await imports.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?category=${category}&url=${url}${token ? `&key=${token}` : ""}`)
|
||||
console.debug(request.data)
|
||||
const {score, title} = request.data.lighthouseResult.categories[category]
|
||||
scores.set(category, {score, title})
|
||||
@@ -34,7 +34,7 @@
|
||||
//Detailed metrics
|
||||
if (detailed) {
|
||||
console.debug(`metrics/compute/${login}/plugins > pagespeed > performing detailed audit`)
|
||||
const request = await imports.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?&url=${url}&key=${token}`)
|
||||
const request = await imports.axios.get(`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?&url=${url}${token ? `&key=${token}` : ""}`)
|
||||
console.debug(request.data)
|
||||
Object.assign(result.metrics, ...request.data.lighthouseResult.audits.metrics.details.items)
|
||||
console.debug(`metrics/compute/${login}/plugins > pagespeed > performed detailed audit (status code ${request.status})`)
|
||||
|
||||
@@ -895,6 +895,152 @@
|
||||
</section>
|
||||
<% } %>
|
||||
|
||||
<% if (plugins.activity) { %>
|
||||
<section>
|
||||
<h2 class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M0 8a8 8 0 1116 0v5.25a.75.75 0 01-1.5 0V8a6.5 6.5 0 10-13 0v5.25a.75.75 0 01-1.5 0V8zm5.5 4.25a.75.75 0 01.75-.75h3.5a.75.75 0 010 1.5h-3.5a.75.75 0 01-.75-.75zM3 6.75C3 5.784 3.784 5 4.75 5h6.5c.966 0 1.75.784 1.75 1.75v1.5A1.75 1.75 0 0111.25 10h-6.5A1.75 1.75 0 013 8.25v-1.5zm1.47-.53a.75.75 0 011.06 0l.97.97.97-.97a.75.75 0 011.06 0l.97.97.97-.97a.75.75 0 111.06 1.06l-1.5 1.5a.75.75 0 01-1.06 0L8 7.81l-.97.97a.75.75 0 01-1.06 0l-1.5-1.5a.75.75 0 010-1.06z"></path></svg>
|
||||
Recent activity
|
||||
</h2>
|
||||
<div class="row">
|
||||
<section>
|
||||
<% if (plugins.activity.error) { %>
|
||||
<div class="field error">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.343 13.657A8 8 0 1113.657 2.343 8 8 0 012.343 13.657zM6.03 4.97a.75.75 0 00-1.06 1.06L6.94 8 4.97 9.97a.75.75 0 101.06 1.06L8 9.06l1.97 1.97a.75.75 0 101.06-1.06L9.06 8l1.97-1.97a.75.75 0 10-1.06-1.06L8 6.94 6.03 4.97z"></path></svg>
|
||||
<%= plugins.activity.error.message %>
|
||||
</div>
|
||||
<% } else { %>
|
||||
<% if (!plugins.activity.events.length) { %>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.75 1.5a.25.25 0 00-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 01.75.75v2.19l2.72-2.72a.75.75 0 01.53-.22h6.5a.25.25 0 00.25-.25v-9.5a.25.25 0 00-.25-.25H1.75zM0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0114.25 13H8.06l-2.573 2.573A1.457 1.457 0 013 14.543V13H1.75A1.75 1.75 0 010 11.25v-9.5zM9 9a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z"></path></svg>
|
||||
No recent activity
|
||||
</div>
|
||||
<% } %>
|
||||
<% for (const {type, repo, ...event} of plugins.activity.events) { %>
|
||||
<div class="row fill-width">
|
||||
<section class="activity">
|
||||
<% if (/^ref/.test(type)) { %>
|
||||
<div class="field">
|
||||
<% if (event.ref.type === "branch") { %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M11.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122V6A2.5 2.5 0 0110 8.5H6a1 1 0 00-1 1v1.128a2.251 2.251 0 11-1.5 0V5.372a2.25 2.25 0 111.5 0v1.836A2.492 2.492 0 016 7h4a1 1 0 001-1v-.628A2.25 2.25 0 019.5 3.25zM4.25 12a.75.75 0 100 1.5.75.75 0 000-1.5zM3.5 3.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0z"></path></svg>
|
||||
<% } else { %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.5 7.775V2.75a.25.25 0 01.25-.25h5.025a.25.25 0 01.177.073l6.25 6.25a.25.25 0 010 .354l-5.025 5.025a.25.25 0 01-.354 0l-6.25-6.25a.25.25 0 01-.073-.177zm-1.5 0V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 010 2.474l-5.026 5.026a1.75 1.75 0 01-2.474 0l-6.25-6.25A1.75 1.75 0 011 7.775zM6 5a1 1 0 100 2 1 1 0 000-2z"></path></svg>
|
||||
<% } %>
|
||||
<%= /create/.test(type) ? "Created new" : "Deleted" %>
|
||||
<%= event.ref.type %> <div class="code"><%= event.ref.name %></div> in <div class="repo"><%= repo %></div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (type === "comment") { %>
|
||||
<div class="field">
|
||||
<% if (event.on === "pr") { %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 2.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v8.5a.25.25 0 01-.25.25h-6.5a.75.75 0 00-.53.22L4.5 14.44v-2.19a.75.75 0 00-.75-.75h-2a.25.25 0 01-.25-.25v-8.5zM1.75 1A1.75 1.75 0 000 2.75v8.5C0 12.216.784 13 1.75 13H3v1.543a1.457 1.457 0 002.487 1.03L8.061 13h6.189A1.75 1.75 0 0016 11.25v-8.5A1.75 1.75 0 0014.25 1H1.75zm5.03 3.47a.75.75 0 010 1.06L5.31 7l1.47 1.47a.75.75 0 01-1.06 1.06l-2-2a.75.75 0 010-1.06l2-2a.75.75 0 011.06 0zm2.44 0a.75.75 0 000 1.06L10.69 7 9.22 8.47a.75.75 0 001.06 1.06l2-2a.75.75 0 000-1.06l-2-2a.75.75 0 00-1.06 0z"></path></svg>
|
||||
<% } else if ((event.on === "issue")||(event.on === "commit")) { %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.75 2.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 01.75.75v2.19l2.72-2.72a.75.75 0 01.53-.22h4.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25H2.75zM1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0113.25 12H9.06l-2.573 2.573A1.457 1.457 0 014 13.543V12H2.75A1.75 1.75 0 011 10.25v-7.5z"></path></svg>
|
||||
<% } %>
|
||||
Commented on <div class="issue">#<%= event.number %> <%= event.title %></div>
|
||||
</div>
|
||||
<div class="details">
|
||||
<div><%= event.on === "commit" ? "committed" : "opened" %> by <%= event.user %> in <div class="repo"><%= repo %></div></div>
|
||||
<div class="comment"><%= event.content %></div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (type === "wiki") { %>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M0 1.75A.75.75 0 01.75 1h4.253c1.227 0 2.317.59 3 1.501A3.744 3.744 0 0111.006 1h4.245a.75.75 0 01.75.75v10.5a.75.75 0 01-.75.75h-4.507a2.25 2.25 0 00-1.591.659l-.622.621a.75.75 0 01-1.06 0l-.622-.621A2.25 2.25 0 005.258 13H.75a.75.75 0 01-.75-.75V1.75zm8.755 3a2.25 2.25 0 012.25-2.25H14.5v9h-3.757c-.71 0-1.4.201-1.992.572l.004-7.322zm-1.504 7.324l.004-5.073-.002-2.253A2.25 2.25 0 005.003 2.5H1.5v9h3.757a3.75 3.75 0 011.994.574z"></path></svg>
|
||||
Updated <%= event.pages.length %> wiki page<%= s(event.pages.length) %> in <div class="repo"><%= repo %></div>
|
||||
</div>
|
||||
<div class="details">
|
||||
<% for (const page of event.pages) { %>
|
||||
<div class="page">
|
||||
<%= page %>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (type === "pr") { %>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.177 3.073L9.573.677A.25.25 0 0110 .854v4.792a.25.25 0 01-.427.177L7.177 3.427a.25.25 0 010-.354zM3.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122v5.256a2.251 2.251 0 11-1.5 0V5.372A2.25 2.25 0 011.5 3.25zM11 2.5h-1V4h1a1 1 0 011 1v5.628a2.251 2.251 0 101.5 0V5A2.5 2.5 0 0011 2.5zm1 10.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.75 12a.75.75 0 100 1.5.75.75 0 000-1.5z"></path></svg>
|
||||
<%= event.action === "opened" ? "Opened" : "Merged" %> <div class="issue">#<%= event.number %> <%= event.title %></div>
|
||||
</div>
|
||||
<div class="details">
|
||||
<div>opened <%= user.login !== event.user ? `by ${event.user}` : "" %> in <div class="repo"><%= repo %></div></div>
|
||||
<div><%= event.files.changed %> file<%= s(event.files.changed) %> changed <div class="code">++<%= event.lines.added %> --<%= event.lines.deleted%></div></div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (type === "issue") { %>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8zm9 3a1 1 0 11-2 0 1 1 0 012 0zm-.25-6.25a.75.75 0 00-1.5 0v3.5a.75.75 0 001.5 0v-3.5z"></path></svg>
|
||||
<%= event.action === "opened" ? "Opened" : event.action === "reopened" ? "Reopened" : "Closed" %> <div class="issue">#<%= event.number %> <%= event.title %></div>
|
||||
</div>
|
||||
<div class="details">
|
||||
<div>opened <%= user.login !== event.user ? `by ${event.user}` : "" %> in <div class="repo"><%= repo %></div></div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (type === "fork") { %>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"></path></svg>
|
||||
Forked <div class="repo"><%= repo %></div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (type === "public") { %>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path></svg>
|
||||
Made <div class="repo"><%= repo %></div> public
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (type === "review") { %>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.5 1.75a.25.25 0 01.25-.25h8.5a.25.25 0 01.25.25v7.736a.75.75 0 101.5 0V1.75A1.75 1.75 0 0011.25 0h-8.5A1.75 1.75 0 001 1.75v11.5c0 .966.784 1.75 1.75 1.75h3.17a.75.75 0 000-1.5H2.75a.25.25 0 01-.25-.25V1.75zM4.75 4a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-4.5zM4 7.75A.75.75 0 014.75 7h2a.75.75 0 010 1.5h-2A.75.75 0 014 7.75zm11.774 3.537a.75.75 0 00-1.048-1.074L10.7 14.145 9.281 12.72a.75.75 0 00-1.062 1.058l1.943 1.95a.75.75 0 001.055.008l4.557-4.45z"></path></svg>
|
||||
Reviewed <div class="issue">#<%= event.number %> <%= event.title %></div>
|
||||
</div>
|
||||
<div class="details">
|
||||
<div>opened <%= user.login !== event.user ? `by ${event.user}` : "" %> in <div class="repo"><%= repo %></div></div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (type === "push") { %>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M10.5 7.75a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm1.43.75a4.002 4.002 0 01-7.86 0H.75a.75.75 0 110-1.5h3.32a4.001 4.001 0 017.86 0h3.32a.75.75 0 110 1.5h-3.32z"></path></svg>
|
||||
Pushed <%= event.size %> commit<%= s(event.size) %> in <div class="repo"><%= repo %></div>
|
||||
</div>
|
||||
<div class="details">
|
||||
<% if (event.branch) { %>
|
||||
<div>on branch <div class="code"><%= event.branch %></div></div>
|
||||
<% } %>
|
||||
<% for (const commit of event.commits) { %>
|
||||
<div class="commit">
|
||||
<div class="sha">#<%= commit.sha %></div>
|
||||
<div class="message"><%= commit.message %></div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (type === "release") { %>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8.878.392a1.75 1.75 0 00-1.756 0l-5.25 3.045A1.75 1.75 0 001 4.951v6.098c0 .624.332 1.2.872 1.514l5.25 3.045a1.75 1.75 0 001.756 0l5.25-3.045c.54-.313.872-.89.872-1.514V4.951c0-.624-.332-1.2-.872-1.514L8.878.392zM7.875 1.69a.25.25 0 01.25 0l4.63 2.685L8 7.133 3.245 4.375l4.63-2.685zM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432L2.5 5.677zm6.25 8.271l4.625-2.683a.25.25 0 00.125-.216V5.677L8.75 8.432v5.516z"></path></svg>
|
||||
<%= event.draft ? "Drafted release" : event.prerelease ? "Pre-released" : "Released" %>
|
||||
<div class="bold"><%= event.name %></div> of <div class="repo"><%= repo %></div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (type === "star") { %>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path></svg>
|
||||
Starred <div class="repo"><%= repo %></div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (type === "member") { %>
|
||||
<div class="field">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M10.5 5a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm.061 3.073a4 4 0 10-5.123 0 6.004 6.004 0 00-3.431 5.142.75.75 0 001.498.07 4.5 4.5 0 018.99 0 .75.75 0 101.498-.07 6.005 6.005 0 00-3.432-5.142z"></path></svg>
|
||||
Added <%= event.user %> as collaborator in <div class="repo"><%= repo %></div>
|
||||
</div>
|
||||
<% } %>
|
||||
</section>
|
||||
</div>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
<% } %>
|
||||
|
||||
<% if (base.metadata) { %>
|
||||
<footer>
|
||||
<span>These metrics <%= !computed.token.scopes.includes("repo") ? "does not include all" : "includes" %> private contributions<% if ((config.timezone?.name)&&(!config.timezone?.error)) { %>, timezone <%= config.timezone.name %><% } %></span>
|
||||
|
||||
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 100 KiB |
@@ -311,6 +311,7 @@
|
||||
|
||||
.tweet .mention, .tweet .link, .tweet .hashtag {
|
||||
color: #0366d6;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.tweet .date {
|
||||
@@ -428,6 +429,79 @@
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
/* Activity */
|
||||
.activity {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.activity .field {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 450px;
|
||||
white-space: nowrap;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.activity .repo, .activity .issue, .activity .commit .sha {
|
||||
color: #58a6ff;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.activity .code {
|
||||
background-color: #F3F4F4;
|
||||
padding: 1px 5px;
|
||||
font-size: 80%;
|
||||
border-radius: 6px;
|
||||
color: #24294E;
|
||||
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;
|
||||
margin: 0 4px -3px;
|
||||
}
|
||||
|
||||
.activity .bold {
|
||||
font-weight: 600;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.activity .details {
|
||||
padding-left: 42px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 13px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.activity .details > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.activity .commit .sha {
|
||||
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;
|
||||
}
|
||||
|
||||
.activity .commit .message {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 360px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.activity .details .comment {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
width: 420px;
|
||||
margin-top: 6px;
|
||||
border-left: 3px solid #777777B2;
|
||||
padding-left: 6px;
|
||||
max-height: 38px;
|
||||
/* May not work in all browsers */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
/* Fade animation */
|
||||
.af {
|
||||
opacity: 0;
|
||||
|
||||
@@ -236,8 +236,15 @@
|
||||
plugin_habits_from:5,
|
||||
plugin_habits_charts:true,
|
||||
}, {skip:["terminal", "repository"]}],
|
||||
["Gists plugin (default)", {
|
||||
plugin_gists:true,
|
||||
["Activity plugin (default)", {
|
||||
plugin_activity:true,
|
||||
plugin_activity_limit:100,
|
||||
plugin_activity_days:14,
|
||||
plugin_activity_filter:"all",
|
||||
}, {skip:["terminal"]}],
|
||||
["Activity plugin (filtered)", {
|
||||
plugin_activity:true,
|
||||
plugin_activity_filter:"pr, issue",
|
||||
}, {skip:["terminal"]}],
|
||||
["Stars plugin (default)", {
|
||||
plugin_stars:true,
|
||||
@@ -245,6 +252,9 @@
|
||||
["Stargazers plugin (default)", {
|
||||
plugin_stargazers:true,
|
||||
}, {skip:["terminal"]}],
|
||||
["Gists plugin (default)", {
|
||||
plugin_gists:true,
|
||||
}, {skip:["terminal"]}],
|
||||
]
|
||||
|
||||
//Tests run
|
||||
|
||||
Reference in New Issue
Block a user