Files
2026-07-27 19:31:43 +08:00

243 lines
5.5 KiB
Go

package pan115open
import (
"bytes"
"encoding/json"
"strings"
"time"
"litepan/internal/domain"
)
type listPageResp struct {
Count int64 `json:"count"`
Data []fileEntry `json:"data"`
}
type fileEntry struct {
Fid string `json:"fid"`
FileID string `json:"file_id"`
Fn string `json:"fn"`
FileName string `json:"file_name"`
Fc flexString `json:"fc"`
FileCategory flexString `json:"file_category"`
Aid flexString `json:"aid"`
Pid string `json:"pid"`
Cid string `json:"cid"`
ParentID string `json:"parent_id"`
Pc string `json:"pc"`
PickCode string `json:"pick_code"`
Pickcode string `json:"pickcode"`
Code string `json:"code"`
Sha1 string `json:"sha1"`
SizeByte flexNumber `json:"size_byte"`
S flexNumber `json:"s"`
FS flexNumber `json:"fs"`
Size flexNumber `json:"size"`
Thumb string `json:"thumb"`
Thumbnail string `json:"thumbnail"`
T flexNumber `json:"t"`
Upt flexNumber `json:"upt"`
Uetime flexNumber `json:"uet"`
Uppt flexNumber `json:"uppt"`
Utime string `json:"utime"`
Ptime string `json:"ptime"`
}
type mkdirResp struct {
Cid string `json:"cid"`
FileID string `json:"file_id"`
FileName string `json:"file_name"`
}
type recycleListResp struct {
Count json.Number `json:"count"`
Offset json.Number `json:"offset"`
Limit json.Number `json:"limit"`
RbPass json.Number `json:"rb_pass"`
Files map[string]recycleFile `json:"-"`
}
type recycleFile struct {
ID string `json:"id"`
FileName string `json:"file_name"`
Dtime json.Number `json:"dtime"`
DeleteTime json.Number `json:"delete_time"`
}
func (e fileEntry) entryID() string {
if s := strings.TrimSpace(e.Fid); s != "" {
return s
}
return strings.TrimSpace(e.FileID)
}
func (e fileEntry) entryName() string {
if s := strings.TrimSpace(e.Fn); s != "" {
return s
}
return strings.TrimSpace(e.FileName)
}
func (e fileEntry) isDirectory() bool {
if s := e.FileCategory.String(); s != "" {
return s == "0"
}
return e.Fc.String() == "0"
}
func (e fileEntry) entrySize() int64 {
for _, n := range []flexNumber{e.FS, e.SizeByte, e.S, e.Size} {
if v := n.int64(); v > 0 {
return v
}
}
return 0
}
func (e fileEntry) pickCode() string {
for _, s := range []string{e.Pc, e.PickCode, e.Pickcode, e.Code} {
if v := strings.TrimSpace(s); v != "" {
return v
}
}
return ""
}
func (e *fileEntry) UnmarshalJSON(data []byte) error {
data = bytes.TrimSpace(data)
if len(data) > 0 && data[0] == '[' {
var arr []fileEntry
if err := json.Unmarshal(data, &arr); err != nil {
return err
}
if len(arr) == 0 {
return domain.Errf(domain.CodeNotFound)
}
*e = arr[0]
return nil
}
type alias fileEntry
return json.Unmarshal(data, (*alias)(e))
}
func fileToItem(e fileEntry) domain.FileItem {
item := domain.FileItem{
ID: e.entryID(),
Name: e.entryName(),
Size: e.entrySize(),
IsDir: e.isDirectory(),
IDKind: domain.IDStable,
}
if sha1 := strings.TrimSpace(e.Sha1); sha1 != "" {
item.Hash = map[domain.HashType]string{domain.HashSHA1: sha1}
}
thumb := strings.TrimSpace(e.Thumb)
if thumb == "" {
thumb = strings.TrimSpace(e.Thumbnail)
}
if thumb != "" {
item.Thumb = thumb
}
if ts := entryModTime(e); !ts.IsZero() {
item.ModTime = ts
}
return item
}
func entryModTime(e fileEntry) time.Time {
for _, n := range []flexNumber{e.Upt, e.T, e.Uetime, e.Uppt} {
if v := n.int64(); v > 0 {
return time.Unix(v, 0)
}
}
for _, raw := range []string{e.Utime, e.Ptime} {
if ts := parseTimeText(raw); !ts.IsZero() {
return ts
}
}
return time.Time{}
}
func parseTimeText(raw string) time.Time {
raw = strings.TrimSpace(raw)
if raw == "" || raw == "0" {
return time.Time{}
}
if ts, err := time.ParseInLocation("2006-01-02 15:04:05", raw, time.Local); err == nil {
return ts
}
return time.Time{}
}
func isTrashed(e fileEntry) bool {
switch e.Aid.String() {
case "7", "120":
return true
default:
return false
}
}
func (r *recycleListResp) UnmarshalJSON(data []byte) error {
var envelope struct {
Data json.RawMessage `json:"data"`
}
if err := json.Unmarshal(data, &envelope); err != nil {
return err
}
payload := data
if len(bytes.TrimSpace(envelope.Data)) > 0 {
payload = envelope.Data
}
return r.parseRecyclePayload(payload)
}
func (r *recycleListResp) parseRecyclePayload(payload []byte) error {
var meta struct {
Count json.Number `json:"count"`
Offset json.Number `json:"offset"`
Limit json.Number `json:"limit"`
RbPass json.Number `json:"rb_pass"`
}
if err := json.Unmarshal(payload, &meta); err != nil {
return err
}
r.Count = meta.Count
r.Offset = meta.Offset
r.Limit = meta.Limit
r.RbPass = meta.RbPass
var raw map[string]json.RawMessage
if err := json.Unmarshal(payload, &raw); err != nil {
return err
}
skip := map[string]struct{}{
"count": {}, "offset": {}, "limit": {}, "rb_pass": {},
}
files := make(map[string]recycleFile)
for key, val := range raw {
if _, ok := skip[key]; ok {
continue
}
var f recycleFile
if json.Unmarshal(val, &f) != nil {
continue
}
files[key] = f
}
r.Files = files
return nil
}
func recycleDeleteTime(f recycleFile) int64 {
for _, n := range []json.Number{f.DeleteTime, f.Dtime} {
if s := strings.TrimSpace(n.String()); s != "" && s != "0" {
if v, err := n.Int64(); err == nil {
return v
}
}
}
return 0
}