Пример #1
0
 def test_guess_digest_algorithm(self):
     s = 'joe'
     md5_digest = hashlib.md5(s).hexdigest()
     self.assertEquals(guess_digest_algorithm(md5_digest), 'md5')
     sha1_digest = hashlib.sha1(s).hexdigest()
     self.assertEquals(guess_digest_algorithm(sha1_digest), 'sha1')
     # For now only md5 and sha1 are supported
     sha256_digest = hashlib.sha256(s).hexdigest()
     try:
         guess_digest_algorithm(sha256_digest)
         self.fail('Other algorithms than md5 and sha1 should not be supported for now')
     except:
         pass
Пример #2
0
    def is_equal_digests(
        self,
        local_digest,
        remote_digest,
        local_path,
        remote_digest_algorithm=None,
    ):
        # type: (Text, Text, Text, Optional[Text]) -> bool
        """
        Compare 2 document's digests.

        :param str local_digest: Digest of the local document.
                                 Set to None to force digest computation.
        :param str remote_digest: Digest of the remote document.
        :param str local_path: Local path of the document.
        :param str remote_digest_algorithm: Remote document digest algorithm
        :return bool: Digest are equals.
        """

        if local_digest == remote_digest:
            return True

        if remote_digest_algorithm is None:
            remote_digest_algorithm = guess_digest_algorithm(remote_digest)
        if remote_digest_algorithm == self._digest_func:
            return False

        file_info = self.get_info(local_path)
        digest = file_info.get_digest(digest_func=remote_digest_algorithm)
        return digest == remote_digest
Пример #3
0
 def is_equal_digests(self, local_digest, remote_digest, local_path, remote_digest_algorithm=None):
     if local_digest == remote_digest:
         return True
     if remote_digest_algorithm is None:
         remote_digest_algorithm = guess_digest_algorithm(remote_digest)
     if remote_digest_algorithm == self._digest_func:
         return False
     else:
         return self.get_info(local_path).get_digest(digest_func=remote_digest_algorithm) == remote_digest
Пример #4
0
    def _prepare_edit(self, server_url, doc_id, user=None, download_url=None):
        engine = self._get_engine(server_url, user=user)
        if engine is None:
            values = dict()
            values['user'] = user
            values['server'] = server_url
            log.warn("No engine found for %s(%s)", server_url, doc_id)
            self._display_modal("DIRECT_EDIT_CANT_FIND_ENGINE", values)
            return
        # Get document info
        remote_client = engine.get_remote_doc_client()
        # Avoid any link with the engine, remote_doc are not cached so we can do that
        remote_client.check_suspended = self.stop_client
        info = remote_client.get_info(doc_id)
        filename = info.filename

        # Create local structure
        dir_path = os.path.join(self._folder, doc_id)
        if not os.path.exists(dir_path):
            os.mkdir(dir_path)

        log.debug("Editing %r", filename)
        file_path = os.path.join(dir_path, filename)

        # Download the file
        url = None
        if download_url is not None:
            url = server_url
            if not url.endswith('/'):
                url += '/'
            url += download_url
        tmp_file = self._download_content(engine, remote_client, info, file_path, url=url)
        if tmp_file is None:
            log.debug("Download failed")
            return
        # Set the remote_id
        dir_path = self._local_client.get_path(os.path.dirname(file_path))
        self._local_client.set_remote_id(dir_path, doc_id)
        self._local_client.set_remote_id(dir_path, server_url, "nxdriveedit")
        if user is not None:
            self._local_client.set_remote_id(dir_path, user, "nxdriveedituser")
        if info.digest is not None:
            self._local_client.set_remote_id(dir_path, info.digest, "nxdriveeditdigest")
            # Set digest algorithm if not sent by the server
            digest_algorithm = info.digest_algorithm
            if digest_algorithm is None:
                digest_algorithm = guess_digest_algorithm(info.digest)
            self._local_client.set_remote_id(dir_path, digest_algorithm, "nxdriveeditdigestalgorithm")
        self._local_client.set_remote_id(dir_path, filename, "nxdriveeditname")
        # Rename to final filename
        # Under Windows first need to delete target file if exists, otherwise will get a 183 WindowsError
        if sys.platform == 'win32' and os.path.exists(file_path):
            os.unlink(file_path)
        os.rename(tmp_file, file_path)
        return file_path
