2

The docs aren't clear about how to properly set output format. I hardcoded a route for a single file on google drive: http://localhost:8080/0B-zdryEj60U_OXZBVklsdG13Wlk and it responds below: the runtime process gave a bad HTTP response:

2016/05/28 06:00:26 handleOneDoc
2016/05/28 06:00:26 
2016/05/28 06:00:26 &{0xc82007a500 0xc8201121c0 0x84de40 false false 0xc82016a180 {0xc82016c820 map[] false false} map[] false 0 -1 0 false false [] 0 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] <nil>}
2016/05/28 06:00:29 Unable to get download link %vgoogleapi: got HTTP response code 400 with body: {"error":{"errors":[{"domain":"global","reason":"unsupportedOutputFormat","message":"Unsupported Output Format","locationType":"parameter","location":"alt"}],"code":400,"message":"Unsupported Output Format"}}

Below is the source:

package gwebdrive

import (
    "fmt"
    "golang.org/x/net/context"
    _ "golang.org/x/oauth2"
    "golang.org/x/oauth2/google"
    "golang.org/x/oauth2/jwt"
    "google.golang.org/api/drive/v3"
    "google.golang.org/appengine"
    _ "html/template"
    _ "io/ioutil"
    "log"
    "net/http"
    "net/url"

    "strings"
)

const (
    assetFolder = "0B-zdryEj60U_N0NtSFJuQUdaWTA"
)

var (
    //tpl  *template
    dir  *drive.FileList
    conf *jwt.Config
)

func init() {
    ... key config content here. 
    http.Handle("/list", appengineHandler(handleList))
    http.Handle("/0B-zdryEj60U_OXZBVklsdG13Wlk", appengineHandler(handleOneDoc))

    //http.Handle("/.+", appengineHandler(handleContent))
}

// appengineHandler wraps http.Handler to pass it a new `appengine.Context` and handle errors.
type appengineHandler func(c context.Context, w http.ResponseWriter, r *http.Request) error

func (h appengineHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

    c := appengine.NewContext(r)
    if err := h(c, w, r); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello Darian Go Serve some Assets")

}

func handleOneDoc(c context.Context, w http.ResponseWriter, r *http.Request) error {
    log.Print("handleOneDoc")
    u, err := url.Parse(r.RequestURI)
    if err != nil {
        log.Fatalf("Unable to parse Request URL %v", err)
    }
    log.Printf(u.RawPath)
    s := strings.Split(u.RawPath, "/")
    // looking for regex for Google File ID's.

    // I don't actually know the point of this call but it's needed.
    client := conf.Client(appengine.NewContext(r))
    // use url to decide what asset to return as data.
    // for now assume url contains id.
    srv, err := drive.New(client)
    fileid := s[len(s)-1]
    log.Print(w, fileid)
    if err != nil {
        log.Fatalf("Unable to retrieve drive Client %v", err)
    }

    dwn, err := srv.Files.Get(fileid).Download()
    fmt.Fprint(w, "mimeType:image/png")

    if err != nil {
        log.Fatal("Unable to get download link %v", err)
    }

    fmt.Fprint(w, dwn.Body)

    return nil

}

func handleContent(c context.Context, w http.ResponseWriter, r *http.Request) error {
    log.Print("handleContent")
    u, err := url.Parse(r.RequestURI)
    if err != nil {
        log.Fatalf("Unable to parse Request URL %v", err)
    }
    fmt.Fprintf(w, u.RawPath)
    s := strings.Split(u.RawPath, "/")
    // looking for regex for Google File ID's.

    // I don't actually know the point of this call but it's needed.
    client := conf.Client(appengine.NewContext(r))
    // use url to decide what asset to return as data.
    // for now assume url contains id.
    srv, err := drive.New(client)
    fileid := s[len(s)-1]
    if err != nil {
        log.Fatalf("Unable to retrieve drive Client %v", err)
    }

    dwn, err := srv.Files.Get(fileid).Download()
    //service.files().get(fileId).executeMediaAndDownloadTo(w)
    fmt.Fprint(w, dwn)
    if err != nil {
        log.Fatal("Unable to get download link %v", err)
    }

    //fmt.Fprint(w, dwn)

    return nil

}

func handleList(c context.Context, w http.ResponseWriter, r *http.Request) error {
    log.Print("just handle")

    // Initiate an http.Client, the following GET request will be
    // authorized and authenticated on the behalf of user@example.com.
    client := conf.Client(appengine.NewContext(r))

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

    dir, err = srv.Files.List().PageSize(10).Q("'0B-zdryEj60U_MXVkajFweXBQWHM' in parents").
        Fields("files(id, kind, name, size, webViewLink)").Do()
    //resp, err := srv.Files.Export(dir.Files[1].Id, dir.Files[1].MimeType).Download()
    //fmt.Fprint(w, resp.Body)

    if err != nil {
        log.Fatalf("Unable to retrieve files.", err)
    }

    fmt.Fprint(w, "Files:")
    if len(dir.Files) > 0 {
        for _, i := range dir.Files {
            fmt.Fprint(w, "%s (%s)\n", i.Name, i.WebViewLink)
        }
    } else {
        fmt.Fprint(w, "No files found.")
    }
    return err
}
pinoyyid
  • 21,499
  • 14
  • 64
  • 115
Darian Hickman
  • 853
  • 10
  • 26

1 Answers1

0

this solution worked for me. the change found is that to give the file URL directly. which lead to another error on inSufficientPermission. Solved that too via this

Rajeesh
  • 27
  • 7
  • while the link may give an answer the question, it is better to include the most important parts in your answer and to use the link only as reference – DaFois Dec 12 '17 at 14:44
  • Thank you for the suggestion Mr. DaFois – Rajeesh Dec 13 '17 at 10:09