mirror of
https://github.com/Direct-Dev-Ru/go-lcg.git
synced 2025-11-16 01:29:55 +00:00
before refactor serve.go
This commit is contained in:
124
CHANGELOG.txt
Normal file
124
CHANGELOG.txt
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
CHANGELOG
|
||||||
|
=========
|
||||||
|
|
||||||
|
Версия 2.0.0 (2025-01-19)
|
||||||
|
=========================
|
||||||
|
|
||||||
|
КРУПНОЕ ОБНОВЛЕНИЕ: Полная реструктуризация архитектуры и добавление веб-интерфейса
|
||||||
|
|
||||||
|
## 🚀 НОВЫЕ ВОЗМОЖНОСТИ
|
||||||
|
|
||||||
|
### Веб-интерфейс
|
||||||
|
- ✨ Добавлен полноценный веб-сервер для управления результатами
|
||||||
|
- 🌐 Веб-интерфейс доступен по адресу http://localhost:8080 (по умолчанию)
|
||||||
|
- 📊 Страница просмотра результатов с форматированием и подсветкой синтаксиса
|
||||||
|
- 📝 Страница истории запросов с возможностью удаления
|
||||||
|
- ⚙️ Страница управления промптами с полным CRUD функционалом
|
||||||
|
|
||||||
|
### Управление промптами
|
||||||
|
- 🔧 Полная система управления системными промптами через веб-интерфейс
|
||||||
|
- 🌍 Поддержка многоязычности (английский/русский) с переключением языка
|
||||||
|
- 📝 Редактирование, добавление и удаление промптов через веб-интерфейс
|
||||||
|
- 🔄 Кнопки восстановления промптов к значениям по умолчанию
|
||||||
|
- 📋 Двухвкладочный интерфейс: системные промпты (1-5) и промпты подробности (v/vv/vvv)
|
||||||
|
|
||||||
|
### Улучшенная система промптов
|
||||||
|
- 📁 Централизованное хранение промптов в файле sys_prompts
|
||||||
|
- 🏗️ Встроенные промпты загружаются из YAML файла (builtin_prompts.yaml)
|
||||||
|
- 🔍 Автоматическое определение встроенных промптов
|
||||||
|
- 🌐 Многоязычные промпты с поддержкой английского и русского языков
|
||||||
|
- 🔄 Автоматическая инициализация sys_prompts при первом запуске CLI
|
||||||
|
|
||||||
|
### Новые CLI команды
|
||||||
|
- 📜 `lcg history` - просмотр истории запросов
|
||||||
|
- 📜 `lcg history clear` - очистка истории
|
||||||
|
- 📜 `lcg history delete <id>` - удаление записи из истории
|
||||||
|
- 📝 `lcg prompts list` - список всех промптов
|
||||||
|
- 📝 `lcg prompts list --full` - полный вывод содержимого промптов
|
||||||
|
- 📝 `lcg prompts add` - добавление нового промпта
|
||||||
|
- 📝 `lcg prompts edit <id>` - редактирование промпта
|
||||||
|
- 📝 `lcg prompts delete <id>` - удаление промпта
|
||||||
|
|
||||||
|
### Расширенная функциональность
|
||||||
|
- 🔍 Флаг --debug для отображения параметров запросов и промптов
|
||||||
|
- 📊 Улучшенное отображение результатов с подсветкой синтаксиса
|
||||||
|
- 🎨 Обновленный дизайн веб-интерфейса с современным UI
|
||||||
|
- 📱 Адаптивный дизайн для различных размеров экрана
|
||||||
|
|
||||||
|
## 🏗️ АРХИТЕКТУРНЫЕ ИЗМЕНЕНИЯ
|
||||||
|
|
||||||
|
### Новая структура проекта
|
||||||
|
- 📁 cmd/ - модули команд (explain.go, history.go, serve.go)
|
||||||
|
- 📁 config/ - централизованная конфигурация
|
||||||
|
- 📁 gpt/ - логика работы с промптами и LLM
|
||||||
|
- 📁 reader/ - модуль чтения файлов
|
||||||
|
- 📁 shell-code/ - скрипты сборки и развертывания
|
||||||
|
|
||||||
|
### Централизованная конфигурация
|
||||||
|
- ⚙️ config/config.go - единая точка конфигурации
|
||||||
|
- 🔧 Поддержка переменных окружения для всех настроек
|
||||||
|
- 📝 Автоматическое создание конфигурационных файлов
|
||||||
|
|
||||||
|
### Встроенные промпты
|
||||||
|
- 📄 builtin_prompts.yaml - YAML файл с встроенными промптами
|
||||||
|
- 🔧 builtin_prompts.go - логика работы с встроенными промптами
|
||||||
|
- 🌐 Поддержка многоязычности на уровне YAML
|
||||||
|
|
||||||
|
## 🐛 ИСПРАВЛЕНИЯ
|
||||||
|
|
||||||
|
- 🔧 Исправлена проблема с регистронезависимым поиском в истории
|
||||||
|
- 🎨 Улучшена цветовая схема веб-интерфейса (менее яркие цвета)
|
||||||
|
- 🔘 Стандартизированы размеры и цвета кнопок навигации
|
||||||
|
- 🌍 Исправлена логика определения языка в веб-интерфейсе
|
||||||
|
- 🔍 Исправлена логика определения встроенных промптов при смене языка
|
||||||
|
|
||||||
|
## 📋 ОБРАТНАЯ СОВМЕСТИМОСТЬ
|
||||||
|
|
||||||
|
- ✅ Все существующие CLI команды сохранены
|
||||||
|
- ✅ Поддержка всех переменных окружения из v1.x.x
|
||||||
|
- ✅ Автоматическая миграция существующих конфигураций
|
||||||
|
- ✅ Сохранена совместимость с существующими API
|
||||||
|
|
||||||
|
## 🔧 ТЕХНИЧЕСКИЕ УЛУЧШЕНИЯ
|
||||||
|
|
||||||
|
### Производительность
|
||||||
|
- ⚡ Оптимизирована загрузка промптов
|
||||||
|
- 🚀 Улучшена скорость работы веб-интерфейса
|
||||||
|
- 💾 Эффективное кэширование промптов
|
||||||
|
|
||||||
|
### Безопасность
|
||||||
|
- 🔒 Валидация входных данных в веб-интерфейсе
|
||||||
|
- 🛡️ Защита от XSS атак
|
||||||
|
- 🔐 Безопасная обработка файлов
|
||||||
|
|
||||||
|
### Код
|
||||||
|
- 🧹 Рефакторинг архитектуры для лучшей поддерживаемости
|
||||||
|
- 📚 Улучшенная документация кода
|
||||||
|
- 🧪 Добавлены тесты для критических компонентов
|
||||||
|
|
||||||
|
## 📦 ЗАВИСИМОСТИ
|
||||||
|
|
||||||
|
### Новые зависимости
|
||||||
|
- github.com/urfave/cli/v2 - CLI фреймворк
|
||||||
|
- gopkg.in/yaml.v3 - работа с YAML файлами
|
||||||
|
- html/template - шаблонизация веб-страниц
|
||||||
|
|
||||||
|
### Обновленные зависимости
|
||||||
|
- Обновлены все существующие зависимости до последних версий
|
||||||
|
|
||||||
|
## 🚀 МИГРАЦИЯ С v1.x.x
|
||||||
|
|
||||||
|
1. **Автоматическая миграция**: При первом запуске v2.0.0 автоматически создастся файл sys_prompts с встроенными промптами
|
||||||
|
2. **Сохранение настроек**: Все переменные окружения и настройки сохраняются
|
||||||
|
3. **Новые возможности**: Доступ к веб-интерфейсу через `lcg serve-result`
|
||||||
|
4. **Управление промптами**: Используйте `lcg prompts list` для просмотра всех промптов
|
||||||
|
|
||||||
|
## 📖 ДОКУМЕНТАЦИЯ
|
||||||
|
|
||||||
|
- 📚 Обновлен USAGE_GUIDE.md с описанием новых команд
|
||||||
|
- 📋 Добавлен API_CONTRACT.md для веб-интерфейса
|
||||||
|
- 🔧 Обновлен README.md с инструкциями по использованию
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Примечание**: Версия 2.0.0 представляет собой кардинальное обновление с полной реструктуризацией архитектуры. Рекомендуется ознакомиться с новыми возможностями веб-интерфейса и системой управления промптами.
|
||||||
25
README.md
25
README.md
@@ -9,7 +9,7 @@ Generate Linux commands from natural language. Supports Ollama and Proxy backend
|
|||||||
Build from source:
|
Build from source:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone --depth 1 https://github.com/Direct-Dev-Ru/go-lcg.git ~/.linux-command-gpt
|
git clone --depth 1 https://github.com/Direct-Dev-Ru/linux-command-gpt.git ~/.linux-command-gpt
|
||||||
cd ~/.linux-command-gpt
|
cd ~/.linux-command-gpt
|
||||||
go build -o lcg
|
go build -o lcg
|
||||||
|
|
||||||
@@ -37,10 +37,20 @@ Clipboard support requires `xclip` or `xsel`.
|
|||||||
|
|
||||||
## Environment
|
## Environment
|
||||||
|
|
||||||
- `LCG_PROVIDER` (ollama|proxy), `LCG_HOST`, `LCG_MODEL`, `LCG_PROMPT`
|
- `LCG_PROVIDER` (default `ollama`) — provider type: `ollama` or `proxy`
|
||||||
- `LCG_TIMEOUT` (default 120), `LCG_RESULT_FOLDER` (default ./gpt_results)
|
- `LCG_HOST` (default `http://192.168.87.108:11434/`) — base API URL
|
||||||
- `LCG_RESULT_HISTORY` (default $(LCG_RESULT_FOLDER)/lcg_history.json)
|
- `LCG_MODEL` (default `hf.co/yandex/YandexGPT-5-Lite-8B-instruct-GGUF:Q4_K_M`)
|
||||||
- `LCG_JWT_TOKEN` (for proxy)
|
- `LCG_PROMPT` — default system prompt content
|
||||||
|
- `LCG_PROXY_URL` (default `/api/v1/protected/sberchat/chat`) — proxy chat endpoint
|
||||||
|
- `LCG_COMPLETIONS_PATH` (default `api/chat`) — Ollama chat endpoint (relative)
|
||||||
|
- `LCG_TIMEOUT` (default `300`) — request timeout in seconds
|
||||||
|
- `LCG_RESULT_FOLDER` (default `~/.config/lcg/gpt_results`) — folder for saved results
|
||||||
|
- `LCG_RESULT_HISTORY` (default `$(LCG_RESULT_FOLDER)/lcg_history.json`) — JSON history path
|
||||||
|
- `LCG_PROMPT_FOLDER` (default `~/.config/lcg/gpt_sys_prompts`) — folder for system prompts
|
||||||
|
- `LCG_PROMPT_ID` (default `1`) — default system prompt ID
|
||||||
|
- `LCG_JWT_TOKEN` — JWT token for proxy provider
|
||||||
|
- `LCG_NO_HISTORY` — if `1`/`true`, disables history writes for the process
|
||||||
|
- `LCG_SERVER_PORT` (default `8080`), `LCG_SERVER_HOST` (default `localhost`) — HTTP server settings
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
@@ -48,6 +58,8 @@ Clipboard support requires `xclip` or `xsel`.
|
|||||||
- `--sys, -s` system prompt content or ID
|
- `--sys, -s` system prompt content or ID
|
||||||
- `--prompt-id, --pid` choose built-in prompt (1–5)
|
- `--prompt-id, --pid` choose built-in prompt (1–5)
|
||||||
- `--timeout, -t` request timeout (sec)
|
- `--timeout, -t` request timeout (sec)
|
||||||
|
- `--no-history, --nh` disable writing/updating JSON history for this run
|
||||||
|
- `--debug, -d` show debug information (request parameters and prompts)
|
||||||
- `--version, -v` print version; `--help, -h` help
|
- `--version, -v` print version; `--help, -h` help
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
@@ -60,10 +72,11 @@ Clipboard support requires `xclip` or `xsel`.
|
|||||||
- `history list` — list history from JSON
|
- `history list` — list history from JSON
|
||||||
- `history view <index>` — view by index
|
- `history view <index>` — view by index
|
||||||
- `history delete <index>` — delete by index (re-numbering)
|
- `history delete <index>` — delete by index (re-numbering)
|
||||||
|
- `serve-result` — start HTTP server to browse saved results (`--port`, `--host`)
|
||||||
|
|
||||||
## Saving results
|
## Saving results
|
||||||
|
|
||||||
Files are saved to `LCG_RESULT_FOLDER`.
|
Files are saved to `LCG_RESULT_FOLDER` (default `~/.config/lcg/gpt_results`).
|
||||||
|
|
||||||
- Command result: `gpt_request_<MODEL>_YYYY-MM-DD_HH-MM-SS.md`
|
- Command result: `gpt_request_<MODEL>_YYYY-MM-DD_HH-MM-SS.md`
|
||||||
- `# <title>` — H1 with original request (trimmed to 120 chars: first 116 + `...`)
|
- `# <title>` — H1 with original request (trimmed to 120 chars: first 116 + `...`)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ sudo apt-get install xsel
|
|||||||
Сборка из исходников:
|
Сборка из исходников:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone --depth 1 https://github.com/asrul10/linux-command-gpt.git ~/.linux-command-gpt
|
git clone --depth 1 https://github.com/Direct-Dev-Ru/linux-command-gpt.git ~/.linux-command-gpt
|
||||||
cd ~/.linux-command-gpt
|
cd ~/.linux-command-gpt
|
||||||
go build -o lcg
|
go build -o lcg
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ func ShowHistory(historyPath string, printColored func(string, string), colorYel
|
|||||||
for _, h := range items {
|
for _, h := range items {
|
||||||
ts := h.Timestamp.Format("2006-01-02 15:04:05")
|
ts := h.Timestamp.Format("2006-01-02 15:04:05")
|
||||||
fmt.Printf("%d. [%s] %s → %s\n", h.Index, ts, h.Command, h.Response)
|
fmt.Printf("%d. [%s] %s → %s\n", h.Index, ts, h.Command, h.Response)
|
||||||
|
fmt.Printf("%s\n", "========================================================================================")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
go-ansible-vault -i shell-code/build.env -a get -m GITHUB_TOKEN > /tmp/source && source /tmp/source
|
go-ansible-vault -i shell-code/build.env -a get -m GITHUB_TOKEN > /tmp/source && source /tmp/source
|
||||||
|
|
||||||
#GITHUB_TOKEN=$GITHUB_TOKEN python3 shell-code/release.py
|
GITHUB_TOKEN=$GITHUB_TOKEN python3 shell-code/release.py
|
||||||
@@ -11,6 +11,8 @@ import requests
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# Цвета для вывода
|
# Цвета для вывода
|
||||||
|
|
||||||
|
|
||||||
class Colors:
|
class Colors:
|
||||||
RED = '\033[0;31m'
|
RED = '\033[0;31m'
|
||||||
GREEN = '\033[0;32m'
|
GREEN = '\033[0;32m'
|
||||||
@@ -18,23 +20,29 @@ class Colors:
|
|||||||
BLUE = '\033[0;34m'
|
BLUE = '\033[0;34m'
|
||||||
NC = '\033[0m' # No Color
|
NC = '\033[0m' # No Color
|
||||||
|
|
||||||
|
|
||||||
def log(message):
|
def log(message):
|
||||||
print(f"{Colors.GREEN}[INFO]{Colors.NC} {message}")
|
print(f"{Colors.GREEN}[INFO]{Colors.NC} {message}")
|
||||||
|
|
||||||
|
|
||||||
def error(message):
|
def error(message):
|
||||||
print(f"{Colors.RED}[ERROR]{Colors.NC} {message}", file=sys.stderr)
|
print(f"{Colors.RED}[ERROR]{Colors.NC} {message}", file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
def warn(message):
|
def warn(message):
|
||||||
print(f"{Colors.YELLOW}[WARN]{Colors.NC} {message}")
|
print(f"{Colors.YELLOW}[WARN]{Colors.NC} {message}")
|
||||||
|
|
||||||
|
|
||||||
def debug(message):
|
def debug(message):
|
||||||
print(f"{Colors.BLUE}[DEBUG]{Colors.NC} {message}")
|
print(f"{Colors.BLUE}[DEBUG]{Colors.NC} {message}")
|
||||||
|
|
||||||
|
|
||||||
# Конфигурация
|
# Конфигурация
|
||||||
REPO = "direct-dev-ru/go-lcg"
|
REPO = "direct-dev-ru/go-lcg"
|
||||||
VERSION_FILE = "VERSION.txt"
|
VERSION_FILE = "VERSION.txt"
|
||||||
BINARIES_DIR = "binaries-for-upload"
|
BINARIES_DIR = "binaries-for-upload"
|
||||||
|
|
||||||
|
|
||||||
def check_environment():
|
def check_environment():
|
||||||
"""Проверка переменных окружения"""
|
"""Проверка переменных окружения"""
|
||||||
token = os.getenv('GITHUB_TOKEN')
|
token = os.getenv('GITHUB_TOKEN')
|
||||||
@@ -44,39 +52,42 @@ def check_environment():
|
|||||||
log(f"GITHUB_TOKEN установлен (длина: {len(token)} символов)")
|
log(f"GITHUB_TOKEN установлен (длина: {len(token)} символов)")
|
||||||
return token
|
return token
|
||||||
|
|
||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
"""Получение версии из файла"""
|
"""Получение версии из файла"""
|
||||||
version_file = Path(VERSION_FILE)
|
version_file = Path(VERSION_FILE)
|
||||||
if not version_file.exists():
|
if not version_file.exists():
|
||||||
error(f"Файл {VERSION_FILE} не найден")
|
error(f"Файл {VERSION_FILE} не найден")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
version = version_file.read_text().strip()
|
version = version_file.read_text().strip()
|
||||||
tag = f"lcg.{version}"
|
tag = f"lcg.{version}"
|
||||||
log(f"Версия: {version}")
|
log(f"Версия: {version}")
|
||||||
log(f"Тег: {tag}")
|
log(f"Тег: {tag}")
|
||||||
return tag
|
return tag
|
||||||
|
|
||||||
|
|
||||||
def check_files():
|
def check_files():
|
||||||
"""Проверка файлов для загрузки"""
|
"""Проверка файлов для загрузки"""
|
||||||
binaries_path = Path(BINARIES_DIR)
|
binaries_path = Path(BINARIES_DIR)
|
||||||
if not binaries_path.exists():
|
if not binaries_path.exists():
|
||||||
error(f"Директория {BINARIES_DIR} не найдена")
|
error(f"Директория {BINARIES_DIR} не найдена")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
files = list(binaries_path.glob("*"))
|
files = list(binaries_path.glob("*"))
|
||||||
files = [f for f in files if f.is_file()]
|
files = [f for f in files if f.is_file()]
|
||||||
|
|
||||||
if not files:
|
if not files:
|
||||||
error(f"В директории {BINARIES_DIR} нет файлов")
|
error(f"В директории {BINARIES_DIR} нет файлов")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
log(f"Найдено файлов: {len(files)}")
|
log(f"Найдено файлов: {len(files)}")
|
||||||
for file in files:
|
for file in files:
|
||||||
log(f" - {file.name} ({file.stat().st_size} байт)")
|
log(f" - {file.name} ({file.stat().st_size} байт)")
|
||||||
|
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
|
||||||
def create_github_session(token):
|
def create_github_session(token):
|
||||||
"""Создание сессии для GitHub API"""
|
"""Создание сессии для GitHub API"""
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
@@ -87,28 +98,30 @@ def create_github_session(token):
|
|||||||
})
|
})
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
|
||||||
def check_existing_release(session, tag):
|
def check_existing_release(session, tag):
|
||||||
"""Проверка существующего релиза"""
|
"""Проверка существующего релиза"""
|
||||||
log("Проверяем существующий релиз...")
|
log("Проверяем существующий релиз...")
|
||||||
url = f"https://api.github.com/repos/{REPO}/releases/tags/{tag}"
|
url = f"https://api.github.com/repos/{REPO}/releases/tags/{tag}"
|
||||||
|
|
||||||
response = session.get(url)
|
response = session.get(url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
release_data = response.json()
|
release_data = response.json()
|
||||||
log(f"Реліз {tag} уже существует")
|
log(f"Релиз с тегом {tag} уже существует")
|
||||||
return release_data
|
return release_data
|
||||||
elif response.status_code == 404:
|
elif response.status_code == 404:
|
||||||
log(f"Реліз {tag} не найден, создаем новый")
|
log(f"Релиз с тегом {tag} не найден, создаем новый")
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
error(f"Ошибка проверки релиза: {response.status_code}")
|
error(f"Ошибка проверки релиза: {response.status_code}")
|
||||||
debug(f"Ответ: {response.text}")
|
debug(f"Ответ: {response.text}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def create_release(session, tag):
|
def create_release(session, tag):
|
||||||
"""Создание нового релиза"""
|
"""Создание нового релиза"""
|
||||||
log(f"Создаем новый релиз {tag}...")
|
log(f"Создаем новый релиз {tag}...")
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"tag_name": tag,
|
"tag_name": tag,
|
||||||
"name": tag,
|
"name": tag,
|
||||||
@@ -116,38 +129,34 @@ def create_release(session, tag):
|
|||||||
"draft": False,
|
"draft": False,
|
||||||
"prerelease": False
|
"prerelease": False
|
||||||
}
|
}
|
||||||
|
|
||||||
url = f"https://api.github.com/repos/{REPO}/releases"
|
url = f"https://api.github.com/repos/{REPO}/releases"
|
||||||
response = session.post(url, json=data)
|
response = session.post(url, json=data)
|
||||||
|
|
||||||
if response.status_code == 201:
|
if response.status_code == 201:
|
||||||
release_data = response.json()
|
release_data = response.json()
|
||||||
log("Реліз создан успешно")
|
log("Релиз с тегом {tag} создан успешно")
|
||||||
return release_data
|
return release_data
|
||||||
else:
|
else:
|
||||||
error(f"Ошибка создания релиза: {response.status_code}")
|
error(f"Ошибка создания релиза с тегом {tag}: {response.status_code}")
|
||||||
debug(f"Ответ: {response.text}")
|
debug(f"Ответ: {response.text}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def upload_file(session, upload_url, file_path):
|
def upload_file(session, upload_url, file_path):
|
||||||
"""Загрузка файла в релиз"""
|
"""Загрузка файла в релиз"""
|
||||||
filename = file_path.name
|
filename = file_path.name
|
||||||
log(f"Загружаем: {filename}")
|
|
||||||
|
|
||||||
# Убираем {?name,label} из URL
|
|
||||||
upload_url = upload_url.replace("{?name,label}", "")
|
|
||||||
|
|
||||||
with open(file_path, 'rb') as f:
|
with open(file_path, 'rb') as f:
|
||||||
headers = {'Content-Type': 'application/octet-stream'}
|
headers = {'Content-Type': 'application/octet-stream'}
|
||||||
params = {'name': filename}
|
params = {'name': filename}
|
||||||
|
|
||||||
response = session.post(
|
response = session.post(
|
||||||
upload_url,
|
upload_url,
|
||||||
data=f,
|
data=f,
|
||||||
headers=headers,
|
headers=headers,
|
||||||
params=params
|
params=params
|
||||||
)
|
)
|
||||||
|
|
||||||
if response.status_code == 201:
|
if response.status_code == 201:
|
||||||
log(f"✓ {filename} загружен")
|
log(f"✓ {filename} загружен")
|
||||||
return True
|
return True
|
||||||
@@ -156,38 +165,39 @@ def upload_file(session, upload_url, file_path):
|
|||||||
debug(f"Ответ: {response.text}")
|
debug(f"Ответ: {response.text}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Основная функция"""
|
"""Основная функция"""
|
||||||
log("=== НАЧАЛО РАБОТЫ СКРИПТА ===")
|
log("=== НАЧАЛО РАБОТЫ СКРИПТА ===")
|
||||||
|
|
||||||
# Проверки
|
# Проверки
|
||||||
token = check_environment()
|
token = check_environment()
|
||||||
tag = get_version()
|
tag = get_version()
|
||||||
files = check_files()
|
files = check_files()
|
||||||
|
|
||||||
# Создание сессии
|
# Создание сессии
|
||||||
session = create_github_session(token)
|
session = create_github_session(token)
|
||||||
|
|
||||||
# Проверка/создание релиза
|
# Проверка/создание релиза
|
||||||
release = check_existing_release(session, tag)
|
release = check_existing_release(session, tag)
|
||||||
if not release:
|
if not release:
|
||||||
release = create_release(session, tag)
|
release = create_release(session, tag)
|
||||||
|
|
||||||
# Получение URL для загрузки
|
# Получение URL для загрузки
|
||||||
upload_url = release['upload_url']
|
upload_url = release['upload_url']
|
||||||
log(f"Upload URL: {upload_url}")
|
log(f"Upload URL: {upload_url}")
|
||||||
|
|
||||||
# Загрузка файлов
|
# Загрузка файлов
|
||||||
log("=== ЗАГРУЗКА ФАЙЛОВ ===")
|
log("=== ЗАГРУЗКА ФАЙЛОВ ===")
|
||||||
uploaded = 0
|
uploaded = 0
|
||||||
failed = 0
|
failed = 0
|
||||||
|
|
||||||
for file_path in files:
|
for file_path in files:
|
||||||
if upload_file(session, upload_url, file_path):
|
if upload_file(session, upload_url, file_path):
|
||||||
uploaded += 1
|
uploaded += 1
|
||||||
else:
|
else:
|
||||||
failed += 1
|
failed += 1
|
||||||
|
|
||||||
# Результат
|
# Результат
|
||||||
log("=== РЕЗУЛЬТАТ ===")
|
log("=== РЕЗУЛЬТАТ ===")
|
||||||
log(f"Успешно загружено: {uploaded}")
|
log(f"Успешно загружено: {uploaded}")
|
||||||
@@ -195,9 +205,10 @@ def main():
|
|||||||
warn(f"Ошибок: {failed}")
|
warn(f"Ошибок: {failed}")
|
||||||
else:
|
else:
|
||||||
log("Все файлы загружены успешно!")
|
log("Все файлы загружены успешно!")
|
||||||
|
|
||||||
log(f"Реліз доступен: https://github.com/{REPO}/releases/tag/{tag}")
|
log(f"Реліз доступен: https://github.com/{REPO}/releases/tag/{tag}")
|
||||||
log("=== СКРИПТ ЗАВЕРШЕН ===")
|
log("=== СКРИПТ ЗАВЕРШЕН ===")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user