Пример #5
0
 def is_equal_digests(self,
                      local_digest,
                      remote_digest,
                      local_path,
                      remote_digest_algorithm=None):
     if local_digest == remote_digest:
         return True
     if remote_digest_algorithm is None:
         remote_digest_algorithm = guess_digest_algorithm(remote_digest)
     if remote_digest_algorithm == self._digest_func:
         return False
     else:
         return self.get_info(local_path).get_digest(
             digest_func=remote_digest_algorithm) == remote_digest
Пример #6
0
    def _prepare_edit(self, server_url, doc_id, user=None, download_url=None):
        start_time = current_milli_time()
        engine = self._get_engine(server_url, user=user)
        if engine is None:
            values = dict()
            if user is None:
                values['user'] = '******'
            else:
                values['user'] = user
            values['server'] = server_url
            log.warn("No engine found for server_url=%s, user=%s, doc_id=%s",
                     server_url, user, doc_id)
            self._display_modal("DIRECT_EDIT_CANT_FIND_ENGINE", values)
            return
        # Get document info
        remote_client = engine.get_remote_doc_client()
        # Avoid any link with the engine, remote_doc are not cached so we can do that
        remote_client.check_suspended = self.stop_client
        info = remote_client.get_info(doc_id)
        filename = info.filename

        # Create local structure
        dir_path = os.path.join(self._folder, doc_id)
        if not os.path.exists(dir_path):
            os.mkdir(dir_path)

        log.debug("Editing %r", filename)
        file_path = os.path.join(dir_path, filename)

        # Download the file
        url = None
        if download_url is not None:
            url = server_url
            if not url.endswith('/'):
                url += '/'
            url += download_url
        tmp_file = self._download_content(engine,
                                          remote_client,
                                          info,
                                          file_path,
                                          url=url)
        if tmp_file is None:
            log.debug("Download failed")
            return
        # Set the remote_id
        dir_path = self._local_client.get_path(os.path.dirname(file_path))
        self._local_client.set_remote_id(dir_path, doc_id)
        self._local_client.set_remote_id(dir_path, server_url, "nxdirectedit")
        if user is not None:
            self._local_client.set_remote_id(dir_path, user,
                                             "nxdirectedituser")
        if info.digest is not None:
            self._local_client.set_remote_id(dir_path, info.digest,
                                             "nxdirecteditdigest")
            # Set digest algorithm if not sent by the server
            digest_algorithm = info.digest_algorithm
            if digest_algorithm is None:
                digest_algorithm = guess_digest_algorithm(info.digest)
            self._local_client.set_remote_id(dir_path, digest_algorithm,
                                             "nxdirecteditdigestalgorithm")
        self._local_client.set_remote_id(dir_path, filename,
                                         "nxdirecteditname")
        # Rename to final filename
        # Under Windows first need to delete target file if exists, otherwise will get a 183 WindowsError
        if sys.platform == 'win32' and os.path.exists(file_path):
            os.unlink(file_path)
        os.rename(tmp_file, file_path)
        self._last_action_timing = current_milli_time() - start_time
        self.openDocument.emit(info)
        return file_path
 def do_get(self, url, file_out=None, digest=None, digest_algorithm=None):
     log.trace(
         'Downloading file from %r to %r with digest=%s, digest_algorithm=%s',
         url, file_out, digest, digest_algorithm)
     h = None
     if digest is not None:
         if digest_algorithm is None:
             digest_algorithm = guess_digest_algorithm(digest)
             log.trace('Guessed digest algorithm from digest: %s',
                       digest_algorithm)
         digester = getattr(hashlib, digest_algorithm, None)
         if digester is None:
             raise ValueError('Unknow digest method: ' + digest_algorithm)
         h = digester()
     headers = self._get_common_headers()
     base_error_message = (
         "Failed to connect to Nuxeo server %r with user %r") % (
             self.server_url, self.user_id)
     try:
         log.trace("Calling '%s' with headers: %r", url, headers)
         req = urllib2.Request(url, headers=headers)
         response = self.opener.open(req, timeout=self.blob_timeout)
         current_action = Action.get_current_action()
         # Get the size file
         if (current_action and response is not None
                 and response.info() is not None):
             current_action.size = int(response.info().getheader(
                 'Content-Length', 0))
         if file_out is not None:
             locker = self.unlock_path(file_out)
             try:
                 with open(file_out, "wb") as f:
                     while True:
                         # Check if synchronization thread was suspended
                         if self.check_suspended is not None:
                             self.check_suspended('File download: %s' %
                                                  file_out)
                         buffer_ = response.read(self.get_download_buffer())
                         if buffer_ == '':
                             break
                         if current_action:
                             current_action.progress += (
                                 self.get_download_buffer())
                         f.write(buffer_)
                         if h is not None:
                             h.update(buffer_)
                 if digest is not None:
                     actual_digest = h.hexdigest()
                     if digest != actual_digest:
                         if os.path.exists(file_out):
                             os.remove(file_out)
                         raise CorruptedFile(
                             "Corrupted file %r: expected digest = %s, actual digest = %s"
                             % (file_out, digest, actual_digest))
                 return None, file_out
             finally:
                 self.lock_path(file_out, locker)
         else:
             result = response.read()
             if h is not None:
                 h.update(result)
                 if digest is not None:
                     actual_digest = h.hexdigest()
                     if digest != actual_digest:
                         raise CorruptedFile(
                             "Corrupted file: expected digest = %s, actual digest = %s"
                             % (digest, actual_digest))
             return result, None
     except urllib2.HTTPError as e:
         if e.code == 401 or e.code == 403:
             raise Unauthorized(self.server_url, self.user_id, e.code)
         else:
             e.msg = base_error_message + ": HTTP error %d" % e.code
             raise e
     except Exception as e:
         if hasattr(e, 'msg'):
             e.msg = base_error_message + ": " + e.msg
         raise
