Files
gotelegram_pro/lib/templates_catalog.sh
anten-ka 64da5de1ae fix: download_template - handle StartBootstrap dist/ structure + fallback index.html search
StartBootstrap templates store production files in dist/ subdirectory.
Added: dist/ detection, recursive index.html fallback, ls output to stderr.
2026-04-06 23:03:49 +03:00

313 lines
12 KiB
Bash
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.
#!/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 "" >&2
echo -e " ${BOLD}${WHITE}📂 Категории шаблонов сайтов:${NC}" >&2
echo -e " ${DIM}$(printf '─%.0s' {1..55})${NC}" >&2
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" >&2
cats+=("$id")
((i++))
done < <(get_categories)
printf " ${CYAN}%2d)${NC} 🎲 Случайный шаблон\n" "$i" >&2
echo -e " ${DIM}$(printf '─%.0s' {1..55})${NC}" >&2
echo -ne " ${WHITE}Выбор:${NC} " >&2
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 "" >&2
echo -e " ${BOLD}${WHITE}📋 $cat_name — доступные шаблоны:${NC}" >&2
echo -e " ${DIM}$(printf '─%.0s' {1..60})${NC}" >&2
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" >&2
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}" >&2
echo -ne " ${WHITE}Выбор (1-$((i-1))):${NC} " >&2
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 "" >&2
echo -e " ${BOLD}${WHITE}🔍 Превью шаблона:${NC}" >&2
echo -e " ${DIM}$(printf '─%.0s' {1..55})${NC}" >&2
echo -e " ${WHITE}Название:${NC} $name" >&2
echo -e " ${WHITE}Источник:${NC} $source" >&2
echo -e " ${WHITE}Описание:${NC} $description" >&2
if [ -n "$preview_url" ]; then
echo "" >&2
echo -e " ${GREEN}👁 Превью:${NC} ${CYAN}${preview_url}${NC}" >&2
echo -e " ${DIM}Откройте ссылку в браузере для просмотра шаблона${NC}" >&2
fi
if [ -n "$repo_url" ]; then
echo -e " ${DIM}📦 Репо: ${repo_url}${NC}" >&2
fi
# Благодарность автору
echo "" >&2
echo -e " ${MAGENTA}💜 Спасибо авторам ${source} за открытый код!${NC}" >&2
echo -e " ${DIM}$(printf '─%.0s' {1..55})${NC}" >&2
echo "" >&2
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
local sb_tmp="/tmp/sb_clone_$$"
rm -rf "$sb_tmp"
git clone --depth 1 "$repo_url" "$sb_tmp" 2>/dev/null
if [ -d "$sb_tmp" ]; then
rm -rf "$sb_tmp/.git"
# StartBootstrap хранит production-файлы в dist/
if [ -f "$sb_tmp/dist/index.html" ]; then
cp -r "$sb_tmp/dist/"* "$clone_dir/"
elif [ -f "$sb_tmp/index.html" ]; then
cp -r "$sb_tmp/"* "$clone_dir/"
else
# fallback: ищем index.html рекурсивно
local found_index
found_index=$(find "$sb_tmp" -name "index.html" -type f 2>/dev/null | head -1)
if [ -n "$found_index" ]; then
local found_dir
found_dir=$(dirname "$found_index")
cp -r "$found_dir/"* "$clone_dir/"
fi
fi
fi
rm -rf "$sb_tmp"
fi
# Проверяем результат
if [ -f "$clone_dir/index.html" ]; then
log_success "Шаблон \"$name\" скачан"
echo "$clone_dir"
return 0
else
# fallback: ищем index.html в подпапках (нестандартная структура)
local fallback_index
fallback_index=$(find "$clone_dir" -name "index.html" -type f 2>/dev/null | head -1)
if [ -n "$fallback_index" ]; then
local fallback_dir
fallback_dir=$(dirname "$fallback_index")
if [ "$fallback_dir" != "$clone_dir" ]; then
cp -r "$fallback_dir/"* "$clone_dir/"
log_success "Шаблон \"$name\" скачан (из подпапки)"
echo "$clone_dir"
return 0
fi
fi
log_error "Шаблон не содержит index.html"
log_dim "Путь: $clone_dir"
ls -la "$clone_dir" 2>/dev/null >&2
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
}