func (p *FileInf) Downloader(c *cli.Context) *FileInf {
	if p.MimeType == "application/vnd.google-apps.folder" {
		err := p.DlFolders()
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error: %s", err)
			os.Exit(1)
		}
		p.TotalEt = math.Trunc(time.Now().Sub(p.PstartTime).Seconds()*1000) / 1000
		return p
	}
	ext := strings.ToLower(p.WantExt)
	if len(ext) > 0 {
		p.DlMime = extToMime(ext)
	} else {
		p.DlMime, ext = defFormat(p.MimeType)
	}
	if len(p.FileID) > 0 && c.String("deletefile") == "" {
		var gm map[string]interface{}
		json.Unmarshal([]byte(googlemimetypes), &gm)
		if gm["exportFormats"].(map[string]interface{})[p.MimeType] != nil {
			for _, e := range gm["exportFormats"].(map[string]interface{})[p.MimeType].([]interface{}) {
				if e == p.DlMime {
					p.SaveName = p.FileName + "." + ext
				}
			}
			if len(p.SaveName) == 0 {
				dispRes, _ := json.MarshalIndent(gm["exportFormats"], "", "  ")
				fmt.Fprintf(os.Stderr, "Error: Bad extension or No extension. It supports as follows.\n%s ", string(dispRes))
				os.Exit(1)
			}
			if p.MimeType == "application/vnd.google-apps.script" {
				u, _ := url.Parse(appsscriptapi)
				u.Path = path.Join(u.Path, p.FileID+"/content")
				p.writeFile(u.String())
			} else if p.MimeType != "" {
				p.writeFile(driveapiurl + p.FileID + "/export?mimeType=" + p.DlMime)
			}
		} else {
			p.SaveName = p.FileName
			p.writeFile(driveapiurl + p.FileID + "?alt=media")
		}
	} else if c.String("deletefile") != "" {
		p.deleteFile(c.String("deletefile"))
		p.Msgar = append(p.Msgar, fmt.Sprintf("File with fileId '%s' was deleted.", c.String("deletefile")))
	} else {
		p.Msgar = append(p.Msgar, "Error: Please input File Name or File ID. Please check HELP using 'ggsrun d --help'.")
	}
	p.TotalEt = math.Trunc(time.Now().Sub(p.PstartTime).Seconds()*1000) / 1000
	return p
}
Downloader : Download files.
package utl
import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"math"
	"mime/multipart"
	"net/textproto"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"
	"github.com/urfave/cli"
)
const (
	driveapiv3          = "https://www.googleapis.com/drive/v3"
	lurl                = "https://www.googleapis.com/drive/v3/files?"
	driveapiurl         = "https://www.googleapis.com/drive/v3/files/"
	driveapiurlv2       = "https://www.googleapis.com/drive/v2/files/"
	uploadurl           = "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&"
	updateurl           = "https://www.googleapis.com/upload/drive/v3/files/"
	lengthOfProjectId   = 57
	maxSizeForMultipart = 5242880
)
type FileInf struct {
	ProjectID         string            `json:"project_id,omitempty"`
	ParentID          string            `json:"parentId,omitempty"`
	RevisionID        string            `json:"revisionid,omitempty"`
	FileID            string            `json:"id,omitempty"`
	FileName          string            `json:"name,omitempty"`
	SaveName          string            `json:"saved_file_name,omitempty"`
	MimeType          string            `json:"mimeType,omitempty"`
	UpFilename        []string          `json:"upload_file_name,omitempty"`
	UpFileID          []string          `json:"uid,omitempty"`
	Parents           []string          `json:"parents,omitempty"`
	FileSize          string            `json:"size,omitempty"`
	WebLink           string            `json:"webContentLink,omitempty"`
	WebView           string            `json:"webViewLink,omitempty"`
	CreatedTime       *time.Time        `json:"createdTime,omitempty"`
	ModifiedTime      *time.Time        `json:"modifiedTime,omitempty"`
	UppedFiles        []uploadedFile    `json:"uploaded_files,omitempty"`
	LastModifyingUser *lastmodifieduser `json:"lastModifyingUser,omitempty"`
	Owners            []owners          `json:"owners,omitempty"`
	Msgar             []string          `json:"message,omitempty"`
	TotalEt           float64           `json:"TotalElapsedTime,omitempty"`
	FolderTree        *fileListDl       `json:"folderTreeWithFiles,omitempty"`
	SearchQuery       string            `json:"query,omitempty"`
	SearchFields      string            `json:"fields,omitempty"`
	SearchRegex       string            `json:"regex,omitempty"`
	SearchedFiles     []fileS           `json:"searchedFiles,omitempty"`
	SearchedResult    string            `json:"searchedResult,omitempty"`
	InputtedMimeType  []string          `json:"inputtedMimeType,omitempty"`
	ReturnedResult    interface{}       `json:"returnedResult,omitempty"`
	Accesstoken       string        `json:"-"`
	BoundScriptName   string        `json:"-"`
	ChunkSize         int64         `json:"-"`
	ConvertTo         string        `json:"-"`
	DlMime            string        `json:"-"`
	GoogleDocName     string        `json:"-"`
	OverWrite         bool          `json:"-"`
	PermissionInfo    permissionInf `json:"-"`
	Progress          bool          `json:"-"`
	ProjectType       string        `json:"-"`
	PstartTime        time.Time     `json:"-"`
	RawProject        bool          `json:"-"`
	SearchByName      string        `json:"-"`
	SearchByID        string        `json:"-"`
	ShowFileInf       bool          `json:"-"`
	Size              int64         `json:"-"`
	Skip              bool          `json:"-"`
	UseServiceAccount string        `json:"-"`
	WantExt           string        `json:"-"`
	WantName          string        `json:"-"`
	Workdir           string        `json:"-"`
	Zip               bool          `json:"-"`
}
type owners struct {
	Name         string `json:"displayName,omitempty"`
	PermissionID string `json:"permissionId"`
	Email        string `json:"emailAddress,omitempty"`
}
type lastmodifieduser struct {
	Name  string `json:"displayName,omitempty"`
	Email string `json:"emailAddress,omitempty"`
}
type dlError struct {
	Error struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	} `json:"error"`
}
type project struct {
	Files []struct {
		ID     string `json:"id,omitempty"`
		Name   string `json:"name"`
		Type   string `json:"type"`
		Source string `json:"source"`
	} `json:"files"`
}
type filea struct {
	ID     string `json:"id,omitempty"`
	Name   string `json:"name"`
	Type   string `json:"type"`
	Source string `json:"source"`
}
type newProject struct {
	ParentId string `json:"parentId,omitempty"`
	Title    string `json:"title"`
}
type fileS struct {
	Kind              string     `json:"kind,omitempty"`
	ID                string     `json:"id,omitempty"`
	Name              string     `json:"name,omitempty"`
	MimeType          string     `json:"mimeType,omitempty"`
	Starred           bool       `json:"starred,omitempty"`
	Trashed           bool       `json:"trashed,omitempty"`
	ExplicitlyTrashed bool       `json:"explicitlyTrashed,omitempty"`
	Parents           []string   `json:"parents,omitempty"`
	CreatedTime       *time.Time `json:"createdTime,omitempty"`
	ModifiedTime      *time.Time `json:"modifiedTime,omitempty"`
	ModifiedByMeTime  *time.Time `json:"modifiedByMeTime,omitempty"`
	ModifiedByMe      bool       `json:"modifiedByMe,omitempty"`
	FullFileExtension string     `json:"fullFileExtension,omitempty"`
	Size              string     `json:"size,omitempty"`
	Version           string     `json:"version,omitempty"`
	HasThumbnail      bool       `json:"hasThumbnail,omitempty"`
	ThumbnailVersion  string     `json:"thumbnailVersion,omitempty"`
	ViewedByMe        bool       `json:"viewedByMe,omitempty"`
	WebLink           string     `json:"webContentLink,omitempty"`
	WebView           string     `json:"webViewLink,omitempty"`
	Owners            []owners   `json:"owners,omitempty"`
	Shared            bool       `json:"shared,omitempty"`
	Permissions       []struct {
		Kind         string `json:"kind,omitempty"`
		ID           string `json:"id,omitempty"`
		Type         string `json:"type,omitempty"`
		EmailAddress string `json:"emailAddress,omitempty"`
		Role         string `json:"role,omitempty"`
		DisplayName  string `json:"displayName,omitempty"`
		PhotoLink    string `json:"photoLink,omitempty"`
		Deleted      bool   `json:"deleted,omitempty"`
	} `json:"permissions,omitempty"`
	OwnedByMe                    bool              `json:"ownedByMe,omitempty"`
	ViewersCanCopyContent        bool              `json:"viewersCanCopyContent,omitempty"`
	CopyRequiresWriterPermission bool              `json:"copyRequiresWriterPermission,omitempty"`
	WritersCanShare              bool              `json:"writersCanShare,omitempty"`
	PermissionIds                []string          `json:"permissionIds,omitempty"`
	FolderColorRgb               string            `json:"folderColorRgb,omitempty"`
	QuotaBytesUsed               string            `json:"quotaBytesUsed,omitempty"`
	IsAppAuthorized              bool              `json:"isAppAuthorized,omitempty"`
	Path                         string            `json:"path,omitempty"`
	OutMimeType                  string            `json:"outMimeType,omitempty"`
	LastModifyingUser            *lastmodifieduser `json:"lastModifyingUser,omitempty"`
}
type fileListSt struct {
	NextPageToken string  `json:"nextPageToken,omitempty"`
	Files         []fileS `json:"files,omitempty"`
}
type fileUploaderMeta struct {
	Name     string   `json:"name"`
	Parents  []string `json:"parents,omitempty"`
	MimeType string   `json:"mimeType"`
}
type uploadedFile struct {
	fileS
}
type dispDup struct {
	Name         string
	FileID       string
	MimeType     string
	ModifiedTime string
}
func (p *FileInf) saveScript(data []byte) *FileInf {
	var f project
	json.Unmarshal(data, &f)
	if p.RawProject {
		filename := filepath.Join(p.Workdir, p.FileName+".json")
		if chkFile(filename) && !p.OverWrite {
			if !p.Skip {
				fmt.Fprintf(os.Stderr, "Error: '%s' is exsinting. If you want to overwrite the file, please use option '--overwrite'.", filename)
				os.Exit(1)
			} else {
				if p.Progress {
					fmt.Printf("File of '%s' is not saved and skipped, because the file is duplicated.\n", filename)
				}
				p.Msgar = append(p.Msgar, fmt.Sprintf("File of '%s' was not saved and skipped, because the file is duplicated.", filename))
			}
		} else {
			p.SaveName = p.FileName + ".json"
			p.Msgar = append(p.Msgar, fmt.Sprintf("Saved project as a JSON file '%s.json'.", p.FileName))
			btok, _ := json.MarshalIndent(f, "", "\t")
			ioutil.WriteFile(filename, btok, 0777)
		}
	} else {
		p.SaveName = ""
		if len(f.Files) == 1 {
			p.Msgar = append(p.Msgar, fmt.Sprintf("%s has %d script.", p.FileName, len(f.Files)))
		} else {
			p.Msgar = append(p.Msgar, fmt.Sprintf("%s has %d scripts.", p.FileName, len(f.Files)))
		}
		zh := &zipFileHeads{}
		for _, e := range f.Files {
			eType := strings.ToLower(e.Type)
			saveName := p.FileName + "_" + e.Name + "." + func(ex, ty string) string {
				var eext string
				if len(ex) > 0 {
					eext = ex
				} else {
					switch ty {
					case "server_js":
						eext = "gs"
					case "html":
						eext = "html"
					case "json":
						eext = "json"
					default:
						eext = "txt"
					}
				}
				return eext
			}(p.WantExt, eType)
			z := &zipFileHead{
				Name:     saveName,
				Modified: p.PstartTime,
				Method:   8,
				Body:     []byte(e.Source),
			}
			zh.Files = append(zh.Files, *z)
		}
		if p.Zip {
			buf := zh.doFilesZip(p.zipComment())
			zn := p.FileName + ".zip"
			zipFileName := filepath.Join(p.Workdir, zn)
			if chkFile(zipFileName) && !p.OverWrite {
				if !p.Skip {
					fmt.Fprintf(os.Stderr, "Error: '%s' is exsinting. If you want to overwrite the file, please use option '--overwrite'.", zipFileName)
					os.Exit(1)
				} else {
					if p.Progress {
						fmt.Printf("File of '%s' is not saved and skipped, because the file is duplicated.\n", p.FileName)
					}
					p.Msgar = append(p.Msgar, fmt.Sprintf("File of '%s' was not saved and skipped, because the file is duplicated.", p.FileName))
				}
			} else {
				if p.Progress {
					fmt.Printf("Project file '%s' is downloaded.\n", p.FileName)
				}
				ioutil.WriteFile(zipFileName, buf.Bytes(), 0777)
				p.Msgar = append(p.Msgar, fmt.Sprintf("%d scripts in the project were saved as '%s'.", len(zh.Files), zn))
			}
		} else {
			for _, e := range zh.Files {
				scriptFileName := filepath.Join(p.Workdir, e.Name)
				if chkFile(scriptFileName) && !p.OverWrite {
					if !p.Skip {
						fmt.Fprintf(os.Stderr, "Error: '%s' is exsinting. If you want to overwrite the file, please use option '--overwrite'.", scriptFileName)
						os.Exit(1)
					} else {
						if p.Progress {
							fmt.Printf("File of '%s' is not saved and skipped, because the file is duplicated.\n", scriptFileName)
						}
						p.Msgar = append(p.Msgar, fmt.Sprintf("File of '%s' was not saved and skipped, because the file is duplicated.", scriptFileName))
					}
				} else {
					if p.Progress {
						fmt.Printf("Script '%s' is downloaded.\n", e.Name)
					}
					ioutil.WriteFile(scriptFileName, e.Body, 0777)
					p.Msgar = append(p.Msgar, fmt.Sprintf("Script was downloaded as '%s'.", e.Name))
				}
			}
		}
	}
	return p
}
func chkFile(name string) bool {
	_, err := os.Stat(name)
	return err == nil
}