Files
2025-02-02 20:41:04 +08:00

463 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
# 禁用辅助功能支持,减少 zenity 的报错输出
export GTK_A11Y=none
# 读取 AppImage 文件地址
APPIMAGE_FILE=`zenity --file-selection --title="选择 AppImage 文件"`
case $? in
0)
echo "[STATUS] APPIMAGE_FILE=${APPIMAGE_FILE}"
;;
1)
echo "[WARN] 没有选择文件"
exit 1
;;
-1)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 创建工作目录
APPIMAGE_NAME=`basename "${APPIMAGE_FILE}"`
WORK_DIR=`realpath "./${APPIMAGE_NAME%.*}"`
mkdir "${WORK_DIR}"
case $? in
0)
echo "[STATUS] 工作目录创建成功"
echo "[STATUS] APPIMAGE_NAME=${APPIMAGE_NAME}"
echo "[STATUS] WORK_DIR=${WORK_DIR}"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 复制 AppImage 到工作目录
cp "${APPIMAGE_FILE}" "${WORK_DIR}"
case $? in
0)
echo "[STATUS] 复制 AppImage 到工作目录成功"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 赋予 AppImage 可执行权限
PASSWORD=`zenity --entry \
--title="输入密码" \
--text="输入 sudo 密码以赋权 AppImage 文件" \
--entry-text "" \
--hide-text`
case $? in
0)
echo "[STATUS] PASSWORD=${PASSWORD}"
;;
1)
echo "[WARN] 取消输入密码"
exit 1
;;
-1)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
(echo "${PASSWORD}" | sudo -S chmod +x "${WORK_DIR}/${APPIMAGE_NAME}")
case $? in
0)
echo "[STATUS] AppImage 可执行权限已经成功赋予"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 进入工作目录
cd "${WORK_DIR}"
case $? in
0)
echo "[STATUS] 进入工作目录成功"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 解压 AppImage
"./${APPIMAGE_NAME}" --appimage-extract > /dev/null
case $? in
0)
echo "[STATUS] AppImage 解压成功"
rm "./${APPIMAGE_NAME}"
echo "[STATUS] 复制到工作目录的 AppImage 删除成功"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 获取必要的 deb 打包信息
zenity --forms --title="获取必要信息" \
--text="输入必要的 deb 打包信息" \
--separator=$'\n' \
--add-entry="包名" \
--add-entry="版本" \
--add-entry="作者" \
--add-entry="邮箱" > info.txt
case $? in
0)
echo "[STATUS] 必要的 deb 打包信息已写入到 info.txt"
;;
1)
echo "[WARN] 取消输入 deb 打包信息"
exit 1
;;
-1)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
mapfile -t INFO_LINES < "./info.txt"
for i in "${!INFO_LINES[@]}"; do
trimmed_line=$(echo "${INFO_LINES[$i]}" | sed 's/^[ \t]*//;s/[ \t]*$//')
INFO_LINES[$i]="$trimmed_line"
done
case $? in
0)
echo "[STATUS] 已读取 info.txt 中存储的信息到 INFO_LINES"
echo "[STATUS] INFO_LINES="${INFO_LINES[@]}""
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
ID="${INFO_LINES[0]}"
VERSION="${INFO_LINES[1]}"
MAINTAINER="${INFO_LINES[2]}"
MAIL="${INFO_LINES[3]}"
echo "[STATUS] ID=${ID}"
echo "[STATUS] VERSION=${VERSION}"
echo "[STATUS] MAINTAINER=${MAINTAINER}"
echo "[STATUS] MAIL=${MAIL}"
# 构建符合 uos 的 deb 打包标准的目录结构
{
mkdir "./${ID}/"
mkdir "./${ID}/DEBIAN/"
touch "./${ID}/DEBIAN/control"
mkdir -p "./${ID}/opt/apps/${ID}/entries/applications/"
mkdir -p "./${ID}/opt/apps/${ID}/entries/icons/hicolor/512x512/apps/"
mkdir -p "./${ID}/opt/apps/${ID}/entries/icons/hicolor/scalable/apps/"
mkdir "./${ID}/opt/apps/${ID}/files/"
touch "./${ID}/opt/apps/${ID}/info"
}
case $? in
0)
echo "[STATUS] 符合 uos 的 deb 打包标准的目录结构构建成功"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 写入 info 文件
echo -e "{\n \"appid\": \"${ID}\"\n}" > "./${ID}/opt/apps/${ID}/info"
case $? in
0)
echo "[STATUS] 写入 info 文件成功"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 移动 AppImage 解压后的 squashfs-root/ 内容到 bin/
mv "./squashfs-root/" "./${ID}/opt/apps/${ID}/files/"
mv "./${ID}/opt/apps/${ID}/files/squashfs-root/" "./${ID}/opt/apps/${ID}/files/bin/"
case $? in
0)
echo "[STATUS] 移动 AppImage 解压后的 squashfs-root/ 内容到 bin/ 成功"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 创建并写入内容到 start.sh 文件
touch "./${ID}/opt/apps/${ID}/files/start.sh"
{
printf "#!/usr/bin/env bash\n"
printf 'if [ -n "$1" ]; then'"\n"
printf ' file_path="$1"'"\n"
printf ' file_path="${file_path#file://}"'"\n"
printf " /opt/apps/${ID}/files/bin/AppRun "'"${file_path}"'"\n"
printf "else\n"
printf " /opt/apps/${ID}/files/bin/AppRun\n"
printf "fi\n"
} > "./${ID}/opt/apps/${ID}/files/start.sh"
case $? in
0)
echo "[STATUS] 创建并写入内容到 start.sh 文件成功"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 寻找 .desktop 文件
DESKTOP_FILE="$(find "./${ID}/opt/apps/${ID}/files/bin/" -type f -name "*.desktop" -print -quit)"
DESKTOP_FILE="$(readlink -f "${DESKTOP_FILE}")"
case $? in
0)
echo "[STATUS] DESKTOP_FILE=${DESKTOP_FILE}"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 将 .desktop 文件复制到 applications/ 并修改文件名
cp "${DESKTOP_FILE}" "./${ID}/opt/apps/${ID}/entries/applications/${ID}.desktop"
case $? in
0)
echo "[STATUS] 成功将 ${DESKTOP_FILE_NAME} 文件复制到 applications/ 并修改文件名为 ${ID}.desktop"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 修改 .desktop 文件的 Exec 字段
sed -i "s#^Exec=.*#Exec=/opt/apps/${ID}/files/start.sh %f#" "./${ID}/opt/apps/${ID}/entries/applications/${ID}.desktop"
case $? in
0)
echo "[STATUS] 成功修改 .desktop 文件的 Exec 字段"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 获取 Installed-Size
INSTALLED_SIZE=$(du -sk "./${ID}/opt/apps/${ID}/" | awk '{print $1}')
case $? in
0)
echo "[STATUS] INSTALL_SIZE=${INSTALLED_SIZE}"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 获取 icon 文件名
ICON_FIELD=$(grep -iE '^Icon=' "${DESKTOP_FILE}" | cut -d= -f2 | tr -d ' \n\r')
IMAGE_SUFFIXES="svg|png|xpm"
if [[ "${ICON_FIELD}" =~ \.(${IMAGE_SUFFIXES})$ ]]; then
echo "[STATUS] ICON_FIELD=${ICON_FIELD}"
else
ICON_FIELD="${ICON_FIELD}.suffix"
echo "[STATUS] ICON_FIELD=${ICON_FIELD}"
fi
ICON_FILE="$(basename "$ICON_FIELD")"
ICON_NAME="${ICON_FILE%.*}"
echo "[STATUS] ICON_FILE=${ICON_FILE}"
echo "[STATUS] ICON_NAME=${ICON_NAME}"
# 将 icon 文件放到指定位置
SVG_FILE_NAME="${ICON_NAME}.svg"
PNG_FILE_NAME="${ICON_NAME}.png"
SVG_FILE="./${ID}/opt/apps/${ID}/files/bin/${SVG_FILE_NAME}"
PNG_FILE="./${ID}/opt/apps/${ID}/files/bin/${PNG_FILE_NAME}"
if [[ -L "${SVG_FILE}" || -e "${SVG_FILE}" ]]; then
resolved_svg=$(readlink -f "${SVG_FILE}")
cp -f "${resolved_svg}" "./${ID}/opt/apps/${ID}/entries/icons/hicolor/scalabel/apps/${ID}.svg"
echo "[STATUS] SVG 图标已复制到指定位置"
elif [[ -L "${PNG_FILE}" || -e "${PNG_FILE}" ]]; then
resolved_png=$(readlink -f "${PNG_FILE}")
../SR-PNG "${resolved_png}" "./${ID}/opt/apps/${ID}/entries/icons/hicolor/512x512/apps/${ID}.png"
echo "[STATUS] PNG 图标已超分辨率到 512x512 并复制到指定位置"
else
echo "[WARN] 没有找到图标文件"
fi
# 修改 .desktop 文件的 Icon 字段
sed -i "s#^Icon=.*#Icon=${ID}#" "./${ID}/opt/apps/${ID}/entries/applications/${ID}.desktop"
case $? in
0)
echo "[STATUS] 成功修改 .desktop 文件的 Icon 字段"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 从 .desktop 文件的 comment 获取 description
DESCRIPTION="$(grep '^Comment=' "${DESKTOP_FILE}" | awk -F'=' '{print $2}')"
DESCRIPTION="${DESCRIPTION##*([[:space:]])}"
DESCRIPTION="${DESCRIPTION%%*([[:space:]])}"
case $? in
0)
echo "[STATUS] DESCRIPTION=${DESCRIPTION}"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# TODO 从 .desktop 文件的 Categories 解析 section
CATEGORIES="$(grep -Ei '^Categories=' "${DESKTOP_FILE}" | cut -d= -f2 | tr -d ' ')"
case $? in
0)
echo "[STATUS] CATEGORIES=${CATEGORIES}"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
map_category_to_section() {
case "$1" in
"Development") echo "devel" ;;
"Utility") echo "utils" ;;
"Game") echo "games" ;;
"Education") echo "edu" ;;
"Network") echo "net" ;;
"Graphics") echo "graphics" ;;
"AudioVideo") echo "sound" ;;
"Science") echo "science" ;;
"Settings") echo "admin" ;;
"System") echo "admin" ;;
"Office") echo "text" ;;
*) echo "utils" ;;
esac
}
CATEGORIES=$(echo "${CATEGORIES}" | sed 's/;\+/;/g; s/;$//')
IFS=';' read -ra CATEGORY_ARRAY <<< "${CATEGORIES}"
SECTION=""
for category in "${CATEGORY_ARRAY[@]}"; do
if [[ -n "${category}" ]]; then
mapped_section="$(map_category_to_section "${category}")"
if [[ -n "${mapped_section}" ]]; then
SECTION="${mapped_section}"
break
fi
fi
done
case $? in
0)
echo "[STATUS] SECTION="${SECTION}""
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 写入 control 文件
{
printf "Package: ${ID}\n"
printf "Version: ${VERSION}\n"
printf "Section: ${SECTION}\n"
printf "Priority: optional\n"
printf "Architecture: amd64\n"
printf "Installed-Size: ${INSTALLED_SIZE}\n"
printf "Maintainer: ${MAINTAINER} <${MAIL}>\n"
printf "Description: ${DESCRIPTION}\n"
} > "./${ID}/DEBIAN/control"
case $? in
0)
echo "[STATUS] 写入 control 文件成功"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 更改用户组和权限
echo "${PASSWORD}" | sudo -S chown -R root:root "./${ID}"
echo "${PASSWORD}" | sudo -S chmod -R 755 "./${ID}"
case $? in
0)
echo "[STATUS] 更改用户组和权限成功"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac
# 生成 deb 包
printf "[STATUS] "
zenity --info --text="正在生成 deb 包,生成结束后会弹出信息框,请耐心等待" &
dpkg-deb --build "./${ID}" . &
pid=$!
wait ${pid}
case $? in
0)
echo "[STATUS] 生成 deb 包成功"
zenity --info --text="生成 deb 包成功"
;;
*)
echo "[ERROR] 发生意外错误"
exit -1
;;
esac