Skip to content
This repository was archived by the owner on May 11, 2025. It is now read-only.

Commit 2a268eb

Browse files
committed
add repo view
1 parent 79b1cde commit 2a268eb

5 files changed

Lines changed: 114 additions & 5 deletions

File tree

app/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
.idea
1+
.idea

app/error.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
$header = $dark ? "#fff" : "#434d58";
66
$background = $dark ? "#000" : "#fffefe";
77

8-
ob_start('compress_output');
8+
ob_start('compress');
99
?>
1010

1111
<svg width="540" viewBox="0 0 660 216" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="descId">

app/repo.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
include 'utils.php';
3+
4+
$dark = isset($_GET['theme']) && $_GET['theme'] === 'dark';
5+
$username = get('username', 'zmh-program');
6+
$repo = get('repo', 'code-statistic');
7+
8+
$stats = fetch("repo/$username/$repo");
9+
echo $stats->color;
10+
$header = $dark ? "#fff" : "#434d58";
11+
$background = $dark ? "#000" : "#fffefe";
12+
13+
ob_start('compress');
14+
?>
15+
<% const left = Math.ceil(langs.length / 2); const height = 215 + (left > 4 ? (left - 4) * 20 : 0) %>
16+
<svg width="540" viewBox="0 0 660 <%- height + 1 %>" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="descId">
17+
<title id="titleId"><%- repo %>'s Code Stats</title>
18+
<desc id="descId">Repository Code Statistics</desc>
19+
<style>.oct-icon{display:block;fill:#8b849e;}.repo-color{animation:fadeInAnimation 0.8s ease-in-out forwards;}.header{font:600 18px 'Segoe UI',Ubuntu,Sans-Serif;fill:#2f80ed;animation:fadeInAnimation 0.8s ease-in-out forwards;}@supports(appearance:auto){.header{font-size:15.5px;}}.stat{font:600 14px 'Segoe UI',Ubuntu,"Helvetica Neue",Sans-Serif;fill:<%- dark ? "#fff":"#434d58" %>;}@supports(appearance:auto){.stat{font-size:12px;}}.stagger{opacity:0;animation:fadeInAnimation 0.3s ease-in-out forwards;}.bold{font-weight:700}.icon{fill:#4c71f2;display:none;}@keyframes growWidthAnimation{from{width:0;}to{width:100%;}}.lang-name{font:400 11px "Segoe UI",Ubuntu,Sans-Serif;fill:<%- dark ? "#fff":"#434d58" %>;}.stagger{opacity:0;animation:fadeInAnimation 0.3s ease-in-out forwards;}#rect-mask rect{animation:fadeInAnimation 1s ease-in-out forwards;}@keyframes scaleInAnimation{from{transform:translate(-5px,5px) scale(0);}to{transform:translate(-5px,5px) scale(1);}}@keyframes rankAnimation{from{stroke-dashoffset:251.32741228718345;}to{stroke-dashoffset:125.45405959298056;}}@keyframes scaleInAnimation{from{transform:translate(-5px,5px) scale(0);}to{transform:translate(-5px,5px) scale(1);}}@keyframes fadeInAnimation{from{opacity:0;}to{opacity:1;}}</style>
20+
<rect data-testid="card-bg" x="0.5" y="0.5" rx="4.5" height="99%" stroke="#e4e2e2" width="659" fill="<%- dark ? "#000" : "#fffefe" %>" stroke-opacity="1"/>
21+
<g data-testid="card-title" transform="translate(40, 35)"><g transform="translate(0, 0)"><circle class="repo-color" cx="-10" cy="-5" r="5" fill="<%- color %>"/><text x="0" y="0" class="header" data-testid="header"><a href="https://github.com/<%- username %>/<%- repo %>/"><%- username %> / <%- repo %></a></text></g></g>
22+
<g data-testid="main-card-info" transform="translate(0, 55)"><svg x="0" y="0">
23+
<g transform="translate(0, 0)">
24+
<g class="stagger" style="animation-delay: 450ms" transform="translate(25, 0)">
25+
<svg xmlns="http://www.w3.org/2000/svg" data-testid="icon" class="icon" viewBox="0 0 16 16" version="1.1" 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"/></svg>
26+
<text class="stat bold" y="12.5">Stars:</text>
27+
<svg x="169.01" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="oct-icon"><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>
28+
<text class="stat bold" x="192.01" y="12.5" data-testid="stars"><%- stars %></text>
29+
</g>
30+
</g><g transform="translate(0, 25)">
31+
<g class="stagger" style="animation-delay: 600ms" transform="translate(25, 0)">
32+
<text class="stat bold" y="12.5">Forks:</text>
33+
<svg x="169.01" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="oct-icon"><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>
34+
<text class="stat bold" x="192.01" y="12.5" data-testid="forks"><%- forks %></text>
35+
</g>
36+
</g><g transform="translate(0, 50)">
37+
<g class="stagger" style="animation-delay: 750ms" transform="translate(25, 0)">
38+
<text class="stat bold" y="12.5">Watchers:</text>
39+
<svg class="oct-icon" x="169.01" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path fill-rule="evenodd" d="M1.679 7.932c.412-.621 1.242-1.75 2.366-2.717C5.175 4.242 6.527 3.5 8 3.5c1.473 0 2.824.742 3.955 1.715 1.124.967 1.954 2.096 2.366 2.717a.119.119 0 010 .136c-.412.621-1.242 1.75-2.366 2.717C10.825 11.758 9.473 12.5 8 12.5c-1.473 0-2.824-.742-3.955-1.715C2.92 9.818 2.09 8.69 1.679 8.068a.119.119 0 010-.136zM8 2c-1.981 0-3.67.992-4.933 2.078C1.797 5.169.88 6.423.43 7.1a1.619 1.619 0 000 1.798c.45.678 1.367 1.932 2.637 3.024C4.329 13.008 6.019 14 8 14c1.981 0 3.67-.992 4.933-2.078 1.27-1.091 2.187-2.345 2.637-3.023a1.619 1.619 0 000-1.798c-.45-.678-1.367-1.932-2.637-3.023C11.671 2.992 9.981 2 8 2zm0 8a2 2 0 100-4 2 2 0 000 4z"></path></svg>
40+
<text class="stat bold" x="192.01" y="12.5" data-testid="watchers"><%- watchers %></text>
41+
</g>
42+
</g><g transform="translate(0, 75)">
43+
<g class="stagger" style="animation-delay: 900ms" transform="translate(25, 0)">
44+
<text class="stat bold" y="12.5">Repo Size:</text>
45+
<svg class="oct-icon" x="170.01" height="16" width="14" viewBox="0 0 14 16" aria-hidden="true" version="1.1"><path d="M6,15 C2.69,15 0,14.1 0,13 L0,11 C0,10.83 0.09,10.66 0.21,10.5 C0.88,11.36 3.21,12 6,12 C8.79,12 11.12,11.36 11.79,10.5 C11.92,10.66 12,10.83 12,11 L12,13 C12,14.1 9.31,15 6,15 L6,15 Z M6,11 C2.69,11 0,10.1 0,9 L0,7 C0,6.89 0.04,6.79 0.09,6.69 L0.09,6.69 C0.12,6.63 0.16,6.56 0.21,6.5 C0.88,7.36 3.21,8 6,8 C8.79,8 11.12,7.36 11.79,6.5 C11.84,6.56 11.88,6.63 11.91,6.69 L11.91,6.69 C11.96,6.79 12,6.9 12,7 L12,9 C12,10.1 9.31,11 6,11 L6,11 Z M6,7 C2.69,7 0,6.1 0,5 L0,4 L0,3 C0,1.9 2.69,1 6,1 C9.31,1 12,1.9 12,3 L12,4 L12,5 C12,6.1 9.31,7 6,7 L6,7 Z M6,2 C3.79,2 2,2.45 2,3 C2,3.55 3.79,4 6,4 C8.21,4 10,3.55 10,3 C10,2.45 8.21,2 6,2 L6,2 Z" fill-rule="evenodd"></path></svg>
46+
<text class="stat bold" x="189.01" y="12.5" data-testid="size"><%- size %></text>
47+
</g>
48+
</g><g transform="translate(0, 100)">
49+
<g class="stagger" style="animation-delay: 1050ms" transform="translate(25, 0)">
50+
<text class="stat bold" y="12.5">License:</text>
51+
<svg aria-hidden="true" x="169.01" height="16" width="16" viewBox="0 0 16 16" version="1.1" class="oct-icon"><path fill-rule="evenodd" d="M8.75.75a.75.75 0 00-1.5 0V2h-.984c-.305 0-.604.08-.869.23l-1.288.737A.25.25 0 013.984 3H1.75a.75.75 0 000 1.5h.428L.066 9.192a.75.75 0 00.154.838l.53-.53-.53.53v.001l.002.002.002.002.006.006.016.015.045.04a3.514 3.514 0 00.686.45A4.492 4.492 0 003 11c.88 0 1.556-.22 2.023-.454a3.515 3.515 0 00.686-.45l.045-.04.016-.015.006-.006.002-.002.001-.002L5.25 9.5l.53.53a.75.75 0 00.154-.838L3.822 4.5h.162c.305 0 .604-.08.869-.23l1.289-.737a.25.25 0 01.124-.033h.984V13h-2.5a.75.75 0 000 1.5h6.5a.75.75 0 000-1.5h-2.5V3.5h.984a.25.25 0 01.124.033l1.29.736c.264.152.563.231.868.231h.162l-2.112 4.692a.75.75 0 00.154.838l.53-.53-.53.53v.001l.002.002.002.002.006.006.016.015.045.04a3.517 3.517 0 00.686.45A4.492 4.492 0 0013 11c.88 0 1.556-.22 2.023-.454a3.512 3.512 0 00.686-.45l.045-.04.01-.01.006-.005.006-.006.002-.002.001-.002-.529-.531.53.53a.75.75 0 00.154-.838L13.823 4.5h.427a.75.75 0 000-1.5h-2.234a.25.25 0 01-.124-.033l-1.29-.736A1.75 1.75 0 009.735 2H8.75V.75zM1.695 9.227c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327l-1.305 2.9zm10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327l-1.305 2.9z"></path></svg>
52+
<text class="stat bold" x="189.01" y="12.5" data-testid="license"><%- license %></text>
53+
</g>
54+
</g>
55+
</svg></g>
56+
<line x1="290" y1="40" x2="290" y2="<%- height - 40 %>" stroke="#eeecec"></line>
57+
<g xmlns="http://www.w3.org/2000/svg" transform="translate(300, 55)" data-testid="main-card-progress">
58+
59+
<svg data-testid="lang-items" x="25">
60+
<mask id="rect-mask"><rect x="0" y="0" width="300" height="8" fill="white" rx="5"/></mask>
61+
<% langs.forEach(function(lang){ %>
62+
<rect mask="url(#rect-mask)" data-testid="lang-progress" x="<%- lang.cursor * 300 %>" y="0" width="<%- lang.ratio * 300 %>" height="8" fill="<%- lang.color %>"/>
63+
<% }); %>
64+
<g transform="translate(0, 25)">
65+
<g transform="translate(0, 0)">
66+
<% langs.splice(0, left).forEach(function (lang, idx) { %>
67+
<g transform="translate(0, <%- idx * 25 %>)">
68+
<g class="stagger" style="animation-delay: <%- 450 + (idx * 150) %>ms">
69+
<circle cx="5" cy="6" r="5" fill="<%- lang.color %>"/>
70+
<text data-testid="lang-name" x="15" y="10" class="lang-name"><%- lang.text %></text>
71+
</g>
72+
</g>
73+
<% });%>
74+
</g>
75+
<g transform="translate(150, 0)">
76+
<% langs.splice(0, left).forEach(function (lang, idx) { %>
77+
<g transform="translate(0, <%- idx * 25 %>)">
78+
<g class="stagger" style="animation-delay: <%- 450 + (idx * 150) %>ms">
79+
<circle cx="5" cy="6" r="5" fill="<%- lang.color %>"/>
80+
<text data-testid="lang-name" x="15" y="10" class="lang-name"><%- lang.text %></text>
81+
</g>
82+
</g>
83+
<% });%>
84+
</g>
85+
</g>
86+
</svg>
87+
</g>
88+
</svg>

app/utils.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,29 @@
11
<?php
2+
header('Content-Type: image/svg+xml');
3+
header('Cache-Control: no-cache');
24

3-
function compress_output($buffer)
5+
function compress($buffer)
46
{
57
$search = array('/\>[^\S ]+/s', '/[^\S ]+\</s', '/(\s)+/s', '/> </s');
68
$replace = array('>', '<', '\\1', '><');
79
return preg_replace($search, $replace, $buffer);
810
}
11+
12+
function fetch($uri)
13+
{
14+
$opts = array('http' =>
15+
array(
16+
'method' => 'GET',
17+
'header' => 'Content-type: application/json'
18+
)
19+
);
20+
21+
$context = stream_context_create($opts);
22+
$response = file_get_contents("http://localhost:8080/api/" . $uri, false, $context);
23+
return json_decode($response);
24+
}
25+
26+
function get($param, $default = null)
27+
{
28+
return isset($_GET[$param]) ? $_GET[$param] : $default;
29+
}

server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
func RunServer() {
99
app := iris.Default()
1010
{
11-
app.Get("/user/{username:string}", CachedHandler(UserAPI))
12-
app.Get("/repo/{username:string}/{repo:string}", CachedHandler(RepoAPI))
11+
app.Get("/api/user/{username:string}", CachedHandler(UserAPI))
12+
app.Get("/api/repo/{username:string}/{repo:string}", CachedHandler(RepoAPI))
1313
}
1414
app.Listen(fmt.Sprintf(":%d", conf.Server.Port))
1515
}

0 commit comments

Comments
 (0)