github.com/artpar/rclone@v1.67.3/backend/pikpak/api/types.go (about)

     1  // Package api has type definitions for pikpak
     2  //
     3  // Manually obtained from the API responses using Browse Dev. Tool and https://mholt.github.io/json-to-go/
     4  package api
     5  
     6  import (
     7  	"fmt"
     8  	"reflect"
     9  	"strconv"
    10  	"time"
    11  )
    12  
    13  const (
    14  	// "2022-09-17T14:31:06.056+08:00"
    15  	timeFormat = `"` + time.RFC3339 + `"`
    16  )
    17  
    18  // Time represents date and time information for the pikpak API, by using RFC3339
    19  type Time time.Time
    20  
    21  // MarshalJSON turns a Time into JSON (in UTC)
    22  func (t *Time) MarshalJSON() (out []byte, err error) {
    23  	timeString := (*time.Time)(t).Format(timeFormat)
    24  	return []byte(timeString), nil
    25  }
    26  
    27  // UnmarshalJSON turns JSON into a Time
    28  func (t *Time) UnmarshalJSON(data []byte) error {
    29  	if string(data) == "null" || string(data) == `""` {
    30  		return nil
    31  	}
    32  	newT, err := time.Parse(timeFormat, string(data))
    33  	if err != nil {
    34  		return err
    35  	}
    36  	*t = Time(newT)
    37  	return nil
    38  }
    39  
    40  // Types of things in Item
    41  const (
    42  	KindOfFolder        = "drive#folder"
    43  	KindOfFile          = "drive#file"
    44  	KindOfFileList      = "drive#fileList"
    45  	KindOfResumable     = "drive#resumable"
    46  	KindOfForm          = "drive#form"
    47  	ThumbnailSizeS      = "SIZE_SMALL"
    48  	ThumbnailSizeM      = "SIZE_MEDIUM"
    49  	ThumbnailSizeL      = "SIZE_LARGE"
    50  	PhaseTypeComplete   = "PHASE_TYPE_COMPLETE"
    51  	PhaseTypeRunning    = "PHASE_TYPE_RUNNING"
    52  	PhaseTypeError      = "PHASE_TYPE_ERROR"
    53  	PhaseTypePending    = "PHASE_TYPE_PENDING"
    54  	UploadTypeForm      = "UPLOAD_TYPE_FORM"
    55  	UploadTypeResumable = "UPLOAD_TYPE_RESUMABLE"
    56  	ListLimit           = 100
    57  )
    58  
    59  // ------------------------------------------------------------
    60  
    61  // Error details api error from pikpak
    62  type Error struct {
    63  	Reason  string `json:"error"` // short description of the reason, e.g. "file_name_empty" "invalid_request"
    64  	Code    int    `json:"error_code"`
    65  	URL     string `json:"error_url,omitempty"`
    66  	Message string `json:"error_description,omitempty"`
    67  	// can have either of `error_details` or `details``
    68  	ErrorDetails []*ErrorDetails `json:"error_details,omitempty"`
    69  	Details      []*ErrorDetails `json:"details,omitempty"`
    70  }
    71  
    72  // ErrorDetails contains further details of api error
    73  type ErrorDetails struct {
    74  	Type         string        `json:"@type,omitempty"`
    75  	Reason       string        `json:"reason,omitempty"`
    76  	Domain       string        `json:"domain,omitempty"`
    77  	Metadata     struct{}      `json:"metadata,omitempty"` // TODO: undiscovered yet
    78  	Locale       string        `json:"locale,omitempty"`   // e.g. "en"
    79  	Message      string        `json:"message,omitempty"`
    80  	StackEntries []interface{} `json:"stack_entries,omitempty"` // TODO: undiscovered yet
    81  	Detail       string        `json:"detail,omitempty"`
    82  }
    83  
    84  // Error returns a string for the error and satisfies the error interface
    85  func (e *Error) Error() string {
    86  	out := fmt.Sprintf("Error %q (%d)", e.Reason, e.Code)
    87  	if e.Message != "" {
    88  		out += ": " + e.Message
    89  	}
    90  	return out
    91  }
    92  
    93  // Check Error satisfies the error interface
    94  var _ error = (*Error)(nil)
    95  
    96  // ------------------------------------------------------------
    97  
    98  // Filters contains parameters for filters when listing.
    99  //
   100  // possible operators
   101  // * in: a list of comma-separated string
   102  // * eq: "true" or "false"
   103  // * gt or lt: time format string, e.g. "2023-01-28T10:56:49.757+08:00"
   104  type Filters struct {
   105  	Phase        map[string]string `json:"phase,omitempty"`         // "in" or "eq"
   106  	Trashed      map[string]bool   `json:"trashed,omitempty"`       // "eq"
   107  	Kind         map[string]string `json:"kind,omitempty"`          // "eq"
   108  	Starred      map[string]bool   `json:"starred,omitempty"`       // "eq"
   109  	ModifiedTime map[string]string `json:"modified_time,omitempty"` // "gt" or "lt"
   110  }
   111  
   112  // Set sets filter values using field name, operator and corresponding value
   113  func (f *Filters) Set(field, operator, value string) {
   114  	if value == "" {
   115  		// UNSET for empty values
   116  		return
   117  	}
   118  	r := reflect.ValueOf(f)
   119  	fd := reflect.Indirect(r).FieldByName(field)
   120  	if v, err := strconv.ParseBool(value); err == nil {
   121  		fd.Set(reflect.ValueOf(map[string]bool{operator: v}))
   122  	} else {
   123  		fd.Set(reflect.ValueOf(map[string]string{operator: value}))
   124  	}
   125  }
   126  
   127  // ------------------------------------------------------------
   128  // Common Elements
   129  
   130  // Link contains a download URL for opening files
   131  type Link struct {
   132  	URL    string `json:"url"`
   133  	Token  string `json:"token"`
   134  	Expire Time   `json:"expire"`
   135  	Type   string `json:"type,omitempty"`
   136  }
   137  
   138  // Valid reports whether l is non-nil, has an URL, and is not expired.
   139  func (l *Link) Valid() bool {
   140  	return l != nil && l.URL != "" && time.Now().Add(10*time.Second).Before(time.Time(l.Expire))
   141  }
   142  
   143  // URL is a basic form of URL
   144  type URL struct {
   145  	Kind string `json:"kind,omitempty"` // e.g. "upload#url"
   146  	URL  string `json:"url,omitempty"`
   147  }
   148  
   149  // ------------------------------------------------------------
   150  // Base Elements
   151  
   152  // FileList contains a list of File elements
   153  type FileList struct {
   154  	Kind            string  `json:"kind,omitempty"` // drive#fileList
   155  	Files           []*File `json:"files,omitempty"`
   156  	NextPageToken   string  `json:"next_page_token"`
   157  	Version         string  `json:"version,omitempty"`
   158  	VersionOutdated bool    `json:"version_outdated,omitempty"`
   159  }
   160  
   161  // File is a basic element representing a single file object
   162  //
   163  // There are two types of download links,
   164  // 1) one from File.WebContentLink or File.Links.ApplicationOctetStream.URL and
   165  // 2) the other from File.Medias[].Link.URL.
   166  // Empirically, 2) is less restrictive to multiple concurrent range-requests
   167  // for a single file, i.e. supports for higher `--multi-thread-streams=N`.
   168  // However, it is not generally applicable as it is only for meadia.
   169  type File struct {
   170  	Apps              []*FileApp    `json:"apps,omitempty"`
   171  	Audit             *FileAudit    `json:"audit,omitempty"`
   172  	Collection        string        `json:"collection,omitempty"` // TODO
   173  	CreatedTime       Time          `json:"created_time,omitempty"`
   174  	DeleteTime        Time          `json:"delete_time,omitempty"`
   175  	FileCategory      string        `json:"file_category,omitempty"`
   176  	FileExtension     string        `json:"file_extension,omitempty"`
   177  	FolderType        string        `json:"folder_type,omitempty"`
   178  	Hash              string        `json:"hash,omitempty"` // sha1 but NOT a valid file hash. looks like a torrent hash
   179  	IconLink          string        `json:"icon_link,omitempty"`
   180  	ID                string        `json:"id,omitempty"`
   181  	Kind              string        `json:"kind,omitempty"` // "drive#file"
   182  	Links             *FileLinks    `json:"links,omitempty"`
   183  	Md5Checksum       string        `json:"md5_checksum,omitempty"`
   184  	Medias            []*Media      `json:"medias,omitempty"`
   185  	MimeType          string        `json:"mime_type,omitempty"`
   186  	ModifiedTime      Time          `json:"modified_time,omitempty"` // updated when renamed or moved
   187  	Name              string        `json:"name,omitempty"`
   188  	OriginalFileIndex int           `json:"original_file_index,omitempty"` // TODO
   189  	OriginalURL       string        `json:"original_url,omitempty"`
   190  	Params            *FileParams   `json:"params,omitempty"`
   191  	ParentID          string        `json:"parent_id,omitempty"`
   192  	Phase             string        `json:"phase,omitempty"`
   193  	Revision          int           `json:"revision,omitempty,string"`
   194  	Size              int64         `json:"size,omitempty,string"`
   195  	SortName          string        `json:"sort_name,omitempty"`
   196  	Space             string        `json:"space,omitempty"`
   197  	SpellName         []interface{} `json:"spell_name,omitempty"` // TODO maybe list of something?
   198  	Starred           bool          `json:"starred,omitempty"`
   199  	ThumbnailLink     string        `json:"thumbnail_link,omitempty"`
   200  	Trashed           bool          `json:"trashed,omitempty"`
   201  	UserID            string        `json:"user_id,omitempty"`
   202  	UserModifiedTime  Time          `json:"user_modified_time,omitempty"`
   203  	WebContentLink    string        `json:"web_content_link,omitempty"`
   204  	Writable          bool          `json:"writable,omitempty"`
   205  }
   206  
   207  // FileLinks includes links to file at backend
   208  type FileLinks struct {
   209  	ApplicationOctetStream *Link `json:"application/octet-stream,omitempty"`
   210  }
   211  
   212  // FileAudit contains audit information for the file
   213  type FileAudit struct {
   214  	Status  string `json:"status,omitempty"` // "STATUS_OK"
   215  	Message string `json:"message,omitempty"`
   216  	Title   string `json:"title,omitempty"`
   217  }
   218  
   219  // Media contains info about supported version of media, e.g. original, transcoded, etc
   220  type Media struct {
   221  	MediaID   string `json:"media_id,omitempty"`
   222  	MediaName string `json:"media_name,omitempty"`
   223  	Video     struct {
   224  		Height     int    `json:"height,omitempty"`
   225  		Width      int    `json:"width,omitempty"`
   226  		Duration   int64  `json:"duration,omitempty"`
   227  		BitRate    int    `json:"bit_rate,omitempty"`
   228  		FrameRate  int    `json:"frame_rate,omitempty"`
   229  		VideoCodec string `json:"video_codec,omitempty"` // "h264", "hevc"
   230  		AudioCodec string `json:"audio_codec,omitempty"` // "pcm_bluray", "aac"
   231  		VideoType  string `json:"video_type,omitempty"`  // "mpegts"
   232  		HdrType    string `json:"hdr_type,omitempty"`
   233  	} `json:"video,omitempty"`
   234  	Link           *Link         `json:"link,omitempty"`
   235  	NeedMoreQuota  bool          `json:"need_more_quota,omitempty"`
   236  	VipTypes       []interface{} `json:"vip_types,omitempty"` // TODO maybe list of something?
   237  	RedirectLink   string        `json:"redirect_link,omitempty"`
   238  	IconLink       string        `json:"icon_link,omitempty"`
   239  	IsDefault      bool          `json:"is_default,omitempty"`
   240  	Priority       int           `json:"priority,omitempty"`
   241  	IsOrigin       bool          `json:"is_origin,omitempty"`
   242  	ResolutionName string        `json:"resolution_name,omitempty"`
   243  	IsVisible      bool          `json:"is_visible,omitempty"`
   244  	Category       string        `json:"category,omitempty"`
   245  }
   246  
   247  // FileParams includes parameters for instant open
   248  type FileParams struct {
   249  	Duration     int64  `json:"duration,omitempty,string"` // in seconds
   250  	Height       int    `json:"height,omitempty,string"`
   251  	Platform     string `json:"platform,omitempty"` // "Upload"
   252  	PlatformIcon string `json:"platform_icon,omitempty"`
   253  	URL          string `json:"url,omitempty"`
   254  	Width        int    `json:"width,omitempty,string"`
   255  }
   256  
   257  // FileApp includes parameters for instant open
   258  type FileApp struct {
   259  	ID            string        `json:"id,omitempty"`   // "decompress" for rar files
   260  	Name          string        `json:"name,omitempty"` // decompress" for rar files
   261  	Access        []interface{} `json:"access,omitempty"`
   262  	Link          string        `json:"link,omitempty"` // "https://mypikpak.com/drive/decompression/{File.Id}?gcid={File.Hash}\u0026wv-style=topbar%3Ahide"
   263  	RedirectLink  string        `json:"redirect_link,omitempty"`
   264  	VipTypes      []interface{} `json:"vip_types,omitempty"`
   265  	NeedMoreQuota bool          `json:"need_more_quota,omitempty"`
   266  	IconLink      string        `json:"icon_link,omitempty"`
   267  	IsDefault     bool          `json:"is_default,omitempty"`
   268  	Params        struct{}      `json:"params,omitempty"` // TODO
   269  	CategoryIDs   []interface{} `json:"category_ids,omitempty"`
   270  	AdSceneType   int           `json:"ad_scene_type,omitempty"`
   271  	Space         string        `json:"space,omitempty"`
   272  	Links         struct{}      `json:"links,omitempty"` // TODO
   273  }
   274  
   275  // ------------------------------------------------------------
   276  
   277  // TaskList contains a list of Task elements
   278  type TaskList struct {
   279  	Tasks         []*Task `json:"tasks,omitempty"` // "drive#task"
   280  	NextPageToken string  `json:"next_page_token"`
   281  	ExpiresIn     int     `json:"expires_in,omitempty"`
   282  }
   283  
   284  // Task is a basic element representing a single task such as offline download and upload
   285  type Task struct {
   286  	Kind              string        `json:"kind,omitempty"` // "drive#task"
   287  	ID                string        `json:"id,omitempty"`   // task id?
   288  	Name              string        `json:"name,omitempty"` // torrent name?
   289  	Type              string        `json:"type,omitempty"` // "offline"
   290  	UserID            string        `json:"user_id,omitempty"`
   291  	Statuses          []interface{} `json:"statuses,omitempty"`    // TODO
   292  	StatusSize        int           `json:"status_size,omitempty"` // TODO
   293  	Params            *TaskParams   `json:"params,omitempty"`      // TODO
   294  	FileID            string        `json:"file_id,omitempty"`
   295  	FileName          string        `json:"file_name,omitempty"`
   296  	FileSize          string        `json:"file_size,omitempty"`
   297  	Message           string        `json:"message,omitempty"` // e.g. "Saving"
   298  	CreatedTime       Time          `json:"created_time,omitempty"`
   299  	UpdatedTime       Time          `json:"updated_time,omitempty"`
   300  	ThirdTaskID       string        `json:"third_task_id,omitempty"` // TODO
   301  	Phase             string        `json:"phase,omitempty"`         // e.g. "PHASE_TYPE_RUNNING"
   302  	Progress          int           `json:"progress,omitempty"`
   303  	IconLink          string        `json:"icon_link,omitempty"`
   304  	Callback          string        `json:"callback,omitempty"`
   305  	ReferenceResource interface{}   `json:"reference_resource,omitempty"` // TODO
   306  	Space             string        `json:"space,omitempty"`
   307  }
   308  
   309  // TaskParams includes parameters informing status of Task
   310  type TaskParams struct {
   311  	Age          string `json:"age,omitempty"`
   312  	PredictSpeed string `json:"predict_speed,omitempty"`
   313  	PredictType  string `json:"predict_type,omitempty"`
   314  	URL          string `json:"url,omitempty"`
   315  }
   316  
   317  // Form contains parameters for upload by multipart/form-data
   318  type Form struct {
   319  	Headers    struct{} `json:"headers"`
   320  	Kind       string   `json:"kind"`   // "drive#form"
   321  	Method     string   `json:"method"` // "POST"
   322  	MultiParts struct {
   323  		OSSAccessKeyID string `json:"OSSAccessKeyId"`
   324  		Signature      string `json:"Signature"`
   325  		Callback       string `json:"callback"`
   326  		Key            string `json:"key"`
   327  		Policy         string `json:"policy"`
   328  		XUserData      string `json:"x:user_data"`
   329  	} `json:"multi_parts"`
   330  	URL string `json:"url"`
   331  }
   332  
   333  // Resumable contains parameters for upload by resumable
   334  type Resumable struct {
   335  	Kind     string           `json:"kind,omitempty"`     // "drive#resumable"
   336  	Provider string           `json:"provider,omitempty"` // e.g. "PROVIDER_ALIYUN"
   337  	Params   *ResumableParams `json:"params,omitempty"`
   338  }
   339  
   340  // ResumableParams specifies resumable paramegers
   341  type ResumableParams struct {
   342  	AccessKeyID     string `json:"access_key_id,omitempty"`
   343  	AccessKeySecret string `json:"access_key_secret,omitempty"`
   344  	Bucket          string `json:"bucket,omitempty"`
   345  	Endpoint        string `json:"endpoint,omitempty"`
   346  	Expiration      Time   `json:"expiration,omitempty"`
   347  	Key             string `json:"key,omitempty"`
   348  	SecurityToken   string `json:"security_token,omitempty"`
   349  }
   350  
   351  // FileInArchive is a basic element in archive
   352  type FileInArchive struct {
   353  	Index    int    `json:"index,omitempty"`
   354  	Filename string `json:"filename,omitempty"`
   355  	Filesize string `json:"filesize,omitempty"`
   356  	MimeType string `json:"mime_type,omitempty"`
   357  	Gcid     string `json:"gcid,omitempty"`
   358  	Kind     string `json:"kind,omitempty"`
   359  	IconLink string `json:"icon_link,omitempty"`
   360  	Path     string `json:"path,omitempty"`
   361  }
   362  
   363  // ------------------------------------------------------------
   364  
   365  // NewFile is a response to RequestNewFile
   366  type NewFile struct {
   367  	File       *File      `json:"file,omitempty"`
   368  	Form       *Form      `json:"form,omitempty"`
   369  	Resumable  *Resumable `json:"resumable,omitempty"`
   370  	Task       *Task      `json:"task,omitempty"`        // null in this case
   371  	UploadType string     `json:"upload_type,omitempty"` // "UPLOAD_TYPE_FORM" or "UPLOAD_TYPE_RESUMABLE"
   372  }
   373  
   374  // NewTask is a response to RequestNewTask
   375  type NewTask struct {
   376  	UploadType string `json:"upload_type,omitempty"` // "UPLOAD_TYPE_URL"
   377  	File       *File  `json:"file,omitempty"`        // null in this case
   378  	Task       *Task  `json:"task,omitempty"`
   379  	URL        *URL   `json:"url,omitempty"` // {"kind": "upload#url"}
   380  }
   381  
   382  // About informs drive status
   383  type About struct {
   384  	Kind      string   `json:"kind,omitempty"` // "drive#about"
   385  	Quota     *Quota   `json:"quota,omitempty"`
   386  	ExpiresAt string   `json:"expires_at,omitempty"`
   387  	Quotas    struct{} `json:"quotas,omitempty"` // maybe []*Quota?
   388  }
   389  
   390  // Quota informs drive quota
   391  type Quota struct {
   392  	Kind           string `json:"kind,omitempty"`                  // "drive#quota"
   393  	Limit          int64  `json:"limit,omitempty,string"`          // limit in bytes
   394  	Usage          int64  `json:"usage,omitempty,string"`          // bytes in use
   395  	UsageInTrash   int64  `json:"usage_in_trash,omitempty,string"` // bytes in trash but this seems not working
   396  	PlayTimesLimit string `json:"play_times_limit,omitempty"`      // maybe in seconds
   397  	PlayTimesUsage string `json:"play_times_usage,omitempty"`      // maybe in seconds
   398  }
   399  
   400  // Share is a response to RequestShare
   401  //
   402  // used in PublicLink()
   403  type Share struct {
   404  	ShareID   string `json:"share_id,omitempty"`
   405  	ShareURL  string `json:"share_url,omitempty"`
   406  	PassCode  string `json:"pass_code,omitempty"`
   407  	ShareText string `json:"share_text,omitempty"`
   408  }
   409  
   410  // User contains user account information
   411  //
   412  // GET https://user.mypikpak.com/v1/user/me
   413  type User struct {
   414  	Sub               string          `json:"sub,omitempty"`       // userid for internal use
   415  	Name              string          `json:"name,omitempty"`      // Username
   416  	Picture           string          `json:"picture,omitempty"`   // URL to Avatar image
   417  	Email             string          `json:"email,omitempty"`     // redacted email address
   418  	Providers         *[]UserProvider `json:"providers,omitempty"` // OAuth provider
   419  	PhoneNumber       string          `json:"phone_number,omitempty"`
   420  	Password          string          `json:"password,omitempty"` // "SET" if configured
   421  	Status            string          `json:"status,omitempty"`   // "ACTIVE"
   422  	CreatedAt         Time            `json:"created_at,omitempty"`
   423  	PasswordUpdatedAt Time            `json:"password_updated_at,omitempty"`
   424  }
   425  
   426  // UserProvider details third-party authentication
   427  type UserProvider struct {
   428  	ID             string `json:"id,omitempty"` // e.g. "google.com"
   429  	ProviderUserID string `json:"provider_user_id,omitempty"`
   430  	Name           string `json:"name,omitempty"` // username
   431  }
   432  
   433  // VIP includes subscription details about premium account
   434  //
   435  // GET https://api-drive.mypikpak.com/drive/v1/privilege/vip
   436  type VIP struct {
   437  	Result      string `json:"result,omitempty"` // "ACCEPTED"
   438  	Message     string `json:"message,omitempty"`
   439  	RedirectURI string `json:"redirect_uri,omitempty"`
   440  	Data        struct {
   441  		Expire Time   `json:"expire,omitempty"`
   442  		Status string `json:"status,omitempty"`  // "invalid" or "ok"
   443  		Type   string `json:"type,omitempty"`    // "novip" or "platinum"
   444  		UserID string `json:"user_id,omitempty"` // same as User.Sub
   445  	} `json:"data,omitempty"`
   446  }
   447  
   448  // DecompressResult is a response to RequestDecompress
   449  type DecompressResult struct {
   450  	Status       string `json:"status,omitempty"` // "OK"
   451  	StatusText   string `json:"status_text,omitempty"`
   452  	TaskID       string `json:"task_id,omitempty"`   // same as File.Id
   453  	FilesNum     int    `json:"files_num,omitempty"` // number of files in archive
   454  	RedirectLink string `json:"redirect_link,omitempty"`
   455  }
   456  
   457  // ------------------------------------------------------------
   458  
   459  // RequestShare is to request for file share
   460  type RequestShare struct {
   461  	FileIDs        []string `json:"file_ids,omitempty"`
   462  	ShareTo        string   `json:"share_to,omitempty"`         // "publiclink",
   463  	ExpirationDays int      `json:"expiration_days,omitempty"`  // -1 = 'forever'
   464  	PassCodeOption string   `json:"pass_code_option,omitempty"` // "NOT_REQUIRED"
   465  }
   466  
   467  // RequestBatch is to request for batch actions
   468  type RequestBatch struct {
   469  	IDs []string          `json:"ids,omitempty"`
   470  	To  map[string]string `json:"to,omitempty"`
   471  }
   472  
   473  // RequestNewFile is to request for creating a new `drive#folder` or `drive#file`
   474  type RequestNewFile struct {
   475  	// always required
   476  	Kind       string `json:"kind"` // "drive#folder" or "drive#file"
   477  	Name       string `json:"name"`
   478  	ParentID   string `json:"parent_id"`
   479  	FolderType string `json:"folder_type"`
   480  	// only when uploading a new file
   481  	Hash       string            `json:"hash,omitempty"`      // sha1sum
   482  	Resumable  map[string]string `json:"resumable,omitempty"` // {"provider": "PROVIDER_ALIYUN"}
   483  	Size       int64             `json:"size,omitempty"`
   484  	UploadType string            `json:"upload_type,omitempty"` // "UPLOAD_TYPE_FORM" or "UPLOAD_TYPE_RESUMABLE"
   485  }
   486  
   487  // RequestNewTask is to request for creating a new task like offline downloads
   488  //
   489  // Name and ParentID can be left empty.
   490  type RequestNewTask struct {
   491  	Kind       string `json:"kind,omitempty"` // "drive#file"
   492  	Name       string `json:"name,omitempty"`
   493  	ParentID   string `json:"parent_id,omitempty"`
   494  	UploadType string `json:"upload_type,omitempty"` // "UPLOAD_TYPE_URL"
   495  	URL        *URL   `json:"url,omitempty"`         // {"url": downloadUrl}
   496  	FolderType string `json:"folder_type,omitempty"` // "" if parent_id else "DOWNLOAD"
   497  }
   498  
   499  // RequestDecompress is to request for decompress of archive files
   500  type RequestDecompress struct {
   501  	Gcid          string           `json:"gcid,omitempty"`     // same as File.Hash
   502  	Password      string           `json:"password,omitempty"` // ""
   503  	FileID        string           `json:"file_id,omitempty"`
   504  	Files         []*FileInArchive `json:"files,omitempty"` // can request selected files to be decompressed
   505  	DefaultParent bool             `json:"default_parent,omitempty"`
   506  }
   507  
   508  // ------------------------------------------------------------
   509  
   510  // NOT implemented YET
   511  
   512  // RequestArchiveFileList is to request for a list of files in archive
   513  //
   514  // POST https://api-drive.mypikpak.com/decompress/v1/list
   515  type RequestArchiveFileList struct {
   516  	Gcid     string `json:"gcid,omitempty"`     // same as api.File.Hash
   517  	Path     string `json:"path,omitempty"`     // "" by default
   518  	Password string `json:"password,omitempty"` // "" by default
   519  	FileID   string `json:"file_id,omitempty"`
   520  }
   521  
   522  // ArchiveFileList is a response to RequestArchiveFileList
   523  type ArchiveFileList struct {
   524  	Status      string           `json:"status,omitempty"`       // "OK"
   525  	StatusText  string           `json:"status_text,omitempty"`  // ""
   526  	TaskID      string           `json:"task_id,omitempty"`      // ""
   527  	CurrentPath string           `json:"current_path,omitempty"` // ""
   528  	Title       string           `json:"title,omitempty"`
   529  	FileSize    int64            `json:"file_size,omitempty"`
   530  	Gcid        string           `json:"gcid,omitempty"` // same as File.Hash
   531  	Files       []*FileInArchive `json:"files,omitempty"`
   532  }