FastMovieAI 二开基线 v1.0 (完整源码)

This commit is contained in:
李建琦
2026-08-26 18:41:02 +08:00
parent fad7690c0c
commit d54584f70d
888 changed files with 105571 additions and 1 deletions
+41
View File
@@ -0,0 +1,41 @@
local _M = {
root_path = nil
}
local function get_script_dir()
local lfs_ok, lfs = pcall(require, "lfs")
local source
if debug and debug.getinfo then
-- OpenResty 或标准 Lua 都适用
source = debug.getinfo(2, "S").source:sub(2)
elseif arg and arg[0] then
source = arg[0]
else
return nil
end
-- 如果是相对路径,转换为绝对路径
if not source:match("^/") then
if lfs_ok then
source = lfs.currentdir() .. "/" .. source
else
-- 没有 lfs,使用 io.popen("pwd") 获取当前目录
local handle = io.popen("pwd")
local cwd = handle:read("*l")
handle:close()
source = cwd .. "/" .. source
end
end
-- 提取目录
local dir = source:match("(.*/)")
-- 降末尾的/lua/module/去掉
return dir:sub(1,-13)
end
_M.root_path = get_script_dir()
print(_M.root_path)
return _M
+122
View File
@@ -0,0 +1,122 @@
--[[
load_env.lua
功能:
自动读取 .env 文件(优先当前目录,其次模块上一级目录),解析为键值表。
提供安全的 env.get(key, default, type) 方法:
- 不存在 .env 文件或 key 时返回 default
- 支持类型转换(string / number / boolean
使用示例:
local env = require("load_env")
local port = env.get("SERVER_PORT", 8080, "number")
local debug = env.get("DEBUG", false, "boolean")
]]
local config = require "config"
local M = {}
local env_cache = nil
------------------------------------------------------------
-- 工具函数
------------------------------------------------------------
-- 读取文件内容
local function read_file(path)
local file = io.open(path, "r")
if not file then return nil end
local content = file:read("*a")
file:close()
-- 去掉 UTF-8 BOM
if content:sub(1,3) == "\239\187\191" then
content = content:sub(4)
end
return content
end
-- 解析 .env 文件为表
local function parse_env(content)
local env = {}
if not content then return env end
for line in content:gmatch("[^\r\n]+") do
if not line:match("^%s*#") and line:match("%S") then
local key, value = line:match("^%s*([%w_]+)%s*=%s*(.-)%s*$")
if key then
value = value:gsub("^['\"](.-)['\"]$", "%1")
env[key] = value
end
end
end
return env
end
-- 自动搜索 .env 文件路径
local function find_env()
local dirs = {
config.root_path .. "/lua/", -- Lua目录
config.root_path .. "/" -- 项目跟目录
}
for _, dir in ipairs(dirs) do
local path = dir .. ".env"
local f = io.open(path, "r")
if f then f:close() return path end
end
return nil
end
------------------------------------------------------------
-- 主逻辑
------------------------------------------------------------
local function load_env()
if env_cache then return env_cache end
local env_path = find_env()
if not env_path then
print("未找到 .env 文件,返回空表")
env_cache = {}
return env_cache
end
print("加载 .env 文件路径: " .. env_path)
local content = read_file(env_path)
env_cache = parse_env(content)
return env_cache
end
-- 类型转换
local function convert_type(value, expect_type)
if expect_type == "number" then
return tonumber(value)
elseif expect_type == "boolean" then
local v = tostring(value):lower()
return (v == "true" or v == "1" or v == "yes" or v == "on")
else
return tostring(value)
end
end
------------------------------------------------------------
-- 导出接口
------------------------------------------------------------
--- 获取单个键值
-- @param key string 键名
-- @param default any 默认值
-- @param expect_type string 期望类型: "string" | "number" | "boolean"
function M.get(key, default, expect_type)
expect_type = expect_type or "string"
local env = load_env()
local val = env[key]
if val == nil or val == "" then
return default
end
local converted = convert_type(val, expect_type)
if converted == nil then
return default
end
return converted
end
-- 获取完整表
function M.all()
return load_env()
end
return M
+121
View File
@@ -0,0 +1,121 @@
local function get_script_dir()
local lfs_ok, lfs = pcall(require, "lfs")
local source
if debug and debug.getinfo then
-- OpenResty 或标准 Lua 都适用
source = debug.getinfo(2, "S").source:sub(2)
elseif arg and arg[0] then
source = arg[0]
else
return nil
end
-- 如果是相对路径,转换为绝对路径
if not source:match("^/") then
if lfs_ok then
source = lfs.currentdir() .. "/" .. source
else
-- 没有 lfs,使用 io.popen("pwd") 获取当前目录
local handle = io.popen("pwd")
local cwd = handle:read("*l")
handle:close()
source = cwd .. "/" .. source
end
end
-- 提取目录
local dir = source:match("(.*/)")
return dir
end
package.path = package.path .. ";"..get_script_dir().."module/?.lua;"
-- 如过不是以/app/开头的请求,不进行QPS控制
local request_uri = ngx.var.request_uri
if not string.match(request_uri, "^/app/") then
return
end
-- 获取请求方法
local method = ngx.req.get_method()
method=tostring(method)
-- 获取请求路径
local path = string.match(request_uri, "([^?]*)")
path=tostring(path)
local env = require("load_env")
-- 连接Redis
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000) -- 1 秒超时
local ok, err = red:connect(env.get("REDIS_HOST","127.0.0.1"), env.get("REDIS_PORT",6379,"number"))
if not ok then
ngx.log(ngx.ERR,"Connection to Redis failed: ", err)
return
end
local database = env.get("REDIS_DATABASE",2,"number")
-- 选择数据库
local ok,err = red:select(database)
if not ok then
ngx.log(ngx.ERR,"Failed to select Redis database ",database,": ", err)
return
end
-- 获取请求限制
local limit_key="QPS:"..method..":"..path
local limit, err = red:get(limit_key)
limit = tonumber(limit)
-- 如果没有设置限制,则不进行QPS控制
if not limit then
return
end
-- 获取请求头中的Authorization
local authorization=ngx.var.http_authorization
if not authorization then
ngx.log(ngx.ERR,"The request header does not include Authorization: ",authorization)
return ngx.exit(401)
end
-- 拼接用户key
authorization=tostring(authorization)
local user_key = limit_key..":"..authorization
-- 获取用户请求次数
local requests, err = red:get(user_key)
requests = tonumber(requests)
if not requests then
requests = 0
end
-- 如果请求次数超过限制,则返回503
if requests > limit then
ngx.log(ngx.ERR,limit,"qps/s, Authorization: ",authorization)
return ngx.exit(429)
end
-- 原子增加请求次数
local ok, err = red:incr(user_key)
if not ok then
ngx.log(ngx.ERR,"Redis increment operation failed: ", err)
return
end
local ok, err = red:expire(user_key, 1)
if not ok then
ngx.log(ngx.ERR,"Failed to set expiration for Redis key: ", err)
return
end
-- 释放连接(连接池实现)
local ok, err = red:set_keepalive(10000, 100)
if not ok then
ngx.log(ngx.ERR,"Failed to set keepalive: ", err)
return
end
+38
View File
@@ -0,0 +1,38 @@
local function get_script_dir()
local lfs_ok, lfs = pcall(require, "lfs")
local source
if debug and debug.getinfo then
-- OpenResty 或标准 Lua 都适用
source = debug.getinfo(2, "S").source:sub(2)
elseif arg and arg[0] then
source = arg[0]
else
return nil
end
-- 如果是相对路径,转换为绝对路径
if not source:match("^/") then
if lfs_ok then
source = lfs.currentdir() .. "/" .. source
else
-- 没有 lfs,使用 io.popen("pwd") 获取当前目录
local handle = io.popen("pwd")
local cwd = handle:read("*l")
handle:close()
source = cwd .. "/" .. source
end
end
-- 提取目录
local dir = source:match("(.*/)")
return dir
end
package.path = package.path .. ";"..get_script_dir().."module/?.lua;"
local env = require("load_env")
print("ENV文件加载成功,服务名称:"..env.get("SERVER_NAME"))
-- 测试
print(get_script_dir())