Beispiel #1
0
def create_folder(username, path, name, foldername):
    from pathlib import Path
    from os import mkdir
    from flask import current_app
    from diskcloud.libs.response import gen_error_res
    from diskcloud.libs.time import now_time_str
    from diskcloud.libs.mysql import insert_execute, db_commit, db_rollback

    path = Path(path, name).as_posix()
    foldername = generate_name(username, path, foldername, 0)
    if insert_execute(
            'insert into storage(username, path, name, modify_time, type) values(%s, %s, %s, %s, %s)',
        (username, path, foldername, now_time_str(), 1)):
        path = Path(current_app.config['FILES_FOLDER'], 'user', username, path,
                    foldername).as_posix()
        try:
            mkdir(path)
        except:
            db_rollback()
            return gen_error_res('fail to create folder', 500)
        db_commit()
        return ('', 200)
    else:
        db_rollback()
        return gen_error_res('向数据库内插入数据失败', 500)
Beispiel #2
0
def create_file(username, path, name, filename):
    from pathlib import Path
    from flask import current_app
    from diskcloud.libs.response import gen_error_res
    from diskcloud.libs.time import now_time_str
    from diskcloud.libs.mysql import insert_execute, db_commit, db_rollback

    path = Path(path, name).as_posix()
    filename = generate_name(username, path, filename, 0)
    if insert_execute(
            'insert into storage(username, path, name, size, modify_time, type) values(%s, %s, %s, %s, %s, %s)',
        (username, path, filename, 0, now_time_str(), 0)):
        try:
            path = Path(current_app.config['FILES_FOLDER'], 'user', username,
                        path, filename).as_posix()
            file = open(path, 'a+')
            file.close()
        except:
            db_rollback()
            return gen_error_res('创建文件失败', 500)
        db_commit()
        return ('', 200)
    else:
        db_rollback()
        return gen_error_res('向数据库内插入数据失败', 500)
Beispiel #3
0
    def Login(self):
        from diskcloud.libs.string import hash_sha3
        from diskcloud.libs.valid import valid_user
        from diskcloud.libs.response import gen_json_res
        from diskcloud.libs.cookie import set_cookie_id
        from diskcloud.libs.session import create_session

        username = request.json.get('username')
        password = request.json.get('password')
        pw_hashed = hash_sha3(password)
        if valid_user(username, pw_hashed):
            create_session('username', username)
            if request.json.get('enable_cookie') == 'true':
                cookie_id = set_cookie_id(username)
                if cookie_id:
                    response = make_response('')
                    response.status_code = 200
                    response.set_cookie(
                        'login_id',
                        value=cookie_id,
                        max_age=current_app.config['COOKIE_LIFETIME'],
                        path=current_app.config['SESSION_COOKIE_PATH'],
                        domain=current_app.config['SESSION_COOKIE_DOMAIN'],
                        secure=current_app.config['SESSION_COOKIE_SECURE'],
                        httponly=current_app.config['SESSION_COOKIE_HTTPONLY'])
                    return response
                else:
                    return gen_error_res('不能设置COOKIE', 500)
            return ('', 200)
        else:
            return gen_error_res('错误的用户名或密码', 403)