Пример #8
0
 def do_get(self, url, file_out=None, digest=None, digest_algorithm=None):
     h = None
     if digest is not None:
         if digest_algorithm is None:
             digest_algorithm = guess_digest_algorithm(digest)
         digester = getattr(hashlib, digest_algorithm, None)
         if digester is None:
             raise ValueError('Unknow digest method: ' + digest_algorithm)
         h = digester()
     headers = self._get_common_headers()
     base_error_message = (
         "Failed to connect to Nuxeo server %r with user %r"
     ) % (self.server_url, self.user_id)
     try:
         log.trace("Calling '%s' with headers: %r", url, headers)
         req = urllib2.Request(url, headers=headers)
         response = self.opener.open(req, timeout=self.blob_timeout)
         current_action = Action.get_current_action()
         # Get the size file
         if (current_action and response is not None
             and response.info() is not None):
             current_action.size = int(response.info().getheader(
                                                 'Content-Length', 0))
         if file_out is not None:
             locker = self.unlock_path(file_out)
             try:
                 with open(file_out, "wb") as f:
                     while True:
                         # Check if synchronization thread was suspended
                         if self.check_suspended is not None:
                             self.check_suspended('File download: %s'
                                                  % file_out)
                         buffer_ = response.read(self.get_download_buffer())
                         if buffer_ == '':
                             break
                         if current_action:
                             current_action.progress += (
                                                 self.get_download_buffer())
                         f.write(buffer_)
                         if h is not None:
                             h.update(buffer_)
                     if self._remote_error is not None:
                         # Simulate a configurable remote (e.g. network or
                         # server) error for the tests
                         raise self._remote_error
                     if self._local_error is not None:
                         # Simulate a configurable local error (e.g. "No
                         # space left on device") for the tests
                         raise self._local_error
                 if digest is not None and digest != h.hexdigest():
                     if os.path.exists(file_out):
                         os.remove(file_out)
                     raise CorruptedFile("Corrupted file")
                 return None, file_out
             finally:
                 self.lock_path(file_out, locker)
         else:
             result = response.read()
             if h is not None:
                 h.update(result)
                 if digest is not None and digest != h.hexdigest():
                     raise CorruptedFile("Corrupted file")
             return result, None
     except urllib2.HTTPError as e:
         if e.code == 401 or e.code == 403:
             raise Unauthorized(self.server_url, self.user_id, e.code)
         else:
             e.msg = base_error_message + ": HTTP error %d" % e.code
             raise e
     except Exception as e:
         if hasattr(e, 'msg'):
             e.msg = base_error_message + ": " + e.msg
         raise
