5 Commits

15 changed files with 84 additions and 54 deletions

View File

@@ -49,8 +49,5 @@ lto = true
codegen-units = 1 codegen-units = 1
strip = true strip = true
[target.'cfg(windows)'.dependencies]
winres = "0.1"
[build-dependencies] [build-dependencies]
winres = "0.1" winres = "0.1"

View File

@@ -1,7 +1,5 @@
# MIT License # MIT License
Copyright (c) 2026 [Your Name or Company]
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights

Binary file not shown.

BIN
assets/logo.icns Normal file

Binary file not shown.

View File

@@ -1,9 +1,11 @@
// build.rs
fn main() { fn main() {
#[cfg(windows)] #[cfg(windows)]
{ {
let mut res = winres::WindowsResource::new(); if let Err(e) = winres::WindowsResource::new()
res.set_icon("assets/logo.ico"); .set_icon("assets/logo.ico")
res.compile().unwrap(); .compile()
{
eprintln!("warning: не удалось встроить иконку: {e}");
}
} }
} }

View File

@@ -1,4 +1,4 @@
.PHONY: all clean build-mac build-windows build-linux build-linux-musl package help quick package-single icons favicon .PHONY: all clean build-mac build-windows build-linux build-linux-musl package help quick package-single icons
# Название проекта # Название проекта
PROJECT_NAME := ae_anons PROJECT_NAME := ae_anons
@@ -44,9 +44,9 @@ help:
@echo " make package - Создать пакеты для всех платформ" @echo " make package - Создать пакеты для всех платформ"
@echo " make package-single - Создать пакет для текущей платформы" @echo " make package-single - Создать пакет для текущей платформы"
@echo "" @echo ""
@echo "$(GREEN)Иконки:$(NC)" @echo "$(GREEN)Подготовка ресурсов:$(NC)"
@echo " make icons - Создать все иконки (logo.ico, logo.icns, favicon.ico)" @echo " make setup - Подготовить иконки (логотипы, favicon)"
@echo " make favicon - Создать только favicon.ico" @echo " make setup-fontawesome-manual - Скачать и исправить all.min.css (если удалён)"
@echo "" @echo ""
@echo "$(GREEN)Очистка:$(NC)" @echo "$(GREEN)Очистка:$(NC)"
@echo " make clean - Очистить все сборки" @echo " make clean - Очистить все сборки"
@@ -67,15 +67,14 @@ define measure_time
$(2); \ $(2); \
end=$$(date +%s); \ end=$$(date +%s); \
duration=$$((end - start)); \ duration=$$((end - start)); \
echo "$(1): $$duration сек" >> $(TIMING_FILE); \
if [ $$duration -ge 60 ]; then \ if [ $$duration -ge 60 ]; then \
min=$$((duration / 60)); \ min=$$((duration / 60)); \
sec=$$((duration % 60)); \ sec=$$((duration % 60)); \
time_str="$${min}m $${sec}s"; \ echo "$(GREEN)$(1) завершён за $${min}m $${sec}s$(NC)"; \
else \ else \
time_str="$${duration}s"; \ echo "$(GREEN)$(1) завершён за $${duration}s$(NC)"; \
fi; \ fi
echo "$(1): $$time_str" >> $(TIMING_FILE); \
echo "$(GREEN)$(1) завершён за $$time_str$(NC)"
endef endef
define print_timing_summary define print_timing_summary
@@ -100,41 +99,56 @@ define print_timing_summary
endef endef
# ============================================ # ============================================
# ИКОНКИ # ПОДГОТОВКА РЕСУРСОВ
# ============================================ # ============================================
icons: favicon setup: icons
@echo "$(GREEN)Создание иконок для Windows и macOS...$(NC)" @echo "$(GREEN)Все статические ресурсы подготовлены$(NC)"
# Генерация иконок (favicon, .ico, .icns) из логотипа
icons:
@echo "$(GREEN)🎨 Генерация иконок...$(NC)"
@if [ "$(IMAGEMAGICK)" = "false" ]; then \ @if [ "$(IMAGEMAGICK)" = "false" ]; then \
echo "$(RED)❌ ImageMagick не установлен. Установите: brew install imagemagick$(NC)"; \ echo "$(RED)❌ ImageMagick не установлен. Установите: brew install imagemagick$(NC)"; \
exit 1; \ exit 1; \
fi fi
# favicon.ico
@$(IMAGEMAGICK) assets/logo.png -define icon:auto-resize=48,32,16 src/static/favicon.ico
@echo "$(GREEN) ✓ src/static/favicon.ico$(NC)"
# Windows .ico # Windows .ico
@$(IMAGEMAGICK) assets/logo.png -define icon:auto-resize=256,128,64,48,32,16 assets/logo.ico @$(IMAGEMAGICK) assets/logo.png -define icon:auto-resize=256,128,64,48,32,16 assets/logo.ico
@echo "$(GREEN) ✓ assets/logo.ico$(NC)" @echo "$(GREEN) ✓ assets/logo.ico$(NC)"
# macOS .icns # macOS .icns
@mkdir -p assets/icon.iconset @mkdir -p assets/icon.iconset
@sips -z 16 16 assets/logo.png --out assets/icon.iconset/icon_16x16.png 2>/dev/null @sips -z 16 16 assets/logo.png --out assets/icon.iconset/icon_16x16.png 2>/dev/null || true
@sips -z 32 32 assets/logo.png --out assets/icon.iconset/icon_16x16@2x.png 2>/dev/null @sips -z 32 32 assets/logo.png --out assets/icon.iconset/icon_16x16@2x.png 2>/dev/null || true
@sips -z 32 32 assets/logo.png --out assets/icon.iconset/icon_32x32.png 2>/dev/null @sips -z 32 32 assets/logo.png --out assets/icon.iconset/icon_32x32.png 2>/dev/null || true
@sips -z 64 64 assets/logo.png --out assets/icon.iconset/icon_32x32@2x.png 2>/dev/null @sips -z 64 64 assets/logo.png --out assets/icon.iconset/icon_32x32@2x.png 2>/dev/null || true
@sips -z 128 128 assets/logo.png --out assets/icon.iconset/icon_128x128.png 2>/dev/null @sips -z 128 128 assets/logo.png --out assets/icon.iconset/icon_128x128.png 2>/dev/null || true
@sips -z 256 256 assets/logo.png --out assets/icon.iconset/icon_128x128@2x.png 2>/dev/null @sips -z 256 256 assets/logo.png --out assets/icon.iconset/icon_128x128@2x.png 2>/dev/null || true
@sips -z 256 256 assets/logo.png --out assets/icon.iconset/icon_256x256.png 2>/dev/null @sips -z 256 256 assets/logo.png --out assets/icon.iconset/icon_256x256.png 2>/dev/null || true
@sips -z 512 512 assets/logo.png --out assets/icon.iconset/icon_256x256@2x.png 2>/dev/null @sips -z 512 512 assets/logo.png --out assets/icon.iconset/icon_256x256@2x.png 2>/dev/null || true
@sips -z 512 512 assets/logo.png --out assets/icon.iconset/icon_512x512.png 2>/dev/null @sips -z 512 512 assets/logo.png --out assets/icon.iconset/icon_512x512.png 2>/dev/null || true
@iconutil -c icns assets/icon.iconset -o assets/logo.icns 2>/dev/null @iconutil -c icns assets/icon.iconset -o assets/logo.icns 2>/dev/null || true
@rm -rf assets/icon.iconset @rm -rf assets/icon.iconset
@echo "$(GREEN) ✓ assets/logo.icns$(NC)" @echo "$(GREEN) ✓ assets/logo.icns$(NC)"
favicon: # Восстановить CSS Font Awesome вручную (если файл удалён)
@echo "$(GREEN)Создание favicon.ico...$(NC)" setup-fontawesome-manual:
@if [ "$(IMAGEMAGICK)" = "false" ]; then \ @echo "$(GREEN)📥 Скачивание Font Awesome CSS...$(NC)"
echo "$(RED)❌ ImageMagick не установлен. Установите: brew install imagemagick$(NC)"; \ @curl -sL -o src/static/fontawesome/all.min.css $(FONTAWESOME_CSS_URL)
exit 1; \ @sed -i '' -E 's|(\.\./)*webfonts/|/static/fontawesome/webfonts/|g' \
src/static/fontawesome/all.min.css
@echo "$(GREEN)✓ CSS восстановлен и пути исправлены$(NC)"
# ============================================
# ИКОНКА ДЛЯ WINDOWS .EXE
# ============================================
windows-icon:
@if [ ! -f assets/logo.ico ]; then \
echo "$(YELLOW)logo.ico не найден, запускаю генерацию иконок...$(NC)"; \
$(MAKE) icons; \
fi fi
@$(IMAGEMAGICK) assets/logo.png -define icon:auto-resize=48,32,16 src/static/favicon.ico
@echo "$(GREEN) ✓ src/static/favicon.ico$(NC)"
# ============================================ # ============================================
# ОПРЕДЕЛЕНИЕ ПЛАТФОРМЫ # ОПРЕДЕЛЕНИЕ ПЛАТФОРМЫ
@@ -194,7 +208,7 @@ quick-linux:
@echo "$(GREEN)✅ Пакет: $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M)/$(NC)" @echo "$(GREEN)✅ Пакет: $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M)/$(NC)"
@$(call print_timing_summary) @$(call print_timing_summary)
quick-windows: quick-windows: windows-icon
@rm -f $(TIMING_FILE) @rm -f $(TIMING_FILE)
@if command -v x86_64-w64-mingw32-gcc >/dev/null 2>&1; then \ @if command -v x86_64-w64-mingw32-gcc >/dev/null 2>&1; then \
$(call measure_time,"🪟 Windows x64",cargo build --target x86_64-pc-windows-gnu --release); \ $(call measure_time,"🪟 Windows x64",cargo build --target x86_64-pc-windows-gnu --release); \
@@ -217,7 +231,7 @@ build-mac:
@echo "$(GREEN)🍎 Сборка для macOS...$(NC)" @echo "$(GREEN)🍎 Сборка для macOS...$(NC)"
@time cargo build --release @time cargo build --release
build-windows: build-windows: windows-icon
@echo "$(GREEN)🪟 Сборка для Windows x86_64...$(NC)" @echo "$(GREEN)🪟 Сборка для Windows x86_64...$(NC)"
@time cargo build --target x86_64-pc-windows-gnu --release @time cargo build --target x86_64-pc-windows-gnu --release

