Compare commits

...

8 Commits

9 changed files with 120 additions and 44 deletions

View File

@@ -1 +1 @@
v2.0.10
v2.0.13

View File

@@ -198,14 +198,7 @@ log "🔍 Проверка образа:"
echo " docker run --rm $REPOSITORY:$VERSION /app/lcg --version"
echo ""
log "📝 Команды для использования:"
echo " kubectl apply -k kustomize"
echo " kubectl get pods"
echo " kubectl get services"
echo " kubectl get ingress"
echo " kubectl get hpa"
echo " kubectl get servicemonitor"
echo " kubectl get pods"
echo " kubectl get services"
echo " kubectl get ingress"
echo " kubectl get hpa"
echo " kubectl get servicemonitor"

View File

@@ -1 +1 @@
v2.0.10
v2.0.13

View File

@@ -5,7 +5,7 @@ metadata:
namespace: lcg
data:
# Основные настройки
LCG_VERSION: "v2.0.10"
LCG_VERSION: "v2.0.13"
LCG_BASE_PATH: "/lcg"
LCG_SERVER_HOST: "0.0.0.0"
LCG_SERVER_PORT: "8080"

View File

@@ -5,7 +5,7 @@ metadata:
namespace: lcg
labels:
app: lcg
version: v2.0.10
version: v2.0.13
spec:
replicas: 1
selector:
@@ -18,7 +18,7 @@ spec:
spec:
containers:
- name: lcg
image: kuznetcovay/lcg:v2.0.10
image: kuznetcovay/lcg:v2.0.13
imagePullPolicy: Always
ports:
- containerPort: 8080

View File

@@ -15,11 +15,11 @@ resources:
# Common labels
# commonLabels:
# app: lcg
# version: v2.0.10
# version: v2.0.13
# managed-by: kustomize
# Images
# images:
# - name: lcg
# newName: kuznetcovay/lcg
# newTag: v2.0.10
# newTag: v2.0.13

View File

