Example #1
0
// New creates and returns a new *Spooler.
func New(dbPath, destination, errorPath string, noop bool) (*Spooler, error) {
	sp := new(Spooler)
	sp.noop = noop

	if !file.Exists(destination) {
		if _, err := os.Create(destination); err != nil {
			return nil, err
		}
	}
	sp.Destination = destination

	if !file.Exists(errorPath) {
		if _, err := os.Create(errorPath); err != nil {
			return nil, err
		}
	}
	sp.ErrorPath = errorPath

	if sp.noop {
		sp.database = db.NewNoopDb()
	} else {
		database, err := db.NewMapFileDb(dbPath)
		if err != nil {
			return nil, err
		}
		sp.database = database
	}

	sp.closed = false
	return sp, nil
}
Example #2
0
// load deserializes the md5 json database from the given filePath.
func load(path string) (map[string][]string, error) {
	var db map[string][]string

	if file.Exists(path) {
		json_bytes, err := ioutil.ReadFile(path)
		if err != nil {
			return db, err
		}

		err = json.Unmarshal(json_bytes, &db)
		if err != nil {
			return db, err
		}
	} else {
		db = make(map[string][]string)
	}

	return db, nil
}
Example #3
0
// Spool copies the photo given by filename to the correct directory with the correct name.
func (sp *Spooler) Spool(filename string) error {
	if sp.closed {
		return fmt.Errorf("This Spooler is already closed.")
	}

	// calculate an md5 sum for the file
	hash := getHash(filename)

	// get the Time from the DateTimeOriginal exif tag
	dateTime, err := getDateTime(filename)
	if err != nil {
		log.Printf("Could not read the DateTimeOriginal tag. %v", err)
		log.Printf("Moving %s to %s.\n", filename, sp.ErrorPath)
		if sp.noop {
			log.Println("DRY RUN Skipping move file.")
		} else if mverr := file.MoveTo(sp.ErrorPath, filename); mverr != nil {
			log.Fatal(mverr)
		}
		return err
	}

	// check if the hash already exists in the db
	if sp.database.ContainsKey(hash) {
		msg := "A db entry already exists for " + filename + "."
		errorName := filepath.Join(sp.ErrorPath, strings.Join([]string{filepath.Base(filename), "DUPLICATE"}, "."))
		log.Printf("Mv(%s, %s)\n", errorName, filename)
		if sp.noop {
			log.Println("DRY RUN Skipping move file.")
		} else {
			err := file.Mv(errorName, filename)
			if err != nil {
				return err
			}
		}
		return errors.New(msg)
	}

	// calculate the path to copy the file to, including a new file name
	newPath := sp.getDestination(filename, sp.Destination, dateTime)

	// ensure the new path doesn't already exist
	for file.Exists(newPath) {
		dateTime = dateTime.Add(1 * time.Second)
		newPath = sp.getDestination(filename, sp.Destination, dateTime)
	}

	log.Printf("Mv(%s, %s)\n", newPath, filename)
	if file.Exists(newPath) {
		fields := strings.Split(filepath.Base(filename), ".")
		errorName := filepath.Join(sp.ErrorPath, strings.Join([]string{fields[0], filepath.Base(newPath)}, "::"))
		if sp.noop {
			log.Println("DRY RUN Skipping move file.")
		} else {
			err := file.Mv(errorName, filename)
			if err != nil {
				log.Println(err)
				return err
			}
		}
		msg := "A file with that named " + newPath + " already exists at the destination.  Moving to " + errorName
		log.Println(msg) // TODO This logging sucks.
		// TODO send an e-mail.
		return errors.New(msg)
	}

	// move the file to its new home
	if sp.noop {
		log.Println("DRY RUN Skipping move file.")
	} else if err := file.Mv(newPath, filename); err != nil {
		log.Println(err)
		return err
	}

	// add an entry to the hashmap db
	if err := sp.database.Insert(newPath, hash); err != nil {
		return err // TODO plain errors suck...
	}

	return nil
}