Add optional zstd mbox archives
This commit is contained in:
parent
21844688ac
commit
e612896e06
14 changed files with 620 additions and 39 deletions
|
|
@ -14,6 +14,8 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/klauspost/compress/zstd"
|
||||
)
|
||||
|
||||
type ArchiveStats struct {
|
||||
|
|
@ -136,6 +138,9 @@ func archiveDownloadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return err
|
||||
}
|
||||
header.Name = rel
|
||||
if strings.HasSuffix(strings.ToLower(rel), ".mbox.zst") {
|
||||
header.Name = strings.TrimSuffix(rel, ".zst")
|
||||
}
|
||||
header.Method = zip.Deflate
|
||||
dst, err := zw.CreateHeader(header)
|
||||
if err != nil {
|
||||
|
|
@ -146,7 +151,11 @@ func archiveDownloadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return err
|
||||
}
|
||||
defer src.Close()
|
||||
_, err = io.Copy(dst, src)
|
||||
if strings.HasSuffix(strings.ToLower(path), ".mbox.zst") {
|
||||
err = exportPlainMbox(src, dst)
|
||||
} else {
|
||||
_, err = io.Copy(dst, src)
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
|
@ -221,7 +230,7 @@ func renderArchiveUploadForm(w http.ResponseWriter, archives []string) {
|
|||
<label class="label">Archiv-Mailbox`)
|
||||
fmt.Fprint(w, archiveUploadSelect(archives))
|
||||
fmt.Fprint(w, `</label>
|
||||
<label class="label">Datei<input class="input" type="file" name="mailfile" accept=".mbox,.pst" required></label>
|
||||
<label class="label">Datei<input class="input" type="file" name="mailfile" accept=".mbox,.pst,.zst" required></label>
|
||||
<button class="btn" type="submit">Upload</button>
|
||||
</form>
|
||||
<div class="archive-help">
|
||||
|
|
@ -278,7 +287,7 @@ func ArchiveStatsFor(name string) (ArchiveStats, error) {
|
|||
}
|
||||
stat.Files++
|
||||
stat.Bytes += info.Size()
|
||||
if strings.EqualFold(filepath.Ext(path), ".mbox") {
|
||||
if isMboxArchivePath(path) {
|
||||
msgs, err := readMboxMessages(path)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
|
@ -414,17 +423,37 @@ func safeArchiveFileName(value string) (string, error) {
|
|||
if name == "" || name == "." || name == ".." {
|
||||
return "", fmt.Errorf("Dateiname fehlt.")
|
||||
}
|
||||
lower := strings.ToLower(name)
|
||||
ext := strings.ToLower(filepath.Ext(name))
|
||||
if ext != ".mbox" && ext != ".pst" {
|
||||
return "", fmt.Errorf("Nur mbox- und PST-Dateien koennen importiert werden.")
|
||||
if ext != ".mbox" && ext != ".pst" && !strings.HasSuffix(lower, ".mbox.zst") {
|
||||
return "", fmt.Errorf("Nur mbox-, mbox.zst- und PST-Dateien koennen importiert werden.")
|
||||
}
|
||||
clean := strings.NewReplacer("\\", "_", "/", "_", ":", "_").Replace(name)
|
||||
if strings.TrimSuffix(clean, ext) == "" {
|
||||
if strings.HasSuffix(strings.ToLower(clean), ".mbox.zst") {
|
||||
if strings.TrimSuffix(strings.TrimSuffix(clean, ".zst"), ".mbox") == "" {
|
||||
clean = "import.mbox.zst"
|
||||
}
|
||||
} else if strings.TrimSuffix(clean, ext) == "" {
|
||||
clean = "import" + ext
|
||||
}
|
||||
return clean, nil
|
||||
}
|
||||
|
||||
func isMboxArchivePath(path string) bool {
|
||||
lower := strings.ToLower(path)
|
||||
return strings.HasSuffix(lower, ".mbox") || strings.HasSuffix(lower, ".mbox.zst")
|
||||
}
|
||||
|
||||
func exportPlainMbox(src io.Reader, dst io.Writer) error {
|
||||
dec, err := zstd.NewReader(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dec.Close()
|
||||
_, err = io.Copy(dst, dec)
|
||||
return err
|
||||
}
|
||||
|
||||
func formatBytes(n int64) string {
|
||||
const unit = 1024
|
||||
if n < unit {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue