Beispiel #1
0
func main() {
	fmt.Println("Download Start.")
	client := &http.Client{}

	service, err := drive.New(client)
	if err != nil {
		log.Fatalf("Unable to create Drive service: %v", err)
		return
	}

	if err := os.MkDirAll(filepath.Dir(*outputPath), 0755); err != nil {
		log.Fatalf("Unable to make Directory: %v", err)
		return
	}

	fd, err := os.Create(*outputPath)
	if err != nil {
		log.Fatalf("Unable to create File: %v", err)
		return
	}
	defer fd.Close()

	res, err := service.Files.Get(*fileId).Download()
	if err != nil {
		log.Fatalf("Unable to download File: %v", err)
		return
	}
	defer res.Body.Close()
	bytes, err := io.Copy(fd, res.Body)
	if err != nil {
		log.Fatalf("Unable to io Copy: %v", err)
		return
	}
	fmt.Println("Download Finish.")
}
Beispiel #2
0
func NewRemoteContext(context *config.Context) *Remote {
	client := newOAuthClient(context)
	service, _ := drive.New(client)
	progressChan := make(chan int)
	return &Remote{
		progressChan: progressChan,
		service:      service,
		client:       client,
	}
}
Beispiel #3
0
// New initiates a new DriveService. parentId is the ID of the directory
// that will be used as the current directory in methods on the returned
// DriveService (such as Get). If empty, it defaults to the root of the
// drive.
func New(oauthClient *http.Client, parentId string) (*DriveService, error) {
	apiservice, err := client.New(oauthClient)
	if err != nil {
		return nil, err
	}
	if parentId == "" {
		// because "root" is known as a special alias for the root directory in drive.
		parentId = "root"
	}
	service := &DriveService{client: oauthClient, apiservice: apiservice, parentId: parentId}
	return service, err
}
Beispiel #4
0
func setupClients(client *http.Client) {
	var err error

	loginClient = client

	oauthSvc, err = oauth.New(client)
	if err != nil {
		log.Fatalf("Unable to create OAuth service: %v", err)
	}

	drvSvc, err = drive.New(client)
	if err != nil {
		log.Fatalf("Unable to create Drive service: %v", err)
	}
}
Beispiel #5
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)
}
Beispiel #6
0
func AppendLog(msg string) {
	ctx := context.Background()

	b, err := ioutil.ReadFile("client_secret.json")
	if err != nil {
		log.Fatalf("Unable to read client secret file: %v", err)
	}

	config, err := google.ConfigFromJSON(b, drive.DriveScope)
	if err != nil {
		log.Fatalf("Unable to parse client secret file to config: %v", err)
	}
	client := getClient(ctx, config)

	srv, err := drive.New(client)
	if err != nil {
		log.Fatalf("Unable to retrieve drive Client %v", err)
	}

	children, err := GetLog(srv, "0B14gQeVTanyZfnhwalk2OG9UVHVucHhLOE44ZHlySnpIM0FvdmYzMjNiOUZVVjEySzBzZk0")
	if err != nil {
		fmt.Println(err)
	}
	if children != nil {
		fileId := children.Id
		content, err := GetFile(srv, client, fileId)
		if err != nil {
			fmt.Println(err)
			return
		}
		content = content + "\n" + msg
		// remove redundant empty line
		reBlank := regexp.MustCompile(`([ \t]*\n){2,}`)
		output := reBlank.ReplaceAllLiteralString(content, "\n")
		UpdateFile(srv, fileId, output)
	} else {
		// create a new file
		f := &drive.File{Title: ThisWeek(), MimeType: "text/plain"}
		p := &drive.ParentReference{Id: "0B14gQeVTanyZfnhwalk2OG9UVHVucHhLOE44ZHlySnpIM0FvdmYzMjNiOUZVVjEySzBzZk0"}
		f.Parents = []*drive.ParentReference{p}
		_, err := srv.Files.Insert(f).Media(bytes.NewReader([]byte(msg))).Do()
		if err != nil {
			fmt.Printf("An error occurred: %v\n", err)
		}
	}
}
Beispiel #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
}
Beispiel #8
0
func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	runtime.SetBlockProfileRate(1)
	ctx := context.Background()

	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 = getClient(ctx, drive.DriveReadonlyScope)
	} else {
		client = getClient(ctx, 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)
	}
}