diff --git a/ct/navidrome.sh b/ct/navidrome.sh new file mode 100644 index 0000000..dd0ed0d --- /dev/null +++ b/ct/navidrome.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/navidrome/navidrome + +APP="Navidrome" +var_tags="${var_tags:-music}" +var_disk="${var_disk:-7}" +var_cpu="${var_cpu:-4}" +var_ram="${var_ram:-2048}" +var_os="${var_os:-debian}" +var_version="${var_version:-12}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + if [[ ! -d /var/lib/navidrome ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + RELEASE=$(curl -s https://api.github.com/repos/hudikhq/hoodik/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Stopping Services" + systemctl stop hoodik + msg_ok "Services Stopped" + + msg_info "Updating ${APP} to ${RELEASE}" + cd /opt + if [ -d hoodik_bak ]; then + rm -rf hoodik_bak + fi + mv hoodik hoodik_bak + curl -fsSL "https://github.com/hudikhq/hoodik/archive/refs/tags/${RELEASE}.zip" + unzip -q ${RELEASE}.zip + mv hoodik-${RELEASE} /opt/hoodik + cd /opt/hoodik + cargo update -q + cargo build -q --release + msg_ok "Updated Hoodik" + + msg_info "Starting Services" + systemctl start hoodik + msg_ok "Started Services" + + msg_info "Cleaning Up" + rm -R /opt/${RELEASE}.zip + rm -R /opt/hoodik_bak + msg_ok "Cleaned" + msg_ok "Updated Successfully" + else + msg_ok "No update required. ${APP} is already at ${RELEASE}" + fi + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8088${CL}" diff --git a/frontend/src/components/CommandMenu.tsx b/frontend/src/components/CommandMenu.tsx index 166b87a..3b48f79 100644 --- a/frontend/src/components/CommandMenu.tsx +++ b/frontend/src/components/CommandMenu.tsx @@ -8,7 +8,7 @@ import { } from "@/components/ui/command"; import { basePath } from "@/config/siteConfig"; import { fetchCategories } from "@/lib/data"; -import { Category } from "@/lib/types"; +import { Category, Script } from "@/lib/types"; import { cn } from "@/lib/utils"; import Image from "next/image"; import { useRouter } from "next/navigation"; @@ -16,6 +16,7 @@ import React from "react"; import { Badge } from "./ui/badge"; import { Button } from "./ui/button"; import { DialogTitle } from "./ui/dialog"; +import { Sparkles } from "lucide-react"; // <- Hinzugefügt export const formattedBadge = (type: string) => { switch (type) { @@ -31,11 +32,19 @@ export const formattedBadge = (type: string) => { return null; }; +// random Script +function getRandomScript(categories: Category[]): Script | null { + const allScripts = categories.flatMap((cat) => cat.scripts || []); + if (allScripts.length === 0) return null; + const idx = Math.floor(Math.random() * allScripts.length); + return allScripts[idx]; +} + export default function CommandMenu() { const [open, setOpen] = React.useState(false); const [links, setLinks] = React.useState([]); - const router = useRouter(); const [isLoading, setIsLoading] = React.useState(false); + const router = useRouter(); React.useEffect(() => { const down = (e: KeyboardEvent) => { @@ -45,7 +54,6 @@ export default function CommandMenu() { setOpen((open) => !open); } }; - document.addEventListener("keydown", down); return () => document.removeEventListener("keydown", down); }, []); @@ -63,23 +71,58 @@ export default function CommandMenu() { }); }; + const openRandomScript = async () => { + if (links.length === 0) { + setIsLoading(true); + try { + const categories = await fetchCategories(); + setLinks(categories); + const randomScript = getRandomScript(categories); + if (randomScript) { + router.push(`/scripts?id=${randomScript.slug}`); + } + } finally { + setIsLoading(false); + } + } else { + const randomScript = getRandomScript(links); + if (randomScript) { + router.push(`/scripts?id=${randomScript.slug}`); + } + } + }; + return ( <> - +
+ + + +
+ Search scripts diff --git a/install/navidrome-install.sh b/install/navidrome-install.sh new file mode 100644 index 0000000..8ad196b --- /dev/null +++ b/install/navidrome-install.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/navidrome/navidrome + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y \ + ffmpeg +msg_ok "Installed Dependencies" + +msg_info "Installing Navidrome" +RELEASE=$(curl -fsSL https://api.github.com/repos/navidrome/navidrome/releases/latest | grep "tag_name" | awk -F '"' '{print $4}') +TMP_DEB=$(mktemp --suffix=.deb) +curl -fsSL -o "${TMP_DEB}" "https://github.com/navidrome/navidrome/releases/download/${RELEASE}/navidrome_${RELEASE#v}_linux_amd64.deb" +systemctl enable -q --now navidrome.service +$STD apt-get install -y "${TMP_DEB}" +msg_ok "Installed hoodik" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -f "${TMP_DEB}" +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned"