commit 74fd90c850b5e38320cb6fce79dbfd212b6c8250 Author: Aaron Lindsay Date: Sun Feb 10 23:39:23 2013 -0500 Initial Commit diff --git a/asink.go b/asink.go new file mode 100644 index 0000000..8a0f6ab --- /dev/null +++ b/asink.go @@ -0,0 +1,83 @@ +package main + +import ( + "fmt" + "flag" + "path" + "os/user" + "github.com/howeyc/fsnotify" + "code.google.com/p/goconf/conf" +) + +var configFileName string + +func init() { + const config_usage = "Config File to use" + userHomeDir := "~" + + u, err := user.Current() + if err == nil { + userHomeDir = u.HomeDir + } + + flag.StringVar(&configFileName, "config", path.Join(userHomeDir, ".asink", "config"), config_usage) + flag.StringVar(&configFileName, "c", path.Join(userHomeDir, ".asink", "config"), config_usage+" (shorthand)") +} + +func main() { + flag.Parse() + fmt.Println("config file:", configFileName) + + config, err := conf.ReadConfigFile(configFileName) + if err != nil { + fmt.Println(err) + fmt.Println("Error reading config file at ", configFileName, ". Does it exist?") + return + } + + storage, err := GetStorage(config) + if err != nil { + fmt.Println(err) + return + } + + syncdir, err := config.GetString("local", "syncdir") + cachedir, err := config.GetString("local", "cachedir") + + fmt.Println(syncdir) + fmt.Println(cachedir) + fmt.Println(storage) + + setup_watchers() +} + +func setup_watchers() { + watcher, err := fsnotify.NewWatcher() + if err != nil { + fmt.Println("Failed to create fsnotify watcher") + return + } + fmt.Println("Created new fsnotify watcher!") + + err = watcher.Watch("/home/aclindsa/.asink") + if err != nil { + fmt.Println("Failed to watch /home/aclindsa/.asink") + return + } + + for { + select { + case ev := <-watcher.Event: + fmt.Println("event:", ev) + hash, err := HashFile(ev.Name) + //TODO if creating a directory, start watching it (and then initiate a full scan of it so we're sure nothing slipped through the cracks) + if err != nil { + fmt.Println(err) + } else { + fmt.Println(hash) + } + case err := <-watcher.Error: + fmt.Println("error:", err) + } + } +} diff --git a/hash.go b/hash.go new file mode 100644 index 0000000..69047b1 --- /dev/null +++ b/hash.go @@ -0,0 +1,21 @@ +package main + +import ( + "io" + "os" + "fmt" + "crypto/sha256" +) + +func HashFile(filename string) (string, error) { + hashfn := sha256.New() + + infile, err := os.Open(filename) + if err != nil { return "", err } + defer infile.Close() + + _, err = io.Copy(hashfn, infile) + if err != nil { return "", err } + + return fmt.Sprintf("%x", hashfn.Sum(nil)), nil +} diff --git a/storage.go b/storage.go new file mode 100644 index 0000000..ff0aab4 --- /dev/null +++ b/storage.go @@ -0,0 +1,32 @@ +package main + +import ( + "errors" + "code.google.com/p/goconf/conf" +) + +type Storage interface { + Put(filename string, hash string) error + Get(filename string, hash string) error +} + +func GetStorage(config *conf.ConfigFile) (*Storage, error) { + storageMethod, err := config.GetString("storage", "method") + if err != nil { + return nil, errors.New("Error: storage method not specified in config file.") + } + + var storage Storage + + switch storageMethod { + case "local": + storage, err = NewLocalStorage(config) + if err != nil { + return nil, err + } + default: + return nil, errors.New("Error: storage method '" + storageMethod + "' not implemented.") + } + + return &storage, nil +} diff --git a/storage_local.go b/storage_local.go new file mode 100644 index 0000000..c5432ce --- /dev/null +++ b/storage_local.go @@ -0,0 +1,69 @@ +package main + +import ( + "os" + "io" + "io/ioutil" + "path" + "errors" + "code.google.com/p/goconf/conf" +) + +type LocalStorage struct { + storageDir string + tmpSubdir string +} + +func NewLocalStorage(config *conf.ConfigFile) (*LocalStorage, error) { + storageDir, err := config.GetString("storage", "dir") + if err != nil { + return nil, errors.New("Error: LocalStorage indicated in config file, but lacking local storage directory ('dir = some/dir').") + } + + ls := new(LocalStorage) + ls.storageDir = storageDir + ls.tmpSubdir = path.Join(storageDir, ".asink-tmpdir") + return ls, nil +} + +func (ls *LocalStorage) copyToTmp(src string) (string, error) { + infile, err := os.Open(src) + if err != nil { return "", err } + defer infile.Close() + + outfile, err := ioutil.TempFile(ls.tmpSubdir, "asink") + if err != nil { return "", err } + defer outfile.Close() + + _, err = io.Copy(outfile, infile) + if err != nil { return "", err } + + return outfile.Name(), nil +} + +func (ls *LocalStorage) Put(filename string, hash string) (e error) { + tmpfile, err := ls.copyToTmp(filename) + if err != nil { return err } + defer func() { + err := os.Remove(tmpfile) + if err != nil && e == nil { e = err } + }() + + err = os.Rename(tmpfile, path.Join(ls.storageDir, hash)) + + return nil +} + +func (ls *LocalStorage) Get(filename string, hash string) error { + infile, err := os.Open(path.Join(ls.storageDir, hash)) + if err != nil { return err } + defer infile.Close() + + outfile, err := os.Open(filename) + if err != nil { return err } + defer outfile.Close() + + _, err = io.Copy(outfile, infile) + + return err +}