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.
This commit is contained in:
Aleksandar Jankovic 2019-07-26 09:51:51 +02:00 committed by Nick Craig-Wood
parent ff235e4e56
commit 4ba6532915
2 changed files with 23 additions and 6 deletions

View File

@ -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

View File

@ -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