Пример #9
0
    def _prepare_edit(self, server_url, doc_id, user=None, download_url=None):
        start_time = current_milli_time()
        engine = self._get_engine(server_url, user=user)
        if engine is None:
            values = dict()
            values['user'] = str(user)
            values['server'] = server_url
            log.warning(
                'No engine found for server_url=%s, user=%s, doc_id=%s',
                server_url, user, doc_id)
            self._display_modal('DIRECT_EDIT_CANT_FIND_ENGINE', values)
            return None
        # Get document info
        remote_client = engine.get_remote_doc_client()
        # Avoid any link with the engine, remote_doc are not cached so we can do that
        remote_client.check_suspended = self.stop_client
        doc = remote_client.fetch(
            doc_id,
            extra_headers={'fetch-document': 'lock'},
            enrichers=['permissions'],
        )
        info = remote_client.doc_to_info(doc, fetch_parent_uid=False)
        if info.lock_owner is not None and info.lock_owner != engine.remote_user:
            log.debug(
                "Doc %s was locked by %s on %s, won't download it for edit",
                info.name, info.lock_owner, info.lock_created)
            self.directEditLocked.emit(info.name, info.lock_owner,
                                       info.lock_created)
            return None
        if info.permissions is not None and 'Write' not in info.permissions:
            log.debug("Doc %s is readonly for %s, won't download it for edit",
                      info.name, user)
            self.directEditReadonly.emit(info.name)
            return None

        filename = info.filename

        # Create local structure
        dir_path = os.path.join(self._folder, doc_id)
        if not os.path.exists(dir_path):
            os.mkdir(dir_path)

        log.debug("Editing %r", filename)
        file_path = os.path.join(dir_path, filename)

        # Download the file
        url = None
        if download_url is not None:
            url = server_url
            if not url.endswith('/'):
                url += '/'
            url += download_url
        tmp_file = self._download_content(engine,
                                          remote_client,
                                          info,
                                          file_path,
                                          url=url)
        if tmp_file is None:
            log.debug("Download failed")
            return None
        # Set the remote_id
        dir_path = self._local_client.get_path(os.path.dirname(file_path))
        self._local_client.set_remote_id(dir_path, doc_id)
        self._local_client.set_remote_id(dir_path, server_url, "nxdirectedit")
        if user is not None:
            self._local_client.set_remote_id(dir_path, user,
                                             "nxdirectedituser")
        if info.digest is not None:
            self._local_client.set_remote_id(dir_path, info.digest,
                                             "nxdirecteditdigest")
            # Set digest algorithm if not sent by the server
            digest_algorithm = info.digest_algorithm
            if digest_algorithm is None:
                digest_algorithm = guess_digest_algorithm(info.digest)
            self._local_client.set_remote_id(dir_path, digest_algorithm,
                                             "nxdirecteditdigestalgorithm")
        self._local_client.set_remote_id(dir_path, filename,
                                         "nxdirecteditname")
        # Rename to final filename
        # Under Windows first need to delete target file if exists, otherwise will get a 183 WindowsError
        if sys.platform == 'win32' and os.path.exists(file_path):
            os.unlink(file_path)
        os.rename(tmp_file, file_path)
        self._last_action_timing = current_milli_time() - start_time
        self.openDocument.emit(info)
        return file_path
