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  }