@@ -39,11 +39,12 @@ func generateAbbreviation(appName string) string {
// FileInfo содержит информацию о файле
type FileInfo struct {
Name string
Size string
ModTime string
Preview template.HTML
Content string // Полное содержимое для поиска
Name string
DisplayName string
Size string
ModTime string
Preview template.HTML
Content string // Полное содержимое для поиска
}
// handleResultsPage обрабатывает главную страницу со списком файлов
@@ -133,11 +134,12 @@ func getResultFiles() ([]FileInfo, error) {
}
files = append(files, FileInfo{
Name: entry.Name(),
Size: formatFileSize(info.Size()),
ModTime: info.ModTime().Format("02.01.2006 15:04"),
Preview: template.HTML(preview),
Content: fullContent,
Name: entry.Name(),
DisplayName: formatFileDisplayName(entry.Name()),
Size: formatFileSize(info.Size()),
ModTime: info.ModTime().Format("02.01.2006 15:04"),
Preview: template.HTML(preview),
Content: fullContent,
})
}
@@ -167,6 +169,65 @@ func formatFileSize(size int64) string {
return fmt.Sprintf("%.1f %cB", float64(size)/float64(div), "KMGTPE"[exp])
}
// formatFileDisplayName преобразует имя файла вида
// gpt_request_GigaChat-2-Max_2025-10-22_13-50-13.md
// в "Gpt Request GigaChat 2 Max — 2025-10-22 13:50:13"
func formatFileDisplayName(filename string) string {
name := strings.TrimSuffix(filename, ".md")
// Разделим на части по '_'
parts := strings.Split(name, "_")
if len(parts) == 0 {
return filename
}
// Первая часть может быть префиксом gpt/request — заменим '_' на пробел и приведем регистр
var words []string
for _, p := range parts {
if p == "" {
continue
}
// Заменяем '-' на пробел в словах модели/текста
p = strings.ReplaceAll(p, "-", " ")
// Разбиваем по пробелам и капитализуем каждое слово
for _, w := range strings.Fields(p) {
if w == "" {
continue
}
r := []rune(w)
r[0] = unicode.ToUpper(r[0])
words = append(words, string(r))
}
}
// Попробуем распознать хвост как дату и время
// Ищем шаблон YYYY-MM-DD_HH-MM-SS в исходном имени
var pretty string
// ожидаем последние две части — дата и время
if len(parts) >= 3 {
datePart := parts[len(parts)-2]
timePart := parts[len(parts)-1]
// заменить '-' в времени на ':'
timePretty := strings.ReplaceAll(timePart, "-", ":")
if len(datePart) == 10 && len(timePart) == 8 { // примитивная проверка
// Собираем текст до датных частей
text := strings.Join(words[:len(words)-2], " ")
pretty = strings.TrimSpace(text)
if pretty != "" {
pretty += " — " + datePart + " " + timePretty
} else {
pretty = datePart + " " + timePretty
}
return pretty
}
}
if len(words) > 0 {
pretty = strings.Join(words, " ")
return pretty
}
return filename
}
// handleFileView обрабатывает просмотр конкретного файла
func handleFileView(w http.ResponseWriter, r *http.Request) {
// Учитываем BasePath при извлечении имени файла

View File

@@ -111,19 +111,26 @@ const HistoryPageTemplate = `
font-size: 0.9em;
color: #2d5016;
border-left: 3px solid #2d5016;
max-height: 72px; /* ~4 строки */
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
}
.delete-btn {
background: #e74c3c;
color: white;
background: transparent;
color: #ef9a9a; /* бледно-красный */
border: none;
padding: 6px 12px;
padding: 2px 6px;
border-radius: 4px;
cursor: pointer;
font-size: 0.8em;
transition: background 0.3s ease;
font-size: 18px;
line-height: 1;
transition: color 0.2s ease, transform 0.2s ease;
}
.delete-btn:hover {
background: #c0392b;
color: rgb(171, 27, 24); /* ярче при ховере */
transform: translateY(-1px);
}
.empty-state {
text-align: center;
@@ -180,7 +187,7 @@ const HistoryPageTemplate = `
<span class="history-index">#{{.Index}}</span>
<span class="history-timestamp">{{.Timestamp}}</span>
</div>
<button class="delete-btn" onclick="event.stopPropagation(); deleteHistoryEntry({{.Index}})">🗑️ Удалить</button>
<button class="delete-btn" onclick="event.stopPropagation(); deleteHistoryEntry({{.Index}})"></button>
</div>
<div class="history-command">{{.Command}}</div>
<div class="history-response">{{.Response}}</div>

View File

@@ -73,8 +73,10 @@ const ResultsPageTemplate = `
}
.files-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
align-items: stretch;
grid-auto-rows: auto;
}
.file-card {
background: white;
@@ -91,32 +93,36 @@ const ResultsPageTemplate = `
}
.file-card-content {
cursor: pointer;
padding-left: 28px;
}
.file-actions {
position: absolute;
top: 10px;
right: 10px;
left: 10px;
display: flex;
gap: 8px;
}
.delete-btn {
background: #e74c3c;
color: white;
background: transparent;
color: #ef9a9a; /* бледно-красный */
border: none;
padding: 6px 12px;
padding: 4px 8px;
border-radius: 4px;
cursor: pointer;
font-size: 0.8em;
transition: background 0.3s ease;
font-size: 18px;
line-height: 1;
transition: color 0.2s ease, transform 0.2s ease;
}
.delete-btn:hover {
background: #c0392b;
color:rgb(171, 27, 24); /* чуть ярче при ховере */
transform: translateY(-1px);
}
.file-name {
font-weight: 600;
color: #333;
margin-bottom: 8px;
font-size: 1.1em;
padding-right: 10px;
}
.file-info {
color: #666;
@@ -165,16 +171,25 @@ const ResultsPageTemplate = `
body { padding: 10px; }
.container { margin: 0; border-radius: 8px; box-shadow: 0 10px 20px rgba(0,0,0,0.1); }
.header { padding: 20px; }
.header h1 { font-size: 2em; }
.header h1 { font-size: 1.9em; }
.content { padding: 20px; }
.files-grid { grid-template-columns: 1fr; }
/* Стили карточек как в истории */
.file-card { background: #f0f8f0; border: 1px solid #a8e6cf; padding: 15px; }
.file-card:hover { border-color: #2d5016; box-shadow: 0 8px 25px rgba(45,80,22,0.2); transform: translateY(-2px); }
.file-name { color: #333; margin-bottom: 8px; }
.file-info { color: #666; font-size: 0.9em; }
.file-preview { background: #f8f9fa; border-left: 3px solid #2d5016; font-size: 0.85em; }
.file-actions { top: 8px; left: 8px; }
.delete-btn { padding: 2px 6px; font-size: 16px; }
.stats { grid-template-columns: 1fr 1fr; }
.nav-buttons { flex-direction: column; gap: 8px; }
.nav-btn, .nav-button { text-align: center; padding: 12px 16px; font-size: 14px; }
.search-container input { font-size: 16px; width: 96% !important; }
}
@media (max-width: 480px) {
.header h1 { font-size: 1.8em; }
.header h1 { font-size: 1.6em; }
.content { padding: 16px; }
.stats { grid-template-columns: 1fr; }
}
</style>
@@ -216,10 +231,10 @@ const ResultsPageTemplate = `
{{range .Files}}
<div class="file-card" data-content="{{.Content}}">
<div class="file-actions">
<button class="delete-btn" onclick="deleteFile('{{.Name}}')" title="Удалить файл">🗑️</button>
<button class="delete-btn" onclick="deleteFile('{{.Name}}')" title="Удалить файл"></button>
</div>
<div class="file-card-content" onclick="window.location.href='{{$.BasePath}}/file/{{.Name}}'">
<div class="file-name">{{.Name}}</div>
<div class="file-name">{{.DisplayName}}</div>
<div class="file-info">
📅 {{.ModTime}} | 📏 {{.Size}}
</div>