新增 gitee 配置界面

This commit is contained in:
巴拉迪维 2022-04-13 19:20:52 +08:00
parent 54ddcf424b
commit 7b4408ff6a
25 changed files with 462 additions and 191 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
.DS_Store
docker/container-data
!docker/container-data/.keep
!docker/container-data/.keep
.vscode

36
air.toml Normal file
View File

@ -0,0 +1,36 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
bin = "./tmp/main"
cmd = "go build -o ./tmp/main ."
delay = 1000
exclude_dir = ["tmp", "vendor", "testdata","docker"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html","css","js"]
kill_delay = "0s"
log = "build-errors.log"
send_interrupt = false
stop_on_error = true
[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"
[log]
time = false
[misc]
clean_on_exit = true
[screen]
clear_on_rebuild = false

7
assets/admin.css Normal file
View File

@ -0,0 +1,7 @@
#admin-left-menu {
max-width: 200px;
}
#admin-right-content {
padding-left: 200px;
}

53
assets/admin.js Normal file
View File

@ -0,0 +1,53 @@
$(document).ready(function() {
$('#form-gitee-authorize').form({
fields: {
client_id: {
rules: [{
type:'empty',
prompt:'Client ID 尚未填写'
}]
},
client_secret: {
rules: [{
type:'empty',
prompt:'Client Secret 尚未填写'
}]
},
redirect_url: {
rules: [{
type:'empty',
prompt:'应用回调地址尚未填写'
}]
}
}
});
$('#btn-gitee-authorize').click(function(){
authForm = $('#form-gitee-authorize');
authForm.form('validate form');
if(authForm.form('is valid')) {
clientID = authForm.form('get value', 'client_id'),
clientSecret = authForm.form('get value', 'client_secret'),
redirectUrl = authForm.form('get value', 'redirect_url'),
scopes = authForm.form('get value', 'scopes'),
url = `https://gitee.com/oauth/authorize?client_id=`+clientID+`&redirect_uri=`+redirectUrl+`&response_type=code&scope=`+scopes
window.open(url);
}//end of if
});
$('#btn-gitee-token').click(function(){
authForm = $('#form-gitee-authorize');
authForm.form('add rule','code',{
rules: [{
type: 'empty',
prompt: '授权 Code 尚未填写'
}]
});
authForm.form('validate form');
if(authForm.form('is valid')) {
//TODO: go ajax
alert('go ajax');
}
});
});

BIN
assets/imgs/scopes.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

25
controller/admin_c.go Normal file
View File

@ -0,0 +1,25 @@
// Copyright (c) [2022] [巴拉迪维 BaratSemet]
// [ohUrlShortener] is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
package controller
import (
"net/http"
"github.com/gin-gonic/gin"
)
// Dashbaord page controller
//
// Display dashbaord page html
func DashboardPage(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "dashboard.html", gin.H{
"title": "仪表盘 - RepoStats",
"current_url": ctx.Request.URL.Path,
})
}

25
controller/gitee_c.go Normal file
View File

@ -0,0 +1,25 @@
// Copyright (c) [2022] [巴拉迪维 BaratSemet]
// [ohUrlShortener] is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
package controller
import (
"net/http"
"github.com/gin-gonic/gin"
)
// Gitee page controller
//
// Display gitee config page html
func GiteePage(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "gitee.html", gin.H{
"title": "Gitee 配置 - RepoStats",
"current_url": ctx.Request.URL.Path,
})
}

15
controller/github_c.go Normal file
View File

@ -0,0 +1,15 @@
// Copyright (c) [2022] [巴拉迪维 BaratSemet]
// [ohUrlShortener] is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
package controller
import "github.com/gin-gonic/gin"
func GithubPage(ctx *gin.Context) {
}

15
controller/grafana_c.go Normal file
View File

@ -0,0 +1,15 @@
// Copyright (c) [2022] [巴拉迪维 BaratSemet]
// [ohUrlShortener] is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
package controller
import "github.com/gin-gonic/gin"
func GrafanaPage(ctx *gin.Context) {
}

32
controller/login_c.go Normal file
View File

