Pārlūkot izejas kodu

[doc2] Refactor documents API and consolidate views

GET /desktop/api2/docs (search_documents)

GET /desktop/api2/doc (get_document)
Jenny Kim 9 gadi atpakaļ
vecāks
revīzija
f19d7aa

+ 47 - 101
desktop/core/src/desktop/api2.py

@@ -57,9 +57,54 @@ def api_error_handler(func):
 
 
 @api_error_handler
-def get_documents(request):
+def search_documents(request):
   """
-  Returns all documents and directories found for the given uuid or path and current user.
+  Returns the directories and documents based on given params that are accessible by the current user
+  Optional params:
+    perms=<mode>       - Controls whether to retrieve owned, shared, or both. Defaults to both.
+    get_history=<bool> - Controls whether to retrieve history docs. Defaults to false.
+    flatten=<bool>     - Controls whether to return documents in a flat list, or roll up documents to a common directory
+                         if possible. Defaults to true.
+    page=<n>           - Controls pagination. Defaults to 1.
+    limit=<n>          - Controls limit per page. Defaults to all.
+    type=<type>        - Show documents of given type(s) (directory, query-hive, query-impala, query-mysql, etc).
+                         Defaults to all.
+    sort=<key>         - Sort by the attribute <key>, which is one of: "name", "type", "owner", "last_modified"
+                         Accepts the form "-last_modified", which sorts in descending order.
+                         Defaults to "-last_modified".
+    text=<frag>       -  Search for fragment "frag" in names and descriptions.
+  """
+
+  response = {
+    'documents': []
+  }
+
+  perms = request.GET.get('perms', 'both').lower()
+  get_history = json.loads(request.GET.get('get_history', 'false'))
+  flatten = json.loads(request.GET.get('flatten', 'true'))
+
+  if perms not in ['owned', 'shared', 'both']:
+    raise Exception(_('Invalid value for perms, acceptable values are: owned, shared, both.'))
+
+  documents = Document2.objects.documents(user=request.user, perms=perms, get_history=get_history)
+
+  # Refine results
+  response.update(_filter_documents(request, queryset=documents, flatten=flatten))
+
+  # Paginate
+  response.update(_paginate(request, queryset=response['documents']))
+
+  # Serialize results
+  response['documents'] = [doc.to_dict() for doc in response.get('documents', [])]
+
+  return JsonResponse(response)
+
+
+@api_error_handler
+def get_document(request):
+  """
+  Returns the document or directory found for the given uuid or path and current user.
+  If a directory is found, return any children documents too.
   Optional params:
     page=<n>    - Controls pagination. Defaults to 1.
     limit=<n>   - Controls limit per page. Defaults to all.
@@ -104,104 +149,6 @@ def get_documents(request):
   return JsonResponse(response)
 
 
-@api_error_handler
-def get_shared_documents(request):
-  """
-  Returns the directories and documents that are shared with the current user, grouped by top-level directory.
-  Optional params:
-    flatten=<bool>    - Controls whether to return documents in a flat list, or roll up documents to a common directory
-                        if possible. Defaults to false.
-    page=<n>    - Controls pagination. Defaults to 1.
-    limit=<n>   - Controls limit per page. Defaults to all.
-    type=<type> - Show documents of given type(s) (directory, query-hive, query-impala, query-mysql, etc). Default to all.
-    sort=<key>  - Sort by the attribute <key>, which is one of:
-                    "name", "type", "owner", "last_modified"
-                  Accepts the form "-last_modified", which sorts in descending order.
-                  Default to "-last_modified".
-    text=<frag> - Search for fragment "frag" in names and descriptions.
-  """
-
-  response = {
-    'documents': []
-  }
-
-  flatten = json.loads(request.GET.get('flatten', 'false'))
-
-  documents = Document2.objects.get_shared_documents(request.user)
-
-  # Refine results
-  response.update(_filter_documents(request, queryset=documents, flatten=flatten))
-
-  # Paginate
-  response.update(_paginate(request, queryset=response['documents']))
-
-  # Serialize results
-  if response['documents'] and response['documents'].count() > 0:
-    response['documents'] = [doc.to_dict() for doc in response['documents']]
-  else:
-    response['documents'] = []
-
-  return JsonResponse(response)
-
-
-@api_error_handler
-def search_documents(request):
-  """
-  Returns the directories and documents based on given params that are accessible by the current user
-  Optional params:
-    get_shared=<bool> - Controls whether to retrieve shared docs. Defaults to true.
-    get_history=<bool> - Controls whether to retrieve history docs. Defaults to false.
-    flatten=<bool>    - Controls whether to return documents in a flat list, or roll up documents to a common directory
-                        if possible. Defaults to true.
-    page=<n>          - Controls pagination. Defaults to 1.
-    limit=<n>         - Controls limit per page. Defaults to all.
-    type=<type>       - Show documents of given type(s) (directory, query-hive, query-impala, query-mysql, etc).
-                        Defaults to all.
-    sort=<key>        - Sort by the attribute <key>, which is one of: "name", "type", "owner", "last_modified"
-                        Accepts the form "-last_modified", which sorts in descending order.
-                        Defaults to "-last_modified".
-    text=<frag>       - Search for fragment "frag" in names and descriptions.
-  """
-
-  response = {
-    'documents': []
-  }
-
-  get_shared = json.loads(request.GET.get('get_shared', 'true'))
-  get_history = json.loads(request.GET.get('get_history', 'false'))
-  flatten = json.loads(request.GET.get('flatten', 'true'))
-
-  documents = Document2.objects.documents(user=request.user, get_shared=get_shared, get_history=get_history)
-
-  # Refine results
-  response.update(_filter_documents(request, queryset=documents, flatten=flatten))
-
-  # Paginate
-  response.update(_paginate(request, queryset=response['documents']))
-
-  # Serialize results
-  if response['documents'] and response['documents'].count() > 0:
-    response['documents'] = [doc.to_dict() for doc in response['documents']]
-  else:
-    response['documents'] = []
-
-  return JsonResponse(response)
-
-
-
-@api_error_handler
-def get_document(request):
-  if request.GET.get('id'):
-    doc = Document2.objects.get(id=request.GET['id'])
-  else:
-    doc = Document2.objects.get_by_uuid(uuid=request.GET['uuid'])
-
-  # Check if user has read permissions
-  doc.can_read_or_exception(request.user)
-
-  return JsonResponse(doc.to_dict())
-
-
 @api_error_handler
 @require_POST
 def move_document(request):
@@ -347,7 +294,6 @@ def export_documents(request):
           from spark.models import Notebook
           zfile.writestr("notebook-%s-%s.txt" % (doc.name, doc.id), smart_str(Notebook(document=doc).get_str()))
         except Exception, e:
-          print e
           LOG.exception(e)
     zfile.close()
     response = HttpResponse(content_type="application/zip")

+ 11 - 16
desktop/core/src/desktop/models.py

@@ -759,18 +759,24 @@ class Document2Manager(models.Manager):
   def document(self, user, doc_id):
     return self.documents(user).get(id=doc_id)
 
-  def documents(self, user, get_shared=True, get_history=False):
+  def documents(self, user, perms='both', get_history=False):
     """
