This commit is contained in:
Tomáš Dvořák
2025-10-16 13:32:05 +02:00
commit 12cba639b9
663 changed files with 168914 additions and 0 deletions
+191
View File
@@ -0,0 +1,191 @@
package services
import (
"fotbal-club/internal/models"
"strings"
"gorm.io/gorm"
)
// FileTracker provides utilities for tracking file usage
type FileTracker struct {
DB *gorm.DB
}
// NewFileTracker creates a new file tracker instance
func NewFileTracker(db *gorm.DB) *FileTracker {
return &FileTracker{DB: db}
}
// TrackFileUpload records a new uploaded file
func (ft *FileTracker) TrackFileUpload(filePath, fileURL, filename, mimeType string, fileSize int64, uploadedByID *uint) error {
file := models.UploadedFile{
Filename: filename,
FilePath: filePath,
FileURL: fileURL,
FileSize: fileSize,
MimeType: mimeType,
UploadedByID: uploadedByID,
}
return ft.DB.Create(&file).Error
}
// TrackFileUsage records or updates file usage for an entity
func (ft *FileTracker) TrackFileUsage(fileURL, entityType string, entityID uint, fieldName string) error {
if fileURL == "" {
return nil
}
// Find the file by URL
var file models.UploadedFile
if err := ft.DB.Where("file_url = ?", fileURL).First(&file).Error; err != nil {
// File not found in database - skip tracking
return nil
}
// Check if usage already exists
var existingUsage models.FileUsage
err := ft.DB.Where("file_id = ? AND entity_type = ? AND entity_id = ? AND field_name = ?",
file.ID, entityType, entityID, fieldName).First(&existingUsage).Error
if err == gorm.ErrRecordNotFound {
// Create new usage record
usage := models.FileUsage{
FileID: file.ID,
EntityType: entityType,
EntityID: entityID,
FieldName: fieldName,
}
return ft.DB.Create(&usage).Error
}
return err
}
// RemoveFileUsage removes a file usage record
func (ft *FileTracker) RemoveFileUsage(fileURL, entityType string, entityID uint, fieldName string) error {
if fileURL == "" {
return nil
}
// Find the file by URL
var file models.UploadedFile
if err := ft.DB.Where("file_url = ?", fileURL).First(&file).Error; err != nil {
return nil
}
return ft.DB.Where("file_id = ? AND entity_type = ? AND entity_id = ? AND field_name = ?",
file.ID, entityType, entityID, fieldName).Delete(&models.FileUsage{}).Error
}
// UpdateFileUsages updates all file usages for an entity (removes old, adds new)
func (ft *FileTracker) UpdateFileUsages(entityType string, entityID uint, fieldURLMap map[string]string) error {
// Get all current usages for this entity
var currentUsages []models.FileUsage
ft.DB.Where("entity_type = ? AND entity_id = ?", entityType, entityID).Find(&currentUsages)
// Create a map of current usages
currentMap := make(map[string]models.FileUsage)
for _, usage := range currentUsages {
key := usage.FieldName
currentMap[key] = usage
}
// Track new usages
for fieldName, fileURL := range fieldURLMap {
if fileURL != "" {
// Check if already tracked
if _, exists := currentMap[fieldName]; !exists {
ft.TrackFileUsage(fileURL, entityType, entityID, fieldName)
}
delete(currentMap, fieldName) // Remove from current map
}
}
// Remove usages that are no longer present
for fieldName := range currentMap {
ft.DB.Where("entity_type = ? AND entity_id = ? AND field_name = ?",
entityType, entityID, fieldName).Delete(&models.FileUsage{})
}
return nil
}
// TrackArticleFiles tracks all file usages in an article
func (ft *FileTracker) TrackArticleFiles(article *models.Article) error {
fieldURLMap := map[string]string{
"image_url": article.ImageURL,
"og_image_url": article.OGImageURL,
}
// Track attachments if present
if article.Attachments != "" {
// Attachments is a JSON array of URLs
// For simplicity, we'll track each attachment URL separately
// You might want to parse the JSON properly in production
attachments := strings.Split(article.Attachments, ",")
for i, attachment := range attachments {
attachment = strings.Trim(attachment, `[]" `)
if attachment != "" {
fieldName := "attachments"
if i > 0 {
// If multiple attachments, differentiate them
fieldName = "attachments"
}
fieldURLMap[fieldName] = attachment
}
}
}
return ft.UpdateFileUsages("article", article.ID, fieldURLMap)
}
// TrackPlayerFiles tracks all file usages in a player
func (ft *FileTracker) TrackPlayerFiles(player *models.Player) error {
fieldURLMap := map[string]string{
"image_url": player.ImageURL,
}
return ft.UpdateFileUsages("player", player.ID, fieldURLMap)
}
// TrackSponsorFiles tracks all file usages in a sponsor
func (ft *FileTracker) TrackSponsorFiles(sponsor *models.Sponsor) error {
fieldURLMap := map[string]string{
"logo_url": sponsor.LogoURL,
}
return ft.UpdateFileUsages("sponsor", sponsor.ID, fieldURLMap)
}
// TrackEventFiles tracks all file usages in an event
func (ft *FileTracker) TrackEventFiles(event *models.Event) error {
fieldURLMap := map[string]string{
"image_url": event.ImageURL,
"file_url": event.FileURL,
}
return ft.UpdateFileUsages("event", event.ID, fieldURLMap)
}
// TrackContactFiles tracks all file usages in a contact
func (ft *FileTracker) TrackContactFiles(contact *models.Contact) error {
fieldURLMap := map[string]string{
"image_url": contact.ImageURL,
}
return ft.UpdateFileUsages("contact", contact.ID, fieldURLMap)
}
// TrackSettingsFiles tracks all file usages in settings
func (ft *FileTracker) TrackSettingsFiles(settings *models.Settings) error {
fieldURLMap := map[string]string{
"default_og_image_url": settings.DefaultOGImageURL,
"club_logo_url": settings.ClubLogoURL,
}
return ft.UpdateFileUsages("settings", settings.ID, fieldURLMap)
}
// TrackTeamFiles tracks all file usages in a team
func (ft *FileTracker) TrackTeamFiles(team *models.Team) error {
fieldURLMap := map[string]string{
"logo_url": team.LogoURL,
}
return ft.UpdateFileUsages("team", team.ID, fieldURLMap)
}