🎨 Unreferenced assets files and databases sorted by modification time (#17090)

* 🎨 Unreferenced assets files sorted by modification time

* 🐛 Unreferenced databases sorted by modification time
This commit is contained in:
Jeffrey Chen 2026-03-03 00:06:23 +08:00 committed by GitHub
parent 6030629cc9
commit 104b634435
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 44 additions and 25 deletions

View file

@ -344,7 +344,7 @@ func getUnusedAssets(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
unusedAssets := model.UnusedAssets()
unusedAssets := model.UnusedAssets(true)
total := len(unusedAssets)
// List only 512 unreferenced assets https://github.com/siyuan-note/siyuan/issues/13075

View file

@ -58,7 +58,7 @@ func getUnusedAttributeViews(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
unusedAttributeViews := model.UnusedAttributeViews()
unusedAttributeViews := model.UnusedAttributeViews(true)
total := len(unusedAttributeViews)
const maxUnusedAttributeViews = 512

View file

@ -765,7 +765,7 @@ func RemoveUnusedAssets() (ret []string) {
util.PushUpdateMsg(msgId, msg, 7000)
}()
unusedAssets := UnusedAssets()
unusedAssets := UnusedAssets(false)
historyDir, err := GetHistoryDir(HistoryOpClean)
if err != nil {
@ -1006,11 +1006,12 @@ func RenameAsset(oldPath, newName string) (newPath string, err error) {
}
type UnusedItem struct {
Item string `json:"item"`
Name string `json:"name"`
Item string `json:"item"`
Name string `json:"name"`
ModTime time.Time `json:"-"`
}
func UnusedAssets() (ret []*UnusedItem) {
func UnusedAssets(sorted bool) (ret []*UnusedItem) {
defer logging.Recover()
ret = []*UnusedItem{}
@ -1167,7 +1168,24 @@ func UnusedAssets() (ret []*UnusedItem) {
p = p[1:]
}
name := util.RemoveID(path.Base(p))
ret = append(ret, &UnusedItem{Item: p, Name: name})
var modTime time.Time
if sorted {
if info, statErr := os.Stat(assetAbsPath); nil == statErr {
modTime = info.ModTime()
}
}
ret = append(ret, &UnusedItem{Item: p, Name: name, ModTime: modTime})
}
if sorted {
sort.Slice(ret, func(i, j int) bool {
if !ret[i].ModTime.Equal(ret[j].ModTime) {
return ret[i].ModTime.After(ret[j].ModTime)
}
return ret[i].Item > ret[j].Item
})
}
return
}

View file

@ -88,7 +88,7 @@ func RemoveUnusedAttributeViews() (ret []string) {
util.PushUpdateMsg(msgId, msg, 7000)
}()
unusedAttributeViews := UnusedAttributeViews()
unusedAttributeViews := UnusedAttributeViews(false)
historyDir, err := GetHistoryDir(HistoryOpClean)
if err != nil {
@ -132,7 +132,7 @@ func RemoveUnusedAttributeViews() (ret []string) {
return
}
func UnusedAttributeViews() (ret []*UnusedItem) {
func UnusedAttributeViews(sorted bool) (ret []*UnusedItem) {
defer logging.Recover()
ret = []*UnusedItem{}
@ -172,26 +172,27 @@ func UnusedAttributeViews() (ret []*UnusedItem) {
for _, id := range allAvIDs {
if !docReferencedAvIDs[id] && !isRelatedSrcAvDocReferenced(id, docReferencedAvIDs, checkedAvIDs) {
name, _ := av.GetAttributeViewName(id)
ret = append(ret, &UnusedItem{Item: id, Name: name})
var modTime time.Time
if sorted {
p := filepath.Join(util.DataDir, "storage", "av", id+".json")
if info, statErr := os.Stat(p); nil == statErr {
modTime = info.ModTime()
}
}
ret = append(ret, &UnusedItem{Item: id, Name: name, ModTime: modTime})
}
}
// 按文件更新时间排序
modTimes := make([]time.Time, len(ret))
for i := range ret {
p := filepath.Join(util.DataDir, "storage", "av", ret[i].Item+".json")
if info, statErr := os.Stat(p); nil != statErr {
modTimes[i] = info.ModTime()
} else {
modTimes[i] = time.Time{}
}
if sorted {
sort.Slice(ret, func(i, j int) bool {
if !ret[i].ModTime.Equal(ret[j].ModTime) {
return ret[i].ModTime.After(ret[j].ModTime)
}
return ret[i].Item > ret[j].Item
})
}
sort.Slice(ret, func(i, j int) bool {
if !modTimes[i].Equal(modTimes[j]) {
return modTimes[i].After(modTimes[j])
}
return ret[i].Item > ret[j].Item
})
return
}