示例#1
0
def defaultUserPath(aUserId):
    """
    用户默认路径
    user default path
    """
    global __gDefaultUserPath
    if __gDefaultUserPath == "*":
        __gDefaultUserPath = AppConfig().defaultUserPath
    strPathName = "{}".format(aUserId)
    defPath = os.path.join(__gDefaultUserPath, strPathName)
    if not os.path.isdir(defPath):
        log.logObject().info("create path: {}".format(defPath))
        os.makedirs(defPath)
    return defPath
示例#2
0
def sendFile(aStrFileName, aErrorStatusCode=200):
    """发送文件到客户端,支持单 Range 请求

    :aStrFileName: 文件名称
    :returns: Response

    """

    if not os.path.isfile(aStrFileName):
        log.logObject().error("找不到文件=%s" % aStrFileName)
        return buildErrorResponseData(kCmdUserError_NotResource,
                                      statusCode=aErrorStatusCode)

    try:
        httpHeaderRange = request.headers.get("Range")
        r = http.parse_range_header(httpHeaderRange)
        bHasRange = r is not None and len(
            r.ranges) == 1 and r.ranges[0][0] is not None
    except Exception as e:
        bHasRange = False

    #发送整个文件
    if not bHasRange:
        return send_file(aStrFileName)

    #发送部分文件
    nFileSize = os.path.getsize(aStrFileName)
    beginPos, stopPos = r.range_for_length(nFileSize)
    with open(aStrFileName, "rb") as f:
        f.seek(beginPos)
        byteContens = f.read(stopPos - beginPos)

    strMimeType = mimetypes.guess_type(aStrFileName)[0]
    if strMimeType is None:
        strMimeType = "application/octet-stream"
    resp = Response(byteContens,
                    206,
                    mimetype=strMimeType,
                    headers={
                        "Content-Range": r.make_content_range(nFileSize),
                        "Accept-Ranges": r.units,
                        "Etag": "%d" % nFileSize
                    })
    return resp
示例#3
0
 def makeUser(self, aUserName, aPassword):
     "若插入不成功,则判断修改密码,返回ID"
     curTime = unit.getTimeInt()
     fieldValues = {
         "name": aUserName,
         "password": aPassword,
         "createTime": curTime,
         "lastLoginDate": curTime,
         "lastModifyTime": curTime
     }
     nId = self.insert(_kUserTableName, fieldValues)
     if nId is None:
         #插入不成功,正常情况是数据已经存在
         row = self.select(_kUserTableName, {"name": aUserName})
         if row is None:
             log.logObject().log(logging.ERROR, "无法创建用户 %s" % aUserName)
             return None
         nId = row[kUserFieldId]
         if aPassword and len(
                 aPassword) > 0 and row[kUserFieldPassword] != aPassword:
             self.update(_kUserTableName, {"id": nId},
                         {"password": aPassword})
     return nId
示例#4
0
def checkApiParamWithRequestValues(aNeedLogin, aParams, aRequestValues):
    """判断Api参数信息是否正确

    :aNeedLogin: 是否需要登陆才能使用
    :aParams: API请求的参数,是一个list,
        元素为dict: 有以下可用内容
             name: 请求参数名; 
             checkfunc: 从request获取到的数据后进行检查,返回None表示此参数不正确
             default: 当提供此值时,说明这是个可选参数,当参数不正确或没有时,将使用此值代替
        元素为string: 
            表示name
    :returns: (bSuccess, 成功时: loginInfo(当aNeedLogin时,否则为None), {key, value}
                         失败时: response, realStatusCode(实际上的错误码)

    """

    # 判断是否需要登陆, 失败实际Code: 403
    loginInfo = None
    if aNeedLogin:
        key = session.get(defines.kSessionUserKey)
        loginInfo = LoginInfo.GetObject(key)
        if loginInfo is None:
            return False, buildErrorResponseData(kCmdUserError_NeedLogin), 403

    # 参数判断, 失败实际Code: 416
    try:
        result = []
        result.append(True)
        result.append(loginInfo)
        params = {}

        # begin for
        for item in aParams:
            if isinstance(item, str):
                key = item
                bHasDefaultValue = False
                bHasCheckFunc = False
            else:
                key = item["name"]
                bHasDefaultValue = "default" in item.keys()
                defaultValue = item["default"] if bHasDefaultValue else None
                bHasCheckFunc = "checkfunc" in item.keys()
                checkFunc = item["checkfunc"] if bHasCheckFunc else None

            value = aRequestValues.get(key)
            if bHasCheckFunc:
                try:
                    value = checkFunc(value)
                except Exception as e:
                    value = None
            bParamOK = value != None
            if not bParamOK and bHasDefaultValue:
                value = defaultValue
                bParamOK = True

            if not bParamOK:
                log.logObject().info("parse not ok: {}, value: {}".format(
                    item, value))
                return False, buildErrorResponseData(kCmdUserError_Param), 416
            params[key] = value
        # end for
        result.append(params)
        return result
    except Exception as e:
        log.logObject().error("parse param error: {}".format(e))
        return False, buildErrorResponseData(kCmdUserError_Param), 417
