Exemple #1
0
// Lists all of the client's GDrive Folders by Id.
func ListGDriveFolders(client *http.Client) {
	service, _ := drive.New(client)

	folder_query := "mimeType = 'application/vnd.google-apps.folder'"
	files_list, err := service.Files.List().MaxResults(1000).Q(folder_query).Do()
	if err != nil {
		panic(fmt.Sprintf("error listing folders: %v", err))
	}
	for _, file := range files_list.Items {
		fmt.Println("Id:", file.Id, " Title:", file.Title)
	}
}
Exemple #2
0
func main() {
	flag.Parse()

	config.Scope = drive.DriveScope
	config.ClientId = valueOrFileContents(*clientId, *clientIdFile)
	config.ClientSecret = valueOrFileContents(*secret, *secretFile)

	client := getOAuthClient(config)
	service, _ := drive.New(client)

	// Get the ID here
	driveFiles, folderId := getDriveFilesByFolder(service, *driveFolder)
	localFiles := getLocalFiles(*localFolder)

	toSync := mergeFolders(driveFiles, localFiles)

	// Synchronization
	fmt.Printf("Synchronizing %v files", len(toSync))

	work := make(chan uploadRequest, 1)
	done := make(chan bool, len(toSync))
	for i := 0; i < 3; i++ {
		go uploadWorker(service, work, done)
	}

	total := len(toSync)
	for _, file := range toSync {
		goFile, err := os.Open(file.filename)
		if err != nil {
			log.Fatalf("Could not open file %s: %s", file.filename, err)
		}
		driveFile := drive.File{
			Title: file.base,
			Parents: []*drive.ParentReference{
				&drive.ParentReference{Id: folderId},
			},
		}

		work <- uploadRequest{&driveFile, goFile, file.filename}
		total = total - 1
		log.Printf("%d files left to sync", total)
	}

	for _, _ = range toSync {
		<-done
	}
	log.Printf("Done synchronizing!")
}
Exemple #3
0
func driveMain(client *http.Client, argv []string) {
	if len(argv) != 1 {
		fmt.Fprintln(os.Stderr, "Usage: drive filename (to upload a file)")
		return
	}

	service, _ := drive.New(client)
	filename := argv[0]

	goFile, err := os.Open(filename)
	if err != nil {
		log.Fatalf("error opening %q: %v", filename, err)
	}
	driveFile, err := service.Files.Insert(&drive.File{Title: filename}).Media(goFile).Do()
	log.Printf("Got drive.File, err: %#v, %v", driveFile, err)
}
Exemple #4
0
func main() {
	var directory *string = flag.String(
		"directory",
		"/home/mrjones/scans",
		"Directory to (recursively) upload.")

	flag.Parse()

	configFile, err := parseConfigFile("config.json")
	if err != nil {
		log.Fatal(err)
	}

	httpClient, err := authorize(configFile)
	if err != nil {
		log.Fatal(err)
	}

	service, err := drive.New(httpClient)
	if err != nil {
		log.Fatal(err)
	}

	// Code to list files, just to test that things work
	//	res, err := service.Files.List().Do()
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//
	//	for _, f := range res.Items {
	//		fmt.Printf("%s (%s)\n", f.Id, f.Title);
	//	}

	//	err = uploadFile(service, "/home/mrjones/gocrtest.jpg")
	//	if err != nil {
	//		log.Fatal(err)
	//	}

	err = uploadDirectory(service, *directory, &AlwaysTrue{})
	if err != nil {
		log.Fatal(err)
	}
}
Exemple #5
0
func UploadFiles(config ScanServerConfig,
	files_to_upload_chan chan FileForUpload,
	files_done_chan chan FileForUpload) {
	client := getOAuthClient(config)
	service, _ := drive.New(client)

	for file_for_upload := range files_to_upload_chan {
		go_file, err := os.Open(FullPath(file_for_upload))
		if err != nil {
			panic(fmt.Sprintf("error opening file: %v", err))
		}

		file_meta := &drive.File{
			Title:    UploadTitle(file_for_upload),
			MimeType: "application/pdf"}

		// Set the parent folder so that these files don't just get uploaded into
		// the root directory.
		parent := &drive.ParentReference{Id: config.RemoteParentFolderId}
		file_meta.Parents = []*drive.ParentReference{parent}

		_, err = service.Files.Insert(file_meta).Media(go_file).Do()
		if err != nil {
			panic(fmt.Sprintf("error uploading file: %v", err))
		}

		modified_time := ModifyTimeOrPanic(FullPath(file_for_upload))
		if config.LastProccessedScanTime.Before(modified_time) {
			config.LastProccessedScanTime = modified_time
			WriteConfig(*config_file, config)
		}

		files_done_chan <- file_for_upload
	}
	close(files_done_chan)
}
Exemple #6
0
func NewRemoteContext(context *config.Context) *Remote {
	transport := newTransport(context)
	service, _ := drive.New(transport.Client())
	return &Remote{service: service, transport: transport}
}
Exemple #7
0
// NewDriveDB creates a new DriveDB and starts syncing metadata.
func NewDriveDB(client *http.Client, dbPath, cachePath string, pollInterval time.Duration, rootId string) (*DriveDB, error) {
	svc, _ := gdrive.New(client)
	_, err := svc.About.Get().Do()
	if err != nil {
		log.Fatalf("drive.service.About.Get().Do: %v\n", err)
	}

	if *debugDriveDB {
		debug = true
	}

	ldbPath := path.Join(dbPath, "meta")
	log.Printf("using db path: %q", ldbPath)
	err = os.MkdirAll(ldbPath, 0700)
	if err != nil {
		return nil, fmt.Errorf("could not create directory %q", ldbPath)
	}

	log.Printf("using cache path: %q", cachePath)
	err = os.MkdirAll(cachePath, 0700)
	if err != nil {
		return nil, fmt.Errorf("could not create directory %q", cachePath)
	}

	db, err := openLevelDB(ldbPath)
	if err != nil {
		return nil, err
	}

	d := &DriveDB{
		client:       client,
		service:      svc,
		db:           db,
		dbpath:       ldbPath,
		data:         cachePath,
		lruCache:     lru.New(*inodeCacheSize),
		changes:      make(chan *gdrive.ChangeList, 200),
		pollInterval: pollInterval,
		rootId:       rootId,
		driveSize:    (*driveCacheChunk) * (*driveCacheChunks),                     // ensure drive reads are always a multiple of cache size
		cacheBlocks:  (*cacheSize) * ((*driveCacheChunks) * (*prefetchMultiplier)), // enough blocks for readahead
		pfetchq:      make(chan DownloadSpec, 20000),
		pfetchmap:    make(map[string]bool),
	}

	log.Printf("%d cache blocks of %d bytes", d.cacheBlocks, *driveCacheChunk)

	// Get saved checkpoint.
	err = d.get(internalKey("checkpoint"), &d.cpt)
	if err != nil {
		log.Printf("error reading checkpoint: %v", err)
		d.cpt = NewCheckpoint()
	}
	if d.cpt.Version < checkpointVersion {
		log.Printf("checkpoint version invalid, require %v but found %v", checkpointVersion, d.cpt.Version)
		err = d.reinit()
		if err != nil {
			log.Printf("Failed to reinitialize the database: %v", err)
			log.Fatal("You should probably run: rm -rf %v", ldbPath)
		}
	}
	err = d.writeCheckpoint(nil)
	if err != nil {
		return nil, fmt.Errorf("could not write checkpoint: %v", err)
	}
	debug.Printf("Recovered from checkpoint: %+v", d.cpt)

	if err := d.createRoot(); err != nil {
		return nil, fmt.Errorf("could not create root inode entry: %v", err)
	}

	d.synced = sync.NewCond(&d.syncmu)

	go d.sync()
	go d.pollForChanges()
	if debug {
		registerDebugHandles(*d) // in http_handlers.go
	}

	for i := 0; i < *prefetchWorkers; i++ {
		go d.prefetcher()
	}
	return d, nil
}
Exemple #8
0
func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	runtime.SetBlockProfileRate(1)

	flag.Usage = Usage
	flag.Parse()

	if flag.NArg() != 1 {
		Usage()
		os.Exit(2)
	}
	mountpoint := flag.Arg(0)

	if *debugGdrive {
		debug = true
	}

	userCurrent, err := user.Current()
	if err != nil {
		log.Fatalf("unable to get UID/GID of current user: %v", err)
	}
	uidInt, err := strconv.Atoi(userCurrent.Uid)
	if err != nil {
		log.Fatalf("unable to get UID/GID of current user: %v", err)
	}
	uid := uint32(uidInt)
	gidInt, err := strconv.Atoi(userCurrent.Gid)
	if err != nil {
		log.Fatalf("unable to get UID/GID of current user: %v", err)
	}
	gid := uint32(gidInt)

	if err = sanityCheck(mountpoint); err != nil {
		log.Fatalf("sanityCheck failed: %s\n", err)
	}

	http.HandleFunc("/", RootHandler)
	go http.ListenAndServe(fmt.Sprintf("localhost:%s", *port), nil)

	var client *http.Client
	if *readOnly {
		client = getOAuthClient(drive.DriveReadonlyScope)
	} else {
		client = getOAuthClient(drive.DriveScope)
	}

	driveCache := cache.NewCache("/tmp", client)

	// TODO: move into drivedb, so we don't create a service twice
	service, _ := drive.New(client)
	about, err := service.About.Get().Do()
	if err != nil {
		log.Fatalf("drive.service.About.Get().Do: %v\n", err)
	}
	// fileId of the root of the FS (aka "My Drive")
	rootId := about.RootFolderId
	// email address of the mounted google drive account
	account := about.User.EmailAddress

	// Ensure the token's always fresh
	// TODO: Remove this once goauth2 changes are accepted upstream
	// https://code.google.com/p/goauth2/issues/detail?id=47
	go tokenKicker(client, 59*time.Minute)

	// Create and start the drive metadata syncer.
	db, err := drive_db.NewDriveDB(client, *dbDir, *cacheDir, *driveMetadataLatency, rootId)
	if err != nil {
		log.Fatalf("could not open leveldb: %v", err)
	}
	defer db.Close()
	db.WaitUntilSynced()
	log.Printf("synced!")

	options := []fuse.MountOption{
		fuse.FSName("GoogleDrive"),
		fuse.Subtype("gdrive"),
		fuse.VolumeName(account),
	}

	if *allowOther {
		options = append(options, fuse.AllowOther())
	}
	if *readOnly {
		options = append(options, fuse.ReadOnly())
	}
	c, err := fuse.Mount(mountpoint, options...)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	// Trap control-c (sig INT) and unmount
	sig := make(chan os.Signal, 1)
	signal.Notify(sig, os.Interrupt)
	go func() {
		for _ = range sig {
			if err := fuse.Unmount(mountpoint); err != nil {
				log.Printf("fuse.Unmount failed: %v", err)
			}
		}
	}()

	sc := serveConn{db: db,
		driveCache: driveCache,
		service:    service,
		uid:        uid,
		gid:        gid,
		writers:    make(map[int]io.PipeWriter),
		conn:       c,
	}
	err = sc.Serve()
	if err != nil {
		log.Fatalln("fuse server failed: ", err)
	}

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		log.Fatal(err)
	}
}