mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-01-30 10:48:15 +00:00
Merge branch 'master' into refactor_issues-subscription
This commit is contained in:
commit
90c36e37d3
68 changed files with 5437 additions and 512 deletions
11
README.md
11
README.md
|
@ -1,4 +1,4 @@
|
|||
[简体中文](https://github.com/go-gitea/gitea/blob/master/README_ZH.md)
|
||||
[简体中文](README_ZH.md)
|
||||
|
||||
<h1> <img src="https://raw.githubusercontent.com/go-gitea/gitea/master/public/img/gitea-192.png" alt="logo" width="30" height="30"> Gitea - Git with a cup of tea</h1>
|
||||
|
||||
|
@ -105,9 +105,8 @@ for the full license text.
|
|||
## Screenshots
|
||||
Looking for an overview of the interface? Check it out!
|
||||
|
||||
| | | |
|
||||
|![Dashboard](https://dl.gitea.io/screenshots/home_timeline.png)|![User Profile](https://dl.gitea.io/screenshots/user_profile.png)|![Global Issues](https://dl.gitea.io/screenshots/global_issues.png)|
|
||||
|:---:|:---:|:---:|
|
||||
|![Dashboard](https://image.ibb.co/dms6DG/1.png)|![Repository](https://image.ibb.co/m6MSLw/2.png)|![Commits History](https://image.ibb.co/cjrSLw/3.png)|
|
||||
|![Branches](https://image.ibb.co/e6vbDG/4.png)|![Issues](https://image.ibb.co/bJTJSb/5.png)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)|
|
||||
|![Releases](https://image.ibb.co/cUzgfw/7.png)|![Activity](https://image.ibb.co/eZgGDG/8.png)|![Wiki](https://image.ibb.co/dYV9YG/9.png)|
|
||||
|![Diff](https://image.ibb.co/ewA9YG/10.png)|![Organization](https://image.ibb.co/ceOwDG/11.png)|![Profile](https://image.ibb.co/c44Q7b/12.png)|
|
||||
|![Branches](https://dl.gitea.io/screenshots/branches.png)|![Web Editor](https://dl.gitea.io/screenshots/web_editor.png)|![Activity](https://dl.gitea.io/screenshots/activity.png)|
|
||||
|![New Migration](https://dl.gitea.io/screenshots/migration.png)|![Migrating](https://dl.gitea.io/screenshots/migration.gif)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)
|
||||
![Pull Request Dark](https://dl.gitea.io/screenshots/pull_requests_dark.png)|![Diff Review Dark](https://dl.gitea.io/screenshots/review_dark.png)|![Diff Dark](https://dl.gitea.io/screenshots/diff_dark.png)|
|
||||
|
|
16
README_ZH.md
16
README_ZH.md
|
@ -1,14 +1,15 @@
|
|||
[English](https://github.com/go-gitea/gitea/blob/master/README.md)
|
||||
[English](README.md)
|
||||
|
||||
# Gitea - Git with a cup of tea
|
||||
<h1> <img src="https://raw.githubusercontent.com/go-gitea/gitea/master/public/img/gitea-192.png" alt="logo" width="30" height="30"> Gitea - Git with a cup of tea</h1>
|
||||
|
||||
[![Build Status](https://drone.gitea.io/api/badges/go-gitea/gitea/status.svg)](https://drone.gitea.io/go-gitea/gitea)
|
||||
[![Join the chat at https://img.shields.io/discord/322538954119184384.svg](https://img.shields.io/discord/322538954119184384.svg)](https://discord.gg/gitea)
|
||||
[![Join the Discord chat at https://discord.gg/NsatcWJ](https://img.shields.io/discord/322538954119184384.svg)](https://discord.gg/NsatcWJ)
|
||||
[![](https://images.microbadger.com/badges/image/gitea/gitea.svg)](https://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com")
|
||||
[![codecov](https://codecov.io/gh/go-gitea/gitea/branch/master/graph/badge.svg)](https://codecov.io/gh/go-gitea/gitea)
|
||||
[![Go Report Card](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/code.gitea.io/gitea)
|
||||
[![GoDoc](https://godoc.org/code.gitea.io/gitea?status.svg)](https://godoc.org/code.gitea.io/gitea)
|
||||
[![GitHub release](https://img.shields.io/github/release/go-gitea/gitea.svg)](https://github.com/go-gitea/gitea/releases/latest)
|
||||
[![Help Contribute to Open Source](https://www.codetriage.com/go-gitea/gitea/badges/users.svg)](https://www.codetriage.com/go-gitea/gitea)
|
||||
[![Become a backer/sponsor of gitea](https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen)](https://opencollective.com/gitea)
|
||||
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
|
||||
[![Crowdin](https://badges.crowdin.net/gitea/localized.svg)](https://crowdin.com/project/gitea)
|
||||
|
@ -45,9 +46,8 @@ Fork -> Patch -> Push -> Pull Request
|
|||
|
||||
## 截图
|
||||
|
||||
| | | |
|
||||
|![Dashboard](https://dl.gitea.io/screenshots/home_timeline.png)|![User Profile](https://dl.gitea.io/screenshots/user_profile.png)|![Global Issues](https://dl.gitea.io/screenshots/global_issues.png)|
|
||||
|:---:|:---:|:---:|
|
||||
|![Dashboard](https://image.ibb.co/dms6DG/1.png)|![Repository](https://image.ibb.co/m6MSLw/2.png)|![Commits History](https://image.ibb.co/cjrSLw/3.png)|
|
||||
|![Branches](https://image.ibb.co/e6vbDG/4.png)|![Issues](https://image.ibb.co/bJTJSb/5.png)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)|
|
||||
|![Releases](https://image.ibb.co/cUzgfw/7.png)|![Activity](https://image.ibb.co/eZgGDG/8.png)|![Wiki](https://image.ibb.co/dYV9YG/9.png)|
|
||||
|![Diff](https://image.ibb.co/ewA9YG/10.png)|![Organization](https://image.ibb.co/ceOwDG/11.png)|![Profile](https://image.ibb.co/c44Q7b/12.png)|
|
||||
|![Branches](https://dl.gitea.io/screenshots/branches.png)|![Web Editor](https://dl.gitea.io/screenshots/web_editor.png)|![Activity](https://dl.gitea.io/screenshots/activity.png)|
|
||||
|![New Migration](https://dl.gitea.io/screenshots/migration.png)|![Migrating](https://dl.gitea.io/screenshots/migration.gif)|![Pull Request View](https://image.ibb.co/e02dSb/6.png)
|
||||
![Pull Request Dark](https://dl.gitea.io/screenshots/pull_requests_dark.png)|![Diff Review Dark](https://dl.gitea.io/screenshots/review_dark.png)|![Diff Dark](https://dl.gitea.io/screenshots/diff_dark.png)|
|
||||
|
|
|
@ -30,7 +30,8 @@ After=network.target
|
|||
## PartOf=gitea.service
|
||||
##
|
||||
## [Socket]
|
||||
## ListenStream=
|
||||
## Service=gitea.service
|
||||
## ListenStream=<some_port>
|
||||
## NoDelay=true
|
||||
##
|
||||
## [Install]
|
||||
|
@ -53,7 +54,7 @@ WorkingDirectory=/var/lib/gitea/
|
|||
# If using unix socket: Tells Systemd to create /run/gitea folder to home gitea.sock
|
||||
# Manual cration would vanish after reboot.
|
||||
#RuntimeDirectory=gitea
|
||||
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini
|
||||
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
|
||||
Restart=always
|
||||
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
|
||||
# If you want to bind Gitea to a port below 1024, uncomment
|
||||
|
|
|
@ -18,7 +18,7 @@ params:
|
|||
description: Git with a cup of tea
|
||||
author: The Gitea Authors
|
||||
website: https://docs.gitea.io
|
||||
version: 1.9.3
|
||||
version: 1.9.5
|
||||
|
||||
menu:
|
||||
page:
|
||||
|
|
|
@ -42,6 +42,7 @@ Also see [Support Options]({{< relref "doc/help/seek-help.en-us.md" >}})
|
|||
* [SSH Common Errors](#ssh-common-errors)
|
||||
* [Missing releases after migration repository with tags](#missing-releases-after-migrating-repository-with-tags)
|
||||
* [LFS Issues](#lfs-issues)
|
||||
* [How can I create users before starting Gitea](#how-can-i-create-users-before-starting-gitea)
|
||||
|
||||
|
||||
## Difference between 1.x and 1.x.x downloads
|
||||
|
@ -272,3 +273,6 @@ Check the value of `LFS_HTTP_AUTH_EXPIRY` in your `app.ini` file.
|
|||
By default, your LFS token will expire after 20 minutes. If you have a slow connection or a large file (or both), it may not finish uploading within the time limit.
|
||||
|
||||
You may want to set this value to `60m` or `120m`.
|
||||
|
||||
## How can I create users before starting Gitea
|
||||
Gitea provides a sub-command `gitea migrate` to initialize the database, after which you can use the [admin CLI commands]({{< relref "doc/usage/command-line.en-us.md" >}}) to add users like normal.
|
||||
|
|
|
@ -281,3 +281,10 @@ provided key. You should also set the value
|
|||
NB: opensshd requires the gitea program to be owned by root and not
|
||||
writable by group or others. The program must be specified by an absolute
|
||||
path.
|
||||
|
||||
#### migrate
|
||||
Migrates the database. This command can be used to run other commands before starting the server for the first time.
|
||||
This command is idempotent.
|
||||
|
||||
#### convert
|
||||
Converts an existing MySQL database from utf8 to utf8mb4.
|
||||
|
|
6
go.mod
6
go.mod
|
@ -69,12 +69,10 @@ require (
|
|||
github.com/mattn/go-sqlite3 v1.11.0
|
||||
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75
|
||||
github.com/microcosm-cc/bluemonday v0.0.0-20161012083705-f77f16ffc87a
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae // indirect
|
||||
github.com/msteinert/pam v0.0.0-20151204160544-02ccfbfaf0cc
|
||||
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5
|
||||
github.com/niklasfasching/go-org v0.1.7
|
||||
github.com/niklasfasching/go-org v0.1.8
|
||||
github.com/oliamb/cutter v0.2.2
|
||||
github.com/philhofer/fwd v1.0.0 // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
|
@ -103,7 +101,7 @@ require (
|
|||
github.com/willf/bitset v0.0.0-20180426185212-8ce1146b8621 // indirect
|
||||
github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53
|
||||
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad
|
||||
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271
|
||||
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||
golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b
|
||||
golang.org/x/text v0.3.2
|
||||
|
|
4
go.sum
4
go.sum
|
@ -427,6 +427,8 @@ github.com/niklasfasching/go-org v0.1.6 h1:F521WcqRNl8OJumlgAnekZgERaTA2HpfOYYfV
|
|||
github.com/niklasfasching/go-org v0.1.6/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
||||
github.com/niklasfasching/go-org v0.1.7 h1:t3V+3XnS/7BhKv/7SlMUa8FvAiq577/a1T3D7mLIRXE=
|
||||
github.com/niklasfasching/go-org v0.1.7/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
||||
github.com/niklasfasching/go-org v0.1.8 h1:Kjvs6lP+LIILHhc9zIJ4Gu90a/pVY483if2Qmu8v4Fg=
|
||||
github.com/niklasfasching/go-org v0.1.8/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=
|
||||
github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU=
|
||||
|
@ -658,6 +660,8 @@ golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsi
|
|||
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 h1:N66aaryRB3Ax92gH0v3hp1QYZ3zWWCCUR/j8Ifh45Ss=
|
||||
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9 h1:DPz9iiH3YoKiKhX/ijjoZvT0VFwK2c6CWYWQ7Zyr8TU=
|
||||
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=
|
||||
|
|
|
@ -1293,8 +1293,12 @@ func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) {
|
|||
log.Warn("Malformed Labels argument: %s", opts.Labels)
|
||||
} else {
|
||||
for i, labelID := range labelIDs {
|
||||
sess.Join("INNER", fmt.Sprintf("issue_label il%d", i),
|
||||
fmt.Sprintf("issue.id = il%[1]d.issue_id AND il%[1]d.label_id = %[2]d", i, labelID))
|
||||
if labelID > 0 {
|
||||
sess.Join("INNER", fmt.Sprintf("issue_label il%d", i),
|
||||
fmt.Sprintf("issue.id = il%[1]d.issue_id AND il%[1]d.label_id = %[2]d", i, labelID))
|
||||
} else {
|
||||
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_label WHERE label_id = ?)", -labelID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ func parseKeyString(content string) (string, error) {
|
|||
|
||||
var keyType, keyContent, keyComment string
|
||||
|
||||
if content[:len(ssh2keyStart)] == ssh2keyStart {
|
||||
if strings.HasPrefix(content, ssh2keyStart) {
|
||||
// Parse SSH2 file format.
|
||||
|
||||
// Transform all legal line endings to a single "\n".
|
||||
|
|
|
@ -131,6 +131,19 @@ AAAAC3NzaC1lZDI1NTE5AAAAICV0MGX/W9IvLA4FXpIuUcdDcbj5KX4syHgsTy7soVgf
|
|||
_, err := CheckPublicKeyString(test.content)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
for _, invalidKeys := range []struct {
|
||||
content string
|
||||
}{
|
||||
{"test"},
|
||||
{"---- NOT A REAL KEY ----"},
|
||||
{"bad\nkey"},
|
||||
{"\t\t:)\t\r\n"},
|
||||
{"\r\ntest \r\ngitea\r\n\r\n"},
|
||||
} {
|
||||
_, err := CheckPublicKeyString(invalidKeys.content)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_calcFingerprint(t *testing.T) {
|
||||
|
|
|
@ -118,33 +118,6 @@ func (w *Webhook) AfterLoad() {
|
|||
}
|
||||
}
|
||||
|
||||
// GetSlackHook returns slack metadata
|
||||
func (w *Webhook) GetSlackHook() *SlackMeta {
|
||||
s := &SlackMeta{}
|
||||
if err := json.Unmarshal([]byte(w.Meta), s); err != nil {
|
||||
log.Error("webhook.GetSlackHook(%d): %v", w.ID, err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// GetDiscordHook returns discord metadata
|
||||
func (w *Webhook) GetDiscordHook() *DiscordMeta {
|
||||
s := &DiscordMeta{}
|
||||
if err := json.Unmarshal([]byte(w.Meta), s); err != nil {
|
||||
log.Error("webhook.GetDiscordHook(%d): %v", w.ID, err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// GetTelegramHook returns telegram metadata
|
||||
func (w *Webhook) GetTelegramHook() *TelegramMeta {
|
||||
s := &TelegramMeta{}
|
||||
if err := json.Unmarshal([]byte(w.Meta), s); err != nil {
|
||||
log.Error("webhook.GetTelegramHook(%d): %v", w.ID, err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// History returns history of webhook by given conditions.
|
||||
func (w *Webhook) History(page int) ([]*HookTask, error) {
|
||||
return HookTasks(w.ID, page)
|
||||
|
|
|
@ -24,18 +24,6 @@ func TestIsValidHookContentType(t *testing.T) {
|
|||
assert.False(t, IsValidHookContentType("invalid"))
|
||||
}
|
||||
|
||||
func TestWebhook_GetSlackHook(t *testing.T) {
|
||||
w := &Webhook{
|
||||
Meta: `{"channel": "foo", "username": "username", "color": "blue"}`,
|
||||
}
|
||||
slackHook := w.GetSlackHook()
|
||||
assert.Equal(t, *slackHook, SlackMeta{
|
||||
Channel: "foo",
|
||||
Username: "username",
|
||||
Color: "blue",
|
||||
})
|
||||
}
|
||||
|
||||
func TestWebhook_History(t *testing.T) {
|
||||
assert.NoError(t, PrepareTestDatabase())
|
||||
webhook := AssertExistsAndLoadBean(t, &Webhook{ID: 1}).(*Webhook)
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"html"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
|
@ -91,7 +90,7 @@ func (r *Renderer) WriteRegularLink(l org.RegularLink) {
|
|||
|
||||
description := string(link)
|
||||
if l.Description != nil {
|
||||
description = r.nodesAsString(l.Description...)
|
||||
description = r.WriteNodesAsString(l.Description...)
|
||||
}
|
||||
switch l.Kind() {
|
||||
case "image":
|
||||
|
@ -102,21 +101,3 @@ func (r *Renderer) WriteRegularLink(l org.RegularLink) {
|
|||
r.WriteString(fmt.Sprintf(`<a href="%s" title="%s">%s</a>`, link, description, description))
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) emptyClone() *Renderer {
|
||||
wcopy := *(r.HTMLWriter)
|
||||
wcopy.Builder = strings.Builder{}
|
||||
|
||||
rcopy := *r
|
||||
rcopy.HTMLWriter = &wcopy
|
||||
|
||||
wcopy.ExtendingWriter = &rcopy
|
||||
|
||||
return &rcopy
|
||||
}
|
||||
|
||||
func (r *Renderer) nodesAsString(nodes ...org.Node) string {
|
||||
tmp := r.emptyClone()
|
||||
org.WriteNodes(tmp, nodes...)
|
||||
return tmp.String()
|
||||
}
|
||||
|
|
|
@ -252,27 +252,30 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error {
|
|||
}
|
||||
|
||||
// download attachment
|
||||
resp, err := http.Get(asset.URL)
|
||||
err = func() error {
|
||||
resp, err := http.Get(asset.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
localPath := attach.LocalPath()
|
||||
if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil {
|
||||
return fmt.Errorf("MkdirAll: %v", err)
|
||||
}
|
||||
|
||||
fw, err := os.Create(localPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Create: %v", err)
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
_, err = io.Copy(fw, resp.Body)
|
||||
return err
|
||||
}()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
localPath := attach.LocalPath()
|
||||
if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil {
|
||||
return fmt.Errorf("MkdirAll: %v", err)
|
||||
}
|
||||
|
||||
fw, err := os.Create(localPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Create: %v", err)
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
if _, err := io.Copy(fw, resp.Body); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rel.Attachments = append(rel.Attachments, &attach)
|
||||
}
|
||||
|
||||
|
@ -468,21 +471,24 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR
|
|||
}
|
||||
|
||||
// download patch file
|
||||
resp, err := http.Get(pr.PatchURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
pullDir := filepath.Join(g.repo.RepoPath(), "pulls")
|
||||
if err = os.MkdirAll(pullDir, os.ModePerm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f, err := os.Create(filepath.Join(pullDir, fmt.Sprintf("%d.patch", pr.Number)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = io.Copy(f, resp.Body)
|
||||
err := func() error {
|
||||
resp, err := http.Get(pr.PatchURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
pullDir := filepath.Join(g.repo.RepoPath(), "pulls")
|
||||
if err = os.MkdirAll(pullDir, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(filepath.Join(pullDir, fmt.Sprintf("%d.patch", pr.Number)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = io.Copy(f, resp.Body)
|
||||
return err
|
||||
}()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -496,8 +502,8 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer p.Close()
|
||||
_, err = p.WriteString(pr.Head.SHA)
|
||||
p.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -531,8 +537,8 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer b.Close()
|
||||
_, err = b.WriteString(pr.Head.SHA)
|
||||
b.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
77
modules/notification/action/action.go
Normal file
77
modules/notification/action/action.go
Normal file
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2019 The Gitea 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 action
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/notification/base"
|
||||
)
|
||||
|
||||
type actionNotifier struct {
|
||||
base.NullNotifier
|
||||
}
|
||||
|
||||
var (
|
||||
_ base.Notifier = &actionNotifier{}
|
||||
)
|
||||
|
||||
// NewNotifier create a new webhookNotifier notifier
|
||||
func NewNotifier() base.Notifier {
|
||||
return &actionNotifier{}
|
||||
}
|
||||
|
||||
func (a *actionNotifier) NotifyNewIssue(issue *models.Issue) {
|
||||
if err := issue.LoadPoster(); err != nil {
|
||||
log.Error("issue.LoadPoster: %v", err)
|
||||
return
|
||||
}
|
||||
if err := issue.LoadRepo(); err != nil {
|
||||
log.Error("issue.LoadRepo: %v", err)
|
||||
return
|
||||
}
|
||||
repo := issue.Repo
|
||||
|
||||
if err := models.NotifyWatchers(&models.Action{
|
||||
ActUserID: issue.Poster.ID,
|
||||
ActUser: issue.Poster,
|
||||
OpType: models.ActionCreateIssue,
|
||||
Content: fmt.Sprintf("%d|%s", issue.Index, issue.Title),
|
||||
RepoID: repo.ID,
|
||||
Repo: repo,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
}); err != nil {
|
||||
log.Error("NotifyWatchers: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *actionNotifier) NotifyNewPullRequest(pull *models.PullRequest) {
|
||||
if err := pull.LoadIssue(); err != nil {
|
||||
log.Error("pull.LoadIssue: %v", err)
|
||||
return
|
||||
}
|
||||
if err := pull.Issue.LoadRepo(); err != nil {
|
||||
log.Error("pull.Issue.LoadRepo: %v", err)
|
||||
return
|
||||
}
|
||||
if err := pull.Issue.LoadPoster(); err != nil {
|
||||
log.Error("pull.Issue.LoadPoster: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.NotifyWatchers(&models.Action{
|
||||
ActUserID: pull.Issue.Poster.ID,
|
||||
ActUser: pull.Issue.Poster,
|
||||
OpType: models.ActionCreatePullRequest,
|
||||
Content: fmt.Sprintf("%d|%s", pull.Issue.Index, pull.Issue.Title),
|
||||
RepoID: pull.Issue.Repo.ID,
|
||||
Repo: pull.Issue.Repo,
|
||||
IsPrivate: pull.Issue.Repo.IsPrivate,
|
||||
}); err != nil {
|
||||
log.Error("NotifyWatchers: %v", err)
|
||||
}
|
||||
}
|
|
@ -30,6 +30,7 @@ type Notifier interface {
|
|||
|
||||
NotifyNewPullRequest(*models.PullRequest)
|
||||
NotifyMergePullRequest(*models.PullRequest, *models.User, *git.Repository)
|
||||
NotifyPullRequestSynchronized(doer *models.User, pr *models.PullRequest)
|
||||
NotifyPullRequestReview(*models.PullRequest, *models.Review, *models.Comment)
|
||||
|
||||
NotifyCreateIssueComment(*models.User, *models.Repository,
|
||||
|
@ -40,4 +41,6 @@ type Notifier interface {
|
|||
NotifyNewRelease(rel *models.Release)
|
||||
NotifyUpdateRelease(doer *models.User, rel *models.Release)
|
||||
NotifyDeleteRelease(doer *models.User, rel *models.Release)
|
||||
|
||||
NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits)
|
||||
}
|
||||
|
|
|
@ -46,6 +46,10 @@ func (*NullNotifier) NotifyPullRequestReview(pr *models.PullRequest, r *models.R
|
|||
func (*NullNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *models.User, baseRepo *git.Repository) {
|
||||
}
|
||||
|
||||
// NotifyPullRequestSynchronized places a place holder function
|
||||
func (*NullNotifier) NotifyPullRequestSynchronized(doer *models.User, pr *models.PullRequest) {
|
||||
}
|
||||
|
||||
// NotifyUpdateComment places a place holder function
|
||||
func (*NullNotifier) NotifyUpdateComment(doer *models.User, c *models.Comment, oldContent string) {
|
||||
}
|
||||
|
@ -106,3 +110,7 @@ func (*NullNotifier) NotifyCreateRepository(doer *models.User, u *models.User, r
|
|||
// NotifyMigrateRepository places a place holder function
|
||||
func (*NullNotifier) NotifyMigrateRepository(doer *models.User, u *models.User, repo *models.Repository) {
|
||||
}
|
||||
|
||||
// NotifyPushCommits notifies commits pushed to notifiers
|
||||
func (*NullNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) {
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ package notification
|
|||
import (
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/notification/action"
|
||||
"code.gitea.io/gitea/modules/notification/base"
|
||||
"code.gitea.io/gitea/modules/notification/indexer"
|
||||
"code.gitea.io/gitea/modules/notification/mail"
|
||||
|
@ -33,6 +34,7 @@ func NewContext() {
|
|||
}
|
||||
RegisterNotifier(indexer.NewNotifier())
|
||||
RegisterNotifier(webhook.NewNotifier())
|
||||
RegisterNotifier(action.NewNotifier())
|
||||
}
|
||||
|
||||
// NotifyCreateIssueComment notifies issue comment related message to notifiers
|
||||
|
@ -71,6 +73,13 @@ func NotifyNewPullRequest(pr *models.PullRequest) {
|
|||
}
|
||||
}
|
||||
|
||||
// NotifyPullRequestSynchronized notifies Synchronized pull request
|
||||
func NotifyPullRequestSynchronized(doer *models.User, pr *models.PullRequest) {
|
||||
for _, notifier := range notifiers {
|
||||
notifier.NotifyPullRequestSynchronized(doer, pr)
|
||||
}
|
||||
}
|
||||
|
||||
// NotifyPullRequestReview notifies new pull request review
|
||||
func NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment) {
|
||||
for _, notifier := range notifiers {
|
||||
|
@ -183,3 +192,10 @@ func NotifyMigrateRepository(doer *models.User, u *models.User, repo *models.Rep
|
|||
notifier.NotifyMigrateRepository(doer, u, repo)
|
||||
}
|
||||
}
|
||||
|
||||
// NotifyPushCommits notifies commits pushed to notifiers
|
||||
func NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) {
|
||||
for _, notifier := range notifiers {
|
||||
notifier.NotifyPushCommits(pusher, repo, refName, oldCommitID, newCommitID, commits)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@ import (
|
|||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/notification/base"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/webhook"
|
||||
webhook_module "code.gitea.io/gitea/modules/webhook"
|
||||
)
|
||||
|
||||
|
@ -250,6 +252,15 @@ func (m *webhookNotifier) NotifyIssueChangeStatus(doer *models.User, issue *mode
|
|||
}
|
||||
|
||||
func (m *webhookNotifier) NotifyNewIssue(issue *models.Issue) {
|
||||
if err := issue.LoadRepo(); err != nil {
|
||||
log.Error("issue.LoadRepo: %v", err)
|
||||
return
|
||||
}
|
||||
if err := issue.LoadPoster(); err != nil {
|
||||
log.Error("issue.LoadPoster: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
mode, _ := models.AccessLevel(issue.Poster, issue.Repo)
|
||||
if err := webhook_module.PrepareWebhooks(issue.Repo, models.HookEventIssues, &api.IssuePayload{
|
||||
Action: api.HookIssueOpened,
|
||||
|
@ -262,6 +273,32 @@ func (m *webhookNotifier) NotifyNewIssue(issue *models.Issue) {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *webhookNotifier) NotifyNewPullRequest(pull *models.PullRequest) {
|
||||
if err := pull.LoadIssue(); err != nil {
|
||||
log.Error("pull.LoadIssue: %v", err)
|
||||
return
|
||||
}
|
||||
if err := pull.Issue.LoadRepo(); err != nil {
|
||||
log.Error("pull.Issue.LoadRepo: %v", err)
|
||||
return
|
||||
}
|
||||
if err := pull.Issue.LoadPoster(); err != nil {
|
||||
log.Error("pull.Issue.LoadPoster: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
mode, _ := models.AccessLevel(pull.Issue.Poster, pull.Issue.Repo)
|
||||
if err := webhook.PrepareWebhooks(pull.Issue.Repo, models.HookEventPullRequest, &api.PullRequestPayload{
|
||||
Action: api.HookIssueOpened,
|
||||
Index: pull.Issue.Index,
|
||||
PullRequest: pull.APIFormat(),
|
||||
Repository: pull.Issue.Repo.APIFormat(mode),
|
||||
Sender: pull.Issue.Poster.APIFormat(),
|
||||
}); err != nil {
|
||||
log.Error("PrepareWebhooks: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *webhookNotifier) NotifyIssueChangeContent(doer *models.User, issue *models.Issue, oldContent string) {
|
||||
mode, _ := models.AccessLevel(issue.Poster, issue.Repo)
|
||||
var err error
|
||||
|
@ -461,3 +498,87 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *models.User, issue *m
|
|||
log.Error("PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *webhookNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) {
|
||||
apiPusher := pusher.APIFormat()
|
||||
apiCommits, err := commits.ToAPIPayloadCommits(repo.RepoPath(), repo.HTMLURL())
|
||||
if err != nil {
|
||||
log.Error("commits.ToAPIPayloadCommits failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := webhook_module.PrepareWebhooks(repo, models.HookEventPush, &api.PushPayload{
|
||||
Ref: refName,
|
||||
Before: oldCommitID,
|
||||
After: newCommitID,
|
||||
CompareURL: setting.AppURL + commits.CompareURL,
|
||||
Commits: apiCommits,
|
||||
Repo: repo.APIFormat(models.AccessModeOwner),
|
||||
Pusher: apiPusher,
|
||||
Sender: apiPusher,
|
||||
}); err != nil {
|
||||
log.Error("PrepareWebhooks: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *webhookNotifier) NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment) {
|
||||
var reviewHookType models.HookEventType
|
||||
|
||||
switch review.Type {
|
||||
case models.ReviewTypeApprove:
|
||||
reviewHookType = models.HookEventPullRequestApproved
|
||||
case models.ReviewTypeComment:
|
||||
reviewHookType = models.HookEventPullRequestComment
|
||||
case models.ReviewTypeReject:
|
||||
reviewHookType = models.HookEventPullRequestRejected
|
||||
default:
|
||||
// unsupported review webhook type here
|
||||
log.Error("Unsupported review webhook type")
|
||||
return
|
||||
}
|
||||
|
||||
if err := pr.LoadIssue(); err != nil {
|
||||
log.Error("pr.LoadIssue: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
mode, err := models.AccessLevel(review.Issue.Poster, review.Issue.Repo)
|
||||
if err != nil {
|
||||
log.Error("models.AccessLevel: %v", err)
|
||||
return
|
||||
}
|
||||
if err := webhook.PrepareWebhooks(review.Issue.Repo, reviewHookType, &api.PullRequestPayload{
|
||||
Action: api.HookIssueSynchronized,
|
||||
Index: review.Issue.Index,
|
||||
PullRequest: pr.APIFormat(),
|
||||
Repository: review.Issue.Repo.APIFormat(mode),
|
||||
Sender: review.Reviewer.APIFormat(),
|
||||
Review: &api.ReviewPayload{
|
||||
Type: string(reviewHookType),
|
||||
Content: review.Content,
|
||||
},
|
||||
}); err != nil {
|
||||
log.Error("PrepareWebhooks: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *models.User, pr *models.PullRequest) {
|
||||
if err := pr.LoadIssue(); err != nil {
|
||||
log.Error("pr.LoadIssue: %v", err)
|
||||
return
|
||||
}
|
||||
if err := pr.Issue.LoadAttributes(); err != nil {
|
||||
log.Error("LoadAttributes: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := webhook.PrepareWebhooks(pr.Issue.Repo, models.HookEventPullRequest, &api.PullRequestPayload{
|
||||
Action: api.HookIssueSynchronized,
|
||||
Index: pr.Issue.Index,
|
||||
PullRequest: pr.Issue.PullRequest.APIFormat(),
|
||||
Repository: pr.Issue.Repo.APIFormat(models.AccessModeNone),
|
||||
Sender: doer.APIFormat(),
|
||||
}); err != nil {
|
||||
log.Error("PrepareWebhooks [pull_id: %v]: %v", pr.ID, err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/notification"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/webhook"
|
||||
|
@ -190,22 +191,7 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
|
|||
}
|
||||
|
||||
if isHookEventPush {
|
||||
commits, err := opts.Commits.ToAPIPayloadCommits(repo.RepoPath(), repo.HTMLURL())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = webhook.PrepareWebhooks(repo, models.HookEventPush, &api.PushPayload{
|
||||
Ref: opts.RefFullName,
|
||||
Before: opts.OldCommitID,
|
||||
After: opts.NewCommitID,
|
||||
CompareURL: setting.AppURL + opts.Commits.CompareURL,
|
||||
Commits: commits,
|
||||
Repo: apiRepo,
|
||||
Pusher: apiPusher,
|
||||
Sender: apiPusher,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("PrepareWebhooks: %v", err)
|
||||
}
|
||||
notification.NotifyPushCommits(pusher, repo, opts.RefFullName, opts.OldCommitID, opts.NewCommitID, opts.Commits)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -99,7 +99,8 @@ type EditIssueOption struct {
|
|||
Milestone *int64 `json:"milestone"`
|
||||
State *string `json:"state"`
|
||||
// swagger:strfmt date-time
|
||||
Deadline *time.Time `json:"due_date"`
|
||||
Deadline *time.Time `json:"due_date"`
|
||||
RemoveDeadline *bool `json:"unset_due_date"`
|
||||
}
|
||||
|
||||
// EditDeadlineOption options for creating a deadline
|
||||
|
|
|
@ -88,5 +88,6 @@ type EditPullRequestOption struct {
|
|||
Labels []int64 `json:"labels"`
|
||||
State *string `json:"state"`
|
||||
// swagger:strfmt date-time
|
||||
Deadline *time.Time `json:"due_date"`
|
||||
Deadline *time.Time `json:"due_date"`
|
||||
RemoveDeadline *bool `json:"unset_due_date"`
|
||||
}
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
|
||||
|
@ -184,7 +185,7 @@ func getDingtalkIssuesPayload(p *api.IssuePayload) (*DingtalkPayload, error) {
|
|||
|
||||
func getDingtalkIssueCommentPayload(p *api.IssueCommentPayload) (*DingtalkPayload, error) {
|
||||
title := fmt.Sprintf("#%d: %s", p.Issue.Index, p.Issue.Title)
|
||||
url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID))
|
||||
url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID))
|
||||
var content string
|
||||
switch p.Action {
|
||||
case api.HookIssueCommentCreated:
|
||||
|
@ -286,7 +287,7 @@ func getDingtalkPullRequestPayload(p *api.PullRequestPayload) (*DingtalkPayload,
|
|||
}, nil
|
||||
}
|
||||
|
||||
func getDingtalkPullRequestApprovalPayload(p *api.PullRequestPayload, event HookEventType) (*DingtalkPayload, error) {
|
||||
func getDingtalkPullRequestApprovalPayload(p *api.PullRequestPayload, event models.HookEventType) (*DingtalkPayload, error) {
|
||||
var text, title string
|
||||
switch p.Action {
|
||||
case api.HookIssueSynchronized:
|
||||
|
@ -392,29 +393,29 @@ func getDingtalkReleasePayload(p *api.ReleasePayload) (*DingtalkPayload, error)
|
|||
}
|
||||
|
||||
// GetDingtalkPayload converts a ding talk webhook into a DingtalkPayload
|
||||
func GetDingtalkPayload(p api.Payloader, event HookEventType, meta string) (*DingtalkPayload, error) {
|
||||
func GetDingtalkPayload(p api.Payloader, event models.HookEventType, meta string) (*DingtalkPayload, error) {
|
||||
s := new(DingtalkPayload)
|
||||
|
||||
switch event {
|
||||
case HookEventCreate:
|
||||
case models.HookEventCreate:
|
||||
return getDingtalkCreatePayload(p.(*api.CreatePayload))
|
||||
case HookEventDelete:
|
||||
case models.HookEventDelete:
|
||||
return getDingtalkDeletePayload(p.(*api.DeletePayload))
|
||||
case HookEventFork:
|
||||
case models.HookEventFork:
|
||||
return getDingtalkForkPayload(p.(*api.ForkPayload))
|
||||
case HookEventIssues:
|
||||
case models.HookEventIssues:
|
||||
return getDingtalkIssuesPayload(p.(*api.IssuePayload))
|
||||
case HookEventIssueComment:
|
||||
case models.HookEventIssueComment:
|
||||
return getDingtalkIssueCommentPayload(p.(*api.IssueCommentPayload))
|
||||
case HookEventPush:
|
||||
case models.HookEventPush:
|
||||
return getDingtalkPushPayload(p.(*api.PushPayload))
|
||||
case HookEventPullRequest:
|
||||
case models.HookEventPullRequest:
|
||||
return getDingtalkPullRequestPayload(p.(*api.PullRequestPayload))
|
||||
case HookEventPullRequestApproved, HookEventPullRequestRejected, HookEventPullRequestComment:
|
||||
case models.HookEventPullRequestApproved, models.HookEventPullRequestRejected, models.HookEventPullRequestComment:
|
||||
return getDingtalkPullRequestApprovalPayload(p.(*api.PullRequestPayload), event)
|
||||
case HookEventRepository:
|
||||
case models.HookEventRepository:
|
||||
return getDingtalkRepositoryPayload(p.(*api.RepositoryPayload))
|
||||
case HookEventRelease:
|
||||
case models.HookEventRelease:
|
||||
return getDingtalkReleasePayload(p.(*api.ReleasePayload))
|
||||
}
|
||||
|
|
@ -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 models
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
@ -11,7 +11,9 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
@ -63,6 +65,15 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
// GetDiscordHook returns discord metadata
|
||||
func GetDiscordHook(w *models.Webhook) *DiscordMeta {
|
||||
s := &DiscordMeta{}
|
||||
if err := json.Unmarshal([]byte(w.Meta), s); err != nil {
|
||||
log.Error("webhook.GetDiscordHook(%d): %v", w.ID, err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func color(clr string) int {
|
||||
if clr != "" {
|
||||
clr = strings.TrimLeft(clr, "#")
|
||||
|
@ -288,7 +299,7 @@ func getDiscordIssuesPayload(p *api.IssuePayload, meta *DiscordMeta) (*DiscordPa
|
|||
|
||||
func getDiscordIssueCommentPayload(p *api.IssueCommentPayload, discord *DiscordMeta) (*DiscordPayload, error) {
|
||||
title := fmt.Sprintf("#%d: %s", p.Issue.Index, p.Issue.Title)
|
||||
url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID))
|
||||
url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID))
|
||||
content := ""
|
||||
var color int
|
||||
switch p.Action {
|
||||
|
@ -421,7 +432,7 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, meta *DiscordMeta)
|
|||
}, nil
|
||||
}
|
||||
|
||||
func getDiscordPullRequestApprovalPayload(p *api.PullRequestPayload, meta *DiscordMeta, event HookEventType) (*DiscordPayload, error) {
|
||||
func getDiscordPullRequestApprovalPayload(p *api.PullRequestPayload, meta *DiscordMeta, event models.HookEventType) (*DiscordPayload, error) {
|
||||
var text, title string
|
||||
var color int
|
||||
switch p.Action {
|
||||
|
@ -435,11 +446,11 @@ func getDiscordPullRequestApprovalPayload(p *api.PullRequestPayload, meta *Disco
|
|||
text = p.Review.Content
|
||||
|
||||
switch event {
|
||||
case HookEventPullRequestApproved:
|
||||
case models.HookEventPullRequestApproved:
|
||||
color = greenColor
|
||||
case HookEventPullRequestRejected:
|
||||
case models.HookEventPullRequestRejected:
|
||||
color = redColor
|
||||
case HookEventPullRequestComment:
|
||||
case models.HookEventPullRequestComment:
|
||||
color = greyColor
|
||||
default:
|
||||
color = yellowColor
|
||||
|
@ -534,7 +545,7 @@ func getDiscordReleasePayload(p *api.ReleasePayload, meta *DiscordMeta) (*Discor
|
|||
}
|
||||
|
||||
// GetDiscordPayload converts a discord webhook into a DiscordPayload
|
||||
func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*DiscordPayload, error) {
|
||||
func GetDiscordPayload(p api.Payloader, event models.HookEventType, meta string) (*DiscordPayload, error) {
|
||||
s := new(DiscordPayload)
|
||||
|
||||
discord := &DiscordMeta{}
|
||||
|
@ -543,40 +554,40 @@ func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*Disc
|
|||
}
|
||||
|
||||
switch event {
|
||||
case HookEventCreate:
|
||||
case models.HookEventCreate:
|
||||
return getDiscordCreatePayload(p.(*api.CreatePayload), discord)
|
||||
case HookEventDelete:
|
||||
case models.HookEventDelete:
|
||||
return getDiscordDeletePayload(p.(*api.DeletePayload), discord)
|
||||
case HookEventFork:
|
||||
case models.HookEventFork:
|
||||
return getDiscordForkPayload(p.(*api.ForkPayload), discord)
|
||||
case HookEventIssues:
|
||||
case models.HookEventIssues:
|
||||
return getDiscordIssuesPayload(p.(*api.IssuePayload), discord)
|
||||
case HookEventIssueComment:
|
||||
case models.HookEventIssueComment:
|
||||
return getDiscordIssueCommentPayload(p.(*api.IssueCommentPayload), discord)
|
||||
case HookEventPush:
|
||||
case models.HookEventPush:
|
||||
return getDiscordPushPayload(p.(*api.PushPayload), discord)
|
||||
case HookEventPullRequest:
|
||||
case models.HookEventPullRequest:
|
||||
return getDiscordPullRequestPayload(p.(*api.PullRequestPayload), discord)
|
||||
case HookEventPullRequestRejected, HookEventPullRequestApproved, HookEventPullRequestComment:
|
||||
case models.HookEventPullRequestRejected, models.HookEventPullRequestApproved, models.HookEventPullRequestComment:
|
||||
return getDiscordPullRequestApprovalPayload(p.(*api.PullRequestPayload), discord, event)
|
||||
case HookEventRepository:
|
||||
case models.HookEventRepository:
|
||||
return getDiscordRepositoryPayload(p.(*api.RepositoryPayload), discord)
|
||||
case HookEventRelease:
|
||||
case models.HookEventRelease:
|
||||
return getDiscordReleasePayload(p.(*api.ReleasePayload), discord)
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func parseHookPullRequestEventType(event HookEventType) (string, error) {
|
||||
func parseHookPullRequestEventType(event models.HookEventType) (string, error) {
|
||||
|
||||
switch event {
|
||||
|
||||
case HookEventPullRequestApproved:
|
||||
case models.HookEventPullRequestApproved:
|
||||
return "approved", nil
|
||||
case HookEventPullRequestRejected:
|
||||
case models.HookEventPullRequestRejected:
|
||||
return "rejected", nil
|
||||
case HookEventPullRequestComment:
|
||||
case models.HookEventPullRequestComment:
|
||||
return "comment", nil
|
||||
|
||||
default:
|
|
@ -2,13 +2,14 @@
|
|||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
@ -357,7 +358,7 @@ func getMSTeamsIssuesPayload(p *api.IssuePayload) (*MSTeamsPayload, error) {
|
|||
|
||||
func getMSTeamsIssueCommentPayload(p *api.IssueCommentPayload) (*MSTeamsPayload, error) {
|
||||
title := fmt.Sprintf("#%d: %s", p.Issue.Index, p.Issue.Title)
|
||||
url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID))
|
||||
url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID))
|
||||
content := ""
|
||||
var color int
|
||||
switch p.Action {
|
||||
|
@ -530,7 +531,7 @@ func getMSTeamsPullRequestPayload(p *api.PullRequestPayload) (*MSTeamsPayload, e
|
|||
}, nil
|
||||
}
|
||||
|
||||
func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, event HookEventType) (*MSTeamsPayload, error) {
|
||||
func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, event models.HookEventType) (*MSTeamsPayload, error) {
|
||||
var text, title string
|
||||
var color int
|
||||
switch p.Action {
|
||||
|
@ -544,11 +545,11 @@ func getMSTeamsPullRequestApprovalPayload(p *api.PullRequestPayload, event HookE
|
|||
text = p.Review.Content
|
||||
|
||||
switch event {
|
||||
case HookEventPullRequestApproved:
|
||||
case models.HookEventPullRequestApproved:
|
||||
color = greenColor
|
||||
case HookEventPullRequestRejected:
|
||||
case models.HookEventPullRequestRejected:
|
||||
color = redColor
|
||||
case HookEventPullRequestComment:
|
||||
case models.HookEventPullRequestComment:
|
||||
color = greyColor
|
||||
default:
|
||||
color = yellowColor
|
||||
|
@ -699,29 +700,29 @@ func getMSTeamsReleasePayload(p *api.ReleasePayload) (*MSTeamsPayload, error) {
|
|||
}
|
||||
|
||||
// GetMSTeamsPayload converts a MSTeams webhook into a MSTeamsPayload
|
||||
func GetMSTeamsPayload(p api.Payloader, event HookEventType, meta string) (*MSTeamsPayload, error) {
|
||||
func GetMSTeamsPayload(p api.Payloader, event models.HookEventType, meta string) (*MSTeamsPayload, error) {
|
||||
s := new(MSTeamsPayload)
|
||||
|
||||
switch event {
|
||||
case HookEventCreate:
|
||||
case models.HookEventCreate:
|
||||
return getMSTeamsCreatePayload(p.(*api.CreatePayload))
|
||||
case HookEventDelete:
|
||||
case models.HookEventDelete:
|
||||
return getMSTeamsDeletePayload(p.(*api.DeletePayload))
|
||||
case HookEventFork:
|
||||
case models.HookEventFork:
|
||||
return getMSTeamsForkPayload(p.(*api.ForkPayload))
|
||||
case HookEventIssues:
|
||||
case models.HookEventIssues:
|
||||
return getMSTeamsIssuesPayload(p.(*api.IssuePayload))
|
||||
case HookEventIssueComment:
|
||||
case models.HookEventIssueComment:
|
||||
return getMSTeamsIssueCommentPayload(p.(*api.IssueCommentPayload))
|
||||
case HookEventPush:
|
||||
case models.HookEventPush:
|
||||
return getMSTeamsPushPayload(p.(*api.PushPayload))
|
||||
case HookEventPullRequest:
|
||||
case models.HookEventPullRequest:
|
||||
return getMSTeamsPullRequestPayload(p.(*api.PullRequestPayload))
|
||||
case HookEventPullRequestRejected, HookEventPullRequestApproved, HookEventPullRequestComment:
|
||||
case models.HookEventPullRequestRejected, models.HookEventPullRequestApproved, models.HookEventPullRequestComment:
|
||||
return getMSTeamsPullRequestApprovalPayload(p.(*api.PullRequestPayload), event)
|
||||
case HookEventRepository:
|
||||
case models.HookEventRepository:
|
||||
return getMSTeamsRepositoryPayload(p.(*api.RepositoryPayload))
|
||||
case HookEventRelease:
|
||||
case models.HookEventRelease:
|
||||
return getMSTeamsReleasePayload(p.(*api.ReleasePayload))
|
||||
}
|
||||
|
|
@ -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 models
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
@ -10,7 +10,9 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
@ -23,6 +25,15 @@ type SlackMeta struct {
|
|||
Color string `json:"color"`
|
||||
}
|
||||
|
||||
// GetSlackHook returns slack metadata
|
||||
func GetSlackHook(w *models.Webhook) *SlackMeta {
|
||||
s := &SlackMeta{}
|
||||
if err := json.Unmarshal([]byte(w.Meta), s); err != nil {
|
||||
log.Error("webhook.GetSlackHook(%d): %v", w.ID, err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// SlackPayload contains the information about the slack channel
|
||||
type SlackPayload struct {
|
||||
Channel string `json:"channel"`
|
||||
|
@ -181,7 +192,7 @@ func getSlackIssuesPayload(p *api.IssuePayload, slack *SlackMeta) (*SlackPayload
|
|||
|
||||
func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (*SlackPayload, error) {
|
||||
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
|
||||
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)),
|
||||
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID)),
|
||||
fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
|
||||
var text, title, attachmentText string
|
||||
switch p.Action {
|
||||
|
@ -335,7 +346,7 @@ func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*S
|
|||
}, nil
|
||||
}
|
||||
|
||||
func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackMeta, event HookEventType) (*SlackPayload, error) {
|
||||
func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackMeta, event models.HookEventType) (*SlackPayload, error) {
|
||||
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
|
||||
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index),
|
||||
fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title))
|
||||
|
@ -388,7 +399,7 @@ func getSlackRepositoryPayload(p *api.RepositoryPayload, slack *SlackMeta) (*Sla
|
|||
}
|
||||
|
||||
// GetSlackPayload converts a slack webhook into a SlackPayload
|
||||
func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (*SlackPayload, error) {
|
||||
func GetSlackPayload(p api.Payloader, event models.HookEventType, meta string) (*SlackPayload, error) {
|
||||
s := new(SlackPayload)
|
||||
|
||||
slack := &SlackMeta{}
|
||||
|
@ -397,25 +408,25 @@ func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (*SlackP
|
|||
}
|
||||
|
||||
switch event {
|
||||
case HookEventCreate:
|
||||
case models.HookEventCreate:
|
||||
return getSlackCreatePayload(p.(*api.CreatePayload), slack)
|
||||
case HookEventDelete:
|
||||
case models.HookEventDelete:
|
||||
return getSlackDeletePayload(p.(*api.DeletePayload), slack)
|
||||
case HookEventFork:
|
||||
case models.HookEventFork:
|
||||
return getSlackForkPayload(p.(*api.ForkPayload), slack)
|
||||
case HookEventIssues:
|
||||
case models.HookEventIssues:
|
||||
return getSlackIssuesPayload(p.(*api.IssuePayload), slack)
|
||||
case HookEventIssueComment:
|
||||
case models.HookEventIssueComment:
|
||||
return getSlackIssueCommentPayload(p.(*api.IssueCommentPayload), slack)
|
||||
case HookEventPush:
|
||||
case models.HookEventPush:
|
||||
return getSlackPushPayload(p.(*api.PushPayload), slack)
|
||||
case HookEventPullRequest:
|
||||
case models.HookEventPullRequest:
|
||||
return getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack)
|
||||
case HookEventPullRequestRejected, HookEventPullRequestApproved, HookEventPullRequestComment:
|
||||
case models.HookEventPullRequestRejected, models.HookEventPullRequestApproved, models.HookEventPullRequestComment:
|
||||
return getSlackPullRequestApprovalPayload(p.(*api.PullRequestPayload), slack, event)
|
||||
case HookEventRepository:
|
||||
case models.HookEventRepository:
|
||||
return getSlackRepositoryPayload(p.(*api.RepositoryPayload), slack)
|
||||
case HookEventRelease:
|
||||
case models.HookEventRelease:
|
||||
return getSlackReleasePayload(p.(*api.ReleasePayload), slack)
|
||||
}
|
||||
|
|
@ -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 models
|
||||
package webhook
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
@ -10,7 +10,9 @@ import (
|
|||
"html"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
@ -30,6 +32,15 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
// GetTelegramHook returns telegram metadata
|
||||
func GetTelegramHook(w *models.Webhook) *TelegramMeta {
|
||||
s := &TelegramMeta{}
|
||||
if err := json.Unmarshal([]byte(w.Meta), s); err != nil {
|
||||
log.Error("webhook.GetTelegramHook(%d): %v", w.ID, err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// SetSecret sets the telegram secret
|
||||
func (p *TelegramPayload) SetSecret(_ string) {}
|
||||
|
||||
|
@ -169,7 +180,7 @@ func getTelegramIssuesPayload(p *api.IssuePayload) (*TelegramPayload, error) {
|
|||
}
|
||||
|
||||
func getTelegramIssueCommentPayload(p *api.IssueCommentPayload) (*TelegramPayload, error) {
|
||||
url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID))
|
||||
url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID))
|
||||
title := fmt.Sprintf(`<a href="%s">#%d %s</a>`, url, p.Issue.Index, html.EscapeString(p.Issue.Title))
|
||||
var text string
|
||||
switch p.Action {
|
||||
|
@ -214,7 +225,7 @@ func getTelegramPullRequestPayload(p *api.PullRequestPayload) (*TelegramPayload,
|
|||
p.PullRequest.HTMLURL, p.Index, p.PullRequest.Title)
|
||||
text = p.PullRequest.Body
|
||||
case api.HookIssueAssigned:
|
||||
list, err := MakeAssigneeList(&Issue{ID: p.PullRequest.ID})
|
||||
list, err := models.MakeAssigneeList(&models.Issue{ID: p.PullRequest.ID})
|
||||
if err != nil {
|
||||
return &TelegramPayload{}, err
|
||||
}
|
||||
|
@ -297,27 +308,27 @@ func getTelegramReleasePayload(p *api.ReleasePayload) (*TelegramPayload, error)
|
|||
}
|
||||
|
||||
// GetTelegramPayload converts a telegram webhook into a TelegramPayload
|
||||
func GetTelegramPayload(p api.Payloader, event HookEventType, meta string) (*TelegramPayload, error) {
|
||||
func GetTelegramPayload(p api.Payloader, event models.HookEventType, meta string) (*TelegramPayload, error) {
|
||||
s := new(TelegramPayload)
|
||||
|
||||
switch event {
|
||||
case HookEventCreate:
|
||||
case models.HookEventCreate:
|
||||
return getTelegramCreatePayload(p.(*api.CreatePayload))
|
||||
case HookEventDelete:
|
||||
case models.HookEventDelete:
|
||||
return getTelegramDeletePayload(p.(*api.DeletePayload))
|
||||
case HookEventFork:
|
||||
case models.HookEventFork:
|
||||
return getTelegramForkPayload(p.(*api.ForkPayload))
|
||||
case HookEventIssues:
|
||||
case models.HookEventIssues:
|
||||
return getTelegramIssuesPayload(p.(*api.IssuePayload))
|
||||
case HookEventIssueComment:
|
||||
case models.HookEventIssueComment:
|
||||
return getTelegramIssueCommentPayload(p.(*api.IssueCommentPayload))
|
||||
case HookEventPush:
|
||||
case models.HookEventPush:
|
||||
return getTelegramPushPayload(p.(*api.PushPayload))
|
||||
case HookEventPullRequest:
|
||||
case models.HookEventPullRequest:
|
||||
return getTelegramPullRequestPayload(p.(*api.PullRequestPayload))
|
||||
case HookEventRepository:
|
||||
case models.HookEventRepository:
|
||||
return getTelegramRepositoryPayload(p.(*api.RepositoryPayload))
|
||||
case HookEventRelease:
|
||||
case models.HookEventRelease:
|
||||
return getTelegramReleasePayload(p.(*api.ReleasePayload))
|
||||
}
|
||||
|
|
@ -90,27 +90,27 @@ func prepareWebhook(w *models.Webhook, repo *models.Repository, event models.Hoo
|
|||
// Use separate objects so modifications won't be made on payload on non-Gogs/Gitea type hooks.
|
||||
switch w.HookTaskType {
|
||||
case models.SLACK:
|
||||
payloader, err = models.GetSlackPayload(p, event, w.Meta)
|
||||
payloader, err = GetSlackPayload(p, event, w.Meta)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetSlackPayload: %v", err)
|
||||
}
|
||||
case models.DISCORD:
|
||||
payloader, err = models.GetDiscordPayload(p, event, w.Meta)
|
||||
payloader, err = GetDiscordPayload(p, event, w.Meta)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetDiscordPayload: %v", err)
|
||||
}
|
||||
case models.DINGTALK:
|
||||
payloader, err = models.GetDingtalkPayload(p, event, w.Meta)
|
||||
payloader, err = GetDingtalkPayload(p, event, w.Meta)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetDingtalkPayload: %v", err)
|
||||
}
|
||||
case models.TELEGRAM:
|
||||
payloader, err = models.GetTelegramPayload(p, event, w.Meta)
|
||||
payloader, err = GetTelegramPayload(p, event, w.Meta)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetTelegramPayload: %v", err)
|
||||
}
|
||||
case models.MSTEAMS:
|
||||
payloader, err = models.GetMSTeamsPayload(p, event, w.Meta)
|
||||
payloader, err = GetMSTeamsPayload(p, event, w.Meta)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetMSTeamsPayload: %v", err)
|
||||
}
|
||||
|
|
|
@ -12,6 +12,18 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestWebhook_GetSlackHook(t *testing.T) {
|
||||
w := &models.Webhook{
|
||||
Meta: `{"channel": "foo", "username": "username", "color": "blue"}`,
|
||||
}
|
||||
slackHook := GetSlackHook(w)
|
||||
assert.Equal(t, *slackHook, SlackMeta{
|
||||
Channel: "foo",
|
||||
Username: "username",
|
||||
Color: "blue",
|
||||
})
|
||||
}
|
||||
|
||||
func TestPrepareWebhooks(t *testing.T) {
|
||||
assert.NoError(t, models.PrepareTestDatabase())
|
||||
|
||||
|
|
|
@ -1090,6 +1090,9 @@ activity.period.daily = 1 day
|
|||
activity.period.halfweekly = 3 days
|
||||
activity.period.weekly = 1 week
|
||||
activity.period.monthly = 1 month
|
||||
activity.period.quarterly = 3 months
|
||||
activity.period.semiyearly = 6 months
|
||||
activity.period.yearly = 1 year
|
||||
activity.overview = Overview
|
||||
activity.active_prs_count_1 = <strong>%d</strong> Active Pull Request
|
||||
activity.active_prs_count_n = <strong>%d</strong> Active Pull Requests
|
||||
|
|
|
@ -741,6 +741,7 @@ editor.no_changes_to_show=表示する変更箇所はありません。
|
|||
editor.fail_to_update_file=ファイル '%s' を作成または変更できませんでした: %v
|
||||
editor.add_subdir=ディレクトリを追加…
|
||||
editor.unable_to_upload_files='%s' へファイルをアップロードすることができませんでした: %v
|
||||
editor.upload_file_is_locked=ファイル '%[1]s' は %[2]s がロックしています。
|
||||
editor.upload_files_to_dir='%s' にファイルをアップロード
|
||||
editor.cannot_commit_to_protected_branch=保護されたブランチ '%s' にコミットすることはできません。
|
||||
|
||||
|
@ -1088,6 +1089,9 @@ activity.period.daily=1日
|
|||
activity.period.halfweekly=3日
|
||||
activity.period.weekly=1週間
|
||||
activity.period.monthly=1ヶ月
|
||||
activity.period.quarterly=3ヶ月
|
||||
activity.period.semiyearly=6ヶ月
|
||||
activity.period.yearly=1年
|
||||
activity.overview=概要
|
||||
activity.active_prs_count_1=<strong>%d</strong>件のアクティブなプルリクエスト
|
||||
activity.active_prs_count_n=<strong>%d</strong>件のアクティブなプルリクエスト
|
||||
|
@ -1379,8 +1383,20 @@ settings.unarchive.success=リポジトリのアーカイブを解除しまし
|
|||
settings.unarchive.error=リポジトリのアーカイブ解除でエラーが発生しました。 詳細はログを確認してください。
|
||||
settings.update_avatar_success=リポジトリのアバターを更新しました。
|
||||
settings.lfs=LFS
|
||||
settings.lfs_filelist=このリポジトリに含まれているLFSファイル
|
||||
settings.lfs_no_lfs_files=このリポジトリにLFSファイルはありません
|
||||
settings.lfs_findcommits=コミットを検索
|
||||
settings.lfs_lfs_file_no_commits=このLFSファイルに関するコミットはありません
|
||||
settings.lfs_delete=LFSファイル(OID %s)の削除
|
||||
settings.lfs_delete_warning=LFSファイルを削除すると、チェックアウトのときに 'object does not exist' エラーが発生するかもしれません。 よろしいですか?
|
||||
settings.lfs_findpointerfiles=ポインタファイルを検索
|
||||
settings.lfs_pointers.found=%d件のblobポインタ - 登録済 %d件、未登録 %d件 (実体ファイルなし %d件)
|
||||
settings.lfs_pointers.sha=Blob SHA
|
||||
settings.lfs_pointers.oid=OID
|
||||
settings.lfs_pointers.inRepo=Repo内
|
||||
settings.lfs_pointers.exists=実体ファイルあり
|
||||
settings.lfs_pointers.accessible=ユーザーがアクセス可
|
||||
settings.lfs_pointers.associateAccessible=アクセス可能な%d件のOIDを登録
|
||||
|
||||
diff.browse_source=ソースを参照
|
||||
diff.parent=親
|
||||
|
|
|
@ -1089,6 +1089,9 @@ activity.period.daily=1 dia
|
|||
activity.period.halfweekly=3 dias
|
||||
activity.period.weekly=1 semana
|
||||
activity.period.monthly=1 mês
|
||||
activity.period.quarterly=3 meses
|
||||
activity.period.semiyearly=6 meses
|
||||
activity.period.yearly=1 ano
|
||||
activity.overview=Visão geral
|
||||
activity.active_prs_count_1=<strong>%d</strong> Pull request ativo
|
||||
activity.active_prs_count_n=<strong>%d</strong> Pull requests ativos
|
||||
|
|
|
@ -701,6 +701,7 @@ editor.no_changes_to_show=Gösterilecek değişiklik yok.
|
|||
editor.fail_to_update_file=Şu hata ile '%s' dosyasını güncelleme/oluşturma başarısız oldu: %v
|
||||
editor.add_subdir=Bir dizin ekle…
|
||||
editor.unable_to_upload_files=Şu hata ile dosyalar '%s' 'a yüklenemedi: %v
|
||||
editor.upload_file_is_locked='%s' dosyası %s tarafından kilitlendi.
|
||||
editor.upload_files_to_dir=Dosyaları '%s' 'a yükle
|
||||
editor.cannot_commit_to_protected_branch=Korunan '%s' dalına işleme yapılamıyor.
|
||||
|
||||
|
@ -1046,17 +1047,20 @@ activity.period.daily=1 gün
|
|||
activity.period.halfweekly=3 gün
|
||||
activity.period.weekly=1 hafta
|
||||
activity.period.monthly=1 ay
|
||||
activity.period.quarterly=3 ay
|
||||
activity.period.semiyearly=6 ay
|
||||
activity.period.yearly=1 yıl
|
||||
activity.overview=Genel Bakış
|
||||
activity.active_prs_count_1=<strong>%d</strong> Aktif Çekme İsteği
|
||||
activity.active_prs_count_n=<strong>%d</strong> Aktif Çekme İsteği
|
||||
activity.merged_prs_count_1=Birleştirilmiş Çekme İsteği
|
||||
activity.merged_prs_count_n=Birleştirilmiş Çekme İstekleri
|
||||
activity.merged_prs_count_n=Birleştirilmiş Çekme İsteği
|
||||
activity.opened_prs_count_1=Önerilen Çekme İsteği
|
||||
activity.opened_prs_count_n=Önerilen Çekme İstekleri
|
||||
activity.opened_prs_count_n=Önerilen Çekme İsteği
|
||||
activity.title.user_1=%d kullanıcı
|
||||
activity.title.user_n=%d kullanıcı
|
||||
activity.title.prs_1=%d Çekme isteği
|
||||
activity.title.prs_n=%d Çekme istekleri
|
||||
activity.title.prs_n=%d Çekme isteği
|
||||
activity.title.prs_merged_by=%s tarafından %s birleştirildi
|
||||
activity.title.prs_opened_by=%s tarafından %s önerildi
|
||||
activity.merged_prs_label=Birleştirilen
|
||||
|
@ -1064,20 +1068,21 @@ activity.opened_prs_label=Önerilen
|
|||
activity.active_issues_count_1=<strong>%d</strong> Aktif Konu
|
||||
activity.active_issues_count_n=<strong>%d</strong> Aktif Konu
|
||||
activity.closed_issues_count_1=Kapalı Konu
|
||||
activity.closed_issues_count_n=Kapalı Konular
|
||||
activity.closed_issues_count_n=Kapalı Konu
|
||||
activity.title.issues_1=%d Konu
|
||||
activity.title.issues_n=%d Konu
|
||||
activity.title.issues_closed_by=%s %s tarafından kapatıldı
|
||||
activity.title.issues_created_by=%s %s tarafından oluşturuldu
|
||||
activity.closed_issue_label=Kapalı
|
||||
activity.new_issues_count_1=Yeni Konu
|
||||
activity.new_issues_count_n=Yeni Konular
|
||||
activity.new_issues_count_n=Yeni Konu
|
||||
activity.new_issue_label=Açıldı
|
||||
activity.title.unresolved_conv_1=%d Çözümlenmemiş Konuşma
|
||||
activity.title.unresolved_conv_n=%d Çözümlenmemiş Konuşma
|
||||
activity.unresolved_conv_desc=Son zamanlarda değişen bu konu ve değişiklik istekleri henüz çözümlenmedi.
|
||||
activity.unresolved_conv_label=Açık
|
||||
activity.title.releases_1=%d Serbest bırak
|
||||
activity.title.releases_n=%d Serbest bırakmalar
|
||||
activity.title.releases_1=%d Sürüm
|
||||
activity.title.releases_n=%d Sürüm
|
||||
activity.title.releases_published_by=%s tarafından %s yayınlandı
|
||||
activity.published_release_label=Yayınlandı
|
||||
activity.no_git_activity=Bu dönemde herhangi bir işleme yapılmamıştır.
|
||||
|
@ -1095,6 +1100,7 @@ activity.git_stats_file_1=%d dosya
|
|||
activity.git_stats_file_n=%d dosya
|
||||
activity.git_stats_files_changed_1=değişti
|
||||
activity.git_stats_files_changed_n=değişti
|
||||
activity.git_stats_additions=ve oldu
|
||||
activity.git_stats_addition_1=%d ekleme
|
||||
activity.git_stats_addition_n=%d ekleme
|
||||
activity.git_stats_and_deletions=ve
|
||||
|
|
|
@ -79,12 +79,11 @@ func NewUserPost(ctx *context.Context, form auth.AdminCreateUserForm) {
|
|||
}
|
||||
|
||||
u := &models.User{
|
||||
Name: form.UserName,
|
||||
Email: form.Email,
|
||||
Passwd: form.Password,
|
||||
IsActive: true,
|
||||
LoginType: models.LoginPlain,
|
||||
MustChangePassword: form.MustChangePassword,
|
||||
Name: form.UserName,
|
||||
Email: form.Email,
|
||||
Passwd: form.Password,
|
||||
IsActive: true,
|
||||
LoginType: models.LoginPlain,
|
||||
}
|
||||
|
||||
if len(form.LoginType) > 0 {
|
||||
|
@ -95,9 +94,12 @@ func NewUserPost(ctx *context.Context, form auth.AdminCreateUserForm) {
|
|||
u.LoginName = form.LoginName
|
||||
}
|
||||
}
|
||||
if !password.IsComplexEnough(form.Password) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.password_complexity"), tplUserNew, &form)
|
||||
return
|
||||
if u.LoginType == models.LoginPlain {
|
||||
if !password.IsComplexEnough(form.Password) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.password_complexity"), tplUserNew, &form)
|
||||
return
|
||||
}
|
||||
u.MustChangePassword = form.MustChangePassword
|
||||
}
|
||||
if err := models.CreateUser(u); err != nil {
|
||||
switch {
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/structs"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/webhook"
|
||||
|
||||
"github.com/unknwon/com"
|
||||
)
|
||||
|
@ -166,7 +167,7 @@ func ToHook(repoLink string, w *models.Webhook) *api.Hook {
|
|||
"content_type": w.ContentType.Name(),
|
||||
}
|
||||
if w.HookTaskType == models.SLACK {
|
||||
s := w.GetSlackHook()
|
||||
s := webhook.GetSlackHook(w)
|
||||
config["channel"] = s.Channel
|
||||
config["username"] = s.Username
|
||||
config["icon_url"] = s.IconURL
|
||||
|
|
|
@ -458,9 +458,16 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
|
|||
issue.Content = *form.Body
|
||||
}
|
||||
|
||||
// Update the deadline
|
||||
if form.Deadline != nil && ctx.Repo.CanWrite(models.UnitTypeIssues) {
|
||||
deadlineUnix := timeutil.TimeStamp(form.Deadline.Unix())
|
||||
// Update or remove the deadline, only if set and allowed
|
||||
if (form.Deadline != nil || form.RemoveDeadline != nil) && ctx.Repo.CanWrite(models.UnitTypeIssues) {
|
||||
var deadlineUnix timeutil.TimeStamp
|
||||
|
||||
if (form.RemoveDeadline == nil || !*form.RemoveDeadline) && !form.Deadline.IsZero() {
|
||||
deadline := time.Date(form.Deadline.Year(), form.Deadline.Month(), form.Deadline.Day(),
|
||||
23, 59, 59, 0, form.Deadline.Location())
|
||||
deadlineUnix = timeutil.TimeStamp(deadline.Unix())
|
||||
}
|
||||
|
||||
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
|
||||
ctx.Error(500, "UpdateIssueDeadline", err)
|
||||
return
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/auth"
|
||||
|
@ -326,7 +327,7 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
|
|||
func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
|
||||
// swagger:operation PATCH /repos/{owner}/{repo}/pulls/{index} repository repoEditPullRequest
|
||||
// ---
|
||||
// summary: Update a pull request
|
||||
// summary: Update a pull request. If using deadline only the date will be taken into account, and time of day ignored.
|
||||
// consumes:
|
||||
// - application/json
|
||||
// produces:
|
||||
|
@ -385,9 +386,15 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
|
|||
issue.Content = form.Body
|
||||
}
|
||||
|
||||
// Update Deadline
|
||||
if form.Deadline != nil {
|
||||
deadlineUnix := timeutil.TimeStamp(form.Deadline.Unix())
|
||||
// Update or remove deadline if set
|
||||
if form.Deadline != nil || form.RemoveDeadline != nil {
|
||||
var deadlineUnix timeutil.TimeStamp
|
||||
if (form.RemoveDeadline == nil || !*form.RemoveDeadline) && !form.Deadline.IsZero() {
|
||||
deadline := time.Date(form.Deadline.Year(), form.Deadline.Month(), form.Deadline.Day(),
|
||||
23, 59, 59, 0, form.Deadline.Location())
|
||||
deadlineUnix = timeutil.TimeStamp(deadline.Unix())
|
||||
}
|
||||
|
||||
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
|
||||
ctx.Error(500, "UpdateIssueDeadline", err)
|
||||
return
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/webhook"
|
||||
"code.gitea.io/gitea/routers/api/v1/convert"
|
||||
"code.gitea.io/gitea/routers/utils"
|
||||
|
||||
|
@ -129,7 +130,7 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID
|
|||
return nil, false
|
||||
}
|
||||
|
||||
meta, err := json.Marshal(&models.SlackMeta{
|
||||
meta, err := json.Marshal(&webhook.SlackMeta{
|
||||
Channel: strings.TrimSpace(channel),
|
||||
Username: form.Config["username"],
|
||||
IconURL: form.Config["icon_url"],
|
||||
|
@ -203,7 +204,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *models.Webho
|
|||
|
||||
if w.HookTaskType == models.SLACK {
|
||||
if channel, ok := form.Config["channel"]; ok {
|
||||
meta, err := json.Marshal(&models.SlackMeta{
|
||||
meta, err := json.Marshal(&webhook.SlackMeta{
|
||||
Channel: channel,
|
||||
Username: form.Config["username"],
|
||||
IconURL: form.Config["icon_url"],
|
||||
|
|
|
@ -35,6 +35,12 @@ func Activity(ctx *context.Context) {
|
|||
timeFrom = timeUntil.Add(-time.Hour * 168)
|
||||
case "monthly":
|
||||
timeFrom = timeUntil.AddDate(0, -1, 0)
|
||||
case "quarterly":
|
||||
timeFrom = timeUntil.AddDate(0, -3, 0)
|
||||
case "semiyearly":
|
||||
timeFrom = timeUntil.AddDate(0, -6, 0)
|
||||
case "yearly":
|
||||
timeFrom = timeUntil.AddDate(-1, 0, 0)
|
||||
default:
|
||||
ctx.Data["Period"] = "weekly"
|
||||
timeFrom = timeUntil.Add(-time.Hour * 168)
|
||||
|
@ -70,6 +76,12 @@ func ActivityAuthors(ctx *context.Context) {
|
|||
timeFrom = timeUntil.Add(-time.Hour * 168)
|
||||
case "monthly":
|
||||
timeFrom = timeUntil.AddDate(0, -1, 0)
|
||||
case "quarterly":
|
||||
timeFrom = timeUntil.AddDate(0, -3, 0)
|
||||
case "semiyearly":
|
||||
timeFrom = timeUntil.AddDate(0, -6, 0)
|
||||
case "yearly":
|
||||
timeFrom = timeUntil.AddDate(-1, 0, 0)
|
||||
default:
|
||||
timeFrom = timeUntil.Add(-time.Hour * 168)
|
||||
}
|
||||
|
|
|
@ -268,7 +268,7 @@ func DiscordHooksNewPost(ctx *context.Context, form auth.NewDiscordHookForm) {
|
|||
return
|
||||
}
|
||||
|
||||
meta, err := json.Marshal(&models.DiscordMeta{
|
||||
meta, err := json.Marshal(&webhook.DiscordMeta{
|
||||
Username: form.Username,
|
||||
IconURL: form.IconURL,
|
||||
})
|
||||
|
@ -357,7 +357,7 @@ func TelegramHooksNewPost(ctx *context.Context, form auth.NewTelegramHookForm) {
|
|||
return
|
||||
}
|
||||
|
||||
meta, err := json.Marshal(&models.TelegramMeta{
|
||||
meta, err := json.Marshal(&webhook.TelegramMeta{
|
||||
BotToken: form.BotToken,
|
||||
ChatID: form.ChatID,
|
||||
})
|
||||
|
@ -452,7 +452,7 @@ func SlackHooksNewPost(ctx *context.Context, form auth.NewSlackHookForm) {
|
|||
return
|
||||
}
|
||||
|
||||
meta, err := json.Marshal(&models.SlackMeta{
|
||||
meta, err := json.Marshal(&webhook.SlackMeta{
|
||||
Channel: strings.TrimSpace(form.Channel),
|
||||
Username: form.Username,
|
||||
IconURL: form.IconURL,
|
||||
|
@ -515,11 +515,11 @@ func checkWebhook(ctx *context.Context) (*orgRepoCtx, *models.Webhook) {
|
|||
ctx.Data["HookType"] = w.HookTaskType.Name()
|
||||
switch w.HookTaskType {
|
||||
case models.SLACK:
|
||||
ctx.Data["SlackHook"] = w.GetSlackHook()
|
||||
ctx.Data["SlackHook"] = webhook.GetSlackHook(w)
|
||||
case models.DISCORD:
|
||||
ctx.Data["DiscordHook"] = w.GetDiscordHook()
|
||||
ctx.Data["DiscordHook"] = webhook.GetDiscordHook(w)
|
||||
case models.TELEGRAM:
|
||||
ctx.Data["TelegramHook"] = w.GetTelegramHook()
|
||||
ctx.Data["TelegramHook"] = webhook.GetTelegramHook(w)
|
||||
}
|
||||
|
||||
ctx.Data["History"], err = w.History(1)
|
||||
|
@ -646,7 +646,7 @@ func SlackHooksEditPost(ctx *context.Context, form auth.NewSlackHookForm) {
|
|||
return
|
||||
}
|
||||
|
||||
meta, err := json.Marshal(&models.SlackMeta{
|
||||
meta, err := json.Marshal(&webhook.SlackMeta{
|
||||
Channel: strings.TrimSpace(form.Channel),
|
||||
Username: form.Username,
|
||||
IconURL: form.IconURL,
|
||||
|
@ -690,7 +690,7 @@ func DiscordHooksEditPost(ctx *context.Context, form auth.NewDiscordHookForm) {
|
|||
return
|
||||
}
|
||||
|
||||
meta, err := json.Marshal(&models.DiscordMeta{
|
||||
meta, err := json.Marshal(&webhook.DiscordMeta{
|
||||
Username: form.Username,
|
||||
IconURL: form.IconURL,
|
||||
})
|
||||
|
@ -763,7 +763,7 @@ func TelegramHooksEditPost(ctx *context.Context, form auth.NewTelegramHookForm)
|
|||
ctx.HTML(200, orCtx.NewTemplate)
|
||||
return
|
||||
}
|
||||
meta, err := json.Marshal(&models.TelegramMeta{
|
||||
meta, err := json.Marshal(&webhook.TelegramMeta{
|
||||
BotToken: form.BotToken,
|
||||
ChatID: form.ChatID,
|
||||
})
|
||||
|
|
|
@ -5,10 +5,7 @@
|
|||
package issue
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/notification"
|
||||
)
|
||||
|
||||
|
@ -24,18 +21,6 @@ func NewIssue(repo *models.Repository, issue *models.Issue, labelIDs []int64, uu
|
|||
}
|
||||
}
|
||||
|
||||
if err := models.NotifyWatchers(&models.Action{
|
||||
ActUserID: issue.Poster.ID,
|
||||
ActUser: issue.Poster,
|
||||
OpType: models.ActionCreateIssue,
|
||||
Content: fmt.Sprintf("%d|%s", issue.Index, issue.Title),
|
||||
RepoID: repo.ID,
|
||||
Repo: repo,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
}); err != nil {
|
||||
log.Error("NotifyWatchers: %v", err)
|
||||
}
|
||||
|
||||
notification.NotifyNewIssue(issue)
|
||||
|
||||
return nil
|
||||
|
|
|
@ -9,9 +9,8 @@ import (
|
|||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/notification"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/webhook"
|
||||
)
|
||||
|
||||
func syncAction(opType models.ActionType, repo *models.Repository, refName string, data []byte) error {
|
||||
|
@ -45,25 +44,9 @@ func SyncPushAction(repo *models.Repository, opts SyncPushActionOptions) error {
|
|||
opts.Commits.Commits = opts.Commits.Commits[:setting.UI.FeedMaxCommitNum]
|
||||
}
|
||||
|
||||
apiCommits, err := opts.Commits.ToAPIPayloadCommits(repo.RepoPath(), repo.HTMLURL())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
opts.Commits.CompareURL = repo.ComposeCompareURL(opts.OldCommitID, opts.NewCommitID)
|
||||
apiPusher := repo.MustOwner().APIFormat()
|
||||
if err := webhook.PrepareWebhooks(repo, models.HookEventPush, &api.PushPayload{
|
||||
Ref: opts.RefName,
|
||||
Before: opts.OldCommitID,
|
||||
After: opts.NewCommitID,
|
||||
CompareURL: setting.AppURL + opts.Commits.CompareURL,
|
||||
Commits: apiCommits,
|
||||
Repo: repo.APIFormat(models.AccessModeOwner),
|
||||
Pusher: apiPusher,
|
||||
Sender: apiPusher,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("PrepareWebhooks: %v", err)
|
||||
}
|
||||
|
||||
notification.NotifyPushCommits(repo.MustOwner(), repo, opts.RefName, opts.OldCommitID, opts.NewCommitID, opts.Commits)
|
||||
|
||||
data, err := json.Marshal(opts.Commits)
|
||||
if err != nil {
|
||||
|
|
|
@ -20,10 +20,9 @@ import (
|
|||
"code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/notification"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/webhook"
|
||||
|
||||
"github.com/mcuadros/go-version"
|
||||
)
|
||||
|
@ -360,16 +359,7 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
|||
return nil
|
||||
}
|
||||
|
||||
mode, _ := models.AccessLevel(doer, pr.Issue.Repo)
|
||||
if err = webhook.PrepareWebhooks(pr.Issue.Repo, models.HookEventPullRequest, &api.PullRequestPayload{
|
||||
Action: api.HookIssueClosed,
|
||||
Index: pr.Index,
|
||||
PullRequest: pr.APIFormat(),
|
||||
Repository: pr.Issue.Repo.APIFormat(mode),
|
||||
Sender: doer.APIFormat(),
|
||||
}); err != nil {
|
||||
log.Error("PrepareWebhooks: %v", err)
|
||||
}
|
||||
notification.NotifyIssueChangeStatus(doer, pr.Issue, true)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ import (
|
|||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/webhook"
|
||||
"code.gitea.io/gitea/modules/notification"
|
||||
issue_service "code.gitea.io/gitea/services/issue"
|
||||
)
|
||||
|
||||
|
@ -27,30 +26,10 @@ func NewPullRequest(repo *models.Repository, pull *models.Issue, labelIDs []int6
|
|||
}
|
||||
}
|
||||
|
||||
if err := models.NotifyWatchers(&models.Action{
|
||||
ActUserID: pull.Poster.ID,
|
||||
ActUser: pull.Poster,
|
||||
OpType: models.ActionCreatePullRequest,
|
||||
Content: fmt.Sprintf("%d|%s", pull.Index, pull.Title),
|
||||
RepoID: repo.ID,
|
||||
Repo: repo,
|
||||
IsPrivate: repo.IsPrivate,
|
||||
}); err != nil {
|
||||
log.Error("NotifyWatchers: %v", err)
|
||||
}
|
||||
|
||||
pr.Issue = pull
|
||||
pull.PullRequest = pr
|
||||
mode, _ := models.AccessLevel(pull.Poster, repo)
|
||||
if err := webhook.PrepareWebhooks(repo, models.HookEventPullRequest, &api.PullRequestPayload{
|
||||
Action: api.HookIssueOpened,
|
||||
Index: pull.Index,
|
||||
PullRequest: pr.APIFormat(),
|
||||
Repository: repo.APIFormat(mode),
|
||||
Sender: pull.Poster.APIFormat(),
|
||||
}); err != nil {
|
||||
log.Error("PrepareWebhooks: %v", err)
|
||||
}
|
||||
|
||||
notification.NotifyNewPullRequest(pr)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -109,23 +88,9 @@ func AddTestPullRequestTask(doer *models.User, repoID int64, branch string, isSy
|
|||
if err == nil {
|
||||
for _, pr := range prs {
|
||||
pr.Issue.PullRequest = pr
|
||||
if err = pr.Issue.LoadAttributes(); err != nil {
|
||||
log.Error("LoadAttributes: %v", err)
|
||||
continue
|
||||
}
|
||||
if err = webhook.PrepareWebhooks(pr.Issue.Repo, models.HookEventPullRequest, &api.PullRequestPayload{
|
||||
Action: api.HookIssueSynchronized,
|
||||
Index: pr.Issue.Index,
|
||||
PullRequest: pr.Issue.PullRequest.APIFormat(),
|
||||
Repository: pr.Issue.Repo.APIFormat(models.AccessModeNone),
|
||||
Sender: doer.APIFormat(),
|
||||
}); err != nil {
|
||||
log.Error("PrepareWebhooks [pull_id: %v]: %v", pr.ID, err)
|
||||
continue
|
||||
}
|
||||
notification.NotifyPullRequestSynchronized(doer, pr)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
addHeadRepoTasks(prs)
|
||||
|
|
|
@ -7,8 +7,7 @@ package pull
|
|||
|
||||
import (
|
||||
"code.gitea.io/gitea/models"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/webhook"
|
||||
"code.gitea.io/gitea/modules/notification"
|
||||
)
|
||||
|
||||
// CreateReview creates a new review based on opts
|
||||
|
@ -18,7 +17,9 @@ func CreateReview(opts models.CreateReviewOptions) (*models.Review, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return review, reviewHook(review)
|
||||
notification.NotifyPullRequestReview(review.Issue.PullRequest, review, nil)
|
||||
|
||||
return review, nil
|
||||
}
|
||||
|
||||
// UpdateReview updates a review
|
||||
|
@ -28,43 +29,7 @@ func UpdateReview(review *models.Review) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return reviewHook(review)
|
||||
}
|
||||
|
||||
func reviewHook(review *models.Review) error {
|
||||
var reviewHookType models.HookEventType
|
||||
|
||||
switch review.Type {
|
||||
case models.ReviewTypeApprove:
|
||||
reviewHookType = models.HookEventPullRequestApproved
|
||||
case models.ReviewTypeComment:
|
||||
reviewHookType = models.HookEventPullRequestComment
|
||||
case models.ReviewTypeReject:
|
||||
reviewHookType = models.HookEventPullRequestRejected
|
||||
default:
|
||||
// unsupported review webhook type here
|
||||
return nil
|
||||
}
|
||||
|
||||
pr := review.Issue.PullRequest
|
||||
|
||||
if err := pr.LoadIssue(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mode, err := models.AccessLevel(review.Issue.Poster, review.Issue.Repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return webhook.PrepareWebhooks(review.Issue.Repo, reviewHookType, &api.PullRequestPayload{
|
||||
Action: api.HookIssueSynchronized,
|
||||
Index: review.Issue.Index,
|
||||
PullRequest: pr.APIFormat(),
|
||||
Repository: review.Issue.Repo.APIFormat(mode),
|
||||
Sender: review.Reviewer.APIFormat(),
|
||||
Review: &api.ReviewPayload{
|
||||
Type: string(reviewHookType),
|
||||
Content: review.Content,
|
||||
},
|
||||
})
|
||||
notification.NotifyPullRequestReview(review.Issue.PullRequest, review, nil)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
<input id="password" name="password" type="password" value="{{.password}}" {{if eq .login_type "0-0"}}required{{end}}>
|
||||
</div>
|
||||
|
||||
<div class="inline field">
|
||||
<div class="inline field local{{if ne .login_type "0-0"}} hide{{end}}">
|
||||
<div class="ui checkbox">
|
||||
<label><strong>{{.i18n.Tr "auth.allow_password_change" }}</strong></label>
|
||||
<input name="must_change_password" type="checkbox" checked>
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
<a class="{{if eq .Period "halfweekly"}}active {{end}}item" href="{{$.RepoLink}}/activity/halfweekly">{{.i18n.Tr "repo.activity.period.halfweekly"}}</a>
|
||||
<a class="{{if eq .Period "weekly"}}active {{end}}item" href="{{$.RepoLink}}/activity/weekly">{{.i18n.Tr "repo.activity.period.weekly"}}</a>
|
||||
<a class="{{if eq .Period "monthly"}}active {{end}}item" href="{{$.RepoLink}}/activity/monthly">{{.i18n.Tr "repo.activity.period.monthly"}}</a>
|
||||
<a class="{{if eq .Period "quarterly"}}active {{end}}item" href="{{$.RepoLink}}/activity/quarterly">{{.i18n.Tr "repo.activity.period.quarterly"}}</a>
|
||||
<a class="{{if eq .Period "semiyearly"}}active {{end}}item" href="{{$.RepoLink}}/activity/semiyearly">{{.i18n.Tr "repo.activity.period.semiyearly"}}</a>
|
||||
<a class="{{if eq .Period "yearly"}}active {{end}}item" href="{{$.RepoLink}}/activity/yearly">{{.i18n.Tr "repo.activity.period.yearly"}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -13,56 +13,55 @@
|
|||
{{range $r}}
|
||||
<tr>
|
||||
<td class="author">
|
||||
{{$userName := .Author.Name}}
|
||||
{{$userName := .Author.Name}}
|
||||
{{if .User}}
|
||||
{{if .User.FullName}}
|
||||
{{$userName = .User.FullName}}
|
||||
{{$userName = .User.FullName}}
|
||||
{{end}}
|
||||
<img class="ui avatar image" src="{{.User.RelAvatarLink}}" alt=""/> <a href="{{AppSubUrl}}/{{.User.Name}}">{{$userName}}</a>
|
||||
<img class="ui avatar image" src="{{.User.RelAvatarLink}}" alt=""/> <a href="{{AppSubUrl}}/{{.User.Name}}">{{$userName}}</a>
|
||||
{{else}}
|
||||
<img class="ui avatar image" src="{{AvatarLink .Author.Email}}" alt=""/> {{$userName}}
|
||||
{{end}}
|
||||
</td>
|
||||
<td class="sha">
|
||||
{{$class := "ui sha label"}}
|
||||
{{if .Signature}}
|
||||
{{$class = (printf "%s%s" $class " isSigned")}}
|
||||
{{if .Verification.Verified}}
|
||||
{{$class = (printf "%s%s" $class " isVerified")}}
|
||||
{{else if .Verification.Warning}}
|
||||
{{$class = (printf "%s%s" $class " isWarning")}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{if $.Reponame}}
|
||||
<a href="{{AppSubUrl}}/{{$.Username}}/{{$.Reponame}}/commit/{{.ID}}" rel="nofollow" class="{{$class}}">
|
||||
{{else}}
|
||||
<span class="{{$class}}">
|
||||
{{end}}
|
||||
{{$class := "ui sha label"}}
|
||||
{{if .Signature}}
|
||||
{{$class = (printf "%s%s" $class " isSigned")}}
|
||||
{{if .Verification.Verified}}
|
||||
{{$class = (printf "%s%s" $class " isVerified")}}
|
||||
{{else if .Verification.Warning}}
|
||||
{{$class = (printf "%s%s" $class " isWarning")}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{if $.Reponame}}
|
||||
<a href="{{AppSubUrl}}/{{$.Username}}/{{$.Reponame}}/commit/{{.ID}}" rel="nofollow" class="{{$class}}">
|
||||
{{else}}
|
||||
<span class="{{$class}}">
|
||||
{{end}}
|
||||
{{ShortSha .ID.String}}
|
||||
{{if .Signature}}
|
||||
<div class="ui detail icon button">
|
||||
{{if .Verification.Verified}}
|
||||
<i title="{{.Verification.Reason}}" class="lock green icon"></i>
|
||||
{{if ne .Verification.SigningUser.ID 0}}
|
||||
<i title="{{.Verification.Reason}}" class="lock green icon"></i>
|
||||
{{else}}
|
||||
<i title="{{.Verification.Reason}}" class="icons">
|
||||
<i class="green lock icon"></i>
|
||||
<i class="tiny inverted cog icon centerlock"></i>
|
||||
</i>
|
||||
{{end}}
|
||||
<i title="{{.Verification.Reason}}" class="lock green icon"></i>
|
||||
{{else}}
|
||||
<i title="{{.Verification.Reason}}" class="icons">
|
||||
<i class="green lock icon"></i>
|
||||
<i class="tiny inverted cog icon centerlock"></i>
|
||||
</i>
|
||||
{{end}}
|
||||
{{else if .Verification.Warning}}
|
||||
<i title="{{$.i18n.Tr .Verification.Reason}}" class="red unlock icon"></i>
|
||||
{{else}}
|
||||
<i title="{{$.i18n.Tr .Verification.Reason}}" class="red unlock icon"></i>
|
||||
{{else}}
|
||||
<i title="{{$.i18n.Tr .Verification.Reason}}" class="unlock icon"></i>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $.Reponame}}
|
||||
</a>
|
||||
{{else}}
|
||||
</span>
|
||||
{{end}}
|
||||
{{if $.Reponame}}
|
||||
</a>
|
||||
{{else}}
|
||||
</span>
|
||||
{{end}}
|
||||
</td>
|
||||
<td class="message">
|
||||
<span class="message-wrapper">
|
||||
|
@ -73,7 +72,7 @@
|
|||
<button class="basic compact mini ui icon button commit-button"><i class="ellipsis horizontal icon"></i></button>
|
||||
{{end}}
|
||||
{{if eq (CommitType .) "SignCommitWithStatuses"}}
|
||||
{{template "repo/commit_status" .Status}}
|
||||
{{template "repo/commit_status" .Status}}
|
||||
{{end}}
|
||||
{{if IsMultilineCommitMessage .Message}}
|
||||
<pre class="commit-body" style="display: none;">{{RenderCommitBody .Message $.RepoLink $.Repository.ComposeMetas}}</pre>
|
||||
|
|
|
@ -3,7 +3,12 @@
|
|||
<i class="dropdown icon"></i>
|
||||
<div class="menu">
|
||||
<a class="item tiny basic toggle button" data-target="#diff-files">{{.i18n.Tr "repo.diff.show_diff_stats"}}</a>
|
||||
<a class="item" href="{{$.RepoLink}}/pulls/{{.Issue.Index}}.patch" download="{{.Issue.Index}}.patch">{{.i18n.Tr "repo.diff.download_patch"}}</a>
|
||||
<a class="item" href="{{$.RepoLink}}/pulls/{{.Issue.Index}}.diff" download="{{.Issue.Index}}.diff">{{.i18n.Tr "repo.diff.download_diff"}}</a>
|
||||
{{if .Issue.Index}}
|
||||
<a class="item" href="{{$.RepoLink}}/pulls/{{.Issue.Index}}.patch" download="{{.Issue.Index}}.patch">{{.i18n.Tr "repo.diff.download_patch"}}</a>
|
||||
<a class="item" href="{{$.RepoLink}}/pulls/{{.Issue.Index}}.diff" download="{{.Issue.Index}}.diff">{{.i18n.Tr "repo.diff.download_diff"}}</a>
|
||||
{{else if .Commit.ID.String}}
|
||||
<a class="item" href="{{$.RepoLink}}/commit/{{.Commit.ID.String}}.patch" download="{{ShortSha .Commit.ID.String}}.patch">{{.i18n.Tr "repo.diff.download_patch"}}</a>
|
||||
<a class="item" href="{{$.RepoLink}}/commit/{{.Commit.ID.String}}.diff" download="{{ShortSha .Commit.ID.String}}.diff">{{.i18n.Tr "repo.diff.download_diff"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -132,7 +132,7 @@
|
|||
{{range $.branch_status_check_contexts}}
|
||||
<tr><td>
|
||||
<span class="ui checkbox">
|
||||
<input class="enable-whitelist" name="status_check_contexts" value="{{.}}" type="checkbox" {{if $.is_context_require}}{{if call $.is_context_required .}}checked{{end}}{{end}}>
|
||||
<input class="enable-whitelist" name="status_check_contexts" value="{{.}}" type="checkbox" {{if $.is_context_required}}{{if call $.is_context_required .}}checked{{end}}{{end}}>
|
||||
</span>
|
||||
{{.}}
|
||||
{{if $.is_context_required}}{{if call $.is_context_required .}}<div class="ui label right">Required</div>{{end}}{{end}}
|
||||
|
|
|
@ -4715,7 +4715,7 @@
|
|||
"tags": [
|
||||
"repository"
|
||||
],
|
||||
"summary": "Update a pull request",
|
||||
"summary": "Update a pull request. If using deadline only the date will be taken into account, and time of day ignored.",
|
||||
"operationId": "repoEditPullRequest",
|
||||
"parameters": [
|
||||
{
|
||||
|
@ -8532,6 +8532,10 @@
|
|||
"title": {
|
||||
"type": "string",
|
||||
"x-go-name": "Title"
|
||||
},
|
||||
"unset_due_date": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "RemoveDeadline"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
|
@ -8660,6 +8664,10 @@
|
|||
"title": {
|
||||
"type": "string",
|
||||
"x-go-name": "Title"
|
||||
},
|
||||
"unset_due_date": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "RemoveDeadline"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
|
|
4
vendor/github.com/niklasfasching/go-org/org/block.go
generated
vendored
4
vendor/github.com/niklasfasching/go-org/org/block.go
generated
vendored
|
@ -80,5 +80,5 @@ func trimIndentUpTo(max int) func(string) string {
|
|||
}
|
||||
}
|
||||
|
||||
func (n Example) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Block) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Example) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n Block) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
|
|
2
vendor/github.com/niklasfasching/go-org/org/document.go
generated
vendored
2
vendor/github.com/niklasfasching/go-org/org/document.go
generated
vendored
|
@ -90,7 +90,7 @@ func New() *Configuration {
|
|||
}
|
||||
|
||||
// String returns the pretty printed Org mode string for the given nodes (see OrgWriter).
|
||||
func String(nodes []Node) string { return orgWriter.nodesAsString(nodes...) }
|
||||
func String(nodes []Node) string { return orgWriter.WriteNodesAsString(nodes...) }
|
||||
|
||||
// Write is called after with an instance of the Writer interface to export a parsed Document into another format.
|
||||
func (d *Document) Write(w Writer) (out string, err error) {
|
||||
|
|
4
vendor/github.com/niklasfasching/go-org/org/drawer.go
generated
vendored
4
vendor/github.com/niklasfasching/go-org/org/drawer.go
generated
vendored
|
@ -93,5 +93,5 @@ func (d *PropertyDrawer) Get(key string) (string, bool) {
|
|||
return "", false
|
||||
}
|
||||
|
||||
func (n Drawer) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n PropertyDrawer) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Drawer) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n PropertyDrawer) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
|
|
2
vendor/github.com/niklasfasching/go-org/org/footnote.go
generated
vendored
2
vendor/github.com/niklasfasching/go-org/org/footnote.go
generated
vendored
|
@ -32,4 +32,4 @@ func (d *Document) parseFootnoteDefinition(i int, parentStop stopFn) (int, Node)
|
|||
return consumed, definition
|
||||
}
|
||||
|
||||
func (n FootnoteDefinition) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n FootnoteDefinition) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
|
|
2
vendor/github.com/niklasfasching/go-org/org/headline.go
generated
vendored
2
vendor/github.com/niklasfasching/go-org/org/headline.go
generated
vendored
|
@ -98,4 +98,4 @@ func (parent *Section) add(current *Section) {
|
|||
}
|
||||
}
|
||||
|
||||
func (n Headline) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Headline) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
|
|
39
vendor/github.com/niklasfasching/go-org/org/html_writer.go
generated
vendored
39
vendor/github.com/niklasfasching/go-org/org/html_writer.go
generated
vendored
|
@ -69,16 +69,13 @@ func NewHTMLWriter() *HTMLWriter {
|
|||
}
|
||||
}
|
||||
|
||||
func (w *HTMLWriter) emptyClone() *HTMLWriter {
|
||||
wcopy := *w
|
||||
wcopy.Builder = strings.Builder{}
|
||||
return &wcopy
|
||||
}
|
||||
|
||||
func (w *HTMLWriter) nodesAsString(nodes ...Node) string {
|
||||
tmp := w.emptyClone()
|
||||
WriteNodes(tmp, nodes...)
|
||||
return tmp.String()
|
||||
func (w *HTMLWriter) WriteNodesAsString(nodes ...Node) string {
|
||||
original := w.Builder
|
||||
w.Builder = strings.Builder{}
|
||||
WriteNodes(w, nodes...)
|
||||
out := w.String()
|
||||
w.Builder = original
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *HTMLWriter) WriterWithExtensions() Writer {
|
||||
|
@ -104,12 +101,14 @@ func (w *HTMLWriter) WritePropertyDrawer(PropertyDrawer) {}
|
|||
func (w *HTMLWriter) WriteBlock(b Block) {
|
||||
content := ""
|
||||
if isRawTextBlock(b.Name) {
|
||||
exportWriter := w.emptyClone()
|
||||
exportWriter.htmlEscape = false
|
||||
WriteNodes(exportWriter, b.Children...)
|
||||
content = strings.TrimRightFunc(exportWriter.String(), unicode.IsSpace)
|
||||
builder, htmlEscape := w.Builder, w.htmlEscape
|
||||
w.Builder, w.htmlEscape = strings.Builder{}, false
|
||||
WriteNodes(w, b.Children...)
|
||||
out := w.String()
|
||||
w.Builder, w.htmlEscape = builder, htmlEscape
|
||||
content = strings.TrimRightFunc(out, unicode.IsSpace)
|
||||
} else {
|
||||
content = w.nodesAsString(b.Children...)
|
||||
content = w.WriteNodesAsString(b.Children...)
|
||||
}
|
||||
switch name := b.Name; {
|
||||
case name == "SRC":
|
||||
|
@ -194,7 +193,7 @@ func (w *HTMLWriter) writeSection(section *Section) {
|
|||
// NOTE: To satisfy hugo ExtractTOC() check we cannot use `<li>\n` here. Doesn't really matter, just a note.
|
||||
w.WriteString("<li>")
|
||||
h := section.Headline
|
||||
title := cleanHeadlineTitleForHTMLAnchorRegexp.ReplaceAllString(w.nodesAsString(h.Title...), "")
|
||||
title := cleanHeadlineTitleForHTMLAnchorRegexp.ReplaceAllString(w.WriteNodesAsString(h.Title...), "")
|
||||
w.WriteString(fmt.Sprintf("<a href=\"#%s\">%s</a>\n", h.ID(), title))
|
||||
if len(section.Children) != 0 {
|
||||
w.WriteString("<ul>\n")
|
||||
|
@ -306,7 +305,7 @@ func (w *HTMLWriter) WriteRegularLink(l RegularLink) {
|
|||
}
|
||||
description := url
|
||||
if l.Description != nil {
|
||||
description = w.nodesAsString(l.Description...)
|
||||
description = w.WriteNodesAsString(l.Description...)
|
||||
}
|
||||
switch l.Kind() {
|
||||
case "image":
|
||||
|
@ -384,10 +383,10 @@ func (w *HTMLWriter) WriteHorizontalRule(h HorizontalRule) {
|
|||
}
|
||||
|
||||
func (w *HTMLWriter) WriteNodeWithMeta(n NodeWithMeta) {
|
||||
out := w.nodesAsString(n.Node)
|
||||
out := w.WriteNodesAsString(n.Node)
|
||||
if p, ok := n.Node.(Paragraph); ok {
|
||||
if len(p.Children) == 1 && isImageOrVideoLink(p.Children[0]) {
|
||||
out = w.nodesAsString(p.Children[0])
|
||||
out = w.WriteNodesAsString(p.Children[0])
|
||||
}
|
||||
}
|
||||
for _, attributes := range n.Meta.HTMLAttributes {
|
||||
|
@ -399,7 +398,7 @@ func (w *HTMLWriter) WriteNodeWithMeta(n NodeWithMeta) {
|
|||
if i != 0 {
|
||||
caption += " "
|
||||
}
|
||||
caption += w.nodesAsString(ns...)
|
||||
caption += w.WriteNodesAsString(ns...)
|
||||
}
|
||||
out = fmt.Sprintf("<figure>\n%s<figcaption>\n%s\n</figcaption>\n</figure>\n", out, caption)
|
||||
}
|
||||
|
|
22
vendor/github.com/niklasfasching/go-org/org/inline.go
generated
vendored
22
vendor/github.com/niklasfasching/go-org/org/inline.go
generated
vendored
|
@ -147,8 +147,8 @@ func (d *Document) parseExplicitLineBreakOrLatexFragment(input string, start int
|
|||
switch {
|
||||
case start+2 >= len(input):
|
||||
case input[start+1] == '\\' && start != 0 && input[start-1] != '\n':
|
||||
for i := start + 2; unicode.IsSpace(rune(input[i])); i++ {
|
||||
if i >= len(input) || input[i] == '\n' {
|
||||
for i := start + 2; i <= len(input)-1 && unicode.IsSpace(rune(input[i])); i++ {
|
||||
if input[i] == '\n' {
|
||||
return i + 1 - start, ExplicitLineBreak{}
|
||||
}
|
||||
}
|
||||
|
@ -346,12 +346,12 @@ func (l RegularLink) Kind() string {
|
|||
return "regular"
|
||||
}
|
||||
|
||||
func (n Text) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n LineBreak) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n ExplicitLineBreak) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n StatisticToken) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Emphasis) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n LatexFragment) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n FootnoteLink) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n RegularLink) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Timestamp) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Text) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n LineBreak) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n ExplicitLineBreak) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n StatisticToken) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n Emphasis) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n LatexFragment) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n FootnoteLink) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n RegularLink) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n Timestamp) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
|
|
10
vendor/github.com/niklasfasching/go-org/org/keyword.go
generated
vendored
10
vendor/github.com/niklasfasching/go-org/org/keyword.go
generated
vendored
|
@ -177,8 +177,8 @@ func (d *Document) loadSetupFile(k Keyword) (int, Node) {
|
|||
return 1, k
|
||||
}
|
||||
|
||||
func (n Comment) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Keyword) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n NodeWithMeta) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n NodeWithName) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Include) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Comment) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n Keyword) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n NodeWithMeta) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n NodeWithName) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n Include) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
|
|
6
vendor/github.com/niklasfasching/go-org/org/list.go
generated
vendored
6
vendor/github.com/niklasfasching/go-org/org/list.go
generated
vendored
|
@ -109,6 +109,6 @@ func (d *Document) parseListItem(l List, i int, parentStop stopFn) (int, Node) {
|
|||
return i - start, ListItem{bullet, status, nodes}
|
||||
}
|
||||
|
||||
func (n List) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n ListItem) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n DescriptiveListItem) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n List) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n ListItem) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n DescriptiveListItem) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
|
|
71
vendor/github.com/niklasfasching/go-org/org/org_writer.go
generated
vendored
71
vendor/github.com/niklasfasching/go-org/org/org_writer.go
generated
vendored
|
@ -43,39 +43,33 @@ func (w *OrgWriter) WriterWithExtensions() Writer {
|
|||
func (w *OrgWriter) Before(d *Document) {}
|
||||
func (w *OrgWriter) After(d *Document) {}
|
||||
|
||||
func (w *OrgWriter) emptyClone() *OrgWriter {
|
||||
wcopy := *w
|
||||
wcopy.Builder = strings.Builder{}
|
||||
return &wcopy
|
||||
}
|
||||
|
||||
func (w *OrgWriter) nodesAsString(nodes ...Node) string {
|
||||
tmp := w.emptyClone()
|
||||
WriteNodes(tmp, nodes...)
|
||||
return tmp.String()
|
||||
func (w *OrgWriter) WriteNodesAsString(nodes ...Node) string {
|
||||
builder := w.Builder
|
||||
w.Builder = strings.Builder{}
|
||||
WriteNodes(w, nodes...)
|
||||
out := w.String()
|
||||
w.Builder = builder
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *OrgWriter) WriteHeadline(h Headline) {
|
||||
tmp := w.emptyClone()
|
||||
tmp.WriteString(strings.Repeat("*", h.Lvl))
|
||||
start := w.Len()
|
||||
w.WriteString(strings.Repeat("*", h.Lvl))
|
||||
if h.Status != "" {
|
||||
tmp.WriteString(" " + h.Status)
|
||||
w.WriteString(" " + h.Status)
|
||||
}
|
||||
if h.Priority != "" {
|
||||
tmp.WriteString(" [#" + h.Priority + "]")
|
||||
w.WriteString(" [#" + h.Priority + "]")
|
||||
}
|
||||
tmp.WriteString(" ")
|
||||
WriteNodes(tmp, h.Title...)
|
||||
hString := tmp.String()
|
||||
w.WriteString(" ")
|
||||
WriteNodes(w, h.Title...)
|
||||
if len(h.Tags) != 0 {
|
||||
tString := ":" + strings.Join(h.Tags, ":") + ":"
|
||||
if n := w.TagsColumn - len(tString) - len(hString); n > 0 {
|
||||
w.WriteString(hString + strings.Repeat(" ", n) + tString)
|
||||
if n := w.TagsColumn - len(tString) - (w.Len() - start); n > 0 {
|
||||
w.WriteString(strings.Repeat(" ", n) + tString)
|
||||
} else {
|
||||
w.WriteString(hString + " " + tString)
|
||||
w.WriteString(" " + tString)
|
||||
}
|
||||
} else {
|
||||
w.WriteString(hString)
|
||||
}
|
||||
w.WriteString("\n")
|
||||
if len(h.Children) != 0 {
|
||||
|
@ -123,7 +117,7 @@ func (w *OrgWriter) WritePropertyDrawer(d PropertyDrawer) {
|
|||
|
||||
func (w *OrgWriter) WriteFootnoteDefinition(f FootnoteDefinition) {
|
||||
w.WriteString(fmt.Sprintf("[fn:%s]", f.Name))
|
||||
content := w.nodesAsString(f.Children...)
|
||||
content := w.WriteNodesAsString(f.Children...)
|
||||
if content != "" && !unicode.IsSpace(rune(content[0])) {
|
||||
w.WriteString(" ")
|
||||
}
|
||||
|
@ -131,7 +125,7 @@ func (w *OrgWriter) WriteFootnoteDefinition(f FootnoteDefinition) {
|
|||
}
|
||||
|
||||
func (w *OrgWriter) WriteParagraph(p Paragraph) {
|
||||
content := w.nodesAsString(p.Children...)
|
||||
content := w.WriteNodesAsString(p.Children...)
|
||||
if len(content) > 0 && content[0] != '\n' {
|
||||
w.WriteString(w.indent)
|
||||
}
|
||||
|
@ -141,7 +135,7 @@ func (w *OrgWriter) WriteParagraph(p Paragraph) {
|
|||
func (w *OrgWriter) WriteExample(e Example) {
|
||||
for _, n := range e.Children {
|
||||
w.WriteString(w.indent + ":")
|
||||
if content := w.nodesAsString(n); content != "" {
|
||||
if content := w.WriteNodesAsString(n); content != "" {
|
||||
w.WriteString(" " + content)
|
||||
}
|
||||
w.WriteString("\n")
|
||||
|
@ -185,10 +179,11 @@ func (w *OrgWriter) WriteComment(c Comment) {
|
|||
func (w *OrgWriter) WriteList(l List) { WriteNodes(w, l.Items...) }
|
||||
|
||||
func (w *OrgWriter) WriteListItem(li ListItem) {
|
||||
liWriter := w.emptyClone()
|
||||
liWriter.indent = w.indent + strings.Repeat(" ", len(li.Bullet)+1)
|
||||
WriteNodes(liWriter, li.Children...)
|
||||
content := strings.TrimPrefix(liWriter.String(), liWriter.indent)
|
||||
originalBuilder, originalIndent := w.Builder, w.indent
|
||||
w.Builder, w.indent = strings.Builder{}, w.indent+strings.Repeat(" ", len(li.Bullet)+1)
|
||||
WriteNodes(w, li.Children...)
|
||||
content := strings.TrimPrefix(w.String(), w.indent)
|
||||
w.Builder, w.indent = originalBuilder, originalIndent
|
||||
w.WriteString(w.indent + li.Bullet)
|
||||
if li.Status != "" {
|
||||
w.WriteString(fmt.Sprintf(" [%s]", li.Status))
|
||||
|
@ -207,14 +202,15 @@ func (w *OrgWriter) WriteDescriptiveListItem(di DescriptiveListItem) {
|
|||
}
|
||||
indent := w.indent + strings.Repeat(" ", len(di.Bullet)+1)
|
||||
if len(di.Term) != 0 {
|
||||
term := w.nodesAsString(di.Term...)
|
||||
term := w.WriteNodesAsString(di.Term...)
|
||||
w.WriteString(" " + term + " ::")
|
||||
indent = indent + strings.Repeat(" ", len(term)+4)
|
||||
}
|
||||
diWriter := w.emptyClone()
|
||||
diWriter.indent = indent
|
||||
WriteNodes(diWriter, di.Details...)
|
||||
details := strings.TrimPrefix(diWriter.String(), diWriter.indent)
|
||||
originalBuilder, originalIndent := w.Builder, w.indent
|
||||
w.Builder, w.indent = strings.Builder{}, indent
|
||||
WriteNodes(w, di.Details...)
|
||||
details := strings.TrimPrefix(w.String(), w.indent)
|
||||
w.Builder, w.indent = originalBuilder, originalIndent
|
||||
if len(details) > 0 && details[0] == '\n' {
|
||||
w.WriteString(details)
|
||||
} else {
|
||||
|
@ -239,7 +235,7 @@ func (w *OrgWriter) WriteTable(t Table) {
|
|||
w.WriteString(`|`)
|
||||
for _, column := range row.Columns {
|
||||
w.WriteString(` `)
|
||||
content := w.nodesAsString(column.Children...)
|
||||
content := w.WriteNodesAsString(column.Children...)
|
||||
if content == "" {
|
||||
content = " "
|
||||
}
|
||||
|
@ -326,9 +322,6 @@ func (w *OrgWriter) WriteRegularLink(l RegularLink) {
|
|||
} else if l.Description == nil {
|
||||
w.WriteString(fmt.Sprintf("[[%s]]", l.URL))
|
||||
} else {
|
||||
descriptionWriter := w.emptyClone()
|
||||
WriteNodes(descriptionWriter, l.Description...)
|
||||
description := descriptionWriter.String()
|
||||
w.WriteString(fmt.Sprintf("[[%s][%s]]", l.URL, description))
|
||||
w.WriteString(fmt.Sprintf("[[%s][%s]]", l.URL, w.WriteNodesAsString(l.Description...)))
|
||||
}
|
||||
}
|
||||
|
|
4
vendor/github.com/niklasfasching/go-org/org/paragraph.go
generated
vendored
4
vendor/github.com/niklasfasching/go-org/org/paragraph.go
generated
vendored
|
@ -42,5 +42,5 @@ func (d *Document) parseHorizontalRule(i int, parentStop stopFn) (int, Node) {
|
|||
return 1, HorizontalRule{}
|
||||
}
|
||||
|
||||
func (n Paragraph) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n HorizontalRule) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Paragraph) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
func (n HorizontalRule) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
|
|
2
vendor/github.com/niklasfasching/go-org/org/table.go
generated
vendored
2
vendor/github.com/niklasfasching/go-org/org/table.go
generated
vendored
|
@ -127,4 +127,4 @@ func isSpecialRow(rawColumns []string) bool {
|
|||
return isAlignRow
|
||||
}
|
||||
|
||||
func (n Table) String() string { return orgWriter.nodesAsString(n) }
|
||||
func (n Table) String() string { return orgWriter.WriteNodesAsString(n) }
|
||||
|
|
1
vendor/github.com/niklasfasching/go-org/org/writer.go
generated
vendored
1
vendor/github.com/niklasfasching/go-org/org/writer.go
generated
vendored
|
@ -9,6 +9,7 @@ type Writer interface {
|
|||
String() string // String is called at the very end to retrieve the final output.
|
||||
|
||||
WriterWithExtensions() Writer
|
||||
WriteNodesAsString(...Node) string
|
||||
|
||||
WriteKeyword(Keyword)
|
||||
WriteInclude(Include)
|
||||
|
|
2
vendor/golang.org/x/net/idna/tables11.0.0.go
generated
vendored
2
vendor/golang.org/x/net/idna/tables11.0.0.go
generated
vendored
|
@ -1,6 +1,6 @@
|
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// +build go1.13
|
||||
// +build go1.13,!go1.14
|
||||
|
||||
package idna
|
||||
|
||||
|
|
4733
vendor/golang.org/x/net/idna/tables12.00.go
generated
vendored
Normal file
4733
vendor/golang.org/x/net/idna/tables12.00.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
|
@ -330,7 +330,7 @@ github.com/mschoch/smat
|
|||
github.com/msteinert/pam
|
||||
# github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5
|
||||
github.com/nfnt/resize
|
||||
# github.com/niklasfasching/go-org v0.1.7
|
||||
# github.com/niklasfasching/go-org v0.1.8
|
||||
github.com/niklasfasching/go-org/org
|
||||
# github.com/oliamb/cutter v0.2.2
|
||||
github.com/oliamb/cutter
|
||||
|
@ -464,7 +464,7 @@ golang.org/x/crypto/scrypt
|
|||
golang.org/x/crypto/ssh
|
||||
golang.org/x/crypto/ssh/agent
|
||||
golang.org/x/crypto/ssh/knownhosts
|
||||
# golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271
|
||||
# golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9
|
||||
golang.org/x/net/context
|
||||
golang.org/x/net/context/ctxhttp
|
||||
golang.org/x/net/html
|
||||
|
|
Loading…
Reference in a new issue