lsjson: use exactly the correct number of decimal places in the seconds
This commit is contained in:
parent
da90069462
commit
2135879dda
3 changed files with 43 additions and 9 deletions
|
@ -60,7 +60,13 @@ If "remote:path" contains the file "subfolder/file.txt", the Path for "file.txt"
|
|||
will be "subfolder/file.txt", not "remote:path/subfolder/file.txt".
|
||||
When used without --recursive the Path will always be the same as Name.
|
||||
|
||||
The time is in RFC3339 format with nanosecond precision.
|
||||
The time is in RFC3339 format with up to nanosecond precision. The
|
||||
number of decimal digits in the seconds will depend on the precision
|
||||
that the remote can hold the times, so if times are accurate to the
|
||||
nearest millisecond (eg Google Drive) then 3 digits will always be
|
||||
shown ("2017-05-31T16:15:57.034+01:00") whereas if the times are
|
||||
accurate to the nearest second (Dropbox, Box, WebDav etc) no digits
|
||||
will be shown ("2017-05-31T16:15:57+01:00").
|
||||
|
||||
The whole output can be processed as a JSON blob, or alternatively it
|
||||
can be processed line by line as each item is written one to a line.
|
||||
|
|
|
@ -24,16 +24,43 @@ type ListJSONItem struct {
|
|||
OrigID string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// Timestamp a time in RFC3339 format with Nanosecond precision secongs
|
||||
type Timestamp time.Time
|
||||
// Timestamp a time in the provided format
|
||||
type Timestamp struct {
|
||||
When time.Time
|
||||
Format string
|
||||
}
|
||||
|
||||
// MarshalJSON turns a Timestamp into JSON
|
||||
func (t Timestamp) MarshalJSON() (out []byte, err error) {
|
||||
tt := time.Time(t)
|
||||
if tt.IsZero() {
|
||||
if t.When.IsZero() {
|
||||
return []byte(`""`), nil
|
||||
}
|
||||
return []byte(`"` + tt.Format(time.RFC3339Nano) + `"`), nil
|
||||
return []byte(`"` + t.When.Format(t.Format) + `"`), nil
|
||||
}
|
||||
|
||||
// Returns a time format for the given precision
|
||||
func formatForPrecision(precision time.Duration) string {
|
||||
switch {
|
||||
case precision <= time.Nanosecond:
|
||||
return "2006-01-02T15:04:05.000000000Z07:00"
|
||||
case precision <= 10*time.Nanosecond:
|
||||
return "2006-01-02T15:04:05.00000000Z07:00"
|
||||
case precision <= 100*time.Nanosecond:
|
||||
return "2006-01-02T15:04:05.0000000Z07:00"
|
||||
case precision <= time.Microsecond:
|
||||
return "2006-01-02T15:04:05.000000Z07:00"
|
||||
case precision <= 10*time.Microsecond:
|
||||
return "2006-01-02T15:04:05.00000Z07:00"
|
||||
case precision <= 100*time.Microsecond:
|
||||
return "2006-01-02T15:04:05.0000Z07:00"
|
||||
case precision <= time.Millisecond:
|
||||
return "2006-01-02T15:04:05.000Z07:00"
|
||||
case precision <= 10*time.Millisecond:
|
||||
return "2006-01-02T15:04:05.00Z07:00"
|
||||
case precision <= 100*time.Millisecond:
|
||||
return "2006-01-02T15:04:05.0Z07:00"
|
||||
}
|
||||
return time.RFC3339
|
||||
}
|
||||
|
||||
// ListJSONOpt describes the options for ListJSON
|
||||
|
@ -61,6 +88,7 @@ func ListJSON(fsrc fs.Fs, remote string, opt *ListJSONOpt, callback func(*ListJS
|
|||
return errors.Wrap(err, "ListJSON failed to make new crypt remote")
|
||||
}
|
||||
}
|
||||
format := formatForPrecision(fsrc.Precision())
|
||||
err := walk.Walk(fsrc, remote, false, ConfigMaxDepth(opt.Recurse), func(dirPath string, entries fs.DirEntries, err error) error {
|
||||
if err != nil {
|
||||
fs.CountError(err)
|
||||
|
@ -75,7 +103,7 @@ func ListJSON(fsrc fs.Fs, remote string, opt *ListJSONOpt, callback func(*ListJS
|
|||
MimeType: fs.MimeTypeDirEntry(entry),
|
||||
}
|
||||
if !opt.NoModTime {
|
||||
item.ModTime = Timestamp(entry.ModTime())
|
||||
item.ModTime = Timestamp{When: entry.ModTime(), Format: format}
|
||||
}
|
||||
if cipher != nil {
|
||||
switch entry.(type) {
|
||||
|
|
|
@ -175,7 +175,7 @@ func TestRcList(t *testing.T) {
|
|||
assert.Equal(t, 2, len(list))
|
||||
|
||||
checkFile1 := func(got *operations.ListJSONItem) {
|
||||
assert.WithinDuration(t, t1, time.Time(got.ModTime), time.Second)
|
||||
assert.WithinDuration(t, t1, got.ModTime.When, time.Second)
|
||||
assert.Equal(t, "a", got.Path)
|
||||
assert.Equal(t, "a", got.Name)
|
||||
assert.Equal(t, int64(1), got.Size)
|
||||
|
@ -209,7 +209,7 @@ func TestRcList(t *testing.T) {
|
|||
checkSubdir(list[1])
|
||||
|
||||
checkFile2 := func(got *operations.ListJSONItem) {
|
||||
assert.WithinDuration(t, t2, time.Time(got.ModTime), time.Second)
|
||||
assert.WithinDuration(t, t2, got.ModTime.When, time.Second)
|
||||
assert.Equal(t, "subdir/b", got.Path)
|
||||
assert.Equal(t, "b", got.Name)
|
||||
assert.Equal(t, int64(2), got.Size)
|
||||
|
|
Loading…
Reference in a new issue