Rewrite from Python to Go for single-binary cross-platform builds
Replaces imapdown.py with a multi-file Go implementation using github.com/emersion/go-imap/v2. All features preserved: SSL/STARTTLS, incremental UID-based downloads, attachment extraction to zip, modified UTF-7 folder name decoding, and full-mode safety checks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const stateFileName = ".imapdown_state.json"
|
||||
|
||||
// State tracks the highest UID downloaded per folder
|
||||
type State map[string]uint32
|
||||
|
||||
// LoadState reads the state file from the base directory
|
||||
// Returns empty state if file doesn't exist or can't be read
|
||||
func LoadState(baseDir string, fullMode bool) (State, error) {
|
||||
if fullMode {
|
||||
return make(State), nil
|
||||
}
|
||||
|
||||
statePath := filepath.Join(baseDir, stateFileName)
|
||||
|
||||
data, err := os.ReadFile(statePath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return make(State), nil
|
||||
}
|
||||
return make(State), err
|
||||
}
|
||||
|
||||
var state State
|
||||
if err := json.Unmarshal(data, &state); err != nil {
|
||||
// Return empty state on parse error
|
||||
return make(State), nil
|
||||
}
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// SaveState writes the state file to the base directory with indentation
|
||||
func SaveState(baseDir string, state State) error {
|
||||
statePath := filepath.Join(baseDir, stateFileName)
|
||||
|
||||
data, err := json.MarshalIndent(state, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.WriteFile(statePath, data, 0644)
|
||||
}
|
||||
|
||||
// UpdateFolder updates the highest UID for a folder
|
||||
func (s State) UpdateFolder(folder string, uid uint32) {
|
||||
if current, exists := s[folder]; !exists || uid > current {
|
||||
s[folder] = uid
|
||||
}
|
||||
}
|
||||
|
||||
// GetLastUID returns the last UID for a folder, or 0 if not found
|
||||
func (s State) GetLastUID(folder string) uint32 {
|
||||
if uid, exists := s[folder]; exists {
|
||||
return uid
|
||||
}
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user