add current db layout and data

add handling for mounted export template directory
fixed naming problems and port exposure
This commit is contained in:
2025-12-27 08:27:34 +01:00
parent 29947ed4a4
commit 5f952742c8
7 changed files with 302 additions and 16 deletions
+8
View File
@@ -56,6 +56,14 @@ func main() {
database.ConnectDatabase()
logger.Info("Datenbankverbindung erfolgreich")
// Initialize PDF templates
logger.Debug("Initialisiere PDF-Templates...")
if err := pdfrender.InitializeTemplates("/app/default_templates", cfg.TemplatesDir); err != nil {
logger.Warn("Fehler beim Initialisieren der Templates: %s", err.Error())
} else {
logger.Info("PDF-Templates erfolgreich initialisiert")
}
r := gin.Default()
router.SetupGin(r)
+175
View File
@@ -0,0 +1,175 @@
package pdfrender
import (
"bamort/logger"
"fmt"
"io"
"os"
"path/filepath"
)
// InitializeTemplates copies default templates to target directory if they don't exist
// or if the content has changed (for development updates)
// This should be called once during application startup
func InitializeTemplates(defaultDir, targetDir string) error {
// Check if default directory exists
if _, err := os.Stat(defaultDir); os.IsNotExist(err) {
return fmt.Errorf("default templates directory does not exist: %s", defaultDir)
}
// Read default templates
entries, err := os.ReadDir(defaultDir)
if err != nil {
return fmt.Errorf("failed to read default templates: %w", err)
}
// Process each template directory
for _, entry := range entries {
if !entry.IsDir() {
continue
}
srcDir := filepath.Join(defaultDir, entry.Name())
dstDir := filepath.Join(targetDir, entry.Name())
// Copy or update template directory
updated, err := syncDir(srcDir, dstDir)
if err != nil {
return fmt.Errorf("failed to sync template %s: %w", entry.Name(), err)
}
if updated {
logger.Info("Initialized/updated template: %s", entry.Name())
} else {
logger.Debug("Template %s is up to date", entry.Name())
}
}
return nil
}
// syncDir synchronizes source directory to destination, copying only changed files
// Returns true if any files were updated
func syncDir(src, dst string) (bool, error) {
// Get source directory info
srcInfo, err := os.Stat(src)
if err != nil {
return false, err
}
// Create destination directory if it doesn't exist
if err := os.MkdirAll(dst, srcInfo.Mode()); err != nil {
return false, err
}
// Read source directory entries
entries, err := os.ReadDir(src)
if err != nil {
return false, err
}
updated := false
// Copy each entry
for _, entry := range entries {
srcPath := filepath.Join(src, entry.Name())
dstPath := filepath.Join(dst, entry.Name())
if entry.IsDir() {
// Recursively sync subdirectory
subUpdated, err := syncDir(srcPath, dstPath)
if err != nil {
return false, err
}
if subUpdated {
updated = true
}
} else {
// Check if file needs to be copied
needsCopy, err := fileNeedsUpdate(srcPath, dstPath)
if err != nil {
return false, err
}
if needsCopy {
if err := copyFile(srcPath, dstPath); err != nil {
return false, err
}
updated = true
}
}
}
return updated, nil
}
// fileNeedsUpdate checks if destination file is missing or differs from source
func fileNeedsUpdate(src, dst string) (bool, error) {
// If destination doesn't exist, needs update
dstInfo, err := os.Stat(dst)
if os.IsNotExist(err) {
return true, nil
}
if err != nil {
return false, err
}
// Get source info
srcInfo, err := os.Stat(src)
if err != nil {
return false, err
}
// Quick check: if sizes differ, files differ
if srcInfo.Size() != dstInfo.Size() {
return true, nil
}
// Compare file contents
return filesContentDiffer(src, dst)
}
// filesContentDiffer compares file contents
func filesContentDiffer(file1, file2 string) (bool, error) {
content1, err := os.ReadFile(file1)
if err != nil {
return false, err
}
content2, err := os.ReadFile(file2)
if err != nil {
return false, err
}
// Files differ if contents don't match
return string(content1) != string(content2), nil
}
// copyFile copies a single file
func copyFile(src, dst string) error {
// Open source file
srcFile, err := os.Open(src)
if err != nil {
return err
}
defer srcFile.Close()
// Get source file info
srcInfo, err := srcFile.Stat()
if err != nil {
return err
}
// Create destination file
dstFile, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, srcInfo.Mode())
if err != nil {
return err
}
defer dstFile.Close()
// Copy contents
if _, err := io.Copy(dstFile, srcFile); err != nil {
return err
}
return nil
}
+105
View File
@@ -0,0 +1,105 @@
package pdfrender
import (
"os"
"path/filepath"
"testing"
)
func TestInitializeTemplates(t *testing.T) {
// Setup test directories
tmpDir := t.TempDir()
defaultDir := filepath.Join(tmpDir, "default_templates")
targetDir := filepath.Join(tmpDir, "templates")
// Create default templates directory with test files
if err := os.MkdirAll(filepath.Join(defaultDir, "TestTemplate"), 0755); err != nil {
t.Fatalf("Failed to create default template dir: %v", err)
}
testFile := filepath.Join(defaultDir, "TestTemplate", "page1.html")
if err := os.WriteFile(testFile, []byte("test content"), 0644); err != nil {
t.Fatalf("Failed to create test file: %v", err)
}
// Test 1: Copy when target directory doesn't exist
if err := InitializeTemplates(defaultDir, targetDir); err != nil {
t.Errorf("InitializeTemplates failed: %v", err)
}
// Verify file was copied
copiedFile := filepath.Join(targetDir, "TestTemplate", "page1.html")
if _, err := os.Stat(copiedFile); os.IsNotExist(err) {
t.Error("Expected file was not copied")
}
content, err := os.ReadFile(copiedFile)
if err != nil || string(content) != "test content" {
t.Error("Copied file content doesn't match")
}
// Test 2: Don't overwrite when content is identical
if err := InitializeTemplates(defaultDir, targetDir); err != nil {
t.Errorf("InitializeTemplates failed on second run: %v", err)
}
// Verify file still has same content
content, err = os.ReadFile(copiedFile)
if err != nil || string(content) != "test content" {
t.Error("File content should remain unchanged")
}
// Test 3: Update when default template changed
updatedContent := []byte("updated test content")
if err := os.WriteFile(testFile, updatedContent, 0644); err != nil {
t.Fatalf("Failed to update source file: %v", err)
}
if err := InitializeTemplates(defaultDir, targetDir); err != nil {
t.Errorf("InitializeTemplates failed after source update: %v", err)
}
// Verify file was updated
content, err = os.ReadFile(copiedFile)
if err != nil || string(content) != "updated test content" {
t.Error("File should have been updated with new content")
}
// Test 4: Handle missing default directory gracefully
if err := InitializeTemplates("/nonexistent", targetDir); err == nil {
t.Error("Expected error for nonexistent default directory")
}
}
func TestInitializeTemplatesWithMultipleFiles(t *testing.T) {
tmpDir := t.TempDir()
defaultDir := filepath.Join(tmpDir, "default_templates")
targetDir := filepath.Join(tmpDir, "templates")
// Create multiple templates and files
templates := []string{"Template1", "Template2"}
for _, tmpl := range templates {
tmplDir := filepath.Join(defaultDir, tmpl)
if err := os.MkdirAll(tmplDir, 0755); err != nil {
t.Fatalf("Failed to create template dir: %v", err)
}
for i := 1; i <= 3; i++ {
file := filepath.Join(tmplDir, filepath.Base(tmpl)+".html")
if err := os.WriteFile(file, []byte("content "+tmpl), 0644); err != nil {
t.Fatalf("Failed to create file: %v", err)
}
}
}
// Initialize templates
if err := InitializeTemplates(defaultDir, targetDir); err != nil {
t.Fatalf("InitializeTemplates failed: %v", err)
}
// Verify all templates were copied
for _, tmpl := range templates {
tmplDir := filepath.Join(targetDir, tmpl)
if _, err := os.Stat(tmplDir); os.IsNotExist(err) {
t.Errorf("Template directory %s was not copied", tmpl)
}
}
}