Skip to content

Commit b9aed84

Browse files
committed
support tar.gz .gz compress file
1 parent fbb099b commit b9aed84

File tree

5 files changed

+127
-84
lines changed

5 files changed

+127
-84
lines changed

Diff for: src/components/function.go

+73-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package components
22

33
import (
4+
"archive/tar"
45
"archive/zip"
6+
"compress/gzip"
57
"encoding/json"
68
"fmt"
79
"io"
@@ -549,16 +551,6 @@ func unzip(src, dest string) error {
549551
total: totalFiles,
550552
done: 0,
551553
}
552-
if _, err := os.Stat(filepath.Join(dest, filepath.Base(src))); os.IsExist(err) {
553-
p.state = failure
554-
p.name = "󰛫 Directory already exist"
555-
channel <- channelMessage{
556-
messageId: id,
557-
processNewState: p,
558-
}
559-
return nil
560-
}
561-
os.MkdirAll(dest, 0755)
562554

563555
// Closure to address file descriptors issue with all the deferred .Close() methods
564556
extractAndWriteFile := func(f *zip.File) error {
@@ -640,6 +632,77 @@ func unzip(src, dest string) error {
640632
return nil
641633
}
642634

635+
func ungzip(input, output string) error {
636+
var err error
637+
input, err = filepath.Abs(input)
638+
if err != nil {
639+
return err
640+
}
641+
output, err = filepath.Abs(output)
642+
if err != nil {
643+
return err
644+
}
645+
646+
inputFile, err := os.Open(input)
647+
if err != nil {
648+
return err
649+
}
650+
defer inputFile.Close()
651+
652+
gzReader, err := gzip.NewReader(inputFile)
653+
if err != nil {
654+
return err
655+
}
656+
defer gzReader.Close()
657+
658+
err = os.MkdirAll(output, 0755)
659+
if err != nil {
660+
return err
661+
}
662+
663+
tarReader := tar.NewReader(gzReader)
664+
for {
665+
header, err := tarReader.Next()
666+
667+
if err == io.EOF {
668+
break
669+
}
670+
if err != nil {
671+
return err
672+
}
673+
674+
targetPath := filepath.Join(output, header.Name)
675+
676+
fileInfo := header.FileInfo()
677+
if fileInfo.IsDir() {
678+
err = os.MkdirAll(targetPath, fileInfo.Mode())
679+
if err != nil {
680+
return err
681+
}
682+
continue
683+
}
684+
685+
targetFile, err := os.Create(targetPath)
686+
if err != nil {
687+
return err
688+
}
689+
690+
_, err = io.Copy(targetFile, tarReader)
691+
if err != nil {
692+
targetFile.Close()
693+
return err
694+
}
695+
696+
err = targetFile.Close()
697+
if err != nil {
698+
return err
699+
}
700+
701+
}
702+
703+
return nil
704+
}
705+
643706
func zipSource(source, target string) error {
644707
id := shortuuid.New()
645708
prog := progress.New()
@@ -669,7 +732,6 @@ func zipSource(source, target string) error {
669732
return nil
670733
}
671734

672-
// 1. Create a ZIP file and zip.Writer
673735
f, err := os.Create(target)
674736
if err != nil {
675737
return err
@@ -679,7 +741,6 @@ func zipSource(source, target string) error {
679741
writer := zip.NewWriter(f)
680742
defer writer.Close()
681743

682-
// 2. Go through all the files of the source
683744
err = filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
684745
p.name = "󰗄 " + filepath.Base(path)
685746
if len(channel) < 5 {
@@ -693,16 +754,13 @@ func zipSource(source, target string) error {
693754
return err
694755
}
695756

696-
// 3. Create a local file header
697757
header, err := zip.FileInfoHeader(info)
698758
if err != nil {
699759
return err
700760
}
701761

702-
// set compression
703762
header.Method = zip.Deflate
704763

705-
// 4. Set relative path of a file as the header name
706764
header.Name, err = filepath.Rel(filepath.Dir(source), path)
707765
if err != nil {
708766
return err
@@ -711,7 +769,6 @@ func zipSource(source, target string) error {
711769
header.Name += "/"
712770
}
713771

714-
// 5. Create writer for the file header and save content of the file
715772
headerWriter, err := writer.CreateHeader(header)
716773
if err != nil {
717774
return err

Diff for: src/components/global_controller.go

+42-21
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,12 @@ func contollerProcessBarListDown(m model) model {
123123
if len(m.processBarModel.processList) == 0 {
124124
return m
125125
}
126-
if m.processBarModel.cursor < len(m.processBarModel.processList)-1 {
126+
if m.processBarModel.cursor < len(m.processBarModel.processList)-1 {
127127
m.processBarModel.cursor++
128128
if m.processBarModel.cursor > m.processBarModel.render+2 {
129129
m.processBarModel.render++
130130
}
131-
} else {
131+
} else {
132132
m.processBarModel.render = 0
133133
m.processBarModel.cursor = 0
134134
}
@@ -274,7 +274,9 @@ func pasteItem(m model) model {
274274
if len(m.copyItems.items) == 0 {
275275
return m
276276
}
277+
277278
totalFiles := 0
279+
278280
for _, folderPath := range m.copyItems.items {
279281
count, err := countFiles(folderPath)
280282
if err != nil {
@@ -289,22 +291,17 @@ func pasteItem(m model) model {
289291

290292
newProcess := process{}
291293

294+
prefixIcon := "󰆏 "
292295
if m.copyItems.cut {
293-
newProcess = process{
294-
name: "󰆐 " + filepath.Base(m.copyItems.items[0]),
295-
progress: prog,
296-
state: inOperation,
297-
total: totalFiles,
298-
done: 0,
299-
}
300-
} else {
301-
newProcess = process{
302-
name: "󰆏 " + filepath.Base(m.copyItems.items[0]),
303-
progress: prog,
304-
state: inOperation,
305-
total: totalFiles,
306-
done: 0,
307-
}
296+
prefixIcon = "󰆐 "
297+
}
298+
299+
newProcess = process{
300+
name: prefixIcon + filepath.Base(m.copyItems.items[0]),
301+
progress: prog,
302+
state: inOperation,
303+
total: totalFiles,
304+
done: 0,
308305
}
309306

310307
m.processBarModel.process[id] = newProcess
@@ -350,7 +347,7 @@ func pasteItem(m model) model {
350347
if m.copyItems.cut {
351348
for _, item := range m.copyItems.items {
352349
if runtime.GOOS == "darwin" {
353-
err := moveElement(item, HomeDir + "/.Trash/" + filepath.Base(item))
350+
err := moveElement(item, HomeDir+"/.Trash/"+filepath.Base(item))
354351
if err != nil {
355352
outPutLog("Delete single item function move file to trash can error", err)
356353
}
@@ -476,8 +473,26 @@ func toggleDotFileController(m model) model {
476473
}
477474

478475
func extractFile(m model) model {
476+
var err error
479477
panel := m.fileModel.filePanels[m.filePanelFocusIndex]
480-
unzip(panel.element[panel.cursor].location, filepath.Dir(panel.element[panel.cursor].location))
478+
ext := strings.ToLower(filepath.Ext(panel.element[panel.cursor].location))
479+
outputDir := fileNameWithoutExtension(panel.element[panel.cursor].location)
480+
outputDir, err = renameIfDuplicate(outputDir)
481+
482+
if err != nil {
483+
outPutLog("Error extract file when craete new directory", err)
484+
}
485+
486+
switch ext {
487+
case ".zip":
488+
os.MkdirAll(outputDir, 0755)
489+
unzip(panel.element[panel.cursor].location, outputDir)
490+
case ".tar", ".gz":
491+
os.MkdirAll(outputDir, 0755)
492+
ungzip(panel.element[panel.cursor].location, outputDir)
493+
default:
494+
return m
495+
}
481496
m.fileModel.filePanels[m.filePanelFocusIndex] = panel
482497
return m
483498
}
@@ -487,6 +502,12 @@ func compressFile(m model) model {
487502
fileName := filepath.Base(panel.element[panel.cursor].location)
488503

489504
zipName := strings.TrimSuffix(fileName, filepath.Ext(fileName)) + ".zip"
505+
zipName, err := renameIfDuplicate(zipName)
506+
507+
if err != nil {
508+
outPutLog("Error compress file when rename dublicate", err)
509+
}
510+
490511
zipSource(panel.element[panel.cursor].location, filepath.Join(filepath.Dir(panel.element[panel.cursor].location), zipName))
491512
m.fileModel.filePanels[m.filePanelFocusIndex] = panel
492513
return m
@@ -501,7 +522,7 @@ func openFileWithEditor(m model) tea.Cmd {
501522
editor = "nano"
502523
}
503524
c := exec.Command(editor, panel.element[panel.cursor].location)
504-
525+
505526
return tea.ExecProcess(c, func(err error) tea.Msg {
506527
return editorFinishedMsg{err}
507528
})
@@ -527,4 +548,4 @@ func openHelpMenu(m model) model {
527548

528549
m.helpMenu.open = true
529550
return m
530-
}
551+
}

Diff for: src/components/model.go

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ var forceReloadElement = false
3131
var firstUse = false
3232

3333
var HomeDir = basedir.Home
34+
3435
var SuperFileMainDir = basedir.ConfigHome + "/superfile"
3536
var SuperFileCacheDir = basedir.CacheHome + "/superfile"
3637
var SuperFileDataDir = basedir.DataHome + "/superfile"

Diff for: src/components/string_function.go

+11-41
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package components
22

33
import (
4+
"strings"
45
"unicode/utf8"
56

67
"github.com/charmbracelet/lipgloss"
@@ -66,44 +67,13 @@ func clipboardPrettierName(name string, width int, isDir bool, isSelected bool)
6667
}
6768
}
6869

69-
// func placeOverlay(x, y int,background, placeModal string) string {
70-
// lines := strings.Split(placeModal, "\n")
71-
// lines = lines
72-
// re := regexp.MustCompile(`\x1b\[[0-9;]*[mK]`)
73-
74-
// // 示例字符串
75-
// str := "┏A我"
76-
77-
// // 使用 FindAllStringIndex 找出所有匹配的位置
78-
// indexes := re.FindAllStringIndex(str, -1)
79-
// outPutLog(str)
80-
// // 檢查是否找到匹配
81-
// if indexes != nil {
82-
// for _, loc := range indexes {
83-
// loc = mapCoords(str, loc)
84-
// outPutLog(fmt.Sprintf("匹配的開始位置: %d, 結束位置: %d", loc[0], loc[1]))
85-
// }
86-
// } else {
87-
// outPutLog("沒有找到匹配")
88-
// }
89-
90-
// return ""
91-
// }
92-
93-
// func mapCoords(s string, byteCoords []int) (graphemeCoords []int) {
94-
// graphemeCoords = make([]int, 2)
95-
// gr := uniseg.NewGraphemes(s)
96-
// graphemeIndex := -1
97-
// for gr.Next() {
98-
// graphemeIndex++
99-
// a, b := gr.Positions()
100-
// if a == byteCoords[0] {
101-
// graphemeCoords[0] = graphemeIndex
102-
// }
103-
// if b == byteCoords[1] {
104-
// graphemeCoords[1] = graphemeIndex + 1
105-
// break
106-
// }
107-
// }
108-
// return
109-
// }
70+
func fileNameWithoutExtension(fileName string) string {
71+
for {
72+
pos := strings.LastIndexByte(fileName, '.')
73+
if pos == -1 {
74+
break
75+
}
76+
fileName = fileName[:pos]
77+
}
78+
return fileName
79+
}

Diff for: src/go.sum

-6
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ github.com/charmbracelet/x/exp/term v0.0.0-20240425164147-ba2a9512b05f h1:1BXkZq
1616
github.com/charmbracelet/x/exp/term v0.0.0-20240425164147-ba2a9512b05f/go.mod h1:yQqGHmheaQfkqiJWjklPHVAq1dKbk8uGbcoS/lcKCJ0=
1717
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
1818
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
19-
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
20-
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
2119
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
2220
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
2321
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -76,12 +74,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
7674
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
7775
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
7876
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
79-
github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
80-
github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
8177
github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
8278
github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
83-
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
84-
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
8579
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
8680
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
8781
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=

0 commit comments

Comments
 (0)