Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/internal/archive/archives/utils.go
1562 views
1
package archives
2
3
import (
4
"io"
5
fs2 "io/fs"
6
"os"
7
stdpath "path"
8
"strings"
9
10
"github.com/alist-org/alist/v3/internal/errs"
11
"github.com/alist-org/alist/v3/internal/model"
12
"github.com/alist-org/alist/v3/internal/stream"
13
"github.com/alist-org/alist/v3/pkg/utils"
14
"github.com/mholt/archives"
15
)
16
17
func getFs(ss *stream.SeekableStream, args model.ArchiveArgs) (*archives.ArchiveFS, error) {
18
reader, err := stream.NewReadAtSeeker(ss, 0)
19
if err != nil {
20
return nil, err
21
}
22
if r, ok := reader.(*stream.RangeReadReadAtSeeker); ok {
23
r.InitHeadCache()
24
}
25
format, _, err := archives.Identify(ss.Ctx, ss.GetName(), reader)
26
if err != nil {
27
return nil, errs.UnknownArchiveFormat
28
}
29
extractor, ok := format.(archives.Extractor)
30
if !ok {
31
return nil, errs.UnknownArchiveFormat
32
}
33
switch f := format.(type) {
34
case archives.SevenZip:
35
f.Password = args.Password
36
case archives.Rar:
37
f.Password = args.Password
38
}
39
return &archives.ArchiveFS{
40
Stream: io.NewSectionReader(reader, 0, ss.GetSize()),
41
Format: extractor,
42
Context: ss.Ctx,
43
}, nil
44
}
45
46
func toModelObj(file os.FileInfo) *model.Object {
47
return &model.Object{
48
Name: file.Name(),
49
Size: file.Size(),
50
Modified: file.ModTime(),
51
IsFolder: file.IsDir(),
52
}
53
}
54
55
func filterPassword(err error) error {
56
if err != nil && strings.Contains(err.Error(), "password") {
57
return errs.WrongArchivePassword
58
}
59
return err
60
}
61
62
func decompress(fsys fs2.FS, filePath, targetPath string, up model.UpdateProgress) error {
63
rc, err := fsys.Open(filePath)
64
if err != nil {
65
return err
66
}
67
defer rc.Close()
68
stat, err := rc.Stat()
69
if err != nil {
70
return err
71
}
72
f, err := os.OpenFile(stdpath.Join(targetPath, stat.Name()), os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
73
if err != nil {
74
return err
75
}
76
defer f.Close()
77
_, err = utils.CopyWithBuffer(f, &stream.ReaderUpdatingProgress{
78
Reader: &stream.SimpleReaderWithSize{
79
Reader: rc,
80
Size: stat.Size(),
81
},
82
UpdateProgress: up,
83
})
84
return err
85
}
86
87