github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/backend/jottacloud/api/types.go (about) 1 package api 2 3 import ( 4 "encoding/xml" 5 "fmt" 6 "time" 7 8 "github.com/pkg/errors" 9 ) 10 11 const ( 12 // default time format for almost all request and responses 13 timeFormat = "2006-01-02-T15:04:05Z0700" 14 // the API server seems to use a different format 15 apiTimeFormat = "2006-01-02T15:04:05Z07:00" 16 ) 17 18 // Time represents time values in the Jottacloud API. It uses a custom RFC3339 like format. 19 type Time time.Time 20 21 // UnmarshalXML turns XML into a Time 22 func (t *Time) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 23 var v string 24 if err := d.DecodeElement(&v, &start); err != nil { 25 return err 26 } 27 if v == "" { 28 *t = Time(time.Time{}) 29 return nil 30 } 31 newTime, err := time.Parse(timeFormat, v) 32 if err == nil { 33 *t = Time(newTime) 34 } 35 return err 36 } 37 38 // MarshalXML turns a Time into XML 39 func (t *Time) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 40 return e.EncodeElement(t.String(), start) 41 } 42 43 // Return Time string in Jottacloud format 44 func (t Time) String() string { return time.Time(t).Format(timeFormat) } 45 46 // APIString returns Time string in Jottacloud API format 47 func (t Time) APIString() string { return time.Time(t).Format(apiTimeFormat) } 48 49 // Flag is a hacky type for checking if an attribute is present 50 type Flag bool 51 52 // UnmarshalXMLAttr sets Flag to true if the attribute is present 53 func (f *Flag) UnmarshalXMLAttr(attr xml.Attr) error { 54 *f = true 55 return nil 56 } 57 58 // MarshalXMLAttr : Do not use 59 func (f *Flag) MarshalXMLAttr(name xml.Name) (xml.Attr, error) { 60 attr := xml.Attr{ 61 Name: name, 62 Value: "false", 63 } 64 return attr, errors.New("unimplemented") 65 } 66 67 // TokenJSON is the struct representing the HTTP response from OAuth2 68 // providers returning a token in JSON form. 69 type TokenJSON struct { 70 AccessToken string `json:"access_token"` 71 TokenType string `json:"token_type"` 72 RefreshToken string `json:"refresh_token"` 73 ExpiresIn int32 `json:"expires_in"` // at least PayPal returns string, while most return number 74 } 75 76 /* 77 GET http://www.jottacloud.com/JFS/<account> 78 79 <user time="2018-07-18-T21:39:10Z" host="dn-132"> 80 <username>12qh1wsht8cssxdtwl15rqh9</username> 81 <account-type>free</account-type> 82 <locked>false</locked> 83 <capacity>5368709120</capacity> 84 <max-devices>-1</max-devices> 85 <max-mobile-devices>-1</max-mobile-devices> 86 <usage>0</usage> 87 <read-locked>false</read-locked> 88 <write-locked>false</write-locked> 89 <quota-write-locked>false</quota-write-locked> 90 <enable-sync>true</enable-sync> 91 <enable-foldershare>true</enable-foldershare> 92 <devices> 93 <device> 94 <name xml:space="preserve">Jotta</name> 95 <display_name xml:space="preserve">Jotta</display_name> 96 <type>JOTTA</type> 97 <sid>5c458d01-9eaf-4f23-8d3c-2486fd9704d8</sid> 98 <size>0</size> 99 <modified>2018-07-15-T22:04:59Z</modified> 100 </device> 101 </devices> 102 </user> 103 */ 104 105 // AccountInfo represents a Jottacloud account 106 type AccountInfo struct { 107 Username string `xml:"username"` 108 AccountType string `xml:"account-type"` 109 Locked bool `xml:"locked"` 110 Capacity int64 `xml:"capacity"` 111 MaxDevices int `xml:"max-devices"` 112 MaxMobileDevices int `xml:"max-mobile-devices"` 113 Usage int64 `xml:"usage"` 114 ReadLocked bool `xml:"read-locked"` 115 WriteLocked bool `xml:"write-locked"` 116 QuotaWriteLocked bool `xml:"quota-write-locked"` 117 EnableSync bool `xml:"enable-sync"` 118 EnableFolderShare bool `xml:"enable-foldershare"` 119 Devices []JottaDevice `xml:"devices>device"` 120 } 121 122 /* 123 GET http://www.jottacloud.com/JFS/<account>/<device> 124 125 <device time="2018-07-23-T20:21:50Z" host="dn-158"> 126 <name xml:space="preserve">Jotta</name> 127 <display_name xml:space="preserve">Jotta</display_name> 128 <type>JOTTA</type> 129 <sid>5c458d01-9eaf-4f23-8d3c-2486fd9704d8</sid> 130 <size>0</size> 131 <modified>2018-07-15-T22:04:59Z</modified> 132 <user>12qh1wsht8cssxdtwl15rqh9</user> 133 <mountPoints> 134 <mountPoint> 135 <name xml:space="preserve">Archive</name> 136 <size>0</size> 137 <modified>2018-07-15-T22:04:59Z</modified> 138 </mountPoint> 139 <mountPoint> 140 <name xml:space="preserve">Shared</name> 141 <size>0</size> 142 <modified></modified> 143 </mountPoint> 144 <mountPoint> 145 <name xml:space="preserve">Sync</name> 146 <size>0</size> 147 <modified></modified> 148 </mountPoint> 149 </mountPoints> 150 <metadata first="" max="" total="3" num_mountpoints="3"/> 151 </device> 152 */ 153 154 // JottaDevice represents a Jottacloud Device 155 type JottaDevice struct { 156 Name string `xml:"name"` 157 DisplayName string `xml:"display_name"` 158 Type string `xml:"type"` 159 Sid string `xml:"sid"` 160 Size int64 `xml:"size"` 161 User string `xml:"user"` 162 MountPoints []JottaMountPoint `xml:"mountPoints>mountPoint"` 163 } 164 165 /* 166 GET http://www.jottacloud.com/JFS/<account>/<device>/<mountpoint> 167 168 <mountPoint time="2018-07-24-T20:35:02Z" host="dn-157"> 169 <name xml:space="preserve">Sync</name> 170 <path xml:space="preserve">/12qh1wsht8cssxdtwl15rqh9/Jotta</path> 171 <abspath xml:space="preserve">/12qh1wsht8cssxdtwl15rqh9/Jotta</abspath> 172 <size>0</size> 173 <modified></modified> 174 <device>Jotta</device> 175 <user>12qh1wsht8cssxdtwl15rqh9</user> 176 <folders> 177 <folder name="test"/> 178 </folders> 179 <metadata first="" max="" total="1" num_folders="1" num_files="0"/> 180 </mountPoint> 181 */ 182 183 // JottaMountPoint represents a Jottacloud mountpoint 184 type JottaMountPoint struct { 185 Name string `xml:"name"` 186 Size int64 `xml:"size"` 187 Device string `xml:"device"` 188 Folders []JottaFolder `xml:"folders>folder"` 189 Files []JottaFile `xml:"files>file"` 190 } 191 192 /* 193 GET http://www.jottacloud.com/JFS/<account>/<device>/<mountpoint>/<folder> 194 195 <folder name="test" time="2018-07-24-T20:41:37Z" host="dn-158"> 196 <path xml:space="preserve">/12qh1wsht8cssxdtwl15rqh9/Jotta/Sync</path> 197 <abspath xml:space="preserve">/12qh1wsht8cssxdtwl15rqh9/Jotta/Sync</abspath> 198 <folders> 199 <folder name="t2"/>c 200 </folders> 201 <files> 202 <file name="block.csv" uuid="f6553cd4-1135-48fe-8e6a-bb9565c50ef2"> 203 <currentRevision> 204 <number>1</number> 205 <state>COMPLETED</state> 206 <created>2018-07-05-T15:08:02Z</created> 207 <modified>2018-07-05-T15:08:02Z</modified> 208 <mime>application/octet-stream</mime> 209 <size>30827730</size> 210 <md5>1e8a7b728ab678048df00075c9507158</md5> 211 <updated>2018-07-24-T20:41:10Z</updated> 212 </currentRevision> 213 </file> 214 </files> 215 <metadata first="" max="" total="2" num_folders="1" num_files="1"/> 216 </folder> 217 */ 218 219 // JottaFolder represents a JottacloudFolder 220 type JottaFolder struct { 221 XMLName xml.Name 222 Name string `xml:"name,attr"` 223 Deleted Flag `xml:"deleted,attr"` 224 Path string `xml:"path"` 225 CreatedAt Time `xml:"created"` 226 ModifiedAt Time `xml:"modified"` 227 Updated Time `xml:"updated"` 228 Folders []JottaFolder `xml:"folders>folder"` 229 Files []JottaFile `xml:"files>file"` 230 } 231 232 /* 233 GET http://www.jottacloud.com/JFS/<account>/<device>/<mountpoint>/.../<file> 234 235 <file name="block.csv" uuid="f6553cd4-1135-48fe-8e6a-bb9565c50ef2"> 236 <currentRevision> 237 <number>1</number> 238 <state>COMPLETED</state> 239 <created>2018-07-05-T15:08:02Z</created> 240 <modified>2018-07-05-T15:08:02Z</modified> 241 <mime>application/octet-stream</mime> 242 <size>30827730</size> 243 <md5>1e8a7b728ab678048df00075c9507158</md5> 244 <updated>2018-07-24-T20:41:10Z</updated> 245 </currentRevision> 246 </file> 247 */ 248 249 // JottaFile represents a Jottacloud file 250 type JottaFile struct { 251 XMLName xml.Name 252 Name string `xml:"name,attr"` 253 Deleted Flag `xml:"deleted,attr"` 254 PublicSharePath string `xml:"publicSharePath"` 255 State string `xml:"currentRevision>state"` 256 CreatedAt Time `xml:"currentRevision>created"` 257 ModifiedAt Time `xml:"currentRevision>modified"` 258 Updated Time `xml:"currentRevision>updated"` 259 Size int64 `xml:"currentRevision>size"` 260 MimeType string `xml:"currentRevision>mime"` 261 MD5 string `xml:"currentRevision>md5"` 262 } 263 264 // Error is a custom Error for wrapping Jottacloud error responses 265 type Error struct { 266 StatusCode int `xml:"code"` 267 Message string `xml:"message"` 268 Reason string `xml:"reason"` 269 Cause string `xml:"cause"` 270 } 271 272 // Error returns a string for the error and statistifes the error interface 273 func (e *Error) Error() string { 274 out := fmt.Sprintf("error %d", e.StatusCode) 275 if e.Message != "" { 276 out += ": " + e.Message 277 } 278 if e.Reason != "" { 279 out += fmt.Sprintf(" (%+v)", e.Reason) 280 } 281 return out 282 } 283 284 // AllocateFileRequest to prepare an upload to Jottacloud 285 type AllocateFileRequest struct { 286 Bytes int64 `json:"bytes"` 287 Created string `json:"created"` 288 Md5 string `json:"md5"` 289 Modified string `json:"modified"` 290 Path string `json:"path"` 291 } 292 293 // AllocateFileResponse for upload requests 294 type AllocateFileResponse struct { 295 Name string `json:"name"` 296 Path string `json:"path"` 297 State string `json:"state"` 298 UploadID string `json:"upload_id"` 299 UploadURL string `json:"upload_url"` 300 Bytes int64 `json:"bytes"` 301 ResumePos int64 `json:"resume_pos"` 302 } 303 304 // UploadResponse after an upload 305 type UploadResponse struct { 306 Name string `json:"name"` 307 Path string `json:"path"` 308 Kind string `json:"kind"` 309 ContentID string `json:"content_id"` 310 Bytes int64 `json:"bytes"` 311 Md5 string `json:"md5"` 312 Created int64 `json:"created"` 313 Modified int64 `json:"modified"` 314 Deleted interface{} `json:"deleted"` 315 Mime string `json:"mime"` 316 } 317 318 // DeviceRegistrationResponse is the response to registering a device 319 type DeviceRegistrationResponse struct { 320 ClientID string `json:"client_id"` 321 ClientSecret string `json:"client_secret"` 322 }