Example #1
0
func processLocalEvent_Upper(globals *AsinkGlobals, event *asink.Event, latestLocal *asink.Event, absolutePath string) error {
	if latestLocal != nil {
		event.Predecessor = latestLocal.Hash

		if event.Timestamp < latestLocal.Timestamp {
			fmt.Printf("trying to send event older than latestLocal:\n")
			fmt.Printf("OLD %+v\n", latestLocal)
			fmt.Printf("NEW %+v\n", event)
		}
	}

	if event.IsUpdate() {
		//copy to tmp
		//TODO upload in chunks and check modification times to make sure it hasn't been changed instead of copying the whole thing off
		tmpfilename, err := util.CopyToTmp(absolutePath, globals.tmpDir)
		if err != nil {
			//bail out if the file we are trying to upload already got deleted
			if util.ErrorFileNotFound(err) {
				event.LocalStatus |= asink.DISCARDED
				return nil
			}
			return err
		}

		//try to collect the file's permissions
		fileinfo, err := os.Stat(absolutePath)
		if err != nil {
			//bail out if the file we are trying to upload already got deleted
			if util.ErrorFileNotFound(err) {
				event.LocalStatus |= asink.DISCARDED
				return nil
			}
			return ProcessingError{PERMANENT, err}
		} else {
			event.Permissions = fileinfo.Mode()
		}

		//get the file's hash
		hash, err := HashFile(tmpfilename)
		if err != nil {
			return ProcessingError{TEMPORARY, err}
		}
		event.Hash = hash

		//If the hash is the same, don't try to upload the event again
		if latestLocal != nil && event.Hash == latestLocal.Hash {
			os.Remove(tmpfilename)
			//If neither the file contents nor permissions changed, squash this event completely
			if event.Permissions == latestLocal.Permissions {
				event.LocalStatus |= asink.DISCARDED
				return nil
			}
		} else {
			//rename to local cache w/ filename=hash
			cachedFilename := path.Join(globals.cacheDir, event.Hash)
			err = os.Rename(tmpfilename, cachedFilename)
			if err != nil {
				err = os.Remove(tmpfilename)
				if err != nil {
					return ProcessingError{PERMANENT, err}
				}
				return ProcessingError{PERMANENT, err}
			}
		}
	} else {
		//if we're trying to delete a file that we thought was already deleted, there's no need to delete it again
		if latestLocal != nil && latestLocal.IsDelete() {
			event.LocalStatus |= asink.DISCARDED
			return nil
		}
	}
	return nil
}