| @@ -243,6 +243,11 @@ func runWeb(*cli.Context) { | |||
| r.Post("/:authid", bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost) | |||
| r.Post("/:authid/delete", admin.DeleteAuthSource) | |||
| }) | |||
| m.Group("/notices", func(r *macaron.Router) { | |||
| r.Get("", admin.Notices) | |||
| r.Get("/:id:int/delete", admin.DeleteNotice) | |||
| }) | |||
| }, adminReq) | |||
| m.Get("/:username", ignSignIn, user.Profile) | |||
| @@ -416,6 +416,7 @@ organizations = Organizations | |||
| repositories = Repositories | |||
| authentication = Authentications | |||
| config = Configuration | |||
| notices = System Notices | |||
| monitor = Monitoring | |||
| prev = Prev. | |||
| next = Next | |||
| @@ -593,6 +594,13 @@ monitor.desc = Description | |||
| monitor.start = Start Time | |||
| monitor.execute_time = Execution Time | |||
| notices.system_notice_list = System Notices | |||
| notices.type = Type | |||
| notices.type_1 = Repository | |||
| notices.desc = Description | |||
| notices.op = Op. | |||
| notices.delete_success = System notice has been successfully deleted. | |||
| [action] | |||
| create_repo = created repository <a href="%s/%s">%s</a> | |||
| commit_repo = pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a> | |||
| @@ -416,6 +416,7 @@ organizations = 组织管理 | |||
| repositories = 仓库管理 | |||
| authentication = 授权认证管理 | |||
| config = 应用配置管理 | |||
| notices = 系统提示管理 | |||
| monitor = 应用监控面板 | |||
| prev = 上一页 | |||
| next = 下一页 | |||
| @@ -593,6 +594,13 @@ monitor.desc = 进程描述 | |||
| monitor.start = 开始时间 | |||
| monitor.execute_time = 已执行时间 | |||
| notices.system_notice_list = 系统提示管理 | |||
| notices.type = 提示类型 | |||
| notices.type_1 = 仓库 | |||
| notices.desc = 描述 | |||
| notices.op = 操作 | |||
| notices.delete_success = 系统提示删除成功! | |||
| [action] | |||
| create_repo = 创建了仓库 <a href="%s/%s">%s</a> | |||
| commit_repo = 推送了 <a href="%s/%s/src/%s">%s</a> 分支的代码到 <a href="%s/%s">%s</a> | |||
| @@ -17,7 +17,7 @@ import ( | |||
| "github.com/gogits/gogs/modules/setting" | |||
| ) | |||
| const APP_VER = "0.5.5.1007 Beta" | |||
| const APP_VER = "0.5.5.1008 Beta" | |||
| func init() { | |||
| runtime.GOMAXPROCS(runtime.NumCPU()) | |||
| @@ -0,0 +1,64 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package models | |||
| import ( | |||
| "time" | |||
| "github.com/Unknwon/com" | |||
| ) | |||
| type NoticeType int | |||
| const ( | |||
| NOTICE_REPOSITORY NoticeType = iota + 1 | |||
| ) | |||
| // Notice represents a system notice for admin. | |||
| type Notice struct { | |||
| Id int64 | |||
| Type NoticeType | |||
| Description string `xorm:"TEXT"` | |||
| Created time.Time `xorm:"CREATED"` | |||
| } | |||
| // TrStr returns a translation format string. | |||
| func (n *Notice) TrStr() string { | |||
| return "admin.notices.type_" + com.ToStr(n.Type) | |||
| } | |||
| // CreateNotice creates new system notice. | |||
| func CreateNotice(tp NoticeType, desc string) error { | |||
| n := &Notice{ | |||
| Type: tp, | |||
| Description: desc, | |||
| } | |||
| _, err := x.Insert(n) | |||
| return err | |||
| } | |||
| // CreateRepositoryNotice creates new system notice with type NOTICE_REPOSITORY. | |||
| func CreateRepositoryNotice(desc string) error { | |||
| return CreateNotice(NOTICE_REPOSITORY, desc) | |||
| } | |||
| // CountNotices returns number of notices. | |||
| func CountNotices() int64 { | |||
| count, _ := x.Count(new(Notice)) | |||
| return count | |||
| } | |||
| // GetNotices returns given number of notices with offset. | |||
| func GetNotices(num, offset int) ([]*Notice, error) { | |||
| notices := make([]*Notice, 0, num) | |||
| err := x.Limit(num, offset).Desc("id").Find(¬ices) | |||
| return notices, err | |||
| } | |||
| // DeleteNotice deletes a system notice by given ID. | |||
| func DeleteNotice(id int64) error { | |||
| _, err := x.Id(id).Delete(new(Notice)) | |||
| return err | |||
| } | |||
| @@ -32,12 +32,12 @@ var ( | |||
| ) | |||
| func init() { | |||
| tables = append(tables, new(User), new(PublicKey), | |||
| tables = append(tables, new(User), new(PublicKey), new(Follow), new(Oauth2), | |||
| new(Repository), new(Watch), new(Star), new(Action), new(Access), | |||
| new(Issue), new(Comment), new(Oauth2), new(Follow), | |||
| new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser), | |||
| new(Milestone), new(Label), new(HookTask), new(Team), new(OrgUser), new(TeamUser), | |||
| new(UpdateTask), new(Attachment)) | |||
| new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone), | |||
| new(Mirror), new(Release), new(LoginSource), new(Webhook), | |||
| new(UpdateTask), new(HookTask), new(Team), new(OrgUser), new(TeamUser), | |||
| new(Notice)) | |||
| } | |||
| func LoadModelsConfig() { | |||
| @@ -934,9 +934,14 @@ func DeleteRepository(uid, repoId int64, userName string) error { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| // Remove repository files. | |||
| if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| desc := fmt.Sprintf("Fail to delete repository files(%s/%s): %v", userName, repo.Name, err) | |||
| log.Warn(desc) | |||
| if err = CreateRepositoryNotice(desc); err != nil { | |||
| log.Error(4, "Fail to add notice: %v", err) | |||
| } | |||
| } | |||
| return sess.Commit() | |||
| } | |||
| @@ -0,0 +1,46 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package admin | |||
| import ( | |||
| "github.com/Unknwon/com" | |||
| "github.com/gogits/gogs/models" | |||
| "github.com/gogits/gogs/modules/base" | |||
| "github.com/gogits/gogs/modules/log" | |||
| "github.com/gogits/gogs/modules/middleware" | |||
| ) | |||
| const ( | |||
| NOTICES base.TplName = "admin/notice" | |||
| ) | |||
| func Notices(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = ctx.Tr("admin.notices") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminNotices"] = true | |||
| pageNum := 50 | |||
| p := pagination(ctx, models.CountNotices(), pageNum) | |||
| notices, err := models.GetNotices(pageNum, (p-1)*pageNum) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetNotices", err) | |||
| return | |||
| } | |||
| ctx.Data["Notices"] = notices | |||
| ctx.HTML(200, NOTICES) | |||
| } | |||
| func DeleteNotice(ctx *middleware.Context) { | |||
| id := com.StrTo(ctx.Params(":id")).MustInt64() | |||
| if err := models.DeleteNotice(id); err != nil { | |||
| ctx.Handle(500, "DeleteNotice", err) | |||
| return | |||
| } | |||
| log.Trace("System notice deleted by admin(%s): %d", ctx.User.Name, id) | |||
| ctx.Flash.Success(ctx.Tr("admin.notices.delete_success")) | |||
| ctx.Redirect("/admin/notices") | |||
| } | |||
| @@ -48,12 +48,12 @@ func Users(ctx *middleware.Context) { | |||
| pageNum := 50 | |||
| p := pagination(ctx, models.CountUsers(), pageNum) | |||
| var err error | |||
| ctx.Data["Users"], err = models.GetUsers(pageNum, (p-1)*pageNum) | |||
| users, err := models.GetUsers(pageNum, (p-1)*pageNum) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetUsers", err) | |||
| return | |||
| } | |||
| ctx.Data["Users"] = users | |||
| ctx.HTML(200, USERS) | |||
| } | |||
| @@ -1 +1 @@ | |||
| 0.5.5.1007 Beta | |||
| 0.5.5.1008 Beta | |||
| @@ -8,6 +8,7 @@ | |||
| <li {{if .PageIsAdminRepositories}}class="current"{{end}}><a href="{{AppSubUrl}}/admin/repos">{{.i18n.Tr "admin.repositories"}}</a></li> | |||
| <li {{if .PageIsAdminAuthentications}}class="current"{{end}}><a href="{{AppSubUrl}}/admin/auths">{{.i18n.Tr "admin.authentication"}}</a></li> | |||
| <li {{if .PageIsAdminConfig}}class="current"{{end}}><a href="{{AppSubUrl}}/admin/config">{{.i18n.Tr "admin.config"}}</a></li> | |||
| <li {{if .PageIsAdminNotices}}class="current"{{end}}><a href="{{AppSubUrl}}/admin/notices">{{.i18n.Tr "admin.notices"}}</a></li> | |||
| <li {{if .PageIsAdminMonitor}}class="current"{{end}}><a href="{{AppSubUrl}}/admin/monitor">{{.i18n.Tr "admin.monitor"}}</a></li> | |||
| </ul> | |||
| </div> | |||
| @@ -0,0 +1,54 @@ | |||
| {{template "ng/base/head" .}} | |||
| {{template "ng/base/header" .}} | |||
| <div id="admin-wrapper"> | |||
| <div id="setting-wrapper" class="main-wrapper"> | |||
| <div id="admin-setting" class="container clear"> | |||
| {{template "admin/nav" .}} | |||
| <div class="grid-4-5 left"> | |||
| <div class="setting-content"> | |||
| {{template "ng/base/alert" .}} | |||
| <div id="setting-content"> | |||
| <div class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "admin.notices.system_notice_list"}}</strong> | |||
| </div> | |||
| <div class="panel-body admin-panel"> | |||
| <div class="admin-table"> | |||
| <table class="table table-striped"> | |||
| <thead> | |||
| <tr> | |||
| <th>Id</th> | |||
| <th>{{.i18n.Tr "admin.notices.type"}}</th> | |||
| <th>{{.i18n.Tr "admin.notices.desc"}}</th> | |||
| <th>{{.i18n.Tr "admin.users.created"}}</th> | |||
| <th>{{.i18n.Tr "admin.notices.op"}}</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| {{range .Notices}} | |||
| <tr> | |||
| <td>{{.Id}}</td> | |||
| <td>{{$.i18n.Tr .TrStr}}</td> | |||
| <td class="grid-1-2"><span>{{.Description}}</span></td> | |||
| <td>{{.Created}}</td> | |||
| <td><a href="{{AppSubUrl}}/admin/notices/{{.Id}}/delete"><i class="fa fa-trash-o text-red"></i></a></td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| </table> | |||
| {{if or .LastPageNum .NextPageNum}} | |||
| <ul class="pagination"> | |||
| {{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.LastPageNum}}">« {{.i18n.Tr "admin.prev"}}</a></li>{{end}} | |||
| {{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.NextPageNum}}">» {{.i18n.Tr "admin.next"}}</a></li>{{end}} | |||
| </ul> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "ng/base/footer" .}} | |||