summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-07-18 20:04:03 +0300
committerPaul Buetow <paul@buetow.org>2025-07-18 20:04:03 +0300
commit186629c94152c9066158edb1b0105737ed39d6da (patch)
treef4326ab8dc7ffa4ba9a6d6184252cdc4115079e5
parent85900734f1ab76b1079d935e046b6edcbfab84ae (diff)
fix: use unique filenames in Anki exports by prefixing with card ID
- Fixed issue where all cards used the same filenames (audio.mp3, image.jpg) - Now prefixes media files with card ID (directory name) in Anki exports - Updated both CSV and APKG generators to use unique names - Ensures Anki properly associates correct media with each card - Files in directories remain unchanged, only Anki references are prefixed 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
-rw-r--r--internal/anki/apkg_generator.go48
-rw-r--r--internal/anki/generator.go25
2 files changed, 53 insertions, 20 deletions
diff --git a/internal/anki/apkg_generator.go b/internal/anki/apkg_generator.go
index 6f0043f..6da0cfb 100644
--- a/internal/anki/apkg_generator.go
+++ b/internal/anki/apkg_generator.go
@@ -504,19 +504,29 @@ func (g *APKGGenerator) insertNotesAndCards(db *sql.DB) error {
imageField := ""
if card.ImageFile != "" && fileExists(card.ImageFile) {
- basename := filepath.Base(card.ImageFile)
- if _, ok := g.mediaFiles[basename]; ok {
- // Use the original filename in the card content
- imageField = fmt.Sprintf(`<img src="%s">`, basename)
+ // Get card ID from the source path (parent directory name)
+ cardID := filepath.Base(filepath.Dir(card.ImageFile))
+ originalFilename := filepath.Base(card.ImageFile)
+ // Create unique filename with card ID prefix
+ uniqueFilename := fmt.Sprintf("%s_%s", cardID, originalFilename)
+
+ if _, ok := g.mediaFiles[uniqueFilename]; ok {
+ // Use the unique filename in the card content
+ imageField = fmt.Sprintf(`<img src="%s">`, uniqueFilename)
}
}
audioField := ""
if card.AudioFile != "" && fileExists(card.AudioFile) {
- basename := filepath.Base(card.AudioFile)
- if _, ok := g.mediaFiles[basename]; ok {
- // Use the original filename in the card content
- audioField = fmt.Sprintf("[sound:%s]", basename)
+ // Get card ID from the source path (parent directory name)
+ cardID := filepath.Base(filepath.Dir(card.AudioFile))
+ originalFilename := filepath.Base(card.AudioFile)
+ // Create unique filename with card ID prefix
+ uniqueFilename := fmt.Sprintf("%s_%s", cardID, originalFilename)
+
+ if _, ok := g.mediaFiles[uniqueFilename]; ok {
+ // Use the unique filename in the card content
+ audioField = fmt.Sprintf("[sound:%s]", uniqueFilename)
}
}
@@ -588,26 +598,36 @@ func (g *APKGGenerator) copyMediaFiles(tempDir string) error {
for _, card := range g.cards {
// Copy audio file
if card.AudioFile != "" && fileExists(card.AudioFile) {
- filename := filepath.Base(card.AudioFile)
- if _, exists := g.mediaFiles[filename]; !exists {
+ // Get card ID from the source path (parent directory name)
+ cardID := filepath.Base(filepath.Dir(card.AudioFile))
+ originalFilename := filepath.Base(card.AudioFile)
+ // Create unique filename with card ID prefix
+ uniqueFilename := fmt.Sprintf("%s_%s", cardID, originalFilename)
+
+ if _, exists := g.mediaFiles[uniqueFilename]; !exists {
targetPath := filepath.Join(tempDir, fmt.Sprintf("%d", g.mediaCounter))
if err := copyFile(card.AudioFile, targetPath); err != nil {
return fmt.Errorf("failed to copy audio file %s: %w", card.AudioFile, err)
}
- g.mediaFiles[filename] = g.mediaCounter
+ g.mediaFiles[uniqueFilename] = g.mediaCounter
g.mediaCounter++
}
}
// Copy image file
if card.ImageFile != "" && fileExists(card.ImageFile) {
- filename := filepath.Base(card.ImageFile)
- if _, exists := g.mediaFiles[filename]; !exists {
+ // Get card ID from the source path (parent directory name)
+ cardID := filepath.Base(filepath.Dir(card.ImageFile))
+ originalFilename := filepath.Base(card.ImageFile)
+ // Create unique filename with card ID prefix
+ uniqueFilename := fmt.Sprintf("%s_%s", cardID, originalFilename)
+
+ if _, exists := g.mediaFiles[uniqueFilename]; !exists {
targetPath := filepath.Join(tempDir, fmt.Sprintf("%d", g.mediaCounter))
if err := copyFile(card.ImageFile, targetPath); err != nil {
return fmt.Errorf("failed to copy image file %s: %w", card.ImageFile, err)
}
- g.mediaFiles[filename] = g.mediaCounter
+ g.mediaFiles[uniqueFilename] = g.mediaCounter
g.mediaCounter++
}
}
diff --git a/internal/anki/generator.go b/internal/anki/generator.go
index 0682d94..0b393f3 100644
--- a/internal/anki/generator.go
+++ b/internal/anki/generator.go
@@ -109,8 +109,12 @@ func (g *Generator) formatAudioField(audioFile string) string {
return ""
}
- // Get just the filename
- filename := filepath.Base(audioFile)
+ // Get card ID from the source path (parent directory name)
+ cardID := filepath.Base(filepath.Dir(audioFile))
+ originalFilename := filepath.Base(audioFile)
+
+ // Create filename with card ID prefix for uniqueness in Anki
+ filename := fmt.Sprintf("%s_%s", cardID, originalFilename)
// Anki audio format: [sound:filename.mp3]
return fmt.Sprintf("[sound:%s]", filename)
@@ -122,8 +126,13 @@ func (g *Generator) formatImageField(imageFile string) string {
return ""
}
- // Get just the filename
- filename := filepath.Base(imageFile)
+ // Get card ID from the source path (parent directory name)
+ cardID := filepath.Base(filepath.Dir(imageFile))
+ originalFilename := filepath.Base(imageFile)
+
+ // Create filename with card ID prefix for uniqueness in Anki
+ filename := fmt.Sprintf("%s_%s", cardID, originalFilename)
+
return fmt.Sprintf(`<img src="%s">`, filename)
}
@@ -279,8 +288,12 @@ func (g *Generator) copyMediaFile(src, destDir string) (string, error) {
return "", err
}
- // Create destination path
- filename := filepath.Base(src)
+ // Get the card ID from the source path (parent directory name)
+ cardID := filepath.Base(filepath.Dir(src))
+
+ // Create destination filename with card ID prefix
+ originalFilename := filepath.Base(src)
+ filename := fmt.Sprintf("%s_%s", cardID, originalFilename)
destPath := filepath.Join(destDir, filename)
// Check if file already exists