Package u1rest :: Package files :: Module resources
[hide private]
[frames] | no frames]

Source Code for Module u1rest.files.resources

  1  #Copyright (C) 2011 by John O'Brien 
  2  # 
  3  #Permission is hereby granted, free of charge, to any person obtaining a copy 
  4  #of this software and associated documentation files (the "Software"), to deal 
  5  #in the Software without restriction, including without limitation the rights 
  6  #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
  7  #copies of the Software, and to permit persons to whom the Software is 
  8  #furnished to do so, subject to the following conditions: 
  9  # 
 10  #The above copyright notice and this permission notice shall be included in 
 11  #all copies or substantial portions of the Software. 
 12  # 
 13  #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 14  #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 15  #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 16  #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 17  #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 18  #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
 19  #THE SOFTWARE. 
 20  """REST Resources of the files api.""" 
 21  from u1rest.lib.client import ResourceClient 
 22  from u1rest.files.content import ContentClient 
 23   
 24  BASE_API_PATH = "/api/file_storage/v1" 
 25   
 26   
27 -def get_user(res_host, cont_host, auth):
28 """Get a user object for accessing rest resources. 29 30 @param res_host: The host for File Resources (metadata) 31 @param cont_host: The host for File Content. 32 @param auth: An authenticator used in authenticating requests. 33 """ 34 resource_client = ResourceClient(res_host, auth, BASE_API_PATH) 35 content_client = ContentClient(cont_host, auth) 36 user_json = resource_client.get_resource() 37 return FileStorageUser(user_json, resource_client, content_client)
38 39
40 -class FileStorageUser(object):
41 """A File Storage User resource. 42 43 This is the main part of the API where typically every call is made. 44 45 The get, put, delete are provided for user who do not need a simplified api 46 and plan on parsing the JSON themselves. 47 48 Other methods are provided that return serialized objects for simplified 49 user of the API. 50 """ 51 resource_path = None 52
53 - def __init__(self, res_json, resource_client, content_client):
54 self.__dict__.update(res_json) 55 self.resource_client = resource_client 56 self.content_client = content_client
57
58 - def get(self, path, params=None):
59 """GET a resource. 60 61 @param path: The path of the resource relative to the base API. 62 @param params: Optionally a dictionary of querystring values. 63 """ 64 return self.resource_client.get_resource(path, params=params)
65
66 - def put(self, path, data=None, params=None):
67 """PUT a resource. 68 69 @param path: The path of the resource relative to the base API. 70 @param data: A JSON Serializable object sent in the PUT 71 @param params: Optionally a dictionary of querystring values. 72 """ 73 return self.resource_client.put_resource(path, data, params=params)
74
75 - def delete(self, path, params=None):
76 """DELETE a resource. 77 . 78 @param path: The path of the resource relative to the base API. 79 @param params: Optionally a dictionary of querystring values. 80 """ 81 self.resource_client.delete_resource(path, params=params)
82
83 - def make_file(self, path):
84 """Make a File. 85 86 @param path: The path of the file using the <volume path>/<node path>. 87 For example ~/Ubuntu One/a/b/c/file.txt 88 """ 89 res_json = self.put(path, data={"kind": "file"}) 90 return FileNode(res_json, self)
91
92 - def make_directory(self, path):
93 """Make a Directory. 94 95 @param path: The path of the file using the <volume path>/<node path>. 96 For example ~/Ubuntu One/a/b/c/dirname 97 """ 98 res_json = self.put(path, data={"kind": "directory"}) 99 return DirectoryNode(res_json, self)
100
101 - def get_node(self, path, with_children=False):
102 """Get a File or Directory node. 103 104 @param path: The path of the file using the <volume path>/<node path>. 105 For example ~/Ubuntu One/a/b/c/dirname 106 @param with_children: If True, the children property of the directory 107 will be filled with Node Resources of the direct children. 108 """ 109 params = {'include_children': 'true'} if with_children else None 110 res_json = self.get(path, params=params) 111 return get_node_resource(res_json, self)
112
113 - def set_file_public(self, path, public=True):
114 """Make a file public. 115 116 @param path: The path of the file using the <volume path>/<node path>. 117 For example ~/Ubuntu One/a/b/c/file.txt 118 @param public: If True the file will be published else it will be 119 unpublished. Defaults to True. 120 """ 121 res_json = self.put(path, data={"is_public": public}) 122 return get_node_resource(res_json, self)
123
124 - def move_node(self, path, new_path):
125 """Move a node from one path to the other. 126 127 The new_path is a path relative path within the volume. 128 """ 129 res_json = self.put(path, data={"path": new_path}) 130 return get_node_resource(res_json, self)
131
132 - def make_volume(self, path):
133 """Create a new Volume (aka UDF).""" 134 path = 'volumes/' + path.lstrip("/") 135 res_json = self.put(path) 136 return Volume(res_json, self)
137
138 - def get_volume(self, path):
139 """Get a Volume.""" 140 path = 'volumes/' + path.lstrip("/") 141 res_json = self.get(path) 142 return Volume(res_json, self)
143
144 - def delete_volume(self, path):
145 """Get a Volume.""" 146 path = 'volumes/' + path.lstrip("/") 147 self.delete(path)
148
149 - def get_volumes(self):
150 """Get a list of all Volumes.""" 151 res_json = self.get('volumes') 152 return [Volume(v, self) for v in res_json]
153
154 - def load(self):
155 """Reload this User Resource.""" 156 res_json = self.get(self.resource_path) 157 self.__dict__.update(res_json)
158
159 - def download_file(self, path, destination=None):
160 """Download a file. 161 162 @param destination: The local directory to download the file to. 163 """ 164 self.content_client.get_file(path, download_directory=destination)
165
166 - def upload_file(self, file_name, path):
167 """Download a file.""" 168 response = self.content_client.put_file(file_name, path) 169 return get_node_resource(response, self)
170 171
172 -class Resource(object):
173 """Base class for all resources providing common methods. 174 175 All resources are dynamically loaded from the JSON returned in a Resource 176 Response. This is done because all File Storage resource have a 177 resource_path property which identifies the resource. 178 """ 179 resource_path = None 180
181 - def __init__(self, res_json=None, user=None):
182 self.__dict__.update(res_json) 183 self.user = user
184
185 - def load(self):
186 """Reload the resource.""" 187 res_json = self.user.get(self.resource_path) 188 self.__dict__.update(res_json)
189
190 - def delete(self):
191 """Delete the resource.""" 192 self.user.delete(self.resource_path)
193 194
195 -def get_node_resource(res_json, user):
196 """Used when given a Node Respresentation to return the right resource. 197 198 @param res_json: The JSON representation of the node. 199 @param user: The {FileStorageUser} Resource used to get the node. 200 """ 201 if res_json.get('kind') == 'file': 202 return FileNode(res_json, user) 203 else: 204 return DirectoryNode(res_json, user)
205 206
207 -class DirectoryNode(Resource):
208 """Directory Node Resource."""
209 - def __init__(self, res_json=None, user=None):
210 super(DirectoryNode, self).__init__(res_json=res_json, user=user) 211 if res_json and res_json.get('children'): 212 self.children = [get_node_resource(n, user) 213 for n in res_json.get('children')]
214
215 - def make_file(self, name):
216 """Make a file in this directory given a file name. 217 218 @param name: The name of the file to be created under this path. 219 """ 220 path = self.resource_path + '/' + name.lstrip('/') 221 return self.user.make_file(path)
222
223 - def make_directory(self, name):
224 """Make a subdirectory in this directory given a directory name. 225 226 @param name: The name of the directory to be created under this path. 227 """ 228 path = self.resource_path + '/' + name.lstrip('/') 229 return self.user.make_directory(path)
230
231 - def load(self, with_children=False, cascade=False):
232 """Reload this directory. 233 234 @param with_children: If True, direct children will be loaded into 235 children. 236 @param cascade: If True all descendants of this node will be loaded 237 into the children recursively. This should be used with caution. 238 """ 239 node = self.user.get_node(self.resource_path, 240 with_children=with_children or cascade) 241 if cascade: 242 for child in [d for d in node.children if d.kind == 'directory']: 243 child.load(cascade=True) 244 self.__dict__.clear() 245 self.__dict__.update(node.__dict__)
246
247 - def move(self, new_path):
248 """Move this node to a new path. 249 250 @param new_path: The new path of the node. Note that this path is 251 relative the volume path, so the volume path is not included. 252 For example node.mode("/a/b/c") will move the node to a new path 253 under the volume. Moving to a different volume is not permitted. 254 """ 255 node = self.user.move_node(self.resource_path, new_path) 256 self.__dict__.clear() 257 self.__dict__.update(node.__dict__)
258 259
260 -class FileNode(Resource):
261 """A File Node Resource.""" 262
263 - def set_public(self, public=True):
264 """Set the file public. 265 266 @param public: If True the file will be published else it will be 267 unpublished. Defaults to True. 268 """ 269 node = self.user.set_file_public(self.resource_path, public) 270 self.__dict__.clear() 271 self.__dict__.update(node.__dict__)
272
273 - def move(self, new_path):
274 """Move this node to a new path. 275 276 @param new_path: The new path of the node. Note that this path is 277 relative the volume path, so the volume path is not included. 278 For example node.mode("/a/b/c") will move the node to a new path 279 under the volume. Moving to a different volume is not permitted. 280 """ 281 node = self.user.move_node(self.resource_path, new_path) 282 self.__dict__.clear() 283 self.__dict__.update(node.__dict__)
284
285 - def download(self, destination=None):
286 """Download this file. 287 288 @param destination: The local directory to download the file to. 289 """ 290 return self.user.download_file( 291 self.resource_path, destination=destination)
292
293 -class Volume(Resource):
294 """A Volume Resource.""" 295 node_path = None 296
297 - def get_root_dir(self, with_children=False):
298 """Get the root directory node for this volume.""" 299 return self.user.get_node(self.node_path, with_children)
300