Beispiel #4
0
def untrash_can(username, path, name, is_file):
    from diskcloud.libs.mysql import select_execute, update_execute, db_commit, db_rollback
    from diskcloud.libs.response import gen_error_res
    from diskcloud.libs.time import now_time_str
    from pathlib import Path
    from flask import current_app
    from shutil import move

    def is_empty(generator):
        try:
            i = next(generator)
        except StopIteration:
            return True
        return False

    def walk(username, path, af_path):
        result = select_execute(
            'select name, type from storage where username = %s and path = %s and trash_can = %s',
            (username, path, 1))
        update_result = True
        for i in range(len(result)):
            update_result = update_result and update_execute(
                'update storage set path = %s, trash_can = %s, trash_can_time = %s where username = %s and path = %s and name = %s and trash_can = %s',
                (af_path, 0, now_time_str(), username, path, result[i][0], 1))
            if result[i][1] == 1:
                update_result = update_result and walk(
                    username,
                    Path(path, result[i][0]).as_posix(),
                    Path(af_path, result[i][0]).as_posix())
        return update_result

    af_name = generate_name(username, path, name, 0)
    result = update_execute(
        'update storage set name = %s, trash_can = %s, trash_can_time = %s where username = %s and path = %s and name = %s and trash_can = %s',
        (af_name, 0, None, username, path, name, 1))

    if not is_file:
        result = result and walk(username,
                                 Path(path, name).as_posix(),
                                 Path(path, af_name).as_posix())
    if result:
        bf_path = Path(current_app.config['FILES_FOLDER'], 'trash_can',
                       username, path, name)
        af_path = Path(current_app.config['FILES_FOLDER'], 'user', username,
                       path, af_name)
        try:
            move(bf_path.as_posix(), af_path.as_posix())
            if bf_path.parent.resolve() != Path(
                    current_app.config['FILES_FOLDER'], 'trash_can',
                    username).resolve() and is_empty(bf_path.parent.iterdir()):
                bf_path.parent.rmdir()
        except:
            db_rollback()
            return gen_error_res('无法还原,原文件夹可能更名或移动了位置', 500)
        db_commit()
        return ('', 200)
    db_rollback()
    return gen_error_res('更新数据库失败', 500)
Beispiel #5
0
def valid_url_path(url_path, root_ok=False, trash_can=False):
    from pathlib import Path
    from diskcloud.libs.session import valid_session
    from diskcloud.libs.response import gen_error_res
    from diskcloud.libs.mysql import select_execute

    url_path = url_path.strip().replace('..', '').replace('~', '')
    if url_path.endswith('/'):
        return gen_error_res('无效的路径', 400)
    if url_path.count('/') == 0:
        if root_ok == False:
            return gen_error_res('无效的路径,该路径不得为根目录', 404)
        username = url_path
        if valid_session('username', username):
            return {
                'username': username,
                'path': '.',
                'name': '.',
                'is_file': False
            }
        else:
            return gen_error_res('无效的session', 401)
    elif url_path.count('/') == 1:
        path = '.'
        username, name = url_path.split('/', maxsplit=1)
    else:
        username, others = url_path.split('/', maxsplit=1)
        path, name = others.rsplit('/', maxsplit=1)
    if valid_session('username', username):
        if trash_can == False:
            trash_can = 0
        elif trash_can == True:
            trash_can = 1
        result = select_execute(
            "select type from storage where username = %s and path = %s and name = %s and trash_can = %s",
            (username, path, name, trash_can))
        if result[0][0] == 0:
            return {
                'username': username,
                'path': path,
                'name': name,
                'is_file': True
            }
        elif result[0][0] == 1:
            return {
                'username': username,
                'path': path,
                'name': name,
                'is_file': False
            }
        else:
            return gen_error_res('无效的路径', 404)
    else:
        return gen_error_res('无效的session', 401)
Beispiel #6
0
    def SearchInfo(self, path):
        from diskcloud.libs.file import get_search_info
        from diskcloud.libs.response import gen_json_res

        search_text = request.args.get('search_text', None)
        if search_text is None:
            return gen_error_res("无效的请求参数", 400)
        result = valid_url_path(path, True)
        if isinstance(result, dict):
            if result['path'] == '.' and result['name'] == '.':
                json_obj = get_search_info(result['username'], search_text)
                return gen_json_res(json_obj)
            else:
                return gen_error_res('无效的URL', 400)
        return result
Beispiel #7
0
    def CreateFolder(self, path):
        from diskcloud.libs.file import create_folder
        from diskcloud.libs.valid import valid_dir_name

        name = request.args.get('name', None)
        if name is None:
            return gen_error_res("无效的请求参数", 400)
        result = valid_url_path(path, True)
        if isinstance(result, dict):
            if result['is_file'] is False:
                if valid_dir_name(name):
                    return create_folder(result['username'], result['path'],
                                         result['name'], name)
                return gen_error_res("无效的文件夹名称", 400)
            return gen_error_res("路径必须是文件夹", 400)
        return result
