Exemple #1
0
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))
Exemple #2
0
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())
Exemple #3
0
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'])
Exemple #4
0
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}
Exemple #5
0
 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')
Exemple #6
0
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}))
Exemple #7
0
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}))
Exemple #8
0
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))
Exemple #9
0
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}))
Exemple #10
0
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("解析后的实际路径不存在!这可能是其他程序对之造成的修改,建议及时做数据同步。")
Exemple #11
0
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}))
Exemple #12
0
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)}))
Exemple #13
0
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'}))
Exemple #14
0
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()
Exemple #16
0
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': '卷添加成功,选择文件同步可同步卷的目录结构'
        }))
Exemple #17
0
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
Exemple #18
0
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()
Exemple #19
0
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}))
Exemple #20
0
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}