-    Returns all documents that are either owned or shared with the user
-    WARNING: Do NOT use this if you ONLY need documents that are owned by the user!
+    Returns all documents that are owned or shared with the user.
+    :param perms: both, shared, owned. Defaults to both.
+    :param get_history: boolean flag to return history documents. Defaults to False.
     """
-    if get_shared:
+    if perms == 'both':
       docs = Document2.objects.filter(
         Q(owner=user) |
         Q(document2permission__users=user) |
         Q(document2permission__groups__in=user.groups.all())
       )
-    else:
+    elif perms == 'shared':
+      docs = Document2.objects.filter(
+        Q(document2permission__users=user) |
+        Q(document2permission__groups__in=user.groups.all())
+      )
+    else:  # only return documents owned by the user
       docs = Document2.objects.filter(owner=user)
 
     if not get_history:
@@ -780,17 +786,6 @@ class Document2Manager(models.Manager):
 
     return docs.order_by('-last_modified')
 
-  def get_shared_documents(self, user):
-    """
-    Returns all documents that are shared with the user
-    """
-    documents = Document2.objects.filter(
-        Q(document2permission__users=user) |
-        Q(document2permission__groups__in=user.groups.all())
-    ).distinct()
-
-    return documents
-
   def refine_documents(self, documents, types=None, search_text=None, order_by=None):
     """
     Refines a queryset of document objects by type filters, search_text or order_by

