├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── LICENSE
├── README.md
├── cmd
└── gdown
│ ├── cli.go
│ └── main.go
├── go.mod
├── go.sum
├── internal
├── helpers
│ ├── auth
│ │ ├── client.go
│ │ └── token.go
│ └── webscraping
│ │ └── webscraping.go
├── process
│ ├── account.go
│ └── functions.go
└── utils
│ ├── clienthttp.go
│ ├── output.go
│ └── utils.go
├── module.go
└── pkg
└── gdriveapi
├── files.go
└── permissions.go
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | tags:
4 | - 'v*'
5 |
6 | name: Build & Upload Release Asset
7 |
8 | jobs:
9 | build:
10 | name: Build & Upload Release Asset
11 | runs-on: ubuntu-latest
12 | steps:
13 |
14 | - name: Set up Go 1.13
15 | uses: actions/setup-go@v1
16 | with:
17 | go-version: 1.13
18 | id: go
19 |
20 | - name: Check out code into the Go module directory
21 | uses: actions/checkout@v2
22 |
23 | - name: Get dependencies
24 | run: |
25 | go get -v -t -d ./...
26 | if [ -f Gopkg.toml ]; then
27 | curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
28 | dep ensure
29 | fi
30 |
31 | - name: Get the version
32 | id: get_version
33 | run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
34 |
35 | - name: Building
36 | run: |
37 | GOOS=darwin GOARCH=amd64 go build -v -o gdown ./cmd/gdown/
38 | zip --junk-paths gdown_${{ steps.get_version.outputs.VERSION }}_macos.zip gdown
39 |
40 | GOOS=windows GOARCH=386 go build -v -o gdown.exe ./cmd/gdown/
41 | zip --junk-paths gdown_${{ steps.get_version.outputs.VERSION }}_windows-x86.zip gdown.exe
42 |
43 | GOOS=windows GOARCH=amd64 go build -v -o gdown.exe ./cmd/gdown/
44 | zip --junk-paths gdown_${{ steps.get_version.outputs.VERSION }}_windows-x64.zip gdown.exe
45 |
46 | GOOS=linux GOARCH=amd64 go build -v -o gdown ./cmd/gdown/
47 | zip --junk-paths gdown_${{ steps.get_version.outputs.VERSION }}_linux-x64.zip gdown
48 |
49 | - name: Create Release
50 | id: create_release
51 | uses: actions/create-release@v1
52 | env:
53 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54 | with:
55 | tag_name: ${{ github.ref }}
56 | release_name: Release ${{ github.ref }}
57 | draft: false
58 | prerelease: false
59 |
60 | - name: Upload macOS Asset
61 | uses: actions/upload-release-asset@v1
62 | env:
63 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
64 | with:
65 | upload_url: ${{ steps.create_release.outputs.upload_url }}
66 | asset_path: ./gdown_${{ steps.get_version.outputs.VERSION }}_macos.zip
67 | asset_name: gdown_${{ steps.get_version.outputs.VERSION }}_macos.zip
68 | asset_content_type: application/x-msdownload
69 |
70 | - name: Upload Windows x86
71 | uses: actions/upload-release-asset@v1
72 | env:
73 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
74 | with:
75 | upload_url: ${{ steps.create_release.outputs.upload_url }}
76 | asset_path: ./gdown_${{ steps.get_version.outputs.VERSION }}_windows-x86.zip
77 | asset_name: gdown_${{ steps.get_version.outputs.VERSION }}_windows-x86.zip
78 | asset_content_type: application/x-msdownload
79 |
80 | - name: Upload Windows x64
81 | uses: actions/upload-release-asset@v1
82 | env:
83 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
84 | with:
85 | upload_url: ${{ steps.create_release.outputs.upload_url }}
86 | asset_path: ./gdown_${{ steps.get_version.outputs.VERSION }}_windows-x64.zip
87 | asset_name: gdown_${{ steps.get_version.outputs.VERSION }}_windows-x64.zip
88 | asset_content_type: application/x-msdownload
89 |
90 | - name: Upload linux x64
91 | uses: actions/upload-release-asset@v1
92 | env:
93 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
94 | with:
95 | upload_url: ${{ steps.create_release.outputs.upload_url }}
96 | asset_path: ./gdown_${{ steps.get_version.outputs.VERSION }}_linux-x64.zip
97 | asset_name: gdown_${{ steps.get_version.outputs.VERSION }}_linux-x64.zip
98 | asset_content_type: application/x-msdownload
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, built with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # Dependency directories (remove the comment below to include it)
15 | # vendor/
16 |
17 | *.txt
18 | *.json
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Juvenal Yescas
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Gdown
5 |
6 |
7 |
8 | Directly download google drive public files from the command line
9 |
10 | Explore docs »
11 |
12 |
13 | Report bug
14 | ·
15 | Request feature
16 |
17 |
18 | 
19 | [](https://github.com/Juvenal-Yescas/gdown/issues)
20 | [](https://deepsource.io/gh/Juvenal-Yescas/gdown/?ref=repository-badge)
21 | [](LICENSE)
22 |
23 | ## Table of contents
24 |
25 | - [Usage](#usage)
26 | - [Contributing](#contributing)
27 | - [License](#license)
28 | - [Acknowledgments](#acknowledgments)
29 |
30 | ## Usage
31 |
32 | Download the latest [release](https://github.com/Juvenal-Yescas/gdown/releases)
33 |
34 | ### From Command Line
35 |
36 | ```
37 | Windows
38 | gdown.exe --help
39 |
40 | macOS or linux
41 | gdown --help
42 | ```
43 |
44 | ```
45 | gdown "0B4y35FiV1wh7QWpuVlFROXlBTHc"
46 | gdown "https://drive.google.com/uc?id=0B9P1L--7Wd2vU3VUVlFnbTgtS2c"
47 | gdown "https://drive.google.com/open?id=0B7EVK8r0v71pZjFTYXZWM3FlRnM"
48 | gdown "https://drive.google.com/open?id=0B4y35FiV1wh7QWpuVlFROXlBTHc"
49 | gdown "https://drive.google.com/file/d/0B4y35FiV1wh7QWpuVlFROXlBTHc/view?usp=sharing"
50 | gdown "https://drive.google.com/file/d/0B4y35FiV1wh7QWpuVlFROXlBTHc/view"
51 | gdown "https://drive.google.com/file/d/0B65DIm6DrZJceGltX2VOczNkcEE/edit"
52 | ```
53 |
54 | ## Build with
55 |
56 | * [Go](https://golang.org/) - Programming language
57 |
58 | ## Contributing
59 |
60 | Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
61 |
62 | ## License
63 |
64 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
65 |
66 | ## Acknowledgments
67 |
68 | * [gdown](https://github.com/wkentaro/gdown)
69 |
--------------------------------------------------------------------------------
/cmd/gdown/cli.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "github.com/Juvenal-Yescas/gdown"
6 | "github.com/Juvenal-Yescas/gdown/internal/helpers/auth"
7 | "github.com/Juvenal-Yescas/gdown/internal/process"
8 | "github.com/Juvenal-Yescas/gdown/internal/utils"
9 | "os"
10 | )
11 |
12 | func cliDownload(url string) {
13 | output, err := gdown.Download(url)
14 | if err != nil {
15 | if utils.CaseInsensitiveContains(err.Error(), "exceeded") {
16 | fmt.Println("The file has exceeded the download limit, try download with your account")
17 | output, err := downloadWithAccount(url)
18 | if err != nil {
19 | fmt.Println("Error : ", err)
20 | os.Exit(1)
21 | }
22 | fmt.Println("File downloaded : ", output)
23 | os.Exit(0)
24 | }
25 | fmt.Println("Error : ", err)
26 | os.Exit(1)
27 |
28 | }
29 | fmt.Println("File downloaded: ", output)
30 | os.Exit(0)
31 | }
32 |
33 | func downloadWithAccount(url string) (string, error) {
34 | idFileUrl, err := process.GetIdFromUrl(url)
35 | if err != nil {
36 | return "", err
37 | }
38 |
39 | clientHttp := utils.CreateClientHttp()
40 | outputName, err := process.GetNameOutput(clientHttp, idFileUrl)
41 | if err != nil {
42 | return "", err
43 | }
44 |
45 | clientGDrive, err := auth.CreateClientApiDrive()
46 | if err != nil {
47 | return "", err
48 | }
49 | infoFolderDrive, infoFileDrive, err := process.CreateCopyInDrive(clientGDrive, idFileUrl, outputName)
50 | if err != nil {
51 | return "", err
52 | }
53 | fmt.Println("Downloading ... ", outputName)
54 | output, err := gdown.DownloadOutput("https://drive.google.com/uc?id="+infoFileDrive.Id, outputName)
55 | if err != nil {
56 | return "", err
57 | }
58 |
59 | err = process.CleanCopyInDrive(clientGDrive, infoFolderDrive.Id)
60 | if err != nil {
61 | return "", err
62 | }
63 |
64 | return output, nil
65 | }
66 |
--------------------------------------------------------------------------------
/cmd/gdown/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | log "github.com/sirupsen/logrus"
6 | "github.com/urfave/cli/v2"
7 | "io/ioutil"
8 | "os"
9 | )
10 |
11 | func init() {
12 | log.SetOutput(ioutil.Discard)
13 | // log.SetLevel(log.DebugLevel)
14 | }
15 |
16 | const Version = "0.1.0"
17 |
18 | func main() {
19 |
20 | cli.VersionFlag = &cli.BoolFlag{
21 | Name: "print-version", Aliases: []string{"V"},
22 | Usage: "print only the version",
23 | }
24 |
25 | app := &cli.App{
26 | Name: "gdown",
27 | Version: Version,
28 | Usage: "Download files directly from googledrive",
29 |
30 | Flags: []cli.Flag{
31 | &cli.StringFlag{
32 | Name: "url",
33 | Aliases: []string{"u"},
34 | Usage: "`\"FILEURL\"` to download from google drive ",
35 | },
36 | },
37 | Action: func(c *cli.Context) error {
38 | if c.String("url") != "" {
39 | cliDownload(c.String("url"))
40 | }
41 | if c.NArg() > 0 {
42 | link := c.Args().Get(0)
43 | cliDownload(link)
44 | }
45 | return nil
46 | },
47 | }
48 |
49 | err := app.Run(os.Args)
50 | if err != nil {
51 | log.Fatal(err)
52 | }
53 | fmt.Println("gdown --help")
54 | }
55 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/Juvenal-Yescas/gdown
2 |
3 | go 1.13
4 |
5 | require (
6 | github.com/sirupsen/logrus v1.4.2
7 | github.com/urfave/cli/v2 v2.1.1
8 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
9 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
10 | google.golang.org/api v0.19.0
11 | )
12 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3 | cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
4 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
5 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
6 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
7 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
8 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
9 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
10 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
12 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
13 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
14 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
15 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
16 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
17 | github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
18 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
19 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
20 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
21 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
22 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
23 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
24 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
25 | github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
26 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
27 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
28 | github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
29 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
30 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
31 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
32 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
33 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
34 | github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
35 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
36 | github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
37 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
38 | github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
39 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
40 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
41 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
42 | github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
43 | github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=
44 | github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
45 | go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
46 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
47 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
48 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
49 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
50 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
51 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
52 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
53 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
54 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
55 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
56 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
57 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
58 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
59 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
60 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
61 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
62 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
63 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
64 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
65 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
66 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
67 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
68 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
69 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
70 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
71 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
72 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
73 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
74 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
75 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
76 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
77 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
78 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
79 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
80 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
81 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
82 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
83 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
84 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
85 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
86 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
87 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
88 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
89 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
90 | google.golang.org/api v0.19.0 h1:GwFK8+l5/gdsOYKz5p6M4UK+QT8OvmHWZPJCnf+5DjA=
91 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
92 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
93 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
94 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
95 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
96 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
97 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
98 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
99 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
100 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
101 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
102 | google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
103 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
104 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
105 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
106 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
107 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
108 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
109 |
--------------------------------------------------------------------------------
/internal/helpers/auth/client.go:
--------------------------------------------------------------------------------
1 | // refs https://developers.google.com/drive/v3/web/quickstart/go
2 | package auth
3 |
4 | import (
5 | "github.com/Juvenal-Yescas/gdown/internal/utils"
6 | "golang.org/x/net/context"
7 | "golang.org/x/oauth2"
8 | "golang.org/x/oauth2/google"
9 | "google.golang.org/api/drive/v3"
10 | "io/ioutil"
11 | "log"
12 | "net/http"
13 | )
14 |
15 | func CreateClientApiDrive() (*drive.Service, error) {
16 | b, err := ioutil.ReadFile("credentials.json")
17 | if err != nil {
18 | log.Fatalf("Unable to read client secret file: %v", err)
19 | return nil, err
20 | }
21 |
22 | // If modifying these scopes, delete your previously saved token.json.
23 | config, err := google.ConfigFromJSON(b, drive.DriveScope)
24 | if err != nil {
25 | log.Fatalf("Unable to parse client secret file to config: %v", err)
26 | return nil, err
27 | }
28 |
29 | client := getClient(config)
30 |
31 | srv, err := drive.New(client)
32 | if err != nil {
33 | log.Fatalf("Unable to retrieve Drive client: %v", err)
34 | return nil, err
35 | }
36 | return srv, nil
37 | }
38 |
39 | // Retrieve a token, saves the token, then returns the generated client.
40 | func getClient(config *oauth2.Config) *http.Client {
41 | // The file token.json stores the user's access and refresh tokens, and is
42 | // created automatically when the authorization flow completes for the first
43 | // time.
44 |
45 | tokFile := utils.GetDefaultConfigDir() // tokFile := "token.json"
46 | tok, err := tokenFromFile(tokFile)
47 | if err != nil {
48 | tok = getTokenFromWeb(config)
49 | saveToken(tokFile, tok)
50 | }
51 | return config.Client(context.Background(), tok)
52 | }
53 |
--------------------------------------------------------------------------------
/internal/helpers/auth/token.go:
--------------------------------------------------------------------------------
1 | // refs https://developers.google.com/drive/v3/web/quickstart/go
2 | package auth
3 |
4 | import (
5 | "encoding/json"
6 | "fmt"
7 | log "github.com/sirupsen/logrus"
8 | "golang.org/x/net/context"
9 | "golang.org/x/oauth2"
10 | "os"
11 | )
12 |
13 | // Request a token from the web, then returns the retrieved token.
14 | func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
15 | authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
16 | log.Debug("Go to the following link in your browser then type the "+
17 | "authorization code: \n", authURL)
18 |
19 | var authCode string
20 | if _, err := fmt.Scan(&authCode); err != nil {
21 | log.Error("Unable to read authorization code %v", err)
22 | }
23 |
24 | tok, err := config.Exchange(context.TODO(), authCode)
25 | if err != nil {
26 | log.Error("Unable to retrieve token from web %v", err)
27 | }
28 | return tok
29 | }
30 |
31 | // Retrieves a token from a local file.
32 | func tokenFromFile(file string) (*oauth2.Token, error) {
33 | f, err := os.Open(file)
34 | if err != nil {
35 | return nil, err
36 | }
37 | defer f.Close()
38 | tok := &oauth2.Token{}
39 | err = json.NewDecoder(f).Decode(tok)
40 | return tok, err
41 | }
42 |
43 | // Saves a token to a file path.
44 | func saveToken(path string, token *oauth2.Token) {
45 | log.Debug("Saving credential file to: ", path)
46 | f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
47 | if err != nil {
48 | log.Fatalf("Unable to cache oauth token: %v", err)
49 | }
50 | defer f.Close()
51 | json.NewEncoder(f).Encode(token)
52 | }
53 |
--------------------------------------------------------------------------------
/internal/helpers/webscraping/webscraping.go:
--------------------------------------------------------------------------------
1 | package webscraping
2 |
3 | import (
4 | log "github.com/sirupsen/logrus"
5 | "golang.org/x/net/html"
6 | "io"
7 | "net/http"
8 | )
9 |
10 | func GetTittle(client *http.Client, link string) string {
11 | resp, err := client.Get(link)
12 | if err != nil {
13 | panic(err)
14 | }
15 |
16 | defer resp.Body.Close()
17 |
18 | if title, ok := getHtmlTitle(resp.Body); ok {
19 | log.Debug("Tittle website: ", title)
20 | return title
21 | } else {
22 | println("Fail to get HTML title")
23 | }
24 |
25 | return ""
26 | }
27 |
28 | func getHtmlTitle(r io.Reader) (string, bool) {
29 | doc, err := html.Parse(r)
30 | if err != nil {
31 | panic("Fail to parse html")
32 | }
33 |
34 | return traverse(doc)
35 | }
36 |
37 | func traverse(n *html.Node) (string, bool) {
38 | if isTitleElement(n) {
39 | return n.FirstChild.Data, true
40 | }
41 |
42 | for c := n.FirstChild; c != nil; c = c.NextSibling {
43 | result, ok := traverse(c)
44 | if ok {
45 | return result, ok
46 | }
47 | }
48 |
49 | return "", false
50 | }
51 |
52 | func isTitleElement(n *html.Node) bool {
53 | return n.Type == html.ElementNode && n.Data == "title"
54 | }
55 |
--------------------------------------------------------------------------------
/internal/process/account.go:
--------------------------------------------------------------------------------
1 | package process
2 |
3 | import (
4 | // "github.com/Juvenal-Yescas/gdown/internal/helpers/auth"
5 | "github.com/Juvenal-Yescas/gdown/pkg/gdriveapi"
6 | "google.golang.org/api/drive/v3"
7 | )
8 |
9 | func CreateCopyInDrive(clientGDrive *drive.Service, idFile string, outputName string) (*drive.File, *drive.File, error) {
10 | idFolder, err := gdriveapi.CreateFolder(clientGDrive, "gdown")
11 | if err != nil {
12 | return nil, nil, err
13 | }
14 |
15 | _, err = gdriveapi.MakeSharedFolder(clientGDrive, idFolder.Id)
16 | if err != nil {
17 | return idFolder, nil, err
18 | }
19 | arrayFolder := []string{idFolder.Id}
20 |
21 | idFileCopied, err := gdriveapi.CreateACopy(clientGDrive, idFile, outputName, arrayFolder)
22 | if err != nil {
23 | return idFolder, nil, err
24 | }
25 |
26 | return idFolder, idFileCopied, nil
27 | }
28 |
29 | func CleanCopyInDrive(clientGDrive *drive.Service, idFolder string) error {
30 | err := gdriveapi.Delete(clientGDrive, idFolder)
31 | return err
32 | }
33 |
34 | // func SkipQuotaExceeded(clientWeb *http.Client, idFile string, outputName string) (string, error) {
35 | // client, err := auth.CreateClient()
36 | // if err != nil {
37 | // return "", err
38 | // }
39 |
40 | // log.Debug("Try download again")
41 | // output, err := StartDownload(clientWeb, idFileCopied.Id, outputName)
42 | // if err != nil {
43 | // return "", err
44 | // }
45 |
46 | // err = gdriveapi.Delete(client, idFolder.Id)
47 | // if err != nil {
48 | // return "", err
49 | // }
50 | // return output, err
51 | // }
52 |
--------------------------------------------------------------------------------
/internal/process/functions.go:
--------------------------------------------------------------------------------
1 | package process
2 |
3 | import (
4 | "errors"
5 | "github.com/Juvenal-Yescas/gdown/internal/helpers/webscraping"
6 | "github.com/Juvenal-Yescas/gdown/internal/utils"
7 | log "github.com/sirupsen/logrus"
8 | "io/ioutil"
9 | "net/http"
10 | "regexp"
11 | "strings"
12 | )
13 |
14 | func GetUrlConfirmation(clientHttp *http.Client, idFile string) (string, error) {
15 |
16 | urlGoogleDrive := "https://drive.google.com/uc?id=" + idFile
17 |
18 | // Generate cookie
19 | resp, err := clientHttp.Get(urlGoogleDrive)
20 | if err != nil {
21 | log.Error("Client get : %v", err)
22 | return "", err
23 | }
24 |
25 | defer resp.Body.Close()
26 |
27 | var urlDirect string
28 |
29 | if len(resp.Cookies()) == 0 {
30 |
31 | data, _ := ioutil.ReadAll(resp.Body)
32 | bodyString := string(data)
33 |
34 | if utils.CaseInsensitiveContains(bodyString, "exceeded") {
35 | log.Info("Google Drive - Quota exceeded : Try download using your account...")
36 | log.Debug(urlGoogleDrive)
37 | return "", errors.New("This file is limited: Quota exceeded")
38 | }
39 | // small file
40 | return urlGoogleDrive, nil
41 | }
42 |
43 | // big file
44 | codeConfirmation := resp.Cookies()[0].Value
45 | urlDirect = urlGoogleDrive + "&confirm=" + codeConfirmation
46 | return urlDirect, nil
47 | }
48 |
49 | func StartDownload(clientHttp *http.Client, urlDirect string, outputName string) (string, error) {
50 | log.Info("Downloading ... ", outputName)
51 |
52 | fileOutput, err := utils.CreateFile(outputName)
53 | if err != nil {
54 | return "", err
55 | }
56 |
57 | resp, err := clientHttp.Get(urlDirect)
58 | if err != nil {
59 | log.Error("Client get : %v", err)
60 | return "", err
61 | }
62 |
63 | defer resp.Body.Close()
64 | _, err = utils.WriteToOutput(fileOutput, resp.Body)
65 | if err != nil {
66 | log.Error("Write data error : %v", err)
67 | return "", err
68 | }
69 | return outputName, nil
70 | }
71 |
72 | func GetIdFromUrl(url string) (string, error) {
73 | if utils.CaseInsensitiveContains(url, "google.com") {
74 | if utils.CaseInsensitiveContains(url, "id") {
75 | arrayUrl := strings.Split(url, "=")
76 | if utils.CaseInsensitiveContains(arrayUrl[1], "export") {
77 | arrayUrl := strings.Split(arrayUrl[1], "&")
78 | return arrayUrl[0], nil
79 | }
80 | return arrayUrl[1], nil
81 | } else if utils.CaseInsensitiveContains(url, "docs") {
82 | log.Error("Documents not implemented")
83 | return "", errors.New("Documents not implemented")
84 | } else {
85 | arrayUrl := strings.Split(url, "/")
86 | return arrayUrl[5], nil
87 | }
88 | }
89 | return url, nil
90 | }
91 |
92 | func GetNameOutput(client *http.Client, idFile string) (string, error) {
93 | urlOpen := "https://drive.google.com/open?id=" + idFile
94 |
95 | tittleWebsite := webscraping.GetTittle(client, urlOpen)
96 |
97 | extraTittle := regexp.MustCompile(" - Google Drive")
98 | outputName := extraTittle.ReplaceAllString(tittleWebsite, "")
99 | log.Debug("Correct name output: ", outputName)
100 |
101 | if outputName == "" {
102 | return "", errors.New("Tittle dont found")
103 | }
104 | return outputName, nil
105 | }
106 |
--------------------------------------------------------------------------------
/internal/utils/clienthttp.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "net/http"
5 | "net/http/cookiejar"
6 | )
7 |
8 | func CreateClientHttp() *http.Client {
9 | cookieJar, _ := cookiejar.New(nil)
10 | client := &http.Client{
11 | Jar: cookieJar,
12 | CheckRedirect: func(r *http.Request, via []*http.Request) error {
13 | r.URL.Opaque = r.URL.Path
14 | return nil
15 | },
16 | }
17 | return client
18 | }
19 |
--------------------------------------------------------------------------------
/internal/utils/output.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | log "github.com/sirupsen/logrus"
5 | "io"
6 | "os"
7 | )
8 |
9 | func CreateFile(output string) (*os.File, error) {
10 | fileOuput, err := os.Create(output)
11 | if err != nil {
12 | log.Debug("create file: %v", err)
13 | return nil, err
14 | }
15 | return fileOuput, nil
16 | }
17 |
18 | func WriteToOutput(fileOuput *os.File, resp io.Reader) (int64, error) {
19 | n, err := io.Copy(fileOuput, resp)
20 | defer fileOuput.Close()
21 | return n, err
22 | }
23 |
--------------------------------------------------------------------------------
/internal/utils/utils.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "os"
5 | "path/filepath"
6 | "runtime"
7 | "strings"
8 | )
9 |
10 | func CaseInsensitiveContains(s, substr string) bool {
11 | s, substr = strings.ToUpper(s), strings.ToUpper(substr)
12 | return strings.Contains(s, substr)
13 | }
14 |
15 | func GetDefaultConfigDir() string {
16 | return filepath.Join(Homedir(), ".gdown")
17 | }
18 |
19 | func Homedir() string {
20 | if runtime.GOOS == "windows" {
21 | return os.Getenv("APPDATA")
22 | }
23 | return os.Getenv("HOME")
24 | }
25 |
--------------------------------------------------------------------------------
/module.go:
--------------------------------------------------------------------------------
1 | package gdown
2 |
3 | import (
4 | "github.com/Juvenal-Yescas/gdown/internal/process"
5 | "github.com/Juvenal-Yescas/gdown/internal/utils"
6 | )
7 |
8 | func Download(url string) (string, error) {
9 | idFile, err := process.GetIdFromUrl(url)
10 | if err != nil {
11 | return "", err
12 | }
13 |
14 | clientHttp := utils.CreateClientHttp()
15 | outputName, err := process.GetNameOutput(clientHttp, idFile)
16 | if err != nil {
17 | return "", err
18 | }
19 |
20 | urlDirect, err := process.GetUrlConfirmation(clientHttp, idFile)
21 | if err != nil {
22 | return "", err
23 | }
24 |
25 | downloaded, err := process.StartDownload(clientHttp, urlDirect, outputName)
26 | if err != nil {
27 | return "", err
28 | }
29 | return downloaded, nil
30 | }
31 |
32 | func DownloadOutput(url string, outputName string) (string, error) {
33 | idFile, err := process.GetIdFromUrl(url)
34 | if err != nil {
35 | return "", err
36 | }
37 |
38 | clientHttp := utils.CreateClientHttp()
39 | urlDirect, err := process.GetUrlConfirmation(clientHttp, idFile)
40 | if err != nil {
41 | return "", err
42 | }
43 |
44 | downloaded, err := process.StartDownload(clientHttp, urlDirect, outputName)
45 | if err != nil {
46 | return "", err
47 | }
48 | return downloaded, nil
49 | }
50 |
--------------------------------------------------------------------------------
/pkg/gdriveapi/files.go:
--------------------------------------------------------------------------------
1 | package gdriveapi
2 |
3 | import (
4 | log "github.com/sirupsen/logrus"
5 | "google.golang.org/api/drive/v3"
6 | )
7 |
8 | func CreateFolder(client *drive.Service, nameFolder string) (*drive.File, error) {
9 |
10 | file := &drive.File{Name: nameFolder, MimeType: "application/vnd.google-apps.folder"}
11 |
12 | resp, err := client.Files.Create(file).Do()
13 | if err != nil {
14 | log.Error("An error occurred: %v\n", err)
15 | return nil, err
16 | }
17 | log.Debug("Id folder: %+v", resp.Id)
18 | return resp, nil
19 | }
20 |
21 | func CreateACopy(client *drive.Service, fileId string, nameOutput string, folderId []string) (*drive.File, error) {
22 |
23 | file := &drive.File{Name: nameOutput, Parents: folderId}
24 |
25 | resp, err := client.Files.Copy(fileId, file).Do()
26 | if err != nil {
27 | log.Debug("An error occurred: %v\n", err)
28 | log.Error(err)
29 | return nil, err
30 | }
31 |
32 | log.Debug("Id file copied: %+v", resp.Id)
33 | return resp, err
34 | }
35 |
36 | func Delete(client *drive.Service, fileIde string) error {
37 | error := client.Files.Delete(fileIde).Do()
38 | if error != nil {
39 | log.Error("An error occurred: %v\n", error)
40 | }
41 | return error
42 | }
43 |
--------------------------------------------------------------------------------
/pkg/gdriveapi/permissions.go:
--------------------------------------------------------------------------------
1 | package gdriveapi
2 |
3 | import (
4 | log "github.com/sirupsen/logrus"
5 | "google.golang.org/api/drive/v3"
6 | )
7 |
8 | func MakeSharedFolder(client *drive.Service, idFolder string) (*drive.Permission, error) {
9 | file := &drive.Permission{Role: "reader", Type: "anyone"}
10 | resp, err := client.Permissions.Create(idFolder, file).Do()
11 | if err != nil {
12 | log.Debug("An error occurred: %v\n", err)
13 | return nil, err
14 | }
15 | log.Debug("Type shared folder: %+v", resp.Id)
16 | return resp, nil
17 | }
18 |
--------------------------------------------------------------------------------