mirror of
https://github.com/sphildreth/roadie
synced 2024-11-22 04:03:10 +00:00
Implemented similar artists and fixed bug with deleting associated.
This commit is contained in:
parent
1402cfbb72
commit
7295095460
11 changed files with 154 additions and 8 deletions
|
@ -25,8 +25,8 @@ namespace Roadie.Library.Tests
|
|||
Assert.True(secondHash > 0);
|
||||
Assert.Equal(hash, secondHash);
|
||||
|
||||
var similiar = ImageHasher.Similarity(imageFilename, secondImagFilename);
|
||||
Assert.Equal(100d, similiar);
|
||||
var similar = ImageHasher.Similarity(imageFilename, secondImagFilename);
|
||||
Assert.Equal(100d, similar);
|
||||
|
||||
Assert.True(ImageHasher.ImagesAreSame(imageFilename, secondImagFilename));
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@ namespace Roadie.Library.Data
|
|||
[InverseProperty("Artist")]
|
||||
public ICollection<ArtistAssociation> AssociatedArtists { get; set; }
|
||||
|
||||
[InverseProperty("Artist")]
|
||||
public ICollection<ArtistSimilar> SimilarArtists { get; set; }
|
||||
|
||||
[Column("bandStatus", TypeName = "enum")]
|
||||
public BandStatus? BandStatus { get; set; }
|
||||
|
||||
|
@ -89,6 +92,7 @@ namespace Roadie.Library.Data
|
|||
this.Releases = new HashSet<Release>();
|
||||
this.Genres = new HashSet<ArtistGenre>();
|
||||
this.AssociatedArtists = new HashSet<ArtistAssociation>();
|
||||
this.SimilarArtists = new HashSet<ArtistSimilar>();
|
||||
this.Comments = new HashSet<Comment>();
|
||||
this.Rating = 0;
|
||||
this.Status = Statuses.Ok;
|
||||
|
|
27
Roadie.Api.Library/Data/ArtistSimiliar.cs
Normal file
27
Roadie.Api.Library/Data/ArtistSimiliar.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Roadie.Library.Data
|
||||
{
|
||||
[Table("artistSimilar")]
|
||||
public partial class ArtistSimilar
|
||||
{
|
||||
//[ForeignKey("artistId")]
|
||||
public Artist Artist { get; set; }
|
||||
|
||||
[Column("artistId")]
|
||||
[Required]
|
||||
public int ArtistId { get; set; }
|
||||
|
||||
//[ForeignKey("associatedArtistId")]
|
||||
public Artist SimilarArtist { get; set; }
|
||||
|
||||
[Column("similarArtistId")]
|
||||
public int SimilarArtistId { get; set; }
|
||||
|
||||
[Key]
|
||||
[Column("id")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ namespace Roadie.Library.Data
|
|||
public interface IRoadieDbContext : IDisposable, IInfrastructure<IServiceProvider>, IDbContextDependencies, IDbSetCache, IDbQueryCache, IDbContextPoolable
|
||||
{
|
||||
DbSet<ArtistAssociation> ArtistAssociations { get; set; }
|
||||
DbSet<ArtistSimilar> ArtistSimilar { get; set; }
|
||||
DbSet<ArtistGenre> ArtistGenres { get; set; }
|
||||
DbSet<Artist> Artists { get; set; }
|
||||
DbSet<Bookmark> Bookmarks { get; set; }
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace Roadie.Library.Data
|
|||
public class RoadieDbContext : DbContext, IRoadieDbContext
|
||||
{
|
||||
public DbSet<ArtistAssociation> ArtistAssociations { get; set; }
|
||||
public DbSet<ArtistSimilar> ArtistSimilar { get; set; }
|
||||
public DbSet<ArtistGenre> ArtistGenres { get; set; }
|
||||
public DbSet<Artist> Artists { get; set; }
|
||||
public DbSet<Bookmark> Bookmarks { get; set; }
|
||||
|
|
|
@ -375,6 +375,7 @@ namespace Roadie.Library.Factories
|
|||
|
||||
var artistGenreTables = Artist.Genres.Select(x => new ArtistGenre { ArtistId = Artist.Id, GenreId = x.GenreId }).ToList();
|
||||
var artistAssociatedWith = Artist.AssociatedArtists.Select(x => new ArtistAssociation { ArtistId = Artist.Id, AssociatedArtistId = x.AssociatedArtistId }).ToList();
|
||||
var similarArtists = Artist.SimilarArtists.Select(x => new ArtistSimilar { ArtistId = Artist.Id, SimilarArtistId = x.SimilarArtistId }).ToList();
|
||||
var result = true;
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
@ -393,6 +394,7 @@ namespace Roadie.Library.Factories
|
|||
where at.ArtistId == Artist.Id
|
||||
select at));
|
||||
Artist.AssociatedArtists = artistAssociatedWith;
|
||||
Artist.SimilarArtists = similarArtists;
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
|
||||
var existingImageIds = (from ai in ArtistImages
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Roadie.Library.Models
|
|||
[Serializable]
|
||||
public class Artist : EntityModelBase
|
||||
{
|
||||
public const string DefaultIncludes = "stats,images,associatedartists,comments,collections,playlists,contributions,labels";
|
||||
public const string DefaultIncludes = "stats,images,associatedartists,similarartists,comments,collections,playlists,contributions,labels";
|
||||
|
||||
public IEnumerable<ReleaseList> ArtistContributionReleases;
|
||||
public IEnumerable<LabelList> ArtistLabels;
|
||||
|
@ -29,6 +29,10 @@ namespace Roadie.Library.Models
|
|||
|
||||
public IEnumerable<DataToken> AssociatedArtistsTokens { get; set; }
|
||||
|
||||
public IEnumerable<ArtistList> SimilarArtists { get; set; }
|
||||
|
||||
public IEnumerable<DataToken> SimilarArtistsTokens { get; set; }
|
||||
|
||||
public string BandStatus { get; set; }
|
||||
|
||||
[MaxLength(65535)]
|
||||
|
|
|
@ -667,8 +667,8 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
CollectionId = collection.Id,
|
||||
Position = csvRelease.Position,
|
||||
Artist = csvRelease.Artist,
|
||||
Release = searchName
|
||||
Artist = searchName,
|
||||
Release = csvRelease.Release.NormalizeName()
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -557,10 +557,48 @@ namespace Roadie.Api.Services
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (model.AssociatedArtistsTokens == null || !model.AssociatedArtistsTokens.Any())
|
||||
{
|
||||
artist.AssociatedArtists.Clear();
|
||||
var associatedArtists = DbContext.ArtistAssociations.Include(x => x.AssociatedArtist).Where(x => x.ArtistId == artist.Id || x.AssociatedArtistId == artist.Id).ToList();
|
||||
DbContext.ArtistAssociations.RemoveRange(associatedArtists);
|
||||
}
|
||||
|
||||
if(model.SimilarArtistsTokens != null && model.SimilarArtistsTokens.Any())
|
||||
{
|
||||
var similarArtists = DbContext.ArtistSimilar.Include(x => x.SimilarArtist)
|
||||
.Where(x => x.ArtistId == artist.Id).ToList();
|
||||
|
||||
// Remove existing AssociatedArtists not in model list
|
||||
foreach (var similarArtist in similarArtists)
|
||||
{
|
||||
var doesExistInModel = model.SimilarArtistsTokens.Any(x =>
|
||||
SafeParser.ToGuid(x.Value) == similarArtist.SimilarArtist.RoadieId);
|
||||
if (!doesExistInModel) DbContext.ArtistSimilar.Remove(similarArtist);
|
||||
}
|
||||
|
||||
// Add new SimilarArtists in model not in data
|
||||
foreach (var similarArtist in model.SimilarArtistsTokens)
|
||||
{
|
||||
var similarArtistId = SafeParser.ToGuid(similarArtist.Value);
|
||||
var doesExistInData = similarArtists.Any(x => x.SimilarArtist.RoadieId == similarArtistId);
|
||||
if (!doesExistInData)
|
||||
{
|
||||
var a = DbContext.Artists.FirstOrDefault(x => x.RoadieId == similarArtistId);
|
||||
if (a != null)
|
||||
DbContext.ArtistSimilar.Add(new data.ArtistSimilar
|
||||
{
|
||||
ArtistId = artist.Id,
|
||||
SimilarArtistId = a.Id
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (model.SimilarArtistsTokens == null || !model.SimilarArtistsTokens.Any())
|
||||
{
|
||||
var similarArtists = DbContext.ArtistSimilar.Include(x => x.SimilarArtist).Where(x => x.ArtistId == artist.Id || x.SimilarArtistId == artist.Id).ToList();
|
||||
DbContext.ArtistSimilar.RemoveRange(similarArtists);
|
||||
}
|
||||
|
||||
if (model.Images != null && model.Images.Any())
|
||||
|
@ -816,6 +854,63 @@ namespace Roadie.Api.Services
|
|||
timings.Add("associatedartists", tsw.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
if (includes.Contains("similarartists"))
|
||||
{
|
||||
tsw.Restart();
|
||||
var similarWithArtists = (from aa in DbContext.ArtistSimilar
|
||||
join a in DbContext.Artists on aa.SimilarArtistId equals a.Id
|
||||
where aa.ArtistId == artist.Id
|
||||
select new ArtistList
|
||||
{
|
||||
DatabaseId = a.Id,
|
||||
Id = a.RoadieId,
|
||||
Artist = new DataToken
|
||||
{
|
||||
Text = a.Name,
|
||||
Value = a.RoadieId.ToString()
|
||||
},
|
||||
Thumbnail = MakeArtistThumbnailImage(a.RoadieId),
|
||||
Rating = a.Rating,
|
||||
Rank = a.Rank,
|
||||
CreatedDate = a.CreatedDate,
|
||||
LastUpdated = a.LastUpdated,
|
||||
LastPlayed = a.LastPlayed,
|
||||
PlayedCount = a.PlayedCount,
|
||||
ReleaseCount = a.ReleaseCount,
|
||||
TrackCount = a.TrackCount,
|
||||
SortName = a.SortName
|
||||
}).ToArray();
|
||||
|
||||
var similarArtists = (from aa in DbContext.ArtistSimilar
|
||||
join a in DbContext.Artists on aa.ArtistId equals a.Id
|
||||
where aa.SimilarArtistId == artist.Id
|
||||
select new ArtistList
|
||||
{
|
||||
DatabaseId = a.Id,
|
||||
Id = a.RoadieId,
|
||||
Artist = new DataToken
|
||||
{
|
||||
Text = a.Name,
|
||||
Value = a.RoadieId.ToString()
|
||||
},
|
||||
Thumbnail = MakeArtistThumbnailImage(a.RoadieId),
|
||||
Rating = a.Rating,
|
||||
Rank = a.Rank,
|
||||
CreatedDate = a.CreatedDate,
|
||||
LastUpdated = a.LastUpdated,
|
||||
LastPlayed = a.LastPlayed,
|
||||
PlayedCount = a.PlayedCount,
|
||||
ReleaseCount = a.ReleaseCount,
|
||||
TrackCount = a.TrackCount,
|
||||
SortName = a.SortName
|
||||
}).ToArray();
|
||||
result.SimilarArtists = similarWithArtists.Union(similarArtists, new ArtistListComparer())
|
||||
.OrderBy(x => x.SortName);
|
||||
result.SimilarArtistsTokens = result.SimilarArtists.Select(x => x.Artist).ToArray();
|
||||
tsw.Stop();
|
||||
timings.Add("similarartists", tsw.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
if (includes.Contains("collections"))
|
||||
{
|
||||
tsw.Restart();
|
||||
|
|
|
@ -1269,7 +1269,7 @@ namespace Roadie.Api.Services
|
|||
public Task<subsonic.SubsonicOperationResult<subsonic.Response>> GetSimliarSongs(subsonic.Request request,
|
||||
User roadieUser, subsonic.SimilarSongsVersion version, int? count = 50)
|
||||
{
|
||||
// TODO How to determine similiar songs? Perhaps by genre?
|
||||
// TODO How to determine similar songs? Perhaps by genre?
|
||||
|
||||
switch (version)
|
||||
{
|
||||
|
|
|
@ -8,4 +8,16 @@ CREATE TABLE `collectionMissing` (
|
|||
`release` varchar(1000) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ix_collection_collectionId` (`collectionId`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Create artistSimilar table for < 1.0.2.0 database
|
||||
CREATE TABLE `artistSimilar` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`artistId` int(11) NOT NULL,
|
||||
`similarArtistId` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `similarArtistId` (`similarArtistId`),
|
||||
KEY `idx_artistSimilar` (`artistId`,`similarArtistId`),
|
||||
CONSTRAINT `artistSimilar_ibfk_1` FOREIGN KEY (`artistId`) REFERENCES `artist` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `artistSimilar_ibfk_2` FOREIGN KEY (`similarArtistId`) REFERENCES `artist` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
|
|
Loading…
Reference in a new issue