+ 52 - 52
desktop/core/src/desktop/tests_doc2.py

@@ -39,7 +39,7 @@ class TestDocument2(object):
     grant_access("doc2", "doc2", "beeswax")
 
     # This creates the user directories for the new user
-    response = self.client.get('/desktop/api2/docs/')
+    response = self.client.get('/desktop/api2/doc/')
     data = json.loads(response.content)
     assert_equal('/', data['document']['path'], data)
 
@@ -88,13 +88,13 @@ class TestDocument2(object):
   def test_get_document(self):
     doc = Document2.objects.create(name='test_doc', type='query-hive', owner=self.user, data={})
     self.home_dir.children.add(doc)
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': doc.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': doc.uuid})
     data = json.loads(response.content)
-    assert_true('uuid' in data)
-    assert_equal(doc.uuid, data['uuid'])
+    assert_true('document' in data)
+    assert_equal(doc.uuid, data['document']['uuid'])
 
     # Invalid uuid returns error
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': '1234-5678-9'})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': '1234-5678-9'})
     data = json.loads(response.content)
     assert_equal(-1, data['status'])
     assert_true('not found' in data['message'])
@@ -116,13 +116,13 @@ class TestDocument2(object):
     doc = Document2.objects.create(name='query1.sql', type='query-hive', owner=self.user, data={}, parent_directory=source_dir)
 
     # Verify original paths before move operation
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': source_dir.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': source_dir.uuid})
     data = json.loads(response.content)
-    assert_equal('/test_mv_file_src', data['path'])
+    assert_equal('/test_mv_file_src', data['document']['path'])
 
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': doc.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': doc.uuid})
     data = json.loads(response.content)
-    assert_equal('/test_mv_file_src/query1.sql', data['path'])
+    assert_equal('/test_mv_file_src/query1.sql', data['document']['path'])
 
     response = self.client.post('/desktop/api2/doc/move', {
         'source_doc_uuid': json.dumps(doc.uuid),
@@ -132,13 +132,13 @@ class TestDocument2(object):
     assert_equal(0, data['status'], data)
 
     # Verify that the paths are updated
-    response = self.client.get('/desktop/api2/docs', {'uuid': source_dir.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': source_dir.uuid})
     data = json.loads(response.content)
     assert_false(any(doc['uuid'] == doc.uuid for doc in data['children']), data['children'])
 
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': doc.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': doc.uuid})
     data = json.loads(response.content)
-    assert_equal('/test_mv_file_dst/query1.sql', data['path'])
+    assert_equal('/test_mv_file_dst/query1.sql', data['document']['path'])
 
 
   def test_directory_move(self):
@@ -147,13 +147,13 @@ class TestDocument2(object):
     doc = Document2.objects.create(name='query1.sql', type='query-hive', owner=self.user, data={}, parent_directory=source_dir)
 
     # Verify original paths before move operation
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': source_dir.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': source_dir.uuid})
     data = json.loads(response.content)
-    assert_equal('/test_mv', data['path'])
+    assert_equal('/test_mv', data['document']['path'])
 
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': doc.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': doc.uuid})
     data = json.loads(response.content)
-    assert_equal('/test_mv/query1.sql', data['path'])
+    assert_equal('/test_mv/query1.sql', data['document']['path'])
 
     response = self.client.post('/desktop/api2/doc/move', {
         'source_doc_uuid': json.dumps(Directory.objects.get(owner=self.user, name='test_mv').uuid),
@@ -163,13 +163,13 @@ class TestDocument2(object):
     assert_equal(0, data['status'], data)
 
     # Verify that the paths are updated
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': source_dir.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': source_dir.uuid})
     data = json.loads(response.content)
-    assert_equal('/test_mv_dst/test_mv', data['path'])
+    assert_equal('/test_mv_dst/test_mv', data['document']['path'])
 
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': doc.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': doc.uuid})
     data = json.loads(response.content)
