Add Size column to attachment (#3734)

* Add size column to attachment
Migrate attachments by calculating file sizes

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Calculate attachment size on creation

Signed-off-by: Jonas Franz <info@jonasfranz.software>

* Log error instead of returning error

Signed-off-by: Jonas Franz <info@jonasfranz.software>
release/v1.15
Jonas Franz 2018-03-31 03:10:44 +02:00 committed by Bo-Yi Wu
parent d877bf7e15
commit 3e06490d38
4 changed files with 57 additions and 23 deletions

View File

@ -11,7 +11,6 @@ import (
"os" "os"
"path" "path"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
api "code.gitea.io/sdk/gitea" api "code.gitea.io/sdk/gitea"
@ -29,6 +28,7 @@ type Attachment struct {
CommentID int64 CommentID int64
Name string Name string
DownloadCount int64 `xorm:"DEFAULT 0"` DownloadCount int64 `xorm:"DEFAULT 0"`
Size int64 `xorm:"DEFAULT 0"`
CreatedUnix util.TimeStamp `xorm:"created"` CreatedUnix util.TimeStamp `xorm:"created"`
} }
@ -44,13 +44,12 @@ func (a *Attachment) IncreaseDownloadCount() error {
// APIFormat converts models.Attachment to api.Attachment // APIFormat converts models.Attachment to api.Attachment
func (a *Attachment) APIFormat() *api.Attachment { func (a *Attachment) APIFormat() *api.Attachment {
size, _ := a.Size()
return &api.Attachment{ return &api.Attachment{
ID: a.ID, ID: a.ID,
Name: a.Name, Name: a.Name,
Created: a.CreatedUnix.AsTime(), Created: a.CreatedUnix.AsTime(),
DownloadCount: a.DownloadCount, DownloadCount: a.DownloadCount,
Size: size, Size: a.Size,
UUID: a.UUID, UUID: a.UUID,
DownloadURL: a.DownloadURL(), DownloadURL: a.DownloadURL(),
} }
@ -67,25 +66,6 @@ func (a *Attachment) LocalPath() string {
return AttachmentLocalPath(a.UUID) return AttachmentLocalPath(a.UUID)
} }
// Size returns the file's size of the attachment
func (a *Attachment) Size() (int64, error) {
fi, err := os.Stat(a.LocalPath())
if err != nil {
return 0, err
}
return fi.Size(), nil
}
// MustSize returns the result of a.Size() by ignoring errors
func (a *Attachment) MustSize() int64 {
size, err := a.Size()
if err != nil {
log.Error(4, "size: %v", err)
return 0
}
return size
}
// DownloadURL returns the download url of the attached file // DownloadURL returns the download url of the attached file
func (a *Attachment) DownloadURL() string { func (a *Attachment) DownloadURL() string {
return fmt.Sprintf("%sattachments/%s", setting.AppURL, a.UUID) return fmt.Sprintf("%sattachments/%s", setting.AppURL, a.UUID)
@ -115,6 +95,13 @@ func NewAttachment(name string, buf []byte, file multipart.File) (_ *Attachment,
return nil, fmt.Errorf("Copy: %v", err) return nil, fmt.Errorf("Copy: %v", err)
} }
// Update file size
var fi os.FileInfo
if fi, err = fw.Stat(); err != nil {
return nil, fmt.Errorf("file size: %v", err)
}
attach.Size = fi.Size()
if _, err := x.Insert(attach); err != nil { if _, err := x.Insert(attach); err != nil {
return nil, err return nil, err
} }

View File

@ -174,6 +174,8 @@ var migrations = []Migration{
NewMigration("add merge whitelist for protected branches", addProtectedBranchMergeWhitelist), NewMigration("add merge whitelist for protected branches", addProtectedBranchMergeWhitelist),
// v60 -> v61 // v60 -> v61
NewMigration("add is_fsck_enabled column for repos", addFsckEnabledToRepo), NewMigration("add is_fsck_enabled column for repos", addFsckEnabledToRepo),
// v61 -> v62
NewMigration("add size column for attachments", addSizeToAttachment),
} }
// Migrate database to current version // Migrate database to current version

45
models/migrations/v61.go Normal file
View File

@ -0,0 +1,45 @@
// Copyright 2018 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 migrations
import (
"fmt"
"os"
"path"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/go-xorm/xorm"
)
func addSizeToAttachment(x *xorm.Engine) error {
type Attachment struct {
ID int64 `xorm:"pk autoincr"`
UUID string `xorm:"uuid UNIQUE"`
Size int64 `xorm:"DEFAULT 0"`
}
if err := x.Sync2(new(Attachment)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
attachments := make([]Attachment, 0, 100)
if err := x.Find(&attachments); err != nil {
return fmt.Errorf("query attachments: %v", err)
}
for _, attach := range attachments {
localPath := path.Join(setting.AttachmentPath, attach.UUID[0:1], attach.UUID[1:2], attach.UUID)
fi, err := os.Stat(localPath)
if err != nil {
log.Error(4, "calculate file size of attachment[UUID: %s]: %v", attach.UUID, err)
continue
}
attach.Size = fi.Size()
if _, err := x.ID(attach.ID).Cols("size").Update(attach); err != nil {
return fmt.Errorf("update size column: %v", err)
}
}
return nil
}

View File

@ -79,7 +79,7 @@
<li> <li>
<a target="_blank" rel="noopener" href="{{AppSubUrl}}/attachments/{{.UUID}}"> <a target="_blank" rel="noopener" href="{{AppSubUrl}}/attachments/{{.UUID}}">
<strong><span class="ui image octicon octicon-package" title='{{.Name}}'></span> {{.Name}}</strong> <strong><span class="ui image octicon octicon-package" title='{{.Name}}'></span> {{.Name}}</strong>
<span class="ui text grey right">{{.MustSize | FileSize}}</span> <span class="ui text grey right">{{.Size | FileSize}}</span>
</a> </a>
</li> </li>
{{end}} {{end}}