From 4ba65329159de3d6a4b7f1eae220b55bb61ad4a3 Mon Sep 17 00:00:00 2001 From: Aleksandar Jankovic Date: Fri, 26 Jul 2019 09:51:51 +0200 Subject: [PATCH] accounting: make stats response consistent core/stats can return two different schemas in 'transferring' field. One is object with fields the other is just plain string. This is confusing, unnecessary and makes defining response schema more difficult. It also returns `lastError` as value which can be rendered differently depending on source of error. This change standardizes 'transferring' filed to always return object but with reduced fields if they are not available. Former string item is converted to {name:remote_name} object. 'lastError' is forced to be a string as in some cases it can be encoded as an object. --- fs/accounting/accounting.go | 6 ++++-- fs/accounting/stats.go | 23 +++++++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/fs/accounting/accounting.go b/fs/accounting/accounting.go index 4d3c2af4a..7fa21a292 100644 --- a/fs/accounting/accounting.go +++ b/fs/accounting/accounting.go @@ -8,6 +8,8 @@ import ( "time" "unicode/utf8" + "github.com/ncw/rclone/fs/rc" + "github.com/ncw/rclone/fs" "github.com/ncw/rclone/fs/asyncreader" "github.com/ncw/rclone/fs/fserrors" @@ -318,8 +320,8 @@ func (acc *Account) String() string { } // RemoteStats produces stats for this file -func (acc *Account) RemoteStats() (out map[string]interface{}) { - out = make(map[string]interface{}) +func (acc *Account) RemoteStats() (out rc.Params) { + out = make(rc.Params) a, b := acc.progress() out["bytes"] = a out["size"] = b diff --git a/fs/accounting/stats.go b/fs/accounting/stats.go index a3747e7b9..9f4f07aad 100644 --- a/fs/accounting/stats.go +++ b/fs/accounting/stats.go @@ -76,24 +76,39 @@ func (s *StatsInfo) RemoteStats() (out rc.Params, err error) { out["checking"] = c } if !s.transferring.empty() { - var t []interface{} s.transferring.mu.RLock() - defer s.transferring.mu.RUnlock() + + var t []rc.Params for name := range s.transferring.items { if acc := s.inProgress.get(name); acc != nil { t = append(t, acc.RemoteStats()) } else { - t = append(t, name) + t = append(t, s.transferRemoteStats(name)) } } out["transferring"] = t + s.transferring.mu.RUnlock() } if s.errors > 0 { - out["lastError"] = s.lastError + out["lastError"] = s.lastError.Error() } return out, nil } +func (s *StatsInfo) transferRemoteStats(name string) rc.Params { + s.mu.RLock() + defer s.mu.RUnlock() + for _, tr := range s.startedTransfers { + if tr.remote == name { + return rc.Params{ + "name": name, + "size": tr.size, + } + } + } + return rc.Params{"name": name} +} + type timeRange struct { start time.Time end time.Time