mirror of
https://github.com/whyour/qinglong.git
synced 2026-01-27 18:35:40 +08:00
Add support for GitHub URLs and requirements files in Python dependencies
Co-authored-by: whyour <22700758+whyour@users.noreply.github.com>
This commit is contained in:
parent
e28f746294
commit
f526d3f972
|
|
@ -536,11 +536,26 @@ export async function setSystemTimezone(timezone: string): Promise<boolean> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getGetCommand(type: DependenceTypes, name: string): string {
|
export function getGetCommand(type: DependenceTypes, name: string): string {
|
||||||
|
const trimmedName = name.trim();
|
||||||
|
|
||||||
|
// For Python dependencies installed from GitHub or requirements files,
|
||||||
|
// we can't reliably check if they're installed, so skip the check
|
||||||
|
if (type === DependenceTypes.python3) {
|
||||||
|
if (trimmedName.match(/^(https?:\/\/|git\+)/i) ||
|
||||||
|
trimmedName.match(/\.(txt|in)$/i) ||
|
||||||
|
trimmedName.includes('requirements') ||
|
||||||
|
trimmedName.endsWith('pyproject.toml')) {
|
||||||
|
// Return a command that will always indicate not installed
|
||||||
|
// This ensures GitHub URLs and requirements files are always installed
|
||||||
|
return 'echo ""';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const baseCommands = {
|
const baseCommands = {
|
||||||
[DependenceTypes.nodejs]: `pnpm ls -g | grep "${name}" | head -1`,
|
[DependenceTypes.nodejs]: `pnpm ls -g | grep "${trimmedName}" | head -1`,
|
||||||
[DependenceTypes.python3]: `
|
[DependenceTypes.python3]: `
|
||||||
python3 -c "exec('''
|
python3 -c "exec('''
|
||||||
name='${name}'
|
name='${trimmedName}'
|
||||||
try:
|
try:
|
||||||
from importlib.metadata import version
|
from importlib.metadata import version
|
||||||
print(version(name))
|
print(version(name))
|
||||||
|
|
@ -550,7 +565,7 @@ except:
|
||||||
spec=u.find_spec(name)
|
spec=u.find_spec(name)
|
||||||
print(name if spec else '')
|
print(name if spec else '')
|
||||||
''')"`,
|
''')"`,
|
||||||
[DependenceTypes.linux]: `apk info -es ${name}`,
|
[DependenceTypes.linux]: `apk info -es ${trimmedName}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
return baseCommands[type];
|
return baseCommands[type];
|
||||||
|
|
@ -570,7 +585,27 @@ export function getInstallCommand(type: DependenceTypes, name: string): string {
|
||||||
command = `${command} --prefix=${PYTHON_INSTALL_DIR}`;
|
command = `${command} --prefix=${PYTHON_INSTALL_DIR}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${command} ${name.trim()}`;
|
const trimmedName = name.trim();
|
||||||
|
|
||||||
|
// Handle different installation methods for Python
|
||||||
|
if (type === DependenceTypes.python3) {
|
||||||
|
// Check if it's a GitHub URL (support both git+ and direct URLs)
|
||||||
|
if (trimmedName.match(/^(https?:\/\/|git\+)/i)) {
|
||||||
|
return `${command} ${trimmedName}`;
|
||||||
|
}
|
||||||
|
// Check if it's a requirements file path
|
||||||
|
if (trimmedName.match(/\.(txt|in)$/i) || trimmedName.includes('requirements')) {
|
||||||
|
return `${command} -r ${trimmedName}`;
|
||||||
|
}
|
||||||
|
// Check if it's a pyproject.toml file
|
||||||
|
if (trimmedName.endsWith('pyproject.toml')) {
|
||||||
|
// For pyproject.toml, install from the directory containing it
|
||||||
|
const dir = trimmedName.replace(/\/pyproject\.toml$/, '') || '.';
|
||||||
|
return `${command} ${dir}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${command} ${trimmedName}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUninstallCommand(
|
export function getUninstallCommand(
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,56 @@ add_cron() {
|
||||||
notify_api "$path 新增任务" "$detail"
|
notify_api "$path 新增任务" "$detail"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## 自动安装订阅仓库中的Python依赖
|
||||||
|
auto_install_python_deps() {
|
||||||
|
local repo_path="$1"
|
||||||
|
local uniq_path="$2"
|
||||||
|
|
||||||
|
echo -e "\n检测订阅仓库中的Python依赖文件...\n"
|
||||||
|
|
||||||
|
get_token
|
||||||
|
|
||||||
|
# 检查 requirements.txt
|
||||||
|
if [[ -f "${repo_path}/requirements.txt" ]]; then
|
||||||
|
echo -e "发现 requirements.txt,开始自动安装依赖...\n"
|
||||||
|
local req_file="${dir_scripts}/${uniq_path}/requirements.txt"
|
||||||
|
cp -f "${repo_path}/requirements.txt" "${req_file}"
|
||||||
|
|
||||||
|
# 调用API添加依赖安装任务
|
||||||
|
local dep_name="${uniq_path}/requirements.txt"
|
||||||
|
local currentTimeStamp=$(date +%s)
|
||||||
|
local result=$(curl -s --noproxy "*" "http://127.0.0.1:${ql_port}/open/dependencies?t=$currentTimeStamp" \
|
||||||
|
-X POST \
|
||||||
|
-H "Content-Type: application/json;charset=UTF-8" \
|
||||||
|
-H "Authorization: Bearer ${__ql_token__}" \
|
||||||
|
--data-raw "[{\"name\":\"${dep_name}\",\"type\":1,\"remark\":\"自动检测:${uniq_path} 订阅依赖\"}]" | jq -r '.code')
|
||||||
|
|
||||||
|
if [[ "$result" == "200" ]]; then
|
||||||
|
echo -e "已添加 requirements.txt 依赖安装任务\n"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查 pyproject.toml
|
||||||
|
if [[ -f "${repo_path}/pyproject.toml" ]]; then
|
||||||
|
echo -e "发现 pyproject.toml,开始自动安装依赖...\n"
|
||||||
|
local pyproject_file="${dir_scripts}/${uniq_path}/pyproject.toml"
|
||||||
|
cp -f "${repo_path}/pyproject.toml" "${pyproject_file}"
|
||||||
|
|
||||||
|
# 调用API添加依赖安装任务
|
||||||
|
local dep_name="${uniq_path}/pyproject.toml"
|
||||||
|
local currentTimeStamp=$(date +%s)
|
||||||
|
local result=$(curl -s --noproxy "*" "http://127.0.0.1:${ql_port}/open/dependencies?t=$currentTimeStamp" \
|
||||||
|
-X POST \
|
||||||
|
-H "Content-Type: application/json;charset=UTF-8" \
|
||||||
|
-H "Authorization: Bearer ${__ql_token__}" \
|
||||||
|
--data-raw "[{\"name\":\"${dep_name}\",\"type\":1,\"remark\":\"自动检测:${uniq_path} 订阅依赖\"}]" | jq -r '.code')
|
||||||
|
|
||||||
|
if [[ "$result" == "200" ]]; then
|
||||||
|
echo -e "已添加 pyproject.toml 依赖安装任务\n"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
## 更新仓库
|
## 更新仓库
|
||||||
update_repo() {
|
update_repo() {
|
||||||
local url="$1"
|
local url="$1"
|
||||||
|
|
@ -137,6 +187,10 @@ update_repo() {
|
||||||
|
|
||||||
if [[ $exit_status -eq 0 ]]; then
|
if [[ $exit_status -eq 0 ]]; then
|
||||||
echo -e "拉取 ${uniq_path} 成功...\n"
|
echo -e "拉取 ${uniq_path} 成功...\n"
|
||||||
|
|
||||||
|
# 自动检测并安装Python依赖
|
||||||
|
auto_install_python_deps "${repo_path}" "${uniq_path}"
|
||||||
|
|
||||||
diff_scripts "$repo_path" "$author" "$path" "$blackword" "$dependence" "$extensions" "$autoAddCron" "$autoDelCron"
|
diff_scripts "$repo_path" "$author" "$path" "$blackword" "$dependence" "$extensions" "$autoAddCron" "$autoDelCron"
|
||||||
else
|
else
|
||||||
echo -e "拉取 ${uniq_path} 失败,请检查日志...\n"
|
echo -e "拉取 ${uniq_path} 失败,请检查日志...\n"
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,9 @@ const DependenceModal = ({
|
||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [selectedType, setSelectedType] = useState(
|
||||||
|
DependenceTypes[defaultType as any],
|
||||||
|
);
|
||||||
|
|
||||||
const handleOk = async (values: any) => {
|
const handleOk = async (values: any) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
@ -90,7 +93,7 @@ const DependenceModal = ({
|
||||||
label={intl.get('依赖类型')}
|
label={intl.get('依赖类型')}
|
||||||
initialValue={DependenceTypes[defaultType as any]}
|
initialValue={DependenceTypes[defaultType as any]}
|
||||||
>
|
>
|
||||||
<Select>
|
<Select onChange={(value) => setSelectedType(value)}>
|
||||||
{config.dependenceTypes.map((x, i) => (
|
{config.dependenceTypes.map((x, i) => (
|
||||||
<Option key={i} value={i}>
|
<Option key={i} value={i}>
|
||||||
{x}
|
{x}
|
||||||
|
|
@ -121,11 +124,24 @@ const DependenceModal = ({
|
||||||
whitespace: true,
|
whitespace: true,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
tooltip={
|
||||||
|
selectedType === DependenceTypes.python3
|
||||||
|
? intl.get(
|
||||||
|
'Python支持多种安装方式:\n1. 包名(如:requests)\n2. GitHub链接(如:git+https://github.com/user/repo.git)\n3. requirements文件路径(如:path/to/requirements.txt)\n4. pyproject.toml文件路径',
|
||||||
|
)
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
rows={4}
|
rows={4}
|
||||||
autoSize={{ minRows: 1, maxRows: 5 }}
|
autoSize={{ minRows: 1, maxRows: 5 }}
|
||||||
placeholder={intl.get('请输入依赖名称')}
|
placeholder={
|
||||||
|
selectedType === DependenceTypes.python3
|
||||||
|
? intl.get(
|
||||||
|
'支持包名、GitHub链接、requirements.txt或pyproject.toml路径',
|
||||||
|
)
|
||||||
|
: intl.get('请输入依赖名称')
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="remark" label={intl.get('备注')}>
|
<Form.Item name="remark" label={intl.get('备注')}>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user