Skip to content

Commit c750803

Browse files
committed
Updated to v1.5.0
1 parent 30ab370 commit c750803

19 files changed

+1010
-148
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Features of "ggsrun" are as follows.
2525
1. **[Downloads spreadsheet, document and presentation, while executes GAS, simultaneously.](help/README.md#DownloadFiles)**
2626
1. **[Downloads files from Google Drive and Uploads files to Google Drive.](help/README.md#UploadFiles)** <sup><font color="Red">Updated! (v1.4.1)</font></sup>
2727
1. **[Downloads standalone script and bound script.](help/README.md#DownloadFiles)** <sup><font color="Red">Updated! (v1.4.0)</font></sup>
28+
1. **[Downloads all files and folders in a specific folder.](help/README.md#DownloadFilesFromFolder)** <sup><font color="Red">Updated! (v1.5.0)</font></sup>
2829
1. **[Upload script files and create project as standalone script and container-bound script.](help/README.md#UploadFiles)** <sup><font color="Red">Updated! (v1.4.0)</font></sup>
2930
1. **[Update project.](help/README.md#Update_Project)** <sup><font color="Red">Updated! (v1.4.0)</font></sup>
3031
1. **[Retrieve revision files of Google Docs and retrieve versions of projects.](help/README.md#RevisionFile)** <sup><font color="Red">Updated! (v1.4.0)</font></sup>
@@ -99,6 +100,7 @@ Completed!
99100
1. [Executes GAS with Values and Downloads File](help/README.md#ExecutesGASwithValuesandDownloadsFile)
100101
1. [Executes Existing Functions on Project](help/README.md#ExecutesExistingFunctionsonProject)
101102
1. [Download Files](help/README.md#DownloadFiles)
103+
1. [Downloads all files and folders in a specific folder.](help/README.md#DownloadFilesFromFolder)
102104
1. [Upload Files](help/README.md#UploadFiles)
103105
1. [Show File List](help/README.md#ShowFileList)
104106
1. [Search Files](help/README.md#SearchFiles)

doc.go

+8-10
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,21 @@ Will you want to develop GAS on your local PC? Generally, when we develop GAS, w
1414
1515
4. Downloads spreadsheet, document and presentation, while executes GAS, simultaneously.
1616
17-
5. Upload files to Google Drive. When files are uploaded, also they can be converted by options.
17+
5. Downloads files from Google Drive and Uploads files to Google Drive.
1818
19-
6. Creates, updates and backs up project of both standalone type and bound script type.
19+
6. Downloads standalone script and bound script.
2020
21-
7. Creates Google Docs (Spreadsheet, Document, Slide and Form) and create bound script in the created Google Docs.
21+
7. Downloads all files and folders in a specific folder.
2222
23-
8. Downloads files from Google Drive and Uploads files to Google Drive. Also container-bound scripts can be downloaded.
23+
8. Upload script files and create project as standalone script and container-bound script.
2424
25-
9. Downloads revision files from Google Drive.
25+
9. Update project.
2626
27-
10. Rearranges files in project of both standalone type and bound script type.
27+
10. Retrieve revision files of Google Docs and retrieve versions of projects.
2828
29-
11. Modifies Manifests (appsscript.json) in project.
29+
11. Rearranges scripts in project.
3030
31-
12. Remove files in the project of both standalone type and bound script type.
32-
33-
13. Retrieve revision file list and revision data.
31+
12. Modifies Manifests in project.
3432
3533
3634
You can see the release page https://github.com/tanaikech/ggsrun/releases

ggsrun.go

+17-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func main() {
1515
app.Author = "Tanaike [ https://github.com/tanaikech/ggsrun ] "
1616
app.Email = "tanaike@hotmail.com"
1717
app.Usage = "Executes Google Apps Script (GAS) on Google and Feeds Back Results."
18-
app.Version = "1.4.1"
18+
app.Version = "1.5.0"
1919
app.Commands = []cli.Command{
2020
{
2121
Name: "exe1",
@@ -163,10 +163,26 @@ func main() {
163163
Name: "rawdata, r",
164164
Usage: "Save a project with GAS scripts as raw data (JSON data).",
165165
},
166+
cli.BoolFlag{
167+
Name: "zip, z",
168+
Usage: "Create a zip file including all scripts of a GAS project. Please use this for downloading a GAS project.",
169+
},
166170
cli.StringFlag{
167171
Name: "deletefile",
168172
Usage: "Value is file ID. This can delete a file using a file ID on Google Drive.",
169173
},
174+
cli.BoolFlag{
175+
Name: "overwrite, o",
176+
Usage: "When filename of downloading file is existing in directory at local PC, overwrite it. At default, it is not overwritten.",
177+
},
178+
cli.BoolFlag{
179+
Name: "skip, s",
180+
Usage: "When filename of downloading file is existing in directory at local PC, skip it. At default, it is not overwritten.",
181+
},
182+
cli.BoolFlag{
183+
Name: "showfilelist, l",
184+
Usage: "When files from a folder are retrieved, file list is returned using this option. When this is used, files are not downloaded.",
185+
},
170186
cli.BoolFlag{
171187
Name: "jsonparser, j",
172188
Usage: "Display results by JSON parser",

help/README.md

+105-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ ggsrun
2525
- Executes GAS with Values and Downloads File
2626
- Executes Existing Functions on Project
2727
- Download Files
28+
- Download All Files and Folders in Specific Folder
2829
- Upload Files
2930
- Show File List
3031
- Search Files
@@ -69,6 +70,8 @@ Features of "ggsrun" are as follows.
6970

7071
1. **[Downloads standalone script and bound script.](#DownloadFiles)**
7172

73+
1. **[Downloads all files and folders in a specific folder.](#DownloadFilesFromFolder)**
74+
7275
1. **[Upload script files and create project as standalone script and container-bound script.](#UploadFiles)**
7376

7477
1. **[Update project.](#Update_Project)**
@@ -890,7 +893,8 @@ $ ggsrun d -f filename -e pdf
890893

891894
You can convert only from Google Docs Files (spreadsheet, slide, documentation and so on). For example, you cannot convert image files and text data.
892895

893-
When you download project files which are standalone script and container-bound script, you can use the option of ``--raw``. You can download raw files of project by this.
896+
- When you download project files which are standalone script and container-bound script, you can use the option of ``--raw``. You can download raw files of project by this.
897+
- When you download a project file, when you use the option ``--zip`` or ``-zip``, you can download the prject as a zip file. This zip file has all scripts in the project. This option was added at v1.5.0.
894898

895899
~~~bash
896900
$ ggsrun d -i fileId -r
@@ -912,6 +916,106 @@ You can also delete files using file ID.
912916
$ ggsrun d --deletefile [fileId]
913917
~~~
914918

919+
<a name="DownloadFilesFromFolder"></a>
920+
### 6-1. Download All Files and Folders in Specific Folder
921+
From version 1.5.0, ggsrun got to be able to download all files and folders in the specific folder in Google Drive. The same folder structure of Google Drive is created to the local PC.
922+
923+
**Run :**
924+
925+
~~~bash
926+
$ ggsrun d -f foldername
927+
~~~
928+
929+
or
930+
931+
~~~bash
932+
$ ggsrun d -i folderid
933+
~~~
934+
935+
- When the option ``--jsonparser`` or ``-j `` is used like ``$ ggsrun d -f foldername -j``, you can see the progress of download. Other options are the same with those of download.
936+
- When the option ``--showfilelist`` or ``-l`` is used, only the file list and folder structure can be retrieved as JSON object. In this case, no files and folders are downloaded.
937+
- When the option ``--overwrite`` or ``-o`` is used, when the duplicated files in the downloaded folder on the local PC are found, the downloaded files are overwritten.
938+
- When the option ``--skip`` or ``-s`` is used, when the duplicated files in the downloaded folder on the local PC are found, the downloaded files are skipped and not saved. This can be used to know whether the files with new filename were created in the folder of Google Drive.
939+
- About the folder, you can download from not only the folders in your Google Drive, but also the shared folders in other Google Drive. When you want to download the files from the shared folder, please use the folder ID of the shared folder.
940+
- When the files and folders are downloaded, the folder structure in Google Drive is also created to the working directory on the local PC.
941+
- When the project of the standalone script script type is downloaded, it is created as a zip file. In the zip file, all scripts are included.
942+
943+
#### Sample:
944+
![](images/downloadFolder_sample.png)
945+
As a sample, it supposes that it downloads the files from the above structure. The command is as follows.
946+
947+
~~~bash
948+
$ ggsrun d -f sampleFolder1 -j
949+
~~~
950+
951+
By this command, all files with the folder structure ot the above figure are created in the working directory on local PC. When the command is run, the following result is returned. When ``-j`` is not used, only JSON object is returned.
952+
953+
~~~bash
954+
$ ggsrun d -f sampleFolder1 -j
955+
Files are downloaded from a folder 'sampleFolder1'.
956+
Getting values to download.
957+
Download files from a folder 'sampleFolder1'.
958+
There are 10 files and 6 folders in the folder.
959+
Starting download.
960+
Now downloading 'Spreadsheet1.xlsx' (bytes)... 3595
961+
Now downloading 'Spreadsheet2.xlsx' (bytes)... 3595
962+
Now downloading 'Spreadsheet4.xlsx' (bytes)... 3595
963+
Now downloading 'Spreadsheet3.xlsx' (bytes)... 3595
964+
Now downloading 'Document1.docx' (bytes)... 6097
965+
Now downloading 'image1.jpg' (bytes)... 958546 / 958546
966+
Now downloading 'Slides1.pptx' (bytes)... 31733
967+
Now downloading 'Spreadsheet5.xlsx' (bytes)... 3595
968+
Project file 'StandaloneProject1.gs' is downloaded.
969+
Now downloading 'Text1.txt' (bytes)... 50000000 / 50000000
970+
{
971+
"id": "### folderId ###",
972+
"name": "sampleFolder1",
973+
"mimeType": "application/vnd.google-apps.folder",
974+
"parents": [
975+
"### parent folderId ###"
976+
],
977+
"webViewLink": "https://drive.google.com/drive/folders/###",
978+
"createdTime": "2000-01-01T00:00:00.000Z",
979+
"modifiedTime": "2000-01-01T00:00:00.000Z",
980+
"lastModifyingUser": {
981+
"displayName": "Tanaike",
982+
"emailAddress": "mailaddress"
983+
},
984+
"owners": [
985+
{
986+
"displayName": "Tanaike",
987+
"permissionId": "###",
988+
"emailAddress": "mailaddress"
989+
}
990+
],
991+
"message": [
992+
"Files were downloaded from folder 'sampleFolder1'.",
993+
"File was downloaded as 'Spreadsheet1.xlsx'. Size was 3595 bytes.",
994+
"File was downloaded as 'Spreadsheet2.xlsx'. Size was 3595 bytes.",
995+
"File was downloaded as 'Spreadsheet4.xlsx'. Size was 3595 bytes.",
996+
"File was downloaded as 'Spreadsheet3.xlsx'. Size was 3595 bytes.",
997+
"File was downloaded as 'Document1.docx'. Size was 6097 bytes.",
998+
"File was downloaded as 'image1.jpg'. Size was 958546 bytes.",
999+
"File was downloaded as 'Slides1.pptx'. Size was 31733 bytes.",
1000+
"File was downloaded as 'Spreadsheet5.xlsx'. Size was 3595 bytes.",
1001+
"StandaloneProject1.gs has 4 scripts.",
1002+
"4 scripts in the project were saved as 'StandaloneProject1.gs.zip'.",
1003+
"File was downloaded as 'Text1.txt'. Size was 50000000 bytes.",
1004+
"There were 10 files and 6 folders in the folder."
1005+
],
1006+
"TotalElapsedTime": 12.345
1007+
}
1008+
~~~
1009+
1010+
1011+
> **IMPORTANT :**
1012+
1013+
> As a limitation, the project ID of the container-bound script still cannot be retrieved using the file ID of Google Docs by Drive API and Apps Script API. By this situation, only the projects of the container-bound script type cannot be downloaded. When the container-bound script can be retrieved from file ID of Google Docs, the backup of folder will be completely done.
1014+
1015+
> I have already reported about this situation at [https://issuetracker.google.com/issues/111149037](https://issuetracker.google.com/issues/111149037).
1016+
1017+
1018+
9151019
<a name="UploadFiles"></a>
9161020
## 7. Upload Files
9171021
ggsrun can upload local files to Google Drive. The files also include GAS projects and scripts.

help/UpdateHistory.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ ggsrun
2626
- If the environment variable (**``GGSRUN_CFG_PATH``**) is set, ggsrun.cfg is read using it.
2727
- If it is not set, ggsrun.cfg is read from the current working directory. This is as has been the way until now.
2828
- This is the response for some requests.
29-
- This incofmation was added to [here](help/README.md#environmentvariable).
29+
- This information was added to [here](help/README.md#environmentvariable).
3030

3131
* v1.2.2 (July 12, 2017)
3232

@@ -110,6 +110,17 @@ ggsrun
110110
- ``$ ggsrun u -f filename -chunk 10``
111111
- This means that a file with filename is uploaded by each chunk of 10 MB.
112112

113+
* v1.5.0 (October 27, 2018)
114+
1. [From this version, ggsrun got to be able to download all files and folders in the specific folder in Google Drive.](README.md#DownloadFilesFromFolder) When all files are downloaded from a folder, the same folder structure of Google Drive is created to the local PC.
115+
- ``$ ggsrun d -f folderName or folderId``
116+
- When the project file is downloaded, it is downloaded as a zip file. All scripts in the project is put in the zip file.
117+
- Also when you download a single project, you can use an option ``--zip`` or ``-z``. By this, the downloaded project is saved as a zip file.
118+
- This new function can be also used for the shared folders. When you want to download the files from the shared folder, please use the folder ID of the shared folder.
119+
1. The file list with the folder tree in the specific folder got to be able to be retrieved.
120+
1. When the files are downloaded, the progression got to be able to be seen. When you want to see the progression, please use ``-j`` when you download files and folders.
121+
1. Files with large size got to be able to be used. In order to download files with large size (several gigabytes), files are saved by chunks.
122+
1. Some modifications.
123+
113124

114125
**You can read "How to install" at [here](https://github.com/tanaikech/ggsrun/blob/master/README.md#How_to_Install).**
115126

help/images/downloadFolder_sample.png

29.3 KB
Loading

init.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,5 @@ func (a *AuthContainer) chkInitFile(file string) ([]byte, error) {
7373
return body, err
7474
}
7575
}
76-
return nil, fmt.Errorf("Error: %s was not found.\n", file)
76+
return nil, fmt.Errorf("error: %s was not found", file)
7777
}

materials.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,12 @@ func (a *AuthContainer) defDownloadContainer(c *cli.Context) *utl.FileInf {
366366
BoundScriptName: c.String("boundscriptname"),
367367
WantExt: c.String("extension"),
368368
WantName: c.String("filename"),
369+
Progress: c.Bool("jsonparser"),
370+
OverWrite: c.Bool("overwrite"),
371+
RawProject: c.Bool("rawdata"),
372+
ShowFileInf: c.Bool("showfilelist"),
373+
Skip: c.Bool("skip"),
374+
Zip: c.Bool("zip"),
369375
}
370376
return p
371377
}
@@ -380,16 +386,14 @@ func (a *AuthContainer) defUploadContainer(c *cli.Context) *utl.FileInf {
380386
ChunkSize: func(chnk int64) int64 {
381387
if chnk < 1 {
382388
return 1048576
383-
} else {
384-
return chnk * 1048576
385389
}
390+
return chnk * 1048576
386391
}(c.Int64("chunksize")),
387392
UpFilename: func(filenames string) []string {
388393
if filenames != "" {
389394
return regexp.MustCompile(`\s*,\s*`).Split(filenames, -1)
390-
} else {
391-
return nil
392395
}
396+
return nil
393397
}(c.String("filename")),
394398
ParentID: c.String("parentid"),
395399
ProjectType: func(ptype string) string {

oauth.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ func (a *AuthContainer) getAtoken() *AuthContainer {
7878
}
7979
body, err := r.FetchAPI()
8080
if err != nil {
81-
fmt.Fprintf(os.Stderr, "Error: %v. ", err)
81+
fmt.Fprintf(os.Stderr, "Error: %v. %s\n", err, body)
82+
fmt.Println("Hint: If you use old ggsrun.cfg, please remove it and run 'ggsrun auth'. Then try again.")
8283
os.Exit(1)
8384
}
8485
json.Unmarshal(body, &a.Atoken)
@@ -138,7 +139,7 @@ func (a *AuthContainer) chkRedirectURI() bool {
138139
func (a *AuthContainer) getCode() (string, error) {
139140
p := a.InitVal.Port
140141
if !a.chkRedirectURI() {
141-
return "", fmt.Errorf("Go manual mode.")
142+
return "", fmt.Errorf("Go manual mode")
142143
}
143144
fmt.Printf("\n### This is a automatic input mode.\n### Please follow opened browser, login Google and click authentication.\n### It will move to a manual mode if you wait for 30 seconds under this situation.\n")
144145
a.Cs.Cid.Redirecturis = append(a.Cs.Cid.Redirecturis, "http://localhost:"+strconv.Itoa(p)+"/")
@@ -164,7 +165,7 @@ func (a *AuthContainer) getCode() (string, error) {
164165
code := r.URL.Query().Get("code")
165166
if len(code) == 0 {
166167
fmt.Fprintf(w, `<html><head><title>ggsrun status</title></head><body><p>Erorr.</p></body></html>`)
167-
s.Response <- authCode{Err: fmt.Errorf("Not found code.")}
168+
s.Response <- authCode{Err: fmt.Errorf("Not found code")}
168169
return
169170
}
170171
fmt.Fprintf(w, `<html><head><title>ggsrun status</title></head><body><p>The authentication was done. Please close this page.</p></body></html>`)
@@ -195,19 +196,19 @@ func (a *AuthContainer) getCode() (string, error) {
195196
case "windows":
196197
cmd = exec.Command("cmd", "/c", "start", strings.Replace(codeurl, "&", `^&`, -1))
197198
default:
198-
return "", fmt.Errorf("Go manual mode.")
199+
return "", fmt.Errorf("Go manual mode")
199200
}
200201
if err := cmd.Start(); err != nil {
201-
return "", fmt.Errorf("Go manual mode.")
202+
return "", fmt.Errorf("Go manual mode")
202203
}
203204
var result authCode
204205
select {
205206
case result = <-s.Response:
206207
case <-time.After(time.Duration(30) * time.Second): // After 30 s, move to manual mode.
207-
return "", fmt.Errorf("Go manual mode.")
208+
return "", fmt.Errorf("Go manual mode")
208209
}
209210
if result.Err != nil {
210-
return "", fmt.Errorf("Go manual mode.")
211+
return "", fmt.Errorf("Go manual mode")
211212
}
212213
return result.Code, nil
213214
}

projectupdater.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,12 @@ func (e *ExecutionContainer) projectUpdateControl(c *cli.Context) *utl.FileInf {
2424
ProjectMaker().
2525
projectUpdate2().
2626
dispUpdateProjectContainer()
27-
} else {
28-
return e.defUpdateProjectContainer(c).
29-
projectBackup(c).
30-
filesInProjectRemover().
31-
projectUpdate2().
32-
dispUpdateProjectContainer()
3327
}
28+
return e.defUpdateProjectContainer(c).
29+
projectBackup(c).
30+
filesInProjectRemover().
31+
projectUpdate2().
32+
dispUpdateProjectContainer()
3433
}
3534
if c.Bool("rearrange") {
3635
e.defUpdateProjectContainer(c).

scriptrearrange.go

+7-12
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,9 @@ func (e *ExecutionContainer) rearrangeByTerminal() *ExecutionContainer {
4444
s.Stop()
4545
fmt.Printf("\n")
4646
return e
47-
} else {
48-
e.Msg = append(e.Msg, "Scripts of project were NOT rearranged.")
49-
return e
5047
}
48+
e.Msg = append(e.Msg, "Scripts of project were NOT rearranged.")
49+
return e
5150
}
5251

5352
// rearrange : Rearranging scripts in a project using a configuration file.
@@ -84,22 +83,18 @@ func (e *ExecutionContainer) rearrangeByFile(data []string) *ExecutionContainer
8483
if cn == len(e.Project.Files) {
8584
e.rearrange(baseProject, changedIndx)
8685
return e
87-
} else {
88-
e.Msg = append(e.Msg, "Error: Script names of inputted file are different for script names in project.")
89-
return e
9086
}
91-
} else {
92-
e.Msg = append(e.Msg, "Error: Order of inputted file are the same to the order in project.")
87+
e.Msg = append(e.Msg, "Error: Script names of inputted file are different for script names in project.")
9388
return e
9489
}
95-
} else {
96-
e.Msg = append(e.Msg, "Error: Number of script names of inputted file are different for number of scripts in project.")
90+
e.Msg = append(e.Msg, "Error: Order of inputted file are the same to the order in project.")
9791
return e
9892
}
99-
} else {
100-
e.Msg = append(e.Msg, "Error: There are duplicated names in script names of inputted file.")
93+
e.Msg = append(e.Msg, "Error: Number of script names of inputted file are different for number of scripts in project.")
10194
return e
10295
}
96+
e.Msg = append(e.Msg, "Error: There are duplicated names in script names of inputted file.")
97+
return e
10398
}
10499

105100
// rearrange : Main method for rearranging scripts.

0 commit comments

Comments
 (0)