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 }