View File

@@ -1,7 +1,5 @@
# MIT License # MIT License
Copyright (c) 2026 [Your Name or Company]
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights

View File

@@ -1,7 +1,5 @@
# MIT License # MIT License
Copyright (c) 2026 [Your Name or Company]
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights

View File

@@ -1,7 +1,5 @@
# MIT License # MIT License
Copyright (c) 2026 [Your Name or Company]
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights

View File

@@ -1,7 +1,5 @@
# MIT License # MIT License
Copyright (c) 2026 [Your Name or Company]
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights

View File

@@ -11,7 +11,6 @@ use serde::Serialize;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tower_http::services::ServeDir;
use tower_http::trace::TraceLayer; use tower_http::trace::TraceLayer;
#[derive(Clone)] #[derive(Clone)]
@@ -89,19 +88,26 @@ pub async fn run_web_server(config: Config) -> anyhow::Result<()> {
.route("/favicon.ico", get(favicon)) .route("/favicon.ico", get(favicon))
.route("/static/style.css", get(style_css)) .route("/static/style.css", get(style_css))
.route("/static/fontawesome/all.min.css", get(fontawesome_css)) .route("/static/fontawesome/all.min.css", get(fontawesome_css))
.route(
"/static/fontawesome/webfonts/fa-solid-900.woff2",
get(fa_solid_woff2),
)
.route(
"/static/fontawesome/webfonts/fa-regular-400.woff2",
get(fa_regular_woff2),
)
.route(
"/static/fontawesome/webfonts/fa-brands-400.woff2",
get(fa_brands_woff2),
)
.route("/assets/logo.png", get(logo_png)) .route("/assets/logo.png", get(logo_png))
.route("/api/jobs", get(list_jobs)) .route("/api/jobs", get(list_jobs))
.route("/api/generate", post(generate_jobs)) .route("/api/generate", post(generate_jobs))
.route("/api/cleanup", post(cleanup_jobs)) .route("/api/cleanup", post(cleanup_jobs))
.route("/api/status", get(get_status)) .route("/api/status", get(get_status))
.route("/api/jobs/stop-all", post(stop_all_jobs)) .route("/api/jobs/stop-all", post(stop_all_jobs))
.nest_service(
"/static/fontawesome/webfonts",
ServeDir::new("src/static/fontawesome/webfonts"),
)
.layer(TraceLayer::new_for_http()) .layer(TraceLayer::new_for_http())
.with_state(state); .with_state(state);
let addr: SocketAddr = format!("0.0.0.0:{}", web_port).parse()?; let addr: SocketAddr = format!("0.0.0.0:{}", web_port).parse()?;
log::info!("Web server listening on http://{}", addr); log::info!("Web server listening on http://{}", addr);
@@ -229,6 +235,27 @@ async fn stop_all_jobs(State(state): State<AppState>) -> Result<impl IntoRespons
Ok((StatusCode::OK, format!("Stopped {} jobs", stopped))) Ok((StatusCode::OK, format!("Stopped {} jobs", stopped)))
} }
async fn fa_solid_woff2() -> impl IntoResponse {
(
[(CONTENT_TYPE, "font/woff2")],
include_bytes!("static/fontawesome/webfonts/fa-solid-900.woff2").as_slice(),
)
}
async fn fa_regular_woff2() -> impl IntoResponse {
(
[(CONTENT_TYPE, "font/woff2")],
include_bytes!("static/fontawesome/webfonts/fa-regular-400.woff2").as_slice(),
)
}
async fn fa_brands_woff2() -> impl IntoResponse {
(
[(CONTENT_TYPE, "font/woff2")],
include_bytes!("static/fontawesome/webfonts/fa-brands-400.woff2").as_slice(),
)
}
struct AppError(StatusCode, String); struct AppError(StatusCode, String);
impl IntoResponse for AppError { impl IntoResponse for AppError {