-    assert_equal('/test_mv_dst/test_mv/query1.sql', data['path'])
+    assert_equal('/test_mv_dst/test_mv/query1.sql', data['document']['path'])
 
 
   def test_directory_children(self):
@@ -183,27 +183,27 @@ class TestDocument2(object):
     self.home_dir.children.add(*children)
 
     # Test that all children directories and documents are returned
-    response = self.client.get('/desktop/api2/docs', {'path': '/'})
+    response = self.client.get('/desktop/api2/doc', {'path': '/'})
     data = json.loads(response.content)
     assert_true('children' in data)
     assert_equal(5, data['count'])  # This includes the 4 docs and .Trash
 
     # Test filter type
-    response = self.client.get('/desktop/api2/docs', {'path': '/', 'type': ['directory']})
+    response = self.client.get('/desktop/api2/doc', {'path': '/', 'type': ['directory']})
     data = json.loads(response.content)
     assert_equal(['directory'], data['types'])
     assert_equal(3, data['count'])
     assert_true(all(doc['type'] == 'directory' for doc in data['children']))
 
     # Test search text
-    response = self.client.get('/desktop/api2/docs', {'path': '/', 'text': 'query'})
+    response = self.client.get('/desktop/api2/doc', {'path': '/', 'text': 'query'})
     data = json.loads(response.content)
     assert_equal('query', data['text'])
     assert_equal(2, data['count'])
     assert_true(all('query' in doc['name'] for doc in data['children']))
 
     # Test pagination with limit
-    response = self.client.get('/desktop/api2/docs', {'path': '/', 'page': 2, 'limit': 2})
+    response = self.client.get('/desktop/api2/doc', {'path': '/', 'page': 2, 'limit': 2})
     data = json.loads(response.content)
     assert_equal(5, data['count'])
     assert_equal(2, len(data['children']))
@@ -220,7 +220,7 @@ class TestDocument2(object):
     query = Document2.objects.create(name='query2.sql', type='query-hive', owner=self.user, data={}, parent_directory=self.home_dir)
 
     # Test that .Trash is currently empty
-    response = self.client.get('/desktop/api2/docs', {'path': '/.Trash'})
+    response = self.client.get('/desktop/api2/doc', {'path': '/.Trash'})
     data = json.loads(response.content)
     assert_equal(0, data['count'])
 
@@ -229,7 +229,7 @@ class TestDocument2(object):
     data = json.loads(response.content)
     assert_equal(0, data['status'])
 
-    response = self.client.get('/desktop/api2/docs', {'path': '/.Trash'})
+    response = self.client.get('/desktop/api2/doc', {'path': '/.Trash'})
     data = json.loads(response.content)
     assert_equal(1, data['count'])
     assert_equal(data['children'][0]['uuid'], query.uuid)
@@ -239,12 +239,12 @@ class TestDocument2(object):
     data = json.loads(response.content)
     assert_equal(0, data['status'], data)
 
-    response = self.client.get('/desktop/api2/docs', {'path': '/.Trash'})
+    response = self.client.get('/desktop/api2/doc', {'path': '/.Trash'})
     data = json.loads(response.content)
     assert_equal(2, data['count'])
 
     # Child document should be in trash too
-    response = self.client.get('/desktop/api2/docs', {'path': '/.Trash/test_dir'})
+    response = self.client.get('/desktop/api2/doc', {'path': '/.Trash/test_dir'})
     data = json.loads(response.content)
     assert_equal(nested_query.uuid, data['children'][0]['uuid'])
 
@@ -256,7 +256,7 @@ class TestDocument2(object):
     assert_false(Document2.objects.filter(uuid=nested_query.uuid).exists())
 
     # Verify that only doc in home is .Trash
-    response = self.client.get('/desktop/api2/docs', {'path': '/'})
+    response = self.client.get('/desktop/api2/doc', {'path': '/'})
     data = json.loads(response.content)
     assert_true('children' in data)
     assert_equal(1, data['count'])
@@ -330,7 +330,7 @@ class TestDocument2Permissions(object):
     self.default_group = get_default_user_group()
 
     # This creates the user directories for the new user
