Skip to content
This repository has been archived by the owner on Sep 6, 2023. It is now read-only.

Commit

Permalink
Add document, example
Browse files Browse the repository at this point in the history
  • Loading branch information
canhlinh committed Nov 4, 2018
1 parent cd8d886 commit b5a55d8
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 12 deletions.
62 changes: 59 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# gphoto
# GPHOTO
A small lib to upload files to the google photo

[![GoDoc](https://godoc.org/github.com/canhlinh/gphoto?status.svg)](http://godoc.org/github.com/canhlinh/gphoto)

#### Features
# Features
- Uploads file to google photo account via user's cookies, via user's credential (user, pass).
- Update upload's progress while a file is uploading.

#### How to use
# Getting Started

If you want to login to google automaticaly, you have to install ChromeDriver first.
See more about ChromeDrive at https://sites.google.com/a/chromium.org/chromedriver/
Expand All @@ -16,3 +16,59 @@ I'm not ensure the code can work smoothy. Use at your own risk.
July 14 2018, This code still can work well.

You can take a look at the test code to get some example.

## Install
```
go get -u github.com/jinzhu/gorm
```

## Quick Start
```
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"github.com/canhlinh/gphoto"
)
func main() {
cookies := GetCookiesFromJSON("./json.")
client := gphoto.NewClient(cookies...)
photo, err := client.Upload("../sample_data/sample.mp4", "sample.mp4", "AnyAlbumName", progressHandler)
if err != nil {
panic(err)
}
fmt.Println(photo)
}
// GetCookiesFromJSON parse cookies from a JSON file
// The JSON file can be exported by this extension https://chrome.google.com/webstore/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg
func GetCookiesFromJSON(path string) []*http.Cookie {
file, err := os.Open(path)
if err != nil {
panic(err)
}
var cookies []*http.Cookie
json.NewDecoder(file).Decode(&cookies)
return cookies
}
func progressHandler(current int64, total int64) {
fmt.Printf("current %d , total %d ", current, total)
}
```

## Run test

Exports your google photo into an variable GPHOTO_COOKIES_BASE64.
Run test:
```
go test -v -race
```
13 changes: 11 additions & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ func (c *Client) SetHTTPClient(hClient *http.Client) *Client {
return c
}

// Login login to google photo with your authentication info.
func (c *Client) Login(user, pass string) error {
log.Info("Request to login")

Expand Down Expand Up @@ -317,6 +318,7 @@ func (c *Client) enableUploadedFile(uploadBase64Token, fileName string, fileModA
return photoID, photoURL, nil
}

// DoQuery executes http request
func (client *Client) DoQuery(endpoint string, query string) (io.ReadCloser, error) {
if err := client.parseAtToken(); err != nil {
return nil, err
Expand All @@ -340,6 +342,7 @@ func (client *Client) DoQuery(endpoint string, query string) (io.ReadCloser, err
return res.Body, nil
}

// GetAlbums gets all google photo albums
func (client *Client) GetAlbums() (Albums, error) {
log.Info("Request to get albums")
query := fmt.Sprintf(`[[["Z5xsfc","[null,null,null,null,2,2]",null,"generic"]]]`)
Expand All @@ -355,6 +358,7 @@ func (client *Client) GetAlbums() (Albums, error) {
return albumlResponse.Albums()
}

// SearchOrCreteaAlbum creates an album if the album name doesn't exist
func (c *Client) SearchOrCreteaAlbum(name string, photoID string) (*Album, error) {
albums, err := c.GetAlbums()
if err != nil {
Expand All @@ -370,6 +374,7 @@ func (c *Client) SearchOrCreteaAlbum(name string, photoID string) (*Album, error
return c.CreateAlbum(name, photoID)
}

// CreateAlbum creates a new album
func (c *Client) CreateAlbum(albumName string, photoID string) (*Album, error) {
log.Info("Request to create new album %v with photo's id %s \n", albumName, photoID)

Expand Down Expand Up @@ -399,8 +404,9 @@ func (c *Client) CreateAlbum(albumName string, photoID string) (*Album, error) {
return &album, nil
}

func (client *Client) GetSharedAlbumKey(albumID string) string {
res, _ := client.hClient.Get(fmt.Sprintf("https://photos.google.com/u/0/album/%s", albumID))
// GetSharedAlbumKey gets an album's share key
func (c *Client) GetSharedAlbumKey(albumID string) string {
res, _ := c.hClient.Get(fmt.Sprintf("https://photos.google.com/u/0/album/%s", albumID))
if res.StatusCode != 200 {
return ""
}
Expand All @@ -420,6 +426,7 @@ func (client *Client) GetSharedAlbumKey(albumID string) string {
return sharedKey
}

// AddPhotoToAlbum adds a photo to an album
func (c *Client) AddPhotoToAlbum(albumID, photoID string) error {
log.Info("Request to add photo %s to album %s", photoID, albumID)
sharedAlbumKey := c.GetSharedAlbumKey(albumID)
Expand All @@ -441,6 +448,7 @@ func (c *Client) AddPhotoToAlbum(albumID, photoID string) error {
return nil
}

// RemoveFromAlbum Remove a photo from an album
func (c *Client) RemoveFromAlbum(photoID string) error {
log.Info("Request to remove photo %s from the relevant album", photoID)

Expand All @@ -460,6 +468,7 @@ func (c *Client) RemoveFromAlbum(photoID string) error {
return nil
}

// moveToAlbum move a photo to an album
func (c *Client) moveToAlbum(albumName string, photoID string) (*Photo, error) {
log.Info("Request to move the upload file to the album %s", albumName)

Expand Down
21 changes: 14 additions & 7 deletions client_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gphoto

import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
Expand All @@ -12,6 +13,7 @@ import (
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

const (
Expand Down Expand Up @@ -39,13 +41,18 @@ func GenNewSampleFile(orginalPath string) string {
return filePath
}

func GetTestCookies() []*http.Cookie {
file, err := os.Open(CookieJsonFile)
if err != nil {
panic(err)
func getTestCookiesFromENV(t testing.TB) []*http.Cookie {
photoCookiesBase64 := os.Getenv("GPHOTO_COOKIES_BASE64")
if photoCookiesBase64 == "" {
t.Fatal("ENV GPHOTO_COOKIES_BASE64 can not be empty")
}
photoCookies, err := base64.URLEncoding.DecodeString(photoCookiesBase64)
require.NoError(t, err)

var cookies []*http.Cookie
json.NewDecoder(file).Decode(&cookies)
if err := json.Unmarshal([]byte(photoCookies), &cookies); err != nil {
t.Log(err)
}
return cookies
}

Expand All @@ -54,7 +61,7 @@ func TestUpload(t *testing.T) {
sampleFile := GenNewSampleFile("./sample_data/sample.mp4")
defer os.Remove(sampleFile)

client := NewClient(GetTestCookies()...)
client := NewClient(getTestCookiesFromENV(t)...)

t.Run("UploadSuccessWithoutProgressHandler", func(t *testing.T) {
photo, err := client.Upload(sampleFile, "sample.mp4", "", nil)
Expand Down Expand Up @@ -112,7 +119,7 @@ func BenchmarkReUpload(b *testing.B) {
sampleFile := GenNewSampleFile("./sample_data/sample.mp4")
defer os.Remove(sampleFile)

client := NewClient(GetTestCookies()...)
client := NewClient(getTestCookiesFromENV(b)...)

if _, err := client.Upload(sampleFile, "", "", nil); err != nil {
b.Fatal(err)
Expand Down
39 changes: 39 additions & 0 deletions examples/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"encoding/json"
"fmt"
"net/http"
"os"

"github.com/canhlinh/gphoto"
)

func main() {

cookies := GetCookiesFromJSON("./json.")
client := gphoto.NewClient(cookies...)

photo, err := client.Upload("../sample_data/sample.mp4", "sample.mp4", "AnyAlbumName", progressHandler)
if err != nil {
panic(err)
}
fmt.Println(photo)
}

// GetCookiesFromJSON parse cookies from a JSON file
// The JSON file can be exported by this extension https://chrome.google.com/webstore/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg
func GetCookiesFromJSON(path string) []*http.Cookie {
file, err := os.Open(path)
if err != nil {
panic(err)
}

var cookies []*http.Cookie
json.NewDecoder(file).Decode(&cookies)
return cookies
}

func progressHandler(current int64, total int64) {
fmt.Printf("current %d , total %d ", current, total)
}
17 changes: 17 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module github.com/canhlinh/gphoto

require (
github.com/PuerkitoBio/goquery v1.4.1
github.com/andybalholm/cascadia v1.0.0 // indirect
github.com/canhlinh/log4go v0.0.0-20171123040613-fb8d218825e0
github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/getsentry/raven-go v0.1.0 // indirect
github.com/onsi/gomega v1.4.2 // indirect
github.com/peterbourgon/g2s v0.0.0-20170223122336-d4e7ad98afea // indirect
github.com/pkg/errors v0.8.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sclevine/agouti v3.0.0+incompatible
github.com/stretchr/testify v1.2.2
golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc
)
50 changes: 50 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
github.com/PuerkitoBio/goquery v1.4.1 h1:smcIRGdYm/w7JSbcdeLHEMzxmsBQvl8lhf0dSw2nzMI=
github.com/PuerkitoBio/goquery v1.4.1/go.mod h1:T9ezsOHcCrDCgA8aF1Cqr3sSYbO/xgdy8/R/XiIMAhA=
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/canhlinh/log4go v0.0.0-20171123040613-fb8d218825e0 h1:rzkyamwkQaaXsPCS2pklGFonmmYhi1etjOiv1J2FsfE=
github.com/canhlinh/log4go v0.0.0-20171123040613-fb8d218825e0/go.mod h1:jZt4nDOAX1J2RcvFolWaw/n/ptBzMjthdwiYyTRCsGw=
github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2 h1:MmeatFT1pTPSVb4nkPmBFN/LRZ97vPjsFKsZrU3KKTs=
github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/getsentry/raven-go v0.1.0 h1:lc5jnN9D+q3panDpihwShgaOVvP6esoMEKbID2yhLoQ=
github.com/getsentry/raven-go v0.1.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/peterbourgon/g2s v0.0.0-20170223122336-d4e7ad98afea h1:sKwxy1H95npauwu8vtF95vG/syrL0p8fSZo/XlDg5gk=
github.com/peterbourgon/g2s v0.0.0-20170223122336-d4e7ad98afea/go.mod h1:1VcHEd3ro4QMoHfiNl/j7Jkln9+KQuorp0PItHMJYNg=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sclevine/agouti v3.0.0+incompatible h1:8IBJS6PWz3uTlMP3YBIR5f+KAldcGuOeFkFbUWfBgK4=
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc h1:ZMCWScCvS2fUVFw8LOpxyUUW5qiviqr4Dg5NdjLeiLU=
golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

0 comments on commit b5a55d8

Please sign in to comment.