Files
AppImage2Deb-For-Deepin/Zenity-Edition/AppImage2Deb.sh
2025-02-01 21:12:55 +08:00

452 lines
11 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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/"
DESKTOP_FILE_NAME="$(ls "./${ID}/opt/apps/${ID}/entries/applications/")"
mv "./${ID}/opt/apps/${ID}/entries/applications/${DESKTOP_FILE_NAME}" "./${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 文件
PNG_FILE_NAME="$(basename ${DESKTOP_FILE_NAME} .desktop).png"
SVG_FILE_NAME="$(basename ${DESKTOP_FILE_NAME} .desktop).svg"
PNG_FILE="./${ID}/opt/apps/${ID}/files/bin/${PNG_FILE_NAME}"
SVG_FILE="./${ID}/opt/apps/${ID}/files/bin/${SVG_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
# 处理 PNG符号链接或普通文件
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