Beispiel #8
0
    def Register(self):
        from os import mkdir
        from pathlib import Path
        from diskcloud.libs.string import hash_sha3
        from diskcloud.libs.session import create_session
        from diskcloud.libs.mysql import select_execute, insert_execute, db_commit, db_rollback

        if current_app.config['CAN_REGISTER']:
            username = request.json.get('username')
            password = request.json.get('password')
            email = request.json.get('email')
            pw_hashed = hash_sha3(password)

            result = select_execute(
                'select password from user where username = %s', (username, ))
            if len(result) == 0:
                result = select_execute(
                    'select password from user where email = %s', (email, ))
                if len(result) == 0:
                    result = insert_execute(
                        'insert into user(username, password, email) values(%s, %s, %s)',
                        (username, pw_hashed, email))
                    if result:
                        user_path = Path(current_app.config['FILES_FOLDER'],
                                         'user', username).as_posix()
                        trash_can_path = Path(
                            current_app.config['FILES_FOLDER'], 'trash_can',
                            username).as_posix()
                        tar_path = Path(current_app.config['FILES_FOLDER'],
                                        'tar', username).as_posix()
                        try:
                            mkdir(user_path)
                            mkdir(trash_can_path)
                            mkdir(tar_path)
                        except FileExistsError:
                            pass
                        except:
                            raise
                        db_commit()
                        create_session('username', username)
                        return ('', 200)
                    else:
                        db_rollback()
                        return gen_error_res('数据库插入数据失败', 500)
                return gen_error_res('该email已被使用', 403)
            return gen_error_res('该用户名已被使用', 403)
        return gen_error_res('注册功能暂不开放', 403)
Beispiel #9
0
    def Rename(self, path):
        from diskcloud.libs.file import rename
        from diskcloud.libs.valid import valid_file_name, valid_dir_name
        from diskcloud.libs.response import gen_error_res

        result = valid_url_path(path)
        if isinstance(result, dict):
            af_name = request.json.get('af_name')
            if result['is_file']:
                if not valid_file_name(af_name):
                    return gen_error_res('无效的文件名称', 400)
            else:
                if not valid_dir_name(af_name):
                    return gen_error_res('无效的文件夹名称', 400)
            return rename(result['username'], result['path'], result['name'],
                          af_name, result['is_file'])
        return result
Beispiel #10
0
def moveto(username, bf_path, bf_name, af_path, af_name, is_file):
    from pathlib import Path
    from flask import current_app
    from diskcloud.libs.response import gen_error_res
    from diskcloud.libs.mysql import update_execute, db_commit, db_rollback

    def walk(username, path, af_path):
        result = select_execute(
            'select name, type from storage where username = %s and path = %s and trash_can = %s',
            (username, path, 0))
        update_result = True
        for i in range(len(result)):
            update_result = update_result and update_execute(
                'update storage set path = %s where username = %s and path = %s and name = %s and trash_can = %s',
                (af_path, username, path, result[i][0], 0))
            if result[i][1] == 1:
                update_result = update_result and walk(
                    username,
                    Path(path, result[i][0]).as_posix(),
                    Path(af_path, result[i][0]).as_posix())
        return update_result

    af_path = Path(af_path, af_name).as_posix()
    af_name = generate_name(username, af_path, bf_name, 0)
    result = True
    if not is_file:
        result = walk(username,
                      Path(bf_path, bf_name).as_posix(),
                      Path(af_path, af_name).as_posix())
    if result and update_execute(
            'update storage set path = %s, name = %s where username = %s and path = %s and name = %s and trash_can = %s',
        (af_path, af_name, username, bf_path, bf_name, 0)):
        bf_path = Path(current_app.config['FILES_FOLDER'], 'user', username,
                       bf_path, bf_name)
        af_path = Path(current_app.config['FILES_FOLDER'], 'user', username,
                       af_path, af_name)
        try:
            bf_path.rename(af_path)
        except:
            db_rollback()
            return gen_error_res('移动失败', 500)
        db_commit()
        return ('', 200)
    else:
        return gen_error_res('更新数据库失败', 500)
