forked from TrueCloudLab/rclone
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".
|
will be "subfolder/file.txt", not "remote:path/subfolder/file.txt".
|
||||||
When used without --recursive the Path will always be the same as Name.
|
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
|
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.
|
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"`
|
OrigID string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timestamp a time in RFC3339 format with Nanosecond precision secongs
|
// Timestamp a time in the provided format
|
||||||
type Timestamp time.Time
|
type Timestamp struct {
|
||||||
|
When time.Time
|
||||||
|
Format string
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalJSON turns a Timestamp into JSON
|
// MarshalJSON turns a Timestamp into JSON
|
||||||
func (t Timestamp) MarshalJSON() (out []byte, err error) {
|
func (t Timestamp) MarshalJSON() (out []byte, err error) {
|
||||||
tt := time.Time(t)
|
if t.When.IsZero() {
|
||||||
if tt.IsZero() {
|
|
||||||
return []byte(`""`), nil
|
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
|
// 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")
|
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 {
|
err := walk.Walk(fsrc, remote, false, ConfigMaxDepth(opt.Recurse), func(dirPath string, entries fs.DirEntries, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.CountError(err)
|
fs.CountError(err)
|
||||||
|
@ -75,7 +103,7 @@ func ListJSON(fsrc fs.Fs, remote string, opt *ListJSONOpt, callback func(*ListJS
|
||||||
MimeType: fs.MimeTypeDirEntry(entry),
|
MimeType: fs.MimeTypeDirEntry(entry),
|
||||||
}
|
}
|
||||||
if !opt.NoModTime {
|
if !opt.NoModTime {
|
||||||
item.ModTime = Timestamp(entry.ModTime())
|
item.ModTime = Timestamp{When: entry.ModTime(), Format: format}
|
||||||
}
|
}
|
||||||
if cipher != nil {
|
if cipher != nil {
|
||||||
switch entry.(type) {
|
switch entry.(type) {
|
||||||
|
|
|
@ -175,7 +175,7 @@ func TestRcList(t *testing.T) {
|
||||||
assert.Equal(t, 2, len(list))
|
assert.Equal(t, 2, len(list))
|
||||||
|
|
||||||
checkFile1 := func(got *operations.ListJSONItem) {
|
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.Path)
|
||||||
assert.Equal(t, "a", got.Name)
|
assert.Equal(t, "a", got.Name)
|
||||||
assert.Equal(t, int64(1), got.Size)
|
assert.Equal(t, int64(1), got.Size)
|
||||||
|
@ -209,7 +209,7 @@ func TestRcList(t *testing.T) {
|
||||||
checkSubdir(list[1])
|
checkSubdir(list[1])
|
||||||
|
|
||||||
checkFile2 := func(got *operations.ListJSONItem) {
|
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, "subdir/b", got.Path)
|
||||||
assert.Equal(t, "b", got.Name)
|
assert.Equal(t, "b", got.Name)
|
||||||
assert.Equal(t, int64(2), got.Size)
|
assert.Equal(t, int64(2), got.Size)
|
||||||
|
|
Loading…
Add table
Reference in a new issue