Implemented saving a file
continuous-integration/drone/pr Build is failing Details

This commit is contained in:
kolaente 2019-10-09 22:22:01 +02:00
parent cecda676a6
commit 247a35b087
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
7 changed files with 92 additions and 23 deletions

View File

@ -80,6 +80,9 @@ func initialize() {
log.Fatal(err.Error())
}
// Initialize the files handler
files.InitFileHandler()
// Start the mail daemon
mail.StartMailDaemon()
}

View File

@ -85,6 +85,8 @@ const (
RateLimitPeriod Key = `ratelimit.period`
RateLimitLimit Key = `ratelimit.limit`
RateLimitStore Key = `ratelimit.store`
FilesBasePath Key = `files.basepath`
)
// GetString returns a string config value

30
pkg/files/filehandling.go Normal file
View File

@ -0,0 +1,30 @@
// Vikunja is a todo-list application to facilitate your life.
// Copyright 2019 Vikunja and contributors. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package files
import "github.com/spf13/afero"
// This file handling storing and retrieving a file for different backends
var fs afero.Fs
var afs *afero.Afero
// InitFileHandler creates a new file handler for the file backend we want to use
func InitFileHandler() {
fs = afero.NewOsFs()
afs = &afero.Afero{Fs: fs}
}

View File

@ -16,30 +16,58 @@
package files
import "time"
import (
"code.vikunja.io/api/pkg/config"
"mime/multipart"
"strconv"
"time"
)
type File struct {
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"`
Name string `xorm:"text not null" json:"name"`
Mime string `xorm:"text null" json:"mime"`
Size float64 `xorm:"double not null default 0" json:"size"`
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"`
Name string `xorm:"text not null" json:"name"`
Mime string `xorm:"text null" json:"mime"`
Size int64 `xorm:"int(11) not null default 0" json:"size"`
Created time.Time `xorm:"datetime" json:"created"`
Updated time.Time `xorm:"datetime" json:"updated"`
InsertedUnix int64 `xorm:"created" json:"inserted_unix"`
CreatedByID int64 `xorm:"int(11) not null" json:"-"`
File *multipart.FileHeader `xorm:"-" json:"-"`
}
func (File) TableName() string {
return "files"
}
func (f *File) GetFileFromID() (err error) {
func (f *File) GetFileByID() (err error) {
return
}
func (f *File) Save() (err error) {
func Create(f *multipart.FileHeader) (file *File, err error) {
// We first insert the file into the db to get it's ID
file = &File{
Name: f.Filename,
Size: f.Size,
}
_, err = x.Insert(file)
if err != nil {
return
}
// Open the actual file
ff, err := f.Open()
if err != nil {
return
}
defer ff.Close()
// Save the file to storage with its new ID as path
err = afs.WriteReader(config.FilesBasePath.GetString()+"/"+strconv.FormatInt(file.ID, 10), ff)
return
}

View File

@ -23,10 +23,10 @@ import (
)
type file20191008194238 struct {
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"`
Name string `xorm:"text not null" json:"name"`
Mime string `xorm:"text null" json:"mime"`
Size float64 `xorm:"double not null default 0" json:"size"`
ID int64 `xorm:"int(11) autoincr not null unique pk" json:"id"`
Name string `xorm:"text not null" json:"name"`
Mime string `xorm:"text null" json:"mime"`
Size int64 `xorm:"int(11) not null default 0" json:"size"`
Created time.Time `xorm:"datetime" json:"created"`
Updated time.Time `xorm:"datetime" json:"updated"`

View File

@ -17,6 +17,7 @@
package models
import (
"code.vikunja.io/api/pkg/files"
"code.vikunja.io/web"
"mime/multipart"
)
@ -30,20 +31,31 @@ type TaskAttachment struct {
CreatedByID int64 `xorm:"int(11) not null" json:"-"`
CreatedBy *User `xorm:"-" json:"created_by"`
File *multipart.File `xorm:"-" json:"-"`
File *multipart.FileHeader `xorm:"-" json:"-"`
Created int64 `xorm:"created"`
}
func (ta *TaskAttachment) Create(web.Auth) error {
func (ta *TaskAttachment) Create(a web.Auth) error {
// Store the file
file, err := files.Create(ta.File)
if err != nil {
return err
}
// Add an entry to the db
ta.FileID = file.ID
_, err = x.Insert(ta)
if err != nil {
// remove the uploaded file if adding it to the db fails
if err2 := file.Delete(); err2 != nil {
return err2
}
return err
}
// remove the uploaded file if adding it to the db fails
panic("implement me")
return nil
}
func (ta *TaskAttachment) ReadOne() error {

View File

@ -51,16 +51,10 @@ func UploadTaskAttachment(c echo.Context) error {
files := form.File["files"]
for _, file := range files {
src, err := file.Open()
if err != nil {
return echo.ErrInternalServerError
}
defer src.Close()
// We create a new attachment object here to have a clean start
ta := models.TaskAttachment{
TaskID: taskAttachment.TaskID,
File: &src,
File: file,
}
err = ta.Create(user)
if err != nil {