Beispiel #11
0
def empty_trash_can(username):
    from diskcloud.libs.mysql import delete_execute, db_commit, db_rollback
    from diskcloud.libs.response import gen_error_res
    from pathlib import Path
    from flask import current_app

    def delete_file(path):
        for i in path.iterdir():
            if i.is_file():
                i.unlink()
            elif i.is_dir():
                delete_file(i)

    def delete_folder(path):
        try:
            next(path.iterdir())
        except StopIteration:
            path.rmdir()
            return
        for i in path.iterdir():
            if i.is_dir():
                delete_folder(i)
        path.rmdir()

    def empty(path):
        delete_file(path)
        delete_folder(path)
        path.mkdir()

    if delete_execute(
            'delete from storage where username = %s and trash_can = %s',
        (username, 1)):
        trash_can_path = Path(current_app.config['FILES_FOLDER'], 'trash_can',
                              username)
        try:
            empty(trash_can_path)
        except:
            db_rollback()
            return gen_error_res('清空回收站失败', 500)
        db_commit()
        return ('', 200)
    else:
        db_rollback()
        return gen_error_res('更新数据库失败', 500)
Beispiel #12
0
    def EmptyTrashcan(self, path):
        from diskcloud.libs.file import empty_trash_can

        result = valid_url_path(path, True)
        if isinstance(result, dict):
            if result['path'] == '.' and result['name'] == '.':
                return empty_trash_can(result['username'])
            else:
                return gen_error_res('无效的URL', 400)
        return result
Beispiel #13
0
    def StarInfo(self, path):
        from diskcloud.libs.file import get_star_info
        from diskcloud.libs.response import gen_json_res

        result = valid_url_path(path, True)
        if isinstance(result, dict):
            if result['path'] == '.' and result['name'] == '.':
                json_obj = get_star_info(result['username'])
                return gen_json_res(json_obj)
            else:
                return gen_error_res('无效的URL', 400)
        return result
Beispiel #14
0
def unshare(username, path, name):
    from diskcloud.libs.mysql import update_execute, db_commit, db_rollback
    from diskcloud.libs.response import gen_error_res

    result = update_execute(
        'update storage set share = %s, share_time = %s, expire_time = %s, sid = %s where username = %s and path = %s and name = %s and trash_can = %s',
        (0, None, None, None, username, path, name, 0))
    if result:
        db_commit()
        return ('', 200)
    db_rollback()
    return gen_error_res('更新数据库失败', 500)
Beispiel #15
0
    def UploadFiles(self, path):
        from diskcloud.libs.file import save_file
        from diskcloud.libs.valid import valid_file_name

        result = valid_url_path(path, True)
        if isinstance(result, dict):
            if result['is_file'] is False:
                files = request.files
                if len(files) == 0:
                    return gen_error_res("没有选中的文件")
                for i in files:
                    if valid_file_name(files[i].filename):
                        save_result = save_file(result['username'],
                                                result['path'], result['name'],
                                                files[i])
                        if save_result is not True:
                            return save_result
                    else:
                        return gen_error_res('无效的文件名称', 400)
                return ('', 200)
            return gen_error_res("路径必须是文件夹", 400)
        return result
Beispiel #16
0
def star(username, path, name):
    from diskcloud.libs.mysql import update_execute, db_commit, db_rollback
    from diskcloud.libs.response import gen_error_res
    from diskcloud.libs.time import now_time_str

    result = update_execute(
        'update storage set star = %s, star_time = %s where username = %s and path = %s and name = %s and trash_can = %s',
        (1, now_time_str(), username, path, name, 0))
    if result:
        db_commit()
        return ('', 200)
    db_rollback()
    return gen_error_res('更新数据库失败', 500)
