github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/backend/b2/api/types.go (about)

     1  package api
     2  
     3  import (
     4  	"fmt"
     5  	"path"
     6  	"strconv"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/rclone/rclone/fs/fserrors"
    11  )
    12  
    13  // Error describes a B2 error response
    14  type Error struct {
    15  	Status  int    `json:"status"`  // The numeric HTTP status code. Always matches the status in the HTTP response.
    16  	Code    string `json:"code"`    // A single-identifier code that identifies the error.
    17  	Message string `json:"message"` // A human-readable message, in English, saying what went wrong.
    18  }
    19  
    20  // Error satisfies the error interface
    21  func (e *Error) Error() string {
    22  	return fmt.Sprintf("%s (%d %s)", e.Message, e.Status, e.Code)
    23  }
    24  
    25  // Fatal satisfies the Fatal interface
    26  //
    27  // It indicates which errors should be treated as fatal
    28  func (e *Error) Fatal() bool {
    29  	return e.Status == 403 // 403 errors shouldn't be retried
    30  }
    31  
    32  var _ fserrors.Fataler = (*Error)(nil)
    33  
    34  // Bucket describes a B2 bucket
    35  type Bucket struct {
    36  	ID        string `json:"bucketId"`
    37  	AccountID string `json:"accountId"`
    38  	Name      string `json:"bucketName"`
    39  	Type      string `json:"bucketType"`
    40  }
    41  
    42  // Timestamp is a UTC time when this file was uploaded. It is a base
    43  // 10 number of milliseconds since midnight, January 1, 1970 UTC. This
    44  // fits in a 64 bit integer such as the type "long" in the programming
    45  // language Java. It is intended to be compatible with Java's time
    46  // long. For example, it can be passed directly into the java call
    47  // Date.setTime(long time).
    48  type Timestamp time.Time
    49  
    50  // MarshalJSON turns a Timestamp into JSON (in UTC)
    51  func (t *Timestamp) MarshalJSON() (out []byte, err error) {
    52  	timestamp := (*time.Time)(t).UTC().UnixNano()
    53  	return []byte(strconv.FormatInt(timestamp/1e6, 10)), nil
    54  }
    55  
    56  // UnmarshalJSON turns JSON into a Timestamp
    57  func (t *Timestamp) UnmarshalJSON(data []byte) error {
    58  	timestamp, err := strconv.ParseInt(string(data), 10, 64)
    59  	if err != nil {
    60  		return err
    61  	}
    62  	*t = Timestamp(time.Unix(timestamp/1e3, (timestamp%1e3)*1e6).UTC())
    63  	return nil
    64  }
    65  
    66  const versionFormat = "-v2006-01-02-150405.000"
    67  
    68  // AddVersion adds the timestamp as a version string into the filename passed in.
    69  func (t Timestamp) AddVersion(remote string) string {
    70  	ext := path.Ext(remote)
    71  	base := remote[:len(remote)-len(ext)]
    72  	s := time.Time(t).Format(versionFormat)
    73  	// Replace the '.' with a '-'
    74  	s = strings.Replace(s, ".", "-", -1)
    75  	return base + s + ext
    76  }
    77  
    78  // RemoveVersion removes the timestamp from a filename as a version string.
    79  //
    80  // It returns the new file name and a timestamp, or the old filename
    81  // and a zero timestamp.
    82  func RemoveVersion(remote string) (t Timestamp, newRemote string) {
    83  	newRemote = remote
    84  	ext := path.Ext(remote)
    85  	base := remote[:len(remote)-len(ext)]
    86  	if len(base) < len(versionFormat) {
    87  		return
    88  	}
    89  	versionStart := len(base) - len(versionFormat)
    90  	// Check it ends in -xxx
    91  	if base[len(base)-4] != '-' {
    92  		return
    93  	}
    94  	// Replace with .xxx for parsing
    95  	base = base[:len(base)-4] + "." + base[len(base)-3:]
    96  	newT, err := time.Parse(versionFormat, base[versionStart:])
    97  	if err != nil {
    98  		return
    99  	}
   100  	return Timestamp(newT), base[:versionStart] + ext
   101  }
   102  
   103  // IsZero returns true if the timestamp is uninitialized
   104  func (t Timestamp) IsZero() bool {
   105  	return time.Time(t).IsZero()
   106  }
   107  
   108  // Equal compares two timestamps
   109  //
   110  // If either are !IsZero then it returns false
   111  func (t Timestamp) Equal(s Timestamp) bool {
   112  	if time.Time(t).IsZero() {
   113  		return false
   114  	}
   115  	if time.Time(s).IsZero() {
   116  		return false
   117  	}
   118  	return time.Time(t).Equal(time.Time(s))
   119  }
   120  
   121  // File is info about a file
   122  type File struct {
   123  	ID              string            `json:"fileId"`          // The unique identifier for this version of this file. Used with b2_get_file_info, b2_download_file_by_id, and b2_delete_file_version.
   124  	Name            string            `json:"fileName"`        // The name of this file, which can be used with b2_download_file_by_name.
   125  	Action          string            `json:"action"`          // Either "upload" or "hide". "upload" means a file that was uploaded to B2 Cloud Storage. "hide" means a file version marking the file as hidden, so that it will not show up in b2_list_file_names. The result of b2_list_file_names will contain only "upload". The result of b2_list_file_versions may have both.
   126  	Size            int64             `json:"size"`            // The number of bytes in the file.
   127  	UploadTimestamp Timestamp         `json:"uploadTimestamp"` // This is a UTC time when this file was uploaded.
   128  	SHA1            string            `json:"contentSha1"`     // The SHA1 of the bytes stored in the file.
   129  	ContentType     string            `json:"contentType"`     // The MIME type of the file.
   130  	Info            map[string]string `json:"fileInfo"`        // The custom information that was uploaded with the file. This is a JSON object, holding the name/value pairs that were uploaded with the file.
   131  }
   132  
   133  // AuthorizeAccountResponse is as returned from the b2_authorize_account call
   134  type AuthorizeAccountResponse struct {
   135  	AbsoluteMinimumPartSize int      `json:"absoluteMinimumPartSize"` // The smallest possible size of a part of a large file.
   136  	AccountID               string   `json:"accountId"`               // The identifier for the account.
   137  	Allowed                 struct { // An object (see below) containing the capabilities of this auth token, and any restrictions on using it.
   138  		BucketID     string      `json:"bucketId"`     // When present, access is restricted to one bucket.
   139  		BucketName   string      `json:"bucketName"`   // When present, name of bucket - may be empty
   140  		Capabilities []string    `json:"capabilities"` // A list of strings, each one naming a capability the key has.
   141  		NamePrefix   interface{} `json:"namePrefix"`   // When present, access is restricted to files whose names start with the prefix
   142  	} `json:"allowed"`
   143  	APIURL              string `json:"apiUrl"`              // The base URL to use for all API calls except for uploading and downloading files.
   144  	AuthorizationToken  string `json:"authorizationToken"`  // An authorization token to use with all calls, other than b2_authorize_account, that need an Authorization header.
   145  	DownloadURL         string `json:"downloadUrl"`         // The base URL to use for downloading files.
   146  	MinimumPartSize     int    `json:"minimumPartSize"`     // DEPRECATED: This field will always have the same value as recommendedPartSize. Use recommendedPartSize instead.
   147  	RecommendedPartSize int    `json:"recommendedPartSize"` // The recommended size for each part of a large file. We recommend using this part size for optimal upload performance.
   148  }
   149  
   150  // ListBucketsRequest is parameters for b2_list_buckets call
   151  type ListBucketsRequest struct {
   152  	AccountID   string   `json:"accountId"`             // The identifier for the account.
   153  	BucketID    string   `json:"bucketId,omitempty"`    // When specified, the result will be a list containing just this bucket.
   154  	BucketName  string   `json:"bucketName,omitempty"`  // When specified, the result will be a list containing just this bucket.
   155  	BucketTypes []string `json:"bucketTypes,omitempty"` // If present, B2 will use it as a filter for bucket types returned in the list buckets response.
   156  }
   157  
   158  // ListBucketsResponse is as returned from the b2_list_buckets call
   159  type ListBucketsResponse struct {
   160  	Buckets []Bucket `json:"buckets"`
   161  }
   162  
   163  // ListFileNamesRequest is as passed to b2_list_file_names or b2_list_file_versions
   164  type ListFileNamesRequest struct {
   165  	BucketID      string `json:"bucketId"`                // required - The bucket to look for file names in.
   166  	StartFileName string `json:"startFileName,omitempty"` // optional - The first file name to return. If there is a file with this name, it will be returned in the list. If not, the first file name after this the first one after this name.
   167  	MaxFileCount  int    `json:"maxFileCount,omitempty"`  // optional - The maximum number of files to return from this call. The default value is 100, and the maximum allowed is 1000.
   168  	StartFileID   string `json:"startFileId,omitempty"`   // optional - What to pass in to startFileId for the next search to continue where this one left off.
   169  	Prefix        string `json:"prefix,omitempty"`        // optional - Files returned will be limited to those with the given prefix. Defaults to the empty string, which matches all files.
   170  	Delimiter     string `json:"delimiter,omitempty"`     // Files returned will be limited to those within the top folder, or any one subfolder. Defaults to NULL. Folder names will also be returned. The delimiter character will be used to "break" file names into folders.
   171  }
   172  
   173  // ListFileNamesResponse is as received from b2_list_file_names or b2_list_file_versions
   174  type ListFileNamesResponse struct {
   175  	Files        []File  `json:"files"`        // An array of objects, each one describing one file.
   176  	NextFileName *string `json:"nextFileName"` // What to pass in to startFileName for the next search to continue where this one left off, or null if there are no more files.
   177  	NextFileID   *string `json:"nextFileId"`   // What to pass in to startFileId for the next search to continue where this one left off, or null if there are no more files.
   178  }
   179  
   180  // GetUploadURLRequest is passed to b2_get_upload_url
   181  type GetUploadURLRequest struct {
   182  	BucketID string `json:"bucketId"` // The ID of the bucket that you want to upload to.
   183  }
   184  
   185  // GetUploadURLResponse is received from b2_get_upload_url
   186  type GetUploadURLResponse struct {
   187  	BucketID           string `json:"bucketId"`           // The unique ID of the bucket.
   188  	UploadURL          string `json:"uploadUrl"`          // The URL that can be used to upload files to this bucket, see b2_upload_file.
   189  	AuthorizationToken string `json:"authorizationToken"` // The authorizationToken that must be used when uploading files to this bucket, see b2_upload_file.
   190  }
   191  
   192  // GetDownloadAuthorizationRequest is passed to b2_get_download_authorization
   193  type GetDownloadAuthorizationRequest struct {
   194  	BucketID               string `json:"bucketId"`                       // The ID of the bucket that you want to upload to.
   195  	FileNamePrefix         string `json:"fileNamePrefix"`                 // The file name prefix of files the download authorization token will allow access to.
   196  	ValidDurationInSeconds int64  `json:"validDurationInSeconds"`         // The number of seconds before the authorization token will expire. The minimum value is 1 second. The maximum value is 604800 which is one week in seconds.
   197  	B2ContentDisposition   string `json:"b2ContentDisposition,omitempty"` // optional - If this is present, download requests using the returned authorization must include the same value for b2ContentDisposition.
   198  }
   199  
   200  // GetDownloadAuthorizationResponse is received from b2_get_download_authorization
   201  type GetDownloadAuthorizationResponse struct {
   202  	BucketID           string `json:"bucketId"`           // The unique ID of the bucket.
   203  	FileNamePrefix     string `json:"fileNamePrefix"`     // The file name prefix of files the download authorization token will allow access to.
   204  	AuthorizationToken string `json:"authorizationToken"` // The authorizationToken that must be used when downloading files, see b2_download_file_by_name.
   205  }
   206  
   207  // FileInfo is received from b2_upload_file, b2_get_file_info and b2_finish_large_file
   208  type FileInfo struct {
   209  	ID              string            `json:"fileId"`          // The unique identifier for this version of this file. Used with b2_get_file_info, b2_download_file_by_id, and b2_delete_file_version.
   210  	Name            string            `json:"fileName"`        // The name of this file, which can be used with b2_download_file_by_name.
   211  	Action          string            `json:"action"`          // Either "upload" or "hide". "upload" means a file that was uploaded to B2 Cloud Storage. "hide" means a file version marking the file as hidden, so that it will not show up in b2_list_file_names. The result of b2_list_file_names will contain only "upload". The result of b2_list_file_versions may have both.
   212  	AccountID       string            `json:"accountId"`       // Your account ID.
   213  	BucketID        string            `json:"bucketId"`        // The bucket that the file is in.
   214  	Size            int64             `json:"contentLength"`   // The number of bytes stored in the file.
   215  	UploadTimestamp Timestamp         `json:"uploadTimestamp"` // This is a UTC time when this file was uploaded.
   216  	SHA1            string            `json:"contentSha1"`     // The SHA1 of the bytes stored in the file.
   217  	ContentType     string            `json:"contentType"`     // The MIME type of the file.
   218  	Info            map[string]string `json:"fileInfo"`        // The custom information that was uploaded with the file. This is a JSON object, holding the name/value pairs that were uploaded with the file.
   219  }
   220  
   221  // CreateBucketRequest is used to create a bucket
   222  type CreateBucketRequest struct {
   223  	AccountID string `json:"accountId"`
   224  	Name      string `json:"bucketName"`
   225  	Type      string `json:"bucketType"`
   226  }
   227  
   228  // DeleteBucketRequest is used to create a bucket
   229  type DeleteBucketRequest struct {
   230  	ID        string `json:"bucketId"`
   231  	AccountID string `json:"accountId"`
   232  }
   233  
   234  // DeleteFileRequest is used to delete a file version
   235  type DeleteFileRequest struct {
   236  	ID   string `json:"fileId"`   // The ID of the file, as returned by b2_upload_file, b2_list_file_names, or b2_list_file_versions.
   237  	Name string `json:"fileName"` // The name of this file.
   238  }
   239  
   240  // HideFileRequest is used to delete a file
   241  type HideFileRequest struct {
   242  	BucketID string `json:"bucketId"` // The bucket containing the file to hide.
   243  	Name     string `json:"fileName"` // The name of the file to hide.
   244  }
   245  
   246  // GetFileInfoRequest is used to return a FileInfo struct with b2_get_file_info
   247  type GetFileInfoRequest struct {
   248  	ID string `json:"fileId"` // The ID of the file, as returned by b2_upload_file, b2_list_file_names, or b2_list_file_versions.
   249  }
   250  
   251  // StartLargeFileRequest (b2_start_large_file) Prepares for uploading the parts of a large file.
   252  //
   253  // If the original source of the file being uploaded has a last
   254  // modified time concept, Backblaze recommends using
   255  // src_last_modified_millis as the name, and a string holding the base
   256  // 10 number number of milliseconds since midnight, January 1, 1970
   257  // UTC. This fits in a 64 bit integer such as the type "long" in the
   258  // programming language Java. It is intended to be compatible with
   259  // Java's time long. For example, it can be passed directly into the
   260  // Java call Date.setTime(long time).
   261  //
   262  // If the caller knows the SHA1 of the entire large file being
   263  // uploaded, Backblaze recommends using large_file_sha1 as the name,
   264  // and a 40 byte hex string representing the SHA1.
   265  //
   266  // Example: { "src_last_modified_millis" : "1452802803026", "large_file_sha1" : "a3195dc1e7b46a2ff5da4b3c179175b75671e80d", "color": "blue" }
   267  type StartLargeFileRequest struct {
   268  	BucketID    string            `json:"bucketId"`    //The ID of the bucket that the file will go in.
   269  	Name        string            `json:"fileName"`    // The name of the file. See Files for requirements on file names.
   270  	ContentType string            `json:"contentType"` // The MIME type of the content of the file, which will be returned in the Content-Type header when downloading the file. Use the Content-Type b2/x-auto to automatically set the stored Content-Type post upload. In the case where a file extension is absent or the lookup fails, the Content-Type is set to application/octet-stream.
   271  	Info        map[string]string `json:"fileInfo"`    // A JSON object holding the name/value pairs for the custom file info.
   272  }
   273  
   274  // StartLargeFileResponse is the response to StartLargeFileRequest
   275  type StartLargeFileResponse struct {
   276  	ID              string            `json:"fileId"`          // The unique identifier for this version of this file. Used with b2_get_file_info, b2_download_file_by_id, and b2_delete_file_version.
   277  	Name            string            `json:"fileName"`        // The name of this file, which can be used with b2_download_file_by_name.
   278  	AccountID       string            `json:"accountId"`       // The identifier for the account.
   279  	BucketID        string            `json:"bucketId"`        // The unique ID of the bucket.
   280  	ContentType     string            `json:"contentType"`     // The MIME type of the file.
   281  	Info            map[string]string `json:"fileInfo"`        // The custom information that was uploaded with the file. This is a JSON object, holding the name/value pairs that were uploaded with the file.
   282  	UploadTimestamp Timestamp         `json:"uploadTimestamp"` // This is a UTC time when this file was uploaded.
   283  }
   284  
   285  // GetUploadPartURLRequest is passed to b2_get_upload_part_url
   286  type GetUploadPartURLRequest struct {
   287  	ID string `json:"fileId"` // The unique identifier of the file being uploaded.
   288  }
   289  
   290  // GetUploadPartURLResponse is received from b2_get_upload_url
   291  type GetUploadPartURLResponse struct {
   292  	ID                 string `json:"fileId"`             // The unique identifier of the file being uploaded.
   293  	UploadURL          string `json:"uploadUrl"`          // The URL that can be used to upload files to this bucket, see b2_upload_part.
   294  	AuthorizationToken string `json:"authorizationToken"` // The authorizationToken that must be used when uploading files to this bucket, see b2_upload_part.
   295  }
   296  
   297  // UploadPartResponse is the response to b2_upload_part
   298  type UploadPartResponse struct {
   299  	ID         string `json:"fileId"`        // The unique identifier of the file being uploaded.
   300  	PartNumber int64  `json:"partNumber"`    // Which part this is (starting from 1)
   301  	Size       int64  `json:"contentLength"` // The number of bytes stored in the file.
   302  	SHA1       string `json:"contentSha1"`   // The SHA1 of the bytes stored in the file.
   303  }
   304  
   305  // FinishLargeFileRequest is passed to b2_finish_large_file
   306  //
   307  // The response is a FileInfo object (with extra AccountID and BucketID fields which we ignore).
   308  //
   309  // Large files do not have a SHA1 checksum. The value will always be "none".
   310  type FinishLargeFileRequest struct {
   311  	ID    string   `json:"fileId"`        // The unique identifier of the file being uploaded.
   312  	SHA1s []string `json:"partSha1Array"` // A JSON array of hex SHA1 checksums of the parts of the large file. This is a double-check that the right parts were uploaded in the right order, and that none were missed. Note that the part numbers start at 1, and the SHA1 of the part 1 is the first string in the array, at index 0.
   313  }
   314  
   315  // CancelLargeFileRequest is passed to b2_finish_large_file
   316  //
   317  // The response is a CancelLargeFileResponse
   318  type CancelLargeFileRequest struct {
   319  	ID string `json:"fileId"` // The unique identifier of the file being uploaded.
   320  }
   321  
   322  // CancelLargeFileResponse is the response to CancelLargeFileRequest
   323  type CancelLargeFileResponse struct {
   324  	ID        string `json:"fileId"`    // The unique identifier of the file being uploaded.
   325  	Name      string `json:"fileName"`  // The name of this file.
   326  	AccountID string `json:"accountId"` // The identifier for the account.
   327  	BucketID  string `json:"bucketId"`  // The unique ID of the bucket.
   328  }
   329  
   330  // CopyFileRequest is as passed to b2_copy_file
   331  type CopyFileRequest struct {
   332  	SourceID          string            `json:"sourceFileId"`                  // The ID of the source file being copied.
   333  	Name              string            `json:"fileName"`                      // The name of the new file being created.
   334  	Range             string            `json:"range,omitempty"`               // The range of bytes to copy. If not provided, the whole source file will be copied.
   335  	MetadataDirective string            `json:"metadataDirective,omitempty"`   // The strategy for how to populate metadata for the new file: COPY or REPLACE
   336  	ContentType       string            `json:"contentType,omitempty"`         // The MIME type of the content of the file (REPLACE only)
   337  	Info              map[string]string `json:"fileInfo,omitempty"`            // This field stores the metadata that will be stored with the file. (REPLACE only)
   338  	DestBucketID      string            `json:"destinationBucketId,omitempty"` // The destination ID of the bucket if set, if not the source bucket will be used
   339  }