def get_obj(self, path: str): """ 获取目录或对象 :param path: 目录或对象路径 :return: obj # success None # 不存在 :raises: Error """ na_md5 = get_str_hexMD5(path) model_class = self.get_obj_model_class() try: obj = model_class.objects.get(Q(na_md5=na_md5) | Q(na_md5__isnull=True), na=path) except model_class.DoesNotExist as e: return None except MultipleObjectsReturned as e: msg = f'数据库表{self.get_collection_name()}中存在多个相同的目录:{path}' logger.error(msg) raise exceptions.Error(message=msg) except Exception as e: msg = f'select {self.get_collection_name()},path={path},err={str(e)}' logger.error(msg) raise exceptions.Error(msg) return obj
def create_bucket(name: str, user, _id: int = None, ceph_using: str = None, pool_name: str = None): """ 创建存储桶 :param name: bucket name :param user: user bucket belong to :param _id: bucket id :param ceph_using: 多ceph集群时,指定使用那个ceph集群 :param pool_name: ceph pool name that bucket objects data storage """ if not ceph_using and pool_name: raise exceptions.Error(message=f'指定"pool_name"时必须同时指定"ceph_using"') if not ceph_using: ceph_using = get_ceph_alias_rand() if pool_name: pools = get_ceph_poolnames(ceph_using) if pool_name not in pools: raise exceptions.Error( message= f'指定"pool_name"({pool_name})不在"ceph_using"({ceph_using})中') else: pool_name = get_ceph_poolname_rand(ceph_using) bucket_id = _id bucket_name = name if not _id: bucket_id = get_next_bucket_max_id() try: bucket = Bucket(id=bucket_id, name=bucket_name, ceph_using=ceph_using, pool_name=pool_name, user=user) bucket.save(force_insert=True) except Exception as e: raise exceptions.Error( message=f"create bucket metadata failed, {str(e)}.") col_name = bucket.get_bucket_table_name() bfm = BucketFileManagement(collection_name=col_name) model_class = bfm.get_obj_model_class() if not create_table_for_model_class(model=model_class): if not create_table_for_model_class(model=model_class): bucket.delete() delete_table_for_model_class(model=model_class) raise exceptions.Error(f"create bucket table failed.") return bucket
def get_cur_dir_id(self, dir_path=None): """ 获得当前目录节点id :return: id: int # 顶级目录时id=ROOT_DIR_ID :raises: Error,InvalidKey,SameKeyAlreadyExists,NoParentPath """ if self.cur_dir_id: return self.cur_dir_id path = dir_path if dir_path else self._path # path为空,根目录为存储桶 if path == '' or path == '/': return self.ROOT_DIR_ID path = self._hand_path(path) if not path: raise exceptions.InvalidKey(message='父路径无效') # path参数有误 try: obj = self.get_obj(path=path) except Exception as e: raise exceptions.Error(message=f'查询目录id错误,{str(e)}') if obj: if obj.is_dir(): self.cur_dir_id = obj.id return self.cur_dir_id else: raise exceptions.SameKeyAlreadyExists(message='无效目录,同名对象已存在') raise exceptions.NoParentPath(message='目录路径不存在')
def get_dir_or_obj_exists(self, name, check_path_exists: bool = True): """ 通过名称获取当前路径下的子目录或对象 :param name: 目录名或对象名称 :param check_path_exists: 是否检查当前路径是否存在 :return: 文件目录对象 or None raises: Exception # 发生错误,或当前目录参数有误,对应目录不存在 :raises: Error, NoParentPath """ if check_path_exists: self.get_cur_dir_id() path = self.build_dir_full_name(name) try: dir_or_obj = self.get_obj(path=path) except Exception as e: raise exceptions.Error(message=f'查询目录id错误,{str(e)}') return dir_or_obj
def exception_handler(exc, context): """ Returns the response that should be used for any given exception. """ headers = {} if isinstance(exc, Http404): exc = exceptions.NotFound() elif isinstance(exc, PermissionDenied): exc = exceptions.AccessDenied() elif isinstance(exc, APIException): auth_header = getattr(exc, 'auth_header', None) if auth_header: headers['WWW-Authenticate'] = auth_header wait = getattr(exc, 'wait', None) if wait: headers['Retry-After'] = '%d' % wait if isinstance(exc, rf_exceptions.AuthenticationFailed): exc = exceptions.AuthenticationFailed(message=str(exc)) elif isinstance(exc, rf_exceptions.NotAuthenticated): exc = exceptions.NotAuthenticated(message=str(exc)) elif isinstance(exc, rf_exceptions.PermissionDenied): exc = exceptions.AccessDenied(message=str(exc)) elif isinstance(exc, rf_exceptions.MethodNotAllowed): exc = exceptions.MethodNotAllowed() elif isinstance(exc, rf_exceptions.Throttled): exc = exceptions.Throttled(message=str(exc)) else: exc = exceptions.Error(message=str(exc), status_code=exc.status_code) if isinstance(exc, exceptions.Error): set_rollback() return Response(data=exc.err_data(), status=exc.status_code, headers=headers) return None