Beispiel #17
0
def get_sid(username, path, name):
    from diskcloud.libs.mysql import select_execute
    from diskcloud.libs.response import gen_error_res
    from pathlib import Path

    result = select_execute(
        'select sid from storage where username = %s and path = %s and name = %s and trash_can = %s',
        (username, path, name, 0))
    sid = result[0][0]
    if sid != None:
        return {'sid': sid}
    else:
        return gen_error_res('获取分享ID失败', 500)
Beispiel #18
0
    def Share(self, path):
        from diskcloud.libs.share import generate_id
        from diskcloud.libs.response import gen_json_res

        result = valid_url_path(path)
        if isinstance(result, dict):
            # check id_life
            id_life = request.args.get('life')
            if id_life is None:
                return gen_error_res('无效的时间参数', 400)
            try:
                id_life = int(id_life)
            except ValueError:
                return gen_error_res('无效的时间参数', 400)
            if not 0 <= id_life <= 24:
                return gen_error_res('无效的时间参数', 400)
            # generate share id
            result = generate_id(result['username'], result['path'],
                                 result['name'], id_life)
            if result['succeed']:
                return gen_json_res({'sid': result['sid']})
            return gen_error_res(result['reason'], 500)
        return result
Beispiel #19
0
def save_file(username, path, name, file):
    from pathlib import Path
    from flask import current_app
    from diskcloud.libs.response import gen_error_res
    from diskcloud.libs.time import now_time_str
    from diskcloud.libs.mysql import insert_execute, db_commit, db_rollback

    path = Path(path, name).as_posix()
    filename = generate_name(username, path, file.filename, 0)
    whole_path = Path(current_app.config['FILES_FOLDER'], 'user', username,
                      path, filename)
    whole_path_str = whole_path.as_posix()
    try:
        file.save(whole_path_str)
    except:
        return gen_error_res('保存已上传的文件失败', 500)
    if insert_execute(
            'insert into storage(username, path, name, size, modify_time, type) values(%s, %s, %s, %s, %s, %s)',
        (username, path, filename, whole_path.stat().st_size, now_time_str(),
         0)):
        db_commit()
        return True
    return gen_error_res('向数据库内插入数据失败', 500)
Beispiel #20
0
    def Move(self, path):
        from diskcloud.libs.file import moveto

        bf_result = valid_url_path(path)
        if isinstance(bf_result, dict):
            af_path = request.json.get("af_path")
            af_result = valid_url_path(af_path, True)
            if isinstance(af_result, dict):
                if af_result['is_file'] is False:
                    return moveto(bf_result['username'], bf_result['path'],
                                  bf_result['name'], af_result['path'],
                                  af_result['name'], bf_result['is_file'])
                return gen_error_res("目标路径必须是文件夹", 400)
            return af_result
        return bf_result