示例#5
0
文件: app.py 项目: jxd524/iSyncServer
def appUploadFile():
    "上传文件"
    # print(request.args)
    result = responseHelp.checkApiParamWithRequestValues(True, (
        {"name": "id", "checkfunc": unit.checkParamForInt},
        {"name": "obp", "checkfunc": unit.checkParamForInt, "default": 0},
        {"name": "tbp", "checkfunc": unit.checkParamForInt, "default": 0},
        {"name": "sbp", "checkfunc": unit.checkParamForInt, "default": 0},
        {"name": "cm", "default": None}
        ), request.args)

    if not result[kParamForResult]:
        return result[kParamForErrorResponse]

    loginInfo = result[kParamForLoginInfo]
    param = result[kParamForRequestParams]
    nFileId = param["id"]

    db = _getDbManager()
    fileRow = db.getFileByIdAndRootIds(nFileId, loginInfo.rootIdsString)
    if not fileRow:
        return responseHelp.buildErrorResponseData(responseHelp.kCmdUserError_Param)

    upFileInfos = {}
    orgFullFileName = None
    upFileNames = {}
    def _myUploadFileStreamFactory(aTotalContentLength, aContentType, aFileName, aContentLength):
        "生成文件进入写入操作"
        strFullFileName = None
        nBeginPos = 0
        strDbFiledName = None
        if aFileName == "origin":
            #处理R原始文件
            catalogRow = db.getCatalogByIdAndRootIds(fileRow[dataManager.kFileFieldRealCatalogId], 
                    loginInfo.rootIdsString)
            if catalogRow:
                strFullFileName = os.path.join(catalogRow[dataManager.kCatalogFieldPath], 
                        fileRow[dataManager.kFileFieldFileName])
                nBeginPos = param["obp"]
                strDbFiledName = "statusForOrigin"
                nonlocal orgFullFileName
                orgFullFileName = strFullFileName
        elif aFileName == "thumb":
            #小缩略图
            strFullFileName = unit.getFileThumbFullFileName(fileRow[dataManager.kFileFieldRealCatalogId], nFileId, 0)
            nBeginPos = param["tbp"]
            strDbFiledName = "statusForThumb"
        elif aFileName == "screen":
            #大缩略图
            strFullFileName = unit.getFileThumbFullFileName(fileRow[dataManager.kFileFieldRealCatalogId], nFileId, 0)
            nBeginPos = param["sbp"]
            strDbFiledName = "statusForScreen"

        if not strFullFileName:
            raise RuntimeError("filename is error")

        # 判断文件的大小,与传入参数进行对比,若传入文件大小过大,则直接报错.否则根据传入参数进行写操作
        nCurFileSize = os.stat(strFullFileName).st_size if os.path.isfile(strFullFileName) else 0
        if nBeginPos > nCurFileSize:
            raise RuntimeError("begin position is error!")

        upFileInfos[strDbFiledName] = defines.kFileStatusFromUploaded
        upFileNames[aFileName] = strFullFileName

        # print("will open file: ", strFullFileName, "; beginPos: ", nBeginPos)
        f = open(strFullFileName, "a+b")
        f.truncate(nBeginPos)
        f.seek(0, os.SEEK_END)
        return f

    # 开始接收文件内容
    try:
        stream,form,files = werkzeug.formparser.parse_form_data(request.environ, 
                stream_factory = _myUploadFileStreamFactory,
                silent = False) 
    except Exception as e:
        for key in upFileInfos.keys():
            upFileInfos[key] = defines.kFileStatusFromUploading
        db.updateFile(nFileId, upFileInfos, loginInfo.rootIdsString)
        log.logObject().error(e)
        return responseHelp.buildErrorResponseData(responseHelp.kCmdUserError_Param)

    # 更新数据库
    if orgFullFileName:
        upFileInfos["size"] = os.stat(orgFullFileName).st_size
    db.updateFile(nFileId, upFileInfos, loginInfo.rootIdsString)


    # 生成返回数据
    fileRow = db.getFileByIdAndRootIds(nFileId, loginInfo.rootIdsString)
    funcForIdRelatePath = lambda : db.getCatalogIdRelatePathInfo(fileRow[dataManager.kFileFieldRealCatalogId])
    fileInfo = dataManager.buildFileInfo(fileRow, funcForIdRelatePath)
    result = {"fileInfo": fileInfo}

    #写入检验值
    strCm = param["cm"]
    if strCm:
        strCm = strCm.lower()
        bSha1 = strCm == "sha1"
        bMd5 = not bSha1 and strCm == "md5"
        if bSha1 or bMd5:
            check = {}
            for key, filename in upFileNames.items():
                check[key] = unit.SHA1FileWithName(filename) if bSha1 else unit.MD5FileWithName(filename)
            result["check"] = check

    return responseHelp.buildSuccessResponseData(result)