@ -0,0 +1,32 @@
// Copyright (c) [2022] [巴拉迪维 BaratSemet]
// [ohUrlShortener] is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
package controller
import "github.com/gin-gonic/gin"
// Login page controller
//
// Display login page html
func Login(ctx *gin.Context) {
}
// Login action
//
// Ask for account and password to DO the login action
func DoLogin(ctx *gin.Context) {
}
// Logout action
//
// Clean cookies and redirect to login page
func DoLogout(ctx *gin.Context) {
}

15
controller/repos_c.go Normal file
View File

@ -0,0 +1,15 @@
// Copyright (c) [2022] [巴拉迪维 BaratSemet]
// [ohUrlShortener] is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
package controller
import "github.com/gin-gonic/gin"
func ReposPage(ctx *gin.Context) {
}

15
controller/schedule_c.go Normal file
View File

@ -0,0 +1,15 @@
// Copyright (c) [2022] [巴拉迪维 BaratSemet]
// [ohUrlShortener] is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
package controller
import "github.com/gin-gonic/gin"
func SchedulePage(ctx *gin.Context) {
}

View File

@ -11,7 +11,9 @@ services:
- TZ=PRC
- PGTZ=PRC
volumes:
- ../structure.sql:/docker-entrypoint-initdb.d/001.sql
- ../sql/db.sql:/docker-entrypoint-initdb.d/001.sql
- ../sql/gitee.sql:/docker-entrypoint-initdb.d/002.sql
- ../sql/roles.sql:/docker-entrypoint-initdb.d/003.sql
- ../docker/container-data/postgresql:/var/lib/postgresql/data
ports:
- ${PG_LOCAL_PORT}:5432

View File