Пример #10
0
    def _prepare_edit(self, server_url, doc_id, user=None, download_url=None):
        start_time = current_milli_time()
        engine = self._get_engine(server_url, user=user)
        if engine is None:
            values = dict()
            values['user'] = str(user)
            values['server'] = server_url
            log.warning('No engine found for server_url=%s, user=%s, doc_id=%s',
                        server_url, user, doc_id)
            self._display_modal('DIRECT_EDIT_CANT_FIND_ENGINE', values)
            return None
        # Get document info
        remote_client = engine.get_remote_doc_client()
        # Avoid any link with the engine, remote_doc are not cached so we can do that
        remote_client.check_suspended = self.stop_client
        doc = remote_client.fetch(
            doc_id,
            extra_headers={'fetch-document': 'lock'},
            enrichers=['permissions'],
        )
        info = remote_client.doc_to_info(doc, fetch_parent_uid=False)
        if info.lock_owner is not None and info.lock_owner != engine.remote_user:
            log.debug("Doc %s was locked by %s on %s, won't download it for edit", info.name, info.lock_owner,
                      info.lock_created)
            self.directEditLocked.emit(info.name, info.lock_owner, info.lock_created)
            return None
        if info.permissions is not None and 'Write' not in info.permissions:
            log.debug("Doc %s is readonly for %s, won't download it for edit", info.name, user)
            self.directEditReadonly.emit(info.name)
            return None

        filename = info.filename

        # Create local structure
        dir_path = os.path.join(self._folder, doc_id)
        if not os.path.exists(dir_path):
            os.mkdir(dir_path)

        log.debug("Editing %r", filename)
        file_path = os.path.join(dir_path, filename)

        # Download the file
        url = None
        if download_url is not None:
            url = server_url
            if not url.endswith('/'):
                url += '/'
            url += download_url
        tmp_file = self._download_content(engine, remote_client, info, file_path, url=url)
        if tmp_file is None:
            log.debug("Download failed")
            return None
        # Set the remote_id
        dir_path = self._local_client.get_path(os.path.dirname(file_path))
        self._local_client.set_remote_id(dir_path, doc_id)
        self._local_client.set_remote_id(dir_path, server_url, "nxdirectedit")
        if user is not None:
            self._local_client.set_remote_id(dir_path, user, "nxdirectedituser")
        if info.digest is not None:
            self._local_client.set_remote_id(dir_path, info.digest, "nxdirecteditdigest")
            # Set digest algorithm if not sent by the server
            digest_algorithm = info.digest_algorithm
            if digest_algorithm is None:
                digest_algorithm = guess_digest_algorithm(info.digest)
            self._local_client.set_remote_id(dir_path, digest_algorithm, "nxdirecteditdigestalgorithm")
        self._local_client.set_remote_id(dir_path, filename, "nxdirecteditname")
        # Rename to final filename
        # Under Windows first need to delete target file if exists, otherwise will get a 183 WindowsError
        if sys.platform == 'win32' and os.path.exists(file_path):
            os.unlink(file_path)
        os.rename(tmp_file, file_path)
        self._last_action_timing = current_milli_time() - start_time
        self.openDocument.emit(info)
        return file_path
 def do_get(self, url, file_out=None, digest=None, digest_algorithm=None):
     log.trace('Downloading file from %r to %r with digest=%s, digest_algorithm=%s', url, file_out, digest,
               digest_algorithm)
     h = None
     if digest is not None:
         if digest_algorithm is None:
             digest_algorithm = guess_digest_algorithm(digest)
             log.trace('Guessed digest algorithm from digest: %s', digest_algorithm)
         digester = getattr(hashlib, digest_algorithm, None)
         if digester is None:
             raise ValueError('Unknow digest method: ' + digest_algorithm)
         h = digester()
     headers = self._get_common_headers()
     base_error_message = (
         "Failed to connect to Nuxeo server %r with user %r"
     ) % (self.server_url, self.user_id)
     try:
         log.trace("Calling '%s' with headers: %r", url, headers)
         req = urllib2.Request(url, headers=headers)
         response = self.opener.open(req, timeout=self.blob_timeout)
         current_action = Action.get_current_action()
         # Get the size file
         if (current_action
                 and response is not None
                 and response.info() is not None):
             current_action.size = int(response.info().getheader(
                                                 'Content-Length', 0))
         if file_out is not None:
             locker = self.unlock_path(file_out)
             try:
                 with open(file_out, "wb") as f:
                     while True:
                         # Check if synchronization thread was suspended
                         if self.check_suspended is not None:
                             self.check_suspended('File download: %s'
                                                  % file_out)
                         buffer_ = response.read(FILE_BUFFER_SIZE)
                         if buffer_ == '':
                             break
                         if current_action:
                             current_action.progress += FILE_BUFFER_SIZE
                         f.write(buffer_)
                         if h is not None:
                             h.update(buffer_)
                 if digest is not None:
                     actual_digest = h.hexdigest()
                     if digest != actual_digest:
                         if os.path.exists(file_out):
                             os.remove(file_out)
                         raise CorruptedFile("Corrupted file %r: expected digest = %s, actual digest = %s"
                                             % (file_out, digest, actual_digest))
                 return None, file_out
             finally:
                 self.lock_path(file_out, locker)
         else:
             result = response.read()
             if h is not None:
                 h.update(result)
                 if digest is not None:
                     actual_digest = h.hexdigest()
                     if digest != actual_digest:
                         raise CorruptedFile("Corrupted file: expected digest = %s, actual digest = %s"
                                             % (digest, actual_digest))
             return result, None
     except urllib2.HTTPError as e:
         if e.code == 401 or e.code == 403:
             raise Unauthorized(self.server_url, self.user_id, e.code)
         else:
             e.msg = base_error_message + ": HTTP error %d" % e.code
             raise e
     except Exception as e:
         if hasattr(e, 'msg'):
             e.msg = base_error_message + ": " + e.msg
         raise
