mirror of
https://github.com/gogs/gogs.git
synced 2026-02-28 09:10:57 +01:00
Compare commits
97 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d37da1f392 | ||
|
|
cefc50b278 | ||
|
|
b4877b1e06 | ||
|
|
eea2e05da6 | ||
|
|
2b1e955f91 | ||
|
|
63cdee84d1 | ||
|
|
6a6a7512c2 | ||
|
|
6b30b20765 | ||
|
|
126228d146 | ||
|
|
74dfe439c2 | ||
|
|
1d4a5b1825 | ||
|
|
987dcc5372 | ||
|
|
9b6c835715 | ||
|
|
902b578465 | ||
|
|
3d14e73fd8 | ||
|
|
9bcc3c1ea3 | ||
|
|
6a66e5fc98 | ||
|
|
c0b0ce7b1a | ||
|
|
dc0c0dc06b | ||
|
|
2158e6fc43 | ||
|
|
ee686f6231 | ||
|
|
481be9b5c9 | ||
|
|
9330c943cd | ||
|
|
915bf1d2e3 | ||
|
|
f455125d4d | ||
|
|
df339ad8b0 | ||
|
|
2c653141a8 | ||
|
|
fc56f42dc3 | ||
|
|
0bd4d15e47 | ||
|
|
e04c97b9fa | ||
|
|
f04d773f4f | ||
|
|
4325b01a58 | ||
|
|
052519a7d7 | ||
|
|
e347736c9e | ||
|
|
56006da34b | ||
|
|
efea642d6c | ||
|
|
81d7359fdd | ||
|
|
9a0902523b | ||
|
|
d2808e38fe | ||
|
|
7a9777ae36 | ||
|
|
62533560ce | ||
|
|
dc7e74ebb1 | ||
|
|
9a27e1b90c | ||
|
|
ff5f14431e | ||
|
|
ab9411be2a | ||
|
|
114e6790f8 | ||
|
|
ec5f881384 | ||
|
|
9ab96172fc | ||
|
|
e06558e208 | ||
|
|
54fd4cc5fb | ||
|
|
3deddabfd8 | ||
|
|
0cbf56855a | ||
|
|
917d334ebd | ||
|
|
bb1fbe4e70 | ||
|
|
cceb3364bb | ||
|
|
d370effca5 | ||
|
|
29ed7872f8 | ||
|
|
5dc3dd1704 | ||
|
|
134d8e7681 | ||
|
|
c9b65f0fdc | ||
|
|
951037c0ae | ||
|
|
7046df6028 | ||
|
|
1db3ae6601 | ||
|
|
612d0d6d25 | ||
|
|
18de67380c | ||
|
|
1a901433e2 | ||
|
|
e030109b5a | ||
|
|
35d49d3b34 | ||
|
|
ca5678da32 | ||
|
|
4d3138cd10 | ||
|
|
942284648e | ||
|
|
4f03b81ec7 | ||
|
|
b4970b3cc3 | ||
|
|
85c58eba90 | ||
|
|
84a43b38cf | ||
|
|
7c80eba77f | ||
|
|
9c12ed3b6e | ||
|
|
7b1c10ea7e | ||
|
|
679af4ddea | ||
|
|
f8ae161c74 | ||
|
|
1d57f0d64f | ||
|
|
1559bd58e7 | ||
|
|
6a664e88c7 | ||
|
|
0f438ef0b3 | ||
|
|
a6c7716742 | ||
|
|
1c3754bcec | ||
|
|
ee645af107 | ||
|
|
3e7695ae91 | ||
|
|
2268d28189 | ||
|
|
eee6e4206a | ||
|
|
1bfebdcdf6 | ||
|
|
588a0db218 | ||
|
|
5edc2f6d6c | ||
|
|
4dd731cb53 | ||
|
|
ae0fadeb0e | ||
|
|
2717ada14c | ||
|
|
e1c04f043b |
@@ -13,7 +13,7 @@ watch_dirs = [
|
||||
watch_exts = [".go"]
|
||||
build_delay = 1500
|
||||
cmds = [
|
||||
["go", "install"], # sqlite redis memcache cert pam tidb
|
||||
["go", "build"],
|
||||
["go", "install", "-race"], # sqlite redis memcache cert pam tidb
|
||||
["go", "build", "-race"],
|
||||
["./gogs", "web"]
|
||||
]
|
||||
24
.gopmfile
24
.gopmfile
@@ -3,42 +3,42 @@ path = github.com/gogits/gogs
|
||||
|
||||
[deps]
|
||||
github.com/bradfitz/gomemcache = commit:72a68649ba
|
||||
github.com/codegangsta/cli = commit:70e3fa5
|
||||
github.com/codegangsta/cli = commit:0302d39
|
||||
github.com/go-macaron/binding = commit:864a5ce
|
||||
github.com/go-macaron/cache = commit:5617353
|
||||
github.com/go-macaron/captcha = commit:875ff77
|
||||
github.com/go-macaron/csrf = commit:75c2b04
|
||||
github.com/go-macaron/csrf = commit:3372b25
|
||||
github.com/go-macaron/gzip = commit:4938e9b
|
||||
github.com/go-macaron/i18n = commit:5e728b6
|
||||
github.com/go-macaron/inject = commit:c5ab7bf
|
||||
github.com/go-macaron/session = commit:66031fc
|
||||
github.com/go-macaron/toolbox = commit:ddfcf96
|
||||
github.com/go-sql-driver/mysql = commit:527bcd55aa
|
||||
github.com/go-macaron/toolbox = commit:ab30a81
|
||||
github.com/go-sql-driver/mysql = commit:d512f20
|
||||
github.com/go-xorm/core = commit:3e10003353
|
||||
github.com/go-xorm/xorm = commit:8bf4405
|
||||
github.com/go-xorm/xorm = commit:c643188
|
||||
github.com/gogits/chardet = commit:2404f77725
|
||||
github.com/gogits/go-gogs-client = commit:1030bf8
|
||||
github.com/gogits/go-gogs-client = commit:7c02c95
|
||||
github.com/issue9/identicon = commit:5a61672
|
||||
github.com/klauspost/compress = commit:0449b1c
|
||||
github.com/klauspost/compress = commit:bbfa9dc
|
||||
github.com/klauspost/cpuid = commit:8d9fe96
|
||||
github.com/klauspost/crc32 = commit:f8d2e12
|
||||
github.com/klauspost/crc32 = commit:3e5c38b
|
||||
github.com/lib/pq = commit:83c4f41
|
||||
github.com/mattn/go-sqlite3 = commit:5651a9d
|
||||
github.com/mcuadros/go-version = commit:d52711f
|
||||
github.com/microcosm-cc/bluemonday = commit:4ac6f27
|
||||
github.com/mssola/user_agent = commit:783ec61
|
||||
github.com/msteinert/pam = commit:6534f23b39
|
||||
github.com/nfnt/resize = commit:dc93e1b98c
|
||||
github.com/russross/blackfriday = commit:510be64
|
||||
github.com/russross/blackfriday = commit:300106c
|
||||
github.com/shurcooL/sanitized_anchor_name = commit:10ef21a
|
||||
github.com/Unknwon/cae = commit:7f5e046
|
||||
github.com/Unknwon/com = commit:28b053d
|
||||
github.com/Unknwon/i18n = commit:7457d88830
|
||||
github.com/Unknwon/paginater = commit:7748a72
|
||||
golang.org/x/net =
|
||||
golang.org/x/text =
|
||||
golang.org/x/text =
|
||||
golang.org/x/crypto =
|
||||
gopkg.in/gomail.v2 = commit:df6fc79
|
||||
gopkg.in/ini.v1 = commit:060d7da
|
||||
gopkg.in/ini.v1 = commit:2e44421
|
||||
gopkg.in/macaron.v1 = commit:1c6dd87
|
||||
gopkg.in/redis.v2 = commit:e617904962
|
||||
|
||||
|
||||
@@ -19,4 +19,4 @@ RUN ./docker/build.sh
|
||||
VOLUME ["/data"]
|
||||
EXPOSE 22 3000
|
||||
ENTRYPOINT ["docker/start.sh"]
|
||||
CMD ["/usr/bin/s6-svscan", "/app/gogs/docker/s6/"]
|
||||
CMD ["/bin/s6-svscan", "/app/gogs/docker/s6/"]
|
||||
|
||||
@@ -5,7 +5,7 @@ Gogs - Go Git Service [
|
||||
|
||||
##### Current version: 0.7.6 Beta
|
||||
##### Current version: 0.7.19 Beta
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@@ -29,7 +29,8 @@ Gogs - Go Git Service [ has been reset in **Jan 28, 2015** and will reset multiple times after. Please do **NOT** put your important data on the site.
|
||||
- The demo site [try.gogs.io](https://try.gogs.io) is running under `develop` branch.
|
||||
- :bangbang:<span style="color: red">You **MUST** read [CONTRIBUTING.md](CONTRIBUTING.md) before you start filing an issue or making a Pull Request, and **MUST** discuss with us on [Gitter](https://gitter.im/gogits/gogs) for UI changes and feature Pull Requests, otherwise it's high possibilities that we are not going to merge it.</span>:bangbang:
|
||||
- :bangbang:<span style="color: red">You **MUST** read [CONTRIBUTING.md](CONTRIBUTING.md) before you start filing an issue or making a Pull Request, and **MUST** discuss with us on [Gitter](https://gitter.im/gogits/gogs) for UI changes, otherwise it's high possibilities that we are not going to merge it.</span>:bangbang:
|
||||
- Please [start discussion](http://forum.gogs.io/category/2/general-discussion) or [ask a question](http://forum.gogs.io/category/4/getting-help) on [the forum](http://forum.gogs.io/). GitHub issue tracker only keeps **bugs** and **feature requests**, all other topics will be closed without reason.
|
||||
- If you think there are vulnerabilities in the project, please talk privately to **u@gogs.io**. Thanks!
|
||||
- If you're interested in using APIs, we have experimental support with [documentation](https://github.com/gogits/go-gogs-client/wiki).
|
||||
- If your team/company is using Gogs and would like to put your logo on [our website](http://gogs.io), contact us by any means.
|
||||
|
||||
12
cmd/cert.go
12
cmd/cert.go
@@ -32,12 +32,12 @@ var CmdCert = cli.Command{
|
||||
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
|
||||
Action: runCert,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{"host", "", "Comma-separated hostnames and IPs to generate a certificate for", ""},
|
||||
cli.StringFlag{"ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521", ""},
|
||||
cli.IntFlag{"rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set", ""},
|
||||
cli.StringFlag{"start-date", "", "Creation date formatted as Jan 1 15:04:05 2011", ""},
|
||||
cli.DurationFlag{"duration", 365 * 24 * time.Hour, "Duration that certificate is valid for", ""},
|
||||
cli.BoolFlag{"ca", "whether this cert should be its own Certificate Authority", ""},
|
||||
stringFlag("host", "", "Comma-separated hostnames and IPs to generate a certificate for"),
|
||||
stringFlag("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521"),
|
||||
intFlag("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set"),
|
||||
stringFlag("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011"),
|
||||
durationFlag("duration", 365*24*time.Hour, "Duration that certificate is valid for"),
|
||||
boolFlag("ca", "whether this cert should be its own Certificate Authority"),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
42
cmd/cmd.go
Normal file
42
cmd/cmd.go
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
)
|
||||
|
||||
func stringFlag(name, value, usage string) cli.StringFlag {
|
||||
return cli.StringFlag{
|
||||
Name: name,
|
||||
Value: value,
|
||||
Usage: usage,
|
||||
}
|
||||
}
|
||||
|
||||
func boolFlag(name, usage string) cli.BoolFlag {
|
||||
return cli.BoolFlag{
|
||||
Name: name,
|
||||
Usage: usage,
|
||||
}
|
||||
}
|
||||
|
||||
func intFlag(name string, value int, usage string) cli.IntFlag {
|
||||
return cli.IntFlag{
|
||||
Name: name,
|
||||
Value: value,
|
||||
Usage: usage,
|
||||
}
|
||||
}
|
||||
|
||||
func durationFlag(name string, value time.Duration, usage string) cli.DurationFlag {
|
||||
return cli.DurationFlag{
|
||||
Name: name,
|
||||
Value: value,
|
||||
Usage: usage,
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,8 @@ var CmdDump = cli.Command{
|
||||
It can be used for backup and capture Gogs server image to send to maintainer`,
|
||||
Action: runDump,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
|
||||
cli.BoolFlag{"verbose, v", "show process details", ""},
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
boolFlag("verbose, v", "show process details"),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ var CmdServ = cli.Command{
|
||||
Description: `Serv provide access auth for repositories`,
|
||||
Action: runServ,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ var CmdUpdate = cli.Command{
|
||||
Description: `Update get pushed info and insert into database`,
|
||||
Action: runUpdate,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
37
cmd/web.go
37
cmd/web.go
@@ -7,7 +7,7 @@ package cmd
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"html/template"
|
||||
gotmpl "html/template"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/fcgi"
|
||||
@@ -35,11 +35,11 @@ import (
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
"github.com/gogits/gogs/modules/auth/apiv1"
|
||||
"github.com/gogits/gogs/modules/avatar"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/bindata"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
"github.com/gogits/gogs/modules/template"
|
||||
"github.com/gogits/gogs/routers"
|
||||
"github.com/gogits/gogs/routers/admin"
|
||||
"github.com/gogits/gogs/routers/api/v1"
|
||||
@@ -56,8 +56,8 @@ var CmdWeb = cli.Command{
|
||||
and it takes care of all the other things for you`,
|
||||
Action: runWeb,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{"port, p", "3000", "Temporary port number to prevent conflict", ""},
|
||||
cli.StringFlag{"config, c", "custom/conf/app.ini", "Custom configuration file path", ""},
|
||||
stringFlag("port, p", "3000", "Temporary port number to prevent conflict"),
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ func checkVersion() {
|
||||
{"github.com/go-macaron/csrf", csrf.Version, "0.0.3"},
|
||||
{"github.com/go-macaron/i18n", i18n.Version, "0.0.7"},
|
||||
{"github.com/go-macaron/session", session.Version, "0.1.6"},
|
||||
{"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"},
|
||||
{"gopkg.in/ini.v1", ini.Version, "1.3.4"},
|
||||
}
|
||||
for _, c := range checkers {
|
||||
@@ -124,7 +125,7 @@ func newMacaron() *macaron.Macaron {
|
||||
))
|
||||
m.Use(macaron.Renderer(macaron.RenderOptions{
|
||||
Directory: path.Join(setting.StaticRootPath, "templates"),
|
||||
Funcs: []template.FuncMap{base.TemplateFuncs},
|
||||
Funcs: []gotmpl.FuncMap{template.Funcs},
|
||||
IndentJSON: macaron.Env != macaron.PROD,
|
||||
}))
|
||||
|
||||
@@ -237,6 +238,13 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Patch("/hooks/:id:int", bind(api.EditHookOption{}), v1.EditRepoHook)
|
||||
m.Get("/raw/*", middleware.RepoRef(), v1.GetRepoRawFile)
|
||||
m.Get("/archive/*", v1.GetRepoArchive)
|
||||
|
||||
m.Group("/keys", func() {
|
||||
m.Combo("").Get(v1.ListRepoDeployKeys).
|
||||
Post(bind(api.CreateDeployKeyOption{}), v1.CreateRepoDeployKey)
|
||||
m.Combo("/:id").Get(v1.GetRepoDeployKey).
|
||||
Delete(v1.DeleteRepoDeploykey)
|
||||
})
|
||||
}, middleware.ApiRepoAssignment())
|
||||
}, middleware.ApiReqToken())
|
||||
|
||||
@@ -462,8 +470,10 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Post("/delete", repo.DeleteDeployKey)
|
||||
})
|
||||
|
||||
}, func(ctx *middleware.Context) {
|
||||
ctx.Data["PageIsSettings"] = true
|
||||
})
|
||||
}, reqSignIn, middleware.RepoAssignment(true), reqRepoAdmin)
|
||||
}, reqSignIn, middleware.RepoAssignment(true), reqRepoAdmin, middleware.RepoRef())
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Get("/action/:action", repo.Action)
|
||||
@@ -504,6 +514,7 @@ func runWeb(ctx *cli.Context) {
|
||||
m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
|
||||
m.Get("/edit/:tagname", repo.EditRelease)
|
||||
m.Post("/edit/:tagname", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
|
||||
m.Post("/delete", repo.DeleteRelease)
|
||||
}, reqRepoAdmin, middleware.RepoRef())
|
||||
|
||||
m.Combo("/compare/*").Get(repo.CompareAndPullRequest).
|
||||
@@ -511,11 +522,17 @@ func runWeb(ctx *cli.Context) {
|
||||
}, reqSignIn, middleware.RepoAssignment(true))
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Get("/releases", middleware.RepoRef(), repo.Releases)
|
||||
m.Get("/^:type(issues|pulls)$", repo.RetrieveLabels, repo.Issues)
|
||||
m.Group("", func() {
|
||||
m.Get("/releases", repo.Releases)
|
||||
m.Get("/^:type(issues|pulls)$", repo.RetrieveLabels, repo.Issues)
|
||||
m.Get("/labels/", repo.RetrieveLabels, repo.Labels)
|
||||
m.Get("/milestones", repo.Milestones)
|
||||
}, middleware.RepoRef(),
|
||||
func(ctx *middleware.Context) {
|
||||
ctx.Data["PageIsList"] = true
|
||||
})
|
||||
m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue)
|
||||
m.Get("/labels/", repo.RetrieveLabels, repo.Labels)
|
||||
m.Get("/milestones", repo.Milestones)
|
||||
|
||||
m.Get("/branches", repo.Branches)
|
||||
m.Get("/archive/*", repo.Download)
|
||||
|
||||
|
||||
@@ -334,3 +334,5 @@ it-IT = it
|
||||
|
||||
[other]
|
||||
SHOW_FOOTER_BRANDING = false
|
||||
; Show version information about gogs and go in the footer
|
||||
SHOW_FOOTER_VERSION = true
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -164,6 +164,7 @@ activate_account = Please activate your account
|
||||
activate_email = Verify your e-mail address
|
||||
reset_password = Reset your password
|
||||
register_success = Register success, Welcome
|
||||
register_notify = Welcome on board
|
||||
|
||||
[modal]
|
||||
yes = Yes
|
||||
@@ -336,6 +337,7 @@ visibility = Visibility
|
||||
visiblity_helper = This repository is <span class="ui red text">Private</span>
|
||||
visiblity_helper_forced = Site admin has forced all new repositories to be <span class="ui red text">Private</span>
|
||||
visiblity_fork_helper = (Change of this value will affect all forks)
|
||||
clone_helper = Need help cloning? Visit <a target="_blank" href="%s">Help</a>!
|
||||
fork_repo = Fork Repository
|
||||
fork_from = Fork From
|
||||
fork_visiblity_helper = You cannot alter the visibility of a forked repository.
|
||||
@@ -350,6 +352,9 @@ auto_init = Initialize this repository with selected files and template
|
||||
create_repo = Create Repository
|
||||
default_branch = Default Branch
|
||||
mirror_interval = Mirror Interval (hour)
|
||||
watchers = Watchers
|
||||
stargazers = Stargazers
|
||||
forks = Forks
|
||||
|
||||
form.name_reserved = Repository name '%s' is reserved.
|
||||
form.name_pattern_not_allowed = Repository name pattern '%s' is not allowed.
|
||||
@@ -362,15 +367,14 @@ migrate.clone_address = Clone Address
|
||||
migrate.clone_address_desc = This can be a HTTP/HTTPS/GIT URL or local server path.
|
||||
migrate.permission_denied = You are not allowed to import local repositories.
|
||||
migrate.invalid_local_path = Invalid local path, it does not exist or not a directory.
|
||||
migrate.failed = Migration failed: %v
|
||||
|
||||
forked_from = forked from
|
||||
fork_from_self = You cannot fork repository you already owned!
|
||||
copy_link = Copy
|
||||
copy_link_success = Copied!
|
||||
copy_link_error = Press ⌘-C or Ctrl-C to copy
|
||||
click_to_copy = Copy to clipboard
|
||||
copied = Copied OK
|
||||
clone_helper = Need help cloning? Visit <a target="_blank" href="%s">Help</a>!
|
||||
unwatch = Unwatch
|
||||
watch = Watch
|
||||
unstar = Unstar
|
||||
@@ -384,10 +388,9 @@ create_new_repo_command = Create a new repository on the command line
|
||||
push_exist_repo = Push an existing repository from the command line
|
||||
repo_is_empty = This repository is empty, please come back later!
|
||||
|
||||
|
||||
branch = Branch
|
||||
tree = Tree
|
||||
branch_and_tags = Branches & Tags
|
||||
filter_branch_and_tag = Filter branch or tag
|
||||
branches = Branches
|
||||
tags = Tags
|
||||
issues = Issues
|
||||
@@ -482,6 +485,7 @@ issues.label_deletion = Label Deletion
|
||||
issues.label_deletion_desc = Delete this label will remove its information in all related issues. Do you want to continue?
|
||||
issues.label_deletion_success = Label has been deleted successfully!
|
||||
|
||||
pulls.new = New Pull Request
|
||||
pulls.compare_changes = Compare Changes
|
||||
pulls.compare_changes_desc = Compare two branches and make a pull request for changes.
|
||||
pulls.compare_base = base
|
||||
@@ -562,6 +566,7 @@ settings.confirm_delete = Confirm Deletion
|
||||
settings.add_collaborator = Add New Collaborator
|
||||
settings.add_collaborator_success = New collaborator has been added.
|
||||
settings.remove_collaborator_success = Collaborator has been removed.
|
||||
settings.search_user_placeholder = Search user...
|
||||
settings.user_is_org_member = User is organization member who cannot be added as a collaborator.
|
||||
settings.add_webhook = Add Webhook
|
||||
settings.hooks_desc = Webhooks are much like basic HTTP POST event triggers. Whenever something occurs in Gogs, we will handle the notification to the target host you specify. Learn more in this <a target="_blank" href="%s">Webhooks Guide</a>.
|
||||
@@ -634,21 +639,28 @@ release.stable = Stable
|
||||
release.edit = edit
|
||||
release.ahead = <strong>%d</strong> commits to %s since this release
|
||||
release.source_code = Source Code
|
||||
release.new_subheader = Publish releases to iterate product.
|
||||
release.edit_subheader = Detailed change log can help users understand what has been improved.
|
||||
release.tag_name = Tag name
|
||||
release.target = Target
|
||||
release.tag_helper = Choose an existing tag, or create a new tag on publish.
|
||||
release.release_title = Release title
|
||||
release.content_with_md = Content with <a href="%s">Markdown</a>
|
||||
release.title = Title
|
||||
release.content = Content
|
||||
release.write = Write
|
||||
release.preview = Preview
|
||||
release.content_placeholder = Write some content
|
||||
release.loading = Loading...
|
||||
release.prerelease_desc = This is a pre-release
|
||||
release.prerelease_helper = We’ll point out that this release is not production-ready.
|
||||
release.cancel = Cancel
|
||||
release.publish = Publish Release
|
||||
release.save_draft = Save Draft
|
||||
release.edit_release = Edit Release
|
||||
release.delete_release = Delete This Release
|
||||
release.deletion = Release Deletion
|
||||
release.deletion_desc = Delete this release will delete corresponding Git tag. Do you want to continue?
|
||||
release.deletion_success = Release has been deleted successfully!
|
||||
release.tag_name_already_exist = Release with this tag name has already existed.
|
||||
release.downloads = Downloads
|
||||
|
||||
[org]
|
||||
org_name_holder = Organization Name
|
||||
@@ -753,6 +765,8 @@ dashboard.delete_inactivate_accounts = Delete all inactive accounts
|
||||
dashboard.delete_inactivate_accounts_success = All inactivate accounts have been deleted successfully.
|
||||
dashboard.delete_repo_archives = Delete all repositories archives
|
||||
dashboard.delete_repo_archives_success = All repositories archives have been deleted successfully.
|
||||
dashboard.delete_missing_repos = Delete all repository records that lost Git files
|
||||
dashboard.delete_missing_repos_success = All repository records that lost Git files have been deleted successfully.
|
||||
dashboard.git_gc_repos = Do garbage collection on repositories
|
||||
dashboard.git_gc_repos_success = All repositories have done garbage collection successfully.
|
||||
dashboard.resync_all_sshkeys = Rewrite '.ssh/authorized_keys' file (caution: non-Gogs keys will be lost)
|
||||
@@ -957,7 +971,7 @@ notices.delete_success = System notice has been deleted successfully.
|
||||
[action]
|
||||
create_repo = created repository <a href="%s">%s</a>
|
||||
rename_repo = renamed repository from <code>%[1]s</code> to <a href="%[2]s">%[3]s</a>
|
||||
commit_repo = pushed to <a href="%s/src/%s">%[2]s</a> at <a href="%[1]s">%[3]s</a>
|
||||
commit_repo = pushed to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
create_issue = `opened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request = `created pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue = `commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -464,7 +464,7 @@
|
||||
"ignore": 0,
|
||||
"ignoreWasSetByUser": 0,
|
||||
"inputAbbreviatedPath": "\/public\/less\/gogs.less",
|
||||
"outputAbbreviatedPath": "\/public\/css\/gogs.min.css",
|
||||
"outputAbbreviatedPath": "\/public\/css\/gogs.css",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 1,
|
||||
"outputStyle": 1,
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
web:
|
||||
build: .
|
||||
links:
|
||||
- mysql
|
||||
ports:
|
||||
- "3000:3000"
|
||||
|
||||
mysql:
|
||||
image: mysql
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=gogs
|
||||
- MYSQL_DATABASE=gogs
|
||||
@@ -1,4 +1,6 @@
|
||||
#!/bin/sh
|
||||
set -x
|
||||
set -e
|
||||
|
||||
# Set temp environment vars
|
||||
export GOPATH=/tmp/go
|
||||
|
||||
@@ -52,5 +52,5 @@ fi
|
||||
if [ $# -gt 0 ];then
|
||||
exec "$@"
|
||||
else
|
||||
exec /usr/bin/s6-svscan /app/gogs/docker/s6/
|
||||
exec /bin/s6-svscan /app/gogs/docker/s6/
|
||||
fi
|
||||
|
||||
2
gogs.go
2
gogs.go
@@ -17,7 +17,7 @@ import (
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const APP_VER = "0.7.6.1112 Beta"
|
||||
const APP_VER = "0.7.19.1121 Beta"
|
||||
|
||||
func init() {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
||||
@@ -36,19 +36,19 @@ func accessLevel(e Engine, u *User, repo *Repository) (AccessMode, error) {
|
||||
mode = ACCESS_MODE_READ
|
||||
}
|
||||
|
||||
if u != nil {
|
||||
if u.Id == repo.OwnerID {
|
||||
return ACCESS_MODE_OWNER, nil
|
||||
}
|
||||
|
||||
a := &Access{UserID: u.Id, RepoID: repo.ID}
|
||||
if has, err := e.Get(a); !has || err != nil {
|
||||
return mode, err
|
||||
}
|
||||
return a.Mode, nil
|
||||
if u == nil {
|
||||
return mode, nil
|
||||
}
|
||||
|
||||
return mode, nil
|
||||
if u.Id == repo.OwnerID {
|
||||
return ACCESS_MODE_OWNER, nil
|
||||
}
|
||||
|
||||
a := &Access{UserID: u.Id, RepoID: repo.ID}
|
||||
if has, err := e.Get(a); !has || err != nil {
|
||||
return mode, err
|
||||
}
|
||||
return a.Mode, nil
|
||||
}
|
||||
|
||||
// AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
|
||||
@@ -67,9 +67,8 @@ func HasAccess(u *User, repo *Repository, testMode AccessMode) (bool, error) {
|
||||
return hasAccess(x, u, repo, testMode)
|
||||
}
|
||||
|
||||
// GetAccessibleRepositories finds all repositories where a user has access to,
|
||||
// besides he/she owns.
|
||||
func (u *User) GetAccessibleRepositories() (map[*Repository]AccessMode, error) {
|
||||
// GetRepositoryAccesses finds all repositories with their access mode where a user has access but does not own.
|
||||
func (u *User) GetRepositoryAccesses() (map[*Repository]AccessMode, error) {
|
||||
accesses := make([]*Access, 0, 10)
|
||||
if err := x.Find(&accesses, &Access{UserID: u.Id}); err != nil {
|
||||
return nil, err
|
||||
@@ -80,7 +79,7 @@ func (u *User) GetAccessibleRepositories() (map[*Repository]AccessMode, error) {
|
||||
repo, err := GetRepositoryByID(access.RepoID)
|
||||
if err != nil {
|
||||
if IsErrRepoNotExist(err) {
|
||||
log.Error(4, "%v", err)
|
||||
log.Error(4, "GetRepositoryByID: %v", err)
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
@@ -92,11 +91,28 @@ func (u *User) GetAccessibleRepositories() (map[*Repository]AccessMode, error) {
|
||||
}
|
||||
repos[repo] = access.Mode
|
||||
}
|
||||
|
||||
// FIXME: should we generate an ordered list here? Random looks weird.
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
// GetAccessibleRepositories finds all repositories where a user has access but does not own.
|
||||
func (u *User) GetAccessibleRepositories() ([]*Repository, error) {
|
||||
accesses := make([]*Access, 0, 10)
|
||||
if err := x.Find(&accesses, &Access{UserID: u.Id}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(accesses) == 0 {
|
||||
return []*Repository{}, nil
|
||||
}
|
||||
|
||||
repoIDs := make([]int64, 0, len(accesses))
|
||||
for _, access := range accesses {
|
||||
repoIDs = append(repoIDs, access.RepoID)
|
||||
}
|
||||
repos := make([]*Repository, 0, len(repoIDs))
|
||||
return repos, x.Where("owner_id != ?", u.Id).In("id", repoIDs).Desc("updated").Find(&repos)
|
||||
}
|
||||
|
||||
func maxAccessMode(modes ...AccessMode) AccessMode {
|
||||
max := ACCESS_MODE_NONE
|
||||
for _, mode := range modes {
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/go-xorm/xorm"
|
||||
|
||||
api "github.com/gogits/go-gogs-client"
|
||||
@@ -136,6 +137,26 @@ func (a Action) GetIssueInfos() []string {
|
||||
return strings.SplitN(a.Content, "|", 2)
|
||||
}
|
||||
|
||||
func (a Action) GetIssueTitle() string {
|
||||
index := com.StrTo(a.GetIssueInfos()[0]).MustInt64()
|
||||
issue, err := GetIssueByIndex(a.RepoID, index)
|
||||
if err != nil {
|
||||
log.Error(4, "GetIssueByIndex: %v", err)
|
||||
return "500 when get issue"
|
||||
}
|
||||
return issue.Name
|
||||
}
|
||||
|
||||
func (a Action) GetIssueContent() string {
|
||||
index := com.StrTo(a.GetIssueInfos()[0]).MustInt64()
|
||||
issue, err := GetIssueByIndex(a.RepoID, index)
|
||||
if err != nil {
|
||||
log.Error(4, "GetIssueByIndex: %v", err)
|
||||
return "500 when get issue"
|
||||
}
|
||||
return issue.Content
|
||||
}
|
||||
|
||||
func newRepoAction(e Engine, u *User, repo *Repository) (err error) {
|
||||
if err = notifyWatchers(e, &Action{
|
||||
ActUserID: u.Id,
|
||||
@@ -187,8 +208,48 @@ func issueIndexTrimRight(c rune) bool {
|
||||
return !unicode.IsDigit(c)
|
||||
}
|
||||
|
||||
type PushCommit struct {
|
||||
Sha1 string
|
||||
Message string
|
||||
AuthorEmail string
|
||||
AuthorName string
|
||||
}
|
||||
|
||||
type PushCommits struct {
|
||||
Len int
|
||||
Commits []*PushCommit
|
||||
CompareUrl string
|
||||
|
||||
avatars map[string]string
|
||||
}
|
||||
|
||||
func NewPushCommits() *PushCommits {
|
||||
return &PushCommits{
|
||||
avatars: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
// AvatarLink tries to match user in database with e-mail
|
||||
// in order to show custom avatar, and falls back to general avatar link.
|
||||
func (push *PushCommits) AvatarLink(email string) string {
|
||||
_, ok := push.avatars[email]
|
||||
if !ok {
|
||||
u, err := GetUserByEmail(email)
|
||||
if err != nil {
|
||||
push.avatars[email] = base.AvatarLink(email)
|
||||
if !IsErrUserNotExist(err) {
|
||||
log.Error(4, "GetUserByEmail: %v", err)
|
||||
}
|
||||
} else {
|
||||
push.avatars[email] = u.AvatarLink()
|
||||
}
|
||||
}
|
||||
|
||||
return push.avatars[email]
|
||||
}
|
||||
|
||||
// updateIssuesCommit checks if issues are manipulated by commit message.
|
||||
func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string, commits []*base.PushCommit) error {
|
||||
func updateIssuesCommit(u *User, repo *Repository, repoUserName, repoName string, commits []*PushCommit) error {
|
||||
// Commits are appended in the reverse order.
|
||||
for i := len(commits) - 1; i >= 0; i-- {
|
||||
c := commits[i]
|
||||
@@ -322,7 +383,7 @@ func CommitRepoAction(
|
||||
repoID int64,
|
||||
repoUserName, repoName string,
|
||||
refFullName string,
|
||||
commit *base.PushCommits,
|
||||
commit *PushCommits,
|
||||
oldCommitID string, newCommitID string) error {
|
||||
|
||||
u, err := GetUserByID(userID)
|
||||
@@ -348,7 +409,7 @@ func CommitRepoAction(
|
||||
// Check it's tag push or branch.
|
||||
if strings.HasPrefix(refFullName, "refs/tags/") {
|
||||
opType = PUSH_TAG
|
||||
commit = &base.PushCommits{}
|
||||
commit = &PushCommits{}
|
||||
} else {
|
||||
// if not the first commit, set the compareUrl
|
||||
if !strings.HasPrefix(oldCommitID, "0000000") {
|
||||
@@ -357,6 +418,10 @@ func CommitRepoAction(
|
||||
isNewBranch = true
|
||||
}
|
||||
|
||||
// NOTE: limit to detect latest 100 commits.
|
||||
if len(commit.Commits) > 100 {
|
||||
commit.Commits = commit.Commits[len(commit.Commits)-100:]
|
||||
}
|
||||
if err = updateIssuesCommit(u, repo, repoUserName, repoName, commit.Commits); err != nil {
|
||||
log.Error(4, "updateIssuesCommit: %v", err)
|
||||
}
|
||||
|
||||
@@ -114,6 +114,19 @@ func (err ErrUserHasOrgs) Error() string {
|
||||
// |____| |____/|___ /____/__|\___ > |____|__ \___ > ____|
|
||||
// \/ \/ \/ \/\/
|
||||
|
||||
type ErrKeyUnableVerify struct {
|
||||
Result string
|
||||
}
|
||||
|
||||
func IsErrKeyUnableVerify(err error) bool {
|
||||
_, ok := err.(ErrKeyUnableVerify)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrKeyUnableVerify) Error() string {
|
||||
return fmt.Sprintf("Unable to verify key content [result: %s]", err.Result)
|
||||
}
|
||||
|
||||
type ErrKeyNotExist struct {
|
||||
ID int64
|
||||
}
|
||||
@@ -155,6 +168,21 @@ func (err ErrKeyNameAlreadyUsed) Error() string {
|
||||
return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name)
|
||||
}
|
||||
|
||||
type ErrDeployKeyNotExist struct {
|
||||
ID int64
|
||||
KeyID int64
|
||||
RepoID int64
|
||||
}
|
||||
|
||||
func IsErrDeployKeyNotExist(err error) bool {
|
||||
_, ok := err.(ErrDeployKeyNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrDeployKeyNotExist) Error() string {
|
||||
return fmt.Sprintf("Deploy key does not exist [id: %d, key_id: %d, repo_id: %d]", err.ID, err.KeyID, err.RepoID)
|
||||
}
|
||||
|
||||
type ErrDeployKeyAlreadyExist struct {
|
||||
KeyID int64
|
||||
RepoID int64
|
||||
@@ -288,6 +316,33 @@ func (err ErrUpdateTaskNotExist) Error() string {
|
||||
return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID)
|
||||
}
|
||||
|
||||
type ErrReleaseAlreadyExist struct {
|
||||
TagName string
|
||||
}
|
||||
|
||||
func IsErrReleaseAlreadyExist(err error) bool {
|
||||
_, ok := err.(ErrReleaseAlreadyExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrReleaseAlreadyExist) Error() string {
|
||||
return fmt.Sprintf("Release tag already exist [tag_name: %s]", err.TagName)
|
||||
}
|
||||
|
||||
type ErrReleaseNotExist struct {
|
||||
ID int64
|
||||
TagName string
|
||||
}
|
||||
|
||||
func IsErrReleaseNotExist(err error) bool {
|
||||
_, ok := err.(ErrReleaseNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrReleaseNotExist) Error() string {
|
||||
return fmt.Sprintf("Release tag does not exist [id: %d, tag_name: %s]", err.ID, err.TagName)
|
||||
}
|
||||
|
||||
// __ __ ___. .__ __
|
||||
// / \ / \ ____\_ |__ | |__ ____ ____ | | __
|
||||
// \ \/\/ // __ \| __ \| | \ / _ \ / _ \| |/ /
|
||||
|
||||
@@ -163,10 +163,10 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
|
||||
if strings.HasPrefix(line, DIFF_HEAD) {
|
||||
middle := -1
|
||||
|
||||
// Note: In case file name is surrounded by double quotes(it happens only in git-shell).
|
||||
hasQuote := strings.Index(line, `\"`) > -1
|
||||
// Note: In case file name is surrounded by double quotes (it happens only in git-shell).
|
||||
// e.g. diff --git "a/xxx" "b/xxx"
|
||||
hasQuote := line[len(DIFF_HEAD)] == '"'
|
||||
if hasQuote {
|
||||
line = strings.Replace(line, `\"`, `"`, -1)
|
||||
middle = strings.Index(line, ` "b/`)
|
||||
} else {
|
||||
middle = strings.Index(line, " b/")
|
||||
@@ -176,8 +176,8 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
|
||||
a := line[beg+2 : middle]
|
||||
b := line[middle+3:]
|
||||
if hasQuote {
|
||||
a = a[1 : len(a)-1]
|
||||
b = b[1 : len(b)-1]
|
||||
a = string(git.UnescapeChars([]byte(a[1 : len(a)-1])))
|
||||
b = string(git.UnescapeChars([]byte(b[1 : len(b)-1])))
|
||||
}
|
||||
|
||||
curFile = &DiffFile{
|
||||
|
||||
@@ -718,32 +718,28 @@ func GetIssueStats(opts *IssueStatsOptions) *IssueStats {
|
||||
if opts.AssigneeID > 0 {
|
||||
baseCond += " AND assignee_id=" + com.ToStr(opts.AssigneeID)
|
||||
}
|
||||
if opts.IsPull {
|
||||
baseCond += " AND issue.is_pull=1"
|
||||
} else {
|
||||
baseCond += " AND issue.is_pull=0"
|
||||
}
|
||||
baseCond += " AND issue.is_pull=?"
|
||||
|
||||
switch opts.FilterMode {
|
||||
case FM_ALL, FM_ASSIGN:
|
||||
results, _ := x.Query(queryStr+baseCond, false)
|
||||
results, _ := x.Query(queryStr+baseCond, false, opts.IsPull)
|
||||
stats.OpenCount = parseCountResult(results)
|
||||
results, _ = x.Query(queryStr+baseCond, true)
|
||||
results, _ = x.Query(queryStr+baseCond, true, opts.IsPull)
|
||||
stats.ClosedCount = parseCountResult(results)
|
||||
|
||||
case FM_CREATE:
|
||||
baseCond += " AND poster_id=?"
|
||||
results, _ := x.Query(queryStr+baseCond, false, opts.UserID)
|
||||
results, _ := x.Query(queryStr+baseCond, false, opts.IsPull, opts.UserID)
|
||||
stats.OpenCount = parseCountResult(results)
|
||||
results, _ = x.Query(queryStr+baseCond, true, opts.UserID)
|
||||
results, _ = x.Query(queryStr+baseCond, true, opts.IsPull, opts.UserID)
|
||||
stats.ClosedCount = parseCountResult(results)
|
||||
|
||||
case FM_MENTION:
|
||||
queryStr += " INNER JOIN `issue_user` ON `issue`.id=`issue_user`.issue_id"
|
||||
baseCond += " AND `issue_user`.uid=? AND `issue_user`.is_mentioned=?"
|
||||
results, _ := x.Query(queryStr+baseCond, false, opts.UserID, true)
|
||||
results, _ := x.Query(queryStr+baseCond, false, opts.IsPull, opts.UserID, true)
|
||||
stats.OpenCount = parseCountResult(results)
|
||||
results, _ = x.Query(queryStr+baseCond, true, opts.UserID, true)
|
||||
results, _ = x.Query(queryStr+baseCond, true, opts.IsPull, opts.UserID, true)
|
||||
stats.ClosedCount = parseCountResult(results)
|
||||
}
|
||||
return stats
|
||||
@@ -1375,8 +1371,8 @@ func ChangeMilestoneAssign(oldMid int64, issue *Issue) (err error) {
|
||||
}
|
||||
|
||||
// DeleteMilestoneByID deletes a milestone by given ID.
|
||||
func DeleteMilestoneByID(mid int64) error {
|
||||
m, err := GetMilestoneByID(mid)
|
||||
func DeleteMilestoneByID(id int64) error {
|
||||
m, err := GetMilestoneByID(id)
|
||||
if err != nil {
|
||||
if IsErrMilestoneNotExist(err) {
|
||||
return nil
|
||||
|
||||
@@ -225,10 +225,9 @@ func DeleteSource(source *LoginSource) error {
|
||||
// |_______ \/_______ /\____|__ /____|
|
||||
// \/ \/ \/
|
||||
|
||||
// Query if name/passwd can login against the LDAP directory pool
|
||||
// Create a local user if success
|
||||
// Return the same LoginUserPlain semantic
|
||||
// FIXME: https://github.com/gogits/gogs/issues/672
|
||||
// LoginUserLDAPSource queries if name/passwd can login against the LDAP directory pool,
|
||||
// and create a local user if success when enabled.
|
||||
// It returns the same LoginUserPlain semantic.
|
||||
func LoginUserLDAPSource(u *User, name, passwd string, source *LoginSource, autoRegister bool) (*User, error) {
|
||||
cfg := source.Cfg.(*LDAPConfig)
|
||||
directBind := (source.Type == DLDAP)
|
||||
|
||||
@@ -32,10 +32,6 @@ const (
|
||||
_TPL_PUBLICK_KEY = `command="%s serv key-%d --config='%s'",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrKeyUnableVerify = errors.New("Unable to verify public key")
|
||||
)
|
||||
|
||||
var sshOpLocker = sync.Mutex{}
|
||||
var SSHPath string // SSH directory.
|
||||
|
||||
@@ -211,7 +207,7 @@ func CheckPublicKeyString(content string) (_ string, err error) {
|
||||
|
||||
sshKeygenOutput := strings.Split(stdout, " ")
|
||||
if len(sshKeygenOutput) < 4 {
|
||||
return content, ErrKeyUnableVerify
|
||||
return content, ErrKeyUnableVerify{stdout}
|
||||
}
|
||||
|
||||
// Check if key type and key size match.
|
||||
@@ -523,6 +519,7 @@ type DeployKey struct {
|
||||
RepoID int64 `xorm:"UNIQUE(s) INDEX"`
|
||||
Name string
|
||||
Fingerprint string
|
||||
Content string `xorm:"-"`
|
||||
Created time.Time `xorm:"CREATED"`
|
||||
Updated time.Time // Note: Updated must below Created for AfterSet.
|
||||
HasRecentActivity bool `xorm:"-"`
|
||||
@@ -537,6 +534,16 @@ func (k *DeployKey) AfterSet(colName string, _ xorm.Cell) {
|
||||
}
|
||||
}
|
||||
|
||||
// GetContent gets associated public key content.
|
||||
func (k *DeployKey) GetContent() error {
|
||||
pkey, err := GetPublicKeyByID(k.KeyID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
k.Content = pkey.Content
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkDeployKey(e Engine, keyID, repoID int64, name string) error {
|
||||
// Note: We want error detail, not just true or false here.
|
||||
has, err := e.Where("key_id=? AND repo_id=?", keyID, repoID).Get(new(DeployKey))
|
||||
@@ -557,18 +564,19 @@ func checkDeployKey(e Engine, keyID, repoID int64, name string) error {
|
||||
}
|
||||
|
||||
// addDeployKey adds new key-repo relation.
|
||||
func addDeployKey(e *xorm.Session, keyID, repoID int64, name, fingerprint string) (err error) {
|
||||
if err = checkDeployKey(e, keyID, repoID, name); err != nil {
|
||||
return err
|
||||
func addDeployKey(e *xorm.Session, keyID, repoID int64, name, fingerprint string) (*DeployKey, error) {
|
||||
if err := checkDeployKey(e, keyID, repoID, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = e.Insert(&DeployKey{
|
||||
key := &DeployKey{
|
||||
KeyID: keyID,
|
||||
RepoID: repoID,
|
||||
Name: name,
|
||||
Fingerprint: fingerprint,
|
||||
})
|
||||
return err
|
||||
}
|
||||
_, err := e.Insert(key)
|
||||
return key, err
|
||||
}
|
||||
|
||||
// HasDeployKey returns true if public key is a deploy key of given repository.
|
||||
@@ -578,39 +586,52 @@ func HasDeployKey(keyID, repoID int64) bool {
|
||||
}
|
||||
|
||||
// AddDeployKey add new deploy key to database and authorized_keys file.
|
||||
func AddDeployKey(repoID int64, name, content string) (err error) {
|
||||
if err = checkKeyContent(content); err != nil {
|
||||
return err
|
||||
func AddDeployKey(repoID int64, name, content string) (*DeployKey, error) {
|
||||
if err := checkKeyContent(content); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key := &PublicKey{
|
||||
pkey := &PublicKey{
|
||||
Content: content,
|
||||
Mode: ACCESS_MODE_READ,
|
||||
Type: KEY_TYPE_DEPLOY,
|
||||
}
|
||||
has, err := x.Get(key)
|
||||
has, err := x.Get(pkey)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// First time use this deploy key.
|
||||
if !has {
|
||||
if err = addKey(sess, key); err != nil {
|
||||
return nil
|
||||
if err = addKey(sess, pkey); err != nil {
|
||||
return nil, fmt.Errorf("addKey: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = addDeployKey(sess, key.ID, repoID, name, key.Fingerprint); err != nil {
|
||||
return err
|
||||
key, err := addDeployKey(sess, pkey.ID, repoID, name, pkey.Fingerprint)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("addDeployKey: %v", err)
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
return key, sess.Commit()
|
||||
}
|
||||
|
||||
// GetDeployKeyByID returns deploy key by given ID.
|
||||
func GetDeployKeyByID(id int64) (*DeployKey, error) {
|
||||
key := new(DeployKey)
|
||||
has, err := x.Id(id).Get(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrDeployKeyNotExist{id, 0, 0}
|
||||
}
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// GetDeployKeyByRepo returns deploy key by given public key ID and repository ID.
|
||||
@@ -619,8 +640,13 @@ func GetDeployKeyByRepo(keyID, repoID int64) (*DeployKey, error) {
|
||||
KeyID: keyID,
|
||||
RepoID: repoID,
|
||||
}
|
||||
_, err := x.Get(key)
|
||||
return key, err
|
||||
has, err := x.Get(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrDeployKeyNotExist{0, keyID, repoID}
|
||||
}
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// UpdateDeployKey updates deploy key information.
|
||||
|
||||
@@ -166,43 +166,49 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error
|
||||
|
||||
var stderr string
|
||||
if _, stderr, err = process.ExecTimeout(5*time.Minute,
|
||||
fmt.Sprintf("PullRequest.Merge(git clone): %s", tmpBasePath),
|
||||
fmt.Sprintf("PullRequest.Merge (git clone): %s", tmpBasePath),
|
||||
"git", "clone", baseGitRepo.Path, tmpBasePath); err != nil {
|
||||
return fmt.Errorf("git clone: %s", stderr)
|
||||
}
|
||||
|
||||
// Check out base branch.
|
||||
if _, stderr, err = process.ExecDir(-1, tmpBasePath,
|
||||
fmt.Sprintf("PullRequest.Merge(git checkout): %s", tmpBasePath),
|
||||
fmt.Sprintf("PullRequest.Merge (git checkout): %s", tmpBasePath),
|
||||
"git", "checkout", pr.BaseBranch); err != nil {
|
||||
return fmt.Errorf("git checkout: %s", stderr)
|
||||
}
|
||||
|
||||
// Add head repo remote.
|
||||
if _, stderr, err = process.ExecDir(-1, tmpBasePath,
|
||||
fmt.Sprintf("PullRequest.Merge(git remote add): %s", tmpBasePath),
|
||||
fmt.Sprintf("PullRequest.Merge (git remote add): %s", tmpBasePath),
|
||||
"git", "remote", "add", "head_repo", headRepoPath); err != nil {
|
||||
return fmt.Errorf("git remote add[%s -> %s]: %s", headRepoPath, tmpBasePath, stderr)
|
||||
return fmt.Errorf("git remote add [%s -> %s]: %s", headRepoPath, tmpBasePath, stderr)
|
||||
}
|
||||
|
||||
// Merge commits.
|
||||
if _, stderr, err = process.ExecDir(-1, tmpBasePath,
|
||||
fmt.Sprintf("PullRequest.Merge(git fetch): %s", tmpBasePath),
|
||||
fmt.Sprintf("PullRequest.Merge (git fetch): %s", tmpBasePath),
|
||||
"git", "fetch", "head_repo"); err != nil {
|
||||
return fmt.Errorf("git fetch[%s -> %s]: %s", headRepoPath, tmpBasePath, stderr)
|
||||
return fmt.Errorf("git fetch [%s -> %s]: %s", headRepoPath, tmpBasePath, stderr)
|
||||
}
|
||||
|
||||
if _, stderr, err = process.ExecDir(-1, tmpBasePath,
|
||||
fmt.Sprintf("PullRequest.Merge(git merge): %s", tmpBasePath),
|
||||
"git", "merge", "--no-ff", "-m",
|
||||
fmt.Sprintf("Merge branch '%s' of %s/%s into %s", pr.HeadBranch, pr.HeadUserName, pr.HeadRepo.Name, pr.BaseBranch),
|
||||
"head_repo/"+pr.HeadBranch); err != nil {
|
||||
return fmt.Errorf("git merge[%s]: %s", tmpBasePath, stderr)
|
||||
fmt.Sprintf("PullRequest.Merge (git merge --no-ff --no-commit): %s", tmpBasePath),
|
||||
"git", "merge", "--no-ff", "--no-commit", "head_repo/"+pr.HeadBranch); err != nil {
|
||||
return fmt.Errorf("git merge --no-ff --no-commit [%s]: %v - %s", tmpBasePath, err, stderr)
|
||||
}
|
||||
|
||||
sig := doer.NewGitSig()
|
||||
if _, stderr, err = process.ExecDir(-1, tmpBasePath,
|
||||
fmt.Sprintf("PullRequest.Merge (git merge): %s", tmpBasePath),
|
||||
"git", "commit", fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email),
|
||||
"-m", fmt.Sprintf("Merge branch '%s' of %s/%s into %s", pr.HeadBranch, pr.HeadUserName, pr.HeadRepo.Name, pr.BaseBranch)); err != nil {
|
||||
return fmt.Errorf("git commit [%s]: %v - %s", tmpBasePath, err, stderr)
|
||||
}
|
||||
|
||||
// Push back to upstream.
|
||||
if _, stderr, err = process.ExecDir(-1, tmpBasePath,
|
||||
fmt.Sprintf("PullRequest.Merge(git push): %s", tmpBasePath),
|
||||
fmt.Sprintf("PullRequest.Merge (git push): %s", tmpBasePath),
|
||||
"git", "push", baseGitRepo.Path, pr.BaseBranch); err != nil {
|
||||
return fmt.Errorf("git push: %s", stderr)
|
||||
}
|
||||
@@ -218,6 +224,7 @@ var patchConflicts = []string{
|
||||
}
|
||||
|
||||
// testPatch checks if patch can be merged to base repository without conflit.
|
||||
// FIXME: make a mechanism to clean up stable local copies.
|
||||
func (pr *PullRequest) testPatch() (err error) {
|
||||
if pr.BaseRepo == nil {
|
||||
pr.BaseRepo, err = GetRepositoryByID(pr.BaseRepoID)
|
||||
@@ -243,14 +250,23 @@ func (pr *PullRequest) testPatch() (err error) {
|
||||
return fmt.Errorf("UpdateLocalCopy: %v", err)
|
||||
}
|
||||
|
||||
pr.Status = PULL_REQUEST_STATUS_CHECKING
|
||||
// Checkout base branch.
|
||||
_, stderr, err := process.ExecDir(-1, pr.BaseRepo.LocalCopyPath(),
|
||||
fmt.Sprintf("PullRequest.Merge(git checkout): %s", pr.BaseRepo.ID),
|
||||
"git", "checkout", pr.BaseBranch)
|
||||
if err != nil {
|
||||
return fmt.Errorf("git checkout: %s", stderr)
|
||||
}
|
||||
|
||||
pr.Status = PULL_REQUEST_STATUS_CHECKING
|
||||
_, stderr, err = process.ExecDir(-1, pr.BaseRepo.LocalCopyPath(),
|
||||
fmt.Sprintf("testPatch(git apply --check): %d", pr.BaseRepo.ID),
|
||||
"git", "apply", "--check", patchPath)
|
||||
if err != nil {
|
||||
for i := range patchConflicts {
|
||||
if strings.Contains(stderr, patchConflicts[i]) {
|
||||
log.Trace("PullRequest[%d].testPatch(apply): has conflit", pr.ID)
|
||||
fmt.Println(stderr)
|
||||
pr.Status = PULL_REQUEST_STATUS_CONFLICT
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -13,18 +13,14 @@ import (
|
||||
"github.com/go-xorm/xorm"
|
||||
|
||||
"github.com/gogits/gogs/modules/git"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrReleaseAlreadyExist = errors.New("Release already exist")
|
||||
ErrReleaseNotExist = errors.New("Release does not exist")
|
||||
"github.com/gogits/gogs/modules/process"
|
||||
)
|
||||
|
||||
// Release represents a release of repository.
|
||||
type Release struct {
|
||||
Id int64
|
||||
RepoId int64
|
||||
PublisherId int64
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64
|
||||
PublisherID int64
|
||||
Publisher *User `xorm:"-"`
|
||||
TagName string
|
||||
LowerTagName string
|
||||
@@ -47,12 +43,12 @@ func (r *Release) AfterSet(colName string, _ xorm.Cell) {
|
||||
}
|
||||
|
||||
// IsReleaseExist returns true if release with given tag name already exists.
|
||||
func IsReleaseExist(repoId int64, tagName string) (bool, error) {
|
||||
func IsReleaseExist(repoID int64, tagName string) (bool, error) {
|
||||
if len(tagName) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return x.Get(&Release{RepoId: repoId, LowerTagName: strings.ToLower(tagName)})
|
||||
return x.Get(&Release{RepoID: repoID, LowerTagName: strings.ToLower(tagName)})
|
||||
}
|
||||
|
||||
func createTag(gitRepo *git.Repository, rel *Release) error {
|
||||
@@ -84,11 +80,11 @@ func createTag(gitRepo *git.Repository, rel *Release) error {
|
||||
|
||||
// CreateRelease creates a new release of repository.
|
||||
func CreateRelease(gitRepo *git.Repository, rel *Release) error {
|
||||
isExist, err := IsReleaseExist(rel.RepoId, rel.TagName)
|
||||
isExist, err := IsReleaseExist(rel.RepoID, rel.TagName)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if isExist {
|
||||
return ErrReleaseAlreadyExist
|
||||
return ErrReleaseAlreadyExist{rel.TagName}
|
||||
}
|
||||
|
||||
if err = createTag(gitRepo, rel); err != nil {
|
||||
@@ -100,22 +96,35 @@ func CreateRelease(gitRepo *git.Repository, rel *Release) error {
|
||||
}
|
||||
|
||||
// GetRelease returns release by given ID.
|
||||
func GetRelease(repoId int64, tagName string) (*Release, error) {
|
||||
isExist, err := IsReleaseExist(repoId, tagName)
|
||||
func GetRelease(repoID int64, tagName string) (*Release, error) {
|
||||
isExist, err := IsReleaseExist(repoID, tagName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !isExist {
|
||||
return nil, ErrReleaseNotExist
|
||||
return nil, ErrReleaseNotExist{0, tagName}
|
||||
}
|
||||
|
||||
rel := &Release{RepoId: repoId, LowerTagName: strings.ToLower(tagName)}
|
||||
rel := &Release{RepoID: repoID, LowerTagName: strings.ToLower(tagName)}
|
||||
_, err = x.Get(rel)
|
||||
return rel, err
|
||||
}
|
||||
|
||||
// GetReleasesByRepoId returns a list of releases of repository.
|
||||
func GetReleasesByRepoId(repoId int64) (rels []*Release, err error) {
|
||||
err = x.Desc("created").Find(&rels, Release{RepoId: repoId})
|
||||
// GetReleaseByID returns release with given ID.
|
||||
func GetReleaseByID(id int64) (*Release, error) {
|
||||
rel := new(Release)
|
||||
has, err := x.Id(id).Get(rel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrReleaseNotExist{id, ""}
|
||||
}
|
||||
|
||||
return rel, nil
|
||||
}
|
||||
|
||||
// GetReleasesByRepoID returns a list of releases of repository.
|
||||
func GetReleasesByRepoID(repoID int64) (rels []*Release, err error) {
|
||||
err = x.Desc("created").Find(&rels, Release{RepoID: repoID})
|
||||
return rels, err
|
||||
}
|
||||
|
||||
@@ -150,6 +159,36 @@ func UpdateRelease(gitRepo *git.Repository, rel *Release) (err error) {
|
||||
if err = createTag(gitRepo, rel); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = x.Id(rel.Id).AllCols().Update(rel)
|
||||
_, err = x.Id(rel.ID).AllCols().Update(rel)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteReleaseByID deletes a release and corresponding Git tag by given ID.
|
||||
func DeleteReleaseByID(id int64) error {
|
||||
rel, err := GetReleaseByID(id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetReleaseByID: %v", err)
|
||||
}
|
||||
|
||||
repo, err := GetRepositoryByID(rel.RepoID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetRepositoryByID: %v", err)
|
||||
}
|
||||
|
||||
repoPath, err := repo.RepoPath()
|
||||
if err != nil {
|
||||
return fmt.Errorf("RepoPath: %v", err)
|
||||
}
|
||||
|
||||
_, stderr, err := process.ExecDir(-1, repoPath, fmt.Sprintf("DeleteReleaseByID (git tag -d): %d", rel.ID),
|
||||
"git", "tag", "-d", rel.TagName)
|
||||
if err != nil && !strings.Contains(stderr, "not found") {
|
||||
return fmt.Errorf("git tag -d: %v - %s", err, stderr)
|
||||
}
|
||||
|
||||
if _, err = x.Id(rel.ID).Delete(new(Release)); err != nil {
|
||||
return fmt.Errorf("Delete: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
153
models/repo.go
153
models/repo.go
@@ -17,6 +17,7 @@ import (
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
@@ -49,7 +50,7 @@ var (
|
||||
Gitignores, Licenses, Readmes []string
|
||||
|
||||
// Maximum items per page in forks, watchers and stars of a repo
|
||||
ItemsPerPage = 54
|
||||
ItemsPerPage = 40
|
||||
)
|
||||
|
||||
func LoadRepoConfig() {
|
||||
@@ -320,7 +321,7 @@ func (repo *Repository) UpdateLocalCopy() error {
|
||||
}
|
||||
} else {
|
||||
_, stderr, err := process.ExecDir(-1, localPath,
|
||||
fmt.Sprintf("UpdateLocalCopy(git pull): %s", repoPath), "git", "pull")
|
||||
fmt.Sprintf("UpdateLocalCopy(git pull --all): %s", repoPath), "git", "pull", "--all")
|
||||
if err != nil {
|
||||
return fmt.Errorf("git pull: %v - %s", err, stderr)
|
||||
}
|
||||
@@ -575,20 +576,20 @@ func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
|
||||
func initRepoCommit(tmpPath string, sig *git.Signature) (err error) {
|
||||
var stderr string
|
||||
if _, stderr, err = process.ExecDir(-1,
|
||||
tmpPath, fmt.Sprintf("initRepoCommit(git add): %s", tmpPath),
|
||||
tmpPath, fmt.Sprintf("initRepoCommit (git add): %s", tmpPath),
|
||||
"git", "add", "--all"); err != nil {
|
||||
return fmt.Errorf("git add: %s", stderr)
|
||||
}
|
||||
|
||||
if _, stderr, err = process.ExecDir(-1,
|
||||
tmpPath, fmt.Sprintf("initRepoCommit(git commit): %s", tmpPath),
|
||||
tmpPath, fmt.Sprintf("initRepoCommit (git commit): %s", tmpPath),
|
||||
"git", "commit", fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email),
|
||||
"-m", "initial commit"); err != nil {
|
||||
return fmt.Errorf("git commit: %s", stderr)
|
||||
}
|
||||
|
||||
if _, stderr, err = process.ExecDir(-1,
|
||||
tmpPath, fmt.Sprintf("initRepoCommit(git push): %s", tmpPath),
|
||||
tmpPath, fmt.Sprintf("initRepoCommit (git push): %s", tmpPath),
|
||||
"git", "push", "origin", "master"); err != nil {
|
||||
return fmt.Errorf("git push: %s", stderr)
|
||||
}
|
||||
@@ -699,7 +700,7 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts C
|
||||
// Init bare new repository.
|
||||
os.MkdirAll(repoPath, os.ModePerm)
|
||||
_, stderr, err := process.ExecDir(-1, repoPath,
|
||||
fmt.Sprintf("initRepository(git init --bare): %s", repoPath), "git", "init", "--bare")
|
||||
fmt.Sprintf("initRepository (git init --bare): %s", repoPath), "git", "init", "--bare")
|
||||
if err != nil {
|
||||
return fmt.Errorf("git init --bare: %v - %s", err, stderr)
|
||||
}
|
||||
@@ -1116,7 +1117,7 @@ func DeleteRepository(uid, repoID int64) error {
|
||||
return err
|
||||
} else if _, err = sess.Delete(&Milestone{RepoID: repoID}); err != nil {
|
||||
return err
|
||||
} else if _, err = sess.Delete(&Release{RepoId: repoID}); err != nil {
|
||||
} else if _, err = sess.Delete(&Release{RepoID: repoID}); err != nil {
|
||||
return err
|
||||
} else if _, err = sess.Delete(&Collaboration{RepoID: repoID}); err != nil {
|
||||
return err
|
||||
@@ -1325,6 +1326,42 @@ func DeleteRepositoryArchives() error {
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteMissingRepositories deletes all repository records that lost Git files.
|
||||
func DeleteMissingRepositories() error {
|
||||
repos := make([]*Repository, 0, 5)
|
||||
if err := x.Where("id > 0").Iterate(new(Repository),
|
||||
func(idx int, bean interface{}) error {
|
||||
repo := bean.(*Repository)
|
||||
repoPath, err := repo.RepoPath()
|
||||
if err != nil {
|
||||
return fmt.Errorf("RepoPath [%d]: %v", repo.ID, err)
|
||||
}
|
||||
|
||||
if !com.IsDir(repoPath) {
|
||||
repos = append(repos, repo)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
if err2 := CreateRepositoryNotice(fmt.Sprintf("DeleteMissingRepositories: %v", err)); err2 != nil {
|
||||
log.Error(4, "CreateRepositoryNotice: %v", err2)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(repos) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, repo := range repos {
|
||||
if err := DeleteRepository(repo.OwnerID, repo.ID); err != nil {
|
||||
if err2 := CreateRepositoryNotice(fmt.Sprintf("DeleteRepository [%d]: %v", repo.ID, err)); err2 != nil {
|
||||
log.Error(4, "CreateRepositoryNotice: %v", err2)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RewriteRepositoryUpdateHook rewrites all repositories' update hook.
|
||||
func RewriteRepositoryUpdateHook() error {
|
||||
return x.Where("id > 0").Iterate(new(Repository),
|
||||
@@ -1341,20 +1378,54 @@ func RewriteRepositoryUpdateHook() error {
|
||||
})
|
||||
}
|
||||
|
||||
var (
|
||||
// Prevent duplicate running tasks.
|
||||
isMirrorUpdating = false
|
||||
isGitFscking = false
|
||||
isCheckingRepos = false
|
||||
// statusPool represents a pool of status with true/false.
|
||||
type statusPool struct {
|
||||
lock sync.RWMutex
|
||||
pool map[string]bool
|
||||
}
|
||||
|
||||
// Start sets value of given name to true in the pool.
|
||||
func (p *statusPool) Start(name string) {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
p.pool[name] = true
|
||||
}
|
||||
|
||||
// Stop sets value of given name to false in the pool.
|
||||
func (p *statusPool) Stop(name string) {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
p.pool[name] = false
|
||||
}
|
||||
|
||||
// IsRunning checks if value of given name is set to true in the pool.
|
||||
func (p *statusPool) IsRunning(name string) bool {
|
||||
p.lock.RLock()
|
||||
defer p.lock.RUnlock()
|
||||
|
||||
return p.pool[name]
|
||||
}
|
||||
|
||||
// Prevent duplicate running tasks.
|
||||
var taskStatusPool = &statusPool{
|
||||
pool: make(map[string]bool),
|
||||
}
|
||||
|
||||
const (
|
||||
_MIRROR_UPDATE = "mirror_update"
|
||||
_GIT_FSCK = "git_fsck"
|
||||
_CHECK_REPOs = "check_repos"
|
||||
)
|
||||
|
||||
// MirrorUpdate checks and updates mirror repositories.
|
||||
func MirrorUpdate() {
|
||||
if isMirrorUpdating {
|
||||
if taskStatusPool.IsRunning(_MIRROR_UPDATE) {
|
||||
return
|
||||
}
|
||||
isMirrorUpdating = true
|
||||
defer func() { isMirrorUpdating = false }()
|
||||
taskStatusPool.Start(_MIRROR_UPDATE)
|
||||
defer taskStatusPool.Stop(_MIRROR_UPDATE)
|
||||
|
||||
log.Trace("Doing: MirrorUpdate")
|
||||
|
||||
@@ -1402,11 +1473,11 @@ func MirrorUpdate() {
|
||||
|
||||
// GitFsck calls 'git fsck' to check repository health.
|
||||
func GitFsck() {
|
||||
if isGitFscking {
|
||||
if taskStatusPool.IsRunning(_GIT_FSCK) {
|
||||
return
|
||||
}
|
||||
isGitFscking = true
|
||||
defer func() { isGitFscking = false }()
|
||||
taskStatusPool.Start(_GIT_FSCK)
|
||||
defer taskStatusPool.Stop(_GIT_FSCK)
|
||||
|
||||
log.Trace("Doing: GitFsck")
|
||||
|
||||
@@ -1471,11 +1542,11 @@ func repoStatsCheck(checker *repoChecker) {
|
||||
}
|
||||
|
||||
func CheckRepoStats() {
|
||||
if isCheckingRepos {
|
||||
if taskStatusPool.IsRunning(_CHECK_REPOs) {
|
||||
return
|
||||
}
|
||||
isCheckingRepos = true
|
||||
defer func() { isCheckingRepos = false }()
|
||||
taskStatusPool.Start(_CHECK_REPOs)
|
||||
defer taskStatusPool.Stop(_CHECK_REPOs)
|
||||
|
||||
log.Trace("Doing: CheckRepoStats")
|
||||
|
||||
@@ -1696,25 +1767,21 @@ func WatchRepo(uid, repoId int64, watch bool) (err error) {
|
||||
return watchRepo(x, uid, repoId, watch)
|
||||
}
|
||||
|
||||
func getWatchers(e Engine, rid int64) ([]*Watch, error) {
|
||||
func getWatchers(e Engine, repoID int64) ([]*Watch, error) {
|
||||
watches := make([]*Watch, 0, 10)
|
||||
err := e.Find(&watches, &Watch{RepoID: rid})
|
||||
return watches, err
|
||||
return watches, e.Find(&watches, &Watch{RepoID: repoID})
|
||||
}
|
||||
|
||||
// GetWatchers returns all watchers of given repository.
|
||||
func GetWatchers(rid int64) ([]*Watch, error) {
|
||||
return getWatchers(x, rid)
|
||||
func GetWatchers(repoID int64) ([]*Watch, error) {
|
||||
return getWatchers(x, repoID)
|
||||
}
|
||||
|
||||
// Repository.GetWatchers returns all users watching given repository.
|
||||
func (repo *Repository) GetWatchers(offset int) ([]*User, error) {
|
||||
users := make([]*User, 0, 10)
|
||||
offset = (offset - 1) * ItemsPerPage
|
||||
|
||||
err := x.Limit(ItemsPerPage, offset).Where("repo_id=?", repo.ID).Join("LEFT", "watch", "user.id=watch.user_id").Find(&users)
|
||||
|
||||
return users, err
|
||||
// Repository.GetWatchers returns range of users watching given repository.
|
||||
func (repo *Repository) GetWatchers(page int) ([]*User, error) {
|
||||
users := make([]*User, 0, ItemsPerPage)
|
||||
return users, x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).
|
||||
Where("repo_id=?", repo.ID).Join("LEFT", "watch", "user.id=watch.user_id").Find(&users)
|
||||
}
|
||||
|
||||
func notifyWatchers(e Engine, act *Action) error {
|
||||
@@ -1794,13 +1861,10 @@ func IsStaring(uid, repoId int64) bool {
|
||||
return has
|
||||
}
|
||||
|
||||
func (repo *Repository) GetStars(offset int) ([]*User, error) {
|
||||
users := make([]*User, 0, 10)
|
||||
offset = (offset - 1) * ItemsPerPage
|
||||
|
||||
err := x.Limit(ItemsPerPage, offset).Where("repo_id=?", repo.ID).Join("LEFT", "star", "user.id=star.uid").Find(&users)
|
||||
|
||||
return users, err
|
||||
func (repo *Repository) GetStargazers(page int) ([]*User, error) {
|
||||
users := make([]*User, 0, ItemsPerPage)
|
||||
return users, x.Limit(ItemsPerPage, (page-1)*ItemsPerPage).
|
||||
Where("repo_id=?", repo.ID).Join("LEFT", "star", "user.id=star.uid").Find(&users)
|
||||
}
|
||||
|
||||
// ___________ __
|
||||
@@ -1872,9 +1936,6 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
|
||||
}
|
||||
|
||||
func (repo *Repository) GetForks() ([]*Repository, error) {
|
||||
forks := make([]*Repository, 0, 10)
|
||||
|
||||
err := x.Find(&forks, &Repository{ForkID: repo.ID})
|
||||
|
||||
return forks, err
|
||||
forks := make([]*Repository, 0, repo.NumForks)
|
||||
return forks, x.Find(&forks, &Repository{ForkID: repo.ID})
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/git"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
)
|
||||
@@ -100,7 +99,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
|
||||
actEmail = cmt.Committer.Email
|
||||
}
|
||||
|
||||
commit := &base.PushCommits{}
|
||||
commit := &PushCommits{}
|
||||
|
||||
if err = CommitRepoAction(userID, user.Id, userName, actEmail,
|
||||
repo.ID, repoUserName, repoName, refName, commit, oldCommitID, newCommitID); err != nil {
|
||||
@@ -133,7 +132,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
|
||||
}
|
||||
|
||||
// Push commits.
|
||||
commits := make([]*base.PushCommit, 0)
|
||||
commits := make([]*PushCommit, 0)
|
||||
var actEmail string
|
||||
for e := l.Front(); e != nil; e = e.Next() {
|
||||
commit := e.Value.(*git.Commit)
|
||||
@@ -141,7 +140,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
|
||||
actEmail = commit.Committer.Email
|
||||
}
|
||||
commits = append(commits,
|
||||
&base.PushCommit{commit.ID.String(),
|
||||
&PushCommit{commit.ID.String(),
|
||||
commit.Message(),
|
||||
commit.Author.Email,
|
||||
commit.Author.Name,
|
||||
@@ -149,7 +148,7 @@ func Update(refName, oldCommitID, newCommitID, userName, repoUserName, repoName
|
||||
}
|
||||
|
||||
if err = CommitRepoAction(userID, user.Id, userName, actEmail,
|
||||
repo.ID, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits, ""}, oldCommitID, newCommitID); err != nil {
|
||||
repo.ID, repoUserName, repoName, refName, &PushCommits{l.Len(), commits, "", nil}, oldCommitID, newCommitID); err != nil {
|
||||
return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"image"
|
||||
"image/jpeg"
|
||||
_ "image/jpeg"
|
||||
"image/png"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -108,6 +109,12 @@ func (u *User) AfterSet(colName string, _ xorm.Cell) {
|
||||
}
|
||||
}
|
||||
|
||||
// HasForkedRepo checks if user has already forked a repository with given ID.
|
||||
func (u *User) HasForkedRepo(repoID int64) bool {
|
||||
_, has := HasForkedRepo(u.Id, repoID)
|
||||
return has
|
||||
}
|
||||
|
||||
// CanEditGitHook returns true if user can edit Git hooks.
|
||||
func (u *User) CanEditGitHook() bool {
|
||||
return u.IsAdmin || u.AllowGitHook
|
||||
@@ -253,14 +260,12 @@ func (u *User) ValidatePassword(passwd string) bool {
|
||||
// UploadAvatar saves custom avatar for user.
|
||||
// FIXME: split uploads to different subdirs in case we have massive users.
|
||||
func (u *User) UploadAvatar(data []byte) error {
|
||||
u.UseCustomAvatar = true
|
||||
|
||||
img, _, err := image.Decode(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("Decode: %v", err)
|
||||
}
|
||||
|
||||
m := resize.Resize(234, 234, img, resize.NearestNeighbor)
|
||||
m := resize.Resize(290, 290, img, resize.NearestNeighbor)
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
@@ -268,19 +273,20 @@ func (u *User) UploadAvatar(data []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Id(u.Id).AllCols().Update(u); err != nil {
|
||||
return err
|
||||
u.UseCustomAvatar = true
|
||||
if err = updateUser(sess, u); err != nil {
|
||||
return fmt.Errorf("updateUser: %v", err)
|
||||
}
|
||||
|
||||
os.MkdirAll(setting.AvatarUploadPath, os.ModePerm)
|
||||
fw, err := os.Create(u.CustomAvatarPath())
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("Create: %v", err)
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
if err = jpeg.Encode(fw, m, nil); err != nil {
|
||||
return err
|
||||
if err = png.Encode(fw, m); err != nil {
|
||||
return fmt.Errorf("Encode: %v", err)
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
@@ -367,6 +373,15 @@ func (u *User) DisplayName() string {
|
||||
return u.Name
|
||||
}
|
||||
|
||||
// ShortName returns shorted user name with given maximum length,
|
||||
// it adds "..." at the end if user name has more length than maximum.
|
||||
func (u *User) ShortName(length int) string {
|
||||
if len(u.Name) < length {
|
||||
return u.Name
|
||||
}
|
||||
return u.Name[:length] + "..."
|
||||
}
|
||||
|
||||
// IsUserExist checks if given user name exist,
|
||||
// the user name should be noncased unique.
|
||||
// If uid is presented, then check will rule out that one,
|
||||
@@ -991,7 +1006,7 @@ func GetUserByEmail(email string) (*User, error) {
|
||||
return GetUserByID(emailAddress.UID)
|
||||
}
|
||||
|
||||
return nil, ErrUserNotExist{0, "email"}
|
||||
return nil, ErrUserNotExist{0, email}
|
||||
}
|
||||
|
||||
// SearchUserByName returns given number of users whose name contains keyword.
|
||||
|
||||
@@ -178,8 +178,8 @@ func GetActiveWebhooksByRepoID(repoID int64) (ws []*Webhook, err error) {
|
||||
return ws, err
|
||||
}
|
||||
|
||||
// GetWebhooksByRepoId returns all webhooks of repository.
|
||||
func GetWebhooksByRepoId(repoID int64) (ws []*Webhook, err error) {
|
||||
// GetWebhooksByRepoID returns all webhooks of repository.
|
||||
func GetWebhooksByRepoID(repoID int64) (ws []*Webhook, err error) {
|
||||
err = x.Find(&ws, &Webhook{RepoID: repoID})
|
||||
return ws, err
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
// \/ /_____/ \/ \/ \/ \/ \/
|
||||
|
||||
type CreateOrgForm struct {
|
||||
OrgName string `binding:"Required;AlphaDashDot;MaxSize(30)" locale:"org.org_name_holder"`
|
||||
OrgName string `binding:"Required;AlphaDashDot;MaxSize(35)" locale:"org.org_name_holder"`
|
||||
}
|
||||
|
||||
func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
@@ -25,7 +25,7 @@ func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) bind
|
||||
}
|
||||
|
||||
type UpdateOrgSettingForm struct {
|
||||
Name string `binding:"Required;AlphaDashDot;MaxSize(30)" locale:"org.org_name_holder"`
|
||||
Name string `binding:"Required;AlphaDashDot;MaxSize(35)" locale:"org.org_name_holder"`
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
Website string `binding:"Url;MaxSize(100)"`
|
||||
|
||||
@@ -215,12 +215,12 @@ func (f *CreateLabelForm) Validate(ctx *macaron.Context, errs binding.Errors) bi
|
||||
// \/ \/ \/ \/ \/ \/
|
||||
|
||||
type NewReleaseForm struct {
|
||||
TagName string `form:"tag_name" binding:"Required"`
|
||||
TagName string `binding:"Required"`
|
||||
Target string `form:"tag_target" binding:"Required"`
|
||||
Title string `form:"title" binding:"Required"`
|
||||
Content string `form:"content" binding:"Required"`
|
||||
Draft string `form:"draft"`
|
||||
Prerelease bool `form:"prerelease"`
|
||||
Title string `binding:"Required"`
|
||||
Content string
|
||||
Draft string
|
||||
Prerelease bool
|
||||
}
|
||||
|
||||
func (f *NewReleaseForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
|
||||
@@ -39,6 +39,8 @@ import (
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
//FIXME: remove cache module
|
||||
|
||||
var gravatarSource string
|
||||
|
||||
func UpdateGravatarSource() {
|
||||
@@ -102,7 +104,7 @@ func New(hash string, cacheDir string) *Avatar {
|
||||
expireDuration: time.Minute * 10,
|
||||
reqParams: url.Values{
|
||||
"d": {"retro"},
|
||||
"size": {"200"},
|
||||
"size": {"290"},
|
||||
"r": {"pg"}}.Encode(),
|
||||
imagePath: filepath.Join(cacheDir, hash+".image"), //maybe png or jpeg
|
||||
}
|
||||
@@ -153,7 +155,7 @@ func (this *Avatar) Encode(wr io.Writer, size int) (err error) {
|
||||
if img, err = decodeImageFile(imgPath); err != nil {
|
||||
return
|
||||
}
|
||||
m := resize.Resize(uint(size), 0, img, resize.NearestNeighbor)
|
||||
m := resize.Resize(uint(size), 0, img, resize.Lanczos3)
|
||||
return jpeg.Encode(wr, m, nil)
|
||||
}
|
||||
|
||||
@@ -192,7 +194,7 @@ func (this *service) mustInt(r *http.Request, defaultValue int, keys ...string)
|
||||
func (this *service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
urlPath := r.URL.Path
|
||||
hash := urlPath[strings.LastIndex(urlPath, "/")+1:]
|
||||
size := this.mustInt(r, 80, "s", "size") // default size = 80*80
|
||||
size := this.mustInt(r, 290, "s", "size") // default size = 290*290
|
||||
|
||||
avatar := New(hash, this.cacheDir)
|
||||
avatar.AlterImage = this.altImage
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/russross/blackfriday"
|
||||
"golang.org/x/net/html"
|
||||
|
||||
@@ -99,13 +100,26 @@ func (options *CustomRender) Link(out *bytes.Buffer, link []byte, title []byte,
|
||||
options.Renderer.Link(out, link, title, content)
|
||||
}
|
||||
|
||||
var (
|
||||
svgSuffix = []byte(".svg")
|
||||
svgSuffixWithMark = []byte(".svg?")
|
||||
)
|
||||
|
||||
func (options *CustomRender) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
|
||||
prefix := strings.Replace(options.urlPrefix, "/src/", "/raw/", 1)
|
||||
if len(link) > 0 && !isLink(link) {
|
||||
if link[0] != '/' {
|
||||
prefix += "/"
|
||||
if len(link) > 0 {
|
||||
if isLink(link) {
|
||||
// External link with .svg suffix usually means CI status.
|
||||
if bytes.HasSuffix(link, svgSuffix) || bytes.Contains(link, svgSuffixWithMark) {
|
||||
options.Renderer.Image(out, link, title, alt)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if link[0] != '/' {
|
||||
prefix += "/"
|
||||
}
|
||||
link = []byte(prefix + string(link))
|
||||
}
|
||||
link = []byte(prefix + string(link))
|
||||
}
|
||||
|
||||
out.WriteString(`<a href="`)
|
||||
@@ -167,7 +181,21 @@ func RenderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
|
||||
return rawBytes
|
||||
}
|
||||
|
||||
func cutoutVerbosePrefix(prefix string) string {
|
||||
count := 0
|
||||
for i := 0; i < len(prefix); i++ {
|
||||
if prefix[i] == '/' {
|
||||
count++
|
||||
}
|
||||
if count >= 3 {
|
||||
return prefix[:i]
|
||||
}
|
||||
}
|
||||
return prefix
|
||||
}
|
||||
|
||||
func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string) []byte {
|
||||
urlPrefix = cutoutVerbosePrefix(urlPrefix)
|
||||
ms := issueIndexPattern.FindAll(rawBytes, -1)
|
||||
for _, m := range ms {
|
||||
var space string
|
||||
@@ -217,11 +245,21 @@ func RenderRawMarkdown(body []byte, urlPrefix string) []byte {
|
||||
return body
|
||||
}
|
||||
|
||||
var (
|
||||
leftAngleBracket = []byte("</")
|
||||
rightAngleBracket = []byte(">")
|
||||
)
|
||||
|
||||
var noEndTags = []string{"img", "input", "br", "hr"}
|
||||
|
||||
// PostProcessMarkdown treats different types of HTML differently,
|
||||
// and only renders special links for plain text blocks.
|
||||
func PostProcessMarkdown(rawHtml []byte, urlPrefix string) []byte {
|
||||
startTags := make([]string, 0, 5)
|
||||
var buf bytes.Buffer
|
||||
tokenizer := html.NewTokenizer(bytes.NewReader(rawHtml))
|
||||
|
||||
OUTER_LOOP:
|
||||
for html.ErrorToken != tokenizer.Next() {
|
||||
token := tokenizer.Token()
|
||||
switch token.Type {
|
||||
@@ -235,15 +273,26 @@ func PostProcessMarkdown(rawHtml []byte, urlPrefix string) []byte {
|
||||
if strings.EqualFold("a", tagName) || strings.EqualFold("code", tagName) || strings.EqualFold("pre", tagName) {
|
||||
for html.ErrorToken != tokenizer.Next() {
|
||||
token = tokenizer.Token()
|
||||
|
||||
// Copy the token to the output verbatim
|
||||
buf.WriteString(token.String())
|
||||
// If this is the close tag, we are done
|
||||
if html.EndTagToken == token.Type && strings.EqualFold(tagName, token.Data) {
|
||||
if token.Type == html.EndTagToken && strings.EqualFold(tagName, token.Data) {
|
||||
break
|
||||
}
|
||||
}
|
||||
continue OUTER_LOOP
|
||||
}
|
||||
|
||||
if !com.IsSliceContainsStr(noEndTags, token.Data) {
|
||||
startTags = append(startTags, token.Data)
|
||||
}
|
||||
|
||||
case html.EndTagToken:
|
||||
buf.Write(leftAngleBracket)
|
||||
buf.WriteString(startTags[len(startTags)-1])
|
||||
buf.Write(rightAngleBracket)
|
||||
startTags = startTags[:len(startTags)-1]
|
||||
default:
|
||||
buf.WriteString(token.String())
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import (
|
||||
"github.com/Unknwon/i18n"
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
|
||||
"github.com/gogits/chardet"
|
||||
|
||||
"github.com/gogits/gogs/modules/avatar"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
@@ -43,6 +45,22 @@ func EncodeSha1(str string) string {
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
func ShortSha(sha1 string) string {
|
||||
if len(sha1) == 40 {
|
||||
return sha1[:10]
|
||||
}
|
||||
return sha1
|
||||
}
|
||||
|
||||
func DetectEncoding(content []byte) (string, error) {
|
||||
detector := chardet.NewTextDetector()
|
||||
result, err := detector.DetectBest(content)
|
||||
if result.Charset != "UTF-8" && len(setting.Repository.AnsiCharset) > 0 {
|
||||
return setting.Repository.AnsiCharset, err
|
||||
}
|
||||
return result.Charset, err
|
||||
}
|
||||
|
||||
func BasicAuthDecode(encoded string) (string, string, error) {
|
||||
s, err := base64.StdEncoding.DecodeString(encoded)
|
||||
if err != nil {
|
||||
|
||||
File diff suppressed because one or more lines are too long
22
modules/git/error.go
Normal file
22
modules/git/error.go
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package git
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ErrUnsupportedVersion struct {
|
||||
Required string
|
||||
}
|
||||
|
||||
func IsErrUnsupportedVersion(err error) bool {
|
||||
_, ok := err.(ErrUnsupportedVersion)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUnsupportedVersion) Error() string {
|
||||
return fmt.Sprintf("Operation requires higher version [required: %s]", err.Required)
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
@@ -21,6 +22,8 @@ func OpenRepository(repoPath string) (*Repository, error) {
|
||||
repoPath, err := filepath.Abs(repoPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !isDir(repoPath) {
|
||||
return nil, errors.New("no such file or directory")
|
||||
}
|
||||
|
||||
return &Repository{Path: repoPath}, nil
|
||||
|
||||
@@ -35,3 +35,16 @@ func (repo *Repository) GetBranches() ([]string, error) {
|
||||
}
|
||||
return branches, nil
|
||||
}
|
||||
|
||||
// SetDefaultBranch sets default branch of repository.
|
||||
func (repo *Repository) SetDefaultBranch(branchName string) error {
|
||||
if gitVer.LessThan(MustParseVersion("1.7.10")) {
|
||||
return ErrUnsupportedVersion{"1.7.10"}
|
||||
}
|
||||
|
||||
_, stderr, err := com.ExecCmdDir(repo.Path, "git", "symbolic-ref", "HEAD", "refs/heads/"+branchName)
|
||||
if err != nil {
|
||||
return concatenateError(err, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ func (repo *Repository) GetPullRequestInfo(basePath, baseBranch, headBranch stri
|
||||
|
||||
// GetPatch generates and returns patch data between given branches.
|
||||
func (repo *Repository) GetPatch(mergeBase, headBranch string) ([]byte, error) {
|
||||
stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "diff", "-p", mergeBase, headBranch)
|
||||
stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "diff", "-p", "--binary", mergeBase, headBranch)
|
||||
if err != nil {
|
||||
return nil, concatenateError(err, string(stderr))
|
||||
}
|
||||
|
||||
@@ -28,6 +28,27 @@ type Tree struct {
|
||||
entriesParsed bool
|
||||
}
|
||||
|
||||
var escapeChar = []byte("\\")
|
||||
|
||||
func UnescapeChars(in []byte) []byte {
|
||||
if bytes.Index(in, escapeChar) == -1 {
|
||||
return in
|
||||
}
|
||||
|
||||
endIdx := len(in) - 1
|
||||
isEscape := false
|
||||
out := make([]byte, 0, endIdx+1)
|
||||
for i := range in {
|
||||
if in[i] == '\\' && !isEscape {
|
||||
isEscape = true
|
||||
continue
|
||||
}
|
||||
isEscape = false
|
||||
out = append(out, in[i])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Parse tree information from the (uncompressed) raw
|
||||
// data from the tree object.
|
||||
func parseTreeData(tree *Tree, data []byte) ([]*TreeEntry, error) {
|
||||
@@ -70,12 +91,12 @@ func parseTreeData(tree *Tree, data []byte) ([]*TreeEntry, error) {
|
||||
pos += step + 1 // Skip half of sha1.
|
||||
|
||||
step = bytes.IndexByte(data[pos:], '\n')
|
||||
entry.name = string(data[pos : pos+step])
|
||||
|
||||
// In case entry name is surrounded by double quotes(it happens only in git-shell).
|
||||
if entry.name[0] == '"' {
|
||||
entry.name = string(data[pos+1 : pos+step-1])
|
||||
entry.name = strings.Replace(entry.name, `\"`, `"`, -1)
|
||||
if data[pos] == '"' {
|
||||
entry.name = string(UnescapeChars(data[pos+1 : pos+step-1]))
|
||||
} else {
|
||||
entry.name = string(data[pos : pos+step])
|
||||
}
|
||||
|
||||
pos += step + 1
|
||||
|
||||
@@ -35,6 +35,11 @@ func parsePrettyFormatLog(repo *Repository, logByts []byte) (*list.List, error)
|
||||
}
|
||||
|
||||
func RefEndName(refStr string) string {
|
||||
if strings.HasPrefix(refStr, "refs/heads/") {
|
||||
// trim the "refs/heads/"
|
||||
return refStr[len("refs/heads/"):]
|
||||
}
|
||||
|
||||
index := strings.LastIndex(refStr, "/")
|
||||
if index != -1 {
|
||||
return refStr[index+1:]
|
||||
|
||||
@@ -109,6 +109,18 @@ func Toggle(options *ToggleOptions) macaron.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
// Try auto-signin when not signed in.
|
||||
if !options.SignOutRequire && !ctx.IsSigned && !auth.IsAPIPath(ctx.Req.URL.Path) {
|
||||
succeed, err := AutoSignIn(ctx)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "AutoSignIn", err)
|
||||
return
|
||||
} else if succeed {
|
||||
ctx.Redirect(setting.AppSubUrl + ctx.Req.RequestURI)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if options.AdminRequire {
|
||||
if !ctx.User.IsAdmin {
|
||||
ctx.Error(403)
|
||||
|
||||
@@ -205,18 +205,10 @@ func Contexter() macaron.Handler {
|
||||
Session: sess,
|
||||
}
|
||||
// Compute current URL for real-time change language.
|
||||
ctx.Data["Link"] = setting.AppSubUrl + ctx.Req.URL.Path
|
||||
ctx.Data["Link"] = setting.AppSubUrl + strings.TrimSuffix(ctx.Req.URL.Path, "/")
|
||||
|
||||
ctx.Data["PageStartTime"] = time.Now()
|
||||
|
||||
// Check auto-signin.
|
||||
if sess.Get("uid") == nil {
|
||||
if _, err := AutoSignIn(ctx); err != nil {
|
||||
ctx.Handle(500, "AutoSignIn", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Get user from session if logined.
|
||||
ctx.User, ctx.IsBasicAuth = auth.SignedInUser(ctx.Context, ctx.Session)
|
||||
|
||||
@@ -245,6 +237,7 @@ func Contexter() macaron.Handler {
|
||||
|
||||
ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton
|
||||
ctx.Data["ShowFooterBranding"] = setting.ShowFooterBranding
|
||||
ctx.Data["ShowFooterVersion"] = setting.ShowFooterVersion
|
||||
|
||||
c.Map(ctx)
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/mcuadros/go-version"
|
||||
"github.com/mssola/user_agent"
|
||||
"gopkg.in/macaron.v1"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
@@ -20,11 +18,6 @@ import (
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
FIREFOX_COPY_SUPPORT = "41.0"
|
||||
CHROME_COPY_SUPPORT = "43.0.2356"
|
||||
)
|
||||
|
||||
func ApiRepoAssignment() macaron.Handler {
|
||||
return func(ctx *Context) {
|
||||
userName := ctx.Params(":username")
|
||||
@@ -86,6 +79,11 @@ func ApiRepoAssignment() macaron.Handler {
|
||||
// RepoRef handles repository reference name including those contain `/`.
|
||||
func RepoRef() macaron.Handler {
|
||||
return func(ctx *Context) {
|
||||
// Empty repository does not have reference information.
|
||||
if ctx.Repo.Repository.IsBare {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
refName string
|
||||
err error
|
||||
@@ -276,19 +274,23 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
return
|
||||
}
|
||||
|
||||
mode, err := models.AccessLevel(ctx.User, repo)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "AccessLevel", err)
|
||||
return
|
||||
// Admin has super access.
|
||||
if ctx.IsSigned && ctx.User.IsAdmin {
|
||||
ctx.Repo.AccessMode = models.ACCESS_MODE_OWNER
|
||||
} else {
|
||||
mode, err := models.AccessLevel(ctx.User, repo)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "AccessLevel", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.AccessMode = mode
|
||||
}
|
||||
ctx.Repo.AccessMode = mode
|
||||
|
||||
// Check access.
|
||||
if ctx.Repo.AccessMode == models.ACCESS_MODE_NONE {
|
||||
ctx.Handle(404, "no access right", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["HasAccess"] = true
|
||||
|
||||
if repo.IsMirror {
|
||||
@@ -393,13 +395,6 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
||||
ctx.Data["GoDocDirectory"] = prefix + "{/dir}"
|
||||
ctx.Data["GoDocFile"] = prefix + "{/dir}/{file}#L{line}"
|
||||
}
|
||||
|
||||
userAgent := ctx.Req.Header.Get("User-Agent")
|
||||
ua := user_agent.New(userAgent)
|
||||
browserName, browserVer := ua.Browser()
|
||||
|
||||
ctx.Data["BrowserSupportsCopy"] = (browserName == "Chrome" && version.Compare(browserVer, CHROME_COPY_SUPPORT, ">=")) ||
|
||||
(browserName == "Firefox" && version.Compare(browserVer, FIREFOX_COPY_SUPPORT, ">="))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -178,6 +178,7 @@ var (
|
||||
|
||||
// Other settings.
|
||||
ShowFooterBranding bool
|
||||
ShowFooterVersion bool
|
||||
|
||||
// Global setting objects.
|
||||
Cfg *ini.File
|
||||
@@ -425,6 +426,7 @@ func NewContext() {
|
||||
dateLangs = Cfg.Section("i18n.datelang").KeysHash()
|
||||
|
||||
ShowFooterBranding = Cfg.Section("other").Key("SHOW_FOOTER_BRANDING").MustBool()
|
||||
ShowFooterVersion = Cfg.Section("other").Key("SHOW_FOOTER_VERSION").MustBool()
|
||||
|
||||
HasRobotsTxt = com.IsFile(path.Join(CustomPath, "robots.txt"))
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
@@ -82,14 +83,17 @@ func handleServerConn(keyID string, chans <-chan ssh.NewChannel) {
|
||||
return
|
||||
}
|
||||
|
||||
go io.Copy(ch, stdout)
|
||||
go io.Copy(ch.Stderr(), stderr)
|
||||
go io.Copy(input, ch)
|
||||
|
||||
// FIXME: check timeout
|
||||
if err = cmd.Start(); err != nil {
|
||||
log.Error(3, "Start: %v", err)
|
||||
return
|
||||
} else if err = cmd.Wait(); err != nil {
|
||||
}
|
||||
|
||||
go io.Copy(input, ch)
|
||||
io.Copy(ch, stdout)
|
||||
io.Copy(ch.Stderr(), stderr)
|
||||
|
||||
if err = cmd.Wait(); err != nil {
|
||||
log.Error(3, "Wait: %v", err)
|
||||
return
|
||||
}
|
||||
@@ -142,7 +146,16 @@ func Listen(port int) {
|
||||
},
|
||||
}
|
||||
|
||||
privateBytes, err := ioutil.ReadFile(filepath.Join(models.SSHPath, "id_rsa"))
|
||||
keyPath := filepath.Join(setting.AppDataPath, "ssh/gogs.rsa")
|
||||
if !com.IsExist(keyPath) {
|
||||
os.MkdirAll(filepath.Dir(keyPath), os.ModePerm)
|
||||
_, stderr, err := com.ExecCmd("ssh-keygen", "-f", keyPath, "-t", "rsa", "-N", "")
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Fail to generate private key: %v - %s", err, stderr))
|
||||
}
|
||||
}
|
||||
|
||||
privateBytes, err := ioutil.ReadFile(keyPath)
|
||||
if err != nil {
|
||||
panic("Fail to load private key")
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package base
|
||||
package template
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
@@ -16,16 +16,90 @@ import (
|
||||
"golang.org/x/net/html/charset"
|
||||
"golang.org/x/text/transform"
|
||||
|
||||
"github.com/gogits/chardet"
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
var Funcs template.FuncMap = map[string]interface{}{
|
||||
"GoVer": func() string {
|
||||
return strings.Title(runtime.Version())
|
||||
},
|
||||
"AppName": func() string {
|
||||
return setting.AppName
|
||||
},
|
||||
"AppSubUrl": func() string {
|
||||
return setting.AppSubUrl
|
||||
},
|
||||
"AppVer": func() string {
|
||||
return setting.AppVer
|
||||
},
|
||||
"AppDomain": func() string {
|
||||
return setting.Domain
|
||||
},
|
||||
"DisableGravatar": func() bool {
|
||||
return setting.DisableGravatar
|
||||
},
|
||||
"LoadTimes": func(startTime time.Time) string {
|
||||
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
|
||||
},
|
||||
"AvatarLink": base.AvatarLink,
|
||||
"Safe": Safe,
|
||||
"Str2html": Str2html,
|
||||
"TimeSince": base.TimeSince,
|
||||
"RawTimeSince": base.RawTimeSince,
|
||||
"FileSize": base.FileSize,
|
||||
"Subtract": base.Subtract,
|
||||
"Add": func(a, b int) int {
|
||||
return a + b
|
||||
},
|
||||
"ActionIcon": ActionIcon,
|
||||
"DateFmtLong": func(t time.Time) string {
|
||||
return t.Format(time.RFC1123Z)
|
||||
},
|
||||
"DateFmtShort": func(t time.Time) string {
|
||||
return t.Format("Jan 02, 2006")
|
||||
},
|
||||
"List": List,
|
||||
"Mail2Domain": func(mail string) string {
|
||||
if !strings.Contains(mail, "@") {
|
||||
return "try.gogs.io"
|
||||
}
|
||||
|
||||
return strings.SplitN(mail, "@", 2)[1]
|
||||
},
|
||||
"SubStr": func(str string, start, length int) string {
|
||||
if len(str) == 0 {
|
||||
return ""
|
||||
}
|
||||
end := start + length
|
||||
if length == -1 {
|
||||
end = len(str)
|
||||
}
|
||||
if len(str) < end {
|
||||
return str
|
||||
}
|
||||
return str[start:end]
|
||||
},
|
||||
"DiffTypeToStr": DiffTypeToStr,
|
||||
"DiffLineTypeToStr": DiffLineTypeToStr,
|
||||
"Sha1": Sha1,
|
||||
"ShortSha": base.ShortSha,
|
||||
"Md5": base.EncodeMd5,
|
||||
"ActionContent2Commits": ActionContent2Commits,
|
||||
"ToUtf8": ToUtf8,
|
||||
"EscapePound": func(str string) string {
|
||||
return strings.Replace(strings.Replace(str, "%", "%25", -1), "#", "%23", -1)
|
||||
},
|
||||
"RenderCommitMessage": RenderCommitMessage,
|
||||
}
|
||||
|
||||
func Safe(raw string) template.HTML {
|
||||
return template.HTML(raw)
|
||||
}
|
||||
|
||||
func Str2html(raw string) template.HTML {
|
||||
return template.HTML(Sanitizer.Sanitize(raw))
|
||||
return template.HTML(base.Sanitizer.Sanitize(raw))
|
||||
}
|
||||
|
||||
func Range(l int) []int {
|
||||
@@ -46,27 +120,11 @@ func List(l *list.List) chan interface{} {
|
||||
}
|
||||
|
||||
func Sha1(str string) string {
|
||||
return EncodeSha1(str)
|
||||
}
|
||||
|
||||
func ShortSha(sha1 string) string {
|
||||
if len(sha1) == 40 {
|
||||
return sha1[:10]
|
||||
}
|
||||
return sha1
|
||||
}
|
||||
|
||||
func DetectEncoding(content []byte) (string, error) {
|
||||
detector := chardet.NewTextDetector()
|
||||
result, err := detector.DetectBest(content)
|
||||
if result.Charset != "UTF-8" && len(setting.Repository.AnsiCharset) > 0 {
|
||||
return setting.Repository.AnsiCharset, err
|
||||
}
|
||||
return result.Charset, err
|
||||
return base.EncodeSha1(str)
|
||||
}
|
||||
|
||||
func ToUtf8WithErr(content []byte) (error, string) {
|
||||
charsetLabel, err := DetectEncoding(content)
|
||||
charsetLabel, err := base.DetectEncoding(content)
|
||||
if err != nil {
|
||||
return err, ""
|
||||
}
|
||||
@@ -124,7 +182,7 @@ func ReplaceLeft(s, old, new string) string {
|
||||
// RenderCommitMessage renders commit message with XSS-safe and special links.
|
||||
func RenderCommitMessage(msg, urlPrefix string) template.HTML {
|
||||
cleanMsg := template.HTMLEscapeString(msg)
|
||||
fullMessage := string(RenderIssueIndexPattern([]byte(cleanMsg), urlPrefix))
|
||||
fullMessage := string(base.RenderIssueIndexPattern([]byte(cleanMsg), urlPrefix))
|
||||
msgLines := strings.Split(strings.TrimSpace(fullMessage), "\n")
|
||||
for i := range msgLines {
|
||||
msgLines[i] = ReplaceLeft(msgLines[i], " ", " ")
|
||||
@@ -134,81 +192,6 @@ func RenderCommitMessage(msg, urlPrefix string) template.HTML {
|
||||
return template.HTML(fullMessage)
|
||||
}
|
||||
|
||||
var TemplateFuncs template.FuncMap = map[string]interface{}{
|
||||
"GoVer": func() string {
|
||||
return strings.Title(runtime.Version())
|
||||
},
|
||||
"AppName": func() string {
|
||||
return setting.AppName
|
||||
},
|
||||
"AppSubUrl": func() string {
|
||||
return setting.AppSubUrl
|
||||
},
|
||||
"AppVer": func() string {
|
||||
return setting.AppVer
|
||||
},
|
||||
"AppDomain": func() string {
|
||||
return setting.Domain
|
||||
},
|
||||
"DisableGravatar": func() bool {
|
||||
return setting.DisableGravatar
|
||||
},
|
||||
"LoadTimes": func(startTime time.Time) string {
|
||||
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
|
||||
},
|
||||
"AvatarLink": AvatarLink,
|
||||
"Safe": Safe,
|
||||
"Str2html": Str2html,
|
||||
"TimeSince": TimeSince,
|
||||
"RawTimeSince": RawTimeSince,
|
||||
"FileSize": FileSize,
|
||||
"Subtract": Subtract,
|
||||
"Add": func(a, b int) int {
|
||||
return a + b
|
||||
},
|
||||
"ActionIcon": ActionIcon,
|
||||
"DateFmtLong": func(t time.Time) string {
|
||||
return t.Format(time.RFC1123Z)
|
||||
},
|
||||
"DateFmtShort": func(t time.Time) string {
|
||||
return t.Format("Jan 02, 2006")
|
||||
},
|
||||
"List": List,
|
||||
"Mail2Domain": func(mail string) string {
|
||||
if !strings.Contains(mail, "@") {
|
||||
return "try.gogs.io"
|
||||
}
|
||||
|
||||
return strings.SplitN(mail, "@", 2)[1]
|
||||
},
|
||||
"SubStr": func(str string, start, length int) string {
|
||||
if len(str) == 0 {
|
||||
return ""
|
||||
}
|
||||
end := start + length
|
||||
if length == -1 {
|
||||
end = len(str)
|
||||
}
|
||||
if len(str) < end {
|
||||
return str
|
||||
}
|
||||
return str[start:end]
|
||||
},
|
||||
"DiffTypeToStr": DiffTypeToStr,
|
||||
"DiffLineTypeToStr": DiffLineTypeToStr,
|
||||
"Sha1": Sha1,
|
||||
"ShortSha": ShortSha,
|
||||
"Md5": EncodeMd5,
|
||||
"ActionContent2Commits": ActionContent2Commits,
|
||||
"Oauth2Icon": Oauth2Icon,
|
||||
"Oauth2Name": Oauth2Name,
|
||||
"ToUtf8": ToUtf8,
|
||||
"EscapePound": func(str string) string {
|
||||
return strings.Replace(strings.Replace(str, "%", "%25", -1), "#", "%23", -1)
|
||||
},
|
||||
"RenderCommitMessage": RenderCommitMessage,
|
||||
}
|
||||
|
||||
type Actioner interface {
|
||||
GetOpType() int
|
||||
GetActUserName() string
|
||||
@@ -227,35 +210,26 @@ type Actioner interface {
|
||||
// and returns a icon class name.
|
||||
func ActionIcon(opType int) string {
|
||||
switch opType {
|
||||
case 1, 8: // Create, transfer repository.
|
||||
case 1, 8: // Create, transfer repository
|
||||
return "repo"
|
||||
case 5, 9: // Commit repository.
|
||||
case 5, 9: // Commit repository
|
||||
return "git-commit"
|
||||
case 6: // Create issue.
|
||||
case 6: // Create issue
|
||||
return "issue-opened"
|
||||
case 10: // Comment issue.
|
||||
case 7: // New pull request
|
||||
return "git-pull-request"
|
||||
case 10: // Comment issue
|
||||
return "comment"
|
||||
case 11: // Merge pull request
|
||||
return "git-merge"
|
||||
default:
|
||||
return "invalid type"
|
||||
}
|
||||
}
|
||||
|
||||
type PushCommit struct {
|
||||
Sha1 string
|
||||
Message string
|
||||
AuthorEmail string
|
||||
AuthorName string
|
||||
}
|
||||
|
||||
type PushCommits struct {
|
||||
Len int
|
||||
Commits []*PushCommit
|
||||
CompareUrl string
|
||||
}
|
||||
|
||||
func ActionContent2Commits(act Actioner) *PushCommits {
|
||||
var push *PushCommits
|
||||
if err := json.Unmarshal([]byte(act.GetContent()), &push); err != nil {
|
||||
func ActionContent2Commits(act Actioner) *models.PushCommits {
|
||||
push := models.NewPushCommits()
|
||||
if err := json.Unmarshal([]byte(act.GetContent()), push); err != nil {
|
||||
return nil
|
||||
}
|
||||
return push
|
||||
@@ -279,35 +253,3 @@ func DiffLineTypeToStr(diffType int) string {
|
||||
}
|
||||
return "same"
|
||||
}
|
||||
|
||||
func Oauth2Icon(t int) string {
|
||||
switch t {
|
||||
case 1:
|
||||
return "fa-github-square"
|
||||
case 2:
|
||||
return "fa-google-plus-square"
|
||||
case 3:
|
||||
return "fa-twitter-square"
|
||||
case 4:
|
||||
return "fa-qq"
|
||||
case 5:
|
||||
return "fa-weibo"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func Oauth2Name(t int) string {
|
||||
switch t {
|
||||
case 1:
|
||||
return "GitHub"
|
||||
case 2:
|
||||
return "Google+"
|
||||
case 3:
|
||||
return "Twitter"
|
||||
case 4:
|
||||
return "腾讯 QQ"
|
||||
case 5:
|
||||
return "Weibo"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -56,6 +56,15 @@
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0
|
||||
},
|
||||
"\/css\/highlight-8.7\/github.css": {
|
||||
"fileType": 16,
|
||||
"ignore": 0,
|
||||
"ignoreWasSetByUser": 0,
|
||||
"inputAbbreviatedPath": "\/css\/highlight-8.7\/github.css",
|
||||
"outputAbbreviatedPath": "No Output Path",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0
|
||||
},
|
||||
"\/css\/jquery.datetimepicker-2.4.5.css": {
|
||||
"fileType": 16,
|
||||
"ignore": 0,
|
||||
@@ -281,6 +290,17 @@
|
||||
"outputPathIsSetByUser": 0,
|
||||
"processed": 0
|
||||
},
|
||||
"\/js\/min\/gogs-min.js": {
|
||||
"fileType": 64,
|
||||
"ignore": 1,
|
||||
"ignoreWasSetByUser": 0,
|
||||
"inputAbbreviatedPath": "\/js\/min\/gogs-min.js",
|
||||
"outputAbbreviatedPath": "\/js\/min\/min\/gogs-min-min.js",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0,
|
||||
"outputStyle": 1,
|
||||
"syntaxCheckerStyle": 1
|
||||
},
|
||||
"\/js\/semantic-2.1.5.min.js": {
|
||||
"fileType": 64,
|
||||
"ignore": 0,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@font-face {
|
||||
font-family: 'octicons';
|
||||
src: url('../fonts/octicons.eot?#iefix&v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d') format('embedded-opentype'), url('../fonts/octicons.woff?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d') format('woff'), url('../fonts/octicons.ttf?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d') format('truetype'), url('../fonts/octicons.svg?v=396334ee3da78f4302d25c758ae3e3ce5dc3c97d#octicons') format('svg');
|
||||
src: url('../fonts/octicons.eot?#iefix&v=30e752e9a0821a0a098947055eeece0b0f46bc34') format('embedded-opentype'), url('../fonts/octicons.woff?v=30e752e9a0821a0a098947055eeece0b0f46bc34') format('woff'), url('../fonts/octicons.ttf?v=30e752e9a0821a0a098947055eeece0b0f46bc34') format('truetype'), url('../fonts/octicons.svg?v=30e752e9a0821a0a098947055eeece0b0f46bc34#octicons') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@@ -65,6 +65,10 @@
|
||||
content: '\f0de';
|
||||
}
|
||||
/* */
|
||||
.octicon-bold:before {
|
||||
content: '\f0e2';
|
||||
}
|
||||
/* */
|
||||
.octicon-book:before {
|
||||
content: '\f007';
|
||||
}
|
||||
@@ -364,6 +368,10 @@
|
||||
content: '\f027';
|
||||
}
|
||||
/* */
|
||||
.octicon-italic:before {
|
||||
content: '\f0e4';
|
||||
}
|
||||
/* */
|
||||
.octicon-jersey:before {
|
||||
content: '\f019';
|
||||
}
|
||||
@@ -411,6 +419,10 @@
|
||||
content: '\f06a';
|
||||
}
|
||||
/* */
|
||||
.octicon-logo-gist:before {
|
||||
content: '\f0ad';
|
||||
}
|
||||
/* */
|
||||
.octicon-logo-github:before {
|
||||
content: '\f092';
|
||||
}
|
||||
@@ -568,14 +580,6 @@
|
||||
content: '\f047';
|
||||
}
|
||||
/* */
|
||||
.octicon-screen-full:before {
|
||||
content: '\f066';
|
||||
}
|
||||
/* */
|
||||
.octicon-screen-normal:before {
|
||||
content: '\f067';
|
||||
}
|
||||
/* */
|
||||
.octicon-search-save:before,
|
||||
.octicon-search:before {
|
||||
content: '\f02e';
|
||||
@@ -628,6 +632,10 @@
|
||||
content: '\f015';
|
||||
}
|
||||
/* */
|
||||
.octicon-tasklist:before {
|
||||
content: '\f0e5';
|
||||
}
|
||||
/* */
|
||||
.octicon-telescope:before {
|
||||
content: '\f088';
|
||||
}
|
||||
@@ -636,6 +644,10 @@
|
||||
content: '\f0c8';
|
||||
}
|
||||
/* */
|
||||
.octicon-text-size:before {
|
||||
content: '\f0e3';
|
||||
}
|
||||
/* */
|
||||
.octicon-three-bars:before {
|
||||
content: '\f05e';
|
||||
}
|
||||
@@ -759,7 +771,7 @@ pre.raw {
|
||||
z-index: 900;
|
||||
}
|
||||
.following.bar .head.link.item {
|
||||
padding-right: 0!important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
.following.bar .head.link.item .dropdown.icon,
|
||||
.following.bar .head.link.item .menu .octicon {
|
||||
@@ -792,50 +804,71 @@ pre.raw {
|
||||
float: right;
|
||||
}
|
||||
.ui .text.red {
|
||||
color: #d95c5c!important;
|
||||
color: #d95c5c !important;
|
||||
}
|
||||
.ui .text.red a {
|
||||
color: #d95c5c!important;
|
||||
color: #d95c5c !important;
|
||||
}
|
||||
.ui .text.red a:hover {
|
||||
color: #E67777!important;
|
||||
color: #E67777 !important;
|
||||
}
|
||||
.ui .text.blue {
|
||||
color: #428bca!important;
|
||||
color: #428bca !important;
|
||||
}
|
||||
.ui .text.blue a {
|
||||
color: #15c!important;
|
||||
color: #15c !important;
|
||||
}
|
||||
.ui .text.blue a:hover {
|
||||
color: #428bca!important;
|
||||
color: #428bca !important;
|
||||
}
|
||||
.ui .text.black {
|
||||
color: #444;
|
||||
}
|
||||
.ui .text.black:hover {
|
||||
color: #000;
|
||||
}
|
||||
.ui .text.grey {
|
||||
color: #767676!important;
|
||||
color: #767676 !important;
|
||||
}
|
||||
.ui .text.grey a {
|
||||
color: #444!important;
|
||||
color: #444 !important;
|
||||
}
|
||||
.ui .text.grey a:hover {
|
||||
color: #000!important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.ui .text.light.grey {
|
||||
color: #888 !important;
|
||||
}
|
||||
.ui .text.green {
|
||||
color: #6cc644!important;
|
||||
color: #6cc644 !important;
|
||||
}
|
||||
.ui .text.purple {
|
||||
color: #6e5494!important;
|
||||
color: #6e5494 !important;
|
||||
}
|
||||
.ui .text.yellow {
|
||||
color: #FBBD08!important;
|
||||
color: #FBBD08 !important;
|
||||
}
|
||||
.ui .text.gold {
|
||||
color: #a1882b !important;
|
||||
}
|
||||
.ui .text.left {
|
||||
text-align: left!important;
|
||||
text-align: left !important;
|
||||
}
|
||||
.ui .text.right {
|
||||
text-align: right!important;
|
||||
text-align: right !important;
|
||||
}
|
||||
.ui .text.small {
|
||||
font-size: 0.75em;
|
||||
}
|
||||
.ui .text.normal {
|
||||
font-weight: normal;
|
||||
}
|
||||
.ui .text.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.ui .text.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
.ui .text.truncate {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -856,14 +889,14 @@ pre.raw {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.ui .warning.header {
|
||||
background-color: #F9EDBE!important;
|
||||
background-color: #F9EDBE !important;
|
||||
border-color: #F0C36D;
|
||||
}
|
||||
.ui .warning.segment {
|
||||
border-color: #F0C36D;
|
||||
}
|
||||
.ui .info.header {
|
||||
background-color: #d9edf7!important;
|
||||
background-color: #d9edf7 !important;
|
||||
border-color: #85c5e5;
|
||||
}
|
||||
.ui .info.segment {
|
||||
@@ -876,7 +909,7 @@ pre.raw {
|
||||
border-radius: 3px;
|
||||
}
|
||||
.ui .form .fake {
|
||||
display: none!important;
|
||||
display: none !important;
|
||||
}
|
||||
.ui.status.buttons .octicon {
|
||||
margin-right: 4px;
|
||||
@@ -894,7 +927,7 @@ pre.raw {
|
||||
border-top: none;
|
||||
line-height: 1em;
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
padding: .71428571em 1.14285714em!important;
|
||||
padding: .71428571em 1.14285714em !important;
|
||||
font-size: 1rem;
|
||||
text-transform: none;
|
||||
font-weight: 400;
|
||||
@@ -910,7 +943,7 @@ pre.raw {
|
||||
z-index: 13;
|
||||
}
|
||||
.scrolling.menu .item.selected {
|
||||
font-weight: 700!important;
|
||||
font-weight: 700 !important;
|
||||
}
|
||||
footer {
|
||||
margin-top: 54px !important;
|
||||
@@ -1010,7 +1043,7 @@ footer .container .links > *:first-child {
|
||||
.octicon.icon,
|
||||
.mega-octicon.icon {
|
||||
font-family: octicons;
|
||||
opacity: 1!important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
@@ -1040,9 +1073,12 @@ footer .container .links > *:first-child {
|
||||
overflow: hidden;
|
||||
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
line-height: 1.6 !important;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.markdown.file-view {
|
||||
padding: 5px 2em 2em !important;
|
||||
}
|
||||
.markdown > *:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
@@ -1176,6 +1212,9 @@ footer .container .links > *:first-child {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.markdown blockquote {
|
||||
margin-left: 0;
|
||||
}
|
||||
.markdown hr {
|
||||
height: 4px;
|
||||
padding: 0;
|
||||
@@ -1440,115 +1479,6 @@ footer .container .links > *:first-child {
|
||||
background: #f8f8f8;
|
||||
border-top: 0;
|
||||
}
|
||||
/* Author: jmblog */
|
||||
/* Project: https://github.com/jmblog/color-themes-for-google-code-prettify */
|
||||
/* GitHub Theme */
|
||||
/* Pretty printing styles. Used with prettify.js. */
|
||||
/* SPAN elements with the classes below are added by prettyprint. */
|
||||
/* plain text */
|
||||
.pln {
|
||||
color: #333333;
|
||||
}
|
||||
@media screen {
|
||||
/* string content */
|
||||
.str {
|
||||
color: #dd1144;
|
||||
}
|
||||
/* a keyword */
|
||||
.kwd {
|
||||
color: #333333;
|
||||
}
|
||||
/* a comment */
|
||||
.com {
|
||||
color: #999988;
|
||||
font-style: italic;
|
||||
}
|
||||
/* a type name */
|
||||
.typ {
|
||||
color: #445588;
|
||||
}
|
||||
/* a literal value */
|
||||
.lit {
|
||||
color: #445588;
|
||||
}
|
||||
/* punctuation */
|
||||
.pun {
|
||||
color: #333333;
|
||||
}
|
||||
/* lisp open bracket */
|
||||
.opn {
|
||||
color: #333333;
|
||||
}
|
||||
/* lisp close bracket */
|
||||
.clo {
|
||||
color: #333333;
|
||||
}
|
||||
/* a markup tag name */
|
||||
.tag {
|
||||
color: navy;
|
||||
}
|
||||
/* a markup attribute name */
|
||||
.atn {
|
||||
color: teal;
|
||||
}
|
||||
/* a markup attribute value */
|
||||
.atv {
|
||||
color: #dd1144;
|
||||
}
|
||||
/* a declaration */
|
||||
.dec {
|
||||
color: #333333;
|
||||
}
|
||||
/* a variable name */
|
||||
.var {
|
||||
color: teal;
|
||||
}
|
||||
/* a function name */
|
||||
.fun {
|
||||
color: #990000;
|
||||
}
|
||||
}
|
||||
/* Use higher contrast and text-weight for printable form. */
|
||||
@media print, projection {
|
||||
.str {
|
||||
color: #006600;
|
||||
}
|
||||
.kwd {
|
||||
color: #006;
|
||||
font-weight: bold;
|
||||
}
|
||||
.com {
|
||||
color: #600;
|
||||
font-style: italic;
|
||||
}
|
||||
.typ {
|
||||
color: #404;
|
||||
font-weight: bold;
|
||||
}
|
||||
.lit {
|
||||
color: #004444;
|
||||
}
|
||||
.pun,
|
||||
.opn,
|
||||
.clo {
|
||||
color: #444400;
|
||||
}
|
||||
.tag {
|
||||
color: #006;
|
||||
font-weight: bold;
|
||||
}
|
||||
.atn {
|
||||
color: #440044;
|
||||
}
|
||||
.atv {
|
||||
color: #006600;
|
||||
}
|
||||
}
|
||||
/* Specify class=linenums on a pre to get line numbering */
|
||||
ol.linenums {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.home {
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
@@ -1828,6 +1758,9 @@ ol.linenums {
|
||||
line-height: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.repository .owner.dropdown {
|
||||
min-width: 40% !important;
|
||||
}
|
||||
.repository .metas .menu {
|
||||
max-height: 300px;
|
||||
overflow-x: auto;
|
||||
@@ -1868,6 +1801,158 @@ ol.linenums {
|
||||
margin: 1px;
|
||||
padding-right: 0;
|
||||
}
|
||||
.repository.file.list #repo-desc {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.repository.file.list .choose.reference .header .icon {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
.repository.file.list .head.meta {
|
||||
padding: 0;
|
||||
}
|
||||
.repository.file.list .head.meta li {
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
}
|
||||
.repository.file.list .head.meta li .ui.breadcrumb {
|
||||
margin-top: -5px;
|
||||
}
|
||||
.repository.file.list .head.meta li .ui.breadcrumb span,
|
||||
.repository.file.list .head.meta li .ui.breadcrumb a {
|
||||
font-size: 16px;
|
||||
}
|
||||
.repository.file.list .clone.input {
|
||||
margin-top: -8px;
|
||||
width: 100%;
|
||||
}
|
||||
.repository.file.list .clone.input input {
|
||||
border-radius: 0;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.repository.file.list .clone.input .clone.button {
|
||||
font-size: 13px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.repository.file.list .clone.input .clone.button:first-child {
|
||||
border-radius: .28571429rem 0 0 .28571429rem;
|
||||
}
|
||||
.repository.file.list .clone.input .icon.button {
|
||||
padding: 0 10px;
|
||||
}
|
||||
.repository.file.list .clone.input .dropdown .menu {
|
||||
right: 0!important;
|
||||
left: auto!important;
|
||||
}
|
||||
.repository.file.list #repo-files-table .table.list {
|
||||
width: 80% !important;
|
||||
}
|
||||
.repository.file.list #repo-files-table thead th {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 5px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.repository.file.list #repo-files-table thead th #last-commit-message {
|
||||
margin-left: 5px;
|
||||
margin-bottom: -4px;
|
||||
width: 400px;
|
||||
}
|
||||
.repository.file.list #repo-files-table thead th .age {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.repository.file.list #repo-files-table thead .ui.avatar {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.repository.file.list #repo-files-table tbody .icon {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.repository.file.list #repo-files-table tbody .name {
|
||||
max-width: 120px;
|
||||
}
|
||||
.repository.file.list #repo-files-table tbody .message {
|
||||
max-width: 300px;
|
||||
}
|
||||
.repository.file.list #repo-files-table tbody .age {
|
||||
min-width: 150px;
|
||||
}
|
||||
.repository.file.list #repo-files-table tbody .text.truncate {
|
||||
margin-bottom: -5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.repository.file.list #repo-files-table td {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.repository.file.list #repo-files-table tr:hover {
|
||||
background-color: #ffffEE;
|
||||
}
|
||||
.repository.file.list #file-content .header .icon {
|
||||
font-size: 1em;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.repository.file.list #file-content .view-raw * {
|
||||
width: 100%;
|
||||
}
|
||||
.repository.file.list #file-content .view-raw img {
|
||||
padding: 5px 5px 0 5px;
|
||||
}
|
||||
.repository.file.list #file-content .code-view * {
|
||||
font-size: 13px;
|
||||
font-family: monospace;
|
||||
line-height: 20px;
|
||||
}
|
||||
.repository.file.list #file-content .code-view table {
|
||||
width: 100%;
|
||||
}
|
||||
.repository.file.list #file-content .code-view .lines-num {
|
||||
vertical-align: top;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
background: #f5f5f5;
|
||||
width: 1%;
|
||||
}
|
||||
.repository.file.list #file-content .code-view .lines-num span {
|
||||
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
line-height: 20px;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
}
|
||||
.repository.file.list #file-content .code-view .lines-num,
|
||||
.repository.file.list #file-content .code-view .lines-code {
|
||||
padding: 0;
|
||||
}
|
||||
.repository.file.list #file-content .code-view .lines-num pre,
|
||||
.repository.file.list #file-content .code-view .lines-code pre,
|
||||
.repository.file.list #file-content .code-view .lines-num ol,
|
||||
.repository.file.list #file-content .code-view .lines-code ol,
|
||||
.repository.file.list #file-content .code-view .lines-num .hljs,
|
||||
.repository.file.list #file-content .code-view .lines-code .hljs {
|
||||
background-color: white;
|
||||
margin: 0;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.repository.file.list #file-content .code-view .lines-num pre li,
|
||||
.repository.file.list #file-content .code-view .lines-code pre li,
|
||||
.repository.file.list #file-content .code-view .lines-num ol li,
|
||||
.repository.file.list #file-content .code-view .lines-code ol li,
|
||||
.repository.file.list #file-content .code-view .lines-num .hljs li,
|
||||
.repository.file.list #file-content .code-view .lines-code .hljs li {
|
||||
padding-left: 5px;
|
||||
}
|
||||
.repository.file.list #file-content .code-view .lines-num pre li.active,
|
||||
.repository.file.list #file-content .code-view .lines-code pre li.active,
|
||||
.repository.file.list #file-content .code-view .lines-num ol li.active,
|
||||
.repository.file.list #file-content .code-view .lines-code ol li.active,
|
||||
.repository.file.list #file-content .code-view .lines-num .hljs li.active,
|
||||
.repository.file.list #file-content .code-view .lines-code .hljs li.active {
|
||||
background: #ffffdd;
|
||||
}
|
||||
.repository.file.list .sidebar {
|
||||
padding-left: 0;
|
||||
}
|
||||
.repository.file.list .sidebar .octicon {
|
||||
width: 16px;
|
||||
}
|
||||
.repository.options #interval {
|
||||
width: 100px!important;
|
||||
min-width: 100px;
|
||||
@@ -2156,11 +2241,6 @@ ol.linenums {
|
||||
font-weight: normal;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.repository.commits .header .ui.right .button {
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
.repository .commits.table {
|
||||
font-size: 13px;
|
||||
}
|
||||
@@ -2314,6 +2394,157 @@ ol.linenums {
|
||||
padding: 5px 10px;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.repository.release #release-list {
|
||||
border-top: 1px solid #DDD;
|
||||
margin-top: 20px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
.repository.release #release-list > li {
|
||||
list-style: none;
|
||||
}
|
||||
.repository.release #release-list > li .meta,
|
||||
.repository.release #release-list > li .detail {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
.repository.release #release-list > li .meta {
|
||||
text-align: right;
|
||||
position: relative;
|
||||
}
|
||||
.repository.release #release-list > li .meta .tag:not(.icon) {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.repository.release #release-list > li .meta .commit {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.repository.release #release-list > li .detail {
|
||||
border-left: 1px solid #DDD;
|
||||
}
|
||||
.repository.release #release-list > li .detail .author img {
|
||||
margin-bottom: -3px;
|
||||
}
|
||||
.repository.release #release-list > li .detail .download {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.repository.release #release-list > li .detail .download > a .octicon {
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.repository.release #release-list > li .detail .download .list {
|
||||
padding-left: 0;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
.repository.release #release-list > li .detail .download .list li {
|
||||
list-style: none;
|
||||
display: block;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.repository.release #release-list > li .detail .dot {
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
background-color: #ccc;
|
||||
z-index: 999;
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: -5px;
|
||||
top: 40px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #FFF;
|
||||
}
|
||||
.repository.new.release .target {
|
||||
min-width: 500px;
|
||||
}
|
||||
.repository.new.release .target .at {
|
||||
margin-left: -5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.repository.new.release .target .dropdown.icon {
|
||||
margin: 0;
|
||||
padding-top: 3px;
|
||||
}
|
||||
.repository.new.release .target .selection.dropdown {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.repository.new.release .prerelease.field {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.repository.watchers .list {
|
||||
padding: 0;
|
||||
}
|
||||
.repository.watchers .list .item {
|
||||
list-style: none;
|
||||
width: 32%;
|
||||
margin: 10px 10px 10px 0;
|
||||
padding-bottom: 14px;
|
||||
float: left;
|
||||
}
|
||||
.repository.watchers .list .item .avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
float: left;
|
||||
display: block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.repository.watchers .list .item .name {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
.repository.watchers .list .item .meta {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.repository.forks .list {
|
||||
margin-top: 0;
|
||||
}
|
||||
.repository.forks .list .item {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #DDD;
|
||||
}
|
||||
.repository.forks .list .item .ui.avatar {
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.repository.forks .list .item .link {
|
||||
padding-top: 5px;
|
||||
}
|
||||
.repository.settings.collaboration .collaborator.list {
|
||||
padding: 0;
|
||||
}
|
||||
.repository.settings.collaboration .collaborator.list .item {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
.repository.settings.collaboration .collaborator.list .item:not(:last-child) {
|
||||
border-bottom: 1px solid #DDD;
|
||||
}
|
||||
.repository.settings.collaboration #repo-collab-form #search-user-box .results {
|
||||
left: 7px;
|
||||
}
|
||||
.repository.settings.collaboration #repo-collab-form .ui.button {
|
||||
margin-left: 5px;
|
||||
margin-top: -3px;
|
||||
}
|
||||
#search-user-box .results {
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
}
|
||||
#search-user-box .results .item {
|
||||
padding: 10px 15px;
|
||||
border-bottom: 1px solid #DDD;
|
||||
cursor: pointer;
|
||||
}
|
||||
#search-user-box .results .item:hover {
|
||||
background: rgba(0, 0, 0, 0.05) !important;
|
||||
color: rgba(0, 0, 0, 0.95) !important;
|
||||
}
|
||||
#search-user-box .results .item img {
|
||||
margin-right: 8px;
|
||||
}
|
||||
.issue.list {
|
||||
list-style: none;
|
||||
padding-top: 15px;
|
||||
@@ -2366,7 +2597,7 @@ ol.linenums {
|
||||
.settings .content {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.settings .content .header,
|
||||
.settings .content > .header,
|
||||
.settings .content .segment {
|
||||
box-shadow: 0 1px 2px 0 rgba(34, 36, 38, 0.15);
|
||||
}
|
||||
@@ -2535,52 +2766,131 @@ ol.linenums {
|
||||
.user.settings .email.list .item:not(:first-child) .button {
|
||||
margin-top: -10px;
|
||||
}
|
||||
.user.profile .ui.card .username {
|
||||
display: block;
|
||||
}
|
||||
.user.profile .ui.card .extra.content {
|
||||
padding: 0;
|
||||
}
|
||||
.user.profile .ui.card .extra.content ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.user.profile .ui.card .extra.content ul li {
|
||||
padding: 10px;
|
||||
list-style: none;
|
||||
}
|
||||
.user.profile .ui.card .extra.content ul li:not(:last-child) {
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
}
|
||||
.user.profile .ui.repository.list {
|
||||
margin-top: 25px;
|
||||
}
|
||||
.dashboard {
|
||||
padding-top: 15px;
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
.dashboard.feeds .context.user.menu,
|
||||
.dashboard.issues .context.user.menu {
|
||||
z-index: 101;
|
||||
min-width: 200px;
|
||||
}
|
||||
.dashboard.feeds .context.user.menu .ui.header,
|
||||
.dashboard.issues .context.user.menu .ui.header {
|
||||
font-size: 1rem;
|
||||
text-transform: none;
|
||||
}
|
||||
.dashboard.feeds .filter.menu .item,
|
||||
.dashboard.issues .filter.menu .item {
|
||||
text-align: left;
|
||||
}
|
||||
.dashboard.feeds .filter.menu .item .text,
|
||||
.dashboard.issues .filter.menu .item .text {
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.dashboard.feeds .filter.menu .item .text.truncate,
|
||||
.dashboard.issues .filter.menu .item .text.truncate {
|
||||
width: 85%;
|
||||
}
|
||||
.dashboard.feeds .filter.menu .item .floating.label,
|
||||
.dashboard.issues .filter.menu .item .floating.label {
|
||||
top: 7px;
|
||||
left: 90%;
|
||||
width: 15%;
|
||||
}
|
||||
.dashboard.feeds .filter.menu .jump.item,
|
||||
.dashboard.issues .filter.menu .jump.item {
|
||||
margin: 1px;
|
||||
padding-right: 0;
|
||||
}
|
||||
.dashboard.feeds .filter.menu .menu,
|
||||
.dashboard.issues .filter.menu .menu {
|
||||
max-height: 300px;
|
||||
overflow-x: auto;
|
||||
right: 0!important;
|
||||
left: auto!important;
|
||||
}
|
||||
.dashboard.feeds .ui.right .head.menu,
|
||||
.dashboard.issues .ui.right .head.menu {
|
||||
margin-top: -5px;
|
||||
}
|
||||
.dashboard.feeds .ui.right .head.menu .item.active,
|
||||
.dashboard.issues .ui.right .head.menu .item.active {
|
||||
color: #d9453d;
|
||||
}
|
||||
.dashboard.feeds .head.menu .octicon,
|
||||
.dashboard.issues .head.menu .octicon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.feeds .news .ui.avatar {
|
||||
margin-top: 13px;
|
||||
}
|
||||
.feeds .news p {
|
||||
line-height: 1em;
|
||||
}
|
||||
.feeds .news .time-since {
|
||||
font-size: 13px;
|
||||
}
|
||||
.feeds .news .issue.title {
|
||||
line-height: 1.1em;
|
||||
width: 80%;
|
||||
}
|
||||
.feeds .news .push.news .content ul {
|
||||
font-size: 13px;
|
||||
list-style: none;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.feeds .news .push.news .content ul img {
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
.feeds .news .push.news .content ul .text.truncate {
|
||||
width: 80%;
|
||||
margin-bottom: -5px;
|
||||
}
|
||||
.feeds .list .header {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.feeds .list ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
.feeds .list ul li:not(:last-child) {
|
||||
border-bottom: 1px solid #EAEAEA;
|
||||
}
|
||||
.feeds .list ul li.private {
|
||||
background-color: #fcf8e9;
|
||||
}
|
||||
.feeds .list ul li a {
|
||||
padding: 6px 1.2em;
|
||||
display: block;
|
||||
}
|
||||
.feeds .list ul li a .octicon {
|
||||
margin-right: 6px;
|
||||
color: #888;
|
||||
}
|
||||
.admin {
|
||||
padding-top: 15px;
|
||||
padding-bottom: 80px;
|
||||
@@ -2593,9 +2903,9 @@ ol.linenums {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.admin .table.segment th:first-child,
|
||||
.admin .table.segment td:first-child {
|
||||
padding-left: 15px;
|
||||
.admin .table.segment th:first-of-type,
|
||||
.admin .table.segment td:first-of-type {
|
||||
padding-left: 15px !important;
|
||||
}
|
||||
.admin .ui.header,
|
||||
.admin .ui.segment {
|
||||
@@ -2604,28 +2914,46 @@ ol.linenums {
|
||||
.admin.user .email {
|
||||
max-width: 200px;
|
||||
}
|
||||
.admin dl.admin-dl-horizontal {
|
||||
padding: 20px;
|
||||
margin: 0;
|
||||
}
|
||||
.admin dl.admin-dl-horizontal dd {
|
||||
margin-left: 240px;
|
||||
}
|
||||
.admin dl.admin-dl-horizontal dt {
|
||||
font-weight: bolder;
|
||||
float: left;
|
||||
width: 250px;
|
||||
clear: left;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.explore {
|
||||
padding-top: 15px;
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
.explore.repositories .ui.repository.list .item {
|
||||
border-top: 1px solid #eee;
|
||||
padding-top: 25px;
|
||||
.ui.repository.list .item {
|
||||
padding-bottom: 25px;
|
||||
}
|
||||
.explore.repositories .ui.repository.list .item .ui.header {
|
||||
.ui.repository.list .item:not(:first-child) {
|
||||
border-top: 1px solid #eee;
|
||||
padding-top: 25px;
|
||||
}
|
||||
.ui.repository.list .item .ui.header {
|
||||
font-size: 1.5rem;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.explore.repositories .ui.repository.list .item .ui.header .metas {
|
||||
.ui.repository.list .item .ui.header .metas {
|
||||
color: #888;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.explore.repositories .ui.repository.list .item .ui.header .metas span:not(:last-child) {
|
||||
.ui.repository.list .item .ui.header .metas span:not(:last-child) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.explore.repositories .ui.repository.list .item .time {
|
||||
.ui.repository.list .item .time {
|
||||
font-size: 12px;
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
98
public/css/highlight-8.7/github.css
Normal file
98
public/css/highlight-8.7/github.css
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
|
||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #998;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-subst {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-literal,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag .hljs-attr {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-doctag {
|
||||
color: #d14;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section,
|
||||
.hljs-selector-id {
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-subst {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-type,
|
||||
.hljs-class .hljs-title {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-attribute {
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.hljs-regexp,
|
||||
.hljs-link {
|
||||
color: #009926;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #990073;
|
||||
}
|
||||
|
||||
.hljs-built_in {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-meta {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
BIN
public/fonts/octicons.eot
Executable file → Normal file
BIN
public/fonts/octicons.eot
Executable file → Normal file
Binary file not shown.
21
public/fonts/octicons.svg
Executable file → Normal file
21
public/fonts/octicons.svg
Executable file → Normal file
@@ -27,15 +27,16 @@ Applies to all other files
|
||||
<glyph glyph-name="arrow-up" unicode="" d="M320 640L0 256h192v-256h256V256h192L320 640z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="beaker" unicode="" d="M920-102L704 384V640h64v64H192v-64h64v-256L40-102c-19-42 12-90 58-90h764c46 0 77 48 58 90zM240 192l80 192V640h320v-256l80-192H240z m272 128h64v-64h-64v64z m-64 64h-64v64h64v-64z m0 192h64v-64h-64v64z m0 192h-64V832h64v-64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="bell" unicode="" d="M896 64v-64H0v64l47 37c49 49 52 163 76 283 49 241 261 320 261 320 0 35 29 64 64 64s64-29 64-64c0 0 217-79 266-320 24-120 27-234 76-283l42-37z m-448-256c71 0 128 57 128 128H320c0-71 57-128 128-128z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="bold" unicode="" d="M0 704h245c159 0 275-48 275-189 0-73-40-143-107-167v-4c85-19 147-79 147-183 0-153-126-225-295-225H0V704z m234-317c107 0 152 42 152 108 0 75-50 103-150 103H136v-211h98z m17-345c113 0 176 41 176 127 0 81-61 116-176 116H136v-243h115z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="book" unicode="" d="M128 512h256v-64H128v64z m0-192h256v64H128v-64z m0-128h256v64H128v-64z m704 320H576v-64h256v64z m0-128H576v-64h256v64z m0-128H576v-64h256v64z m128 384v-576c0-35-29-64-64-64H544l-64-64-64 64H64c-35 0-64 29-64 64V640c0 35 29 64 64 64h352l64-64 64 64h352c35 0 64-29 64-64z m-512-32l-32 32H64v-576h384V608z m448 32H544l-32-32v-544h384V640z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="bookmark" unicode="" d="M0-64l192 128 192-128V640c0 35-29 64-64 64H64c-35 0-64-29-64-64v-704z m72 580l88 1 27 83c3 9 7 9 10 0l27-83 88-1c9 0 11-3 4-9l-72-52 28-83c2-9-1-11-8-7l-72 52-72-52c-7-4-10-2-8 7l28 83-72 52c-7 6-5 9 4 9z" horiz-adv-x="384" />
|
||||
<glyph glyph-name="bookmark" unicode="" d="M576 832H64C17 832 0 815 0 768v-960l320 198 320-198V768c0 47-17 64-64 64z m-50-272l-119-87 46-138c4-14-1-18-13-11l-120 86-120-86c-12-7-16-3-13 11l46 138-119 87c-11 10-9 15 6 15l147 2 45 138h16l45-138 147-2c15 0 17-5 6-15z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="briefcase" unicode="" d="M576 576v64c0 35-29 64-64 64H384c-35 0-64-29-64-64v-64H64c-35 0-64-29-64-64v-512c0-35 29-64 64-64h768c35 0 64 29 64 64V512c0 35-29 64-64 64H576z m-192 64h128v-64H384v64z m448-384H512v-64H384v64H64V512h64v-192h640V512h64v-256z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="broadcast" unicode="" d="M576 256h-64c35 0 64 29 64 64v64c0 35-29 64-64 64h-64c-35 0-64-29-64-64v-64c0-35 29-64 64-64h-64c-35 0-64-29-64-64v-128h64v-192c0-35 29-64 64-64h64c35 0 64 29 64 64V64h64V192c0 35-29 64-64 64zM448 384h64v-64h-64v64z m128-256h-64v-256h-64V128h-64v64h192v-64z m134 224c0 127-103 230-230 230S250 479 250 352c0-18 2-35 6-52v-127c-39 49-64 111-64 179 0 159 129 288 288 288s288-129 288-288c0-68-25-130-64-179V300c4 17 6 34 6 52z m250 0c0-184-104-344-256-424v67c119 74 198 206 198 357 0 233-189 422-422 422S58 585 58 352c0-151 79-283 198-357v-67C104 8 0 168 0 352 0 617 215 832 480 832s480-215 480-480z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="browser" unicode="" d="M320 640h64v-64h-64V640zM192 640h64v-64h-64V640zM64 640h64v-64H64V640zM832 0H64V512h768V0zM832 576H448v64h384V576zM896 640c0 35.35-28.65 64-64 64H64c-35.35 0-64-28.65-64-64v-640c0-35.35 28.65-64 64-64h768c35.35 0 64 28.65 64 64V640z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="bug" unicode="" d="M704 192h192v64H704v64l203 66-22 60-181-62v64c0 35-29 64-64 64v64c0 31-23 56-53 62l66 66h115V768H627L499 640h-38L333 768H192v-64h115l66-66c-30-6-53-31-53-62v-64c-35 0-64-29-64-64v-64L75 446l-22-60 203-66v-64H64v-64h192v-64L53 62l22-60 181 62v-64c0-35 29-64 64-64h64l64 64V448h64v-448l64-64h64c35 0 64 29 64 64v64l181-62 22 60-203 66v64zM576 512H384v64h192v-64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="calendar" unicode="" d="M768 704h-64v-96c0-18-14-32-32-32H544c-18 0-32 14-32 32v96H320v-96c0-18-14-32-32-32H160c-18 0-32 14-32 32v96H64c-35 0-64-29-64-64v-704c0-35 29-64 64-64h704c35 0 64 29 64 64V640c0 35-29 64-64 64z m0-768H64V512h704v-576zM256 640h-64V768h64v-128z m384 0h-64V768h64v-128zM320 384h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64zM192 256h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64zM192 128h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64zM192 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z m128 0h-64v64h64v-64z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="check" unicode="" d="M768 512L256 0 0 256l96 96 160-160 416 416 96-96z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="checklist" unicode="" d="M208 166c1 21 10 42 25 56l64 60c16 15 35 22 55 22s41-8 57-23l39-40 128 128V640c0 35-29 64-64 64H64c-35 0-64-29-64-64v-576c0-35 29-64 64-64h272L231 108c-15 16-23 36-23 58z m-16 474h320v-64H192v64z m-64-192H64v64h64v-64z m0 128H64v64h64v-64z m64-64h320v-64H192v64z m544-224L448 0 288 164l64 60 96-96 224 224 64-64z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="checklist" unicode="" d="M1024 288L640-96 448 96l96 96 96-96 288 288 96-96zM365 51l51-51H128c-35 0-64 29-64 64V640c0 35 29 64 64 64h448c35 0 64-29 64-64v-416l-51 51c-25 25-66 25-91 0L365 141c-25-25-25-65 0-90zM256 576h320v64H256v-64z m0-128h320v64H256v-64z m0-128h192v64H256v-64z m-64-64h-64v-64h64v64z m0 128h-64v-64h64v64z m0 128h-64v-64h64v64z m0 128h-64v-64h64v64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="chevron-down" unicode="" d="M320 128L0 448l96 96 224-240 224 240 96-96-320-320z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="chevron-left" unicode="" d="M352 640l96-96-240-224 240-224-96-96L32 320l320 320z" horiz-adv-x="512" />
|
||||
<glyph glyph-name="chevron-right" unicode="" d="M480 320L160 0l-96 96 240 224L64 544l96 96 320-320z" horiz-adv-x="512" />
|
||||
@@ -100,6 +101,7 @@ Applies to all other files
|
||||
<glyph glyph-name="issue-closed" unicode="" d="M448 192h128v-128H448V192z m128 384H448v-320h128V576z m96-96l-64-64 160-160 256 288-64 64-192-224-96 96zM512-45c-201 0-365 164-365 365s164 365 365 365c117 0 221-56 288-141l59 59C777 704 652 768 512 768 265 768 64 567 64 320s201-448 448-448 448 201 448 448l-97-97c-42-154-183-268-351-268z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="issue-opened" unicode="" d="M448 685c201 0 365-164 365-365S649-45 448-45 83 119 83 320s164 365 365 365m0 83C201 768 0 567 0 320s201-448 448-448 448 201 448 448S695 768 448 768z m64-192H384v-320h128V576z m0-384H384v-128h128V192z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="issue-reopened" unicode="" d="M512 256H384V576h128v-320zM384 64h128V192H384v-128z m405 128H640l96-96c-67-85-171-141-288-141-201 0-365 164-365 365 0 22 2 43 6 64H5c-3-21-5-42-5-64 0-247 201-448 448-448 140 0 264 65 346 166l102-102V192H789zM107 448h149l-96 96c67 85 171 141 288 141 201 0 365-164 365-365 0-22-2-43-6-64h84c3 21 5 42 5 64 0 247-201 448-448 448-140 0-264-65-346-166L0 704v-256h107z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="italic" unicode="" d="M180 512h127L192-64H64l116 576z m23 173c0 45 37 83 85 83 36 0 72-24 72-66 0-48-38-83-85-83-37 0-72 24-72 66z" horiz-adv-x="384" />
|
||||
<glyph glyph-name="jersey" unicode="" d="M224 448l-32-32v-320l32-32h128l32 32V416l-32 32H224z m96-320h-64V384h64v-256z m401 464c-14 88-20 168-17 240H513c0-17-8-31-25-44-16-13-40-19-72-19s-56 6-72 19c-15 13-23 27-23 44H128c3-72-2-152-16-240-13-88-51-136-112-144v-576c1-17 7-31 20-44s27-19 44-20h704c17 1 31 7 44 20s19 27 20 44V448c-61 8-98 56-112 144z m47-720H64V384c57 32 95 80 110 144s20 144 18 240h64c-1-50 10-94 33-132 23-37 65-57 128-60 63 1 105 21 128 60 23 38 32 82 31 132h64c1-91 8-163 21-216 13-52 44-128 107-168v-512zM480 448l-32-32v-320l32-32h128l32 32V416l-32 32H480z m96-320h-64V384h64v-256z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="key" unicode="" d="M821 693c-48 48-108 73-181 75-72-2-133-27-181-75s-72-108-74-181c0-19 2-38 6-57L0 64v-64l64-64h128l64 64v64h64v64h64v64h128l70 71c19-5 38-7 58-7 73 2 133 27 181 75s73 108 75 181c-2 73-27 133-75 181zM704 488c-49 0-88 39-88 88s39 88 88 88 88-39 88-88-39-88-88-88z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="keyboard" unicode="" d="M640 512h-64v64h64v-64z m-448-64h-64v-64h64v64z m320 128h-64v-64h64v64z m-256 0H128v-64h128v64z m512-448h128v64H768v-64zM512 384h64v64h-64v-64zM256 192H128v-64h128v64z m512 384h-64v-64h64v64z m128 0h-64v-64h64v64zM768 256h128V448H768v-192z m256 384v-576c0-35-29-64-64-64H64c-35 0-64 29-64 64V640c0 35 29 64 64 64h896c35 0 64-29 64-64z m-64 0H64v-576h896V640zM384 384h64v64h-64v-64z m0 192h-64v-64h64v64zM256 384h64v64h-64v-64z m64-256h384v64H320v-64z m320 256h64v64h-64v-64z m-448-64h-64v-64h64v64z m320 0v-64h64v64h-64z m-128 0v-64h64v64h-64z m-64 0h-64v-64h64v64z m320-64h64v64h-64v-64z" horiz-adv-x="1024" />
|
||||
@@ -107,10 +109,11 @@ Applies to all other files
|
||||
<glyph glyph-name="light-bulb" unicode="" d="M352 832C159 832 0 692 0 512c0-59 35-144 64-192 86-144 114-178 128-256v-64h320v64c14 78 42 112 128 256 29 48 64 133 64 192C704 692 545 832 352 832z m233-479c-16-28-30-51-43-71-55-90-80-132-93-207-1-3-1-7-1-11H256c0 4 0 8-1 11-13 75-38 117-93 207-13 20-27 43-43 71-27 45-55 117-55 159C64 653 193 768 352 768c78 0 151-27 206-76 53-48 82-112 82-180 0-42-28-114-55-159zM192-64h320c-15-73-83-128-160-128s-145 55-160 128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="link" unicode="" d="M256 256h64v-64h-64c-96 0-192 108-192 224s99 224 192 224h256c93 0 192-108 192-224 0-90-58-174-128-208v74c37 29 64 81 64 134 0 82-65 160-128 160H256c-63 0-128-78-128-160s64-160 128-160z m576 192h-64v-64h64c64 0 128-78 128-160s-65-160-128-160H576c-63 0-128 78-128 160 0 53 27 105 64 134v74c-70-34-128-118-128-208 0-116 99-224 192-224h256c93 0 192 108 192 224s-96 224-192 224z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="link-external" unicode="" d="M704 192h64v-192c0-35-29-64-64-64H64c-35 0-64 29-64 64V640c0 35 29 64 64 64h192v-64H64v-640h640V192zM384 704l144-144-208-208 96-96 208 208 144-144V704H384z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="list-ordered" unicode="" d="M320 256h448v128h-448v-128z m0-256h448v128h-448v-128z m0 640v-128h448v128h-448z m-241-256h78v256h-36l-85-23v-50l43 2v-185z m110-206c0 36-12 78-96 78-33 0-64-6-83-16l1-66c21 10 42 15 67 15s32-11 32-28c0-26-30-58-110-112v-50h192v67l-91-2c49 30 87 66 87 113l1 1z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="list-unordered" unicode="" d="M0 256h128v128h-128v-128z m0 256h128v128h-128v-128z m0-512h128v128h-128v-128z m256 256h512v128h-512v-128z m0 256h512v128h-512v-128z m0-512h512v128h-512v-128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="list-ordered" unicode="" d="M768 0c0-38 0-64-38-64H294c-38 0-38 26-38 64s0 64 38 64h436c38 0 38-26 38-64zM294 576h436c38 0 38 26 38 64s0 64-38 64H294c-38 0-38-26-38-64s0-64 38-64z m436-192H294c-38 0-38-26-38-64s0-64 38-64h436c38 0 38 26 38 64s0 64-38 64zM128 768H82C63 756 45 752 16 746v-42h48v-137H10v-55h182v55h-64V768z m16-520c-11 0-29-2-42-4 34 36 73 80 73 121-1 50-36 83-87 83-38 0-62-13-88-41l37-37c12 12 24 24 41 24 18 0 31-10 31-33 0-34-49-77-109-132v-37h192l-6 56h-42z m-5-242v2c28 12 41 30 41 55 0 45-36 71-92 71-31 0-57-12-82-33l35-41c16 13 28 20 44 20 17 0 27-8 27-23 0-17-13-28-55-28v-48c53 0 63-11 63-30 0-16-15-24-37-24-18 0-36 9-52 24L0-92c19-23 49-36 90-36 53 0 98 26 98 74 0 32-20 52-49 60z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="list-unordered" unicode="" d="M128 0c0-38 0-64-38-64H38c-38 0-38 26-38 64s0 64 38 64h52c38 0 38-26 38-64z m166 576h436c38 0 38 26 38 64s0 64-38 64H294c-38 0-38-26-38-64s0-64 38-64zM90 384H38c-38 0-38-26-38-64s0-64 38-64h52c38 0 38 26 38 64s0 64-38 64z m0 320H38c-38 0-38-26-38-64s0-64 38-64h52c38 0 38 26 38 64s0 64-38 64z m640-320H294c-38 0-38-26-38-64s0-64 38-64h436c38 0 38 26 38 64s0 64-38 64z m0-320H294c-38 0-38-26-38-64s0-64 38-64h436c38 0 38 26 38 64s0 64-38 64z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="location" unicode="" d="M384 832C172 832 0 672 0 480c0-289 384-672 384-672s384 383 384 672C768 672 596 832 384 832z m0-931C265 31 64 292 64 480 64 639 208 768 384 768c86 0 167-31 228-87 59-55 92-126 92-201 0-188-201-449-320-579z m128 579c0-71-57-128-128-128s-128 57-128 128 57 128 128 128 128-57 128-128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="lock" unicode="" d="M256 0h-64v64h64v-64z m512 384v-448c0-35-29-64-64-64H64c-35 0-64 29-64 64V384c0 35 29 64 64 64h64V576C128 717 243 832 384 832s256-115 256-256v-128h64c35 0 64-29 64-64z m-525 64h282V576c0 78-63 141-141 141s-141-63-141-141v-128z m461-64H128v-448h576V384z m-448-64h-64v-64h64v64z m0-128h-64v-64h64v64z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="logo-gist" unicode="" d="M301 402h157v-257c-35-17-105-22-162-22-164 0-223 141-223 323 0 181 59 323 223 323 81 0 132-15 210-47v68c-41 21-106 42-210 42-224 0-296-172-296-386s71-386 296-386c105 0 179 17 230 41v364h-225v-63z m409-239v409h-68v-401c0-80 38-110 110-110v57c-31 0-42 10-42 45z m16 559c0 28-22 50-50 50s-50-22-50-50 22-50 50-50 50 22 50 50z m277-364c-96 8-114 31-114 75 0 49 21 86 120 86 67 0 106-10 145-23v60c-44 19-97 25-144 25-141 0-187-77-187-148 0-69 30-120 175-133 99-8 113-40 113-86 0-47-28-91-132-91-71 0-119 12-150 23v-60c32-13 101-25 149-25 152 0 201 77 201 154 0 82-34 130-176 143z m550 158v55h-155v160l-70-20v-135l-100-29v-31h100v-320c0-98 77-136 160-136 13 0 33 1 45 4v56c-13-1-26-2-39-2-63 0-96 25-96 86v312h155z" horiz-adv-x="1552.629" />
|
||||
<glyph glyph-name="logo-github" unicode="" d="M552.73 499.865H311.557c-6.205 0-11.25-5.045-11.25-11.297v-117.887c0-6.252 5.045-11.272 11.25-11.272h94.109v-146.542c0 0-21.145-7.057-79.496-7.057-68.914 0-165.156 25.244-165.156 236.795 0 211.642 100.197 239.491 194.307 239.491 81.465 0 116.514-14.304 138.869-21.241 7.01-2.203 13.404 4.831 13.404 11.105L534.543 785.87c0 2.912-1.041 6.417-4.262 8.785C521.186 801.048 465.865 832 326.168 832 165.133 832 0 763.513 0 434.243 0 105.02099999999996 189.051 56 348.381 56c131.883 0 212.021 56.314 212.021 56.314 3.268 1.801 3.6 6.395 3.6 8.479V488.568C563.955 494.773 558.887 499.865 552.73 499.865zM1772.381 803.866h-135.695c-6.252 0-11.271-5.044-11.271-11.296v-262.393h-211.619V792.57c0 6.252-5.068 11.296-11.178 11.296h-135.838c-6.111 0-11.084-5.044-11.084-11.296v-710.473c0-6.299 5.021-11.32 11.084-11.32h135.838c6.203 0 11.178 5.068 11.178 11.32V385.933h211.619l-0.475-303.883c0-6.3 5.021-11.272 11.084-11.272h135.885c6.252 0 11.131 5.068 11.131 11.272l0.473 710.521C1783.607 798.822 1778.539 803.866 1772.381 803.866zM714.949 787.763c-48.357 0-87.574-39.572-87.574-88.403 0-48.855 39.217-88.428 87.574-88.428s87.527 39.572 87.527 88.428C802.477 748.19 763.307 787.763 714.949 787.763zM792.861 559.874c0 6.205-5.02 11.344-11.131 11.344H646.32c-6.348 0-11.746-6.394-11.746-12.67 0 0 0-394.654 0-469.867 0-13.735 8.572-17.903 19.703-17.903 0 0 57.688 0 121.959 0 13.311 0 16.814 6.536 16.814 18.188-0.094 25.197-0.094 123.808-0.094 142.942C792.861 250.09500000000003 792.861 559.874 792.861 559.874zM2297.973 570.152h-134.701c-6.158 0-11.084-5.092-11.084-11.344v-348.31c0 0-34.244-25.197-82.934-25.197-48.547 0-61.525 22.024-61.525 69.719 0 47.553 0 303.835 0 303.835 0 6.252-5.068 11.345-11.131 11.345h-136.643c-6.252 0-11.178-5.093-11.178-11.345 0 0 0-185.521 0-326.807 0-141.284 78.766-175.906 186.99-175.906 88.854 0 160.609 49.115 160.609 49.115s3.363-25.766 5.068-28.844c1.422-3.078 5.447-6.158 9.852-6.158h86.58c6.158 0 11.178 5.069 11.178 11.321l0.379 477.278C2309.15 565.0609999999999 2304.129 570.152 2297.973 570.152zM2666.932 586.1610000000001c-76.539 0-128.592-34.148-128.592-34.148V792.57c0 6.252-5.068 11.296-11.131 11.296h-136.264c-6.109 0-11.131-5.044-11.131-11.296l-0.379-710.521c0-6.3 5.068-11.272 11.225-11.272 0 0 94.773 0 94.869 0 4.215 0 7.389 2.179 9.805 5.968 2.369 3.837 5.73 32.775 5.73 32.775s55.557-52.763 161.035-52.763c123.807 0 194.758 62.804 194.758 281.906C2856.859 557.482 2743.471 586.1610000000001 2666.932 586.1610000000001zM2613.791 185.77499999999998c-46.701 1.421-78.34 22.64-78.34 22.64v225.07c0 0 31.307 19.206 69.672 22.593 48.547 4.31 95.438-10.326 95.438-126.13C2700.322 207.94100000000003 2679.199 183.83399999999995 2613.791 185.77499999999998zM1185.125 188.33299999999997c-5.969 0-21.219-2.368-36.85-2.368-49.92 0-66.971 23.256-66.971 53.331 0 30.218 0 199.85 0 199.85h101.926c6.252 0 11.178 5.044 11.178 11.343v109.48c0.094 6.299-4.926 11.344-11.178 11.344h-101.926l-0.143 134.535c0 5.092-2.699 7.625-8.572 7.625H933.861c-5.352 0-8.336-2.391-8.336-7.578v-139.035c0 0-69.576-16.79-74.266-18.188-4.641-1.326-8.051-5.684-8.051-10.822v-87.408c0-6.252 5.068-11.344 11.178-11.344h71.139c0 0 0-91.34 0-210.222 0-156.109 109.553-171.455 183.439-171.455 33.723 0 74.076 10.988 80.848 13.356 4.074 1.421 6.395 5.637 6.395 10.136l0.047 96.101C1196.254 183.312 1190.998 188.428 1185.125 188.33299999999997z" horiz-adv-x="2856.857" />
|
||||
<glyph glyph-name="mail" unicode="" d="M0 576v-512c0-35 29-64 64-64h768c35 0 64 29 64 64V576c0 35-29 64-64 64H64c-35 0-64-29-64-64z m832 0L448 256 64 576h768zM64 480l256-192L64 96V480z m64-416l224 192 96-96 96 96 224-192H128z m704 32L576 288l256 192v-384z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="mail-read" unicode="" d="M384 512H256v64h128v-64z m192-64H256v-64h320v64z m320 31v-543c0-35-29-64-64-64H64c-35 0-64 29-64 64V479c0 21 10 40 27 52l101 72v37c0 35 29 64 64 64h77L448 832l179-128h77c35 0 64-29 64-64v-37l101-72c17-12 27-31 27-52zM192 352l256-160 256 160V640H192v-288zM64-32l288 192L64 352v-384z m704-32L448 128 128-64h640z m64 416L544 160l288-192V352z" horiz-adv-x="896" />
|
||||
@@ -118,7 +121,7 @@ Applies to all other files
|
||||
<glyph glyph-name="mark-github" unicode="" d="M512 832C229.252 832 0 602.748 0 320c0-226.251 146.688-418.126 350.155-485.813 25.593-4.686 34.937 11.125 34.937 24.626 0 12.188-0.469 52.562-0.718 95.314-128.708-23.46-161.707 31.541-172.469 60.373-5.525 14.809-30.407 60.249-52.398 72.263-17.988 9.828-43.26 33.237-0.917 33.735 40.434 0.476 69.348-37.308 78.471-52.75 45.938-77.749 119.876-55.627 148.999-42.5 4.654 32.999 17.902 55.627 32.501 68.373-113.657 12.939-233.22 56.875-233.22 253.063 0 55.94 19.968 101.561 52.658 137.404-5.22 12.999-22.844 65.095 5.063 135.563 0 0 42.937 13.749 140.811-52.501 40.811 11.406 84.594 17.031 128.124 17.22 43.499-0.188 87.314-5.874 128.188-17.28 97.689 66.311 140.686 52.501 140.686 52.501 28-70.532 10.375-122.564 5.124-135.499 32.811-35.844 52.626-81.468 52.626-137.404 0-196.686-119.751-240-233.813-252.686 18.439-15.876 34.748-47.001 34.748-94.748 0-68.437-0.686-123.627-0.686-140.501 0-13.625 9.312-29.561 35.25-24.562C877.436-97.99800000000005 1024 93.87400000000002 1024 320 1024 602.748 794.748 832 512 832z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="markdown" unicode="" d="M950.154 640H73.846C33.127 640 0 606.873 0 566.154v-492.308C0 33.125 33.127 0 73.846 0h876.308c40.721 0 73.846 33.125 73.846 73.846V566.154C1024 606.873 990.875 640 950.154 640zM576 128.125L448 128V320l-96-123.077L256 320v-192H128V512h128l96-128 96 128 128 0.125V128.125zM767.091 96.125L608 320h96V512h128v-192h96L767.091 96.125z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="megaphone" unicode="" d="M640 768c-11 0-23-3-33-9-92-56-319-220-415-247-88 0-192-43-192-160s104-160 192-160c19-5 41-15 64-26v-294h128V93c86-55 172-117 223-148 10-6 22-9 33-9 33 0 64 27 64 64V704c0 37-31 64-64 64z m0-768c-24 15-57 37-96 64-10 7-21 14-32 22V620c10 7 20 13 30 20 39 26 74 49 98 64v-704z m128 384h256v-64H768v64z m0-128l256-128v-64L768 192v64z m256 384v-64L768 448v64l256 128z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="mention" unicode="" d="M466.697 732.899C238.66 760.898 31.1 598.735 3.102 370.698c-28-228.038 134.163-435.598 362.2-463.597 71.429-8.756 145.115 0.913 213.325 29.946l-0.016 0.032c24.404 10.357 35.788 38.538 25.431 62.939-10.359 24.403-38.538 35.787-62.94 25.43l-0.001 0.004c-52.472-22.339-109.15-29.799-164.1-23.067-175.413 21.538-300.153 181.2-278.616 356.613 21.538 175.413 181.199 300.154 356.613 278.616 175.412-21.538 300.154-181.199 278.617-356.612-4.309-35.083-21.542-55.725-61.6-55.725-42.5 0-64 45.889-64 81.222V432c0 26.51-21.49 48-48 48-9.699 0-18.72-2.887-26.269-7.833-25.684 20.259-57.437 33.87-94.349 38.402-105.246 12.923-201.045-61.924-213.967-167.17C212.508 238.15200000000004 287.354 142.35400000000004 392.6 129.43200000000002c57.379-7.045 116.216 14.707 157.871 53.13 24.959-28.124 59.866-47.624 100.121-52.567 87.707-10.769 167.537 51.602 178.307 139.309C856.898 497.34 694.734 704.899 466.697 732.899zM511.285 308.30100000000004c-6.462-52.623-54.361-90.047-106.985-83.585-52.623 6.461-90.046 54.36-83.585 106.984 6.461 52.623 54.361 90.046 106.984 83.585C480.322 408.823 517.746 360.924 511.285 308.30100000000004z" horiz-adv-x="832" />
|
||||
<glyph glyph-name="mention" unicode="" d="M421-128c80 0 161 20 228 60l-27 60c-54-33-121-53-194-53-207 0-361 133-361 366C67 585 274 765 488 765c221 0 334-140 334-333 0-153-86-247-160-247-67 0-87 47-67 140l47 240h-67l-7-46c-26 40-60 53-100 53-140 0-234-153-234-280 0-107 60-167 147-167 54 0 107 34 147 80 7-60 60-93 127-93 107 0 241 107 241 320C896 665 742 832 501 832 234 832 0 619 0 299c0-280 187-427 421-427z m-20 320c-47 0-87 33-87 107 0 93 60 206 154 206 33 0 54-13 80-53l-33-193c-40-47-80-67-114-67z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="milestone" unicode="" d="M512 704H384V832h128v-128z m256-320H128c-35 0-64 29-64 64V576c0 35 29 64 64 64h640l128-128-128-128zM512 576H384v-128h128V576z m-128-768h128V320H384v-512z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="mirror" unicode="" d="M992 531L544 832 96 531c-19-12-32-29-32-51v-672l480 256 480-256V480c0 22-13 39-32 51z m-32-627L576 112v80h-64v-80L128-96V480L512 736v-288h64V736l384-256v-576zM384 384h320V512l192-192-192-192V256H384v-128L192 320l192 192v-128z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="mortar-board" unicode="" d="M501 244l-245 76s0-96 0-160 115-96 256-96 256 32 256 96 0 160 0 160l-245-76c-7-2-15-2-23 0h1z m18 409c-4 1-9 1-13 0l-489-152c-21-7-21-36 0-43l111-35v-113c-19-11-32-32-32-55 0-12 3-23 9-32-5-9-9-20-9-32v-165c0-35 128-35 128 0v165c0 12-3 23-9 32 5 9 9 20 9 32 0 24-13 44-32 55v93l313-98c4-1 9-1 13 0l489 152c21 7 21 36 0 43l-488 153z m-6-205c-35 0-64 14-64 32s29 32 64 32 64-14 64-32-29-32-64-32z" horiz-adv-x="1024" />
|
||||
@@ -137,7 +140,7 @@ Applies to all other files
|
||||
<glyph glyph-name="primitive-square" unicode="" d="M512 64H0V576h512V64z" horiz-adv-x="512" />
|
||||
<glyph glyph-name="pulse" unicode="" d="M736 320.062L563.188 486.406 422.406 288 352 729.594 152.438 320.062H0V192h230.406L288 307.188l57.594-345.562L576 288l102.375-96H896V320.062H736z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="question" unicode="" d="M384 192h128v-128H384V192z m256 224c0-137-128-160-128-160H384c0 35 29 64 64 64h32c18 0 32 14 32 32v64c0 18-14 32-32 32h-64c-18 0-32-14-32-32v-32H256c0 96 96 192 192 192s192-64 192-160zM448 685c201 0 365-164 365-365S649-45 448-45 83 119 83 320s164 365 365 365m0 83C201 768 0 567 0 320s201-448 448-448 448 201 448 448S695 768 448 768z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="quote" unicode="" d="M0 320v-256h256V320H128c0 0 0 128 128 128V576C256 576 0 576 0 320zM640 448V576c0 0-256 0-256-256v-256h256V320H512C512 320 512 448 640 448z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="quote" unicode="" d="M394 629C239 529 163 426 163 254c10 3 19 3 28 3 81 0 160-55 160-154 0-103-66-167-160-167C70-64 0 33 0 208 0 451 112 626 321 747l73-118z m448 0C687 529 611 426 611 254c10 3 19 3 28 3 81 0 160-55 160-154 0-103-66-167-160-167-121 0-191 97-191 272 0 243 112 418 321 539l73-118z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="radio-tower" unicode="" d="M306.838 441.261c15.868 16.306 15.868 42.731 0 59.037-20.521 21.116-30.643 48.417-30.705 76.124 0.062 27.77 10.183 55.039 30.705 76.186 15.868 16.337 15.868 42.764 0 59.069-7.934 8.184-18.272 12.275-28.706 12.275-10.371 0-20.804-4.029-28.738-12.213-36.266-37.297-54.633-86.433-54.57-135.317-0.062-48.792 18.305-97.927 54.57-135.161C265.262 424.955 290.97 424.955 306.838 441.261zM149.093 798.858c-8.121 8.309-18.68 12.463-29.3 12.463-10.558 0-21.179-4.154-29.237-12.463C30.8 737.509 0.751 656.856 0.813 576.422 0.751 496.081 30.8 415.272 90.494 353.985c16.181-16.618 42.356-16.618 58.537 0 16.118 16.587 16.118 43.513 0 60.067-43.7 44.98-65.44 103.456-65.44 162.368s21.74 117.449 65.44 162.368C165.149 755.439 165.149 782.365 149.093 798.858zM513.031 472.153c57.351 0 103.956 46.574 103.956 103.956 0 57.382-46.605 103.955-103.956 103.955-57.381 0-103.956-46.573-103.956-103.955C409.076 518.727 455.65 472.153 513.031 472.153zM933.539 798.233c-16.181 16.618-42.355 16.618-58.475 0-16.181-16.587-16.181-43.513 0-60.068 43.668-44.918 65.409-103.456 65.409-162.368 0-58.85-21.805-117.387-65.473-162.306-16.117-16.618-16.117-43.575 0.062-60.068 8.059-8.309 18.616-12.463 29.237-12.463 10.558 0 21.178 4.154 29.236 12.463 59.726 61.287 89.774 142.096 89.649 222.437C1023.313 656.138 993.264 736.947 933.539 798.233zM513.281 389.127L513.281 389.127c-26.489-0.062-53.04 6.466-77.091 19.429L235.057-127.59000000000003h95.209l54.819 63.973h255.891l53.977-63.973h95.272L589.124 408.431C565.384 395.655 539.395 389.127 513.281 389.127zM512.656 358.483L577.004 128.29999999999995H449.059L512.656 358.483zM385.086 0.3550000000000182l63.974 63.973h127.944l63.974-63.973H385.086zM717.194 710.958c-15.868-16.306-15.868-42.731 0-59.037 20.491-21.116 30.611-48.511 30.674-76.124-0.062-27.77-10.183-55.102-30.674-76.187-15.868-16.336-15.868-42.763 0-59.068 7.871-8.184 18.242-12.213 28.737-12.213 10.309 0 20.741 4.029 28.675 12.213 36.298 37.234 54.665 86.433 54.54 135.255 0.125 48.792-18.181 97.927-54.54 135.161C758.801 727.264 733.062 727.264 717.194 710.958z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="repo" unicode="" d="M256 256h-64v64h64v-64z m0 192h-64v-64h64v64z m0 128h-64v-64h64v64z m0 128h-64v-64h64v64z m512 64v-768c0-35-29-64-64-64H384v-128l-96 96-96-96V-64H64c-35 0-64 29-64 64V768C0 803 29 832 64 832h640c35 0 64-29 64-64z m-64-640H64v-128h128v64h192v-64h320V128z m0 640H128v-576h576V768z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="repo-clone" unicode="" d="M960 832H576v-448c0-35 29-64 64-64h64v-64h64v64h192c35 0 64 29 64 64V768c0 35-29 64-64 64zM704 384h-64v64h64v-64z m256 0H768v64h192v-64z m0 128H704V768h256v-256z m-704 0h-64v64h64v-64z m0 128h-64v64h64v-64zM128 768h384V832H64C29 832 0 803 0 768v-768c0-35 29-64 64-64h128v-128l96 96 96-96V-64h320c35 0 64 29 64 64V192H128V768z m576-640v-128H384v64H192v-64H64V128h640zM192 320h64v-64h-64v64z m64 64h-64v64h64v-64z" horiz-adv-x="1024" />
|
||||
@@ -148,8 +151,6 @@ Applies to all other files
|
||||
<glyph glyph-name="rocket" unicode="" d="M1024 832s-6-24-19-68c-13-45-35-101-68-170-45 5-81 21-106 46s-40 60-45 105c69 33 125 56 169 69 45 13 69 18 69 18zM779 587c-17 17-30 35-40 56-10 20-17 42-22 65-37-21-74-45-111-72-37-28-73-60-108-95-45-45-85-116-114-157H192L0 192h192l128 128c-22-49-65-191-64-192l64-64c1-1 143 41 192 64L384 0v-192l192 192V192c41 29 112 70 157 114 35 35 67 72 94 109 28 37 52 74 73 110-23 5-45 12-66 22-20 10-38 23-55 40z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="rss" unicode="" d="M128 0H0V128c71 0 128-57 128-128zM0 640v-64c318 0 576-258 576-576h64c0 353-287 640-640 640z m0-256v-64c176 0 320-144 320-320h64c0 212-172 384-384 384z" horiz-adv-x="640" />
|
||||
<glyph glyph-name="ruby" unicode="" d="M832 448L512 128V576h192l128-128z m192 0L512-64 0 448l256 256h512l256-256zM512 32l416 416-192 192H288L96 448l416-416z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="screen-full" unicode="" d="M832 192h64v-192c0-35-29-64-64-64H640v64h192V192z m-768 0H0v-192c0-35 29-64 64-64h192v64H64V192z m0 448h192v64H64c-35 0-64-29-64-64v-192h64V640z m64-64h640v-512H128V576z m128-384h384V448H256v-256z m576 512H640v-64h192v-192h64V640c0 35-29 64-64 64z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="screen-normal" unicode="" d="M128 576H0v64h128V768h64v-128c0-35-29-64-64-64z m0-512H0v-64h128v-128h64V0c0 35-29 64-64 64z m576 128c0-35-29-64-64-64H256c-35 0-64 29-64 64V448c0 35 29 64 64 64h384c35 0 64-29 64-64v-256zM576 384H320v-128h256V384z m128-384v-128h64V0h128v64H768c-35 0-64-29-64-64z m64 640V768h-64v-128c0-35 29-64 64-64h128v64H768z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="search" unicode="" d="M1005-83L761 162c45 63 71 139 71 222 0 212-172 384-384 384S64 596 64 384s172-384 384-384c83 0 159 26 222 71l245-244c12-13 29-19 45-19s33 6 45 19c25 25 25 65 0 90zM448 83c-166 0-301 135-301 301s135 301 301 301 301-135 301-301-135-301-301-301z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="server" unicode="" d="M704 448H64c-35 0-64-29-64-64v-128c0-35 29-64 64-64h640c35 0 64 29 64 64V384c0 35-29 64-64 64zM128 256H64V384h64v-128z m128 0h-64V384h64v-128z m128 0h-64V384h64v-128z m128 0h-64V384h64v-128zM704 768H64C29 768 0 739 0 704v-128c0-35 29-64 64-64h640c35 0 64 29 64 64V704c0 35-29 64-64 64zM128 576H64V704h64v-128z m128 0h-64V704h64v-128z m128 0h-64V704h64v-128z m128 0h-64V704h64v-128z m192 64h-64v64h64v-64z m0-512H64c-35 0-64-29-64-64v-128c0-35 29-64 64-64h640c35 0 64 29 64 64V64c0 35-29 64-64 64zM128-64H64V64h64v-128z m128 0h-64V64h64v-128z m128 0h-64V64h64v-128z m128 0h-64V64h64v-128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="settings" unicode="" d="M192 384h-64V704h64v-320z m-64-448h64V128h-64v-192z m320 0h64V320h-64v-384z m320 0h64V64h-64v-128z m64 768h-64v-384h64V704z m-320 0h-64v-128h64V704zM256 320H64c-35 0-64-29-64-64s29-64 64-64h192c35 0 64 29 64 64s-29 64-64 64z m320 192H384c-35 0-64-29-64-64s29-64 64-64h192c35 0 64 29 64 64s-29 64-64 64z m320-256H704c-35 0-64-29-64-64s29-64 64-64h192c35 0 64 29 64 64s-29 64-64 64z" horiz-adv-x="1024" />
|
||||
@@ -161,9 +162,11 @@ Applies to all other files
|
||||
<glyph glyph-name="stop" unicode="" d="M640 768H256L0 512v-384l256-256h384l256 256V512L640 768z m192-608L608-64H288L64 160V480l224 224h320l224-224v-320zM384 576h128v-320H384V576z m0-384h128v-128H384V192z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="sync" unicode="" d="M655.461 358.531c11.875-81.719-13.062-167.781-76.812-230.594-94.188-92.938-239.5-104.375-346.375-34.562l74.875 73L31.96 204.75 70.367-64l84.031 80.5c150.907-111.25 364.938-100.75 502.063 34.562 79.5 78.438 115.75 182.562 111.25 285.312L655.461 358.531zM189.46 511.938c94.156 92.938 239.438 104.438 346.313 34.562l-75-72.969 275.188-38.406L697.586 704l-83.938-80.688C462.711 734.656 248.742 724.031 111.585 588.75 32.085 510.344-4.133 406.219 0.335 303.5l112.25-22.125C100.71 363.125 125.71 449.094 189.46 511.938z" horiz-adv-x="768.051" />
|
||||
<glyph glyph-name="tag" unicode="" d="M431 657c-30 30-71 47-113 47H160C72 704 0 632 0 544v-158c0-42 17-83 47-113l388-388c25-25 65-25 90 0l294 294c25 25 25 65 0 90L431 657zM88 314c-20 19-30 45-30 72V544c0 56 46 102 102 102h158c27 0 53-10 72-30l393-392-303-303L88 314z m40 262h128v-128H128V576z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="tasklist" unicode="" d="M986 256H486c-38 0-38 26-38 64s0 64 38 64h500c38 0 38-26 38-64s0-64-38-64zM614 576c-38 0-38 26-38 64s0 64 38 64h372c38 0 38-26 38-64s0-64-38-64H614zM0 582l90 83 102-102L454 832l90-90-352-352L0 582z m486-518h500c38 0 38-26 38-64s0-64-38-64H486c-38 0-38 26-38 64s0 64 38 64z" horiz-adv-x="1024" />
|
||||
<glyph glyph-name="telescope" unicode="" d="M512 256l192-384h-64L512 128v-320h-64V192L320-128h-64l128 320 128 64zM448 832h-64v-64h64V832zM320 640h-64v-64h64v64zM128 768H64v-64h64V768zM40 256c-14-10-18-28-10-43l35-59c8-15 26-20 41-13l89 42-74 128-81-55z m505 345L174 348l79-137 405 194-113 196z m270-82l-94 161c-9 16-30 21-46 11l-77-53 118-205 85 41c17 8 23 28 14 45z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="terminal" unicode="" d="M448 192h256v-64H448v64z m-192-64l192 192-192 192-48-48 144-144-144-144 48-48z m640 512v-640c0-35-29-64-64-64H64c-35 0-64 29-64 64V640c0 35 29 64 64 64h768c35 0 64-29 64-64z m-64 0H64v-640h768V640z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="three-bars" unicode="" d="M0 640v-128h768v128h-768z m0-384h768v128h-768v-128z m0-256h768v128h-768v-128z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="text-size" unicode="" d="M1150-64h-144l-61 208H685l-61-208H480l-44 149H226l-45-149H42l211 614h160l139-406 185 560h161l252-768zM407 184s-65 231-75 263h-5l-72-263h152z m507 67l-97 347h-4l-96-347h197z" horiz-adv-x="1152" />
|
||||
<glyph glyph-name="three-bars" unicode="" d="M730 256H38c-38 0-38 26-38 64s0 64 38 64h692c38 0 38-26 38-64s0-64-38-64z m0 256H38c-38 0-38 26-38 64s0 64 38 64h692c38 0 38-26 38-64s0-64-38-64zM38 128h692c38 0 38-26 38-64s0-64-38-64H38c-38 0-38 26-38 64s0 64 38 64z" horiz-adv-x="768" />
|
||||
<glyph glyph-name="thumbsdown" unicode="" d="M871 347c9 19 15 40 15 62 0 51-28 96-69 120 4 13 6 27 6 41 0 50-26 93-65 118 2 8 10 19 10 27C768 781 709 832 640 832c0 0-212 0-222 0-88 0-170-43-242-81-42-22-89-47-113-47H0v-576h64c37-2 155-69 206-112 12-10 173-168 173-168 26-26 60-40 96-40 35 0 68 13 92 38 51 51 50 135-2 188-20 20-94 115-117 138l256-44c76 0 128 59 128 131 0 34-3 64-25 88zM768 192l-384 64c-7 0 200-266 200-266 28-29 29-73 3-100-13-13-30-19-48-19s-37 7-52 21L347 34c-86 71-216 158-283 158V642c87 0 221 126 352 126h224c34 0 64-20 64-53 0-34-30-75-64-75h48c45 0 72-25 72-70 0-44-36-90-81-90h63c45 0 81-26 81-71 0-44-36-80-81-80h27c42 0 63-32 63-70 0-39-23-67-64-67z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="thumbsup" unicode="" d="M896 381c0 72-52 131-128 131l-256-44c23 23 97 118 117 138 52 53 53 137 2 188-24 25-57 38-92 38-36 0-70-14-96-40 0 0-161-158-173-168-51-43-169-110-206-112H0v-576h63c24 0 71-25 113-47 72-38 154-81 242-81 10 0 222 0 222 0 69 0 128 51 128 117 0 8-8 19-10 27 39 25 65 68 65 118 0 14-2 28-6 41 41 24 69 69 69 120 0 22-6 43-15 62 22 24 25 54 25 88z m-64 0c0-38-21-70-63-70h-27c45 0 81-36 81-80 0-45-36-71-81-71h-63c45 0 81-46 81-90 0-45-27-70-72-70h-48c34 0 64-41 64-75 0-33-30-53-64-53H416c-131 0-265 126-352 126V448c67 0 197 87 283 158L487 748c15 14 34 21 52 21s35-6 48-19c26-27 25-71-3-100 0 0-207-266-200-266l384 64c41 0 64-28 64-67z" horiz-adv-x="896" />
|
||||
<glyph glyph-name="tools" unicode="" d="M286.547 366.984c16.843-16.812 81.716-85.279 81.716-85.279l35.968 37.093-56.373 58.248L456.072 491.98c0 0-48.842 47.623-27.468 28.655 20.438 75.903 1.812 160.589-55.842 220.243C315.608 800.064 234.392 819.47 161.425 799.096l123.653-127.715-32.53-125.309-121.06-33.438L7.898 640.3820000000001c-19.718-75.436-0.969-159.339 56.311-218.556C124.302 359.703 210.83 341.453 286.547 366.984zM698.815 242.769L549.694 95.46100000000001l245.932-254.805c20.062-20.812 46.498-31.188 72.872-31.188 26.25 0 52.624 10.375 72.811 31.188 40.249 41.624 40.249 108.997 0 150.62L698.815 242.769zM1023.681 670.162L867.06 832.001 405.387 354.703l56.373-58.248L185.425 10.839000000000055l-63.154-33.749-89.217-145.559 22.719-23.562 140.839 92.247 32.655 65.312 276.336 285.554 56.404-58.248L1023.681 670.162z" horiz-adv-x="1024" />
|
||||
|
||||
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 67 KiB |
BIN
public/fonts/octicons.ttf
Executable file → Normal file
BIN
public/fonts/octicons.ttf
Executable file → Normal file
Binary file not shown.
BIN
public/fonts/octicons.woff
Executable file → Normal file
BIN
public/fonts/octicons.woff
Executable file → Normal file
Binary file not shown.
Binary file not shown.
@@ -206,6 +206,31 @@ function initRepository() {
|
||||
return;
|
||||
}
|
||||
|
||||
function initFilterSearchDropdown(selector) {
|
||||
var $dropdown = $(selector);
|
||||
$dropdown.dropdown({
|
||||
fullTextSearch: true,
|
||||
onChange: function (text, value, $choice) {
|
||||
window.location.href = $choice.data('url');
|
||||
console.log($choice.data('url'))
|
||||
},
|
||||
message: {noResults: $dropdown.data('no-results')}
|
||||
});
|
||||
}
|
||||
|
||||
// File list
|
||||
if ($('.repository.file.list').length > 0) {
|
||||
initFilterSearchDropdown('.choose.reference .dropdown');
|
||||
|
||||
$('.reference.column').click(function () {
|
||||
$('.choose.reference .scrolling.menu').css('display', 'none');
|
||||
$('.choose.reference .text').removeClass('black');
|
||||
$($(this).data('target')).css('display', 'block');
|
||||
$(this).find('.text').addClass('black');
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// Options
|
||||
if ($('.repository.settings.options').length > 0) {
|
||||
$('#repo_name').keyup(function () {
|
||||
@@ -289,23 +314,23 @@ function initRepository() {
|
||||
$('#edit-title').click(editTitleToggle);
|
||||
$('#cancel-edit-title').click(editTitleToggle);
|
||||
$('#save-edit-title').click(editTitleToggle).
|
||||
click(function () {
|
||||
if ($edit_input.val().length == 0 ||
|
||||
$edit_input.val() == $issue_title.text()) {
|
||||
$edit_input.val($issue_title.text());
|
||||
return false;
|
||||
}
|
||||
|
||||
$.post($(this).data('update-url'), {
|
||||
"_csrf": csrf,
|
||||
"title": $edit_input.val()
|
||||
},
|
||||
function (data) {
|
||||
$edit_input.val(data.title);
|
||||
$issue_title.text(data.title);
|
||||
});
|
||||
click(function () {
|
||||
if ($edit_input.val().length == 0 ||
|
||||
$edit_input.val() == $issue_title.text()) {
|
||||
$edit_input.val($issue_title.text());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
$.post($(this).data('update-url'), {
|
||||
"_csrf": csrf,
|
||||
"title": $edit_input.val()
|
||||
},
|
||||
function (data) {
|
||||
$edit_input.val(data.title);
|
||||
$issue_title.text(data.title);
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// Edit issue or comment content
|
||||
$('.edit-content').click(function () {
|
||||
@@ -397,33 +422,26 @@ function initRepository() {
|
||||
}
|
||||
}
|
||||
|
||||
// Quick start
|
||||
if ($('.repository.quickstart').length > 0) {
|
||||
$('#repo-clone-ssh').click(function () {
|
||||
$('.clone-url').text($(this).data('link'));
|
||||
$('#repo-clone-url').val($(this).data('link'));
|
||||
$(this).addClass('blue');
|
||||
$('#repo-clone-https').removeClass('blue');
|
||||
});
|
||||
$('#repo-clone-https').click(function () {
|
||||
$('.clone-url').text($(this).data('link'));
|
||||
$('#repo-clone-url').val($(this).data('link'));
|
||||
$(this).addClass('blue');
|
||||
$('#repo-clone-ssh').removeClass('blue');
|
||||
});
|
||||
}
|
||||
// Quick start and repository home
|
||||
$('#repo-clone-ssh').click(function () {
|
||||
$('.clone-url').text($(this).data('link'));
|
||||
$('#repo-clone-url').val($(this).data('link'));
|
||||
$(this).addClass('blue');
|
||||
$('#repo-clone-https').removeClass('blue');
|
||||
});
|
||||
$('#repo-clone-https').click(function () {
|
||||
$('.clone-url').text($(this).data('link'));
|
||||
$('#repo-clone-url').val($(this).data('link'));
|
||||
$(this).addClass('blue');
|
||||
$('#repo-clone-ssh').removeClass('blue');
|
||||
});
|
||||
$('#repo-clone-url').click(function () {
|
||||
$(this).select();
|
||||
});
|
||||
|
||||
// Pull request
|
||||
if ($('.repository.compare.pull').length > 0) {
|
||||
var $branch_dropdown = $('.choose.branch .dropdown');
|
||||
$branch_dropdown.dropdown({
|
||||
fullTextSearch: true,
|
||||
onChange: function (text, value, $choice) {
|
||||
window.location.href = $choice.data('url');
|
||||
console.log($choice.data('url'))
|
||||
},
|
||||
message: {noResults: $branch_dropdown.data('no-results')}
|
||||
});
|
||||
initFilterSearchDropdown('.choose.branch .dropdown');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,12 +558,70 @@ function initAdmin() {
|
||||
}
|
||||
|
||||
function buttonsClickOnEnter() {
|
||||
$('.ui.button').keypress(function(e){
|
||||
$('.ui.button').keypress(function (e) {
|
||||
if (e.keyCode == 13 || e.keyCode == 32) // enter key or space bar
|
||||
$(this).click();
|
||||
});
|
||||
}
|
||||
|
||||
function searchUsers() {
|
||||
if (!$('#search-user-box .results').length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $search_user_box = $('#search-user-box');
|
||||
var $result_list = $search_user_box.find('.results');
|
||||
$search_user_box.keyup(function () {
|
||||
var $this = $(this);
|
||||
var keyword = $this.find('input').val();
|
||||
if (keyword.length < 2) {
|
||||
$result_list.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: suburl + '/api/v1/users/search?q=' + keyword,
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
var notEmpty = function (str) {
|
||||
return str && str.length > 0;
|
||||
};
|
||||
|
||||
$result_list.html('');
|
||||
|
||||
if (response.ok && response.data.length) {
|
||||
var html = '';
|
||||
$.each(response.data, function (i, item) {
|
||||
html += '<div class="item"><img class="ui avatar image" src="' + item.avatar_url + '"><span class="username">' + item.username + '</span>';
|
||||
if (notEmpty(item.full_name)) {
|
||||
html += ' (' + item.full_name + ')';
|
||||
}
|
||||
html += '</div>';
|
||||
});
|
||||
$result_list.html(html);
|
||||
$this.find('.results .item').click(function () {
|
||||
$this.find('input').val($(this).find('.username').text());
|
||||
$result_list.hide();
|
||||
});
|
||||
$result_list.show();
|
||||
} else {
|
||||
$result_list.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
$search_user_box.find('input').focus(function () {
|
||||
$search_user_box.keyup();
|
||||
});
|
||||
$(document).click(function (e) {
|
||||
var target = e.target;
|
||||
|
||||
if (!$(target).is('#search-user-box .results') && !$(target).parents().is('#search-user-box')) {
|
||||
$('#search-user-box .results').hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
csrf = $('meta[name=_csrf]').attr("content");
|
||||
suburl = $('meta[name=_suburl]').attr("content");
|
||||
@@ -553,9 +629,9 @@ $(document).ready(function () {
|
||||
// Show exact time
|
||||
$('.time-since').each(function () {
|
||||
$(this).addClass('poping up').
|
||||
attr('data-content', $(this).attr('title')).
|
||||
attr('data-variation', 'inverted tiny').
|
||||
attr('title', '');
|
||||
attr('data-content', $(this).attr('title')).
|
||||
attr('data-variation', 'inverted tiny').
|
||||
attr('title', '');
|
||||
});
|
||||
|
||||
// Semantic UI modules.
|
||||
@@ -583,6 +659,7 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
$('.tabular.menu .item').tab();
|
||||
$('.tabable.menu .item').tab();
|
||||
|
||||
$('.toggle.button').click(function () {
|
||||
$($(this).data('target')).slideToggle(100);
|
||||
@@ -629,9 +706,7 @@ $(document).ready(function () {
|
||||
emojify.setConfig({
|
||||
img_dir: suburl + '/img/emoji'
|
||||
});
|
||||
$('.emojify').each(function () {
|
||||
emojify.run($(this)[0]);
|
||||
});
|
||||
emojify.run();
|
||||
|
||||
// Clipboard JS
|
||||
var clipboard = new Clipboard('.clipboard');
|
||||
@@ -679,7 +754,29 @@ $(document).ready(function () {
|
||||
$($(this).data('modal')).modal('show');
|
||||
});
|
||||
|
||||
// Set anchor.
|
||||
$('.markdown').each(function () {
|
||||
var headers = {};
|
||||
$(this).find('h1, h2, h3, h4, h5, h6').each(function () {
|
||||
var node = $(this);
|
||||
var val = encodeURIComponent(node.text().toLowerCase().replace(/[^\w\- ]/g, '').replace(/[ ]/g, '-'));
|
||||
var name = val;
|
||||
if (headers[val] > 0) {
|
||||
name = val + '-' + headers[val];
|
||||
}
|
||||
if (headers[val] == undefined) {
|
||||
headers[val] = 1;
|
||||
} else {
|
||||
headers[val] += 1;
|
||||
}
|
||||
node = node.wrap('<div id="' + name + '" class="anchor-wrap" ></div>');
|
||||
node.append('<a class="anchor" href="#' + name + '"><span class="octicon octicon-link"></span></a>');
|
||||
});
|
||||
});
|
||||
|
||||
buttonsClickOnEnter();
|
||||
searchUsers();
|
||||
|
||||
|
||||
initCommentForm();
|
||||
initInstall();
|
||||
@@ -688,4 +785,88 @@ $(document).ready(function () {
|
||||
initUser();
|
||||
initWebhook();
|
||||
initAdmin();
|
||||
});
|
||||
|
||||
$(window).load(function () {
|
||||
function changeHash(hash) {
|
||||
if (history.pushState) {
|
||||
history.pushState(null, null, hash);
|
||||
}
|
||||
else {
|
||||
location.hash = hash;
|
||||
}
|
||||
}
|
||||
|
||||
function deSelect() {
|
||||
if (window.getSelection) {
|
||||
window.getSelection().removeAllRanges();
|
||||
} else {
|
||||
document.selection.empty();
|
||||
}
|
||||
}
|
||||
|
||||
function selectRange($list, $select, $from) {
|
||||
$list.removeClass('active');
|
||||
if ($from) {
|
||||
var a = parseInt($select.attr('rel').substr(1));
|
||||
var b = parseInt($from.attr('rel').substr(1));
|
||||
var c;
|
||||
if (a != b) {
|
||||
if (a > b) {
|
||||
c = a;
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
var classes = [];
|
||||
for (i = a; i <= b; i++) {
|
||||
classes.push('.L' + i);
|
||||
}
|
||||
$list.filter(classes.join(',')).addClass('active');
|
||||
changeHash('#L' + a + '-' + 'L' + b);
|
||||
return
|
||||
}
|
||||
}
|
||||
$select.addClass('active');
|
||||
changeHash('#' + $select.attr('rel'));
|
||||
}
|
||||
|
||||
// Code view.
|
||||
if ($('.code-view').length > 0) {
|
||||
var $block = $('.code-view .linenums');
|
||||
var lines = $block.html().split("\n");
|
||||
$block.html('');
|
||||
|
||||
var $num_list = $('.code-view .lines-num');
|
||||
|
||||
// Building blocks.
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
$block.append('<li class="L' + (i + 1) + '" rel="L' + (i + 1) + '">' + lines[i] + '</li>');
|
||||
$num_list.append('<span id="L' + (i + 1) + '">' + (i + 1) + '</span>');
|
||||
}
|
||||
|
||||
$(document).on('click', '.lines-num span', function (e) {
|
||||
var $select = $(this);
|
||||
var $list = $select.parent().siblings('.lines-code').find('ol.linenums > li');
|
||||
selectRange($list, $list.filter('[rel=' + $select.attr('id') + ']'), (e.shiftKey ? $list.filter('.active').eq(0) : null));
|
||||
deSelect();
|
||||
});
|
||||
|
||||
$(window).on('hashchange', function (e) {
|
||||
var m = window.location.hash.match(/^#(L\d+)\-(L\d+)$/);
|
||||
var $list = $('.code-view ol.linenums > li');
|
||||
var $first;
|
||||
if (m) {
|
||||
$first = $list.filter('.' + m[1]);
|
||||
selectRange($list, $first, $list.filter('.' + m[2]));
|
||||
$("html, body").scrollTop($first.offset().top - 200);
|
||||
return;
|
||||
}
|
||||
m = window.location.hash.match(/^#(L\d+)$/);
|
||||
if (m) {
|
||||
$first = $list.filter('.' + m[1]);
|
||||
selectRange($list, $first);
|
||||
$("html, body").scrollTop($first.offset().top - 200);
|
||||
}
|
||||
}).trigger('hashchange');
|
||||
}
|
||||
});
|
||||
1
public/js/min/gogs-min.js
vendored
Normal file
1
public/js/min/gogs-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -10,8 +10,8 @@
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
th, td {
|
||||
&:first-child {
|
||||
padding-left: 15px;
|
||||
&:first-of-type {
|
||||
padding-left: 15px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,4 +25,22 @@
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dl.admin-dl-horizontal {
|
||||
padding: 20px;
|
||||
margin: 0;
|
||||
|
||||
dd{
|
||||
margin-left: 240px;
|
||||
}
|
||||
dt {
|
||||
font-weight: bolder;
|
||||
float: left;
|
||||
width: 250px;
|
||||
clear: left;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ pre {
|
||||
z-index: 900;
|
||||
}
|
||||
.head.link.item {
|
||||
padding-right: 0!important;
|
||||
padding-right: 0 !important;
|
||||
.dropdown.icon,
|
||||
.menu .octicon {
|
||||
margin-right: 5px;
|
||||
@@ -65,9 +65,9 @@ pre {
|
||||
margin-right: 0;
|
||||
}
|
||||
.searchbox {
|
||||
background-color: rgb(244, 244, 244)!important;
|
||||
background-color: rgb(244, 244, 244) !important;
|
||||
&:focus {
|
||||
background-color: rgb(233, 233, 233)!important;
|
||||
background-color: rgb(233, 233, 233) !important;
|
||||
}
|
||||
}
|
||||
.text .octicon {
|
||||
@@ -84,6 +84,7 @@ pre {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ui {
|
||||
&.left {
|
||||
float: left;
|
||||
@@ -94,51 +95,72 @@ pre {
|
||||
|
||||
.text {
|
||||
&.red {
|
||||
color: #d95c5c!important;
|
||||
color: #d95c5c !important;
|
||||
a {
|
||||
color: #d95c5c!important;
|
||||
color: #d95c5c !important;
|
||||
&:hover {
|
||||
color: #E67777!important;
|
||||
color: #E67777 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.blue {
|
||||
color: #428bca!important;
|
||||
color: #428bca !important;
|
||||
a {
|
||||
color: #15c!important;
|
||||
color: #15c !important;
|
||||
&:hover {
|
||||
color: #428bca!important;
|
||||
color: #428bca !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.black {
|
||||
color: #444;
|
||||
&:hover {
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
&.grey {
|
||||
color: #767676!important;
|
||||
color: #767676 !important;
|
||||
a {
|
||||
color: #444!important;
|
||||
color: #444 !important;
|
||||
&:hover {
|
||||
color: #000!important;
|
||||
color: #000 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.light.grey {
|
||||
color: #888 !important;
|
||||
}
|
||||
&.green {
|
||||
color: #6cc644!important;
|
||||
color: #6cc644 !important;
|
||||
}
|
||||
&.purple {
|
||||
color: #6e5494!important;
|
||||
color: #6e5494 !important;
|
||||
}
|
||||
&.yellow {
|
||||
color: #FBBD08!important;
|
||||
color: #FBBD08 !important;
|
||||
}
|
||||
&.gold {
|
||||
color: #a1882b !important;
|
||||
}
|
||||
|
||||
&.left {
|
||||
text-align: left!important;
|
||||
text-align: left !important;
|
||||
}
|
||||
&.right {
|
||||
text-align: right!important;
|
||||
text-align: right !important;
|
||||
}
|
||||
&.small {
|
||||
font-size: 0.75em;
|
||||
}
|
||||
&.normal {
|
||||
font-weight: normal;
|
||||
}
|
||||
&.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
&.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
&.truncate {
|
||||
overflow: hidden;
|
||||
@@ -166,7 +188,7 @@ pre {
|
||||
}
|
||||
.warning {
|
||||
&.header {
|
||||
background-color: #F9EDBE!important;
|
||||
background-color: #F9EDBE !important;
|
||||
border-color: #F0C36D;
|
||||
}
|
||||
&.segment {
|
||||
@@ -175,7 +197,7 @@ pre {
|
||||
}
|
||||
.info {
|
||||
&.header {
|
||||
background-color: #d9edf7!important;
|
||||
background-color: #d9edf7 !important;
|
||||
border-color: #85c5e5;
|
||||
}
|
||||
&.segment {
|
||||
@@ -193,7 +215,7 @@ pre {
|
||||
|
||||
.form {
|
||||
.fake {
|
||||
display: none!important;
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +239,7 @@ pre {
|
||||
border-top: none;
|
||||
line-height: 1em;
|
||||
color: rgba(0,0,0,.8);
|
||||
padding: .71428571em 1.14285714em!important;
|
||||
padding: .71428571em 1.14285714em !important;
|
||||
font-size: 1rem;
|
||||
text-transform: none;
|
||||
font-weight: 400;
|
||||
@@ -237,12 +259,12 @@ pre {
|
||||
|
||||
.scrolling.menu {
|
||||
.item.selected {
|
||||
font-weight: 700!important;
|
||||
font-weight: 700 !important;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: @footer-margin+14px!important;
|
||||
margin-top: @footer-margin+14px !important;
|
||||
height: @footer-margin;
|
||||
background-color: white;
|
||||
border-top: 1px solid #d6d6d6;
|
||||
@@ -277,8 +299,8 @@ footer {
|
||||
.generate-img(16);
|
||||
.generate-img(@n, @i: 1) when (@i =< @n) {
|
||||
.img-@{i} {
|
||||
width: (2px * @i)!important;
|
||||
height: (2px * @i)!important;
|
||||
width: (2px * @i) !important;
|
||||
height: (2px * @i) !important;
|
||||
}
|
||||
.generate-img(@n, (@i + 1));
|
||||
}
|
||||
@@ -286,7 +308,7 @@ footer {
|
||||
.octicon.icon,
|
||||
.mega-octicon.icon {
|
||||
font-family: octicons;
|
||||
opacity: 1!important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
// Accessibility
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
padding-top: 15px;
|
||||
padding-bottom: @footer-margin * 2;
|
||||
|
||||
&.feeds,
|
||||
&.issues {
|
||||
.context.user.menu {
|
||||
z-index: 101;
|
||||
@@ -52,4 +53,67 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.feeds {
|
||||
.news {
|
||||
.ui.avatar {
|
||||
margin-top: 13px;
|
||||
}
|
||||
p {
|
||||
line-height: 1em;
|
||||
}
|
||||
.time-since {
|
||||
font-size: 13px;
|
||||
}
|
||||
.issue.title {
|
||||
line-height: 1.1em;
|
||||
width: 80%;
|
||||
}
|
||||
.push.news .content ul {
|
||||
font-size: 13px;
|
||||
list-style: none;
|
||||
padding-left: 10px;
|
||||
|
||||
img {
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
.text.truncate {
|
||||
width: 80%;
|
||||
margin-bottom: -5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
.header {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
|
||||
li {
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid #EAEAEA;
|
||||
}
|
||||
|
||||
&.private {
|
||||
background-color: #fcf8e9;
|
||||
}
|
||||
|
||||
a {
|
||||
padding: 6px 1.2em;
|
||||
display: block;
|
||||
|
||||
.octicon {
|
||||
margin-right: 6px;
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,32 @@
|
||||
.explore {
|
||||
padding-top: 15px;
|
||||
padding-bottom: @footer-margin * 2;
|
||||
}
|
||||
|
||||
&.repositories {
|
||||
.ui.repository.list {
|
||||
.item {
|
||||
border-top: 1px solid #eee;
|
||||
padding-top: 25px;
|
||||
padding-bottom: 25px;
|
||||
.ui.header {
|
||||
font-size: 1.5rem;
|
||||
padding-bottom: 10px;
|
||||
.metas {
|
||||
color: #888;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
span:not(:last-child) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.time {
|
||||
font-size: 12px;
|
||||
color: #808080;
|
||||
.ui.repository.list {
|
||||
.item {
|
||||
padding-bottom: 25px;
|
||||
|
||||
&:not(:first-child) {
|
||||
border-top: 1px solid #eee;
|
||||
padding-top: 25px;
|
||||
}
|
||||
|
||||
.ui.header {
|
||||
font-size: 1.5rem;
|
||||
padding-bottom: 10px;
|
||||
.metas {
|
||||
color: #888;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
span:not(:last-child) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.time {
|
||||
font-size: 12px;
|
||||
color: #808080;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,43 @@
|
||||
.markdown {
|
||||
overflow:hidden;
|
||||
font-family:"Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
|
||||
font-size:16px;
|
||||
line-height:1.6;
|
||||
word-wrap:break-word;
|
||||
overflow: hidden;
|
||||
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6 !important;
|
||||
word-wrap: break-word;
|
||||
|
||||
&.file-view {
|
||||
padding: 5px 2em 2em !important;
|
||||
}
|
||||
|
||||
>*:first-child {
|
||||
margin-top:0 !important;
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
>*:last-child {
|
||||
margin-bottom:0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
a:not([href]) {
|
||||
color:inherit;
|
||||
text-decoration:none;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.absent {
|
||||
color:#c00;
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
.anchor {
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
display:block;
|
||||
padding-right:6px;
|
||||
padding-left:30px;
|
||||
margin-left:-30px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
padding-right: 6px;
|
||||
padding-left: 30px;
|
||||
margin-left: -30px;
|
||||
}
|
||||
|
||||
.anchor:focus {
|
||||
outline:none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
h1,
|
||||
@@ -42,11 +46,11 @@
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
position:relative;
|
||||
margin-top:1em;
|
||||
margin-bottom:16px;
|
||||
font-weight:bold;
|
||||
line-height:1.4;
|
||||
position: relative;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 16px;
|
||||
font-weight: bold;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h1 .octicon-link,
|
||||
@@ -157,8 +161,11 @@
|
||||
dl,
|
||||
table,
|
||||
pre {
|
||||
margin-top:0;
|
||||
margin-bottom:16px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
blockquote {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
@@ -471,124 +478,4 @@
|
||||
font-weight:bold;
|
||||
background:#f8f8f8;border-top:0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Author: jmblog */
|
||||
|
||||
/* Project: https://github.com/jmblog/color-themes-for-google-code-prettify */
|
||||
|
||||
/* GitHub Theme */
|
||||
|
||||
/* Pretty printing styles. Used with prettify.js. */
|
||||
|
||||
/* SPAN elements with the classes below are added by prettyprint. */
|
||||
|
||||
/* plain text */
|
||||
|
||||
.pln {
|
||||
color: #333333;
|
||||
}
|
||||
@media screen {
|
||||
/* string content */
|
||||
.str {
|
||||
color: #dd1144;
|
||||
}
|
||||
/* a keyword */
|
||||
.kwd {
|
||||
color: #333333;
|
||||
}
|
||||
/* a comment */
|
||||
.com {
|
||||
color: #999988;
|
||||
font-style: italic;
|
||||
}
|
||||
/* a type name */
|
||||
.typ {
|
||||
color: #445588;
|
||||
}
|
||||
/* a literal value */
|
||||
.lit {
|
||||
color: #445588;
|
||||
}
|
||||
/* punctuation */
|
||||
.pun {
|
||||
color: #333333;
|
||||
}
|
||||
/* lisp open bracket */
|
||||
.opn {
|
||||
color: #333333;
|
||||
}
|
||||
/* lisp close bracket */
|
||||
.clo {
|
||||
color: #333333;
|
||||
}
|
||||
/* a markup tag name */
|
||||
.tag {
|
||||
color: navy;
|
||||
}
|
||||
/* a markup attribute name */
|
||||
.atn {
|
||||
color: teal;
|
||||
}
|
||||
/* a markup attribute value */
|
||||
.atv {
|
||||
color: #dd1144;
|
||||
}
|
||||
/* a declaration */
|
||||
.dec {
|
||||
color: #333333;
|
||||
}
|
||||
/* a variable name */
|
||||
.var {
|
||||
color: teal;
|
||||
}
|
||||
/* a function name */
|
||||
.fun {
|
||||
color: #990000;
|
||||
}
|
||||
}
|
||||
/* Use higher contrast and text-weight for printable form. */
|
||||
|
||||
@media print,
|
||||
projection {
|
||||
.str {
|
||||
color: #006600;
|
||||
}
|
||||
.kwd {
|
||||
color: #006;
|
||||
font-weight: bold;
|
||||
}
|
||||
.com {
|
||||
color: #600;
|
||||
font-style: italic;
|
||||
}
|
||||
.typ {
|
||||
color: #404;
|
||||
font-weight: bold;
|
||||
}
|
||||
.lit {
|
||||
color: #004444;
|
||||
}
|
||||
.pun,
|
||||
.opn,
|
||||
.clo {
|
||||
color: #444400;
|
||||
}
|
||||
.tag {
|
||||
color: #006;
|
||||
font-weight: bold;
|
||||
}
|
||||
.atn {
|
||||
color: #440044;
|
||||
}
|
||||
.atv {
|
||||
color: #006600;
|
||||
}
|
||||
}
|
||||
/* Specify class=linenums on a pre to get line numbering */
|
||||
|
||||
ol.linenums {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// v3.1.0
|
||||
// v3.3.0
|
||||
@octicons-font-path: "../fonts";
|
||||
@octicons-version: "396334ee3da78f4302d25c758ae3e3ce5dc3c97d";
|
||||
@octicons-version: "30e752e9a0821a0a098947055eeece0b0f46bc34";
|
||||
|
||||
@font-face {
|
||||
font-family: 'octicons';
|
||||
@@ -40,6 +40,7 @@
|
||||
.octicon-microscope:before,
|
||||
.octicon-beaker:before { content: '\f0dd'} /* */
|
||||
.octicon-bell:before { content: '\f0de'} /* */
|
||||
.octicon-bold:before { content: '\f0e2'} /* */
|
||||
.octicon-book:before { content: '\f007'} /* */
|
||||
.octicon-bookmark:before { content: '\f07b'} /* */
|
||||
.octicon-briefcase:before { content: '\f0d3'} /* */
|
||||
@@ -120,6 +121,7 @@
|
||||
.octicon-issue-closed:before { content: '\f028'} /* */
|
||||
.octicon-issue-opened:before { content: '\f026'} /* */
|
||||
.octicon-issue-reopened:before { content: '\f027'} /* */
|
||||
.octicon-italic:before { content: '\f0e4'} /* */
|
||||
.octicon-jersey:before { content: '\f019'} /* */
|
||||
.octicon-key:before { content: '\f049'} /* */
|
||||
.octicon-keyboard:before { content: '\f00d'} /* */
|
||||
@@ -134,6 +136,7 @@
|
||||
.octicon-mirror-private:before,
|
||||
.octicon-git-fork-private:before,
|
||||
.octicon-lock:before { content: '\f06a'} /* */
|
||||
.octicon-logo-gist:before { content: '\f0ad'} /* */
|
||||
.octicon-logo-github:before { content: '\f092'} /* */
|
||||
.octicon-mail:before { content: '\f03b'} /* */
|
||||
.octicon-mail-read:before { content: '\f03c'} /* */
|
||||
@@ -180,8 +183,6 @@
|
||||
.octicon-rocket:before { content: '\f033'} /* */
|
||||
.octicon-rss:before { content: '\f034'} /* */
|
||||
.octicon-ruby:before { content: '\f047'} /* */
|
||||
.octicon-screen-full:before { content: '\f066'} /* */
|
||||
.octicon-screen-normal:before { content: '\f067'} /* */
|
||||
.octicon-search-save:before,
|
||||
.octicon-search:before { content: '\f02e'} /* */
|
||||
.octicon-server:before { content: '\f097'} /* */
|
||||
@@ -201,8 +202,10 @@
|
||||
.octicon-tag-remove:before,
|
||||
.octicon-tag-add:before,
|
||||
.octicon-tag:before { content: '\f015'} /* */
|
||||
.octicon-tasklist:before { content: '\f0e5'} /* */
|
||||
.octicon-telescope:before { content: '\f088'} /* */
|
||||
.octicon-terminal:before { content: '\f0c8'} /* */
|
||||
.octicon-text-size:before { content: '\f0e3'} /* */
|
||||
.octicon-three-bars:before { content: '\f05e'} /* */
|
||||
.octicon-thumbsdown:before { content: '\f0db'} /* */
|
||||
.octicon-thumbsup:before { content: '\f0da'} /* */
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.owner.dropdown {
|
||||
min-width: 40% !important;
|
||||
}
|
||||
|
||||
.metas {
|
||||
.menu {
|
||||
max-height: 300px;
|
||||
@@ -78,6 +82,181 @@
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.file.list {
|
||||
#repo-desc {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.choose.reference {
|
||||
.header .icon {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
}
|
||||
.head.meta {
|
||||
padding: 0;
|
||||
li {
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
|
||||
.ui.breadcrumb {
|
||||
margin-top: -5px;
|
||||
|
||||
span,
|
||||
a {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.clone.input {
|
||||
margin-top: -8px;
|
||||
width: 100%;
|
||||
|
||||
input {
|
||||
border-radius: 0;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.clone.button {
|
||||
font-size: 13px;
|
||||
padding: 0 5px;
|
||||
&:first-child {
|
||||
border-radius: .28571429rem 0 0 .28571429rem;
|
||||
}
|
||||
}
|
||||
.icon.button {
|
||||
padding: 0 10px;
|
||||
}
|
||||
.dropdown .menu {
|
||||
right: 0!important;
|
||||
left: auto!important;
|
||||
}
|
||||
}
|
||||
|
||||
#repo-files-table {
|
||||
.table.list {
|
||||
width: 80% !important;
|
||||
}
|
||||
|
||||
thead {
|
||||
th {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 5px;
|
||||
font-weight: normal;
|
||||
|
||||
#last-commit-message {
|
||||
margin-left: 5px;
|
||||
margin-bottom: -4px;
|
||||
width: 400px;
|
||||
}
|
||||
.age {
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
.ui.avatar {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
.icon {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.name {
|
||||
max-width: 120px;
|
||||
}
|
||||
.message {
|
||||
max-width: 300px;
|
||||
}
|
||||
.age {
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.text.truncate {
|
||||
margin-bottom: -5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
td {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
tr:hover {
|
||||
background-color: #ffffEE;
|
||||
}
|
||||
}
|
||||
|
||||
#file-content {
|
||||
.header {
|
||||
.icon {
|
||||
font-size: 1em;
|
||||
margin-top: -2px;
|
||||
}
|
||||
}
|
||||
.view-raw {
|
||||
* {
|
||||
width: 100%;
|
||||
}
|
||||
img {
|
||||
padding: 5px 5px 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.code-view {
|
||||
* {
|
||||
font-size: 13px;
|
||||
font-family: monospace;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
.lines-num {
|
||||
vertical-align: top;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
background: #f5f5f5;
|
||||
width: 1%;
|
||||
|
||||
span {
|
||||
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
line-height: 20px;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.lines-num,
|
||||
.lines-code {
|
||||
padding: 0;
|
||||
|
||||
|
||||
pre,
|
||||
ol,
|
||||
.hljs {
|
||||
background-color: white;
|
||||
margin: 0;
|
||||
padding: 0 !important;
|
||||
li {
|
||||
padding-left: 5px;
|
||||
&.active {
|
||||
background: #ffffdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
padding-left: 0;
|
||||
|
||||
.octicon {
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.options {
|
||||
#interval {
|
||||
@@ -420,11 +599,6 @@
|
||||
padding: 5px 10px;
|
||||
}
|
||||
}
|
||||
.button {
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -619,9 +793,203 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.release {
|
||||
#release-list {
|
||||
border-top: 1px solid #DDD;
|
||||
margin-top: 20px;
|
||||
padding-top: 15px;
|
||||
|
||||
>li {
|
||||
list-style: none;
|
||||
|
||||
.meta,
|
||||
.detail {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
.meta {
|
||||
text-align: right;
|
||||
position: relative;
|
||||
|
||||
.tag:not(.icon) {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.commit {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
.detail {
|
||||
border-left: 1px solid #DDD;
|
||||
|
||||
.author {
|
||||
img {
|
||||
margin-bottom: -3px;
|
||||
}
|
||||
}
|
||||
.download {
|
||||
margin-top: 20px;
|
||||
|
||||
>a {
|
||||
.octicon {
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
padding-left: 0;
|
||||
border-top: 1px solid #eee;
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
display: block;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
.dot {
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
background-color: #ccc;
|
||||
z-index: 999;
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: -5px;
|
||||
top: 40px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #FFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.new.release {
|
||||
.target {
|
||||
min-width: 500px;
|
||||
|
||||
.at {
|
||||
margin-left: -5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.dropdown.icon {
|
||||
margin: 0;
|
||||
padding-top: 3px;
|
||||
}
|
||||
.selection.dropdown {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
.prerelease.field {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.watchers {
|
||||
.list {
|
||||
padding: 0;
|
||||
|
||||
.item {
|
||||
list-style: none;
|
||||
width: 32%;
|
||||
margin: 10px 10px 10px 0;
|
||||
padding-bottom: 14px;
|
||||
float: left;
|
||||
|
||||
.avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
float: left;
|
||||
display: block;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.name {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
.meta {
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.forks {
|
||||
.list {
|
||||
margin-top: 0;
|
||||
|
||||
.item {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #DDD;
|
||||
|
||||
.ui.avatar {
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.link {
|
||||
padding-top: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.settings {
|
||||
&.collaboration {
|
||||
.collaborator.list {
|
||||
padding: 0;
|
||||
|
||||
.item {
|
||||
padding: 10px 20px;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid #DDD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#repo-collab-form {
|
||||
#search-user-box {
|
||||
.results {
|
||||
left: 7px;
|
||||
}
|
||||
}
|
||||
.ui.button {
|
||||
margin-left: 5px;
|
||||
margin-top: -3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// End of .repository
|
||||
|
||||
#search-user-box {
|
||||
.results {
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
|
||||
.item {
|
||||
padding: 10px 15px;
|
||||
border-bottom: 1px solid #DDD;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0,0,0,.05)!important;
|
||||
color: rgba(0,0,0,.95)!important;
|
||||
}
|
||||
img {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.issue.list {
|
||||
list-style: none;
|
||||
padding-top: 15px;
|
||||
@@ -679,7 +1047,7 @@
|
||||
.settings {
|
||||
.content {
|
||||
margin-top: 2px;
|
||||
.header,
|
||||
>.header,
|
||||
.segment {
|
||||
box-shadow: 0 1px 2px 0 rgba(34,36,38,.15);
|
||||
}
|
||||
|
||||
@@ -18,4 +18,33 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.profile {
|
||||
.ui.card {
|
||||
.username {
|
||||
display: block;
|
||||
}
|
||||
.extra.content {
|
||||
padding: 0;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
padding: 10px;
|
||||
list-style: none;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ui.repository.list {
|
||||
margin-top: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,6 +116,7 @@ type AdminOperation int
|
||||
const (
|
||||
CLEAN_INACTIVATE_USER AdminOperation = iota + 1
|
||||
CLEAN_REPO_ARCHIVES
|
||||
CLEAN_MISSING_REPOS
|
||||
GIT_GC_REPOS
|
||||
SYNC_SSH_AUTHORIZED_KEY
|
||||
SYNC_REPOSITORY_UPDATE_HOOK
|
||||
@@ -139,6 +140,9 @@ func Dashboard(ctx *middleware.Context) {
|
||||
case CLEAN_REPO_ARCHIVES:
|
||||
success = ctx.Tr("admin.dashboard.delete_repo_archives_success")
|
||||
err = models.DeleteRepositoryArchives()
|
||||
case CLEAN_MISSING_REPOS:
|
||||
success = ctx.Tr("admin.dashboard.delete_missing_repos_success")
|
||||
err = models.DeleteMissingRepositories()
|
||||
case GIT_GC_REPOS:
|
||||
success = ctx.Tr("admin.dashboard.git_gc_repos_success")
|
||||
err = models.GitGcRepos()
|
||||
|
||||
@@ -106,9 +106,9 @@ func ListMyRepos(ctx *middleware.Context) {
|
||||
}
|
||||
numOwnRepos := len(ownRepos)
|
||||
|
||||
accessibleRepos, err := ctx.User.GetAccessibleRepositories()
|
||||
accessibleRepos, err := ctx.User.GetRepositoryAccesses()
|
||||
if err != nil {
|
||||
ctx.APIError(500, "GetAccessibleRepositories", err)
|
||||
ctx.APIError(500, "GetRepositoryAccesses", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -44,9 +44,9 @@ func ToApiHook(repoLink string, w *models.Webhook) *api.Hook {
|
||||
|
||||
// https://github.com/gogits/go-gogs-client/wiki/Repositories#list-hooks
|
||||
func ListRepoHooks(ctx *middleware.Context) {
|
||||
hooks, err := models.GetWebhooksByRepoId(ctx.Repo.Repository.ID)
|
||||
hooks, err := models.GetWebhooksByRepoID(ctx.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
ctx.APIError(500, "GetWebhooksByRepoId", err)
|
||||
ctx.APIError(500, "GetWebhooksByRepoID", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -127,7 +127,11 @@ func CreateRepoHook(ctx *middleware.Context, form api.CreateHookOption) {
|
||||
func EditRepoHook(ctx *middleware.Context, form api.EditHookOption) {
|
||||
w, err := models.GetWebhookByID(ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
ctx.APIError(500, "GetWebhookById", err)
|
||||
if models.IsErrWebhookNotExist(err) {
|
||||
ctx.Error(404)
|
||||
} else {
|
||||
ctx.APIError(500, "GetWebhookById", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
115
routers/api/v1/repo_keys.go
Normal file
115
routers/api/v1/repo_keys.go
Normal file
@@ -0,0 +1,115 @@
|
||||
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
|
||||
api "github.com/gogits/go-gogs-client"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
func ToApiDeployKey(apiLink string, key *models.DeployKey) *api.DeployKey {
|
||||
return &api.DeployKey{
|
||||
ID: key.ID,
|
||||
Key: key.Content,
|
||||
URL: apiLink + com.ToStr(key.ID),
|
||||
Title: key.Name,
|
||||
Created: key.Created,
|
||||
ReadOnly: true, // All deploy keys are read-only.
|
||||
}
|
||||
}
|
||||
|
||||
func composeDeployKeysAPILink(repoPath string) string {
|
||||
return setting.AppUrl + "api/v1/repos/" + repoPath + "/keys/"
|
||||
}
|
||||
|
||||
// https://github.com/gogits/go-gogs-client/wiki/Repositories---Deploy-Keys#list-deploy-keys
|
||||
func ListRepoDeployKeys(ctx *middleware.Context) {
|
||||
keys, err := models.ListDeployKeys(ctx.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "ListDeployKeys", err)
|
||||
return
|
||||
}
|
||||
|
||||
apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name)
|
||||
apiKeys := make([]*api.DeployKey, len(keys))
|
||||
for i := range keys {
|
||||
if err = keys[i].GetContent(); err != nil {
|
||||
ctx.APIError(500, "GetContent", err)
|
||||
return
|
||||
}
|
||||
apiKeys[i] = ToApiDeployKey(apiLink, keys[i])
|
||||
}
|
||||
|
||||
ctx.JSON(200, &apiKeys)
|
||||
}
|
||||
|
||||
// https://github.com/gogits/go-gogs-client/wiki/Repositories---Deploy-Keys#get-a-deploy-key
|
||||
func GetRepoDeployKey(ctx *middleware.Context) {
|
||||
key, err := models.GetDeployKeyByID(ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrDeployKeyNotExist(err) {
|
||||
ctx.Error(404)
|
||||
} else {
|
||||
ctx.Handle(500, "GetDeployKeyByID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err = key.GetContent(); err != nil {
|
||||
ctx.APIError(500, "GetContent", err)
|
||||
return
|
||||
}
|
||||
|
||||
apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name)
|
||||
ctx.JSON(200, ToApiDeployKey(apiLink, key))
|
||||
}
|
||||
|
||||
// https://github.com/gogits/go-gogs-client/wiki/Repositories---Deploy-Keys#add-a-new-deploy-key
|
||||
func CreateRepoDeployKey(ctx *middleware.Context, form api.CreateDeployKeyOption) {
|
||||
content, err := models.CheckPublicKeyString(form.Key)
|
||||
if err != nil {
|
||||
if models.IsErrKeyUnableVerify(err) {
|
||||
ctx.APIError(422, "", "Unable to verify key content")
|
||||
} else {
|
||||
ctx.APIError(422, "", fmt.Errorf("Invalid key content: %v", err))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
key, err := models.AddDeployKey(ctx.Repo.Repository.ID, form.Title, content)
|
||||
if err != nil {
|
||||
ctx.Data["HasError"] = true
|
||||
switch {
|
||||
case models.IsErrKeyAlreadyExist(err):
|
||||
ctx.APIError(422, "", "Key content has been used as non-deploy key")
|
||||
case models.IsErrKeyNameAlreadyUsed(err):
|
||||
ctx.APIError(422, "", "Key title has been used")
|
||||
default:
|
||||
ctx.APIError(500, "AddDeployKey", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
key.Content = content
|
||||
apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name)
|
||||
ctx.JSON(201, ToApiDeployKey(apiLink, key))
|
||||
}
|
||||
|
||||
// https://github.com/gogits/go-gogs-client/wiki/Repositories---Deploy-Keys#remove-a-deploy-key
|
||||
func DeleteRepoDeploykey(ctx *middleware.Context) {
|
||||
if err := models.DeleteDeployKey(ctx.ParamsInt64(":id")); err != nil {
|
||||
ctx.APIError(500, "DeleteDeployKey", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(204)
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func SearchUsers(ctx *middleware.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Render.JSON(200, map[string]interface{}{
|
||||
ctx.JSON(200, map[string]interface{}{
|
||||
"ok": true,
|
||||
"data": results,
|
||||
})
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
)
|
||||
|
||||
const (
|
||||
FORKS base.TplName = "repo/forks"
|
||||
)
|
||||
|
||||
func Forks(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repos.forks")
|
||||
|
||||
forks, err := ctx.Repo.Repository.GetForks()
|
||||
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetForks", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, fork := range forks {
|
||||
if err = fork.GetOwner(); err != nil {
|
||||
ctx.Handle(500, "GetOwner", fmt.Errorf("%d: %v", fork.ID, err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["Forks"] = forks
|
||||
|
||||
ctx.HTML(200, FORKS)
|
||||
}
|
||||
@@ -59,6 +59,7 @@ func Issues(ctx *middleware.Context) {
|
||||
if isPullList {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.pulls")
|
||||
ctx.Data["PageIsPullList"] = true
|
||||
ctx.Data["HasForkedRepo"] = ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)
|
||||
} else {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.issues")
|
||||
ctx.Data["PageIsIssueList"] = true
|
||||
@@ -493,6 +494,7 @@ func ViewIssue(ctx *middleware.Context) {
|
||||
|
||||
ctx.Data["PageIsPullList"] = true
|
||||
ctx.Data["PageIsPullConversation"] = true
|
||||
ctx.Data["HasForkedRepo"] = ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)
|
||||
} else {
|
||||
ctx.Data["PageIsIssueList"] = true
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ func getForkRepository(ctx *middleware.Context) *models.Repository {
|
||||
}
|
||||
|
||||
ctx.Data["repo_name"] = forkRepo.Name
|
||||
ctx.Data["desc"] = forkRepo.Description
|
||||
ctx.Data["description"] = forkRepo.Description
|
||||
ctx.Data["IsPrivate"] = forkRepo.IsPrivate
|
||||
|
||||
if err = forkRepo.GetOwner(); err != nil {
|
||||
|
||||
@@ -13,15 +13,13 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
RELEASES base.TplName = "repo/release/list"
|
||||
RELEASE_NEW base.TplName = "repo/release/new"
|
||||
RELEASE_EDIT base.TplName = "repo/release/edit"
|
||||
RELEASES base.TplName = "repo/release/list"
|
||||
RELEASE_NEW base.TplName = "repo/release/new"
|
||||
)
|
||||
|
||||
func Releases(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.release.releases")
|
||||
ctx.Data["IsRepoToolbarReleases"] = true
|
||||
ctx.Data["IsRepoReleaseNew"] = false
|
||||
ctx.Data["PageIsReleaseList"] = true
|
||||
|
||||
rawTags, err := ctx.Repo.GitRepo.GetTags()
|
||||
if err != nil {
|
||||
@@ -29,9 +27,9 @@ func Releases(ctx *middleware.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
rels, err := models.GetReleasesByRepoId(ctx.Repo.Repository.ID)
|
||||
rels, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetReleasesByRepoId", err)
|
||||
ctx.Handle(500, "GetReleasesByRepoID", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -45,7 +43,7 @@ func Releases(ctx *middleware.Context) {
|
||||
continue
|
||||
}
|
||||
if rel.TagName == rawTag {
|
||||
rel.Publisher, err = models.GetUserByID(rel.PublisherId)
|
||||
rel.Publisher, err = models.GetUserByID(rel.PublisherID)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetUserById", err)
|
||||
return
|
||||
@@ -105,7 +103,7 @@ func Releases(ctx *middleware.Context) {
|
||||
continue
|
||||
}
|
||||
|
||||
rel.Publisher, err = models.GetUserByID(rel.PublisherId)
|
||||
rel.Publisher, err = models.GetUserByID(rel.PublisherID)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetUserById", err)
|
||||
return
|
||||
@@ -140,27 +138,15 @@ func Releases(ctx *middleware.Context) {
|
||||
}
|
||||
|
||||
func NewRelease(ctx *middleware.Context) {
|
||||
if !ctx.Repo.IsOwner() {
|
||||
ctx.Handle(403, "release.ReleasesNew", nil)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("repo.release.new_release")
|
||||
ctx.Data["PageIsReleaseList"] = true
|
||||
ctx.Data["tag_target"] = ctx.Repo.Repository.DefaultBranch
|
||||
ctx.Data["IsRepoToolbarReleases"] = true
|
||||
ctx.Data["IsRepoReleaseNew"] = true
|
||||
ctx.HTML(200, RELEASE_NEW)
|
||||
}
|
||||
|
||||
func NewReleasePost(ctx *middleware.Context, form auth.NewReleaseForm) {
|
||||
if !ctx.Repo.IsOwner() {
|
||||
ctx.Handle(403, "release.ReleasesNew", nil)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("repo.release.new_release")
|
||||
ctx.Data["IsRepoToolbarReleases"] = true
|
||||
ctx.Data["IsRepoReleaseNew"] = true
|
||||
ctx.Data["PageIsReleaseList"] = true
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.HTML(200, RELEASE_NEW)
|
||||
@@ -185,8 +171,8 @@ func NewReleasePost(ctx *middleware.Context, form auth.NewReleaseForm) {
|
||||
}
|
||||
|
||||
rel := &models.Release{
|
||||
RepoId: ctx.Repo.Repository.ID,
|
||||
PublisherId: ctx.User.Id,
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
PublisherID: ctx.User.Id,
|
||||
Title: form.Title,
|
||||
TagName: form.TagName,
|
||||
Target: form.Target,
|
||||
@@ -198,67 +184,70 @@ func NewReleasePost(ctx *middleware.Context, form auth.NewReleaseForm) {
|
||||
}
|
||||
|
||||
if err = models.CreateRelease(ctx.Repo.GitRepo, rel); err != nil {
|
||||
if err == models.ErrReleaseAlreadyExist {
|
||||
if models.IsErrReleaseAlreadyExist(err) {
|
||||
ctx.Data["Err_TagName"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("repo.release.tag_name_already_exist"), RELEASE_NEW, &form)
|
||||
} else {
|
||||
ctx.Handle(500, "CreateRelease", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("%s Release created: %s/%s:%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.Name, form.TagName)
|
||||
log.Trace("Release created: %s/%s:%s", ctx.User.LowerName, ctx.Repo.Repository.Name, form.TagName)
|
||||
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/releases")
|
||||
}
|
||||
|
||||
func EditRelease(ctx *middleware.Context) {
|
||||
if !ctx.Repo.IsOwner() {
|
||||
ctx.Handle(403, "release.ReleasesEdit", nil)
|
||||
return
|
||||
}
|
||||
ctx.Data["Title"] = ctx.Tr("repo.release.edit_release")
|
||||
ctx.Data["PageIsReleaseList"] = true
|
||||
ctx.Data["PageIsEditRelease"] = true
|
||||
|
||||
tagName := ctx.Params(":tagname")
|
||||
rel, err := models.GetRelease(ctx.Repo.Repository.ID, tagName)
|
||||
if err != nil {
|
||||
if err == models.ErrReleaseNotExist {
|
||||
if models.IsErrReleaseNotExist(err) {
|
||||
ctx.Handle(404, "GetRelease", err)
|
||||
} else {
|
||||
ctx.Handle(500, "GetRelease", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx.Data["Release"] = rel
|
||||
ctx.Data["ID"] = rel.ID
|
||||
ctx.Data["tag_name"] = rel.TagName
|
||||
ctx.Data["tag_target"] = rel.Target
|
||||
ctx.Data["title"] = rel.Title
|
||||
ctx.Data["content"] = rel.Note
|
||||
ctx.Data["prerelease"] = rel.IsPrerelease
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("repo.release.edit_release")
|
||||
ctx.Data["IsRepoToolbarReleases"] = true
|
||||
ctx.HTML(200, RELEASE_EDIT)
|
||||
ctx.HTML(200, RELEASE_NEW)
|
||||
}
|
||||
|
||||
func EditReleasePost(ctx *middleware.Context, form auth.EditReleaseForm) {
|
||||
if !ctx.Repo.IsOwner() {
|
||||
ctx.Handle(403, "release.EditReleasePost", nil)
|
||||
return
|
||||
}
|
||||
ctx.Data["Title"] = ctx.Tr("repo.release.edit_release")
|
||||
ctx.Data["PageIsReleaseList"] = true
|
||||
ctx.Data["PageIsEditRelease"] = true
|
||||
|
||||
tagName := ctx.Params(":tagname")
|
||||
rel, err := models.GetRelease(ctx.Repo.Repository.ID, tagName)
|
||||
if err != nil {
|
||||
if err == models.ErrReleaseNotExist {
|
||||
if models.IsErrReleaseNotExist(err) {
|
||||
ctx.Handle(404, "GetRelease", err)
|
||||
} else {
|
||||
ctx.Handle(500, "GetRelease", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx.Data["Release"] = rel
|
||||
ctx.Data["tag_name"] = rel.TagName
|
||||
ctx.Data["tag_target"] = rel.Target
|
||||
ctx.Data["title"] = rel.Title
|
||||
ctx.Data["content"] = rel.Note
|
||||
ctx.Data["prerelease"] = rel.IsPrerelease
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.HTML(200, RELEASE_EDIT)
|
||||
ctx.HTML(200, RELEASE_NEW)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("repo.release.edit_release")
|
||||
ctx.Data["IsRepoToolbarReleases"] = true
|
||||
|
||||
rel.Title = form.Title
|
||||
rel.Note = form.Content
|
||||
rel.IsDraft = len(form.Draft) > 0
|
||||
@@ -269,3 +258,15 @@ func EditReleasePost(ctx *middleware.Context, form auth.EditReleaseForm) {
|
||||
}
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/releases")
|
||||
}
|
||||
|
||||
func DeleteRelease(ctx *middleware.Context) {
|
||||
if err := models.DeleteReleaseByID(ctx.QueryInt64("id")); err != nil {
|
||||
ctx.Flash.Error("DeleteReleaseByID: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("repo.release.deletion_success"))
|
||||
}
|
||||
|
||||
ctx.JSON(200, map[string]interface{}{
|
||||
"redirect": ctx.Repo.RepoLink + "/releases",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -204,11 +204,14 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
|
||||
}
|
||||
|
||||
if strings.Contains(err.Error(), "Authentication failed") ||
|
||||
strings.Contains(err.Error(), " not found") ||
|
||||
strings.Contains(err.Error(), "could not read Username") {
|
||||
ctx.Data["Err_Auth"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.auth_failed", strings.Replace(err.Error(), ":"+form.AuthPassword+"@", ":<password>@", 1)), MIGRATE, &form)
|
||||
return
|
||||
} else if strings.Contains(err.Error(), "fatal:") {
|
||||
ctx.Data["Err_CloneAddr"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("repo.migrate.failed", strings.Replace(err.Error(), ":"+form.AuthPassword+"@", ":<password>@", 1)), MIGRATE, &form)
|
||||
return
|
||||
}
|
||||
|
||||
handleCreateError(ctx, err, "MigratePost", MIGRATE, &form)
|
||||
|
||||
@@ -80,11 +80,24 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
|
||||
repo.Name = newRepoName
|
||||
repo.LowerName = strings.ToLower(newRepoName)
|
||||
|
||||
if ctx.Repo.GitRepo.IsBranchExist(form.Branch) {
|
||||
if ctx.Repo.GitRepo.IsBranchExist(form.Branch) &&
|
||||
repo.DefaultBranch != form.Branch {
|
||||
repo.DefaultBranch = form.Branch
|
||||
if err := ctx.Repo.GitRepo.SetDefaultBranch(form.Branch); err != nil {
|
||||
if !git.IsErrUnsupportedVersion(err) {
|
||||
ctx.Handle(500, "SetDefaultBranch", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
repo.Description = form.Description
|
||||
repo.Website = form.Website
|
||||
|
||||
// Visibility of forked repository is forced sync with base repository.
|
||||
if repo.IsFork {
|
||||
form.Private = repo.BaseRepo.IsPrivate
|
||||
}
|
||||
|
||||
visibilityChanged := repo.IsPrivate != form.Private
|
||||
repo.IsPrivate = form.Private
|
||||
if err := models.UpdateRepository(repo, visibilityChanged); err != nil {
|
||||
@@ -246,9 +259,9 @@ func Webhooks(ctx *middleware.Context) {
|
||||
ctx.Data["BaseLink"] = ctx.Repo.RepoLink
|
||||
ctx.Data["Description"] = ctx.Tr("repo.settings.hooks_desc", "https://github.com/gogits/go-gogs-client/wiki/Repositories---Webhooks")
|
||||
|
||||
ws, err := models.GetWebhooksByRepoId(ctx.Repo.Repository.ID)
|
||||
ws, err := models.GetWebhooksByRepoID(ctx.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetWebhooksByRepoId", err)
|
||||
ctx.Handle(500, "GetWebhooksByRepoID", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Webhooks"] = ws
|
||||
@@ -671,7 +684,7 @@ func DeployKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
||||
|
||||
content, err := models.CheckPublicKeyString(form.Content)
|
||||
if err != nil {
|
||||
if err == models.ErrKeyUnableVerify {
|
||||
if models.IsErrKeyUnableVerify(err) {
|
||||
ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key"))
|
||||
} else {
|
||||
ctx.Data["HasError"] = true
|
||||
@@ -682,7 +695,8 @@ func DeployKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
||||
}
|
||||
}
|
||||
|
||||
if err = models.AddDeployKey(ctx.Repo.Repository.ID, form.Title, content); err != nil {
|
||||
key, err := models.AddDeployKey(ctx.Repo.Repository.ID, form.Title, content)
|
||||
if err != nil {
|
||||
ctx.Data["HasError"] = true
|
||||
switch {
|
||||
case models.IsErrKeyAlreadyExist(err):
|
||||
@@ -698,7 +712,7 @@ func DeployKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
||||
}
|
||||
|
||||
log.Trace("Deploy key added: %d", ctx.Repo.Repository.ID)
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.add_key_success", form.Title))
|
||||
ctx.Flash.Success(ctx.Tr("repo.settings.add_key_success", key.Name))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/settings/keys")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"github.com/Unknwon/paginater"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
)
|
||||
|
||||
const (
|
||||
STARS base.TplName = "repo/stars"
|
||||
)
|
||||
|
||||
func Stars(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repos.stars")
|
||||
|
||||
page := ctx.QueryInt("page")
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
ctx.Data["Page"] = paginater.New(ctx.Repo.Repository.NumStars, models.ItemsPerPage, page, 5)
|
||||
|
||||
stars, err := ctx.Repo.Repository.GetStars(ctx.QueryInt("page"))
|
||||
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetStars", err)
|
||||
return
|
||||
}
|
||||
|
||||
if (ctx.QueryInt("page")-1)*models.ItemsPerPage > ctx.Repo.Repository.NumStars {
|
||||
ctx.Handle(404, "ctx.Repo.Repository.NumStars", nil)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Stars"] = stars
|
||||
|
||||
ctx.HTML(200, STARS)
|
||||
}
|
||||
@@ -11,19 +11,25 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/Unknwon/paginater"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/git"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
"github.com/gogits/gogs/modules/template"
|
||||
)
|
||||
|
||||
const (
|
||||
HOME base.TplName = "repo/home"
|
||||
HOME base.TplName = "repo/home"
|
||||
WATCHERS base.TplName = "repo/watchers"
|
||||
FORKS base.TplName = "repo/forks"
|
||||
)
|
||||
|
||||
func Home(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Repo.Repository.Name
|
||||
ctx.Data["RequireHighlightJS"] = true
|
||||
|
||||
branchName := ctx.Repo.BranchName
|
||||
userName := ctx.Repo.Owner.Name
|
||||
@@ -105,7 +111,7 @@ func Home(ctx *middleware.Context) {
|
||||
if readmeExist {
|
||||
ctx.Data["FileContent"] = string(base.RenderMarkdown(buf, path.Dir(treeLink)))
|
||||
} else {
|
||||
if err, content := base.ToUtf8WithErr(buf); err != nil {
|
||||
if err, content := template.ToUtf8WithErr(buf); err != nil {
|
||||
if err != nil {
|
||||
log.Error(4, "Convert content encoding: %s", err)
|
||||
}
|
||||
@@ -243,3 +249,53 @@ func Home(ctx *middleware.Context) {
|
||||
ctx.Data["BranchLink"] = branchLink
|
||||
ctx.HTML(200, HOME)
|
||||
}
|
||||
|
||||
func renderItems(ctx *middleware.Context, total int, getter func(page int) ([]*models.User, error)) {
|
||||
page := ctx.QueryInt("page")
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
pager := paginater.New(total, models.ItemsPerPage, page, 5)
|
||||
ctx.Data["Page"] = pager
|
||||
|
||||
items, err := getter(pager.Current())
|
||||
if err != nil {
|
||||
ctx.Handle(500, "getter", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Watchers"] = items
|
||||
|
||||
ctx.HTML(200, WATCHERS)
|
||||
}
|
||||
|
||||
func Watchers(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.watchers")
|
||||
ctx.Data["PageIsWatchers"] = true
|
||||
renderItems(ctx, ctx.Repo.Repository.NumWatches, ctx.Repo.Repository.GetWatchers)
|
||||
}
|
||||
|
||||
func Stars(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.stargazers")
|
||||
ctx.Data["PageIsStargazers"] = true
|
||||
renderItems(ctx, ctx.Repo.Repository.NumStars, ctx.Repo.Repository.GetStargazers)
|
||||
}
|
||||
|
||||
func Forks(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repos.forks")
|
||||
|
||||
forks, err := ctx.Repo.Repository.GetForks()
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetForks", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, fork := range forks {
|
||||
if err = fork.GetOwner(); err != nil {
|
||||
ctx.Handle(500, "GetOwner", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
ctx.Data["Forks"] = forks
|
||||
|
||||
ctx.HTML(200, FORKS)
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"github.com/Unknwon/paginater"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
)
|
||||
|
||||
const (
|
||||
WATCHERS base.TplName = "repo/watchers"
|
||||
)
|
||||
|
||||
func Watchers(ctx *middleware.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repos.watches")
|
||||
|
||||
page := ctx.QueryInt("page")
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
ctx.Data["Page"] = paginater.New(ctx.Repo.Repository.NumWatches, models.ItemsPerPage, page, 5)
|
||||
|
||||
watchers, err := ctx.Repo.Repository.GetWatchers(ctx.QueryInt("page"))
|
||||
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetWatchers", err)
|
||||
return
|
||||
}
|
||||
|
||||
if (ctx.QueryInt("page")-1)*models.ItemsPerPage > ctx.Repo.Repository.NumWatches {
|
||||
ctx.Handle(404, "ctx.Repo.Repository.NumWatches", nil)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Watchers"] = watchers
|
||||
|
||||
ctx.HTML(200, WATCHERS)
|
||||
}
|
||||
@@ -40,8 +40,9 @@ func SignIn(ctx *middleware.Context) {
|
||||
if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
|
||||
ctx.SetCookie("redirect_to", "", -1, setting.AppSubUrl)
|
||||
ctx.Redirect(redirectTo)
|
||||
} else {
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
}
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -253,7 +254,7 @@ func ActivateEmail(ctx *middleware.Context) {
|
||||
}
|
||||
|
||||
log.Trace("Email activated: %s", email.Email)
|
||||
ctx.Flash.Success(ctx.Tr("settings.add_email_successs"))
|
||||
ctx.Flash.Success(ctx.Tr("settings.add_email_success"))
|
||||
}
|
||||
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
|
||||
|
||||
@@ -62,23 +62,21 @@ func Dashboard(ctx *middleware.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check context type.
|
||||
if !ctxUser.IsOrganization() {
|
||||
// Normal user.
|
||||
ctxUser = ctx.User
|
||||
collaborates, err := ctx.User.GetAccessibleRepositories()
|
||||
collaborateRepos, err := ctx.User.GetAccessibleRepositories()
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetAccessibleRepositories", err)
|
||||
return
|
||||
}
|
||||
|
||||
repositories := make([]*models.Repository, 0, len(collaborates))
|
||||
for repo := range collaborates {
|
||||
repositories = append(repositories, repo)
|
||||
for i := range collaborateRepos {
|
||||
if err = collaborateRepos[i].GetOwner(); err != nil {
|
||||
ctx.Handle(500, "GetOwner: "+collaborateRepos[i].Name, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Data["CollaborateCount"] = len(repositories)
|
||||
ctx.Data["CollaborativeRepos"] = repositories
|
||||
ctx.Data["CollaborateCount"] = len(collaborateRepos)
|
||||
ctx.Data["CollaborativeRepos"] = collaborateRepos
|
||||
}
|
||||
|
||||
repos, err := models.GetRepositories(ctxUser.Id, true)
|
||||
@@ -89,7 +87,7 @@ func Dashboard(ctx *middleware.Context) {
|
||||
ctx.Data["Repos"] = repos
|
||||
|
||||
// Get mirror repositories.
|
||||
mirrors := make([]*models.Repository, 0, len(repos)/2)
|
||||
mirrors := make([]*models.Repository, 0, 5)
|
||||
for _, repo := range repos {
|
||||
if repo.IsMirror {
|
||||
if err = repo.GetMirror(); err != nil {
|
||||
@@ -111,6 +109,7 @@ func Dashboard(ctx *middleware.Context) {
|
||||
|
||||
// Check access of private repositories.
|
||||
feeds := make([]*models.Action, 0, len(actions))
|
||||
unameAvatars := make(map[string]string)
|
||||
for _, act := range actions {
|
||||
if act.IsPrivate {
|
||||
// This prevents having to retrieve the repository for each action
|
||||
@@ -122,16 +121,22 @@ func Dashboard(ctx *middleware.Context) {
|
||||
}
|
||||
|
||||
}
|
||||
// FIXME: cache results?
|
||||
u, err := models.GetUserByName(act.ActUserName)
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
continue
|
||||
|
||||
// Cache results to reduce queries.
|
||||
_, ok := unameAvatars[act.ActUserName]
|
||||
if !ok {
|
||||
u, err := models.GetUserByName(act.ActUserName)
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
continue
|
||||
}
|
||||
ctx.Handle(500, "GetUserByName", err)
|
||||
return
|
||||
}
|
||||
ctx.Handle(500, "GetUserByName", err)
|
||||
return
|
||||
unameAvatars[act.ActUserName] = u.AvatarLink()
|
||||
}
|
||||
act.ActAvatar = u.AvatarLink()
|
||||
|
||||
act.ActAvatar = unameAvatars[act.ActUserName]
|
||||
feeds = append(feeds, act)
|
||||
}
|
||||
ctx.Data["Feeds"] = feeds
|
||||
@@ -314,6 +319,9 @@ func Profile(ctx *middleware.Context) {
|
||||
if uname == "favicon.ico" {
|
||||
ctx.Redirect(setting.AppSubUrl + "/img/favicon.png")
|
||||
return
|
||||
} else if strings.HasSuffix(uname, ".png") {
|
||||
ctx.Error(404)
|
||||
return
|
||||
}
|
||||
|
||||
isShowKeys := false
|
||||
@@ -348,7 +356,7 @@ func Profile(ctx *middleware.Context) {
|
||||
ctx.Data["TabName"] = tab
|
||||
switch tab {
|
||||
case "activity":
|
||||
actions, err := models.GetFeeds(u.Id, 0, false)
|
||||
actions, err := models.GetFeeds(u.Id, 0, true)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetFeeds", err)
|
||||
return
|
||||
|
||||
@@ -286,7 +286,7 @@ func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
||||
|
||||
content, err := models.CheckPublicKeyString(form.Content)
|
||||
if err != nil {
|
||||
if err == models.ErrKeyUnableVerify {
|
||||
if models.IsErrKeyUnableVerify(err) {
|
||||
ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key"))
|
||||
} else {
|
||||
ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error()))
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.7.6.1112 Beta
|
||||
0.7.19.1121 Beta
|
||||
@@ -1,213 +1,190 @@
|
||||
{{template "ng/base/head" .}}
|
||||
{{template "ng/base/header" .}}
|
||||
<div id="admin-wrapper">
|
||||
<div id="setting-wrapper" class="main-wrapper">
|
||||
<div id="admin-setting" class="container clear">
|
||||
{{template "admin/nav" .}}
|
||||
<div class="grid-4-5 left">
|
||||
<div class="setting-content">
|
||||
{{template "ng/base/alert" .}}
|
||||
<div id="setting-content">
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.config.server_config"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.app_name"}}</dt>
|
||||
<dd>{{AppName}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.app_ver"}}</dt>
|
||||
<dd>{{AppVer}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.app_url"}}</dt>
|
||||
<dd>{{.AppUrl}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.domain"}}</dt>
|
||||
<dd>{{.Domain}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.offline_mode"}}</dt>
|
||||
<dd><i class="fa fa{{if .OfflineMode}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.disable_router_log"}}</dt>
|
||||
<dd><i class="fa fa{{if .DisableRouterLog}}-check{{end}}-square-o"></i></dd>
|
||||
<hr/>
|
||||
<dt>{{.i18n.Tr "admin.config.run_user"}}</dt>
|
||||
<dd>{{.RunUser}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.run_mode"}}</dt>
|
||||
<dd>{{.RunMode}}</dd>
|
||||
<hr/>
|
||||
<dt>{{.i18n.Tr "admin.config.repo_root_path"}}</dt>
|
||||
<dd>{{.RepoRootPath}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.static_file_root_path"}}</dt>
|
||||
<dd>{{.StaticRootPath}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.log_file_root_path"}}</dt>
|
||||
<dd>{{.LogRootPath}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.script_type"}}</dt>
|
||||
<dd>{{.ScriptType}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.reverse_auth_user"}}</dt>
|
||||
<dd>{{.ReverseProxyAuthUser}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.config.db_config"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.db_type"}}</dt>
|
||||
<dd>{{.DbCfg.Type}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.db_host"}}</dt>
|
||||
<dd>{{.DbCfg.Host}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.db_name"}}</dt>
|
||||
<dd>{{.DbCfg.Name}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.db_user"}}</dt>
|
||||
<dd>{{.DbCfg.User}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.db_ssl_mode"}}</dt>
|
||||
<dd>{{.DbCfg.SSLMode}} {{.i18n.Tr "admin.config.db_ssl_mode_helper"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.db_path"}}</dt>
|
||||
<dd>{{.DbCfg.Path}} {{.i18n.Tr "admin.config.db_path_helper"}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.config.service_config"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.register_email_confirm"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.RegisterEmailConfirm}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.disable_register"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.DisableRegistration}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.show_registration_button"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.ShowRegistrationButton}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.require_sign_in_view"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.RequireSignInView}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.enable_cache_avatar"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.EnableCacheAvatar}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mail_notify"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.EnableNotifyMail}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.disable_key_size_check"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.DisableMinimumKeySizeCheck}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.enable_captcha"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.EnableCaptcha}}-check{{end}}-square-o"></i></dd>
|
||||
<hr/>
|
||||
<dt>{{.i18n.Tr "admin.config.active_code_lives"}}</dt>
|
||||
<dd>{{.Service.ActiveCodeLives}} {{.i18n.Tr "tool.raw_minutes"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.reset_password_code_lives"}}</dt>
|
||||
<dd>{{.Service.ResetPwdCodeLives}} {{.i18n.Tr "tool.raw_minutes"}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.config.webhook_config"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.queue_length"}}</dt>
|
||||
<dd>{{.Webhook.QueueLength}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.deliver_timeout"}}</dt>
|
||||
<dd>{{.Webhook.DeliverTimeout}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.skip_tls_verify"}}</dt>
|
||||
<dd><i class="fa fa{{if .Webhook.SkipTLSVerify}}-check{{end}}-square-o"></i></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.config.mailer_config"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_enabled"}}</dt>
|
||||
<dd><i class="fa fa{{if .MailerEnabled}}-check{{end}}-square-o"></i></dd>
|
||||
{{if .MailerEnabled}}<dt>{{.i18n.Tr "admin.config.mailer_name"}}</dt>
|
||||
<dd>{{.Mailer.Name}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_disable_helo"}}</dt>
|
||||
<dd><i class="fa fa{{if .Mailer.DisableHelo}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_host"}}</dt>
|
||||
<dd>{{.Mailer.Host}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_user"}}</dt>
|
||||
<dd>{{.Mailer.User}}</dd>{{end}}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.config.cache_config"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.cache_adapter"}}</dt>
|
||||
<dd>{{.CacheAdapter}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.cache_interval"}}</dt>
|
||||
<dd>{{.CacheInternal}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.cache_conn"}}</dt>
|
||||
<dd><pre>{{.CacheConn}}</pre></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.config.session_config"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.session_provider"}}</dt>
|
||||
<dd>{{.SessionConfig.Provider}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.provider_config"}}</dt>
|
||||
<dd><pre>{{.SessionConfig.ProviderConfig}}</pre></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.cookie_name"}}</dt>
|
||||
<dd>{{.SessionConfig.CookieName}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.gc_interval_time"}}</dt>
|
||||
<dd>{{.SessionConfig.Gclifetime}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.session_life_time"}}</dt>
|
||||
<dd>{{.SessionConfig.Maxlifetime}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.https_only"}}</dt>
|
||||
<dd><i class="fa fa{{if .SessionConfig.Secure}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.cookie_life_time"}}</dt>
|
||||
<dd>{{.SessionConfig.CookieLifeTime}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.config.picture_config"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.picture_service"}}</dt>
|
||||
<dd>{{.PictureService}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.disable_gravatar"}}</dt>
|
||||
<dd><i class="fa fa{{if .DisableGravatar}}-check{{end}}-square-o"></i></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.config.log_config"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
{{range .Loggers}}
|
||||
<dt>{{$.i18n.Tr "admin.config.log_mode"}}</dt>
|
||||
<dd>{{.Mode}}</dd>
|
||||
<dt>{{$.i18n.Tr "admin.config.log_config"}}</dt>
|
||||
<dd><pre>{{.Config}}</pre></dd>
|
||||
{{end}}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/head" .}}
|
||||
<div class="admin monitor">
|
||||
<div class="ui container">
|
||||
<div class="ui grid">
|
||||
{{template "admin/navbar" .}}
|
||||
<div class="twelve wide column content">
|
||||
{{template "base/alert" .}}
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.config.server_config"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.app_name"}}</dt>
|
||||
<dd>{{AppName}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.app_ver"}}</dt>
|
||||
<dd>{{AppVer}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.app_url"}}</dt>
|
||||
<dd>{{.AppUrl}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.domain"}}</dt>
|
||||
<dd>{{.Domain}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.offline_mode"}}</dt>
|
||||
<dd><i class="fa fa{{if .OfflineMode}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.disable_router_log"}}</dt>
|
||||
<dd><i class="fa fa{{if .DisableRouterLog}}-check{{end}}-square-o"></i></dd>
|
||||
<div class="ui divider"></div>
|
||||
<dt>{{.i18n.Tr "admin.config.run_user"}}</dt>
|
||||
<dd>{{.RunUser}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.run_mode"}}</dt>
|
||||
<dd>{{.RunMode}}</dd>
|
||||
<div class="ui divider"></div>
|
||||
<dt>{{.i18n.Tr "admin.config.repo_root_path"}}</dt>
|
||||
<dd>{{.RepoRootPath}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.static_file_root_path"}}</dt>
|
||||
<dd>{{.StaticRootPath}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.log_file_root_path"}}</dt>
|
||||
<dd>{{.LogRootPath}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.script_type"}}</dt>
|
||||
<dd>{{.ScriptType}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.reverse_auth_user"}}</dt>
|
||||
<dd>{{.ReverseProxyAuthUser}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.config.db_config"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.db_type"}}</dt>
|
||||
<dd>{{.DbCfg.Type}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.db_host"}}</dt>
|
||||
<dd>{{.DbCfg.Host}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.db_name"}}</dt>
|
||||
<dd>{{.DbCfg.Name}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.db_user"}}</dt>
|
||||
<dd>{{.DbCfg.User}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.db_ssl_mode"}}</dt>
|
||||
<dd>{{.DbCfg.SSLMode}} {{.i18n.Tr "admin.config.db_ssl_mode_helper"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.db_path"}}</dt>
|
||||
<dd>{{.DbCfg.Path}} {{.i18n.Tr "admin.config.db_path_helper"}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.config.service_config"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.register_email_confirm"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.RegisterEmailConfirm}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.disable_register"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.DisableRegistration}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.show_registration_button"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.ShowRegistrationButton}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.require_sign_in_view"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.RequireSignInView}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.enable_cache_avatar"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.EnableCacheAvatar}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mail_notify"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.EnableNotifyMail}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.disable_key_size_check"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.DisableMinimumKeySizeCheck}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.enable_captcha"}}</dt>
|
||||
<dd><i class="fa fa{{if .Service.EnableCaptcha}}-check{{end}}-square-o"></i></dd>
|
||||
<div class="ui divider"></div>
|
||||
<dt>{{.i18n.Tr "admin.config.active_code_lives"}}</dt>
|
||||
<dd>{{.Service.ActiveCodeLives}} {{.i18n.Tr "tool.raw_minutes"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.reset_password_code_lives"}}</dt>
|
||||
<dd>{{.Service.ResetPwdCodeLives}} {{.i18n.Tr "tool.raw_minutes"}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.config.webhook_config"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.queue_length"}}</dt>
|
||||
<dd>{{.Webhook.QueueLength}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.deliver_timeout"}}</dt>
|
||||
<dd>{{.Webhook.DeliverTimeout}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.skip_tls_verify"}}</dt>
|
||||
<dd><i class="fa fa{{if .Webhook.SkipTLSVerify}}-check{{end}}-square-o"></i></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.config.mailer_config"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_enabled"}}</dt>
|
||||
<dd><i class="fa fa{{if .MailerEnabled}}-check{{end}}-square-o"></i></dd>
|
||||
{{if .MailerEnabled}}<dt>{{.i18n.Tr "admin.config.mailer_name"}}</dt>
|
||||
<dd>{{.Mailer.Name}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_disable_helo"}}</dt>
|
||||
<dd><i class="fa fa{{if .Mailer.DisableHelo}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_host"}}</dt>
|
||||
<dd>{{.Mailer.Host}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.mailer_user"}}</dt>
|
||||
<dd>{{.Mailer.User}}</dd>{{end}}
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.config.cache_config"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.cache_adapter"}}</dt>
|
||||
<dd>{{.CacheAdapter}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.cache_interval"}}</dt>
|
||||
<dd>{{.CacheInternal}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.cache_conn"}}</dt>
|
||||
<dd><pre>{{.CacheConn}}</pre></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.config.session_config"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.session_provider"}}</dt>
|
||||
<dd>{{.SessionConfig.Provider}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.provider_config"}}</dt>
|
||||
<dd><pre>{{.SessionConfig.ProviderConfig}}</pre></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.cookie_name"}}</dt>
|
||||
<dd>{{.SessionConfig.CookieName}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.gc_interval_time"}}</dt>
|
||||
<dd>{{.SessionConfig.Gclifetime}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.session_life_time"}}</dt>
|
||||
<dd>{{.SessionConfig.Maxlifetime}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.https_only"}}</dt>
|
||||
<dd><i class="fa fa{{if .SessionConfig.Secure}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.cookie_life_time"}}</dt>
|
||||
<dd>{{.SessionConfig.CookieLifeTime}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.config.picture_config"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.config.picture_service"}}</dt>
|
||||
<dd>{{.PictureService}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.disable_gravatar"}}</dt>
|
||||
<dd><i class="fa fa{{if .DisableGravatar}}-check{{end}}-square-o"></i></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.config.log_config"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
{{range .Loggers}}
|
||||
<dt>{{$.i18n.Tr "admin.config.log_mode"}}</dt>
|
||||
<dd>{{.Mode}}</dd>
|
||||
<dt>{{$.i18n.Tr "admin.config.log_config"}}</dt>
|
||||
<dd><pre>{{.Config}}</pre></dd>
|
||||
{{end}}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "ng/base/footer" .}}
|
||||
{{template "base/footer" .}}
|
||||
@@ -1,157 +1,121 @@
|
||||
{{template "ng/base/head" .}}
|
||||
{{template "ng/base/header" .}}
|
||||
<div id="admin-wrapper">
|
||||
<div id="setting-wrapper" class="main-wrapper">
|
||||
<div id="repo-setting" class="container clear">
|
||||
{{template "admin/nav" .}}
|
||||
<div class="grid-4-5 left">
|
||||
<div class="setting-content">
|
||||
{{template "ng/base/alert" .}}
|
||||
<div id="setting-content">
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.dashboard.statistic"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p class="admin-desc">
|
||||
{{.i18n.Tr "admin.dashboard.statistic_info" .Stats.Counter.User .Stats.Counter.Org .Stats.Counter.PublicKey .Stats.Counter.Repo .Stats.Counter.Watch .Stats.Counter.Star .Stats.Counter.Action .Stats.Counter.Access .Stats.Counter.Issue .Stats.Counter.Comment .Stats.Counter.Oauth .Stats.Counter.Follow .Stats.Counter.Mirror .Stats.Counter.Release .Stats.Counter.LoginSource .Stats.Counter.Webhook .Stats.Counter.Milestone .Stats.Counter.Label .Stats.Counter.HookTask .Stats.Counter.Team .Stats.Counter.UpdateTask .Stats.Counter.Attachment | Str2html}}
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.dashboard.operations"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body admin-panel">
|
||||
<div class="admin-table">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.delete_inactivate_accounts"}}</td>
|
||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=1">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.delete_repo_archives"}}</td>
|
||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=2">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.git_gc_repos"}}</td>
|
||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=3">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.resync_all_sshkeys"}}</td>
|
||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=4">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.resync_all_update_hooks"}}</td>
|
||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=5">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<strong>{{.i18n.Tr "admin.dashboard.system_status"}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.dashboard.server_uptime"}}</dt>
|
||||
<dd>{{.SysStatus.Uptime}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.current_goroutine"}}</dt>
|
||||
<dd>{{.SysStatus.NumGoroutine}}</dd>
|
||||
|
||||
<hr/>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.current_memory_usage"}}</dt>
|
||||
<dd>{{.SysStatus.MemAllocated}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.total_memory_allocated"}}</dt>
|
||||
<dd>{{.SysStatus.MemTotal}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.memory_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.MemSys}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.pointer_lookup_times"}}</dt>
|
||||
<dd>{{.SysStatus.Lookups}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.memory_allocate_times"}}</dt>
|
||||
<dd>{{.SysStatus.MemMallocs}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.memory_free_times"}}</dt>
|
||||
<dd>{{.SysStatus.MemFrees}}</dd>
|
||||
|
||||
<hr/>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.current_heap_usage"}}</dt>
|
||||
<dd>{{.SysStatus.HeapAlloc}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.heap_memory_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.HeapSys}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.heap_memory_idle"}}</dt>
|
||||
<dd>{{.SysStatus.HeapIdle}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.heap_memory_in_use"}}</dt>
|
||||
<dd>{{.SysStatus.HeapInuse}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.heap_memory_released"}}</dt>
|
||||
<dd>{{.SysStatus.HeapReleased}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.heap_objects"}}</dt>
|
||||
<dd>{{.SysStatus.HeapObjects}}</dd>
|
||||
|
||||
<hr/>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.bootstrap_stack_usage"}}</dt>
|
||||
<dd>{{.SysStatus.StackInuse}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.stack_memory_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.StackSys}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.mspan_structures_usage"}}</dt>
|
||||
<dd>{{.SysStatus.MSpanInuse}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.mspan_structures_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.HeapSys}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.mcache_structures_usage"}}</dt>
|
||||
<dd>{{.SysStatus.MCacheInuse}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.mcache_structures_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.MCacheSys}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.profiling_bucket_hash_table_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.BuckHashSys}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.gc_metadata_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.GCSys}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.other_system_allocation_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.OtherSys}}</dd>
|
||||
|
||||
<hr>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.next_gc_recycle"}}</dt>
|
||||
<dd>{{.SysStatus.NextGC}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.last_gc_time"}}</dt>
|
||||
<dd>{{.SysStatus.LastGC}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.total_gc_pause"}}</dt>
|
||||
<dd>{{.SysStatus.PauseTotalNs}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.last_gc_pause"}}</dt>
|
||||
<dd>{{.SysStatus.PauseNs}}</dd>
|
||||
|
||||
<dt>{{.i18n.Tr "admin.dashboard.gc_times"}}</dt>
|
||||
<dd>{{.SysStatus.NumGC}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/head" .}}
|
||||
<div class="admin dashboard">
|
||||
<div class="ui container">
|
||||
<div class="ui grid">
|
||||
{{template "admin/navbar" .}}
|
||||
<div class="twelve wide column content">
|
||||
{{template "base/alert" .}}
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.dashboard.statistic"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<p>
|
||||
{{.i18n.Tr "admin.dashboard.statistic_info" .Stats.Counter.User .Stats.Counter.Org .Stats.Counter.PublicKey .Stats.Counter.Repo .Stats.Counter.Watch .Stats.Counter.Star .Stats.Counter.Action .Stats.Counter.Access .Stats.Counter.Issue .Stats.Counter.Comment .Stats.Counter.Oauth .Stats.Counter.Follow .Stats.Counter.Mirror .Stats.Counter.Release .Stats.Counter.LoginSource .Stats.Counter.Webhook .Stats.Counter.Milestone .Stats.Counter.Label .Stats.Counter.HookTask .Stats.Counter.Team .Stats.Counter.UpdateTask .Stats.Counter.Attachment | Str2html}}
|
||||
</p>
|
||||
</div>
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.dashboard.operations"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<table class="ui very basic table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.delete_inactivate_accounts"}}</td>
|
||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=1">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.delete_repo_archives"}}</td>
|
||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=2">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.delete_missing_repos"}}</td>
|
||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=3">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.git_gc_repos"}}</td>
|
||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=4">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.resync_all_sshkeys"}}</td>
|
||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=5">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{.i18n.Tr "admin.dashboard.resync_all_update_hooks"}}</td>
|
||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=6">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "admin.dashboard.system_status"}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<dl class="dl-horizontal admin-dl-horizontal">
|
||||
<dt>{{.i18n.Tr "admin.dashboard.server_uptime"}}</dt>
|
||||
<dd>{{.SysStatus.Uptime}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.current_goroutine"}}</dt>
|
||||
<dd>{{.SysStatus.NumGoroutine}}</dd>
|
||||
<div class="ui divider"></div>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.current_memory_usage"}}</dt>
|
||||
<dd>{{.SysStatus.MemAllocated}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.total_memory_allocated"}}</dt>
|
||||
<dd>{{.SysStatus.MemTotal}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.memory_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.MemSys}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.pointer_lookup_times"}}</dt>
|
||||
<dd>{{.SysStatus.Lookups}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.memory_allocate_times"}}</dt>
|
||||
<dd>{{.SysStatus.MemMallocs}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.memory_free_times"}}</dt>
|
||||
<dd>{{.SysStatus.MemFrees}}</dd>
|
||||
<div class="ui divider"></div>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.current_heap_usage"}}</dt>
|
||||
<dd>{{.SysStatus.HeapAlloc}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.heap_memory_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.HeapSys}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.heap_memory_idle"}}</dt>
|
||||
<dd>{{.SysStatus.HeapIdle}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.heap_memory_in_use"}}</dt>
|
||||
<dd>{{.SysStatus.HeapInuse}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.heap_memory_released"}}</dt>
|
||||
<dd>{{.SysStatus.HeapReleased}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.heap_objects"}}</dt>
|
||||
<dd>{{.SysStatus.HeapObjects}}</dd>
|
||||
<div class="ui divider"></div>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.bootstrap_stack_usage"}}</dt>
|
||||
<dd>{{.SysStatus.StackInuse}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.stack_memory_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.StackSys}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.mspan_structures_usage"}}</dt>
|
||||
<dd>{{.SysStatus.MSpanInuse}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.mspan_structures_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.HeapSys}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.mcache_structures_usage"}}</dt>
|
||||
<dd>{{.SysStatus.MCacheInuse}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.mcache_structures_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.MCacheSys}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.profiling_bucket_hash_table_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.BuckHashSys}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.gc_metadata_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.GCSys}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.other_system_allocation_obtained"}}</dt>
|
||||
<dd>{{.SysStatus.OtherSys}}</dd>
|
||||
<div class="ui divider"></div>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.next_gc_recycle"}}</dt>
|
||||
<dd>{{.SysStatus.NextGC}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.last_gc_time"}}</dt>
|
||||
<dd>{{.SysStatus.LastGC}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.total_gc_pause"}}</dt>
|
||||
<dd>{{.SysStatus.PauseTotalNs}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.last_gc_pause"}}</dt>
|
||||
<dd>{{.SysStatus.PauseNs}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.dashboard.gc_times"}}</dt>
|
||||
<dd>{{.SysStatus.NumGC}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "ng/base/footer" .}}
|
||||
{{template "base/footer" .}}
|
||||
@@ -2,7 +2,7 @@
|
||||
<footer>
|
||||
<div class="ui container">
|
||||
<div class="ui left">
|
||||
© 2015 Gogs {{.i18n.Tr "version"}}: {{AppVer}} {{.i18n.Tr "page"}}: <strong>{{LoadTimes .PageStartTime}}</strong> {{.i18n.Tr "template"}}: <strong>{{call .TmplLoadTimes}}</strong>
|
||||
© 2015 Gogs {{if (or .ShowFooterVersion .PageIsAdmin)}}{{.i18n.Tr "version"}}: {{AppVer}}{{end}} {{.i18n.Tr "page"}}: <strong>{{LoadTimes .PageStartTime}}</strong> {{.i18n.Tr "template"}}: <strong>{{call .TmplLoadTimes}}</strong>
|
||||
</div>
|
||||
<div class="ui right links">
|
||||
{{if .ShowFooterBranding}}
|
||||
@@ -20,7 +20,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<a target="_blank" href="http://gogs.io">{{.i18n.Tr "website"}}</a>
|
||||
<span class="version">{{GoVer}}</span>
|
||||
{{if (or .ShowFooterVersion .PageIsAdmin)}}<span class="version">{{GoVer}}</span>{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
<!-- Third-party libraries -->
|
||||
{{if .RequireHighlightJS}}
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/css/highlight-8.7/default.css">
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/css/highlight-8.7/github.css">
|
||||
<script src="{{AppSubUrl}}/js/libs/highlight-8.7.pack.js"></script>
|
||||
{{end}}
|
||||
{{if .RequireMinicolors}}
|
||||
@@ -46,4 +46,4 @@
|
||||
<script src="{{AppSubUrl}}/js/libs/emojify-1.1.0.min.js"></script>
|
||||
<script src="{{AppSubUrl}}/js/libs/clipboard-1.5.3.min.js"></script>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user