This commit is contained in:
@@ -71,7 +71,12 @@ func (s *CharacterService) Create(ctx context.Context, nick, name, shortName, au
|
||||
}
|
||||
|
||||
if name == "" {
|
||||
return nil, errors.New("Name cannot be empty")
|
||||
return nil, errors.New("name cannot be empty")
|
||||
}
|
||||
|
||||
// Insert nick into existing if character already exists.
|
||||
if character, err := s.characters.FindName(ctx, name); err == nil && character.Name == name {
|
||||
return s.AddNick(ctx, character.ID, nick)
|
||||
}
|
||||
|
||||
if author == "" {
|
||||
|
||||
+45
-5
@@ -3,10 +3,15 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"git.aiterp.net/rpdata/api/internal/generate"
|
||||
"git.aiterp.net/rpdata/api/models"
|
||||
"git.aiterp.net/rpdata/api/models/changekeys"
|
||||
"git.aiterp.net/rpdata/api/repositories"
|
||||
"git.aiterp.net/rpdata/api/space"
|
||||
"github.com/h2non/filetype"
|
||||
"io"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
var ErrPrivateNoAuthor = errors.New("cannot search for private files without an author")
|
||||
@@ -18,8 +23,10 @@ var ErrCouldNotUploadFile = errors.New("could not upload file")
|
||||
|
||||
// FileService is a service for files.
|
||||
type FileService struct {
|
||||
files repositories.FileRepository
|
||||
authService *AuthService
|
||||
files repositories.FileRepository
|
||||
authService *AuthService
|
||||
changeService *ChangeService
|
||||
space *space.Client
|
||||
}
|
||||
|
||||
func (s *FileService) Find(ctx context.Context, id string) (*models.File, error) {
|
||||
@@ -56,13 +63,18 @@ func (s *FileService) List(ctx context.Context, filter models.FileFilter) ([]*mo
|
||||
return s.files.List(ctx, filter)
|
||||
}
|
||||
|
||||
func (s *FileService) Upload(ctx context.Context, reader io.Reader, name string, size int64) (*models.File, error) {
|
||||
func (s *FileService) Upload(ctx context.Context, reader io.Reader, name string, public bool, size int64) (*models.File, error) {
|
||||
if name == "" {
|
||||
return nil, ErrInvalidName
|
||||
} else if size < 320 || size > 16777216 {
|
||||
return nil, ErrInvalidFileSize
|
||||
}
|
||||
|
||||
token := s.authService.TokenFromContext(ctx)
|
||||
if token == nil || !token.Permitted("file.upload", "member") {
|
||||
return nil, ErrUnauthorized
|
||||
}
|
||||
|
||||
head := make([]byte, 320)
|
||||
n, err := reader.Read(head)
|
||||
if err != nil || n < 320 {
|
||||
@@ -74,7 +86,35 @@ func (s *FileService) Upload(ctx context.Context, reader io.Reader, name string,
|
||||
return nil, ErrInvalidFileType
|
||||
}
|
||||
|
||||
panic("implement rest of me")
|
||||
reader2 := &concatReader{head: head, body: reader}
|
||||
|
||||
path := generate.FileUploadID() + "." + fileType.Extension
|
||||
err = s.space.UploadFile(ctx, path, fileType.MIME.Value, reader2, size)
|
||||
if err != nil || !allowedMimeTypes[fileType.MIME.Value] {
|
||||
log.Println("File upload failed:", err)
|
||||
|
||||
return nil, ErrCouldNotUploadFile
|
||||
}
|
||||
|
||||
file := &models.File{
|
||||
Size: size,
|
||||
Name: name,
|
||||
URL: s.space.URLFromPath(path),
|
||||
Time: time.Now(),
|
||||
Author: token.UserID,
|
||||
Kind: "upload",
|
||||
MimeType: fileType.MIME.Value,
|
||||
Public: public,
|
||||
}
|
||||
|
||||
file, err = s.files.Insert(ctx, *file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.changeService.Submit(ctx, models.ChangeModelFile, "upload", file.Public, changekeys.Listed(file), file)
|
||||
|
||||
return file, nil
|
||||
}
|
||||
|
||||
func (s *FileService) Edit(ctx context.Context, id string, name *string, public *bool) (*models.File, error) {
|
||||
@@ -122,7 +162,7 @@ func (r *concatReader) Read(p []byte) (n int, err error) {
|
||||
r.headPos = len(r.head)
|
||||
copy(p, remainder)
|
||||
|
||||
return len(p), nil
|
||||
return len(remainder), nil
|
||||
}
|
||||
|
||||
return r.body.Read(p)
|
||||
|
||||
@@ -3,6 +3,7 @@ package services
|
||||
import (
|
||||
"git.aiterp.net/rpdata/api/database"
|
||||
"git.aiterp.net/rpdata/api/services/loaders"
|
||||
"git.aiterp.net/rpdata/api/space"
|
||||
)
|
||||
|
||||
// A Bundle contains all services.
|
||||
@@ -18,20 +19,22 @@ type Bundle struct {
|
||||
}
|
||||
|
||||
// NewBundle creates a new bundle.
|
||||
func NewBundle(db database.Database) *Bundle {
|
||||
func NewBundle(db database.Database, spaceClient *space.Client) *Bundle {
|
||||
bundle := &Bundle{}
|
||||
bundle.Auth = &AuthService{
|
||||
keys: db.Keys(),
|
||||
users: db.Users(),
|
||||
}
|
||||
bundle.Files = &FileService{
|
||||
files: nil,
|
||||
authService: bundle.Auth,
|
||||
}
|
||||
bundle.Changes = &ChangeService{
|
||||
changes: db.Changes(),
|
||||
authService: bundle.Auth,
|
||||
}
|
||||
bundle.Files = &FileService{
|
||||
files: db.Files(),
|
||||
authService: bundle.Auth,
|
||||
changeService: bundle.Changes,
|
||||
space: spaceClient,
|
||||
}
|
||||
bundle.Tags = &TagService{tags: db.Tags()}
|
||||
bundle.Characters = &CharacterService{
|
||||
characters: db.Characters(),
|
||||
|
||||
Reference in New Issue
Block a user