356 lines
11 KiB
Bash
Executable File
356 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
# Logseq Installer - Installiert und aktualisiert Logseq auf Linux-Systemen
|
|
# Autor: Tim Peters
|
|
# Repository: https://git.tim-peters.org/Tim/Logseq-Installer
|
|
|
|
# =============================================================================
|
|
# KONSTANTEN UND KONFIGURATION
|
|
# =============================================================================
|
|
|
|
# Farb-Codes für die Terminal-Ausgabe
|
|
readonly COLOR_RED=$(tput setaf 1)
|
|
readonly COLOR_GREEN=$(tput setaf 2)
|
|
readonly COLOR_YELLOW=$(tput setaf 3)
|
|
readonly COLOR_RESET=$(tput sgr0)
|
|
|
|
# Standardwerte
|
|
readonly ALLOW_ROOT_DEFAULT=false
|
|
|
|
# Pfad-Konstanten
|
|
readonly INSTALL_DIR="${HOME}/.local/bin"
|
|
readonly DESKTOP_DIR="${HOME}/.local/share/applications"
|
|
readonly SYMLINK_PATH="${INSTALL_DIR}/Logseq"
|
|
|
|
# URLs
|
|
readonly LOGO_URL="https://raw.githubusercontent.com/logseq/logseq/master/resources/icons/logseq.png"
|
|
readonly RELEASE_API_URL="https://github.com/logseq/logseq/releases/latest"
|
|
readonly DOWNLOAD_BASE_URL="https://github.com/logseq/logseq/releases/download"
|
|
|
|
# Dateinamen-Muster
|
|
readonly APP_NAME="Logseq"
|
|
readonly APP_IMAGE_PATTERN="Logseq-linux-x64-*.AppImage"
|
|
readonly DESKTOP_FILE="${DESKTOP_DIR}/logseq.desktop"
|
|
readonly ICON_FILE="${DESKTOP_DIR}/logseq.png"
|
|
|
|
# =============================================================================
|
|
# GLOBALE VARIABLEN
|
|
# =============================================================================
|
|
|
|
ALLOW_ROOT="${ALLOW_ROOT_DEFAULT}"
|
|
VERSION_LATEST=""
|
|
VERSION_CURRENT=""
|
|
FILENAME_LOGSEQ=""
|
|
|
|
# =============================================================================
|
|
# FEHLERBEHANDLUNG
|
|
# =============================================================================
|
|
|
|
# ERR-Trap: Wird bei jedem unbehandelten Befehlsfehler aktiviert
|
|
trap 'handle_error' ERR
|
|
|
|
# Wird durch die ERR-Trap bei unbehandelten Fehlern aufgerufen
|
|
handle_error() {
|
|
local exit_code=$?
|
|
err "Ein unerwarteter Fehler ist aufgetreten (Exit-Code: ${exit_code})"
|
|
cat <<-EOT
|
|
Bitte hilf mit, dieses Skript zu verbessern, und sende einen
|
|
Fehlerbericht per E-Mail an logseq@testorakel.de
|
|
EOT
|
|
exit "${exit_code}"
|
|
}
|
|
|
|
# =============================================================================
|
|
# AUSGABE-HELPER
|
|
# =============================================================================
|
|
|
|
# Gibt eine Fehlermeldung in Rot aus und beendet das Skript mit Code 1
|
|
err() {
|
|
echo "${COLOR_RED}$*${COLOR_RESET}" >&2
|
|
exit 1
|
|
}
|
|
|
|
# Gibt eine Warnung in Gelb auf stderr aus (ohne Abbruch)
|
|
warn() {
|
|
echo "${COLOR_YELLOW}$*${COLOR_RESET}" >&2
|
|
}
|
|
|
|
# Gibt eine Erfolgsmeldung in Grün aus
|
|
success() {
|
|
echo "${COLOR_GREEN}$*${COLOR_RESET}"
|
|
}
|
|
|
|
# Gibt eine Info-Meldung aus (ohne Farbcode)
|
|
info() {
|
|
echo "$*"
|
|
}
|
|
|
|
# =============================================================================
|
|
# ALLGEMEINE HILFSFUNKTIONEN
|
|
# =============================================================================
|
|
|
|
# Zeigt das ASCII-Logo an
|
|
show_logo() {
|
|
echo -n "${COLOR_GREEN}"
|
|
cat <<-'EOT'
|
|
.____
|
|
| | ____ ____ ______ ____ ______
|
|
| | / _ \ / ___\/ ___// __ \/ ____/
|
|
| |__( <_> ) /_/ >___ \\ ___< <_| |
|
|
|_______ \____/\___ /____ >\___ >__ |
|
|
\/ /_____/ \/ \/ |__|
|
|
EOT
|
|
|
|
echo -n "${COLOR_YELLOW}"
|
|
cat <<-'EOT'
|
|
.___ __ .__ .__
|
|
| | ____ _______/ |______ | | | | ___________
|
|
| |/ \ / ___/\ __\__ \ | | | | _/ __ \_ __ \
|
|
| | | \\___ \ | | / __ \| |_| |_\ ___/| | \/
|
|
|___|___| /____ > |__| (____ /____/____/\___ >__|
|
|
\/ \/ \/ \/
|
|
EOT
|
|
echo -n "${COLOR_RESET}"
|
|
}
|
|
|
|
# Zeigt die Hilfe an; optional wird vorher eine Fehlermeldung ausgegeben
|
|
show_help() {
|
|
if [[ $# -gt 0 ]]; then
|
|
echo "$*"
|
|
echo ""
|
|
fi
|
|
|
|
cat <<-EOT
|
|
${APP_NAME} Installer
|
|
================
|
|
Erlaubte Optionen:
|
|
|
|
-h | --hilfe --- Zeigt diese Hilfe an
|
|
-e | --entfernen --- Deinstalliert Logseq
|
|
-r | --root --- Erlaubt die Installation als root
|
|
|
|
Geschrieben von Tim Peters
|
|
---> https://git.tim-peters.org/Tim/Logseq-Installer
|
|
EOT
|
|
exit 1
|
|
}
|
|
|
|
# Stellt sicher, dass ein benötigter Befehl verfügbar ist
|
|
require_command() {
|
|
local cmd="$1"
|
|
command -v "${cmd}" >/dev/null 2>&1 || err "Befehl '${cmd}' nicht gefunden. Bitte installieren Sie ${cmd}."
|
|
}
|
|
|
|
# =============================================================================
|
|
# VERSIONSERMITTLUNG
|
|
# =============================================================================
|
|
|
|
# Ermittelt die neueste verfügbare Version von GitHub
|
|
get_latest_version() {
|
|
info "Ermittle neueste verfügbare Version..."
|
|
# Release-Seite abrufen und Versionsnummer aus dem Redirect-Link extrahieren
|
|
VERSION_LATEST=$(
|
|
wget -qO- "${RELEASE_API_URL}" |
|
|
grep -Po 'releases/tag/\K\d+\.\d+\.\d+' |
|
|
head -n1
|
|
)
|
|
[[ -n "${VERSION_LATEST}" ]] || err "Konnte die neueste Version nicht ermitteln."
|
|
success "Neueste Version: ${VERSION_LATEST}"
|
|
}
|
|
|
|
# Ermittelt die aktuell installierte Version anhand des neuesten AppImage
|
|
get_current_version() {
|
|
info "Ermittle installierte Version..."
|
|
local latest_appimage
|
|
# Neueste AppImage-Datei nach Änderungszeitpunkt (mtime) bestimmen
|
|
latest_appimage=$(
|
|
find "${INSTALL_DIR}" -maxdepth 1 -name "${APP_IMAGE_PATTERN}" -type f -printf '%T@ %p\n' 2>/dev/null |
|
|
sort -n |
|
|
tail -n1 |
|
|
cut -d' ' -f2-
|
|
)
|
|
|
|
if [[ -n "${latest_appimage}" ]]; then
|
|
VERSION_CURRENT=$(basename "${latest_appimage}" | grep -Po 'Logseq-linux-x64-\K\d+\.\d+\.\d+' | head -n1)
|
|
if [[ -n "${VERSION_CURRENT}" ]]; then
|
|
success "Installierte Version: ${VERSION_CURRENT}"
|
|
else
|
|
warn "Installierte Version konnte nicht bestimmt werden."
|
|
fi
|
|
else
|
|
VERSION_CURRENT=""
|
|
info "Logseq ist nicht installiert."
|
|
fi
|
|
}
|
|
|
|
# =============================================================================
|
|
# INSTALLATION & AKTUALISIERUNG
|
|
# =============================================================================
|
|
|
|
# Lädt die neueste Version herunter und installiert sie
|
|
download_and_install() {
|
|
local download_url="${DOWNLOAD_BASE_URL}/${VERSION_LATEST}/Logseq-linux-x64-${VERSION_LATEST}.AppImage"
|
|
local tmp_file
|
|
|
|
info "Lade Logseq ${VERSION_LATEST} herunter..."
|
|
mkdir -p "${INSTALL_DIR}"
|
|
|
|
# Temp-Datei im Installationsverzeichnis anlegen, damit mv kein Dateisystem-Wechsel benötigt
|
|
tmp_file=$(mktemp -p "${INSTALL_DIR}")
|
|
|
|
wget --show-progress -qO "${tmp_file}" "${download_url}" || err "Download fehlgeschlagen."
|
|
|
|
FILENAME_LOGSEQ=$(basename "${download_url}")
|
|
mv -f "${tmp_file}" "${INSTALL_DIR}/${FILENAME_LOGSEQ}" || err "Verschieben der Datei fehlgeschlagen."
|
|
chmod u+x "${INSTALL_DIR}/${FILENAME_LOGSEQ}" || err "Berechtigungen setzen fehlgeschlagen."
|
|
|
|
# Alte Versionen entfernen und Symlink auf die neue Version aktualisieren
|
|
cleanup_old_versions
|
|
ln -sf "${INSTALL_DIR}/${FILENAME_LOGSEQ}" "${SYMLINK_PATH}" || err "Symlink erstellen fehlgeschlagen."
|
|
success "Logseq ${VERSION_LATEST} erfolgreich installiert."
|
|
}
|
|
|
|
# Entfernt alte AppImage-Versionen bis auf die aktuell installierte
|
|
cleanup_old_versions() {
|
|
local current_file="${INSTALL_DIR}/${FILENAME_LOGSEQ}"
|
|
# Alle AppImages außer der aktuellen Datei löschen
|
|
find "${INSTALL_DIR}" -maxdepth 1 -name "${APP_IMAGE_PATTERN}" -type f ! -path "${current_file}" -delete 2>/dev/null || true
|
|
}
|
|
|
|
# Erstellt den Desktop-Eintrag für das Startmenü
|
|
create_desktop_entry() {
|
|
info "Erstelle Desktop-Eintrag..."
|
|
|
|
# Icon herunterladen falls nicht vorhanden
|
|
if [[ ! -f "${ICON_FILE}" ]]; then
|
|
info "Lade Icon herunter..."
|
|
wget -qO "${ICON_FILE}" "${LOGO_URL}" || warn "Icon konnte nicht heruntergeladen werden."
|
|
fi
|
|
|
|
cat > "${DESKTOP_FILE}" <<-EOF
|
|
[Desktop Entry]
|
|
Encoding=UTF-8
|
|
Name=Logseq
|
|
Comment=Wissensmanagement mit Logseq
|
|
Exec=${INSTALL_DIR}/${FILENAME_LOGSEQ} --no-sandbox
|
|
Icon=${ICON_FILE}
|
|
Type=Application
|
|
Categories=Office;
|
|
X-GNOME-SingleWindow=true
|
|
SingleMainWindow=true
|
|
EOF
|
|
|
|
update-desktop-database "${DESKTOP_DIR}" 2>/dev/null || true
|
|
success "Desktop-Eintrag erstellt."
|
|
}
|
|
|
|
# Deinstalliert Logseq vollständig
|
|
uninstall_logseq() {
|
|
info "Deinstalliere Logseq..."
|
|
|
|
# AppImage(s) und Symlink entfernen
|
|
rm -f "${SYMLINK_PATH}"
|
|
rm -f "${INSTALL_DIR}"/Logseq-linux-x64-*.AppImage
|
|
|
|
# Desktop-Eintrag und Icon entfernen
|
|
rm -f "${DESKTOP_FILE}" "${ICON_FILE}"
|
|
|
|
update-desktop-database "${DESKTOP_DIR}" 2>/dev/null || true
|
|
|
|
success "Logseq wurde vollständig deinstalliert."
|
|
exit 0
|
|
}
|
|
|
|
# Prüft, ob Logseq gerade läuft (Update nur bei beendeter Instanz)
|
|
check_running() {
|
|
# pgrep-Flags: -i (case-insensitive), -f (volle Kommandozeile),
|
|
# -c (Anzahl Treffer), -x (exakte Übereinstimmung der Kommandozeile)
|
|
if pgrep -ifcx "${SYMLINK_PATH}" >/dev/null; then
|
|
err "Logseq läuft noch. Bitte beenden Sie Logseq vor dem Update."
|
|
fi
|
|
}
|
|
|
|
# =============================================================================
|
|
# KOMMANDOZEILEN-ARGUMENTE & ROOT-PRÜFUNG
|
|
# =============================================================================
|
|
|
|
# Parst Kommandozeilenargumente (kurz und lang)
|
|
parse_arguments() {
|
|
local optspec=":her-:"
|
|
local OPT OPTARG
|
|
|
|
while getopts "${optspec}" OPT; do
|
|
[[ "${OPT}" == " " ]] && continue
|
|
|
|
# Lange Option (--wort oder --wort=wert) auflösen
|
|
if [[ "${OPT}" == "-" ]]; then
|
|
OPT="${OPTARG%%=*}"
|
|
OPTARG="${OPTARG#"${OPT}"}"
|
|
OPTARG="${OPTARG#=}"
|
|
fi
|
|
|
|
case "${OPT}" in
|
|
h | hilfe) show_help ;;
|
|
e | entfernen) uninstall_logseq ;;
|
|
r | root) ALLOW_ROOT=true ;;
|
|
\?) show_help "Unbekannte Option: -${OPTARG}" ;;
|
|
*) show_help "Unbekannte Option: --${OPT}" ;;
|
|
esac
|
|
done
|
|
shift $((OPTIND - 1))
|
|
}
|
|
|
|
# Verhindert die Ausführung als root, außer wenn explizit erlaubt
|
|
check_root_permissions() {
|
|
if [[ "$(whoami)" == "root" && "${ALLOW_ROOT}" == "false" ]]; then
|
|
show_help "Die Installation sollte nicht als root erfolgen (Option -r/--root erlaubt es)."
|
|
fi
|
|
}
|
|
|
|
# =============================================================================
|
|
# MAIN
|
|
# =============================================================================
|
|
|
|
main() {
|
|
# Abhängigkeiten prüfen
|
|
require_command "wget"
|
|
require_command "pgrep"
|
|
require_command "find"
|
|
|
|
# Kommandozeilenargumente parsen
|
|
parse_arguments "$@"
|
|
|
|
# Root-Prüfung
|
|
check_root_permissions
|
|
|
|
# Logo anzeigen
|
|
show_logo
|
|
|
|
# Versionen ermitteln
|
|
get_latest_version
|
|
get_current_version
|
|
|
|
# Versionsvergleich
|
|
info "Neueste verfügbare Version...... ${COLOR_GREEN}${VERSION_LATEST}${COLOR_RESET}"
|
|
info "Derzeit installierte Version... ${COLOR_GREEN}${VERSION_CURRENT:-${COLOR_RED}Logseq ist nicht installiert${COLOR_RESET}}"
|
|
|
|
# Bereits aktuell?
|
|
if [[ "${VERSION_CURRENT}" == "${VERSION_LATEST}" ]]; then
|
|
success "Logseq ist bereits auf dem neuesten Stand."
|
|
exit 0
|
|
fi
|
|
|
|
# Prüfen ob Logseq läuft
|
|
check_running
|
|
|
|
# Installation durchführen
|
|
download_and_install
|
|
create_desktop_entry
|
|
|
|
success "Logseq wurde erfolgreich installiert/aktualisiert."
|
|
}
|
|
|
|
# =============================================================================
|
|
# EINSTIEGSPUNKT
|
|
# =============================================================================
|
|
|
|
main "$@" |