def new_user(request): """ 新增用户 :param request: POST request.POST: {'id':...,'password':...,'root_dir':...,'size':...} :return: json数据, {'state':...,'details':...} """ user_id = str(request.POST['id']) password = str(request.POST['password']) root_dir = str(request.POST['root_dir']) size = str(request.POST['size']) # 检验用户名是否冲突 curr_user_list = table_user.get_all_user_info() user_exist = False for user in curr_user_list: if user_id == user['user_ID']: user_exist = True break if user_exist: message_to_return = {'state': 'failed', 'details': '用户名已存在'} else: # root_dir是否存在? print(root_dir) root_dir_exist = resolve_path_to_actual_path(root_dir)['state'] if not root_dir_exist: message_to_return = {'state': 'failed', 'details': '传入的用户根目录无法解析'} else: table_user.add_user(user_id, password, root_dir) message_to_return = {'state': 'success', 'details': '新用户添加成功'} return HttpResponse(json.dumps(message_to_return))
def upload_success(request): """ 文件上传成功时调用该函数,将上传过程中服务器上保存的有关该文件的分片整合到一起,形成一个文件 :param request: POST :return: 上传文件界面 """ print('upload_success: ') print(request.POST) target_filename = request.GET.get('filename') # 获取上传文件的文件名 task = request.GET.get('task_id') # 获取文件的唯一标识符 file_path = request.GET.get('file_path') actual_dir = address_transfer.resolve_path_to_actual_path(file_path)['actual_path'] chunk = 0 # 分片序号 with open(actual_dir + target_filename, 'wb') as target_file: # 创建新文件 while True: try: filename = actual_dir + '%s%d' % (task, chunk) source_file = open(filename, 'rb') # 按序打开每个分片 target_file.write(source_file.read()) # 读取分片内容写入新文件 source_file.close() except IOError as msg: break chunk += 1 os.remove(filename) # 删除该分片,节约空间 return render(request, 'upload_test.html', locals())
def download(request, path): """ FileCube文件的下载接口,向前端返回支持文件部分下载的数据流,支持下载暂停、断点续传和多线程并发下载 path为下载文件在FileCube系统内的表示路径 request: WSGI请求 权限控制: 通过request找到对应的session,查找里面记录的用户名,以此来进行权限判断 若用户未登录,则使用匿名账户的权限记录进行判断 """ try: username = request.session['username'] except KeyError: username = '******' # 对path合法性判断一下 path = str(path) access_list = table_access.get_access_list_by_id(username) if not db_helper.lookup_access_in_the_list(path, 'download', access_list): return HttpResponse('no download access to resource', status=403) else: tmp_actual_path = address_transfer.resolve_path_to_actual_path(path) if tmp_actual_path['state'] and not os.path.exists( tmp_actual_path['actual_path']): raise Http404('"%(path)s" does not exist' % {'path': path}) elif not tmp_actual_path['state']: raise Http404('"%(path)s" can not be resolved properly' % {'path': path}) elif os.path.isdir(tmp_actual_path['actual_path']): return HttpResponse('server does not support downloading a folder', status=403) else: # 一切均正常,开始下载 return get_file_response(request, tmp_actual_path['actual_path'])
def rename_and_move_file(curr_path, curr_name, des_path, des_name, operator_name): """ 重命名或移动目录项(文件或文件夹),并返回操作最后的状态信息 :param curr_path: 目录项当前所处文件夹的路径 :param curr_name: 目录项的名称 :param des_path: 目录项移动至该路径下 :param des_name: 目录项的新名称 :param operator_name: 操作者 :return: {'state':...,'details':...} state = 'failed' or 'success'; details为相关信息 """ curr_name = str(curr_name) curr_path_transferred = resolve_path_to_actual_path(str(curr_path)) des_name = str(des_name) des_path_transferred = resolve_path_to_actual_path(str(des_path)) if not curr_path_transferred['state'] or not des_path_transferred['state']: state = 'failed' details = '路径无法解析' else: actual_curr_path = curr_path_transferred['actual_path'] actual_des_path = des_path_transferred['actual_path'] if not os.path.exists(actual_curr_path + curr_name): print(actual_curr_path + curr_name) print("当前文件位置不存在") state = 'failed' details = '当前文件位置不存在' elif os.path.exists(actual_des_path + des_name): print("目标路径存在同名文件") state = 'failed' details = '目标路径存在同名文件' else: try: src = "%s%s" % (actual_curr_path, curr_name) dst = "%s%s" % (actual_des_path, des_name) # print("%s||%s" % (src,dst)) os.rename(src, dst) print("操作完成") state = 'success' details = '操作完成' except OSError as error: print(error) state = 'failed' details = '操作系统移动文件失败' + str(error) return {'state': state, 'details': details}
def test_path_transfer_to_actual_path(self): """ 测试 address_transfer.resolve_path_to_actual_path 的功能 """ self.assertEqual( address_transfer.resolve_path_to_actual_path('zhfs/A/yanbx/lib') ['actual_path'], '/home/ubuntu/hhhh/yanbx/lib') self.assertEqual( address_transfer.resolve_path_to_actual_path('zhfs/A/B/heiheihei') ['actual_path'], '/home/ubuntu/HHHH/heiheihei') self.assertEqual( address_transfer.resolve_path_to_actual_path('zhfs/wanghb/novel/') ['actual_path'], 'E:\\zhfs\\wanghb\\novel\\') self.assertFalse( address_transfer.resolve_path_to_actual_path('blank')['state']) self.assertEqual( address_transfer.resolve_path_to_actual_path('blank') ['actual_path'], 'blank')
def add_access_record(request): """ 增加一条权限记录 :param request: POST request.POST = {user_id, path, read, new, download, remove, modify, admin, opt} request.session['username'] :return: {'state':...,'details':...} """ try: user_id = str(request.POST['user_id']) path = str(request.POST['path']) read = request.POST['read'] == 'true' new = request.POST['new'] == 'true' download = request.POST['download'] == 'true' remove = request.POST['remove'] == 'true' modify = request.POST['modify'] == 'true' admin = request.POST['admin'] == 'true' opt = str(request.POST['opt']) except KeyError as error_msg: print(error_msg) print(traceback.format_exc()) return HttpResponse( json.dumps({ 'state': 'failed', 'details': 'POST参数错误' })) if not validate_identity(request): state = 'failed' details = '未登录' else: if not check_if_have_this_key(request.session, 'username'): raise KeyError('session 中缺少字段username') if not check_if_have_this_key(request.session, 'sys_admin'): raise KeyError('session 中缺少字段sys_admin') # 查询该用户是否能在该路径下赋予他人权限 access_list = table_access.get_access_list_by_id( request.session['username']) if not db_helper.lookup_access_in_the_list( path, 'admin', access_list) and not request.session['sys_admin']: state = 'failed' details = '用户无权限在此路径下增加权限' elif not table_user.if_user_exists(user_id): state = 'failed' details = '请检查新增权限记录中的用户名,用户不存在' elif not address_transfer.resolve_path_to_actual_path(path)['state']: state = 'failed' details = '您不能为不存在的路径赋予权限' else: print(read) table_access.modify_some_access(user_id, path, read, new, download, remove, modify, admin, opt) state = 'success' details = '成功增加一条权限记录' return HttpResponse(json.dumps({'state': state, 'details': details}))
def back_to_parent_dir(request): """ 切换到文件系统的上级目录,返回上级目录下的目录项列表 :param request: POST request.POST = {'file_dir':...} request.session['access_list'] :return: HttpResponse(json.dumps(data_list)) data_list = {'have_access':BOOL,'have_parent': BOOL or None, 'new_current_path': ..., 'file_list': ...} """ current_dir = str(request.POST['file_dir']) # TODO[柏旭] 2020-06-28 检查传入路径是否合法 temp_find_parent_dir_result = address_helper.find_parent_dir(current_dir) have_parent = temp_find_parent_dir_result['result'] if have_parent: new_current_path = temp_find_parent_dir_result['details'] # ------------------------------------------------------------------------------------------------------- if not new_current_path.endswith('/'): new_current_path += "/" have_access = False file_list = [] # 权限校验 if key_checker.check_if_have_this_key(request.session, 'access_list'): access_list = request.session['access_list'] if db_helper.lookup_access_in_the_list(new_current_path, 'read', access_list): have_access = True else: pass if have_access: actual_dir = address_transfer.resolve_path_to_actual_path(new_current_path)['actual_path'] if os.path.exists(actual_dir): filename_list = os.listdir(actual_dir) for filename in filename_list: if os.path.isdir(actual_dir + filename): file_list.append({'file_type': 'dir', 'file_name': filename, 'file_dir': new_current_path + filename, 'file_size': '-'}) else: size = table_file_tree.get_file_size(actual_dir + filename) file_list.append({'file_type': 'file', 'file_name': filename, 'file_dir': new_current_path + filename, 'file_size': size}) # ------------------------------------------------------------------------------------------------------- else: have_access = True new_current_path = current_dir file_list = None return HttpResponse(json.dumps({'have_access': have_access, 'have_parent': have_parent, 'new_current_path': new_current_path, 'file_list': file_list}))
def get_file_list_under_dir(request): """ 展示某目录项下的目录项列表 :param request: POST request.POST = {'file_dir':...} request.session['access_list'] :return: HttpResponse(json.dumps(data_list)) data_list = {'have_access': BOOL, 'dir_exist': BOOL or None, 'file_list': BOOL or None} """ data_dir = str(request.POST['file_dir']) if not data_dir.endswith('/'): data_dir += "/" have_access = False file_list = [] # 权限校验 if key_checker.check_if_have_this_key(request.session, 'access_list'): access_list = request.session['access_list'] if db_helper.lookup_access_in_the_list(data_dir, 'read', access_list): have_access = True else: pass if have_access: actual_dir = address_transfer.resolve_path_to_actual_path(data_dir)['actual_path'] if not os.path.exists(actual_dir): data_list = {'have_access': True, 'dir_exist': False, 'file_list': file_list} else: filename_list = os.listdir(actual_dir) # print(actual_dir) for filename in filename_list: # print(actual_dir + filename) if os.path.isdir(actual_dir + filename): file_list.append({'file_type': 'dir', 'file_name': filename, 'file_dir': data_dir + filename, 'file_size': '-'}) else: size = table_file_tree.get_file_size(actual_dir + filename) file_list.append({'file_type': 'file', 'file_name': filename, 'file_dir': data_dir + filename, 'file_size': size}) data_list = {'have_access': True, 'dir_exist': True, 'file_list': file_list} else: data_list = {'have_access': False, 'dir_exist': None, 'file_list': file_list} return HttpResponse(json.dumps(data_list))
def save_txt_file(request): """ 更新txt文件内容 :param request: POST request.POST['file_dir'], request.POST['file_content'] request.session :return: HttpResponse(json.dumps({'state': 'failed' or 'success', 'details')) """ hfs_sys_basic_funcs.validate_identity(request) file_dir = str(request.POST['file_dir']) # fixme [baixu] 2020-06-28 对file_dir的合法性进行验证处理 have_access = db_helper.lookup_access_in_the_list( file_dir, 'modify', request.session['access_list']) if not have_access: state = 'failed' details = '权限不足、无法修改文件内容' else: temp_path_transfer_result = address_transfer.resolve_path_to_actual_path( file_dir) if not temp_path_transfer_result['state']: state = 'failed' details = '传入的路径无法解析' elif not os.path.exists(temp_path_transfer_result['actual_path']): state = 'failed' details = '所指定文件不存在' else: try: file = open(temp_path_transfer_result['actual_path'], 'w', encoding='utf-8') file.write(request.POST['file_content']) print(file_dir) print('--------------') print(request.POST['file_content']) file.close() state = 'success' details = '文件保存成功' except Exception as error_msg: print(error_msg) state = 'failed' details = '未知错误,请联系管理员查看日志排查' return HttpResponse(json.dumps({'state': state, 'details': details}))
def remove_file(remove_dir, operator_name): """ 删除目录项 :param remove_dir: 待删除目录项的路径,为hfs系统中的路径,非实际路径 :param operator_name: 操作者 :return: unknown """ path_transferred = resolve_path_to_actual_path(remove_dir) if not path_transferred['state']: print("路径无法解析,不知道删除什么文件") return else: actual_remove_dir = path_transferred['actual_path'] if os.path.exists(actual_remove_dir): if os.path.isdir(actual_remove_dir): del_file(actual_remove_dir) else: os.remove(actual_remove_dir) else: print("解析后的实际路径不存在!这可能是其他程序对之造成的修改,建议及时做数据同步。")
def preview_file_content(request): """ 根据传来的文件路径,返回文件的内容供前端预览文件 :param request: POST request.POST['file_dir'] request.session['access_list'] :return:HttpResponse(json.dumps(data)) data = {'result': 'failed' or 'success', 'details': ’文件内容‘ or '报错信息‘} """ hfs_sys_basic_funcs.validate_identity(request) file_dir = str(request.POST['file_dir']) # fixme [baixu] 2020-06-28 对file_dir的合法性进行验证处理 have_access = db_helper.lookup_access_in_the_list( file_dir, 'read', request.session['access_list']) if not have_access: result = 'failed' details = '权限不足、无法查看文件内容' else: temp_path_transfer_result = address_transfer.resolve_path_to_actual_path( file_dir) if not temp_path_transfer_result['state']: result = 'failed' details = '传入的路径无法解析' elif not os.path.exists(temp_path_transfer_result['actual_path']): result = 'failed' details = '所指定文件不存在' else: filename = temp_path_transfer_result['actual_path'] try: fp = open(filename, 'r', encoding='utf-8') details = fp.read() fp.close() result = 'success' except IOError: result = 'failed' details = "文件打开失败,%s文件不存在" % filename except Exception as e: result = 'failed' details = '文件不支持预览、或其他未知错误' print(e) return HttpResponse(json.dumps({'result': result, 'details': details}))
def remove_file(request): """ 删除文件或文件夹 :param request: POST, request.POST={'remove_path':...,'remove_name':...,'remove_file_type':...} :return: HttpResponse(json.dumps({'state':...,'remove_file_id':...})) state = 'failed' or 'success' remove_file_id: 被删除目录项的ID """ print("remove_file ——views.py 11111111111111") try: remove_path = request.POST['remove_path'] # print(remove_path) remove_name = request.POST['remove_name'] remove_file_type = request.POST['remove_file_type'] remove_file_id = -1 except Exception as error: print(error) print("POST中某参数为空 ——views.py remove_file(request)") return {'state': 'failed', 'details': 'session失效'} if not db_helper.lookup_access_in_the_list(remove_path, 'remove', request.session['access']): print("无删除权限 ——views.py remove_file(request)") return HttpResponse(json.dumps({'state': 'failed', 'details': '无权限'})) remove_dir = '' if remove_file_type == 'dir': remove_dir = remove_path + remove_name + '/' else: remove_dir = remove_path + remove_name temp_resolve_result = address_transfer.resolve_path_to_actual_path(remove_dir) if not temp_resolve_result['state'] or not os.path.exists(temp_resolve_result['actual_path']): print("待删除的路径不存在 ——views.py remove_file(request)") print(temp_resolve_result) return HttpResponse(json.dumps({'state': 'failed', 'details': '文件不存在'})) else: operation.remove_file(remove_dir, request.session['username']) print("删完了") return HttpResponse(json.dumps({'state': 'success', 'remove_file_id': str(remove_file_id)}))
def upload(request): """ 接受前端发送过来的文件上传请求,向服务器写文件, 根据request.POST中是否含有chunk参数,来判断传过来的是一个大文件的分片还是一整个文件 :param request: POST request.POST: mode, task_id, file_path, csrfmiddlewaretoken, id, name, type, lastModifiedDate, size :return: null """ print(request.POST) print(request.FILES['file']) task = request.POST['task_id'] # 获取文件的唯一标识符 file_path = request.POST['file_path'] if not hfs_basic_function.validate_identity(request): return HttpResponseRedirect('filescube/login/') elif not db_helper.lookup_access_in_the_list(file_path, 'new', request.session['access']): # 用户在该目录下无上传权限, # fixme[baixu] 添加返回值,与前端交互 print("用户%s希望上传%s, 但他在%s下无上传权限"%(request.session['username'], request.POST['name'], file_path)) else: # 进入上传流程 actual_dir = address_transfer.resolve_path_to_actual_path(file_path)['actual_path'] upload_file = request.FILES['file'] if key_checker.check_if_have_this_key(request.POST, 'chunk'): # 前端发送过来的数据是一个大文件的某个分片 chunk = request.POST['chunk'] # 获取该分片在所有分片中的序号 filename = '%s%s' % (task, chunk) # 构造该分片的唯一标识符 with open(actual_dir + filename, 'wb') as f: for i in upload_file.chunks(): f.write(i) # 保存该分片到本地 else: # 前端发送过来的是一个完整的文件 filename = request.POST['name'] with open(actual_dir + filename, 'wb') as f: for i in upload_file.chunks(): f.write(i) # 保存该文件 return HttpResponse(json.dumps({'123':'123'}))
def upload_part(request): """ 接受一个新的文件分片 :param request: POST :return: 上传文件界面 """ print(request.POST) task = request.POST['task_id'] # 获取文件的唯一标识符 chunk = request.POST['chunk'] # 获取该分片在所有分片中的序号 file_path = request.POST['file_path'] if not hfs_basic_function.validate_identity(request): return HttpResponseRedirect('filescube/login/') elif db_helper.lookup_access_in_the_list(request.POST['file_path'], 'new', request.session['access']): actual_dir = address_transfer.resolve_path_to_actual_path(file_path)['actual_path'] filename = '%s%s' % (task, chunk) # 构造该分片的唯一标识符 upload_file = request.FILES['file'] with open(actual_dir + filename, 'wb') as f: for i in upload_file.chunks(): f.write(i) # 保存分片到本地 else: print('无权限,忽视请求')
def copy_fs_info_from_os_to_db(rt_dir, volume_name): """ 以当前所运行的操作系统上某一文件夹为根目录,将其下所属子树的目录信息同步至hfs系统中 :param rt_dir: 作为根目录的操作系统上的某文件夹的路径 :param volume_name: rt_dir在hfs系统上的对应路径 :return: null """ class Item: """ 数据类型,表示一个目录项的信息,用来往waiting_queue里面插入 """ def __init__(self): self.id = 1 self.name = "" self.parent_id = -1 self.type = "dir" self.dir = "" self.size = '-' print(rt_dir) print(resolve_actual_path_to_path(rt_dir)) if not resolve_actual_path_to_path(rt_dir)['state']: print('---卷映射关系不存在,请检查卷是否配置成功---') return root_dir = Item() root_dir.size = get_file_size(rt_dir) root_dir.dir = resolve_actual_path_to_path(rt_dir)['path_in_hfs'] root_dir.name = volume_name waiting_queue = queue.Queue() waiting_queue.put(root_dir) conn = pymysql.connect(host=DATABASE_HOST, port=DATABASE_PORT, user=DATABASE_USER, passwd=DATABASE_PWD, db=DB_NAME, charset='utf8') cursor = conn.cursor() cursor.execute("INSERT INTO file_tree(type, name, dir, size)\ VALUES ('" + str(root_dir.type) + "','" + str(root_dir.name) + "','" + root_dir.dir + "','" + root_dir.size + "');") while not waiting_queue.empty(): data_dir = waiting_queue.get() actual_data_dir = resolve_path_to_actual_path( data_dir.dir)['actual_path'] cursor.execute("SELECT ID from file_tree WHERE dir='" + data_dir.dir + "';") query_result = cursor.fetchall() for row in query_result: data_dir.id = row[0] for file in os.listdir(actual_data_dir): if os.path.isdir(actual_data_dir + file): if sys_str == 'Windows': new_actual_dir = actual_data_dir + file + '\\' else: new_actual_dir = actual_data_dir + file + '/' new_dir = resolve_actual_path_to_path( new_actual_dir)['path_in_hfs'] cursor.execute( "INSERT INTO file_tree(type, name, parent_id, dir, size) \ VALUES ('dir','" + file + "','" + str(data_dir.id) + "','" + new_dir + "','-')") cursor.execute("SELECT ID from file_tree WHERE dir='" + new_dir + "'") new_file = Item() query_result = cursor.fetchone() new_file.id = query_result[0] new_file.name = file new_file.parent_id = data_dir.id new_file.type = 'dir' new_file.dir = new_dir waiting_queue.put(new_file) else: new_dir = data_dir.dir + file cursor.execute( "INSERT INTO file_tree(type, name, parent_id, dir, size) \ VALUES ('file','" + str(file) + "','" + str(data_dir.id) + "','" + new_dir + "','" + get_file_size(actual_data_dir + file) + "')") conn.commit() conn.close()
def create_normal_volume(request): """ 创建新的本地卷 :param request: POST request.POST['actual_path'] request.POST['path_in_hfs'] :return: HttpResponse(json.dumps({'state': ...,'details': ...} state = 'failed' or 'success' details为详细的描述信息 """ print(request.POST) # 为服务器本机上某个目录创建卷,加入到hfs系统中 actual_path = str(request.POST['actual_path']) path_in_hfs = str(request.POST['path_in_hfs']) if not path_in_hfs.endswith('/'): path_in_hfs += '/' # sys_str为 Windows 或 Linux sys_str = platform.system() if sys_str == 'Windows': if not actual_path.endswith('\\'): actual_path += '\\' elif sys_str == 'Linux': if not actual_path.endswith('/'): actual_path += '/' size = '500G' is_localhost = True conn = pymysql.connect(host=DATABASE_HOST, port=DATABASE_PORT, user=DATABASE_USER, passwd=DATABASE_PWD, db=DB_NAME, charset='utf8') cursor = conn.cursor() # 已有的卷映射表中的实际路径不能包含actual_path、不能被actual_path包含、也不能与actual_path相等 contain = False actual_path_list = table_volume_mapping.get_volume_mapping( 'actual_path', 'is_localhost')['details'] for item in actual_path_list: if item['is_localhost'] and sys_str == 'Windows': if address_helper.is_contain_path(item['actual_path'], actual_path, '\\') or \ address_helper.is_contain_path(actual_path, item['actual_path'], '\\'): contain = True break elif item['is_localhost'] and sys_str == 'Linux': if address_helper.is_contain_path(item['actual_path'], actual_path) or \ address_helper.is_contain_path(actual_path, item['actual_path']): contain = True break if contain: conn.close() return HttpResponse( json.dumps({ 'state': 'failed', 'details': '已有的卷映射表中的实际路径不能包含actual_path、' '不能被actual_path包含、也不能与actual_path相等' })) ''' ------------=========================================================================----------- deprecated [baixu] [2020-07-06] 不允许卷嵌套、取消数据库中对文件路径结构的缓存之后,一下操作没有必要了 ------------=========================================================================----------- # 已有卷映射表中不能有和path_in_hfs相同的系统路径记录 contain = False path_in_hfs_list = table_volume_mapping.get_volume_mapping('volume_path') for item in path_in_hfs_list: if item == path_in_hfs: contain = True break if contain: conn.close() return HttpResponse(json.dumps({'state': 'failed', 'details': 'path_in_hfs值已在卷映射表中存在着对应的实际路径'})) # path_in_hfs 不能已存在于hfs系统中,否则将会导致原来存放于path_in_hfs路径下的文件解析出的地址出错 count = cursor.execute("SELECT * FROM file_tree WHERE dir='" + path_in_hfs + "'") if count > 0: conn.close() return HttpResponse(json.dumps({'state': 'failed', 'details': '卷添加失败,' + path_in_hfs + '已存在,不能挂载在系统中已存在的目录下'})) # 检验传入的实际路径是否能合法地在系统中寻址(是否在系统中存在,之后可以将这一部分扩展为若地址合法而不存在则新建目录,放到所有操作的后面,若新建目录失败则进行回滚): if not os.path.exists(actual_path): conn.close() return HttpResponse(json.dumps({'state': 'failed', 'details': '实际存储位置中没有这个文件夹,请先手动创建'})) # 将传来的 path_in_hfs 字符串拆分成目录项的数组 item_list = address_helper.separate_path(path_in_hfs) # 将新建的卷添加到 hfs 整体的目录结构中: if len(item_list) > 1: curr_dir = str(item_list[0]) + '/' cursor.execute("SELECT ID FROM file_tree WHERE dir='" + curr_dir + "';") query_result = cursor.fetchone() parent_id = query_result[0] exist = True # 在下面目录项遍历的过程中,用于标记是否数据库的文件系统里还能找到目录项了 for i in range(len(item_list) - 1): j = i + 1 item_list[j] = str(item_list[j]) curr_dir += (item_list[j] + '/') if exist: cursor.execute("SELECT ID, name, dir FROM file_tree WHERE parent_id=" + str(parent_id) + ";") query_result = cursor.fetchall() found = False for single_record in query_result: if single_record[1] == item_list[j]: parent_id = single_record[0] found = True break if not found: exist = False cursor.execute("INSERT INTO file_tree(name, type, size, dir, parent_id) \ VALUES('" + item_list[j] + "','dir','-','" + curr_dir + "','" + str(parent_id) + "');") cursor.execute("SELECT ID FROM file_tree WHERE dir='" + curr_dir + "';") query_result = cursor.fetchone() parent_id = query_result[0] # 若不存在就直接插入记录 else: cursor.execute("INSERT INTO file_tree(name, type, size, dir, parent_id) \ VALUES('" + item_list[j] + "','dir','-','" + curr_dir + "','" + str(parent_id) + "');") cursor.execute("SELECT ID FROM file_tree WHERE dir='" + curr_dir + "';") query_result = cursor.fetchone() parent_id = query_result[0] elif len(item_list) == 1: # 前面已经检验过hfs的目录结构中不存在和path_in_hfs相同的路径,故此处可以直接添加 item_list[0] = str(item_list[0]) curr_dir = item_list[0] + '/' cursor.execute("INSERT INTO file_tree(name, type, size, dir) \ VALUES('" + item_list[0] + "','dir','-','" + curr_dir + "');") else: conn.close() return HttpResponse(json.dumps({'state': 'failed', 'details': '卷添加失败,path_in_hfs为空?'})) ''' # ----------=========================================================================----------- # 用于替换上面的新的检验代码: # 传入的path_in_hfs不能已存在于系统中 # 因为方便直接将(系统不能成功解析传入的path_in_hfs)复用,但实际上牺牲了挺多效率,【mark】 if address_transfer.resolve_path_to_actual_path(path_in_hfs)['state']: conn.close() return HttpResponse( json.dumps({ 'state': 'failed', 'details': '卷的挂载点已存在' })) # 最后进行新建卷的操作 cursor.execute( "INSERT INTO volume_mapping" " (volume_path, size, actual_path, path_type, is_localhost) " "VALUES('" + path_in_hfs + "', '" + size + "', '" + address_helper.double_backslash(actual_path) + "','" + sys_str + "', " + str(is_localhost) + ");") conn.commit() conn.close() return HttpResponse( json.dumps({ 'state': 'success', 'details': '卷添加成功,选择文件同步可同步卷的目录结构' }))
def make_dir(path, operator_name, dir_name): """ 新建文件夹 :param path: 所在路径 :param operator_name: 操作者 :param dir_name: 新建的文件夹名 :return: {'state':...,'details':...} state = 'failed' or 'success'; details为报错信息或新建的文件夹的信息 """ # 此处的path是数据库所存储的路径格式的path conn = pymysql.connect(host=DATABASE_HOST, port=DATABASE_PORT, user=DATABASE_USER, passwd=DATABASE_PWD, db=DB_NAME, charset='utf8') cursor = conn.cursor() result = {'state': 'unknown', 'details': 'unknown'} try: count = cursor.execute("SELECT * FROM file_tree " "WHERE dir = '" + str(path) + str(dir_name) + "'") print('1') if count > 0: print('2') result['state'] = 'failed' result['details'] = "已存在同名文件夹" else: print('3') print(path + dir_name) path_transferred = resolve_path_to_actual_path(path + dir_name) print('3.0.1sss') if not path_transferred['state']: print('3.1') result['state'] = 'failed' result['details'] = "路径无法解析" else: print('3.2') os.mkdir(path_transferred['actual_path']) print('3.3') if result['state'] != 'failed': print('4') cursor.execute("SELECT ID FROM file_tree WHERE dir='" + str(path) + "'") parent_id = -1 query_result = cursor.fetchall() for row in query_result: parent_id = row[0] if parent_id == -1: result['state'] = 'failed' result['details'] = "所指定路径不存在" else: print(parent_id) cursor.execute( "INSERT INTO file_tree(SIZE, TYPE, NAME, DIR, PARENT_ID) " "VALUES ('-','dir','" + str(dir_name) + "','" + str(path) + str(dir_name) + "/'," + str(parent_id) + ")") # 接下来进行操作记录的数据库更新 # 暂略 print("新建文件夹成功" + str(dir_name)) cursor.execute( "SELECT ID, size, type, name, dir, parent_id from file_tree " "WHERE dir='" + str(path) + str(dir_name) + "/';") row = cursor.fetchone() conn.commit() conn.close() result['state'] = 'success' result['details'] = { 'ID': row[0], 'name': row[3], 'dir': row[4], 'parent_id': row[5] } except Exception as error: print(error) print("新建文件夹失败,进行回滚") conn.rollback() conn.close() result['state'] = 'failed' result['details'] = "新建文件夹失败,进行回滚" return result
def upload_file(upload_path, uploader_name, my_file): """ 上传文件 :param upload_path: 上传路径,hfs系统中的路径 :param uploader_name: 操作者 :param my_file: request.FILE对象,待上传的文件 :return: unknown """ if not my_file: print('operation.py upload_file: 无上传文件') # 文件是否为空的判断应该在函数外完成,此处仅作调试用 else: try: conn = pymysql.connect(host=DATABASE_HOST, port=DATABASE_PORT, user=DATABASE_USER, passwd=DATABASE_PWD, db=DB_NAME, charset='utf8') cursor = conn.cursor() count = cursor.execute("SELECT * FROM file_tree " "WHERE dir = '" + str(upload_path) + str(my_file.name) + "'") if count > 0: print("已存在同名文件或文件夹") return count = cursor.execute("SELECT * FROM file_tree " "WHERE dir = '" + str(upload_path) + str(my_file.name) + "/'") if count > 0: print("已存在同名文件或文件夹") return actual_upload_path = resolve_path_to_actual_path( upload_path)['actual_path'] with open(actual_upload_path + my_file.name, 'wb') as file: for chunk in my_file.chunks(): file.write(chunk) file_size = get_file_size(actual_upload_path + my_file.name) cursor.execute("SELECT ID FROM file_tree WHERE dir='" + str(upload_path) + "'") result = cursor.fetchall() parent_id = -1 for row in result: parent_id = row[0] if parent_id == -1: print("上传路径不存在") else: print(parent_id) cursor.execute( "INSERT INTO file_tree(SIZE, TYPE, NAME, DIR, PARENT_ID) " "VALUES ('" + str(file_size) + "','file','" + str(my_file.name) + "','" + str(upload_path) + str(my_file.name) + "','" + str(parent_id) + "')") # 接下来进行操作记录的数据库更新 # 暂略 print("上传文件成功" + str(my_file.name)) conn.commit() conn.close() except Exception as error: print(error) print("上传失败,进行回滚") conn.rollback() conn.close()
def clean_up_redundant_records(request): """ 清除权限表中的冗余记录(1.失效记录,path或user已不存在。2,多余记录,删去某记录后对权限判断不会产生影响) :param request: WSGI request GET :return: HttpResponse(json.dumps({'state':...,'details':...})) """ if not validate_identity(request): state = 'failed' details = '请登录后进行该操作' else: get_access_list = table_access.get_access_list() if get_access_list['state'] == 'success': access_list = get_access_list['details'] else: raise Exception(get_access_list['details']) access_records_to_remove = [] # 记录待删除的数据 for i in range(len(access_list)): record = access_list[i] if not table_user.if_user_exists(record['ID']): # 清理用户ID已不存在的权限记录 access_records_to_remove.append(record) elif not address_transfer.resolve_path_to_actual_path( record['path'])['state']: # 清理已经无法解析的权限记录 access_records_to_remove.append(record) elif not os.path.exists( address_transfer.resolve_path_to_actual_path( record['path'])['actual_path']): # 清理路径已不存在的权限记录 access_records_to_remove.append(record) else: # 清除冗余记录 for j in range(i + 1, len(access_list)): record_2 = access_list[j] if record_2['ID'] == record['ID'] and\ record_2['read'] == record['read'] and \ record_2['new'] == record['new'] and \ record_2['download'] == record['download'] and \ record_2['remove'] == record['remove'] and \ record_2['modify'] == record['modify'] and \ record_2['admin'] == record['admin']: if address_helper.is_contain_path(record_2['path'], record['path']) \ and record['opt'] == 'recursive': access_records_to_remove.append(record_2) elif address_helper.is_contain_path(record['path'], record_2['path']) \ and record_2['opt'] == 'recursive': access_records_to_remove.append(record) # 待删除的数据记录完毕,存储在access_records_to_remove中,可能会有重复项 # 开始删除 conn = pymysql.connect(host=DATABASE_HOST, port=DATABASE_PORT, user=DATABASE_USER, passwd=DATABASE_PWD, db=DB_NAME, charset='utf8') cursor = conn.cursor() for record_to_remove in access_records_to_remove: cursor.execute("DELETE FROM Access_for_path WHERE path='" + str(record_to_remove['path']) + "'") conn.commit() conn.close() state = 'success' details = '已清除冗余记录' return HttpResponse(json.dumps({'state': state, 'details': details}))
def add_user(user_id, password, root_dir, is_sysadmin=False): """ 创建用户 :param user_id: 用户ID,字符串类型 :param password: 用户密码,字符串类型 :param root_dir: 用户根目录,字符串类型 :param is_sysadmin: 是否新建管理员用户,布尔类型 :return: {'state':...,'details':...} 'state'为'failed'或'success','details'为附加的详细说明 """ user_id = str(user_id) password = str(password) root_dir = str(root_dir) if not root_dir.endswith('/'): raise ValueError(r'传入用来新建用户的用户根目录没有以/结尾') actual_root_dir = address_transfer.resolve_path_to_actual_path( str(root_dir))['actual_path'] differ_num = 1 # 当用户根目录与操作系统上某一目录重复时,将该值添加到尾部 actual_root_dir_temp = actual_root_dir[:-1] # 去除了末尾的'/'的actual_root_dir root_dir_temp = root_dir[:-1] # 去除了末尾的'/'的root_dir while os.path.exists(actual_root_dir): actual_root_dir = actual_root_dir_temp + str(differ_num) + '/' root_dir = root_dir_temp + str(differ_num) + '/' differ_num += 1 conn = pymysql.connect(host=DATABASE_HOST, port=DATABASE_PORT, user=DATABASE_USER, passwd=DATABASE_PWD, db=DB_NAME, charset='utf8') cursor = conn.cursor() try: if is_sysadmin: cursor.execute( "INSERT INTO USER(ID, PASSWORD, root_dir, sys_admin) \ VALUES ('" + str(user_id) + "','" + str(password) + "','" + str(root_dir) + "',TRUE)") else: print('非系统管理员') cursor.execute( "INSERT INTO USER(ID, PASSWORD, root_dir, sys_admin) \ VALUES ('" + str(user_id) + "','" + str(password) + "','" + str(root_dir) + "',FALSE)") cursor.execute( "INSERT INTO Access_for_path(path, `read`, new, download, remove, modify, admin," " opt, ID) VALUES ('" + str(root_dir) + "',TRUE,TRUE,TRUE,TRUE,TRUE,TRUE," "'recursive','" + str(user_id) + "')") os.mkdir(actual_root_dir) state = 'success' details = '新建用户成功' except Exception as error: print(error) state = 'failed' details = error conn.rollback() finally: conn.commit() conn.close() return {'state': state, 'details': details}