Skip to content

Commit

Permalink
Support custom tags provided by plugin (scripts).
Browse files Browse the repository at this point in the history
 Settings dialog has new tab to define custom tags.
 These tags can be then be consumed by other scripts (library/playlist)
 or read directly.

 The values are persisted to the database so can be searched etc like
 normal meta data.
  • Loading branch information
pudding committed Jan 28, 2024
1 parent 7d460da commit 7bd0218
Show file tree
Hide file tree
Showing 50 changed files with 1,561 additions and 60 deletions.
9 changes: 9 additions & 0 deletions FoxTunes.Core/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -529,5 +529,14 @@ public static float Similarity(this string subject, string value, bool ignoreSpa
var distance = subject.Distance(value, false);
return (1.0f - ((float)distance / (float)Math.Max(subject.Length, value.Length)));
}

public static IList<T> AsList<T>(this IEnumerable<T> sequence)
{
if (sequence is IList<T> list)
{
return list;
}
return sequence.ToList();
}
}
}
3 changes: 2 additions & 1 deletion FoxTunes.Core/Interfaces/Database/IDatabaseInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public enum DatabaseInitializeType : byte
None = 0,
Library = 1,
Playlist = 2,
All = Library | Playlist
MetaData = 4,
All = Library | Playlist | MetaData
}
}
2 changes: 2 additions & 0 deletions FoxTunes.Core/Interfaces/Database/IDatabaseTables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ public interface IDatabaseTables : IBaseComponent
ITableConfig LibraryHierarchyLevel { get; }

ITableConfig LibraryHierarchyNode { get; }

ITableConfig MetaDataProvider { get; }
}
}
8 changes: 1 addition & 7 deletions FoxTunes.Core/Interfaces/Factories/IMessageSinkFactory.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FoxTunes.Interfaces
namespace FoxTunes.Interfaces
{
public interface IMessageSinkFactory : IBaseFactory
{
Expand Down
13 changes: 13 additions & 0 deletions FoxTunes.Core/Interfaces/Factories/IMetaDataDecoratorFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;

namespace FoxTunes.Interfaces
{
public interface IMetaDataDecoratorFactory : IStandardFactory
{
IEnumerable<KeyValuePair<string, MetaDataItemType>> Supported { get; }

bool CanCreate { get; }

IMetaDataDecorator Create();
}
}
2 changes: 2 additions & 0 deletions FoxTunes.Core/Interfaces/IStandardComponents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public interface IStandardComponents

IMetaDataCache MetaDataCache { get; }

IMetaDataProviderCache MetaDataProviderCache { get; }

IMetaDataSynchronizer MetaDataSynchronizer { get; }

IOnDemandMetaDataProvider OnDemandMetaDataProvider { get; }
Expand Down
2 changes: 2 additions & 0 deletions FoxTunes.Core/Interfaces/IStandardFactories.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ public interface IStandardFactories
IDatabaseFactory Database { get; }

IMetaDataSourceFactory MetaDataSource { get; }

IMetaDataDecoratorFactory MetaDataDecorator { get; }
}
}
2 changes: 2 additions & 0 deletions FoxTunes.Core/Interfaces/IStandardManagers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public interface IStandardManagers

IMetaDataManager MetaData { get; }

IMetaDataProviderManager MetaDataProvider { get; }

IFileActionHandlerManager FileActionHandler { get; }
}
}
9 changes: 9 additions & 0 deletions FoxTunes.Core/Interfaces/Managers/IMetaDataProviderManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace FoxTunes.Interfaces
{
public interface IMetaDataProviderManager : IStandardManager, IDatabaseInitializer
{
IMetaDataProvider GetProvider(MetaDataProvider metaDataProvider);

MetaDataProvider[] GetProviders();
}
}
13 changes: 13 additions & 0 deletions FoxTunes.Core/Interfaces/MetaData/IMetaDataDecorator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;

namespace FoxTunes.Interfaces
{
public interface IMetaDataDecorator : IBaseComponent
{
IEnumerable<string> GetWarnings(string fileName);

void Decorate(string fileName, IList<MetaDataItem> metaDataItems, ISet<string> names = null);

void Decorate(IFileAbstraction fileAbstraction, IList<MetaDataItem> metaDataItems, ISet<string> names = null);
}
}
13 changes: 13 additions & 0 deletions FoxTunes.Core/Interfaces/MetaData/IMetaDataProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;

namespace FoxTunes.Interfaces
{
public interface IMetaDataProvider : IBaseComponent
{
MetaDataProviderType Type { get; }

bool AddOrUpdate(string fileName, IList<MetaDataItem> metaDataItems, MetaDataProvider provider);

bool AddOrUpdate(IFileAbstraction fileAbstraction, IList<MetaDataItem> metaDataItems, MetaDataProvider provider);
}
}
10 changes: 10 additions & 0 deletions FoxTunes.Core/Interfaces/MetaData/IMetaDataProviderCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;

namespace FoxTunes.Interfaces
{
public interface IMetaDataProviderCache : IStandardComponent
{
MetaDataProvider[] GetProviders(Func<IEnumerable<MetaDataProvider>> factory);
}
}
14 changes: 10 additions & 4 deletions FoxTunes.Core/Library/LibraryHierarchyPopulator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,12 +285,18 @@ protected IEnumerable<string> GetRoots()

