#!/bin/bash # GoTelegram v2.2 — Каталог шаблонов сайтов # Выбор из ~200 шаблонов, превью-ссылки, скачивание через git sparse-checkout CATALOG_FILE="$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")/templates_catalog.json" TEMPLATES_CACHE="/tmp/gotelegram_templates" # ── Загрузка каталога ──────────────────────────────────────────────────────── load_catalog() { if [ ! -f "$CATALOG_FILE" ]; then log_error "Каталог шаблонов не найден: $CATALOG_FILE" return 1 fi return 0 } # ── Категории ──────────────────────────────────────────────────────────────── get_categories() { jq -r '.categories[] | "\(.id)|\(.name)|\(.icon)|\(.templates | length)"' "$CATALOG_FILE" 2>/dev/null } get_category_name() { local cat_id="$1" jq -r ".categories[] | select(.id == \"$cat_id\") | .name" "$CATALOG_FILE" 2>/dev/null } # ── Шаблоны по категории ──────────────────────────────────────────────────── get_templates_by_category() { local cat_id="$1" jq -r ".categories[] | select(.id == \"$cat_id\") | .templates[] | \"\(.id)|\(.name)|\(.source)|\(.preview_url)\"" "$CATALOG_FILE" 2>/dev/null } # ── Информация о шаблоне ──────────────────────────────────────────────────── get_template_info() { local tpl_id="$1" jq ".categories[].templates[] | select(.id == \"$tpl_id\")" "$CATALOG_FILE" 2>/dev/null } get_template_field() { local tpl_id="$1" local field="$2" jq -r ".categories[].templates[] | select(.id == \"$tpl_id\") | .$field" "$CATALOG_FILE" 2>/dev/null } # ── Интерактивный выбор категории ──────────────────────────────────────────── select_category() { load_catalog || return 1 echo "" echo -e " ${BOLD}${WHITE}📂 Категории шаблонов сайтов:${NC}" echo -e " ${DIM}$(printf '─%.0s' {1..55})${NC}" local cats=() local i=1 while IFS='|' read -r id name icon count; do [ "$count" -eq 0 ] && continue local emoji case "$icon" in briefcase) emoji="🏢" ;; shopping-cart) emoji="🛒" ;; heart) emoji="🏥" ;; book) emoji="🎓" ;; palette) emoji="📸" ;; home) emoji="🏠" ;; utensils) emoji="🍕" ;; rocket) emoji="🎨" ;; chart-bar) emoji="🔧" ;; *) emoji="📄" ;; esac printf " ${CYAN}%2d)${NC} ${emoji} %-30s ${DIM}(%d шаблонов)${NC}\n" "$i" "$name" "$count" cats+=("$id") ((i++)) done < <(get_categories) printf " ${CYAN}%2d)${NC} 🎲 Случайный шаблон\n" "$i" echo -e " ${DIM}$(printf '─%.0s' {1..55})${NC}" echo -ne " ${WHITE}Выбор:${NC} " read -r choice # Случайный if [ "$choice" -eq "$i" ] 2>/dev/null; then local random_cat="${cats[$((RANDOM % ${#cats[@]}))]}" echo "$random_cat" return 0 fi if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -lt "$i" ]; then echo "${cats[$((choice-1))]}" return 0 fi log_error "Неверный выбор" return 1 } # ── Интерактивный выбор шаблона ────────────────────────────────────────────── select_template() { local cat_id="$1" local cat_name cat_name=$(get_category_name "$cat_id") echo "" echo -e " ${BOLD}${WHITE}📋 $cat_name — доступные шаблоны:${NC}" echo -e " ${DIM}$(printf '─%.0s' {1..60})${NC}" local tpls=() local i=1 while IFS='|' read -r id name source preview; do printf " ${CYAN}%2d)${NC} %-30s ${DIM}[%s]${NC}\n" "$i" "$name" "$source" tpls+=("$id") ((i++)) done < <(get_templates_by_category "$cat_id") if [ ${#tpls[@]} -eq 0 ]; then log_info "В этой категории нет шаблонов" return 1 fi echo -e " ${DIM}$(printf '─%.0s' {1..60})${NC}" echo -ne " ${WHITE}Выбор (1-$((i-1))):${NC} " read -r choice if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -lt "$i" ]; then local selected_id="${tpls[$((choice-1))]}" # Показываем превью show_template_preview "$selected_id" echo "$selected_id" return 0 fi log_error "Неверный выбор" return 1 } # ── Показ превью шаблона ──────────────────────────────────────────────────── show_template_preview() { local tpl_id="$1" local info info=$(get_template_info "$tpl_id") local name source preview_url repo_url description name=$(echo "$info" | jq -r '.name') source=$(echo "$info" | jq -r '.source') preview_url=$(echo "$info" | jq -r '.preview_url // empty') repo_url=$(echo "$info" | jq -r '.repo_url // empty') description=$(echo "$info" | jq -r '.description // "—"') echo "" echo -e " ${BOLD}${WHITE}🔍 Превью шаблона:${NC}" echo -e " ${DIM}$(printf '─%.0s' {1..55})${NC}" echo -e " ${WHITE}Название:${NC} $name" echo -e " ${WHITE}Источник:${NC} $source" echo -e " ${WHITE}Описание:${NC} $description" if [ -n "$preview_url" ]; then echo "" echo -e " ${GREEN}👁 Превью:${NC} ${CYAN}${preview_url}${NC}" echo -e " ${DIM}Откройте ссылку в браузере для просмотра шаблона${NC}" fi if [ -n "$repo_url" ]; then echo -e " ${DIM}📦 Репо: ${repo_url}${NC}" fi # Благодарность автору echo "" echo -e " ${MAGENTA}💜 Спасибо авторам ${source} за открытый код!${NC}" echo -e " ${DIM}$(printf '─%.0s' {1..55})${NC}" echo "" if ! confirm "Установить этот шаблон?"; then return 1 fi return 0 } # ── Скачивание шаблона ─────────────────────────────────────────────────────── download_template() { local tpl_id="$1" local output_dir="${2:-$TEMPLATES_CACHE}" local info info=$(get_template_info "$tpl_id") local repo_url sparse_path source name repo_url=$(echo "$info" | jq -r '.repo_url') sparse_path=$(echo "$info" | jq -r '.sparse_path') source=$(echo "$info" | jq -r '.source') name=$(echo "$info" | jq -r '.name') local clone_dir="$output_dir/${tpl_id}" rm -rf "$clone_dir" mkdir -p "$clone_dir" log_info "Скачивание шаблона \"$name\"..." # Для HTML5 UP — отдельный репо с папками if [ "$source" = "html5up" ]; then local tmp_clone="/tmp/html5up_clone_$$" rm -rf "$tmp_clone" # Sparse checkout git clone --depth 1 --filter=blob:none --sparse "$repo_url" "$tmp_clone" 2>/dev/null if [ $? -ne 0 ]; then # Fallback: полный clone git clone --depth 1 "$repo_url" "$tmp_clone" 2>/dev/null fi if [ -d "$tmp_clone" ]; then cd "$tmp_clone" && git sparse-checkout set "$sparse_path" 2>/dev/null if [ -d "$tmp_clone/$sparse_path" ]; then cp -r "$tmp_clone/$sparse_path"/* "$clone_dir/" fi cd - >/dev/null fi rm -rf "$tmp_clone" # Для learning-zone — один большой репо elif [ "$source" = "learning-zone" ]; then local tmp_clone="/tmp/lz_clone_$$" rm -rf "$tmp_clone" git clone --depth 1 --filter=blob:none --sparse "$repo_url" "$tmp_clone" 2>/dev/null if [ $? -ne 0 ]; then git clone --depth 1 "$repo_url" "$tmp_clone" 2>/dev/null fi if [ -d "$tmp_clone" ]; then cd "$tmp_clone" && git sparse-checkout set "$sparse_path" 2>/dev/null if [ -d "$tmp_clone/$sparse_path" ]; then cp -r "$tmp_clone/$sparse_path"/* "$clone_dir/" fi cd - >/dev/null fi rm -rf "$tmp_clone" # Для StartBootstrap — каждый шаблон в своём репо elif [ "$source" = "startbootstrap" ]; then git clone --depth 1 "$repo_url" "$clone_dir" 2>/dev/null # Убираем .git rm -rf "$clone_dir/.git" fi # Проверяем результат if [ -f "$clone_dir/index.html" ]; then log_success "Шаблон \"$name\" скачан" echo "$clone_dir" return 0 else log_error "Шаблон не содержит index.html" log_dim "Путь: $clone_dir" ls -la "$clone_dir" 2>/dev/null return 1 fi } # ── Полный интерактивный процесс выбора ────────────────────────────────────── interactive_template_selection() { load_catalog || return 1 # Выбор категории local cat_id cat_id=$(select_category) [ $? -ne 0 ] && return 1 # Выбор шаблона local tpl_id tpl_id=$(select_template "$cat_id") [ $? -ne 0 ] && return 1 # Скачивание local template_dir template_dir=$(download_template "$tpl_id") [ $? -ne 0 ] && return 1 echo "$template_dir" return 0 }