Beispiel #21
0
def trash_can(username, path, name, is_file):
    from diskcloud.libs.mysql import select_execute, update_execute, db_commit, db_rollback
    from diskcloud.libs.response import gen_error_res
    from diskcloud.libs.time import now_time_str
    from pathlib import Path
    from flask import current_app
    from shutil import move

    def walk(username, bf_path, af_path):
        result = select_execute(
            'select name, type from storage where username = %s and path = %s and trash_can = %s',
            (username, bf_path.as_posix(), 0))
        update_result = True
        for i in range(len(result)):
            af_name = generate_name(username, af_path.as_posix(), result[i][0],
                                    1)
            folder_path = Path(current_app.config['FILES_FOLDER'], 'user',
                               username, bf_path)
            update_result = update_result and update_execute(
                'update storage set path = %s, name = %s, trash_can = %s, trash_can_time = %s where username = %s and path = %s and name = %s and trash_can = %s',
                (af_path.as_posix(), af_name, 1, now_time_str(), username,
                 bf_path.as_posix(), result[i][0], 0))
            if af_name != result[i][0]:
                Path(folder_path,
                     result[i][0]).rename(Path(folder_path, af_name))
            if result[i][1] == 1:
                update_result = update_result and walk(
                    username, Path(bf_path, result[i][0]),
                    Path(af_path, af_name))
        return update_result

    af_name = generate_name(username, path, name, 1)
    bf_path = Path(current_app.config['FILES_FOLDER'], 'user', username, path,
                   name)
    af_path = Path(current_app.config['FILES_FOLDER'], 'trash_can', username,
                   path, af_name)
    result = update_execute(
        'update storage set name = %s, trash_can = %s, trash_can_time = %s where username = %s and path = %s and name = %s and trash_can = %s',
        (af_name, 1, now_time_str(), username, path, name, 0))

    try:
        if is_file:
            af_path.parent.mkdir(parents=True, exist_ok=True)
            move(bf_path.as_posix(), af_path.as_posix())
        else:
            result = result and walk(username, Path(path, name),
                                     Path(path, af_name))

            if af_path.is_dir():
                for child in bf_path.iterdir():
                    move(child.as_posix(), af_path.as_posix())
                bf_path.rmdir()
            elif not af_path.exists():
                move(bf_path.as_posix(), af_path.as_posix())
    except:
        db_rollback()
        return gen_error_res('移动失败', 500)

    if result:
        db_commit()
        return ('', 200)
    else:
        db_rollback()
        return gen_error_res('更新数据库失败', 500)
Beispiel #22
0
def delete(username, path, name, is_file):
    from pathlib import Path
    from shutil import rmtree
    from os import remove
    from flask import current_app
    from diskcloud.libs.response import gen_error_res
    from diskcloud.libs.mysql import select_execute, delete_execute, db_commit, db_rollback

    def is_empty(generator):
        try:
            i = next(generator)
        except StopIteration:
            return True
        return False

    def delete_db(username, path, name):
        return delete_execute(
            'delete from storage where username = %s and path = %s and name = %s and trash_can = %s',
            (username, path, name, 1))

    def delete_folder_db(username, path, name):
        if delete_db(username, path, name):
            path = Path(path, name).as_posix()
            result = select_execute(
                'select name, type from storage where username = %s and path = %s and trash_can = %s',
                (username, path, 1))
            for i in range(len(result)):
                if result[i][1] == 0:
                    if delete_db(username, path, result[i][0]) is False:
                        return False
                else:
                    if delete_folder_db(username, path, result[i][0]) is False:
                        return False
            return True
        return False

    def in_trash_can(username, path, name):
        result = select_execute(
            'select name from storage where username = %s and path = %s and name = %s and trash_can = %s',
            (username, path, name, 1))
        if len(result) != 0:
            return True
        return False

    if in_trash_can(username, path, name):
        if is_file:
            if delete_db(username, path, name):
                path = Path(current_app.config['FILES_FOLDER'], 'trash_can',
                            username, path, name)
                try:
                    remove(path.as_posix())
                    if path.parent.resolve() != Path(
                            current_app.config['FILES_FOLDER'], 'trash_can',
                            username).resolve() and is_empty(
                                path.parent.iterdir()):
                        path.parent.rmdir()
                except:
                    db_rollback()
                    return gen_error_res('删除失败', 500)
                db_commit()
                return ('', 200)
            else:
                return gen_error_res('更新数据库失败', 500)
        else:
            if delete_folder_db(username, path, name):
                path = Path(current_app.config['FILES_FOLDER'], 'trash_can',
                            username, path, name).as_posix()
                try:
                    rmtree(path)
                except:
                    db_rollback()
                    return gen_error_res('删除失败', 500)
                db_commit()
                return ('', 200)
            else:
                db_rollback()
                return gen_error_res('更新数据库失败', 500)
    return gen_error_res("不能删除,因为该文件或文件夹不在回收站中")