diff --git a/README.md b/README.md index a88911a..8b4e1cc 100644 --- a/README.md +++ b/README.md @@ -837,6 +837,7 @@ $ ggsrun e1 -f foo -v 1 -j ``GoogleElapsedTime`` cannot output in this mode, because this mode doesn't use server. + ## 6. Download Files ggsrun can download files from Google Drive by file ID and file name. The files also include GAS projects and scripts. @@ -858,7 +859,26 @@ $ ggsrun d -f filename -e pdf You can convert only from Google Docs Files (spreadsheet, slide, documentation and so on). For example, you cannot convert image files and text data. -Here, I could notice that the container-bound scripts can be downloaded! + +### How to Download Container-Bound Scripts +Here, I could notice that the container-bound scripts can be downloaded! From version 1.3.0, the container-bound scripts could be downloaded. + +- In order to download container-bound scripts, the project ID of container-bound scripts is required. The project ID can be retrieved as follows. + - Open the project. And please operate follows using click. + - -> File + - -> Project properties + - -> Get Script ID (**This is the project ID.**) + +You can download the project by the following command. + +~~~bash +$ ggsrun d -pi project_id +~~~ + +**Limitation :** + +- The file information of container-bound scripts cannot be retrieved by Drive API. So the filename cannot be retrieved from the project ID. + - Prefix of filename of the downloaded project is the project ID. ### Help ~~~ @@ -873,11 +893,12 @@ DESCRIPTION: In this mode, an access token is required. OPTIONS: - --fileid value, -i value File ID on Google Drive - --filename value, -f value File Name on Google Drive - --extension value, -e value Extension (File format of downloaded file) - --rawdata, -r Save a project with GAS scripts as raw data (JSON data). - --jsonparser, -j Display results by JSON parser + --fileid value, -i value File ID on Google Drive + --filename value, -f value File Name on Google Drive + --projectid value, --pi value Project ID of bound scripts of Google Sheets, Docs, or Forms file + --extension value, -e value Extension (File format of downloaded file) + --rawdata, -r Save a project with GAS scripts as raw data (JSON data). + --jsonparser, -j Display results by JSON parser ~~~ ## 7. Upload Files @@ -1549,6 +1570,16 @@ If you have any questions and commissions for me, feel free to tell me using e-m I don't know when this workaround will not be able to be used. But if this could not be used, I would like to investigate of other method. +* v1.3.0 (August 30, 2017) + + 1. From this version, [container-bound scripts](https://developers.google.com/apps-script/guides/bound) can be downloaded. The container-bound script is the script created at the script editor on Google Sheets, Docs, or Forms file. The usage is [here](#DownloadBoundScript). + - In order to download container-bound scripts, the project ID of container-bound scripts is required. The project ID can be retrieved as follows. + - Open the project. And please operate follows using click. + - -> File + - -> Project properties + - -> Get Script ID (**This is the project ID.**) + 1. When a project is downloaded, the filename of HTML file had become ``.gs``. This bug was modified. + ## Server * v1.0.0 (April 24, 2017) diff --git a/doc.go b/doc.go index 71d36eb..601e10d 100644 --- a/doc.go +++ b/doc.go @@ -16,7 +16,7 @@ Will you want to develop GAS on your local PC? Generally, when we develop GAS, w 5. Creates, updates and backs up project with GAS. -6. Downloads files from Google Drive and Uploads files to Google Drive. +6. Downloads files from Google Drive and Uploads files to Google Drive. Also container-bound scripts can be downloaded. 7. Download revision files from Google Drive. diff --git a/ggsrun.go b/ggsrun.go index 858a461..a0a2cde 100644 --- a/ggsrun.go +++ b/ggsrun.go @@ -15,7 +15,7 @@ func main() { app.Author = "tanaike [ https://github.com/tanaikech/ggsrun ] " app.Email = "tanaike@hotmail.com" app.Usage = "Executes Google Apps Script (GAS) on Google and Feeds Back Results." - app.Version = "1.2.2" + app.Version = "1.3.0" app.Commands = []cli.Command{ { Name: "exe1", @@ -155,6 +155,10 @@ func main() { Name: "filename, f", Usage: "File Name on Google Drive", }, + cli.StringFlag{ + Name: "projectid, pi", + Usage: "Project ID of bound scripts of Google Sheets, Docs, or Forms file", + }, cli.StringFlag{ Name: "extension, e", Usage: "Extension (File format of downloaded file)", diff --git a/materials.go b/materials.go index 5a663b9..fccf68a 100644 --- a/materials.go +++ b/materials.go @@ -332,8 +332,15 @@ func (a *AuthContainer) defDownloadContainer(c *cli.Context) *utl.FileInf { Workdir: a.InitVal.workdir, PstartTime: a.InitVal.pstart, FileID: c.String("fileid"), - WantExt: c.String("extension"), - WantName: c.String("filename"), + ProjectID: func(c *cli.Context) string { + id := c.String("projectid") + if c.String("fileid") != "" && c.String("projectid") != "" { + id = "" + } + return id + }(c), + WantExt: c.String("extension"), + WantName: c.String("filename"), } return p } diff --git a/utl/transfer.go b/utl/transfer.go index 2ac9d58..e372e81 100644 --- a/utl/transfer.go +++ b/utl/transfer.go @@ -44,6 +44,7 @@ type FileInf struct { SearchByName string `json:"-"` SearchByID string `json:"-"` FileID string `json:"id,omitempty"` + ProjectID string `json:"project_id,omitempty"` RevisionID string `json:"revisionid,omitempty"` FileName string `json:"name,omitempty"` SaveName string `json:"saved_file_name,omitempty"` @@ -139,15 +140,20 @@ func (p *FileInf) saveScript(data []byte, c *cli.Context) *FileInf { p.Msgar = append(p.Msgar, fmt.Sprintf("%s has %d scripts.", p.FileName, len(f.Files))) } for _, e := range f.Files { - saveName := p.FileName + "_" + e.Name + "." + func(ex string) string { + saveName := p.FileName + "_" + e.Name + "." + func(ex, ty string) string { var eext string if len(ex) > 0 { eext = ex } else { - eext = "gs" + switch ty { + case "server_js": + eext = "gs" + case "html": + eext = "html" + } } return eext - }(p.WantExt) + }(p.WantExt, e.Type) src := fmt.Sprintf("// Script ID in Project = %s \n%s", e.ID, e.Source) ioutil.WriteFile(filepath.Join(p.Workdir, saveName), []byte(src), 0777) p.Msgar = append(p.Msgar, fmt.Sprintf("Script was downloaded as '%s'.", saveName)) @@ -164,7 +170,7 @@ func (p *FileInf) Downloader(c *cli.Context) *FileInf { } else { p.DlMime, ext = defFormat(p.MimeType) } - if len(p.FileID) > 0 { + if len(p.FileID) > 0 || len(p.ProjectID) > 0 { var body []byte var gm map[string]interface{} json.Unmarshal([]byte(googlemimetypes), &gm) @@ -182,12 +188,19 @@ func (p *FileInf) Downloader(c *cli.Context) *FileInf { if p.MimeType == "application/vnd.google-apps.script" { p, body = p.writeFile(sdownloadurl + p.FileID + "&format=json") p.saveScript(body, c) - } else { + } else if p.MimeType != "" { p, _ = p.writeFile(driveapiurl + p.FileID + "/export?mimeType=" + p.DlMime) } } else { - p.SaveName = p.FileName - p, _ = p.writeFile(driveapiurl + p.FileID + "?alt=media") + if len(p.ProjectID) > 0 && p.MimeType == "" { + p.FileName = p.ProjectID + p.MimeType = "application/vnd.google-apps.script" + p, body = p.writeFile(sdownloadurl + p.ProjectID + "&format=json") + p.saveScript(body, c) + } else { + p.SaveName = p.FileName + p, _ = p.writeFile(driveapiurl + p.FileID + "?alt=media") + } } } else { fmt.Fprintf(os.Stderr, "Error: Please input File Name or File ID. ")