Skip to content

Commit 38cdf1a

Browse files
committed
Updated to v1.7.4
1 parent 3d23fba commit 38cdf1a

File tree

3 files changed

+158
-86
lines changed

3 files changed

+158
-86
lines changed

ggsrun.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func main() {
1616
{Name: "Tanaike [ https://github.com/tanaikech/ggsrun ] ", Email: "tanaike@hotmail.com"},
1717
}
1818
app.UsageText = "This is a CLI application for managing Google Drive and Google Apps Script (GAS)."
19-
app.Version = "1.7.3"
19+
app.Version = "1.7.4"
2020
app.Commands = []*cli.Command{
2121
{
2222
Name: "exe1",

help/UpdateHistory.md

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ggsrun
22

3-
<a name="TOP"></a>
3+
<a name="top"></a>
44

55
# Update History
66

@@ -157,18 +157,26 @@
157157
1. A bug was removed.
158158
- When a project is downloaded and zipped, there was a case that "createdTime" and "modifiedTime" of the project cannot be retrieved by Apps Script API. This was modified.
159159

160-
**You can read "How to install" at [here](https://github.com/tanaikech/ggsrun/blob/master/README.md#howtoinstall).**
161-
162160
<a name="v173"></a>
163161

164162
- v1.7.3 (January 3, 2020)
165163

166164
1. It seems that the specification of `github.com/urfave/cli` was changed by the update of [https://github.com/urfave/cli](https://github.com/urfave/cli). By this, when `go get -u github.com/tanaikech/ggsrun` is run, an error occurred. So this error was removed.
167165

166+
<a name="v174"></a>
167+
168+
- v1.7.4 (March 11, 2020)
169+
170+
1. Recently, I noticed that new Google Apps Script project of the standalone script type cannot be created by the create method of Drive API. From now, in order to create the standalone Google Apps Script project, only Google Apps Script API is required to be used. [Ref](https://gist.github.com/tanaikech/0609f2cd989c28d6bd49d211b70b453d) By this, I updated ggsrun. So the command for creating new GAS project is not changed.
171+
172+
- `$ ggsrun u -p ###folderId### -f sample.gs -pn sampleGASProjectName`
173+
168174
## Server
169175

170176
- v1.0.0 (April 24, 2017)
171177

172178
Initial release.
173179

174-
[TOP](#TOP)
180+
**You can read "How to install" at [here](https://github.com/tanaikech/ggsrun/blob/master/README.md#howtoinstall).**
181+
182+
[TOP](#top)

utl/transfer.go

+145-81
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const (
2929
driveapiurl = "https://www.googleapis.com/drive/v3/files/"
3030
driveapiurlv2 = "https://www.googleapis.com/drive/v2/files/"
3131
uploadurl = "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&"
32+
updateurl = "https://www.googleapis.com/upload/drive/v3/files/"
3233
lengthOfProjectId = 57
3334
maxSizeForMultipart = 5242880
3435
)
@@ -659,52 +660,55 @@ func defFormat(mime string) (string, string) {
659660
return dmime, ext
660661
}
661662

662-
// scriptUploader : For uploading scripts.
663-
func (p *FileInf) scriptUploader(metadata map[string]interface{}, pr []byte) *FileInf {
664-
tokenparams := url.Values{}
665-
tokenparams.Set("fields", "createdTime,fullFileExtension,id,mimeType,modifiedTime,name,parents,size,webContentLink,webViewLink,lastModifyingUser(displayName,emailAddress),owners(displayName,emailAddress,permissionId)")
666-
var b bytes.Buffer
667-
w := multipart.NewWriter(&b)
668-
part := make(textproto.MIMEHeader)
669-
part.Set("Content-Type", "application/json")
670-
data, err := w.CreatePart(part)
671-
if err != nil {
672-
fmt.Fprintf(os.Stderr, "Error: %v. ", err)
673-
os.Exit(1)
674-
}
675-
re, _ := json.Marshal(metadata)
676-
if _, err = io.Copy(data, bytes.NewReader(re)); err != nil {
677-
fmt.Fprintf(os.Stderr, "Error: %v. ", err)
678-
os.Exit(1)
679-
}
680-
data, err = w.CreatePart(part)
681-
if err != nil {
682-
fmt.Fprintf(os.Stderr, "Error: %v. ", err)
683-
os.Exit(1)
684-
}
685-
if _, err = io.Copy(data, bytes.NewReader(pr)); err != nil {
686-
fmt.Fprintf(os.Stderr, "Error: %v. ", err)
687-
os.Exit(1)
688-
}
689-
w.Close()
690-
r := &RequestParams{
691-
Method: "POST",
692-
APIURL: uploadurl + tokenparams.Encode(),
693-
Data: &b,
694-
Contenttype: w.FormDataContentType(),
695-
Accesstoken: p.Accesstoken,
696-
Dtime: 30,
697-
}
698-
body, err := r.FetchAPI()
699-
if err != nil {
700-
fmt.Fprintf(os.Stderr, "Error: %s\n%s\n", err, body)
701-
os.Exit(1)
702-
}
703-
var uf uploadedFile
704-
json.Unmarshal(body, &uf)
705-
p.UppedFiles = append(p.UppedFiles, uf)
706-
return p
707-
}
663+
// scriptUploader : For uploading scripts with Drive API.
664+
// At March 9th, 2020, I confirmed that this method had already been deprecated.
665+
// https://gist.github.com/tanaikech/0609f2cd989c28d6bd49d211b70b453d
666+
// I hope for reactivating this.
667+
// func (p *FileInf) scriptUploader(metadata map[string]interface{}, pr []byte) *FileInf {
668+
// tokenparams := url.Values{}
669+
// tokenparams.Set("fields", "createdTime,fullFileExtension,id,mimeType,modifiedTime,name,parents,size,webContentLink,webViewLink,lastModifyingUser(displayName,emailAddress),owners(displayName,emailAddress,permissionId)")
670+
// var b bytes.Buffer
671+
// w := multipart.NewWriter(&b)
672+
// part := make(textproto.MIMEHeader)
673+
// part.Set("Content-Type", "application/json")
674+
// data, err := w.CreatePart(part)
675+
// if err != nil {
676+
// fmt.Fprintf(os.Stderr, "Error: %v. ", err)
677+
// os.Exit(1)
678+
// }
679+
// re, _ := json.Marshal(metadata)
680+
// if _, err = io.Copy(data, bytes.NewReader(re)); err != nil {
681+
// fmt.Fprintf(os.Stderr, "Error: %v. ", err)
682+
// os.Exit(1)
683+
// }
684+
// data, err = w.CreatePart(part)
685+
// if err != nil {
686+
// fmt.Fprintf(os.Stderr, "Error: %v. ", err)
687+
// os.Exit(1)
688+
// }
689+
// if _, err = io.Copy(data, bytes.NewReader(pr)); err != nil {
690+
// fmt.Fprintf(os.Stderr, "Error: %v. ", err)
691+
// os.Exit(1)
692+
// }
693+
// w.Close()
694+
// r := &RequestParams{
695+
// Method: "POST",
696+
// APIURL: uploadurl + tokenparams.Encode(),
697+
// Data: &b,
698+
// Contenttype: w.FormDataContentType(),
699+
// Accesstoken: p.Accesstoken,
700+
// Dtime: 30,
701+
// }
702+
// body, err := r.FetchAPI()
703+
// if err != nil {
704+
// fmt.Fprintf(os.Stderr, "Error: %s\n%s\n", err, body)
705+
// os.Exit(1)
706+
// }
707+
// var uf uploadedFile
708+
// json.Unmarshal(body, &uf)
709+
// p.UppedFiles = append(p.UppedFiles, uf)
710+
// return p
711+
// }
708712

709713
// fileUploader : For uploading files.
710714
func (p *FileInf) fileUploader(metadata map[string]interface{}, file string) *FileInf {
@@ -778,6 +782,66 @@ func (p *FileInf) fileUploader(metadata map[string]interface{}, file string) *Fi
778782
return p
779783
}
780784

785+
// fileUpdater : Update a file metadata and file content.
786+
func (p *FileInf) fileUpdater(query url.Values, metadata map[string]interface{}, pr []byte) *FileInf {
787+
var urlStr string
788+
r := &RequestParams{
789+
Method: "PATCH",
790+
Accesstoken: p.Accesstoken,
791+
Dtime: 30,
792+
}
793+
if query == nil {
794+
query = url.Values{}
795+
}
796+
query.Set("fields", "createdTime,fullFileExtension,id,mimeType,modifiedTime,name,parents,size,webContentLink,webViewLink,lastModifyingUser(displayName,emailAddress),owners(displayName,emailAddress,permissionId)")
797+
if (metadata != nil && pr != nil) || (metadata == nil && pr != nil) {
798+
var b bytes.Buffer
799+
w := multipart.NewWriter(&b)
800+
part := make(textproto.MIMEHeader)
801+
part.Set("Content-Type", "application/json")
802+
data, err := w.CreatePart(part)
803+
if err != nil {
804+
fmt.Fprintf(os.Stderr, "Error: %v. ", err)
805+
os.Exit(1)
806+
}
807+
re, _ := json.Marshal(metadata)
808+
if _, err = io.Copy(data, bytes.NewReader(re)); err != nil {
809+
fmt.Fprintf(os.Stderr, "Error: %v. ", err)
810+
os.Exit(1)
811+
}
812+
data, err = w.CreatePart(part)
813+
if err != nil {
814+
fmt.Fprintf(os.Stderr, "Error: %v. ", err)
815+
os.Exit(1)
816+
}
817+
if _, err = io.Copy(data, bytes.NewReader(pr)); err != nil {
818+
fmt.Fprintf(os.Stderr, "Error: %v. ", err)
819+
os.Exit(1)
820+
}
821+
urlStr = updateurl + p.FileID + "?uploadType=multipart&" + query.Encode()
822+
r.Data = &b
823+
r.Contenttype = w.FormDataContentType()
824+
w.Close()
825+
} else if metadata != nil && pr == nil {
826+
urlStr = driveapiurl + p.FileID + "?" + query.Encode()
827+
meta, _ := json.Marshal(metadata)
828+
r.Data = bytes.NewBuffer(meta)
829+
r.Contenttype = "application/json"
830+
} else if metadata == nil && pr == nil {
831+
urlStr = driveapiurl + p.FileID + "?" + query.Encode()
832+
}
833+
r.APIURL = urlStr
834+
body, err := r.FetchAPI()
835+
if err != nil {
836+
fmt.Fprintf(os.Stderr, "Error: %s\n%s\n", err, body)
837+
os.Exit(1)
838+
}
839+
var uf uploadedFile
840+
json.Unmarshal(body, &uf)
841+
p.UppedFiles = append(p.UppedFiles, uf)
842+
return p
843+
}
844+
781845
// Uploader : Main method for uploading
782846
// "$ ggsrun u -f t1.gs,t2.gs" or "$ ggsrun u -f "t1.gs, t2.gs""
783847
// Upload type is automatically selected by the file size.
@@ -812,21 +876,8 @@ func (p *FileInf) Uploader(c *cli.Context) *FileInf {
812876
if p.UseServiceAccount != "" {
813877
return p.whenServiceAccountIsUsed()
814878
}
815-
var pr project
816-
filedata := &filea{
817-
Name: metadata.Name,
818-
Type: "server_js",
819-
Source: ConvGasToUpload(elm),
820-
}
821-
pr.Files = append(pr.Files, *filedata)
822-
pre, _ := json.Marshal(pr)
823-
upmeta, _ := json.Marshal(metadata)
824-
var u map[string]interface{}
825-
json.Unmarshal(upmeta, &u)
826-
if len(c.String("parentfolderid")) == 0 {
827-
delete(u, "parents")
828-
}
829-
_ = p.scriptUploader(u, pre)
879+
c.Set("projectname", metadata.Name)
880+
p.createProjectMain(c)
830881
p.Msgar = append(p.Msgar, fmt.Sprintf("Uploaded %s as %s. ", filepath.Base(elm), metadata.Name))
831882
} else {
832883
upmeta, _ := json.Marshal(metadata)
@@ -845,20 +896,7 @@ func (p *FileInf) Uploader(c *cli.Context) *FileInf {
845896
}
846897
if p.ParentID == "" {
847898
if p.ProjectType == "standalone" {
848-
metadata := &fileUploaderMeta{
849-
Name: c.String("projectname"),
850-
Parents: []string{c.String("parentfolderid")},
851-
MimeType: "application/vnd.google-apps.script",
852-
}
853-
upmeta, _ := json.Marshal(metadata)
854-
var u map[string]interface{}
855-
json.Unmarshal(upmeta, &u)
856-
if len(c.String("parentfolderid")) == 0 {
857-
delete(u, "parents")
858-
}
859-
pre := p.createProject(c.String("timezone"))
860-
_ = p.scriptUploader(u, pre)
861-
p.createdprojectresult(len(p.UpFilename), metadata.Name)
899+
p.createProjectMain(c)
862900
} else {
863901
parentId := p.createGoogleDocs(c)
864902
p.createProjectInGoogleDocs(c, parentId)
@@ -876,20 +914,46 @@ func (p *FileInf) Uploader(c *cli.Context) *FileInf {
876914
return p
877915
}
878916

879-
// createProjectInGoogleDocs : Create new project as a bound script.
880-
func (p *FileInf) createProjectInGoogleDocs(c *cli.Context, parentId string) {
881-
metadata := &newProject{
882-
ParentId: parentId,
883-
Title: c.String("projectname"),
884-
}
917+
// createNewProject : Create new project.
918+
func (p *FileInf) createNewProject(c *cli.Context, metadata *newProject) {
885919
meta, _ := json.Marshal(metadata)
886920
asi := p.boundScriptCreator(meta)
921+
p.FileID = asi.ScriptId
887922
manifests := p.getBoundScript(asi.ScriptId).getManifests(c.String("timezone"))
888923
pre := p.createProjectForAppsScriptApi(asi.ScriptId).setManifests(manifests)
889924
_ = p.ProjectUpdateByAppsScriptApi(pre)
890925
p.createdprojectresult(len(p.UpFilename), metadata.Title)
891926
}
892927

928+
// createProjectAsStandalone : Create new project as a standalone script type.
929+
func (p *FileInf) createProjectAsStandalone(c *cli.Context) {
930+
metadata := &newProject{
931+
Title: c.String("projectname"),
932+
}
933+
p.createNewProject(c, metadata)
934+
}
935+
936+
// createProjectInGoogleDocs : Create new project as a bound script type.
937+
func (p *FileInf) createProjectInGoogleDocs(c *cli.Context, parentID string) {
938+
metadata := &newProject{
939+
ParentId: parentID,
940+
Title: c.String("projectname"),
941+
}
942+
p.createNewProject(c, metadata)
943+
}
944+
945+
// createProjectMain : Main method for creating new GAS project.
946+
func (p *FileInf) createProjectMain(c *cli.Context) {
947+
p.createProjectAsStandalone(c)
948+
p.createdprojectresult(len(p.UpFilename), c.String("projectname"))
949+
if c.String("parentfolderid") != "" {
950+
query := url.Values{}
951+
query.Set("addParents", c.String("parentfolderid"))
952+
query.Set("removeParents", "root")
953+
p.fileUpdater(query, nil, nil)
954+
}
955+
}
956+
893957
// createGoogleDocs : Create new Google Docs (spreadsheet, document, slide and form)
894958
func (p *FileInf) createGoogleDocs(c *cli.Context) string {
895959
metadata := &fileUploaderMeta{

0 commit comments

Comments
 (0)