@ -14,8 +14,10 @@ import (
"fmt"
"html/template"
"io/fs"
"log"
"net/http"
"os"
"repostats/controller"
"repostats/storage"
"repostats/utils"
@ -52,6 +54,13 @@ func main() {
gin.SetMode(gin.ReleaseMode)
router := gin.Default()
initRouter(router)
log.Println(fmt.Sprintf("[RepoStats v%s build:%s] starts at http://localhost:%d", Version, Build, utils.RepoStatsConfig.AdminPort))
router.Run(fmt.Sprintf("localhost:%d", utils.RepoStatsConfig.AdminPort))
}
func initRouter(router *gin.Engine) {
sub, err := fs.Sub(FS, "assets")
utils.ExitOnError(err)
@ -60,7 +69,18 @@ func main() {
tmpl, err := template.New("").ParseFS(FS, "templates/*.html")
utils.ExitOnError(err)
router.SetHTMLTemplate(tmpl)
router.GET("/login", controller.Login)
router.POST("/login", controller.DoLogin)
router.Run(":9100")
admin := router.Group("/admin") //TODO: auth handler needed
admin.POST("/logout", controller.DoLogout)
admin.GET("/", func(ctx *gin.Context) { ctx.Redirect(http.StatusFound, "/admin/dashboard") })
admin.GET("/dashboard", controller.DashboardPage)
admin.GET("/schedule", controller.SchedulePage)
admin.GET("/gitee", controller.GiteePage)
admin.GET("/github", controller.GithubPage)
admin.GET("/repos", controller.ReposPage)
admin.GET("/grafana", controller.GrafanaPage)
router.SetHTMLTemplate(tmpl)
}

View File

@ -1,6 +1,6 @@
[repostats]
debug = false
admin_port = 9100
admin_port = 9103
[postgres]

3
sql/db.sql Normal file
View File

@ -0,0 +1,3 @@
-- Database Structure For RepoStats
CREATE DATABASE repostats ENCODING 'UTF8';

103
sql/gitee.sql Normal file
View File

@ -0,0 +1,103 @@
-- Connect to database repostats
\c repostats
-- Create schema and define views
CREATE SCHEMA gitee;
-- Repos
CREATE TABLE gitee.repos (
id BIGINT NOT NULL,
full_name VARCHAR(255) NOT NULL,
human_name VARCHAR(255) NOT NULL,
owner_id BIGINT NOT NULL,
html_url VARCHAR(500) NOT NULL,
ssh_url VARCHAR(500) NOT NULL,
recommend BOOLEAN NOT NULL DEFAULT false,
gvp BOOLEAN NOT NULL DEFAULT false,
homepage VARCHAR(500),
language VARCHAR(500),
forks_count BIGINT NOT NULL DEFAULT 0,
stargazers_count BIGINT NOT NULL DEFAULT 0,
watchers_count BIGINT NOT NULL DEFAULT 0,
open_issues_count BIGINT NOT NULL DEFAULT 0,
license VARCHAR(500),
project_creator VARCHAR(500),
pushed_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE
);
ALTER TABLE gitee.repos ADD CONSTRAINT uni_gitee_repos_id UNIQUE (id);
-- Users
CREATE TABLE gitee.users (
id BIGINT NOT NULL,
login VARCHAR(100) NOT NULL,
"name" VARCHAR(255) NOT NULL,
html_url VARCHAR(255) NOT NULL,
"type" VARCHAR(50) NULL
);
ALTER TABLE gitee.users ADD CONSTRAINT uni_gitee_users_id UNIQUE (id);
-- Collaborators
CREATE TABLE gitee.collaborators (
"user_id" BIGINT NOT NULL,
repo_id BIGINT NOT NULL
);
ALTER TABLE gitee.collaborators ADD CONSTRAINT uni_gitee_rcs UNIQUE (user_id,repo_id);
-- Issues
CREATE TABLE gitee.issues (
id BIGINT NOT NULL,
repo_id BIGINT NOT NULL,
"user_id" BIGINT NOT NULL,
html_url VARCHAR(500) NOT NULL,
"number" VARCHAR(40) NOT NULL,
"state" VARCHAR(40) NOT NULL,
scheduled_time INT,
comments INT,
priority INT,
issue_type VARCHAR(40),
issue_state VARCHAR(40),
finished_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE
);
ALTER TABLE gitee.issues ADD CONSTRAINT uni_gitee_issue UNIQUE (id);
-- Pull requests
CREATE TABLE gitee.pullrequests (
id BIGINT NOT NULL,
repo_id BIGINT NOT NULL,
"user_id" BIGINT NOT NULL,
html_url VARCHAR(500) NOT NULL,
"number" VARCHAR(40) NOT NULL,
"state" VARCHAR(40) NOT NULL,
finished_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE,
closed_at TIMESTAMP WITH TIME ZONE,
merged_at TIMESTAMP WITH TIME ZONE,
mergeable BOOLEAN,
can_merge_check BOOLEAN
);
ALTER TABLE gitee.pullrequests ADD CONSTRAINT uni_gitee_prs UNIQUE (id);
-- Commits
CREATE TABLE gitee.commits (
sha VARCHAR(100) NOT NULL,
repo_id BIGINT NOT NULL,
author BIGINT NOT NULL,
html_url VARCHAR(500) NOT NULL,
commiter BIGINT NOT NULL,
commit_at TIMESTAMP WITH TIME ZONE
);
ALTER TABLE gitee.commits ADD CONSTRAINT uni_gitee_commits UNIQUE(sha,repo_id);
-- Stargazers
CREATE TABLE gitee.stargazers (
user_id BIGINT NOT NULL,
repo_id BIGINT NOT NULL,
star_at TIMESTAMP WITH TIME ZONE NOT NULL
);
ALTER TABLE gitee.stargazers ADD CONSTRAINT uni_gitee_stargazers UNIQUE(user_id,repo_id);

11
sql/roles.sql Normal file
View File

@ -0,0 +1,11 @@
-- Connect to database repostats
\c repostats
-- Create Roles & Grant Privileges for Grafana datasource
CREATE USER repostats_readonly WITH PASSWORD '1R_repoSt(ats987';
GRANT CONNECT ON DATABASE repostats TO repostats_readonly;
GRANT USAGE ON SCHEMA public TO repostats_readonly;
GRANT USAGE ON SCHEMA gitee TO repostats_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO repostats_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA gitee TO repostats_readonly;

View File

@ -1,184 +0,0 @@
-- Database Structure For RepoStats
CREATE DATABASE repostats ENCODING 'UTF8';
-- Connect to database repostats
\c repostats
CREATE TABLE public.gitee_repos ( id BIGINT NOT NULL,
full_name VARCHAR(255) NOT NULL,
human_name VARCHAR(255) NOT NULL,
owner_id BIGINT NOT NULL,
html_url VARCHAR(500) NOT NULL,
ssh_url VARCHAR(500) NOT NULL,
recommend BOOLEAN NOT NULL DEFAULT false,
gvp BOOLEAN NOT NULL DEFAULT false,
homepage VARCHAR(500),
language VARCHAR(500),
forks_count BIGINT NOT NULL DEFAULT 0,
stargazers_count BIGINT NOT NULL DEFAULT 0,
watchers_count BIGINT NOT NULL DEFAULT 0,
open_issues_count BIGINT NOT NULL DEFAULT 0,
has_issues BOOLEAN NOT NULL DEFAULT false,
has_wiki BOOLEAN NOT NULL DEFAULT false,
issue_comment BOOLEAN NOT NULL DEFAULT false,
can_comment BOOLEAN NOT NULL DEFAULT false,
pull_requests_enabled BOOLEAN NOT NULL DEFAULT false,
license VARCHAR(500),
project_creator VARCHAR(500),
pushed_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE
);
ALTER TABLE public.gitee_repos ADD CONSTRAINT uni_gitee_repos_id UNIQUE (id);
-- Users
CREATE TABLE public.gitee_users ( id BIGINT NOT NULL,
login VARCHAR(100) NOT NULL,
"name" VARCHAR(255) NOT NULL,
html_url VARCHAR(255) NOT NULL,
"type" VARCHAR(50) NULL
);
ALTER TABLE public.gitee_users ADD CONSTRAINT uni_gitee_users_id UNIQUE (id);
-- Collaborators
CREATE TABLE public.gitee_collaborators ( "user_id" BIGINT NOT NULL, repo_id BIGINT NOT NULL);
ALTER TABLE public.gitee_collaborators ADD CONSTRAINT uni_gitee_rcs UNIQUE (user_id,repo_id);
-- Issues
CREATE TABLE public.gitee_issues ( id BIGINT NOT NULL,
repo_id BIGINT NOT NULL,
"user_id" BIGINT NOT NULL,
html_url VARCHAR(500) NOT NULL,
"number" VARCHAR(40) NOT NULL,
"state" VARCHAR(40) NOT NULL,
scheduled_time INT, comments INT, priority INT, issue_type VARCHAR(40),
issue_state VARCHAR(40),
finished_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE
);
ALTER TABLE public.gitee_issues ADD CONSTRAINT uni_gitee_issue UNIQUE (id);
-- Pull requests
CREATE TABLE public.gitee_pullrequests ( id BIGINT NOT NULL,
repo_id BIGINT NOT NULL,
"user_id" BIGINT NOT NULL,
html_url VARCHAR(500) NOT NULL,
"number" VARCHAR(40) NOT NULL,
"state" VARCHAR(40) NOT NULL,
finished_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE,
closed_at TIMESTAMP WITH TIME ZONE,
merged_at TIMESTAMP WITH TIME ZONE,
mergeable BOOLEAN, can_merge_check BOOLEAN
);
ALTER TABLE public.gitee_pullrequests ADD CONSTRAINT uni_gitee_prs UNIQUE (id);
-- Commits
CREATE TABLE public.gitee_commits ( sha VARCHAR(100) NOT NULL,
repo_id BIGINT NOT NULL,
author BIGINT NOT NULL,
html_url VARCHAR(500) NOT NULL,
commiter BIGINT NOT NULL,
commit_at TIMESTAMP WITH TIME ZONE
);
ALTER TABLE public.gitee_commits ADD CONSTRAINT uni_gitee_commits UNIQUE(sha);
-- Stargazers
CREATE TABLE public.gitee_stargazers ( user_id BIGINT NOT NULL,
repo_id BIGINT NOT NULL,
star_at TIMESTAMP WITH TIME ZONE NOT NULL
);
ALTER TABLE public.gitee_stargazers ADD CONSTRAINT uni_gitee_stargazers UNIQUE(user_id,repo_id);
-- Create schema and define views for Grafana
CREATE SCHEMA gitee_state;
-- Issue Type Detail
CREATE VIEW gitee_state.issue_type_detail AS
SELECT i.ISSUE_TYPE AS issue_type,
count(i.ID) AS total_count,
NOW() AS time
FROM public.GITEE_ISSUES i
GROUP BY i.ISSUE_TYPE;
-- Issue State Detail
CREATE VIEW gitee_state.issue_state_detail AS
SELECT i.STATE AS issue_state,
count(i.ID) AS total_count,
NOW() AS time
FROM public.GITEE_ISSUES i
GROUP BY i.STATE;
-- Repo Detail
CREATE VIEW gitee_state.repo_detail AS
SELECT
r.id AS repo_id,
r.human_name AS repo_name,
r.stargazers_count AS star_count,
r.forks_count AS fork_count,
r.watchers_count AS watch_count,
NOW() AS time
FROM gitee_repos r;
-- Issue by date
CREATE VIEW gitee_state.issue_by_date AS
SELECT date(i.CREATED_AT) AS time,
count(i.ID) AS issue_count
FROM public.GITEE_ISSUES i
GROUP BY date(i.CREATED_AT)
ORDER BY time DESC;
-- Commit by date
CREATE VIEW gitee_state.commit_by_date AS
SELECT date(c.COMMIT_AT) AS time,
count(c.SHA) AS commit_count
FROM public.GITEE_COMMITS c
GROUP BY date(c.COMMIT_AT)
ORDER BY time DESC;
-- PR by date
CREATE VIEW gitee_state.pr_by_date AS
SELECT date(pr.CREATED_AT) AS time,
count(pr.ID) AS pr_count
FROM public.GITEE_PULLREQUESTS pr
GROUP BY date(pr.CREATED_AT)
ORDER BY time DESC;
-- Star by date
CREATE VIEW gitee_state.start_by_date AS
SELECT date(star.STAR_AT) AS time,
count(star.USER_ID) AS star_count
FROM public.GITEE_STARGAZERS star
GROUP BY date(star.STAR_AT)
ORDER BY time DESC;
-- Star DEtail
CREATE OR REPLACE VIEW gitee_state.star_detail
AS SELECT u.id AS user_id,
u.name AS user_name,
r.id AS repo_id,
r.human_name,
s.star_at AS "time"
FROM gitee_repos r,
gitee_users u,
gitee_stargazers s
WHERE s.user_id = u.id AND s.repo_id = r.id;
-- Create Roles & Grant Privileges
CREATE USER repostats_admin WITH PASSWORD '_Rep0stats^123';
CREATE USER repostats_readonly WITH PASSWORD '1R_repoSt(ats987';
ALTER DATABASE repostats OWNER TO repostats_admin;
ALTER SCHEMA public OWNER TO repostats_admin;
ALTER SCHEMA gitee_state OWNER TO repostats_admin;
GRANT ALL PRIVILEGES ON DATABASE repostats TO repostats_admin;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO repostats_admin;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA gitee_state TO repostats_admin;
GRANT CONNECT ON DATABASE repostats TO repostats_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO repostats_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA gitee_state TO repostats_readonly;

8
templates/dashboard.html Normal file
View File

@ -0,0 +1,8 @@
{{define "dashboard.html" -}}
{{template "header.html" .}}
{{template "admin-left-menu.html" .}}
<div id="admin-right-content" class="ui basic segment">
hello world
</div>
{{template "footer.html" .}}
{{end -}}

View File

@ -1,4 +1,5 @@
{{define "footer.html" -}}
</div><!--end of pusher-->
</body>
</html>
{{end -}}

51
templates/gitee.html Normal file
View File

@ -0,0 +1,51 @@
{{define "gitee.html" -}}
{{template "header.html" .}}
{{template "admin-left-menu.html" .}}
<div id="admin-right-content">
<div class="ui basic segment">
<h3 class="ui header">Gitee 配置</h3>
<div class="ui content">
<p>RepoStats 使用 Oauth 授权码模式访问 Gitee 授权许可的接口并获取相关数据。</p>
<p>1. 请根据 <a target="_blank" href="https://gitee.com/api/v5/oauth_doc#/">《Gitee Oauth 文档》</a> 指南新建第三方应用。 </p>
<p>2. 创建第三方应用成功后,请将对应的信息填入下列表格中。</p>
<p>3. 首先点击「应用授权」完成操作。再获取 code 之后,再点击「获取 Token」Oauth 过程。</p>
<div class="ui two column stackable grid">
<div class="eight wide column">
<h3>应用信息</h3>
<form id="form-gitee-authorize" class="ui form">
<div class="ui field">
<label>Client ID</label>
<input type="text" name="client_id" placeholder="Client ID">
</div>
<div class="field">
<label>Client Secret</label>
<input type="text" name="client_secret" placeholder="Client Secret">
</div>
<div class="field">
<label>应用回调地址</label>
<input type="text" name="redirect_url" placeholder="应用回调地址">
</div>
<div class="field">
<label>权限</label>
<input type="text" name="scopes" readonly value="user_info projects pull_requests issues emails">
</div>
<div class="field">
<label>授权 Code</label>
<input type="text" name="code" placeholder="获取授权完成后,转向到回调地址 url 中携带的 code 值">
</div>
<div class="ui error message"></div>
<button id="btn-gitee-authorize" class="ui button" type="button">应用授权</button>
<button id="btn-gitee-token" class="ui button" type="button">获取 Token</button>
</form>
</div>
<div class="eight wide column">
<h3>注意事项</h3>
<p>RepoStats 当前版本需要获取至少以下权限才能保证各项功能正常。</p>
<img src="/assets/imgs/scopes.jpg" />
</div>
</div>
</div><!--end of ui content-->
</div> <!--end of basic segment-->
</div><!--end of admin-right-content-->
{{template "footer.html" .}}
{{end -}}

View File

@ -10,9 +10,12 @@
<meta name="description" content="代码仓库统计数据可视化" />
<title>{{.title}}</title>
<link rel="stylesheet" type="text/css" href="/assets/semantic.min.css">
<link rel="stylesheet" type="text/css" href="/assets/admin.css">
<link rel="shortcut icon" type="image/x-icon" href="/assets/favicon.ico" title="RepoStats">
<script src="/assets/jquery.min.js" type="text/javascript"></script>
<script src="/assets/semantic.min.js" type="text/javascript"></script>
<script src="/assets/admin.js" type="text/javascript"></script>
</head>
<body>
<div class="push">
{{end -}}

View File

@ -1,2 +0,0 @@
{{define "index.html" -}}
{{end -}}

16
templates/menu.html Normal file
View File

@ -0,0 +1,16 @@
{{define "admin-left-menu.html" -}}
<div id="admin-left-menu" class="ui inverted vertical left fixed menu">
<div class="item">
<div class="ui inverted header">RepoStats</div>
<div class="menu">
<a class="{{if eq .current_url "/admin/dashboard"}}active {{end}}item" target="_self" href="/admin/dashboard">仪表盘</a>
<a class="{{if eq .current_url "/admin/gitee"}}active {{end}}item" target="_self" href="/admin/gitee">Gitee 配置</a>
<a class="{{if eq .current_url "/admin/github"}}active {{end}}item" target="_self" href="/admin/github">Github 配置</a>
<a class="{{if eq .current_url "/admin/grafana"}}active {{end}}item" target="_self" href="/admin/grafana">Grafana 配置</a>
<a class="{{if eq .current_url "/admin/repos"}}active {{end}}item" target="_self" href="/admin/repos">代码仓库列表</a>
<a class="{{if eq .current_url "/admin/schedule"}}active {{end}}item" target="_self" href="/admin/schedule">计划任务配置</a>
</div>
</div>
<a class="item" target="_self" href="javascript:sign_out_config()">安全退出</a>
</div><!--end of left-menu-->
{{end -}}