package dataswamp import ( "caj-larsson/bog/dataswamp/namespace" "caj-larsson/bog/dataswamp/swampfile" "io" "path" "path/filepath" "strconv" "strings" "time" ) type SwampFileService struct { namespace_repo namespace.Repository swamp_file_repo swampfile.Repository default_allowance_bytes int64 default_allowance_duration time.Duration } func NewSwampFileService( namespace_repo namespace.Repository, swamp_file_repo swampfile.Repository, da_bytes int64, da_duration time.Duration, ) SwampFileService { return SwampFileService{namespace_repo, swamp_file_repo, da_bytes, da_duration} } func (s SwampFileService) getOrCreateNs(namespace_in string) *namespace.Namespace { ns, err := s.namespace_repo.GetByName(namespace_in) if err == namespace.ErrNotExists { new_ns := namespace.Namespace{ 0, namespace_in, time.Now(), s.default_allowance_duration, namespace.FileSizeQuota{s.default_allowance_bytes, 0}, } created_ns, err := s.namespace_repo.Create(new_ns) if err != nil { panic(err) } return created_ns } if err != nil { panic(err) } return ns } func (s SwampFileService) SaveFile(ref swampfile.FileReference, src io.Reader, size int64) error { ns := s.getOrCreateNs(ref.UserAgent) err := ref.Clean(true) if err != nil { return err } if !ns.FileQuota.Allows(size) { return namespace.ErrExceedQuota } f, err := s.swamp_file_repo.Create(ref.Path, strconv.FormatInt(ns.ID, 10)) if err != nil { return err } written, err := io.CopyN(f, src, size) if written < size { s.swamp_file_repo.Delete(ref.Path, strconv.FormatInt(ns.ID, 10)) return swampfile.ErrContentSizeExaggerated } var buf = make([]byte, 1) overread, err :=src.Read(buf) if overread > 0 || err != io.EOF { s.swamp_file_repo.Delete(ref.Path, strconv.FormatInt(ns.ID, 10)) return swampfile.ErrContentSizeExceeded } f.Close() ns.FileQuota.Add(size) s.namespace_repo.Update(ns.ID, *ns) return nil } func (s SwampFileService) OpenOutFile(ref swampfile.FileReference) (swampfile.SwampOutFile, error) { ns := s.getOrCreateNs(ref.UserAgent) err := ref.Clean(true) if err != nil { return nil, err } f, err := s.swamp_file_repo.Open(ref.Path, strconv.FormatInt(ns.ID, 10)) if err != nil { return nil, err } return f, nil } func CleanPath(inpath string) string { return filepath.FromSlash(path.Clean("/" + strings.Trim(inpath, "/"))) }