mirror of
https://github.com/Picocrypt/Picocrypt.git
synced 2025-05-12 13:48:31 +02:00
Merge pull request #89 from Retengart/test-features
App version in the window title and zip unpacking
This commit is contained in:
commit
670d284603
4 changed files with 151 additions and 7 deletions
|
@ -3,6 +3,12 @@
|
||||||
<li>Migrate golang.org/x/crypto to standard library imports (https://github.com/golang/go/issues/65269)</li>
|
<li>Migrate golang.org/x/crypto to standard library imports (https://github.com/golang/go/issues/65269)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
# v1.46 (Released 01/29/2025)
|
||||||
|
<ul>
|
||||||
|
<li>✓ Added Picocrypt version to the window title</li>
|
||||||
|
<li>✓ Added ability to automatically unzip archives upon decryption</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
# v1.45 (Released 12/05/2024)
|
# v1.45 (Released 12/05/2024)
|
||||||
<ul>
|
<ul>
|
||||||
<li>✓ Bumped GitHub Actions Ubuntu 22 -> 24 and macOS 14 -> 15</li>
|
<li>✓ Bumped GitHub Actions Ubuntu 22 -> 24 and macOS 14 -> 15</li>
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
1.45
|
1.46
|
||||||
|
|
|
@ -44,11 +44,17 @@
|
||||||
</screenshot>
|
</screenshot>
|
||||||
</screenshots>
|
</screenshots>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="1.45" date="2024-12-05">
|
<release version="1.46" date="2025-01-29">
|
||||||
<url type="details">https://github.com/Picocrypt/Picocrypt/blob/main/Changelog.md#v145-released-12052024</url>
|
<url type="details">https://github.com/Picocrypt/Picocrypt/blob/main/Changelog.md#v146-released-01292025</url>
|
||||||
<description>
|
<description>
|
||||||
<p>No code changes; just updated dependencies.</p>
|
<ul>
|
||||||
|
<li>Added Picocrypt version to the window title.</li>
|
||||||
|
<li>Added ability to automatically unpack zip archives during decryption.</li>
|
||||||
|
</ul>
|
||||||
</description>
|
</description>
|
||||||
</release>
|
</release>
|
||||||
|
<release version="1.45" date="2024-12-05">
|
||||||
|
<description></description>
|
||||||
|
</release>
|
||||||
</releases>
|
</releases>
|
||||||
</component>
|
</component>
|
||||||
|
|
138
src/Picocrypt.go
138
src/Picocrypt.go
|
@ -2,7 +2,7 @@ package main
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Picocrypt v1.45
|
Picocrypt v1.46
|
||||||
Copyright (c) Evan Su
|
Copyright (c) Evan Su
|
||||||
Released under a GNU GPL v3 License
|
Released under a GNU GPL v3 License
|
||||||
https://github.com/Picocrypt/Picocrypt
|
https://github.com/Picocrypt/Picocrypt
|
||||||
|
@ -60,7 +60,7 @@ var TRANSPARENT = color.RGBA{0x00, 0x00, 0x00, 0x00}
|
||||||
|
|
||||||
// Generic variables
|
// Generic variables
|
||||||
var window *giu.MasterWindow
|
var window *giu.MasterWindow
|
||||||
var version = "v1.45"
|
var version = "v1.46"
|
||||||
var dpi float32
|
var dpi float32
|
||||||
var mode string
|
var mode string
|
||||||
var working bool
|
var working bool
|
||||||
|
@ -120,6 +120,8 @@ var splitSelected int32 = 1
|
||||||
var recombine bool
|
var recombine bool
|
||||||
var compress bool
|
var compress bool
|
||||||
var delete bool
|
var delete bool
|
||||||
|
var autoUnzip bool
|
||||||
|
var sameLevel bool
|
||||||
var keep bool
|
var keep bool
|
||||||
var kept bool
|
var kept bool
|
||||||
|
|
||||||
|
@ -552,6 +554,22 @@ func draw() {
|
||||||
giu.Checkbox("Delete volume", &delete),
|
giu.Checkbox("Delete volume", &delete),
|
||||||
giu.Tooltip("Delete the volume after a successful decryption"),
|
giu.Tooltip("Delete the volume after a successful decryption"),
|
||||||
).Build()
|
).Build()
|
||||||
|
|
||||||
|
giu.Row(
|
||||||
|
giu.Style().SetDisabled(!strings.HasSuffix(inputFile, ".zip.pcv")).To(
|
||||||
|
giu.Checkbox("Auto unzip", &autoUnzip).OnChange(func() {
|
||||||
|
if !autoUnzip {
|
||||||
|
sameLevel = false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
giu.Tooltip("Extract .zip upon decryption (may overwrite)"),
|
||||||
|
),
|
||||||
|
giu.Dummy(-170, 0),
|
||||||
|
giu.Style().SetDisabled(!autoUnzip).To(
|
||||||
|
giu.Checkbox("Same level", &sameLevel),
|
||||||
|
giu.Tooltip("Extract .zip contents to same folder as volume"),
|
||||||
|
),
|
||||||
|
).Build()
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -2112,6 +2130,21 @@ func work() {
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if mode == "decrypt" && !kept && autoUnzip {
|
||||||
|
showProgress = true
|
||||||
|
popupStatus = "Unzipping..."
|
||||||
|
giu.Update()
|
||||||
|
|
||||||
|
if err := unpackArchive(outputFile); err != nil {
|
||||||
|
mainStatus = "Auto unzipping failed!"
|
||||||
|
mainStatusColor = RED
|
||||||
|
giu.Update()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Remove(outputFile)
|
||||||
|
}
|
||||||
|
|
||||||
// All done, reset the UI
|
// All done, reset the UI
|
||||||
oldKept := kept
|
oldKept := kept
|
||||||
resetUI()
|
resetUI()
|
||||||
|
@ -2209,6 +2242,8 @@ func resetUI() {
|
||||||
recombine = false
|
recombine = false
|
||||||
compress = false
|
compress = false
|
||||||
delete = false
|
delete = false
|
||||||
|
autoUnzip = false
|
||||||
|
sameLevel = false
|
||||||
keep = false
|
keep = false
|
||||||
kept = false
|
kept = false
|
||||||
|
|
||||||
|
@ -2330,9 +2365,106 @@ func sizeify(size int64) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unpackArchive(zipPath string) error {
|
||||||
|
reader, err := zip.OpenReader(zipPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer reader.Close()
|
||||||
|
|
||||||
|
var totalSize int64
|
||||||
|
for _, f := range reader.File {
|
||||||
|
totalSize += int64(f.UncompressedSize64)
|
||||||
|
}
|
||||||
|
|
||||||
|
var extractDir string
|
||||||
|
if sameLevel {
|
||||||
|
extractDir = filepath.Dir(zipPath)
|
||||||
|
} else {
|
||||||
|
extractDir = filepath.Join(filepath.Dir(zipPath), strings.TrimSuffix(filepath.Base(zipPath), ".zip"))
|
||||||
|
}
|
||||||
|
|
||||||
|
var done int64
|
||||||
|
startTime := time.Now()
|
||||||
|
|
||||||
|
for _, f := range reader.File {
|
||||||
|
if strings.Contains(f.Name, "..") {
|
||||||
|
return errors.New("potentially malicious zip item path")
|
||||||
|
}
|
||||||
|
outPath := filepath.Join(extractDir, f.Name)
|
||||||
|
|
||||||
|
// Make directory if current entry is a folder
|
||||||
|
if f.FileInfo().IsDir() {
|
||||||
|
if err := os.MkdirAll(outPath, f.Mode()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, f := range reader.File {
|
||||||
|
if strings.Contains(f.Name, "..") {
|
||||||
|
return errors.New("potentially malicious zip item path")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Already handled above
|
||||||
|
if f.FileInfo().IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
outPath := filepath.Join(extractDir, f.Name)
|
||||||
|
|
||||||
|
// Otherwise create necessary parent directories
|
||||||
|
if err := os.MkdirAll(filepath.Dir(outPath), 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the file inside the archive
|
||||||
|
fileInArchive, err := f.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fileInArchive.Close()
|
||||||
|
|
||||||
|
dstFile, err := os.Create(outPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from zip in chunks to update progress
|
||||||
|
buffer := make([]byte, MiB)
|
||||||
|
for {
|
||||||
|
n, readErr := fileInArchive.Read(buffer)
|
||||||
|
if n > 0 {
|
||||||
|
_, writeErr := dstFile.Write(buffer[:n])
|
||||||
|
if writeErr != nil {
|
||||||
|
dstFile.Close()
|
||||||
|
os.Remove(dstFile.Name())
|
||||||
|
return writeErr
|
||||||
|
}
|
||||||
|
|
||||||
|
done += int64(n)
|
||||||
|
progress, speed, eta = statify(done, totalSize, startTime)
|
||||||
|
progressInfo = fmt.Sprintf("%d/%d", i+1, len(reader.File))
|
||||||
|
popupStatus = fmt.Sprintf("Unpacking at %.2f MiB/s (ETA: %s)", speed, eta)
|
||||||
|
giu.Update()
|
||||||
|
}
|
||||||
|
if readErr != nil {
|
||||||
|
if readErr == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
dstFile.Close()
|
||||||
|
return readErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dstFile.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Create the main window
|
// Create the main window
|
||||||
window = giu.NewMasterWindow("Picocrypt", 318, 507, giu.MasterWindowFlagsNotResizable)
|
window = giu.NewMasterWindow("Picocrypt "+version[1:], 318, 507, giu.MasterWindowFlagsNotResizable)
|
||||||
|
|
||||||
// Start the dialog module
|
// Start the dialog module
|
||||||
dialog.Init()
|
dialog.Init()
|
||||||
|
|
Loading…
Add table
Reference in a new issue