-    response = self.client.get('/desktop/api2/docs/')
+    response = self.client.get('/desktop/api2/doc/')
     data = json.loads(response.content)
     assert_equal('/', data['document']['path'], data)
 
@@ -341,24 +341,24 @@ class TestDocument2Permissions(object):
     # Tests that for a new doc by default, read/write perms are set to no users and no groups
     new_doc = Document2.objects.create(name='new_doc', type='query-hive', owner=self.user, data={}, parent_directory=self.home_dir)
 
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': new_doc.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': new_doc.uuid})
     data = json.loads(response.content)
-    assert_equal(new_doc.uuid, data['uuid'], data)
-    assert_true('perms' in data)
+    assert_equal(new_doc.uuid, data['document']['uuid'], data)
+    assert_true('perms' in data['document'])
     assert_equal({'read': {'users': [], 'groups': []}, 'write': {'users': [], 'groups': []}},
-                 data['perms'])
+                 data['document']['perms'])
 
 
   def test_share_document_read_by_user(self):
     doc = Document2.objects.create(name='new_doc', type='query-hive', owner=self.user, data={}, parent_directory=self.home_dir)
 
     # owner can view document
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': doc.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': doc.uuid})
     data = json.loads(response.content)
-    assert_equal(doc.uuid, data['uuid'], data)
+    assert_equal(doc.uuid, data['document']['uuid'], data)
 
     # other user cannot view document
-    response = self.client_not_me.get('/desktop/api2/doc/get', {'uuid': doc.uuid})
+    response = self.client_not_me.get('/desktop/api2/doc/', {'uuid': doc.uuid})
     data = json.loads(response.content)
     assert_equal(-1, data['status'])
 
@@ -387,21 +387,21 @@ class TestDocument2Permissions(object):
     assert_false(doc.can_write(self.user_not_me))
 
     # other user can view document
-    response = self.client_not_me.get('/desktop/api2/doc/get', {'uuid': doc.uuid})
+    response = self.client_not_me.get('/desktop/api2/doc/', {'uuid': doc.uuid})
     data = json.loads(response.content)
-    assert_equal(doc.uuid, data['uuid'], data)
+    assert_equal(doc.uuid, data['document']['uuid'], data)
 
 
   def test_share_document_read_by_group(self):
     doc = Document2.objects.create(name='new_doc', type='query-hive', owner=self.user, data={}, parent_directory=self.home_dir)
 
     # owner can view document
-    response = self.client.get('/desktop/api2/doc/get', {'uuid': doc.uuid})
+    response = self.client.get('/desktop/api2/doc/', {'uuid': doc.uuid})
     data = json.loads(response.content)
-    assert_equal(doc.uuid, data['uuid'], data)
+    assert_equal(doc.uuid, data['document']['uuid'], data)
 
     # other user cannot view document
-    response = self.client_not_me.get('/desktop/api2/doc/get', {'uuid': doc.uuid})
+    response = self.client_not_me.get('/desktop/api2/doc/', {'uuid': doc.uuid})
     data = json.loads(response.content)
     assert_equal(-1, data['status'])
 
@@ -430,9 +430,9 @@ class TestDocument2Permissions(object):
     assert_false(doc.can_write(self.user_not_me))
 
     # other user can view document
-    response = self.client_not_me.get('/desktop/api2/doc/get', {'uuid': doc.uuid})
+    response = self.client_not_me.get('/desktop/api2/doc/', {'uuid': doc.uuid})
     data = json.loads(response.content)
-    assert_equal(doc.uuid, data['uuid'], data)
+    assert_equal(doc.uuid, data['document']['uuid'], data)
 
 
   def test_share_document_write_by_user(self):
@@ -567,7 +567,7 @@ class TestDocument2Permissions(object):
     shared_2.share(user=self.user, name='read', users=[self.user_not_me], groups=[])
 
     # 2 shared docs should appear in the other user's shared documents response
-    response = self.client_not_me.get('/desktop/api2/docs/shared')
+    response = self.client_not_me.get('/desktop/api2/docs/', {'perms': 'shared'})
     data = json.loads(response.content)
     assert_true('documents' in data)
     assert_equal(2, data['count'])
