def setUp(self): self.app = create_app('TESTING_CONFIG') self.app_context = self.app.app_context() self.app_context.push() self.client = self.app.test_client() self.basedir = os.path.abspath(os.path.dirname(__file__)) db.create_all() test_password = '******' Organization.insert_org() UserScope.insert_scopes() User.insert_user(password=test_password) self.client = self.app.test_client(use_cookies=False) # set the vars for the connection self.cmisUrl = \ 'https://alfresco.oceanobservatories.org/alfresco/s/api/cmis' self.cmisUsername = '******' self.cmisPassword = '******' self.cmisId = 'c161bc66-4f7e-4a4f-b5f2-aac9fbf1d3cd' # cmis is tested elsewhere from cmislib.model import CmisClient client = CmisClient(self.cmisUrl, self.cmisUsername, self.cmisPassword) repo = client.getRepository(self.cmisId)
def test_cmislib_CRD(self): from cmislib.model import CmisClient client = CmisClient(self.cmisUrl, self.cmisUsername, self.cmisPassword) repo = client.getRepository(self.cmisId) # for tests, lets make sure the test folder isn't still there try: print ". . ." someObject = repo.getObjectByPath('/testFolder') someObject.deleteTree() except: print "\tno existing folders..." # create a new dir in the root folder print "\ttesting folder creation..." root = repo.rootFolder someFolder = root.createFolder('testFolder') # create a test file and drop it in the test folder. print "\ttesting file creation..." someFile = open(self.basedir + '/mock_data/test.txt', 'r') someFolder.createDocument('Test Document', contentFile=someFile) # test read by using a full-text search. print "\ttesting full-text search (read)..." repo.query("select * from cmis:document where contains('test')") # Then obliterate the folder and all it's children, mercilessly. print "\ttesting delete..." someFolder.deleteTree()
def test_alfresco_bp(self): from cmislib.model import CmisClient client = CmisClient(self.cmisUrl, self.cmisUsername, self.cmisPassword) repo = client.getRepository(self.cmisId) from ooiservices.app import alfresco # test unauth print '\n\ttesting authenication . . .' response = self.client.get('/alfresco/', content_type = 'application/json') self.assertTrue(response.status_code == 401) # lets auth on the services headers = self.get_api_headers('admin', 'test') # test redirect (if no trailing slash is provided, will get redirect) print '\ttesting redirect . . .' response = self.client.get('/alfresco', headers = headers, content_type = 'application/json') self.assertTrue(response.status_code == 301) # test redirect (if no trailing slash is provided, will get redirect) print '\ttesting not found . . .' response = self.client.get('/alfresco/notfound', headers = headers, content_type = 'application/json') self.assertTrue(response.status_code == 404) # test root (should respond with alfresco repo informatioN) print '\ttesting root . . .' response = self.client.get('/alfresco/', headers = headers, content_type = 'application/json') self.assertTrue(response.status_code == 200)
class DmsAdapter(CRUDAdapter): def auth(self): backend_record = self.backend_record self.client = CmisClient(backend_record.location, backend_record.username, backend_record.password) def get_repositories(self): return { r['repositoryId']: r['repositoryName'] for r in self.client.getRepositories() } def get_repository(self, repository_id): return self.client.getRepository(repository_id) def read_document_from_path(self, repository_id, path): repo = self.client.getRepository(repository_id) if isinstance(path, unicode): path = path.encode('utf-8') doc = repo.getObjectByPath(path) output = StringIO() output.write(doc.getContentStream().read()) data = output.getvalue() version = doc.getProperties()['cmis:versionLabel'] return data, version
def sync(): # Connect to the source repo sourceClient = CmisClient(settings.SOURCE_REPOSITORY_URL, settings.SOURCE_USERNAME, settings.SOURCE_PASSWORD) sourceRepo = sourceClient.defaultRepository dumpRepoHeader(sourceRepo, "SOURCE") # Make sure it supports changes, bail if it does not if sourceRepo.getCapabilities()['Changes'] == None: print "Source repository does not support changes:" + sourceRepo.getCapabilities( )['Changes'] sys.exit(-1) latestChangeToken = sourceRepo.info['latestChangeLogToken'] print "Latest change token: %s" % latestChangeToken # Connect to the target repo targetClient = CmisClient(settings.TARGET_REPOSITORY_URL, settings.TARGET_USERNAME, settings.TARGET_PASSWORD) targetRepo = targetClient.defaultRepository dumpRepoHeader(targetRepo, "TARGET") print " Path: %s" % settings.TARGET_ROOT # Get last token synced from savefile # Using the repository IDs so that you can use this script against # multiple source-target pairs and it will remember where you are syncKey = "%s><%s" % (sourceRepo.id, targetRepo.id) lastChangeSynced = {} changeToken = None if (os.path.exists(SAVE_FILE)): lastChangeSynced = pickle.load(open(SAVE_FILE, "rb")) if lastChangeSynced.has_key(syncKey): print "Last change synced: %s" % lastChangeSynced[syncKey] changeToken = lastChangeSynced[syncKey] else: print "First sync..." else: print "First sync..." if changeToken == latestChangeToken: print "No changes since last sync so no work to do" return # Ask the source repo for changes changes = None if changeToken != None: changes = sourceRepo.getContentChanges(changeLogToken=changeToken) else: changes = sourceRepo.getContentChanges() # Process each change for change in changes: if change.changeType == 'created' or change.changeType == 'updated': processChange(change, sourceRepo, targetRepo) lastChangeSynced[syncKey] = latestChangeToken pickle.dump(lastChangeSynced, open(SAVE_FILE, "wb")) return
def testGetRepositoryBadId(self): """Try to get a repository with a bad repo ID""" cmisClient = CmisClient(self.url, self.user, self.pwd, binding=self.binding, **self.ext_args) with pytest.raises(ObjectNotFoundException): cmisClient.getRepository('123FOO')
def testCmisClientBadUrl(self): """Try to instantiate a CmisClient object with a known bad URL""" cmisClient = CmisClient(self.url + 'foobar', self.user, self.pwd, binding=self.binding, **self.ext_args) with pytest.raises(CmisException): cmisClient.getRepositories()
def _repository(self): client = CmisClient( self._repository_url, self.repository_user, self.repository_password) repositories = client.getRepositories() assert len(repositories) == 1 identifier = repositories[0]['repositoryId'] return client.getRepository(identifier)
def testDefaultRepository(self): """Get the default repository by calling the repo's service URL""" cmisClient = CmisClient(self.url, self.user, self.pwd, binding=self.binding, **self.ext_args) repo = cmisClient.getDefaultRepository() assert repo is not None assert repo.getRepositoryId() is not None
def cmis_connect(url, username = '', password = ''): print print "** Connecting to %s" % url print "Environment variables: CMIS_URL, CMIS_USERNAME, CMIS_PASSWORD" client = CmisClient(url, username, password) print '** Connected to repository %s' % (client.getDefaultRepository().getRepositoryName()) print return client
def make_alfresco_conn(self): # create the cmis client client = CmisClient( self.ALFRESCO_URL, self.ALFRESCO_UN, self.ALFRESCO_PW) # connect to the alfresco server and return the repo object repo = client.getRepository(self.ALFRESCO_ID) # this will be what we work with primarily # returns a repo object return repo
def testTypeDefinition(self): """Get the cmis:document type and test a few props of the type.""" cmisClient = CmisClient(self.url, self.user, self.pwd, binding=self.binding, **self.ext_args) repo = cmisClient.getDefaultRepository() docTypeDef = repo.getTypeDefinition('cmis:document') assert 'cmis:document' == docTypeDef.getTypeId() assert docTypeDef.baseId
def cmis_connect(self, cr, uid): """Connect to the CMIS Server and returns the document repository""" user = self.pool.get('res.users').browse(cr, uid, uid) server_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'document_cmis.server_url') if not server_url: raise osv.except_osv(_('Error!'),_("Cannot connect to the CMIS Server: No CMIS Server URL system property found")) client = CmisClient(server_url, user.login, user.password) repo = client.getDefaultRepository() return repo
def test_cmislib_connection(self): from cmislib.model import CmisClient # create the connection object client = CmisClient(self.cmisUrl, self.cmisUsername, self.cmisPassword) # check to make sure the object was created with the correct url self.assertEquals(client.repositoryUrl, self.cmisUrl) # use the client to connect to the repository repo = client.getRepository(self.cmisId) # make sure the repo information is referencing the correct repository self.assertEqual(repo.info['repositoryId'], self.cmisId)
def testGetRepositories(self): """Call getRepositories and make sure at least one comes back with an ID and a name """ cmisClient = CmisClient(self.url, self.user, self.pwd, binding=self.binding, **self.ext_args) repoInfo = cmisClient.getRepositories() assert len(repoInfo) >= 1 assert 'repositoryId' in repoInfo[0] assert 'repositoryName' in repoInfo[0]
def testGetRepository(self): """Get a repository by repository ID""" cmisClient = CmisClient(self.url, self.user, self.pwd, binding=self.binding, **self.ext_args) repo = cmisClient.getDefaultRepository() defaultRepoId = repo.getRepositoryId() defaultRepoName = repo.getRepositoryName() repo = cmisClient.getRepository(defaultRepoId) assert defaultRepoId == repo.getRepositoryId() assert defaultRepoName == repo.getRepositoryName()
def setLastSync(changeToken): sourceClient = CmisClient(settings.SOURCE_REPOSITORY_URL, settings.SOURCE_USERNAME, settings.SOURCE_PASSWORD) sourceRepo = sourceClient.defaultRepository targetClient = CmisClient(settings.TARGET_REPOSITORY_URL, settings.TARGET_USERNAME, settings.TARGET_PASSWORD) targetRepo = targetClient.defaultRepository syncKey = "%s><%s" % (sourceRepo.id, targetRepo.id) lastChangeSynced = {syncKey: changeToken} pickle.dump(lastChangeSynced, open(SAVE_FILE, "wb")) print "Forced last sync to: %s" % changeToken
def testTypeProperties(self): """Get the properties for a type.""" cmisClient = CmisClient(self.url, self.user, self.pwd, binding=self.binding, **self.ext_args) repo = cmisClient.getDefaultRepository() docTypeDef = repo.getTypeDefinition('cmis:document') assert 'cmis:document' == docTypeDef.getTypeId() props = docTypeDef.getProperties().values() assert len(props) > 0 for prop in props: if prop.queryable: assert prop.queryName assert prop.propertyType
def _auth(self, cr, uid, ids, context=None): """Test connection with CMIS""" if context is None: context = self.pool['res.users'].context_get(cr, uid) # Get the url, user and password for CMIS # ids = self.search(cr, uid, []) if not ids: raise orm.except_orm( _('Internal Error'), _('Something very wrong happened. _auth() ' 'called without any ids.')) if type(ids) is not list: ids = [ids] res = self.read(cr, uid, ids, ['location', 'username', 'password'], context=context)[0] url = res['location'] user_name = res['username'] user_password = res['password'] client = CmisClient(url, user_name, user_password) try: return client.defaultRepository except cmislib.exceptions.ObjectNotFoundException: raise orm.except_orm(_('CMIS connection Error!'), _("Check your CMIS account configuration.")) except cmislib.exceptions.PermissionDeniedException: raise orm.except_orm(_('CMIS connection Error!'), _("Check your CMIS account configuration.")) except urllib2.URLError: raise orm.except_orm(_('CMIS connection Error!'), _("SERVER is down."))
def testCmisClient(self): """Instantiate a CmisClient object""" cmisClient = CmisClient(self.url, self.user, self.pwd, binding=self.binding, **self.ext_args) assert cmisClient is not None
def make_alfresco_query(self, query): ''' query the alfresco server for all documents matching the search param. **CAUTION: THIS MAY TAKE A WHILE TO RESPOND** ''' # create the cmis client client = CmisClient( self.ALFRESCO_URL, self.ALFRESCO_UN, self.ALFRESCO_PW) # connect to the alfresco server and return the repo object repo = client.getRepository(self.ALFRESCO_ID) # use this files connection method # issue the query results = repo.query("select * from cmis:document where contains('\"%s\"')" % query) return results
def __init__(self, repository_url, username, password, base_folder): self.repository_url = repository_url self.username = username self.password = password self.base_folder = base_folder self.client = CmisClient(repository_url, username, password) self.repo = self.client.getDefaultRepository()
def testTypeDescendants(self): """Get the descendant types of the repository.""" cmisClient = CmisClient(self.url, self.user, self.pwd, binding=self.binding, **self.ext_args) repo = cmisClient.getDefaultRepository() typeDefs = repo.getTypeDescendants() folderDef = None for typeDef in typeDefs: if typeDef.getTypeId() == 'cmis:folder': folderDef = typeDef break assert folderDef assert folderDef.baseId
def get_cmis_client(self): """ Get an initialized CmisClient using the CMISBrowserBinding """ self.ensure_one() return CmisClient(self.location, self.username, self.password, binding=BrowserBinding())
def badSetUp(self): self.app = create_app('TESTING_CONFIG') self.app_context = self.app.app_context() self.app_context.push() self.client = self.app.test_client() self.basedir = os.path.abspath(os.path.dirname(__file__)) # set the vars for the connection self.cmisUrl = 'http://localhost/alfresco/badsetup' self.cmisUsername = '******' self.cmisPassword = '******' self.cmisId = 'not-correct-code' # cmis is tested elsewhere from cmislib.model import CmisClient client = CmisClient(self.cmisUrl, self.cmisUsername, self.cmisPassword) repo = client.getRepository(self.cmisId)
def make_alfresco_cruise_query(self, array,cruise): ''' query the alfresco server for all documents relating to a cruise ''' # create the cmis client client = CmisClient(self.ALFRESCO_URL, self.ALFRESCO_UN, self.ALFRESCO_PW) # connect to the alfresco server and return the repo object repo = client.getRepository(self.ALFRESCO_ID) # use this files connection method doc = repo.getObjectByPath("/OOI/"+array+" Array/Cruise Data") folder_query = "IN_FOLDER('"+doc.id+"')" array_cruises = repo.query("select * FROM cmis:folder WHERE "+folder_query) #setup the cruise information results = [] cruise_id = None if len(cruise) > 0: cruise_split = re.split('\s|-|;|,|\*|\n',cruise) cruise = "-".join(cruise_split) #unique case... if cruise == "Scarlett-Isabella": cruise = "SI" for r in array_cruises: cruise_str = r.getName().split("_")[1] if cruise in cruise_str: cruise_id = r break #only should the cruise information if its availablep if cruise_id is not None: cruise_results = repo.query("select * FROM cmis:document where IN_FOLDER('"+cruise_id.id+"')") for c in cruise_results: c.type = "cruise" #add the cruise link cruise_id.type = "link" return cruise_results,cruise_id #return the defaults if not available return results,cruise_id
def start(self): if self._repository is not None: return self._root options = {} if self._settings.proxy: options['proxy'] = { 'http': self._settings.proxy, 'https': self._settings.proxy} client = CmisClient( self._settings.repository_url, self._settings.repository_user, self._settings.repository_password, **options) repositories = client.getRepositories() if self._settings.repository_name: for repository in repositories: if self._settings.repository_name == repository['repositoryName']: break else: raise RESTConnectorError( u'Unknown repository: %s' % ( self._settings.repository_name)) elif len(repositories) == 1: repository = repositories[0] else: raise RESTConnectorError( u'Multiple repository available. Please select one.') self._repository_id = repository['repositoryId'] self._repository = client.getRepository(self._repository_id) # Find root if self._settings.repository_path: self._root = self.get_object_by_path( self._settings.repository_path, root=True) else: self._root = cmis_object_to_dict( self._repository.getRootFolder(), root=True) return self._root
def __init__(self, base_folder=None): self.options = settings.CMIS_STORAGE_OPTIONS if 'baseFolder' not in self.options: self.options['baseFolder'] = '/' if base_folder: self.options['baseFolder'] = base_folder self.client = CmisClient(**self.options) self.repo = self.client.getDefaultRepository()
def get_repository(): try: URL_CMIS = "http://%s:%d/alfresco/cmisatom" % (settings.IP_SERVER, settings.PORT_SERVER) client = CmisClient(URL_CMIS, settings.USERNAME_ALF, settings.PASSWORD_ALF) repo = client.defaultRepository return repo, True except: return False, make_response( jsonify({'error': 'Authentication Failed'}), 503)
def testTypeChildren(self): """Get the child types for this repository and make sure cmis:folder is in the list.""" # This test would be more interesting if there was a standard way to # deploy a custom model. Then we could look for custom types. cmisClient = CmisClient(self.url, self.user, self.pwd, binding=self.binding, **self.ext_args) repo = cmisClient.getDefaultRepository() typeDefs = repo.getTypeChildren() folderDef = None for typeDef in typeDefs: if typeDef.getTypeId() == 'cmis:folder': folderDef = typeDef break assert folderDef assert folderDef.baseId
def load_config(self): '''Read available configurations options from trac.ini''' self.url_api = self.env.config.get('cmis', 'url_api') self.user = self.env.config.get('cmis', 'user') self.password = self.env.config.get('cmis', 'password') self.base_path = self.env.config.get('cmis', 'base_path') self.max_size = self.env.config.getint('cmis', 'max_size') self.log.info('Plugin Configuration loaded') try: self.cmis_client = CmisClient(self.url_api, self.user, self.password) self.repository = self.cmis_client.getDefaultRepository() self.root_cmis_object = self.repository.getObjectByPath(self.base_path) except: raise TracError('Unable to connect to the repository. Check the configuration')
def cmis_env(request): """Initialize a cmis environement with * CmisClient * repo * rootFolder * test folder name * test folder All these attributes are reset after each test method """ _generate_conf(request) param = request.param request.cls._cmisClient = CmisClient(param.url, param.user, param.pwd, binding=param.binding, **param.ext_args) request.cls._repo = request.cls._cmisClient.getDefaultRepository() request.cls._rootFolder = request.cls._repo.getRootFolder() request.cls._folderName = " ".join( ['cmislib', request.cls.__name__, str(time())]) request.cls._testFolder = request.cls._rootFolder.createFolder( request.cls._folderName) productVersion = request.cls._repo.getRepositoryInfo().get( 'productVersion', '9.9.9') request.cls._productVersion = _Version(productVersion) yield request try: request.cls._testFolder.deleteTree() except NotSupportedException: print("Couldn't delete test folder because deleteTree is not " "supported") except RuntimeException: # deleting a folder could fail if the indexation of a new document # is in progress sleep(5) try: request.cls._testFolder.deleteTree() except RuntimeException: print("Couldn't delete test folder")
def submit_document(doc, method=None): repository_disabled = frappe.db.get_single_value("Repository", "disabled") if repository_disabled == 0: mapping_path = frappe.db.get_value("Mapping", {"doc_type": doc.doctype}, "doc_path") if mapping_path is not None: mapping_disabled = frappe.db.get_value("Mapping", {"doc_type": doc.doctype}, "doc_type_disabled") if mapping_disabled == 0: try: repositoryURL = frappe.db.get_single_value("Repository", "url") userName = frappe.db.get_single_value("Repository", "userid") userPass = frappe.db.get_single_value("Repository", "password") #msgprint("RepURL ... "+repositoryURL+" "+userName+" "+userPass, [doc]) client = CmisClient(repositoryURL, userName, userPass) repo = client.defaultRepository mapping_name = frappe.db.get_value("Mapping", {"doc_type": doc.doctype}, "name") mapping_type = frappe.db.get_value("Mapping", {"doc_type": doc.doctype}, "doc_type_alfresco") mapping_user = frappe.db.get_value("User Mapping", {"erpnext_user": frappe.session.user}, "alfresco_user", None, False, False) if mapping_user is None: mapping_user = "******" mapping_properties = frappe.db.get_values("Mapping Item", {"parent": mapping_name}, ["db_field", "alfresco_aspect", "alfresco_property"], as_dict=True) #for map_det in mapping_properties: # print map_det docu = createDoc(doc, repo, mapping_path, mapping_type, mapping_properties) except Exception, e: #print e frappe.throw(_("<p>Cannot connect to Alfresco Repository</p><p><ul><li>Please check the Repository Settings</li><li>Disable the Repository</li><li>Disable the DocType Mapping</li></ul></p>")) # msgprint("Document submitted ... ", [doc]) else: #pass msgprint("Doctype disabled ... ", [doc]) else: pass
def setup(self): self._client = CmisClient(REPOSITORY_URL, USERNAME, PASSWORD) self._repo = self._client.defaultRepository
def main(): """Main method (split it if you want cleaner code. Creates a folder called "TEST", then stuffs if with the content of the local folder specified in config.py. """ client = CmisClient(REPOSITORY_URL, USERNAME, PASSWORD) repo = client.getDefaultRepository() root_folder = repo.getObjectByPath(REMOTE_PATH) # Removes the TEST folder if it already exists try: object = repo.getObjectByPath(REMOTE_PATH + "/TEST") object.deleteTree() except: pass root_folder.createFolder("TEST") start_time = time.time() for root, dirs, files in os.walk(LOCAL_PATH): root_rel = root[len(LOCAL_PATH) :] remote_parent = repo.getObjectByPath(REMOTE_PATH + "/TEST" + root_rel) for dir in dirs: # FIXME later: skip non-ascii file names if dir.encode("ascii", errors="replace") != dir: continue print "----" print ("creating dir: %s" % dir).encode("ascii", errors="replace") remote_parent.createFolder(dir) for file in files: # FIXME later: skip non-ascii file names if file.encode("ascii", errors="replace") != file: continue print "----" if os.stat(os.path.join(root, file)).st_size > 1e6: print ("File %s too big, skipping" % file).encode("ascii", errors="replace") continue print ("Creating file: %s" % file).encode("ascii", errors="replace"), try: local_fd = open(os.path.join(root, file)) created = remote_parent.createDocument(file, contentFile=local_fd) local_fd.close() print "OK" except AssertionError, e: print "KO: exception raised" print e except CmisException, e: print "KO: exception raised" print e print "nNote: remote name is:", created.properties["cmis:name"].encode("ascii", errors="replace") print ("Verifying file: %s" % file).encode("ascii", errors="replace"), try: path = REMOTE_PATH + "/TEST" + root_rel + "/" + file object = repo.getObjectByPath(path) remote_fd = object.getContentStream() local_fd = open(os.path.join(root, file)) if compare(local_fd, remote_fd): print "OK" else: print "KO: Content differs" except AssertionError, e: print "KO: exception raised" print e
weprep = weprep + "<hr>" body = "This is a project to show system load. Using a share amp to expose create update delete behaviors, using a webscript and paper.js with ajax calls. This content is created on the fly using the awesome cmislib (thanks Jeff Potts) to build this content" ftab = "<table width=500 height=30 border=2>" ftab = ftab + "<tr>" ftab = ftab + "<td>Alfresco Hackathon</td><td>marsbard and digcat</td><td>DataVisProject</td><td>1</td>" ftab = ftab + "</tr>" ftab = ftab + "<tr>" ftab = ftab + "<td colspan=4>" + body + "</td>" ftab = ftab + "</tr>" ftab = ftab + "</table>" weprep = weprep + ftab cmurl = 'https://' + hostname + '/alfresco/cmisatom' client = CmisClient(cmurl, 'admin', 'admin') sitename = 'alfresco-hackathon' basepath = '/Sites/' + sitename + '/documentLibrary' rootofwn = basepath + '/' + rootfoldername repo = client.defaultRepository try: rootsite = repo.getObjectByPath(rootofwn) except: rootsite = repo.getObjectByPath(basepath) basefolder = rootsite.createFolder(rootfoldername) try: rootsite = repo.getObjectByPath(rootofwn) except: print "Error: Unable to create folder"
# -*- coding: utf-8 -*- import time import base64 import xmlrpclib from cmislib.model import CmisClient, Repository server = "localhost" dbname = "natuurpunt" uid = 1 pwd = "n2aevl8w" # replace localhost wity the address of the server sock = xmlrpclib.ServerProxy("http://%s:8069/xmlrpc/object" % (server)) """Connect to the CMIS Server and returns the document repository""" client = CmisClient("http://192.168.1.225:8080/alfresco/s/cmis", "admin", "a2aevl8w") repo = client.getDefaultRepository() def process(cmis_naam, cmis_object_id): print "***** Start processing {} *****".format(cmis_naam) process_cmis_dir(repo.getObject(cmis_object_id)) print "***** End processing {} *****".format(cmis_naam) def process_cmis_dir(cmisDir): query = ( """ select cmis:objectId, cmis:name from cmis:folder where in_folder('%s')
class RemoteClient(Client): """CMIS Client""" def __init__(self, repository_url, username, password, base_folder): self.repository_url = repository_url self.username = username self.password = password self.base_folder = base_folder self.client = CmisClient(repository_url, username, password) self.repo = self.client.getDefaultRepository() def get_descendants(self, path=""): result = [] remote_path = self.get_remote_path(path) object = self.repo.getObjectByPath(remote_path) children = object.getChildren() for child in children: properties = child.properties # Hack around some Nuxeo quirks child_name = properties['cmis:name'] if properties.has_key('cmis:path'): child_name = properties['cmis:path'].split('/')[-1] if child_name.startswith('.'): continue if path == "": child_path = child_name else: child_path = path + "/" + child_name state = self.make_state(child_path, properties) if state.type == 'folder': result += [state] + self.get_descendants(child_path) else: result += [state] return result def get_state(self, path): remote_path = self.get_remote_path(path) try: object = self.repo.getObjectByPath(remote_path) properties = object.properties return self.make_state(path, properties) except ObjectNotFoundException: return None def get_content(self, path): remote_path = self.get_remote_path(path) object = self.repo.getObjectByPath(remote_path) try: return object.getContentStream().read() except AssertionError: # No attached stream: bug in Nuxeo? return "" # Modifiers def mkdir(self, path): remote_path = self.get_remote_path(path) parent_path, name = os.path.split(remote_path) parent_folder = self.repo.getObjectByPath(parent_path) parent_folder.createFolder(name) def mkfile(self, path, content=None): remote_path = self.get_remote_path(path) parent_path, name = os.path.split(remote_path) parent_folder = self.repo.getObjectByPath(parent_path) content_file = StringIO(content) content_file.name = path.rsplit('/', 1)[-1] parent_folder.createDocument(name, contentFile=content_file) def update(self, path, content): remote_path = self.get_remote_path(path) object = self.repo.getObjectByPath(remote_path) content_file = StringIO(content) content_file.name = path.rsplit('/', 1)[-1] return object.setContentStream(content_file) # TODO: manage also mime type def delete(self, path): remote_path = self.get_remote_path(path) try: object = self.repo.getObjectByPath(remote_path) # XXX: hack, fix later try: object.delete() except: object.deleteTree() except ObjectNotFoundException: # nothing to delete pass # # Utilities # def get_remote_path(self, path): if path != "": return self.base_folder + "/" + path else: return self.base_folder def make_state(self, path, properties): if properties['cmis:baseTypeId'] == 'cmis:folder': type = 'folder' else: type = 'file' uid = properties['cmis:objectId'] mtime = properties['cmis:lastModificationDate'] return Info(path, uid, type, mtime)
import os, pwd uid = pwd.getpwuid(os.getuid())[0] storage = Storage("Jeff's Sample Python App", uid) http = Http( disable_ssl_certificate_validation=True) # Should not have to do this! flow = flow_from_clientsecrets('client_secrets.json', scope='public_api', redirect_uri='http://localhost:8080/') credentials = storage.get() if credentials == None: credentials = run(flow, storage, http=http) storage.put(credentials) print "Your access_token is: %s" % credentials.access_token http = credentials.authorize(http) headers = {'Authorization': 'Bearer ' + credentials.access_token} client = CmisClient('https://api.alfresco.com/cmis/versions/1.0/atom', '', '', headers=headers) repo = client.defaultRepository print "cmislib connected to:" print " Name: %s" % repo.getRepositoryInfo()['repositoryId'] print " Vendor: %s" % repo.getRepositoryInfo()['vendorName'] print " Version: %s" % repo.getRepositoryInfo()['productVersion']
class CmisTracPlugin(Component): implements(INavigationContributor, IRequestHandler, ITemplateProvider, IPermissionRequestor) def __init__(self): Component.__init__(self) self.url_api = None self.user = None self.password = None self.base_path = None self.max_size = None self.cmis_client = None self.repository = None self.root_cmis_object = None # INavigationContributor methods def get_active_navigation_item(self, req): return 'documents' def get_navigation_items(self, req): if req.perm.has_permission('REPOSITORY_BROWSER'): yield ('mainnav', 'documents', tag.a('Documents', href=req.href.documents())) # IRequestHandler methods def match_request(self, req): '''Check if applicable to this plugin''' match = re.match('^(/documents)(/)?(workspace://SpacesStore/)?([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})?(/)?(newfolder|removefolder|renamefolder|upload|download|removedocument)?$', req.path_info) self._print("cmistracplugin: Check req.path_info: [" + req.path_info + "] match: [" + ("true" if match else "false") + "]") if match: if match.group(4) != None: req.args['objectId'] = match.group(4) if match.group(6) != None: req.args['op'] = match.group(6) return True else: return False def process_request(self, req): '''Processes the request. Input validation and call the corresponding method''' req.perm.assert_permission('REPOSITORY_BROWSER') self.load_config() xhr = req.get_header('X-Requested-With') == 'XMLHttpRequest' add_script(req, 'common/js/expand_dir.js') add_stylesheet(req, 'common/css/browser.css') add_stylesheet(req, 'hw/cmistracplugin.css') if xhr: return 'folder-entries.html', self._render_cmis_object(req, xhr), None elif 'op' in req.args and req.args['op'] == 'newfolder': if 'objectId' in req.args: return 'new-folder.html', self._prepare_newfolder_form(req), None else: self._process_newfolder_form(req) req.redirect(req.href.documents(req.args['objectId'])) elif 'op' in req.args and req.args['op'] == 'removefolder': if 'objectId' in req.args: self._process_removefolder(req) req.redirect(req.href.documents(req.args['objectId'])) elif 'op' in req.args and req.args['op'] == 'renamefolder': if 'objectId' in req.args: if req.method == 'GET': return 'rename-folder.html', self._prepare_renamefolder_form(req), None else: self._process_renamefolder_form(req) if req.args['parentId']: req.redirect(req.href.documents(req.args['parentId'])) else: req.redirect(req.href.documents(req.args['objectId'])) elif 'op' in req.args and req.args['op'] == 'upload': if 'objectId' in req.args: return 'upload-document.html', self._prepare_upload_form(req), None elif 'cancel' in req.args: req.redirect(req.href.documents(req.args['parentId'])) else: self._process_upload_form(req) req.redirect(req.href.documents(req.args['objectId'])) elif 'op' in req.args and req.args['op'] == 'download': if 'objectId' in req.args: self._process_download(req) elif 'op' in req.args and req.args['op'] == 'removedocument': if 'objectId' in req.args: self._process_removedocument(req) if req.session['lastCmisFolderIdVisited']: req.redirect(req.href.documents(req.session['lastCmisFolderIdVisited'])) else: req.redirect(req.href.documents()) else: self._print("cmistracplugin: go to 'repository-browser.html'") return 'repository-browser.html', self._render_cmis_object(req), None # ITemplateProvider methods def get_templates_dirs(self): return [pkg_resources.resource_filename(__name__, 'templates')] def get_htdocs_dirs(self): return [('hw', pkg_resources.resource_filename(__name__, 'htdocs'))] # IPermissionRequestor methods def get_permission_actions(self): return ['REPOSITORY_BROWSER', 'REPOSITORY_UPLOAD', 'REPOSITORY_DOWNLOAD', 'REPOSITORY_CREATE_FOLDER', 'REPOSITORY_REMOVE_FOLDER', 'REPOSITORY_RENAME_FOLDER', 'REPOSITORY_REMOVE_DOCUMENT'] def load_config(self): '''Read available configurations options from trac.ini''' self.url_api = self.env.config.get('cmis', 'url_api') self.user = self.env.config.get('cmis', 'user') self.password = self.env.config.get('cmis', 'password') self.base_path = self.env.config.get('cmis', 'base_path') self.max_size = self.env.config.getint('cmis', 'max_size') self.log.info('Plugin Configuration loaded') try: self.cmis_client = CmisClient(self.url_api, self.user, self.password) self.repository = self.cmis_client.getDefaultRepository() self.root_cmis_object = self.repository.getObjectByPath(self.base_path) except: raise TracError('Unable to connect to the repository. Check the configuration') def _render_cmis_object(self, req, xhr = None): if 'objectId' in req.args: selt._print("cmis: get object: [" + str(req.args['objectId']) + "]") cmis_object = self.repository.getObject(req.args['objectId']) else: cmis_object = self.root_cmis_object data = {} data['rootFolder'] = self.root_cmis_object self._print("p1: cmistracplugin: cmis:objectTypeId: " + cmis_object.getProperties()['cmis:objectTypeId']) if cmis_object.getProperties()['cmis:objectTypeId'] in ['cmis:folder', 'Folder', 'Section', 'Workspace']: #if cmis_object.getProperties()['cmis:objectTypeId'] == 'cmis:folder' || cmis_object.getProperties()['cmis:objectTypeId'] == 'cmis:Section': cmis_objects = cmis_object.getChildren().getResults() data['breadcrumb'] = render_breadcrumb(self.cmis_client, self.repository, self.root_cmis_object, cmis_object) if cmis_object.getObjectId() != self.root_cmis_object.getObjectId(): data['parentId'] = cmis_object.getProperties()['cmis:parentId'] data['cmis_objectTypeId'] = 'cmis:folder' self._print("cmistracplugin: len(cmis_object.getChildren().getResults()): " + str(len(cmis_objects))) for idx in range(len(cmis_objects)): self._printCmisObjetc(cmis_objects[idx]) data['cmis_objects'] = cmis_objects add_ctxtnav(req, tag.a('New folder', href=req.href.documents(cmis_object.getProperties()['cmis:objectId'], 'newfolder'))) add_ctxtnav(req, tag.a('Remove folder', href=req.href.documents(cmis_object.getProperties()['cmis:objectId'], 'removefolder'))) add_ctxtnav(req, tag.a('Rename folder', href=req.href.documents(cmis_object.getProperties()['cmis:objectId'], 'renamefolder'))) add_ctxtnav(req, tag.a('Upload document', href=req.href.documents(cmis_object.getProperties()['cmis:objectId'], 'upload'))) elif cmis_object.getProperties()['cmis:objectTypeId'] == 'cmis:document': data['breadcrumb'] = render_breadcrumb(self.cmis_client, self.repository, self.root_cmis_object, cmis_object) data['cmis_objectTypeId'] = 'cmis:document' data['cmis_object'] = cmis_object else: self._print("cmistracplugin: Unknow cmis:objectTypeId: " + cmis_object.getProperties()['cmis:objectTypeId']) self._printCmisObjetc(cmis_object) if cmis_object.getProperties()['cmis:objectTypeId'] == 'cmis:folder' and xhr == None: req.session['lastCmisFolderIdVisited'] = cmis_object.getObjectId() return data def _prepare_newfolder_form(self, req): req.perm.require('REPOSITORY_CREATE_FOLDER') data = { 'parentId': req.args['objectId'] } return data def _process_newfolder_form(self, req): '''Processes the request to create a new directory''' req.perm.require('REPOSITORY_CREATE_FOLDER') if req.method == 'POST' and 'name' in req.args and 'parentId' in req.args: if 'name' in req.args and req.args['name'] != '': parent_folder = self.repository.getObject(req.args['parentId']) parent_folder.createFolder(req.args['name'].encode('utf-8')) req.args['objectId'] = req.args['parentId'] del req.args['parentId'] else: raise TracError('The folder name can not be empty') self.log.info('A new folder has been created') def _process_removefolder(self, req): '''Processes the request to remove a folder''' req.perm.require('REPOSITORY_REMOVE_FOLDER') if 'objectId' in req.args: cmis_object = self.repository.getObject(req.args['objectId']) if cmis_object.getObjectId() == self.root_cmis_object.getObjectId(): raise TracError('Can\'t remove root folder') parent_folder = self.repository.getObject(cmis_object.getProperties()['cmis:parentId']) cmis_object.deleteTree() req.args['objectId'] = parent_folder.getObjectId() self.log.info('A folder has been removed') def _prepare_upload_form(self, req): req.perm.require('REPOSITORY_UPLOAD') data = { 'parentId': req.args['objectId'], 'max_size': self.max_size } return data def _process_upload_form(self, req): req.perm.require('REPOSITORY_UPLOAD') upload = req.args['document'] if not hasattr(upload, 'filename') or not upload.filename: raise TracError('No file uploaded') if hasattr(upload.file, 'fileno'): size = os.fstat(upload.file.fileno())[6] else: upload.file.seek(0, 2) # seek to end of file size = upload.file.tell() upload.file.seek(0) if size == 0: raise TracError('Can\'t upload empty document') if size > self.max_size: raise TracError('Maximum document size: %s KB' % self.max_size) # We try to normalize the filename to unicode NFC if we can. # Files uploaded from OS X might be in NFD. filename = unicodedata.normalize('NFC', unicode(upload.filename, 'utf-8')) filename = filename.replace('\\', '/').replace(':', '/') filename = os.path.basename(filename) if not filename: raise TracError('No file uploaded') if 'parentId' in req.args: cmis_object = self.repository.getObject(req.args['parentId']) if cmis_object.getProperties()['cmis:objectTypeId'] == 'cmis:folder': cmis_object.createDocument(filename.encode('utf-8'), contentFile = upload.file, contentType = upload.type) req.args['objectId'] = req.args['parentId'] del req.args['parentId'] self.log.info('A document has been saved') def _process_download(self, req): req.perm.require('REPOSITORY_DOWNLOAD') cmis_object = self.repository.getObject(req.args['objectId']) # Validar que es un objecto de tipo documento content = cmis_object.getContentStream() req.send_response(200) req.send_header('Content-Type', cmis_object.getProperties()['cmis:contentStreamMimeType']) req.send_header('Content-Length', cmis_object.getProperties()['cmis:contentStreamLength']) req.send_header('Last-Modified', cmis_object.getProperties()['cmis:lastModificationDate']) req.send_header('Content-Disposition', 'attachment; filename="%s"' % cmis_object.getName()) req.end_headers() chunk = content.read(CHUNK_SIZE) while 1: if not chunk: raise RequestDone req.write(chunk) chunk = content.read(CHUNK_SIZE) self.log.info('A document has been downloaded') def _prepare_renamefolder_form(self, req): req.perm.require('REPOSITORY_RENAME_FOLDER') cmis_object = self.repository.getObject(req.args['objectId']) data = { 'cmis_object': cmis_object } return data def _process_renamefolder_form(self, req): req.perm.require('REPOSITORY_RENAME_FOLDER') folder = self.repository.getObject(req.args['objectId']) parent_folder = folder.getParent() props = { 'cmis:name': req.args['name'].encode('utf-8') } folder.updateProperties(props) if parent_folder: req.args['parentId'] = parent_folder.getObjectId() self.log.info('A folder has been renamed') def _process_removedocument(self, req): req.perm.require('REPOSITORY_REMOVE_DOCUMENT') if 'objectId' in req.args: cmis_object = self.repository.getObject(req.args['objectId']) cmis_object.delete() self.log.info('A document has been removed') def _printCmisObjetc(self, cmis_object): self._print("-- cmis:objectTypeId :: [" + cmis_object.getProperties()['cmis:objectTypeId'] + "] -- cmis:objectId :: [" + cmis_object.getProperties()['cmis:objectId'] + "]") _props = cmis_object.getProperties() for _key in _props: self._print("--- cmis_object.getProperties()['" + _key + "'] :: " + str(_props[_key])) def _print(self, _str): print _str self.log.debug(_str)
def load_cmis(cmis_foldername, cmis_objtype, cmis_choices): es_host = ES_HOSTS[0] headers = {'Content-Type': 'application/json'} if 'http_auth' in es_host: headers['http_auth'] = es_host['http_auth'] host = es_host['host'] doc_type = "cmis" url = "http://" + host + ":9200/" + "cmis" cmis_dirname = os.path.join(BASE_DIR, 'data', 'cmis') client = CmisClient('http://cmis.alfresco.com/cmisatom', 'admin', 'admin') repositories = client.getRepositories() repo = client.defaultRepository info = repo.info #for k,v in info.items(): # print("key {0}, value: {1}".format(k, v)) caps = repo.capabilities if 'recreate' in cmis_choices: map_cmis(url, headers, client, repo, cmis_objtype, cmis_choices) objtype = repo.getTypeDefinition(cmis_objtype) root = repo.getRootFolder() count = 1 objects = root.getDescendants(depth=3) len(objects.getResults()) for object in objects: doc = {} #repo_obj = repo.getObject(object.id) #for key,val in repo_obj.properties.items(): # print(key, val) doc_props = object.properties #print(object.name) #for prop_name, prop_value in doc_props.items(): # print(prop_name ,prop_value) doc_objtype = doc_props['cmis:objectTypeId'] doc_objtype_str = str(doc_objtype) if doc_objtype_str == cmis_objtype: paths = object.getPaths() doc['paths'] = paths parents = object.getObjectParents() for prop_name, prop in objtype.properties.items(): #field = prop.displayName field = prop.id field_type = prop.getPropertyType() prop_value = doc_props[prop_name] sub_doc = doc # in case of nesting sub_fields = field.split('.') last_sub_field = sub_fields[len(sub_fields) - 1] if len(sub_fields) > 1: for sub_field in sub_fields[:-1]: if sub_field not in sub_doc: if sub_field in nested_fields: sub_doc[sub_field] = [{}] else: sub_doc[sub_field] = {} else: if sub_field in nested_fields: sub_doc[sub_field].append({}) sub_field_value = sub_doc[sub_field] if type(sub_field_value) is dict: sub_doc = sub_doc[sub_field] if type(sub_field_value) is list: sub_doc = sub_doc[sub_field][ len(sub_doc[sub_field]) - 1] if last_sub_field not in properties and last_sub_field in nested_fields: pass field = last_sub_field if field_type == 'list': if field not in doc: sub_doc[field] = [] if prop_value != "": if len(format) > 0: delimiter = format prop_value = str(prop_value) if delimiter == '\\n': items = prop_value.splitlines() else: items = prop_value.split(delimiter) for item in items: item = prop_value(item, decoder) sub_doc[field].append(item) else: sub_doc[field].append(cell) elif field_type == 'nested': if field not in sub_doc: sub_doc[field] = [] if prop_value != '': if answer == '': nested_value = prop_value.split(',') sub_doc[field].append({ 'val': nested_value[0], 'prc': float(nested_value[1]) }) else: sub_doc[field].append({ 'val': answer, 'prc': float(cell) }) elif field_type == 'datetime': sub_doc[field] = prop_value.strftime('%Y-%m-%d') elif field_type == 'text' or field_type == 'string': prop_value = str(prop_value) if field not in doc: sub_doc[field] = prop_value else: sub_doc[field] = sub_doc[field] + format + prop_value else: sub_doc[field] = prop_value # write metadata to ES id = object.properties['cmis:objectId'] id = slugify(str(id)) data = json.dumps(doc) print("load_cmis: write cmis line with id", id) r = requests.put(url + "/" + doc_type + "/" + id, headers=headers, data=data) print("load_cmis: writen cmis line with id", id) # download document doc_basename = doc_props.get('cmis:name', None) doc_mime_type = doc_props.get('cmis:contentStreamMimeType', None) doc_length = doc_props.get('cmis:contentStreamLength', 0) cmis_fullname = os.path.join(cmis_dirname, doc_basename) cmis_file_handler = object.getContentStream() buffer = cmis_file_handler.read() try: with open(cmis_fullname, 'w') as output_file: output_file.write(buffer) except IOError as e: pass cmis_file_handler.close() count = count + 1
def open_report_wizard(self, context): print "context .......", context partner_id = context.get('partner_id') uid = context.get('uid') email = self.env['res.partner'].browse(partner_id).email email_uid = self.env['res.partner'].browse(uid).email print "email ....", email_uid configs = self.env['office.alfresco.configuration'].search([ ('is_default', '=', 'True') ])[0] url = configs.url port = configs.port user = configs.user mp = configs.mp try: client = CmisClient( 'http://' + url + ':' + repr(port) + '/alfresco/service/cmis', user, mp) repo = client.defaultRepository except: print 'failed to connect to Alfresco' quit() objet = 'Devis ' + self.reference print "objet .......", objet self.env.cr.execute("DELETE FROM mail_wiz") self.env.cr.execute( "INSERT INTO mail_wiz(id, objet, email, email_from) VALUES(%s,%s,%s,%s)", ('1', objet, email, email_uid)) # *** debut recuperation du rapport --------------------------------------------------------------- document_wiz_rapport = self.env['document_wiz'].create({ 'data': self._rapport_content_jasper(), 'nom_fichier': 'Devis ' + self.reference + '.pdf' }) ir_attachement_rapport = self.env['ir.attachment'].create({ 'datas': self._rapport_content_jasper(), 'datas_fname': 'devis ' + self.reference + '.pdf', 'name': 'Devis ' + self.reference + '.pdf', 'res_model': self._name }) self.env.cr.execute( "INSERT INTO document_wiz_mail_wiz_rel VALUES('1','" + repr(document_wiz_rapport[0].id) + "')") # &&&& Fin recuperation du rapport ----------------------------------------------------------------- # *** debut recuperation des documents ------------------------------------------------------------- obj_courant = self.env['sale.devis'].search([ ('reference', '=', self._get_id_devis(self.env.context)) ]) print "reference obj courant=====", obj_courant.reference, '.....', self.reference, 'self...', self.id products_list = self.devis_lines print "produits===", products_list for product in products_list: product_obj = product.product_id print "product id===", product_obj print "id===", product_obj.id documents_product = self.env[ 'office.document.alfresco.produit'].search([ ('produit_id', '=', product_obj.product_tmpl_id.id) ]) print "document id ======", documents_product for document in documents_product: doc = repo.getObject(document.node) result = doc.getContentStream() fobj = tempfile.NamedTemporaryFile(delete=False) fname = fobj.name fobj.write(result.read()) fobj.close() file_base64 = '' with open(fname, "rb") as file: file_base64 = base64.encodestring(file.read()) document_wiz_piece_jointe = self.env[ 'document_wiz'].create({ 'data': file_base64, 'nom_fichier': document.nom_fichier }) self.env.cr.execute( "INSERT INTO document_wiz_mail_wiz_rel VALUES('1','" + repr(document_wiz_piece_jointe[0].id) + "')") ir_attachement_rapport = self.env['ir.attachment'].create({ 'datas': file_base64, 'datas_fname': document.nom_fichier, 'name': document.nom_fichier, 'res_model': self._name }) # &&&& Fin recuperation des documents ----------------------------------------------------------------- return { 'view_type': 'form', 'view_mode': 'form', 'res_model': 'mail_wiz', 'res_id': int(1), 'view_id ref= report_wizard_form_view1': True, 'type': 'ir.actions.act_window', 'target': 'new', }
def auth(self): backend_record = self.backend_record self.client = CmisClient(backend_record.location, backend_record.username, backend_record.password)
class CMISStorage(Storage): """ Storage engine to upload and fetch files from a CMIS-enabled content management system, like Alfresco """ def __init__(self, base_folder=None): self.options = settings.CMIS_STORAGE_OPTIONS if 'baseFolder' not in self.options: self.options['baseFolder'] = '/' if base_folder: self.options['baseFolder'] = base_folder self.client = CmisClient(**self.options) self.repo = self.client.getDefaultRepository() def _open(self, name, mode='rb'): return File(self.open_stream(name), name=name) def open_stream(self, name): # Build the full path of the file full_path = os.path.join(self.options['baseFolder'], name.strip('./')) # Get the object from the CMS obj = self.repo.getObjectByPath(full_path) # type: cmislib.model.Document # Return the stream return obj.getContentStream() def _save(self, name, content): logger.debug("Saving file {}".format(name)) # Build the full path of the file full_path = os.path.join(self.options['baseFolder'], name.strip('.')) logger.debug("Full path at {}".format(full_path)) # Split the path dirname, filename = os.path.split(full_path) # Get the folder folder = self.repo.getObjectByPath(dirname) # Create the document newfile = folder.createDocument(filename, contentFile=content) # Get the new path for the file newfile_path = newfile.getPaths()[0] logger.debug("New path: {}".format(newfile_path)) return newfile_path def delete(self, name): logger.debug("Deleting file '{}'".format(name)) # Build the full path of the file full_path = os.path.join(self.options['baseFolder'], name.strip('./')) try: obj = self.repo.getObjectByPath(full_path) obj.delete() except cmislib.exceptions.ObjectNotFoundException: pass def exists(self, name): logger.debug("Checking if file exists '{}'".format(name)) # Build the full path of the file full_path = os.path.join(self.options['baseFolder'], name.strip('./')) try: self.repo.getObjectByPath(full_path) except cmislib.exceptions.ObjectNotFoundException: return False return True def path(self, name): return name def _props(self, name): # Build the full path of the file full_path = os.path.join(self.options['baseFolder'], name.strip('./')) # Get the object from the CMS obj = self.repo.getObjectByPath(full_path) # type: cmislib.model.Document return obj.getProperties() def modified_time(self, name): """ Returns the last modification date for the specified file """ return self._props(name).get('cmis:lastModificationDate', None) def accessed_time(self, name): return None def created_time(self, name): return self._props(name).get('cmis:creationDate', None) def size(self, name): return self._props(name).get('cmis:contentStreamLength', 0) def listdir(self, path): try: folder = self.repo.getObjectByPath(path) if not isinstance(folder, cmislib.models.Folder): return [] return [x.getName() for x in folder.getChildren()] except ObjectNotFoundException as e: return [] def url(self, name): return reverse('cmis_storage_get_file', kwargs={'path': name})