package dataswamp import ( "caj-larsson/bog/dataswamp/namespace" "caj-larsson/bog/dataswamp/swampfile" "io" "strconv" "time" // "errors" // "fmt" ) type SwampFileService struct { namespace_repo namespace.Repository swamp_file_repo swampfile.Repository default_allowance_bytes int64 default_allowance_duration time.Duration logger Logger } func NewSwampFileService( namespace_repo namespace.Repository, swamp_file_repo swampfile.Repository, da_bytes int64, da_duration time.Duration, logger Logger, ) SwampFileService { return SwampFileService{namespace_repo, swamp_file_repo, da_bytes, da_duration, logger} } 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}, namespace.Usage{0, 0, 0, 0, 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) ns.Usage = ns.Usage.Downloaded(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 (s SwampFileService) CleanUpExpiredFiles() error { s.logger.Info("Cleaning up expired files") nss, err := s.namespace_repo.All() if err != nil { return err } for _, ns := range nss { expiry := time.Now().Add(-ns.AllowanceDuration) dfs, err := s.swamp_file_repo.DeleteOlderThan(strconv.FormatInt(ns.ID, 10), expiry) for _, df := range dfs { ns.FileQuota.Remove(df.Size) } if err != nil { panic(err) } s.namespace_repo.Update(ns.ID, ns) } return nil }