protected override void OnDisposing()
{
foreach (var context in this.Contexts.Values)
if (this.Contexts != null)
{
context.Dispose();
foreach (var context in this.Contexts.Values)
{
context.Dispose();
}
this.Contexts.Dispose();
}
if (this.Writer != null)
{
this.Writer.Dispose();
}
this.Contexts.Dispose();
this.Writer.Dispose();
base.OnDisposing();
}
}
Expand Down
4 changes: 4 additions & 0 deletions FoxTunes.Core/Library/LibraryUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ protected override void OnElapsed(object sender, ElapsedEventArgs e)
{
lock (SyncRoot)
{
if (this.Timer == null)
{
return;
}
switch (this.Timer.Interval)
{
case NORMAL_INTERVAL:
Expand Down
95 changes: 95 additions & 0 deletions FoxTunes.Core/Managers/MetaDataProviderManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using FoxDb;
using FoxTunes.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;

namespace FoxTunes
{
[ComponentDependency(Slot = ComponentSlots.Database)]
public class MetaDataProviderManager : StandardManager, IMetaDataProviderManager
{
public MetaDataProviderManager()
{
this._Providers = new Lazy<IDictionary<MetaDataProviderType, IMetaDataProvider>>(
() => ComponentRegistry.Instance.GetComponents<IMetaDataProvider>().ToDictionary(
component => component.Type
)
);
}

public Lazy<IDictionary<MetaDataProviderType, IMetaDataProvider>> _Providers { get; private set; }

public IMetaDataProviderCache MetaDataProviderCache { get; private set; }

public IDatabaseFactory DatabaseFactory { get; private set; }

public override void InitializeComponent(ICore core)
{
this.MetaDataProviderCache = core.Components.MetaDataProviderCache;
this.DatabaseFactory = core.Factories.Database;
base.InitializeComponent(core);
}

public IMetaDataProvider GetProvider(MetaDataProvider metaDataProvider)
{
var provider = default(IMetaDataProvider);
if (!this._Providers.Value.TryGetValue(metaDataProvider.Type, out provider))
{
return null;
}
return provider;
}

public MetaDataProvider[] GetProviders()
{
return this.MetaDataProviderCache.GetProviders(this.GetProvidersCore);
}

public IEnumerable<MetaDataProvider> GetProvidersCore()
{
using (var database = this.DatabaseFactory.Create())
{
using (var transaction = database.BeginTransaction(database.PreferredIsolationLevel))
{
var set = database.Set<MetaDataProvider>(transaction);
//It's easier to just filter enabled/disabled in memory, there isn't much data.
//set.Fetch.Filter.AddColumn(
// set.Table.GetColumn(ColumnConfig.By("Enabled", ColumnFlags.None))
//).With(filter => filter.Right = filter.CreateConstant(1));
foreach (var element in set)
{
yield return element;
}
}
}
}

public string Checksum
{
get
{
return "6E3C885D-65D6-4A69-9991-CEC5156121A5";
}
}

public void InitializeDatabase(IDatabaseComponent database, DatabaseInitializeType type)
{
//IMPORTANT: When editing this function remember to change the checksum.
if (!type.HasFlag(DatabaseInitializeType.MetaData))
{
return;
}
using (var transaction = database.BeginTransaction(database.PreferredIsolationLevel))
{
var set = database.Set<LibraryHierarchy>(transaction);
set.Clear();
//No default data, yet.
if (transaction.HasTransaction)
{
transaction.Commit();
}
}
}
}
}
3 changes: 2 additions & 1 deletion FoxTunes.Core/MetaData/MetaDataItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ public enum MetaDataItemType : byte
Image = 4,
Statistic = 8,
Document = 16,
All = Tag | Property | Image | Statistic | Document
CustomTag = 32,
All = Tag | Property | Image | Statistic | Document | CustomTag
}
}
122 changes: 122 additions & 0 deletions FoxTunes.Core/MetaData/MetaDataProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using System;

namespace FoxTunes
{
public class MetaDataProvider : PersistableComponent
{
public MetaDataProvider()
{

}

private string _Name { get; set; }

public string Name
{
get
{
return this._Name;
}
set
{
this._Name = value;
this.OnNameChanged();
}
}

protected virtual void OnNameChanged()
{
if (this.NameChanged != null)
{
this.NameChanged(this, EventArgs.Empty);
}
this.OnPropertyChanged("Name");
}

public event EventHandler NameChanged;

private MetaDataProviderType _Type { get; set; }

public MetaDataProviderType Type
{
get
{
return this._Type;
}
set
{
this._Type = value;
this.OnTypeChanged();
}
}

protected virtual void OnTypeChanged()
{
if (this.TypeChanged != null)
{
this.TypeChanged(this, EventArgs.Empty);
}
this.OnPropertyChanged("Type");
}

public event EventHandler TypeChanged;

private string _Script { get; set; }

public string Script
{
get
{
return this._Script;
}
set
{
this._Script = value;
this.OnScriptChanged();
}
}

protected virtual void OnScriptChanged()
{
if (this.ScriptChanged != null)
{
this.ScriptChanged(this, EventArgs.Empty);
}
this.OnPropertyChanged("Script");
}

public event EventHandler ScriptChanged;

private bool _Enabled { get; set; }

public bool Enabled
{
get
{
return this._Enabled;
}
set
{
this._Enabled = value;
this.OnEnabledChanged();
}
}

protected virtual void OnEnabledChanged()
{
if (this.EnabledChanged != null)
{
this.EnabledChanged(this, EventArgs.Empty);
}
this.OnPropertyChanged("Enabled");
}

public event EventHandler EnabledChanged;
}

public enum MetaDataProviderType : byte
{
None = 0,
Script = 1
}
}
Loading

0 comments on commit 7bd0218

Please sign in to comment.