Skip to content

Commit 0e16e37

Browse files
author
David Khristepher Santos
committed
Import/Export tags
1 parent 96366b2 commit 0e16e37

7 files changed

Lines changed: 100 additions & 10 deletions

File tree

Diffusion.Database/DataStore.Tag.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Diffusion.Common.Query;
33
using Diffusion.Database.Models;
44
using System;
5+
using System.Reflection.Emit;
56
using System.Text;
67
using System.Xml.Linq;
78

@@ -51,6 +52,33 @@ public void CreateTag(string name)
5152
db.Close();
5253
}
5354

55+
public void CreateTags(IEnumerable<string> names)
56+
{
57+
using var db = OpenConnection();
58+
59+
lock (_lock)
60+
{
61+
db.BeginTransaction();
62+
try
63+
{
64+
var command = db.CreateCommand("INSERT INTO Tag (Name) VALUES (@Name)");
65+
foreach (var name in names)
66+
{
67+
command.Bind("@Name", name);
68+
command.ExecuteNonQuery();
69+
}
70+
db.Commit();
71+
}
72+
catch (Exception e)
73+
{
74+
db.Rollback();
75+
throw;
76+
}
77+
}
78+
79+
db.Close();
80+
}
81+
5482
public void UpdateTag(int id, string name)
5583
{
5684
using var db = OpenConnection();
@@ -101,7 +129,7 @@ public void AddImageTag(int id, int tagId)
101129
{
102130
using var db = OpenConnection();
103131

104-
var command = db.CreateCommand("REPLACE INTO ImageTag (ImageId, TagId) VALUES (?,?)", id, tagId);
132+
var command = db.CreateCommand("INSERT OR IGNORE INTO ImageTag (ImageId, TagId) VALUES (?,?)", id, tagId);
105133

106134
lock (_lock)
107135
{
@@ -136,7 +164,7 @@ public void AddImagesTag(IEnumerable<int> ids, int tagId)
136164
values.Add($"({id}, {tagId})");
137165
}
138166

139-
var command = db.CreateCommand($"REPLACE INTO ImageTag (ImageId, TagId) VALUES {string.Join(", ", values)}");
167+
var command = db.CreateCommand($"INSERT OR IGNORE INTO ImageTag (ImageId, TagId) VALUES {string.Join(", ", values)}");
140168

141169
lock (_lock)
142170
{

Diffusion.Database/DataStore.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ void SchemaUpdated(object? sender, EventArgs args)
140140

141141
db.CreateTable<Tag>();
142142
db.CreateIndex<Tag>(tag => tag.Id);
143+
db.CreateIndex<Tag>(tag => tag.Name);
143144

144145
db.CreateTable<ImageTag>();
145146
db.CreateIndex<ImageTag>(tag => new { tag.ImageId, tag.TagId }, true);

Diffusion.Toolkit/Localization/default.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@
6262
"Menu.Tools.Folders.FixMissingImages": "_Fix missing images",
6363
"Menu.Tools.Folders.RemoveExcludedImages": "_Remove excluded images",
6464
"Menu.Tools.Folders.CleanRemovedFolders": "_Clean removed folders",
65+
"Menu.Tools.Tags": "Tags",
66+
"Menu.Tools.Tags.Import": "Import",
67+
"Menu.Tools.Tags.Export": "Export",
6568
"Menu.Tools.UnavailableFiles": "Scan for Unavailable images",
6669
"Menu.Help": "_Help",
6770
"Menu.Help.About": "About",
@@ -327,6 +330,8 @@
327330
"Actions.Tags.CannotBeEmpty.Message": "Tag name cannot be empty.",
328331
"Actions.Tags.Create.Title": "New Tag",
329332
"Actions.Tags.Created.Toast": "Tag \"{tag}\" created.",
333+
"Actions.Tags.ImportTags.Title": "Import Tags",
334+
"Actions.Tags.ExportTags.Title": "Export Tags",
330335
"Actions.Tags.Rename.Message": "Enter a new name for the tag",
331336
"Actions.Tags.Rename.Title": "Rename Tag",
332337
"Actions.Tags.Remove.Message": "Are you sure you want to remove \"{tag}\"?",

Diffusion.Toolkit/MainWindow.xaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,10 @@
428428
<MenuItem Header="{lex:Loc Menu.Tools.Folders.RemoveExcludedImages}" Command="{Binding RemoveExcludedImagesCommand}"/>
429429
<MenuItem Header="{lex:Loc Menu.Tools.Folders.CleanRemovedFolders}" Command="{Binding CleanRemovedFoldersCommand}"/>
430430
</MenuItem>
431+
<MenuItem Header="{lex:Loc Menu.Tools.Tags}">
432+
<MenuItem Header="{lex:Loc Menu.Tools.Tags.Import}" Command="{Binding ImportTagsCommand}"/>
433+
<MenuItem Header="{lex:Loc Menu.Tools.Tags.Export}" Command="{Binding ExportTagsCommand}"/>
434+
</MenuItem>
431435
<MenuItem Header="{lex:Loc Menu.Tools.UnavailableFiles}" Command="{Binding UnavailableFilesCommand}"></MenuItem>
432436
</MenuItem>
433437
<MenuItem Header="{lex:Loc Menu.Help}">

Diffusion.Toolkit/MainWindow.xaml.Tags.cs

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
using Diffusion.Database;
2-
using System.Windows.Controls;
3-
using System.Windows;
2+
using Diffusion.Database.Models;
3+
using Diffusion.Toolkit.Classes;
4+
using Diffusion.Toolkit.Models;
5+
using Diffusion.Toolkit.Services;
6+
using Microsoft.WindowsAPICodePack.Dialogs;
47
using SQLite;
58
using System.Collections.Generic;
6-
using System.Linq;
79
using System.Collections.ObjectModel;
10+
using System.IO;
11+
using System.Linq;
812
using System.Threading.Tasks;
9-
using Diffusion.Toolkit.Classes;
10-
using Diffusion.Toolkit.Models;
11-
using Diffusion.Toolkit.Services;
12-
using Diffusion.Database.Models;
13+
using System.Windows;
14+
using System.Windows.Controls;
1315

1416
namespace Diffusion.Toolkit
1517
{
@@ -19,6 +21,47 @@ private void InitTags()
1921
{
2022
ServiceLocator.TagService.LoadTags = LoadTags;
2123

24+
_model.ImportTagsCommand = new AsyncCommand<object>(async (o) =>
25+
{
26+
using var dialog = new CommonOpenFileDialog();
27+
28+
dialog.Title = GetLocalizedText("Actions.Tags.ImportTags.Title");
29+
dialog.Filters.Add(new CommonFileDialogFilter("Text files", "*.txt"));
30+
dialog.Filters.Add(new CommonFileDialogFilter("All files", "*.*"));
31+
dialog.DefaultExtension = "txt";
32+
33+
if (dialog.ShowDialog(this) == CommonFileDialogResult.Ok)
34+
{
35+
var lines = File.ReadAllLines(dialog.FileName);
36+
var allTags = ServiceLocator.DataStore.GetTags();
37+
38+
var tagLookup = allTags.Select(d => d.Name).ToHashSet();
39+
40+
var normalizedlines = lines.Select(d => d.Trim()).Distinct().Where(d => d.Length > 0 && !tagLookup.Contains(d));
41+
42+
ServiceLocator.TagService.CreateTags(normalizedlines);
43+
44+
LoadTags();
45+
}
46+
});
47+
48+
_model.ExportTagsCommand = new AsyncCommand<object>(async (o) =>
49+
{
50+
using var dialog = new CommonSaveFileDialog();
51+
52+
dialog.Title = GetLocalizedText("Actions.Tags.ExportTags.Title");
53+
dialog.Filters.Add(new CommonFileDialogFilter("Text files", "*.txt"));
54+
dialog.Filters.Add(new CommonFileDialogFilter("All files", "*.*"));
55+
dialog.DefaultExtension = "txt";
56+
57+
if (dialog.ShowDialog(this) == CommonFileDialogResult.Ok)
58+
{
59+
var tags = ServiceLocator.DataStore.GetTags();
60+
61+
File.WriteAllLines(dialog.FileName, tags.Select(d => d.Name));
62+
}
63+
});
64+
2265
_model.CreateTagCommand = new AsyncCommand<object>(async (o) =>
2366
{
2467
var title = GetLocalizedText("Actions.Tags.Create.Title");
@@ -97,7 +140,7 @@ private void InitTags()
97140
private void LoadTags()
98141
{
99142
HashSet<int> currentSelected = new HashSet<int>();
100-
143+
101144
if (_model.Tags is { Count: > 0 })
102145
{
103146
currentSelected = _model.Tags.Where(d => d.IsTicked).Select(d => d.Id).ToHashSet();

Diffusion.Toolkit/Models/MainModel.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,10 @@ public ModelViewModel? CurrentModel
569569

570570
public ICommand CreateAlbumCommand { get; set; }
571571

572+
public ICommand ImportTagsCommand { get; set; }
573+
574+
public ICommand ExportTagsCommand { get; set; }
575+
572576
public ICommand CreateTagCommand { get; set; }
573577

574578
public Action<IAlbumInfo> AddSelectedImagesToAlbum { get; set; }

Diffusion.Toolkit/Services/TagService.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ public class TagService
1010
{
1111
public Action LoadTags;
1212

13+
public void CreateTags(IEnumerable<string> names)
14+
{
15+
ServiceLocator.DataStore.CreateTags(names);
16+
}
17+
1318
public void CreateTag(string name)
1419
{
1520
ServiceLocator.DataStore.CreateTag(name);

0 commit comments

Comments
 (0)