Пример #12
0
    def _prepare_edit(self, server_url, doc_id, filename, user=None, download_url=None):
        engine = self._get_engine(server_url, user=user)
        if engine is None:
            # TO_REVIEW Display an error message
            log.debug("No engine found for %s(%s)", server_url, doc_id)
            return
        # Get document info
        remote_client = engine.get_remote_doc_client()
        # Avoid any link with the engine, remote_doc are not cached so we can do that
        remote_client.check_suspended = self.stop_client
        info = remote_client.get_info(doc_id)

        # Create local structure
        dir_path = os.path.join(self._folder, doc_id)
        if not os.path.exists(dir_path):
            os.mkdir(dir_path)

        log.trace('Raw filename: %r', filename)
        filename = safe_filename(urllib2.unquote(filename))
        log.trace('Unquoted filename = %r', filename)
        decoded_filename = force_decode(filename)
        if decoded_filename is None:
            decoded_filename = filename
        else:
            # Always use utf-8 encoding for xattr
            filename = decoded_filename.encode('utf-8')
        log.debug("Editing %r ('nxdriveeditname' xattr: %r)", decoded_filename, filename)
        file_path = os.path.join(dir_path, decoded_filename)

        # Download the file
        url = None
        if download_url is not None:
            url = server_url
            if not url.endswith('/'):
                url += '/'
            url += download_url
        tmp_file = self._download_content(engine, remote_client, info, file_path, url=url)
        if tmp_file is None:
            log.debug("Download failed")
            return
        # Set the remote_id
        dir_path = self._local_client.get_path(os.path.dirname(file_path))
        self._local_client.set_remote_id(dir_path, doc_id)
        self._local_client.set_remote_id(dir_path, server_url, "nxdriveedit")
        if user is not None:
            self._local_client.set_remote_id(dir_path, user, "nxdriveedituser")
        if info.digest is not None:
            self._local_client.set_remote_id(dir_path, info.digest, "nxdriveeditdigest")
            # Set digest algorithm if not sent by the server
            digest_algorithm = info.digest_algorithm
            if digest_algorithm is None:
                digest_algorithm = guess_digest_algorithm(info.digest)
            self._local_client.set_remote_id(dir_path, digest_algorithm, "nxdriveeditdigestalgorithm")
        self._local_client.set_remote_id(dir_path, filename, "nxdriveeditname")
        # Rename to final filename
        # Under Windows first need to delete target file if exists, otherwise will get a 183 WindowsError
        if sys.platform == 'win32' and os.path.exists(file_path):
            os.unlink(file_path)
        os.rename(tmp_file, file_path)

        return file_path