mirror of https://github.com/Xhofe/alist
fix: updateTime, createTime and HashInfo (#5111)
parent
ce10c9f120
commit
6308f1c35d
|
@ -94,8 +94,10 @@ func (d *AListV3) List(ctx context.Context, dir model.Obj, args model.ListArgs)
|
||||||
Object: model.Object{
|
Object: model.Object{
|
||||||
Name: f.Name,
|
Name: f.Name,
|
||||||
Modified: f.Modified,
|
Modified: f.Modified,
|
||||||
|
Ctime: f.Created,
|
||||||
Size: f.Size,
|
Size: f.Size,
|
||||||
IsFolder: f.IsDir,
|
IsFolder: f.IsDir,
|
||||||
|
HashInfo: utils.FromString(f.HashInfo),
|
||||||
},
|
},
|
||||||
Thumbnail: model.Thumbnail{Thumbnail: f.Thumb},
|
Thumbnail: model.Thumbnail{Thumbnail: f.Thumb},
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,11 @@ type ObjResp struct {
|
||||||
Size int64 `json:"size"`
|
Size int64 `json:"size"`
|
||||||
IsDir bool `json:"is_dir"`
|
IsDir bool `json:"is_dir"`
|
||||||
Modified time.Time `json:"modified"`
|
Modified time.Time `json:"modified"`
|
||||||
|
Created time.Time `json:"created"`
|
||||||
Sign string `json:"sign"`
|
Sign string `json:"sign"`
|
||||||
Thumb string `json:"thumb"`
|
Thumb string `json:"thumb"`
|
||||||
Type int `json:"type"`
|
Type int `json:"type"`
|
||||||
|
HashInfo string `json:"hashinfo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FsListResp struct {
|
type FsListResp struct {
|
||||||
|
|
|
@ -44,6 +44,7 @@ func fileToObj(f File) *model.ObjThumb {
|
||||||
Name: f.Name,
|
Name: f.Name,
|
||||||
Size: f.Size,
|
Size: f.Size,
|
||||||
Modified: f.UpdatedAt,
|
Modified: f.UpdatedAt,
|
||||||
|
Ctime: f.CreatedAt,
|
||||||
IsFolder: f.Type == "folder",
|
IsFolder: f.Type == "folder",
|
||||||
},
|
},
|
||||||
Thumbnail: model.Thumbnail{Thumbnail: f.Thumbnail},
|
Thumbnail: model.Thumbnail{Thumbnail: f.Thumbnail},
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
"github.com/alist-org/alist/v3/internal/driver"
|
"github.com/alist-org/alist/v3/internal/driver"
|
||||||
|
@ -103,7 +104,7 @@ func (d *Local) FileInfoToObj(f fs.FileInfo, reqPath string, fullPath string) mo
|
||||||
if !isFolder {
|
if !isFolder {
|
||||||
size = f.Size()
|
size = f.Size()
|
||||||
}
|
}
|
||||||
ctime := f.ModTime()
|
var ctime time.Time
|
||||||
t, err := times.Stat(stdpath.Join(fullPath, f.Name()))
|
t, err := times.Stat(stdpath.Join(fullPath, f.Name()))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if t.HasBirthTime() {
|
if t.HasBirthTime() {
|
||||||
|
@ -155,10 +156,18 @@ func (d *Local) Get(ctx context.Context, path string) (model.Obj, error) {
|
||||||
if isFolder {
|
if isFolder {
|
||||||
size = 0
|
size = 0
|
||||||
}
|
}
|
||||||
|
var ctime time.Time
|
||||||
|
t, err := times.Stat(path)
|
||||||
|
if err == nil {
|
||||||
|
if t.HasBirthTime() {
|
||||||
|
ctime = t.BirthTime()
|
||||||
|
}
|
||||||
|
}
|
||||||
file := model.Object{
|
file := model.Object{
|
||||||
Path: path,
|
Path: path,
|
||||||
Name: f.Name(),
|
Name: f.Name(),
|
||||||
Modified: f.ModTime(),
|
Modified: f.ModTime(),
|
||||||
|
Ctime: ctime,
|
||||||
Size: size,
|
Size: size,
|
||||||
IsFolder: isFolder,
|
IsFolder: isFolder,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,14 @@ import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"encoding"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/alist-org/alist/v3/internal/errs"
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
"hash"
|
"hash"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetMD5EncodeStr(data string) string {
|
func GetMD5EncodeStr(data string) string {
|
||||||
|
@ -30,6 +32,23 @@ type HashType struct {
|
||||||
NewFunc func() hash.Hash
|
NewFunc func() hash.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ht *HashType) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(`"` + ht.Name + `"`), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ht *HashType) MarshalText() (text []byte, err error) {
|
||||||
|
return []byte(ht.Name), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ json.Marshaler = (*HashType)(nil)
|
||||||
|
//_ json.Unmarshaler = (*HashType)(nil)
|
||||||
|
|
||||||
|
// read/write from/to json keys
|
||||||
|
_ encoding.TextMarshaler = (*HashType)(nil)
|
||||||
|
//_ encoding.TextUnmarshaler = (*HashType)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
name2hash = map[string]*HashType{}
|
name2hash = map[string]*HashType{}
|
||||||
alias2hash = map[string]*HashType{}
|
alias2hash = map[string]*HashType{}
|
||||||
|
@ -158,23 +177,39 @@ func (m *MultiHasher) Size() int64 {
|
||||||
|
|
||||||
// A HashInfo contains hash string for one or more hashType
|
// A HashInfo contains hash string for one or more hashType
|
||||||
type HashInfo struct {
|
type HashInfo struct {
|
||||||
h map[*HashType]string
|
h map[*HashType]string `json:"hashInfo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHashInfo(ht *HashType, str string) HashInfo {
|
func NewHashInfo(ht *HashType, str string) HashInfo {
|
||||||
m := make(map[*HashType]string)
|
m := make(map[*HashType]string)
|
||||||
m[ht] = str
|
if ht != nil {
|
||||||
|
m[ht] = str
|
||||||
|
}
|
||||||
return HashInfo{h: m}
|
return HashInfo{h: m}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hi HashInfo) String() string {
|
func (hi HashInfo) String() string {
|
||||||
var tmp []string
|
result, err := json.Marshal(hi.h)
|
||||||
for ht, str := range hi.h {
|
if err != nil {
|
||||||
if len(str) > 0 {
|
return ""
|
||||||
tmp = append(tmp, ht.Name+":"+str)
|
}
|
||||||
|
return string(result)
|
||||||
|
}
|
||||||
|
func FromString(str string) HashInfo {
|
||||||
|
hi := NewHashInfo(nil, "")
|
||||||
|
var tmp map[string]string
|
||||||
|
err := json.Unmarshal([]byte(str), &tmp)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("failed to unmarsh HashInfo from string=%s", str)
|
||||||
|
} else {
|
||||||
|
for k, v := range tmp {
|
||||||
|
if name2hash[k] != nil && len(v) > 0 {
|
||||||
|
hi.h[name2hash[k]] = v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strings.Join(tmp, "\n")
|
|
||||||
|
return hi
|
||||||
}
|
}
|
||||||
func (hi HashInfo) GetHash(ht *HashType) string {
|
func (hi HashInfo) GetHash(ht *HashType) string {
|
||||||
return hi.h[ht]
|
return hi.h[ht]
|
||||||
|
|
|
@ -58,7 +58,10 @@ func TestMultiHasher(t *testing.T) {
|
||||||
}
|
}
|
||||||
expect := hashInfo.GetHash(nil)
|
expect := hashInfo.GetHash(nil)
|
||||||
require.True(t, len(expect) == 0, "unknown type should return empty string")
|
require.True(t, len(expect) == 0, "unknown type should return empty string")
|
||||||
Log.Info(hashInfo.String())
|
str := hashInfo.String()
|
||||||
|
Log.Info("str=" + str)
|
||||||
|
newHi := FromString(str)
|
||||||
|
assert.Equal(t, newHi.h, hashInfo.h)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,6 +204,8 @@ func toObjsResp(objs []model.Obj, parent string, encrypt bool) []ObjResp {
|
||||||
Size: obj.GetSize(),
|
Size: obj.GetSize(),
|
||||||
IsDir: obj.IsDir(),
|
IsDir: obj.IsDir(),
|
||||||
Modified: obj.ModTime(),
|
Modified: obj.ModTime(),
|
||||||
|
Created: obj.CreateTime(),
|
||||||
|
HashInfo: obj.GetHash().String(),
|
||||||
Sign: common.Sign(obj, parent, encrypt),
|
Sign: common.Sign(obj, parent, encrypt),
|
||||||
Thumb: thumb,
|
Thumb: thumb,
|
||||||
Type: utils.GetObjType(obj.GetName(), obj.IsDir()),
|
Type: utils.GetObjType(obj.GetName(), obj.IsDir()),
|
||||||
|
|
Loading…
Reference in New Issue