@@ -577,7 +577,7 @@ class TestDocument2Permissions(object):
     assert_false('query1.sql' in doc_names)
 
     # they should not appear in the other user's regular get_documents response
-    response = self.client_not_me.get('/desktop/api2/docs/')
+    response = self.client_not_me.get('/desktop/api2/doc/')
     data = json.loads(response.content)
     doc_names = [doc['name'] for doc in data['children']]
     assert_false('query2.sql' in doc_names)
@@ -606,7 +606,7 @@ class TestDocument2Permissions(object):
     doc3.share(user=self.user, name='read', users=[], groups=[self.default_group])
 
     # 3 shared docs should appear, due to directory rollup
-    response = self.client_not_me.get('/desktop/api2/docs/shared')
+    response = self.client_not_me.get('/desktop/api2/docs/', {'perms': 'shared', 'flatten': 'false'})
     data = json.loads(response.content)
     assert_true('documents' in data)
     assert_equal(3, data['count'], data)
@@ -621,13 +621,13 @@ class TestDocument2Permissions(object):
     assert_false('query2.sql' in doc_names)
 
     # but nested documents should still be shared/viewable by group
-    response = self.client_not_me.get('/desktop/api2/doc/get', {'uuid': doc1.uuid})
+    response = self.client_not_me.get('/desktop/api2/doc/', {'uuid': doc1.uuid})
     data = json.loads(response.content)
-    assert_equal(doc1.uuid, data['uuid'], data)
+    assert_equal(doc1.uuid, data['document']['uuid'], data)
 
-    response = self.client_not_me.get('/desktop/api2/doc/get', {'uuid': doc2.uuid})
+    response = self.client_not_me.get('/desktop/api2/doc/', {'uuid': doc2.uuid})
     data = json.loads(response.content)
-    assert_equal(doc2.uuid, data['uuid'], data)
+    assert_equal(doc2.uuid, data['document']['uuid'], data)
 
 
   def test_search_documents(self):
@@ -644,7 +644,7 @@ class TestDocument2Permissions(object):
     shared_2.share(user=self.user_not_me, name='read', users=[], groups=[self.default_group])
 
     # 3 total docs (1 owned, 2 shared)
-    response = self.client.get('/desktop/api2/docs/search', {'type': 'query-hive'})
+    response = self.client.get('/desktop/api2/docs/', {'type': 'query-hive'})
     data = json.loads(response.content)
     assert_true('documents' in data)
     assert_equal(3, data['count'])

+ 10 - 12
desktop/core/src/desktop/urls.py

@@ -116,18 +116,16 @@ dynamic_patterns += patterns('desktop.api',
 )
 
 dynamic_patterns += patterns('desktop.api2',
-  (r'^desktop/api2/docs/?$', 'get_documents'),
-  (r'^desktop/api2/docs/shared?$', 'get_shared_documents'),
-  (r'^desktop/api2/docs/search?$', 'search_documents'),
-
-  (r'^desktop/api2/doc/get$', 'get_document'),
-  (r'^desktop/api2/doc/move$', 'move_document'),
-  (r'^desktop/api2/doc/mkdir$', 'create_directory'),
-  (r'^desktop/api2/doc/delete$', 'delete_document'),
-  (r'^desktop/api2/doc/share$', 'share_document'),
-
-  (r'^desktop/api2/doc/export$', 'export_documents'),
-  (r'^desktop/api2/doc/import$', 'import_documents'),
+  (r'^desktop/api2/docs/?$', 'search_documents'),
+
+  (r'^desktop/api2/doc/?$', 'get_document'),
+  (r'^desktop/api2/doc/move/?$', 'move_document'),
+  (r'^desktop/api2/doc/mkdir/?$', 'create_directory'),
+  (r'^desktop/api2/doc/delete/?$', 'delete_document'),
+  (r'^desktop/api2/doc/share/?$', 'share_document'),
+
+  (r'^desktop/api2/doc/export/?$', 'export_documents'),
+  (r'^desktop/api2/doc/import/?$', 'import_documents'),
 )
 
 dynamic_patterns += patterns('useradmin.views',