diff options
author | Philip Couling <couling@gmail.com> | 2017-01-20 06:58:46 +0000 |
---|---|---|
committer | Kim "BKC" Carlbäcker <kim.carlbacker@gmail.com> | 2017-01-20 07:58:46 +0100 |
commit | 1610b9f547982af08e771e979718ae9e84b573b6 (patch) | |
tree | a2881060065f2b0d3056ab7fd5a8ac2e9f372126 /models/attachment.go | |
parent | 74bbec3bf9f5e306248bf80808f93e116c232306 (diff) | |
download | gitea-1610b9f547982af08e771e979718ae9e84b573b6.tar.gz gitea-1610b9f547982af08e771e979718ae9e84b573b6.zip |
Spun attachments into seperate go file (#701)
Moved attachments into seperate go file
Diffstat (limited to 'models/attachment.go')
-rw-r--r-- | models/attachment.go | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/models/attachment.go b/models/attachment.go new file mode 100644 index 0000000000..149d9ea5bf --- /dev/null +++ b/models/attachment.go @@ -0,0 +1,176 @@ +// Copyright 2017 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 models + +import ( + "fmt" + "io" + "mime/multipart" + "os" + "path" + "time" + + "github.com/go-xorm/xorm" + gouuid "github.com/satori/go.uuid" + + "code.gitea.io/gitea/modules/setting" +) + +// Attachment represent a attachment of issue/comment/release. +type Attachment struct { + ID int64 `xorm:"pk autoincr"` + UUID string `xorm:"uuid UNIQUE"` + IssueID int64 `xorm:"INDEX"` + CommentID int64 + ReleaseID int64 `xorm:"INDEX"` + Name string + + Created time.Time `xorm:"-"` + CreatedUnix int64 +} + + +// BeforeInsert is invoked from XORM before inserting an object of this type. +func (a *Attachment) BeforeInsert() { + a.CreatedUnix = time.Now().Unix() +} + +// AfterSet is invoked from XORM after setting the value of a field of +// this object. +func (a *Attachment) AfterSet(colName string, _ xorm.Cell) { + switch colName { + case "created_unix": + a.Created = time.Unix(a.CreatedUnix, 0).Local() + } +} + +// AttachmentLocalPath returns where attachment is stored in local file +// system based on given UUID. +func AttachmentLocalPath(uuid string) string { + return path.Join(setting.AttachmentPath, uuid[0:1], uuid[1:2], uuid) +} + +// LocalPath returns where attachment is stored in local file system. +func (a *Attachment) LocalPath() string { + return AttachmentLocalPath(a.UUID) +} + +// NewAttachment creates a new attachment object. +func NewAttachment(name string, buf []byte, file multipart.File) (_ *Attachment, err error) { + attach := &Attachment{ + UUID: gouuid.NewV4().String(), + Name: name, + } + + localPath := attach.LocalPath() + if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil { + return nil, fmt.Errorf("MkdirAll: %v", err) + } + + fw, err := os.Create(localPath) + if err != nil { + return nil, fmt.Errorf("Create: %v", err) + } + defer fw.Close() + + if _, err = fw.Write(buf); err != nil { + return nil, fmt.Errorf("Write: %v", err) + } else if _, err = io.Copy(fw, file); err != nil { + return nil, fmt.Errorf("Copy: %v", err) + } + + if _, err := x.Insert(attach); err != nil { + return nil, err + } + + return attach, nil +} + +func getAttachmentByUUID(e Engine, uuid string) (*Attachment, error) { + attach := &Attachment{UUID: uuid} + has, err := x.Get(attach) + if err != nil { + return nil, err + } else if !has { + return nil, ErrAttachmentNotExist{0, uuid} + } + return attach, nil +} + +func getAttachmentsByUUIDs(e Engine, uuids []string) ([]*Attachment, error) { + if len(uuids) == 0 { + return []*Attachment{}, nil + } + + // Silently drop invalid uuids. + attachments := make([]*Attachment, 0, len(uuids)) + return attachments, e.In("uuid", uuids).Find(&attachments) +} + +// GetAttachmentByUUID returns attachment by given UUID. +func GetAttachmentByUUID(uuid string) (*Attachment, error) { + return getAttachmentByUUID(x, uuid) +} + +func getAttachmentsByIssueID(e Engine, issueID int64) ([]*Attachment, error) { + attachments := make([]*Attachment, 0, 10) + return attachments, e.Where("issue_id = ? AND comment_id = 0", issueID).Find(&attachments) +} + +// GetAttachmentsByIssueID returns all attachments of an issue. +func GetAttachmentsByIssueID(issueID int64) ([]*Attachment, error) { + return getAttachmentsByIssueID(x, issueID) +} + +// GetAttachmentsByCommentID returns all attachments if comment by given ID. +func GetAttachmentsByCommentID(commentID int64) ([]*Attachment, error) { + attachments := make([]*Attachment, 0, 10) + return attachments, x.Where("comment_id=?", commentID).Find(&attachments) +} + +// DeleteAttachment deletes the given attachment and optionally the associated file. +func DeleteAttachment(a *Attachment, remove bool) error { + _, err := DeleteAttachments([]*Attachment{a}, remove) + return err +} + +// DeleteAttachments deletes the given attachments and optionally the associated files. +func DeleteAttachments(attachments []*Attachment, remove bool) (int, error) { + for i, a := range attachments { + if remove { + if err := os.Remove(a.LocalPath()); err != nil { + return i, err + } + } + + if _, err := x.Delete(a); err != nil { + return i, err + } + } + + return len(attachments), nil +} + +// DeleteAttachmentsByIssue deletes all attachments associated with the given issue. +func DeleteAttachmentsByIssue(issueID int64, remove bool) (int, error) { + attachments, err := GetAttachmentsByIssueID(issueID) + + if err != nil { + return 0, err + } + + return DeleteAttachments(attachments, remove) +} + +// DeleteAttachmentsByComment deletes all attachments associated with the given comment. +func DeleteAttachmentsByComment(commentID int64, remove bool) (int, error) { + attachments, err := GetAttachmentsByCommentID(commentID) + + if err != nil { + return 0, err + } + + return DeleteAttachments(attachments, remove) +} |