Added User and Subsonic API service and controllers.

This commit is contained in:
Steven Hildreth 2018-11-15 09:10:29 -06:00
parent 8c02b6fd1e
commit 06b0bfffe5
42 changed files with 2346 additions and 2270 deletions

View file

@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Roadie.Api.Services;
using Roadie.Library.Caching;
using Roadie.Library.Identity;
using Roadie.Library.Models.Pagination;
using System.Net;
using System.Threading.Tasks;
namespace Roadie.Api.Controllers
{
[Produces("application/json")]
[Route("subsonic")]
[ApiController]
[Authorize]
public class SubsonicController : EntityControllerBase
{
private ISubsonicService SubsonicService { get; }
public SubsonicController(ISubsonicService subsonicService, ILoggerFactory logger, ICacheManager cacheManager, IConfiguration configuration, UserManager<ApplicationUser> userManager)
: base(cacheManager, configuration, userManager)
{
this._logger = logger.CreateLogger("RoadieApi.Controllers.SubsonicController");
this.SubsonicService = subsonicService;
}
}
}

View file

@ -0,0 +1,70 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Roadie.Api.Services;
using Roadie.Library.Caching;
using Roadie.Library.Identity;
using Roadie.Library.Models.Pagination;
using System.Net;
using System.Threading.Tasks;
namespace Roadie.Api.Controllers
{
[Produces("application/json")]
[Route("user")]
[ApiController]
[Authorize]
public class UserController : EntityControllerBase
{
private IUserService UserService { get; }
public UserController(IUserService userService, ILoggerFactory logger, ICacheManager cacheManager, IConfiguration configuration, UserManager<ApplicationUser> userManager)
: base(cacheManager, configuration, userManager)
{
this._logger = logger.CreateLogger("RoadieApi.Controllers.LabelController");
this.UserService = userService;
}
//[EnableQuery]
//public IActionResult Get()
//{
// return Ok(this._RoadieDbContext.Labels.ProjectToType<models.Label>());
//}
//[HttpGet("{id}")]
//[ProducesResponseType(200)]
//[ProducesResponseType(404)]
//public IActionResult Get(Guid id)
//{
// var key = id.ToString();
// var result = this._cacheManager.Get<models.Label>(key, () =>
// {
// var d = this._RoadieDbContext.Labels.FirstOrDefault(x => x.RoadieId == id);
// if (d != null)
// {
// return d.Adapt<models.Label>();
// }
// return null;
// }, key);
// if (result == null)
// {
// return NotFound();
// }
// return Ok(result);
//}
[HttpPost]
[ProducesResponseType(200)]
public async Task<IActionResult> List(PagedRequest request)
{
var result = await this.UserService.List(request);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
return Ok(result);
}
}
}

View file

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Roadie.Api.Services
{
public interface ISubsonicService
{
}
}

View file

@ -0,0 +1,11 @@
using System.Threading.Tasks;
using Roadie.Library.Models.Pagination;
using Roadie.Library.Models.Users;
namespace Roadie.Api.Services
{
public interface IUserService
{
Task<PagedResult<UserList>> List(PagedRequest request);
}
}

View file

@ -0,0 +1,47 @@
using Mapster;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Roadie.Library;
using Roadie.Library.Caching;
using Roadie.Library.Configuration;
using Roadie.Library.Encoding;
using Roadie.Library.Enums;
using Roadie.Library.Extensions;
using Roadie.Library.Models;
using Roadie.Library.Models.Pagination;
using Roadie.Library.Models.Releases;
using Roadie.Library.Models.Statistics;
using Roadie.Library.Models.Users;
using Roadie.Library.Models.ThirdPartyApi.Subsonic;
using Roadie.Library.Utility;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using data = Roadie.Library.Data;
namespace Roadie.Api.Services
{
/// <summary>
/// Subsonic API emulator for Roadie. Enables Subsonic clients to work with Roadie.
/// <seealso cref="http://www.subsonic.org/pages/inc/api/schema/subsonic-rest-api-1.16.1.xsd">
/// <seealso cref="http://www.subsonic.org/pages/api.jsp#getIndexes"/>
/// <!-- Generated the classes from the schema above using 'xsd subsonic-rest-api-1.16.1.xsd /c /f /n:Roadie.Library.Models.Subsonic' from Visual Studio Command Prompt -->
/// </summary>
public class SubsonicService : ServiceBase, ISubsonicService
{
public SubsonicService(IRoadieSettings configuration,
IHttpEncoder httpEncoder,
IHttpContext httpContext,
data.IRoadieDbContext context,
ICacheManager cacheManager,
ILogger<ArtistService> logger,
ICollectionService collectionService,
IPlaylistService playlistService)
: base(configuration, httpEncoder, context, cacheManager, logger, httpContext)
{
}
}
}

View file

@ -0,0 +1,152 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Roadie.Library.Caching;
using Roadie.Library.Configuration;
using Roadie.Library.Encoding;
using Roadie.Library.Models;
using Roadie.Library.Models.Pagination;
using Roadie.Library.Models.Statistics;
using Roadie.Library.Models.Users;
using Roadie.Library.Utility;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using data = Roadie.Library.Data;
namespace Roadie.Api.Services
{
public class UserService : ServiceBase, IUserService
{
public UserService(IRoadieSettings configuration,
IHttpEncoder httpEncoder,
IHttpContext httpContext,
data.IRoadieDbContext context,
ICacheManager cacheManager,
ILogger<ArtistService> logger,
ICollectionService collectionService,
IPlaylistService playlistService)
: base(configuration, httpEncoder, context, cacheManager, logger, httpContext)
{
}
public async Task<Library.Models.Pagination.PagedResult<UserList>> List(PagedRequest request)
{
var sw = new Stopwatch();
sw.Start();
if (!string.IsNullOrEmpty(request.Sort))
{
request.Sort = request.Sort.Replace("createdDate", "createdDateTime");
request.Sort = request.Sort.Replace("lastLogin", "lastUpdatedDateTime");
request.Sort = request.Sort.Replace("lastApiAccess", "lastApiAccessDateTime");
request.Sort = request.Sort.Replace("registeredOn", "registeredDateTime");
}
var result = (from u in this.DbContext.Users
where (request.FilterValue.Length == 0 || (request.FilterValue.Length > 0 && (u.Username.Contains(request.FilterValue))))
select new UserList
{
DatabaseId = u.Id,
Id = u.RoadieId,
User = new DataToken
{
Text = u.UserName,
Value = u.RoadieId.ToString()
},
IsEditor = u.UserRoles.Any(x => x.Role.Name == "Editor"),
IsPrivate = u.IsPrivate,
Thumbnail = this.MakeUserThumbnailImage(u.RoadieId),
CreatedDate = u.CreatedDate,
LastUpdated = u.LastUpdated,
RegisteredDate = u.RegisteredOn,
LastLoginDate = u.LastLogin,
LastApiAccessDate = u.LastApiAccess
});
UserList[] rows = null;
var rowCount = result.Count();
var sortBy = string.IsNullOrEmpty(request.Sort) ? request.OrderValue(new Dictionary<string, string> { { "User.Text", "ASC" } }) : request.OrderValue(null);
rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
if (rows.Any())
{
foreach (var row in rows)
{
var userArtists = this.DbContext.UserArtists.Include(x => x.Artist).Where(x => x.UserId == row.DatabaseId).ToArray();
var userReleases = this.DbContext.UserReleases.Include(x => x.Release).Where(x => x.UserId == row.DatabaseId).ToArray();
var userTracks = this.DbContext.UserTracks.Include(x => x.Track).Where(x => x.UserId == row.DatabaseId).ToArray();
var mostPlayedArtist = (from a in this.DbContext.Artists
join r in this.DbContext.Releases on a.Id equals r.ArtistId
join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
join t in this.DbContext.Tracks on rm.Id equals t.ReleaseMediaId
join ut in this.DbContext.UserTracks on t.Id equals ut.TrackId
where ut.UserId == row.DatabaseId
select new { a, ut.PlayedCount })
.GroupBy(a => a.a)
.Select(x => new DataToken
{
Text = x.Key.Name,
Value = x.Key.RoadieId.ToString(),
Data = x.Sum(t => t.PlayedCount)
})
.OrderByDescending(x => x.Data)
.FirstOrDefault();
var mostPlayedRelease = (from r in this.DbContext.Releases
join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
join t in this.DbContext.Tracks on rm.Id equals t.ReleaseMediaId
join ut in this.DbContext.UserTracks on t.Id equals ut.TrackId
where ut.UserId == row.DatabaseId
select new { r, ut.PlayedCount })
.GroupBy(r => r.r)
.Select(x => new DataToken {
Text = x.Key.Title,
Value = x.Key.RoadieId.ToString(),
Data = x.Sum(t => t.PlayedCount) })
.OrderByDescending(x => x.Data)
.FirstOrDefault();
var mostPlayedTrack = userTracks
.OrderByDescending(x => x.PlayedCount)
.Select(x => new DataToken
{
Text = x.Track.Title,
Value = x.Track.RoadieId.ToString(),
Data = x.PlayedCount
})
.FirstOrDefault();
row.Statistics = new UserStatistics
{
MostPlayedArtist = mostPlayedArtist,
MostPlayedRelease = mostPlayedRelease,
MostPlayedTrack = mostPlayedTrack,
RatedArtists = userArtists.Where(x => x.Rating > 0).Count(),
FavoritedArtists = userArtists.Where(x => x.IsFavorite ?? false).Count(),
DislikedArtists = userArtists.Where(x => x.IsDisliked ?? false).Count(),
RatedReleases = userReleases.Where(x => x.Rating > 0).Count(),
FavoritedReleases = userReleases.Where(x => x.IsFavorite ?? false).Count(),
DislikedReleases = userReleases.Where(x => x.IsDisliked ?? false).Count(),
RatedTracks = userTracks.Where(x => x.Rating > 0).Count(),
PlayedTracks = userTracks.Where(x => x.PlayedCount.HasValue).Select(x => x.PlayedCount).Sum(),
FavoritedTracks = userTracks.Where(x => x.IsFavorite ?? false).Count(),
DislikedTracks = userTracks.Where(x => x.IsDisliked ?? false).Count()
};
}
}
sw.Stop();
return new Library.Models.Pagination.PagedResult<UserList>
{
TotalCount = rowCount,
CurrentPage = request.PageValue,
TotalPages = (int)Math.Ceiling((double)rowCount / request.LimitValue),
OperationTime = sw.ElapsedMilliseconds,
Rows = rows
};
}
}
}

View file

@ -141,6 +141,8 @@ namespace Roadie.Api
services.AddScoped<IBookmarkService, BookmarkService>();
services.AddScoped<IPlayActivityService, PlayActivityService>();
services.AddScoped<IGenreService, GenreService>();
services.AddScoped<ISubsonicService, SubsonicService>();
services.AddScoped<IUserService, UserService>();
var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(this._configuration["Tokens:PrivateKey"]));
services.AddAuthentication(options =>

View file

@ -45,5 +45,6 @@ namespace Roadie.Library.Models
this._tooltip = value;
}
}
public object Data { get; set; }
}
}

View file

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Roadie.Library.Models.Statistics
{
[Serializable]
public class UserStatistics
{
public DataToken MostPlayedArtist { get; set; }
public DataToken MostPlayedRelease { get; set; }
public DataToken MostPlayedTrack { get; set; }
public int? RatedArtists { get; set; }
public int? DislikedArtists { get; set; }
public int? FavoritedArtists { get; set; }
public int? RatedReleases { get; set; }
public int? DislikedReleases { get; set; }
public int? FavoritedReleases { get; set; }
public int? RatedTracks { get; set; }
public int? PlayedTracks { get; set; }
public int? FavoritedTracks { get; set; }
public int? DislikedTracks { get; set; }
}
}

View file

@ -1,66 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class AlbumInfoXmlResponse : BaseResponse
{
[XmlElement(ElementName = "albumInfo")]
public albuminfo albumInfo { get; set; }
}
[DataContract]
public class AlbumInfoJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public AlbumInfoResponse subsonicresponse { get; set; }
}
[DataContract]
public class AlbumInfoResponse : BaseResponse
{
[DataMember(Name = "albumInfo")]
public albuminfo albumInfo { get; set; }
}
[DataContract]
public class albuminfo
{
[DataMember(Name = "notes")]
[XmlTextAttribute()]
public string notes { get; set; }
[DataMember(Name = "musicBrainzId")]
[XmlElement(ElementName = "musicBrainzId")]
public string musicBrainzId { get; set; }
[DataMember(Name = "lastFmUrl")]
[XmlElement(ElementName = "lastFmUrl")]
public string lastFmUrl { get; set; }
[DataMember(Name = "smallImageUrl")]
[XmlElement(ElementName = "smallImageUrl")]
public string smallImageUrl { get; set; }
[DataMember(Name = "mediumImageUrl")]
[XmlElement(ElementName = "mediumImageUrl")]
public string mediumImageUrl { get; set; }
[DataMember(Name = "largeImageUrl")]
[XmlElement(ElementName = "largeImageUrl")]
public string largeImageUrl { get; set; }
}
}

View file

@ -1,198 +0,0 @@
using System;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[DebuggerDisplay("Title [{title}], PlayCount [{playCount}]")]
public class album
{
/// <summary>
/// Database ID
/// </summary>
[XmlIgnore]
public int ID { get; set; }
[DataMember(Name = "id")]
[XmlAttribute(AttributeName = "id")]
public string id { get; set; }
[DataMember(Name = "userRating")]
[XmlAttribute(AttributeName = "userRating")]
public short userRating { get; set; }
[DataMember(Name = "averageRating")]
[XmlAttribute(AttributeName = "averageRating")]
public short averageRating { get; set; }
[DataMember(Name = "playCount")]
[XmlAttribute(AttributeName = "playCount")]
public int playCount { get; set; }
[DataMember(Name = "parent")]
[XmlAttribute(AttributeName = "parent")]
public string parent { get; set; }
[DataMember(Name = "title")]
[XmlAttribute(AttributeName = "title")]
public string title { get; set; }
[DataMember(Name = "genre")]
[XmlAttribute(AttributeName = "genre")]
public string genre { get; set; }
[DataMember(Name = "album")]
[XmlAttribute(AttributeName = "album")]
public string albumTitle
{
get
{
return this.title;
}
}
[DataMember(Name = "year")]
[XmlAttribute(AttributeName = "year")]
public int year
{
get
{
if (this.yearDateTime.HasValue)
{
return this.yearDateTime.Value.Year;
}
return 0;
}
set
{
}
}
[XmlIgnore]
public DateTime? yearDateTime { get; set; }
[DataMember(Name = "isDir")]
[XmlAttribute(AttributeName = "isDir")]
public bool isDir { get; set; }
[DataMember(Name = "coverArt")]
[XmlAttribute(AttributeName = "coverArt")]
public string coverArt { get; set; }
[DataMember(Name = "songCount")]
[XmlAttribute(AttributeName = "songCount")]
public int songCount { get; set; }
[DataMember(Name = "created")]
[XmlAttribute(AttributeName = "created")]
public string created
{
get
{
if (this.createdDateTime.HasValue)
{
return this.createdDateTime.Value.ToString("s");
}
return null;
}
set
{
}
}
[XmlIgnore]
public DateTime? createdDateTime { get; set; }
[XmlIgnore]
public DateTime? lastPlayed { get; set; }
[DataMember(Name = "starred")]
[XmlAttribute(AttributeName = "starred")]
public string starred
{
get
{
if (this.starredDateTime.HasValue)
{
return this.starredDateTime.Value.ToString("s");
}
return null;
}
set
{
}
}
public bool ShouldSerializestarred()
{
return this.starredDateTime.HasValue;
}
[XmlIgnore]
public DateTime? starredDateTime { get; set; }
[DataMember(Name = "artist")]
[XmlAttribute(AttributeName = "artist")]
public string artist { get; set; }
[DataMember(Name = "artistId")]
[XmlAttribute(AttributeName = "artistId")]
public string artistId { get; set; }
[XmlIgnore]
public int artistID { get; set; }
[DataMember(Name = "duration")]
[XmlAttribute(AttributeName = "duration")]
public int duration
{
get
{
if (this.durationMilliseconds > 0)
{
var contentDurationTimeSpan = TimeSpan.FromMilliseconds((double) (this.durationMilliseconds ?? 0));
return (int) contentDurationTimeSpan.TotalSeconds;
}
return 0;
}
set
{
}
}
[XmlIgnore]
public int? durationMilliseconds { get; set; }
[XmlIgnore]
public int? listNumber { get; set; }
[DataMember(Name = "song")]
[XmlElement(ElementName = "song")]
public song[] song { get; set; }
public bool ShouldSerializesong()
{
return this.song != null;
}
[XmlIgnore]
public string notes { get; set; }
[XmlIgnore]
public string musicBrainzId { get; set; }
[XmlIgnore]
public string lastFMUrl { get; set; }
[XmlIgnore]
public string smallImageUrl { get; set; }
[XmlIgnore]
public string mediumImageUrl { get; set; }
[XmlIgnore]
public string largeImageUrl { get; set; }
}
}

View file

@ -1,101 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[Serializable]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class AlbumListXmlResponse : BaseResponse
{
[XmlElement(ElementName = "albumList")]
public AlbumList albumList { get; set; }
}
[Serializable]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class AlbumXmlResponse : BaseResponse
{
[XmlElement(ElementName = "album")]
public album album { get; set; }
}
[DataContract]
public class AlbumListJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public AlbumListJsonResponse subsonicresponse { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class AlbumListJsonResponse : BaseResponse
{
[DataMember(Name = "albumList")]
public AlbumList albumList { get; set; }
}
[DataContract]
public class AlbumList
{
[DataMember(Name = "album")]
[XmlElement(ElementName = "album")]
public album[] album { get; set; }
}
[DataContract]
public class AlbumJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public AlbumJsonResponse subsonicresponse { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class AlbumJsonResponse : BaseResponse
{
[DataMember(Name = "album")]
public album album { get; set; }
}
//public class Song
//{
// public string id { get; set; }
// public string parent { get; set; }
// public bool isDir { get; set; }
// public string title { get; set; }
// public string album { get; set; }
// public string artist { get; set; }
// public int track { get; set; }
// public int year { get; set; }
// public string genre { get; set; }
// public string coverArt { get; set; }
// public int size { get; set; }
// public string contentType { get; set; }
// public string suffix { get; set; }
// public int duration { get; set; }
// public int bitRate { get; set; }
// public string path { get; set; }
// public int userRating { get; set; }
// public int averageRating { get; set; }
// public int playCount { get; set; }
// public DateTime created { get; set; }
// public DateTime starred { get; set; }
// public string albumId { get; set; }
// public string artistId { get; set; }
// public string type { get; set; }
//}
}

View file

@ -1,98 +0,0 @@
using System;
using System.Runtime.Serialization;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
public class artist
{
/// <summary>
/// Database ID
/// </summary>
[XmlIgnore]
public int ID { get; set; }
[DataMember(Name = "id")]
[XmlAttribute(AttributeName = "id")]
public string id { get; set; }
[DataMember(Name = "name")]
[XmlAttribute(AttributeName = "name")]
public string name { get; set; }
[DataMember(Name = "sortname")]
[XmlAttribute(AttributeName = "sortname")]
public string sortname { get; set; }
[XmlIgnore]
public string biography { get; set; }
[XmlIgnore]
public string musicBrainzId { get; set; }
[XmlIgnore]
public string lastFMUrl { get; set; }
[XmlIgnore]
public string smallImageUrl { get; set; }
[XmlIgnore]
public string mediumImageUrl { get; set; }
[XmlIgnore]
public string largeImageUrl { get; set; }
[DataMember(Name = "genre")]
[XmlAttribute(AttributeName = "genre")]
public string genre { get; set; }
[DataMember(Name = "starred")]
[XmlAttribute(AttributeName = "starred")]
public string starred
{
get
{
if (this.starredDateTime.HasValue)
{
return this.starredDateTime.Value.ToString("s");
}
return null;
}
set
{
}
}
public bool ShouldSerializestarred()
{
return this.starredDateTime.HasValue;
}
[DataMember(Name = "coverArt")]
[XmlAttribute(AttributeName = "coverArt")]
public string coverArt { get; set; }
[DataMember(Name = "albumCount")]
[XmlAttribute(AttributeName = "albumCount")]
public int albumCount { get; set; }
[DataMember(Name = "userRating")]
[XmlAttribute(AttributeName = "userRating")]
public short userRating { get; set; }
[XmlIgnore]
public DateTime? starredDateTime { get; set; }
[XmlIgnore]
public DateTime? createdDateTime { get; set; }
[DataMember(Name = "album")]
[XmlElement(ElementName = "album")]
public album[] album { get; set; }
public bool ShouldSerializealbum()
{
return this.album != null;
}
}
}

View file

@ -1,55 +0,0 @@
using System.Runtime.Serialization;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class ArtistInfo2XmlResponse : BaseResponse
{
[XmlElement(ElementName = "artistInfo2")]
public artistinfo2 artistInfo2 { get; set; }
}
[DataContract]
public class ArtistInfo2JsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public ArtistInfo2Response subsonicresponse { get; set; }
}
[DataContract]
public class ArtistInfo2Response : BaseResponse
{
[DataMember(Name = "artistInfo2")]
public artistinfo2 artistInfo2 { get; set; }
}
[DataContract]
public class artistinfo2
{
[DataMember(Name = "biography")]
[XmlElement(ElementName = "biography")]
public string biography { get; set; }
[DataMember(Name = "musicBrainzId")]
[XmlElement(ElementName = "musicBrainzId")]
public string musicBrainzId { get; set; }
[DataMember(Name = "lastFmUrl")]
[XmlElement(ElementName = "lastFmUrl")]
public string lastFmUrl { get; set; }
[DataMember(Name = "smallImageUrl")]
[XmlElement(ElementName = "smallImageUrl")]
public string smallImageUrl { get; set; }
[DataMember(Name = "mediumImageUrl")]
[XmlElement(ElementName = "mediumImageUrl")]
public string mediumImageUrl { get; set; }
[DataMember(Name = "largeImageUrl")]
[XmlElement(ElementName = "largeImageUrl")]
public string largeImageUrl { get; set; }
}
}

View file

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class ArtistXmlResponse : BaseResponse
{
[XmlElement(ElementName = "artist")]
public artist artist { get; set; }
}
[DataContract]
public class ArtistJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public ArtistResponse subsonicresponse { get; set; }
}
[DataContract]
public class ArtistResponse : BaseResponse
{
[DataMember(Name = "artist")]
public artist artist { get; set; }
}
}

View file

@ -1,26 +0,0 @@
using System;
using System.Runtime.Serialization;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[Serializable]
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class BaseResponse
{
[DataMember(Name = "status")]
[XmlAttribute(AttributeName = "status")]
public string status { get; set; }
[DataMember(Name = "version")]
[XmlAttribute(AttributeName = "version")]
public string version { get; set; }
public BaseResponse()
{
this.status = "ok";
this.version = Credentials.API_VERSION;
}
}
}

View file

@ -1,59 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[Serializable]
public class Child
{
[XmlAttribute(AttributeName = "id")]
public string id { get; set; }
[XmlAttribute(AttributeName = "parent")]
public string parent { get; set; }
[XmlAttribute(AttributeName = "title")]
public string title { get; set; }
/// <summary>
/// True when a Album
/// </summary>
[XmlAttribute(AttributeName = "isDir")]
public string isDir { get; set; }
[XmlAttribute(AttributeName = "album")]
public string album { get; set; }
[XmlAttribute(AttributeName = "artist")]
public string artist { get; set; }
[XmlAttribute(AttributeName = "track")]
public string track { get; set; }
[XmlAttribute(AttributeName = "year")]
public string year { get; set; }
[XmlAttribute(AttributeName = "genre")]
public string genre { get; set; }
[XmlAttribute(AttributeName = "coverArt")]
public string coverArt { get; set; }
[XmlAttribute(AttributeName = "size")]
public string size { get; set; }
[XmlAttribute(AttributeName = "contentType")]
public string contentType { get; set; }
[XmlAttribute(AttributeName = "transcodedContentType")]
public string transcodedContentType { get; set; }
[XmlAttribute(AttributeName = "suffix")]
public string suffix { get; set; }
[XmlAttribute(AttributeName = "transcodedSuffix")]
public string transcodedSuffix { get; set; }
[XmlAttribute(AttributeName = "duration")]
public string duration { get; set; }
[XmlAttribute(AttributeName = "bitRate")]
public string bitRate { get; set; }
[XmlAttribute(AttributeName = "path")]
public string path { get; set; }
public Child()
{
this.isDir = "false";
}
}
}

View file

@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[Serializable]
public class Credentials
{
public const string API_VERSION = "1.14.0";
public string version { get; set; }
public string appName { get; set; }
public string salt { get; set; }
public string user { get; set; }
//public string token
//{
// get { return _token; }
// // set { _token = BitConverter.ToString(Encoding.UTF8.GetBytes(value)).Replace("-", ""); }
//}
public string token { get; set; }
public Credentials(string version, string appName, string user, string salt, string token)
{
this.version = version;
this.appName = appName;
this.user = user;
this.salt = salt;
this.token = token;
}
}
}

View file

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[Serializable]
public class Directory
{
[XmlAttribute(AttributeName = "id")]
public string id { get; set; }
[XmlAttribute(AttributeName = "parent")]
public string parent { get; set; }
[XmlAttribute(AttributeName = "name")]
public string name { get; set; }
[XmlAttribute(AttributeName = "starred")]
public string starred { get; set; }
[XmlElement(ElementName = "child")]
public Child[] child { get; set; }
}
}

View file

@ -1,67 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[Serializable]
public class Entry
{
[XmlAttribute(AttributeName = "username")]
public string username { get; set; }
[XmlAttribute(AttributeName = "minutesAgo")]
public string minutesAgo { get; set; }
[XmlAttribute(AttributeName = "playerId")]
public string playerId { get; set; }
[XmlAttribute(AttributeName = "playerName")]
public string playerName { get; set; }
[XmlAttribute(AttributeName = "id")]
public string id { get; set; }
[XmlAttribute(AttributeName = "parent")]
public string parent { get; set; }
[XmlAttribute(AttributeName = "title")]
public string title { get; set; }
[XmlAttribute(AttributeName = "isDir")]
public string isDir { get; set; }
[XmlAttribute(AttributeName = "album")]
public string album { get; set; }
[XmlAttribute(AttributeName = "artist")]
public string artist { get; set; }
[XmlAttribute(AttributeName = "track")]
public string track { get; set; }
[XmlAttribute(AttributeName = "year")]
public string year { get; set; }
[XmlAttribute(AttributeName = "genre")]
public string genre { get; set; }
[XmlAttribute(AttributeName = "coverArt")]
public string coverArt { get; set; }
[XmlAttribute(AttributeName = "size")]
public string size { get; set; }
[XmlAttribute(AttributeName = "contentType")]
public string contentType { get; set; }
[XmlAttribute(AttributeName = "suffix")]
public string suffix { get; set; }
[XmlAttribute(AttributeName = "path")]
public string path { get; set; }
[XmlAttribute(AttributeName = "transcodedContentType")]
public string transcodedContentType { get; set; }
[XmlAttribute(AttributeName = "transcodedSuffix")]
public string transcodedSuffix { get; set; }
}
}

View file

@ -1,86 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class ErrorXmlResponse : BaseResponse
{
[XmlElement(ElementName = "error")]
public error error { get; set; }
}
public class ErrorJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public ErrorJsonResponse subsonicresponse { get; set; }
}
public class ErrorJsonResponse : BaseResponse
{
[DataMember(Name = "error")]
public error error { get; set; }
}
public static class ErrorCodeHelper
{
public static error WrongUserNameOrPassword()
{
return ErrorCodeHelper.ErrorCodes().First(x => x.code == 40);
}
public static error RequestedDataNotFound()
{
return ErrorCodeHelper.ErrorCodes().First(x => x.code == 70);
}
public static error UserNotAuthorized()
{
return ErrorCodeHelper.ErrorCodes().First(x => x.code == 50);
}
public static error GenericError()
{
return ErrorCodeHelper.ErrorCodes().First(x => x.code == 0);
}
public static error RequiredParameterMissing()
{
return ErrorCodeHelper.ErrorCodes().First(x => x.code == 10);
}
public static List<error> ErrorCodes()
{
return new List<error>
{
new error { code = 0, message = "A generic error." },
new error { code = 10, message = "Required parameter is missing." },
new error { code = 20, message = "Incompatible Subsonic REST protocol version. Client must upgrade." },
new error { code = 30, message = "Incompatible Subsonic REST protocol version. Server must upgrade." },
new error { code = 40, message = "Wrong username or password." },
new error { code = 41, message = "Token authentication not supported for LDAP users." },
new error { code = 50, message = "User is not authorized for the given operation." },
new error { code = 60, message = "The trial period for the Subsonic server is over. Please upgrade to Subsonic Premium. Visit subsonic.org for details." },
new error { code = 70, message = "The requested data was not found." }
};
}
}
public class error
{
public int code { get; set; }
public string message { get; set; }
}
}

View file

@ -1,56 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class GenresXMLResponse : BaseResponse
{
[DataMember(Name = "genres")]
public genre[] genres { get; set; }
}
[DataContract]
public class GenresJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public GenresJsonResponse subsonicresponse { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class GenresJsonResponse : BaseResponse
{
[DataMember(Name = "genres")]
public Genres genres { get; set; }
}
[DataContract]
public class Genres
{
[DataMember(Name = "genre")]
[XmlElement(ElementName = "genre")]
public genre[] genre { get; set; }
}
[DataContract]
public class genre
{
[DataMember(Name = "songCount")]
[XmlAttribute(AttributeName = "songCount")]
public int songCount { get; set; }
[DataMember(Name = "albumCount")]
[XmlAttribute(AttributeName = "albumCount")]
public int albumCount { get; set; }
[DataMember(Name = "value")]
[XmlText]
public string value { get; set; }
}
}

View file

@ -1,94 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class IndexXMLResponse : BaseResponse
{
[XmlElement(ElementName = "indexes")]
public Indexes indexes { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class ArtistsXmlResponse : BaseResponse
{
[XmlElement(ElementName = "artists")]
public artists artists { get; set; }
}
[DataContract]
public class IndexJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public IndexJsonResponse subsonicresponse { get; set; }
}
[DataContract]
public class IndexJsonResponse : BaseResponse
{
[DataMember(Name = "indexes")]
public Indexes indexes { get; set; }
}
[DataContract]
public class ArtistsJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public ArtistsJsonResponse subsonicresponse { get; set; }
}
[DataContract]
public class ArtistsJsonResponse : BaseResponse
{
[DataMember(Name = "artists")]
public artists artists { get; set; }
}
[DataContract]
public class artists
{
[DataMember(Name = "lastModified")]
[XmlAttribute(AttributeName = "lastModified")]
public string lastModified { get; set; }
[DataMember(Name = "ignoredArticles")]
[XmlAttribute(AttributeName = "ignoredArticles")]
public string ignoredArticles { get; set; }
[XmlElement(ElementName = "index")]
[DataMember(Name = "index")]
public Index[] index { get; set; }
}
[DataContract]
public class Indexes
{
[DataMember(Name = "lastModified")]
[XmlAttribute(AttributeName = "lastModified")]
public string lastModified { get; set; }
[DataMember(Name = "ignoredArticles")]
[XmlAttribute(AttributeName = "ignoredArticles")]
public string ignoredArticles { get; set; }
[XmlElement(ElementName = "index")]
[DataMember(Name = "index")]
public Index[] index { get; set; }
}
[DataContract]
public class Index
{
[DataMember(Name = "name")]
[XmlAttribute(AttributeName = "name")]
public string name { get; set; }
[XmlElement(ElementName = "artist")]
[DataMember(Name = "artist")]
public artist[] artist { get; set; }
}
}

View file

@ -1,37 +0,0 @@
using Roadie.Library.Configuration;
using Roadie.Library.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
public class License
{
[DataMember(Name = "valid")]
[XmlAttribute(AttributeName = "valid")]
public bool valid { get; set; }
[DataMember(Name = "email")]
[XmlAttribute(AttributeName = "email")]
public string email { get; set; }
[DataMember(Name = "key")]
[XmlAttribute(AttributeName = "key")]
public string key { get; set; }
[DataMember(Name = "licenseExpires")]
[XmlAttribute(AttributeName = "licenseExpires")]
public string licenseExpires { get; set; }
public License(IRoadieSettings configuration)
{
this.valid = true;
this.email = configuration.SmtpFromAddress;
this.key = "C617BEA251B9E2C03DCF7289";
this.licenseExpires = DateTime.UtcNow.AddYears(5).ToString("s");
}
}
}

View file

@ -1,33 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class LicenseXmlResponse : BaseResponse
{
[XmlElement(ElementName = "license")]
public License license { get; set; }
}
[DataContract]
public class LicenseJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public LicenseJsonResponse subsonicresponse { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class LicenseJsonResponse : BaseResponse
{
[DataMember(Name = "license")]
public License license { get; set; }
}
}

View file

@ -1,40 +0,0 @@
using System.Runtime.Serialization;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class LyricXMLResponse : BaseResponse
{
[XmlElement(ElementName = "lyrics")]
public Lyric lyrics { get; set; }
}
public class LyricJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public LyricJsonResponse subsonicresponse { get; set; }
}
public class LyricJsonResponse : BaseResponse
{
[DataMember(Name = "lyrics")]
public Lyric lyrics { get; set; }
}
public class Lyric
{
[DataMember(Name = "artist")]
[XmlAttribute(AttributeName = "artist")]
public string artist { get; set; }
[DataMember(Name = "title")]
[XmlAttribute(AttributeName = "title")]
public string title { get; set; }
[DataMember(Name = "value")]
[XmlTextAttribute()]
public string value { get; set; }
}
}

View file

@ -1,110 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class ArtistDirectoryXmlResponse : BaseResponse
{
[DataMember(Name = "directory")]
public artistAlbumDirectory directory { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class AlbumSongDirectoryXmlResponse : BaseResponse
{
[DataMember(Name = "directory")]
public albumSongDirectory directory { get; set; }
}
[DataContract]
public class ArtistDirectoryJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public ArtistDirectoryJsonResponse subsonicresponse { get; set; }
}
[DataContract]
public class AlbumDirectoryJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public AlbumDirectoryJsonResponse subsonicresponse { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class ArtistDirectoryJsonResponse : BaseResponse
{
[DataMember(Name = "directory")]
public artistAlbumDirectory directory { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class AlbumDirectoryJsonResponse : BaseResponse
{
[DataMember(Name = "directory")]
public albumSongDirectory directory { get; set; }
}
[DataContract]
public class directory
{
[DataMember(Name = "id")]
[XmlAttribute(AttributeName = "id")]
public string id { get; set; }
[DataMember(Name = "name")]
[XmlAttribute(AttributeName = "name")]
public string name { get; set; }
[DataMember(Name = "starred")]
[XmlAttribute(AttributeName = "starred")]
public string starred
{
get
{
if (this.starredDateTime.HasValue)
{
return this.starredDateTime.Value.ToString("s");
}
return null;
}
}
public DateTime? starredDateTime { get; set; }
}
/// <summary>
/// Get the Albums for an Artist
/// </summary>
[DataContract]
public class artistAlbumDirectory : directory
{
[DataMember(Name = "child")]
[XmlElement(ElementName = "child")]
public album[] child { get; set; }
}
/// <summary>
/// Get the songs for an Album
/// </summary>
[DataContract]
public class albumSongDirectory : directory
{
[DataMember(Name = "averageRating")]
[XmlAttribute(AttributeName = "averageRating")]
public decimal averageRating { get; set; }
[DataMember(Name = "playCount")]
[XmlAttribute(AttributeName = "playCount")]
public int playCount { get; set; }
[DataMember(Name = "child")]
[XmlElement(ElementName = "child")]
public song[] child { get; set; }
}
}

View file

@ -1,55 +0,0 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class MusicFoldersXmlResponse : BaseResponse
{
[DataMember(Name = "musicFolders")]
public musicFolder[] musicFolders { get; set; }
}
[DataContract]
public class MusicFoldersJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public MusicFoldersJsonResponse subsonicresponse { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class MusicFoldersJsonResponse : BaseResponse
{
[DataMember(Name = "musicFolders")]
public Musicfolders musicFolders { get; set; }
}
[DataContract]
public class Musicfolders
{
[DataMember(Name = "musicFolder")]
public musicFolder[] musicFolder { get; set; }
}
[DataContract]
public class musicFolder
{
[DataMember(Name = "id")]
[XmlAttribute]
public int id { get; set; }
[DataMember(Name = "name")]
[XmlAttribute]
public string name { get; set; }
}
}

View file

@ -1,25 +0,0 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class PingXmlResponse : BaseResponse
{
}
[DataContract]
public class PingJsonResponse
{
[DataMember(Name = "subsonic-response")]
public BaseResponse subsonicresponse { get; set; }
}
}

View file

@ -1,156 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class PlaylistsXMLResponse : BaseResponse
{
[XmlElement(ElementName = "playlists")]
public Playlists playlists { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class PlaylistXMLResponse : BaseResponse
{
[XmlElement(ElementName = "playlist")]
public Playlist playlist { get; set; }
}
[DataContract]
public class PlaylistsJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public PlaylistsJsonResponse subsonicresponse { get; set; }
}
[DataContract]
public class PlaylistJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public PlaylistJsonResponse subsonicresponse { get; set; }
}
[DataContract]
public class PlaylistsJsonResponse : BaseResponse
{
[DataMember(Name = "playlists")]
public Playlists playlists { get; set; }
}
[DataContract]
public class PlaylistJsonResponse : BaseResponse
{
[DataMember(Name = "playlist")]
public Playlist playlist { get; set; }
}
[DataContract]
public class Playlists
{
[DataMember(Name = "playlist")]
[XmlElement(ElementName = "playlist")]
public Playlist[] playlist { get; set; }
}
[DataContract]
public class Playlist
{
/// <summary>
/// Database ID
/// </summary>
[XmlIgnore]
public int ID { get; set; }
[DataMember(Name = "id")]
[XmlAttribute(AttributeName = "id")]
public string id { get; set; }
[DataMember(Name = "name")]
[XmlAttribute(AttributeName = "name")]
public string name { get; set; }
[DataMember(Name = "comment")]
[XmlAttribute(AttributeName = "comment")]
public string comment { get; set; }
[DataMember(Name = "owner")]
[XmlAttribute(AttributeName = "owner")]
public string owner { get; set; }
[DataMember(Name = "isPublic")]
[XmlAttribute(AttributeName = "public")]
public bool isPublic { get; set; }
[DataMember(Name = "songCount")]
[XmlAttribute(AttributeName = "songCount")]
public int songCount { get; set; }
[DataMember(Name = "duration")]
[XmlAttribute(AttributeName = "duration")]
public int duration
{
get
{
var contentDurationTimeSpan = TimeSpan.FromMilliseconds((double) (durationMilliseconds));
return (int) contentDurationTimeSpan.TotalSeconds;
}
}
public int durationMilliseconds { get; set; }
[DataMember(Name = "created")]
[XmlAttribute(AttributeName = "created")]
public string created
{
get
{
if (this.createdDateTime.HasValue)
{
return this.createdDateTime.Value.ToString("s");
}
return null;
}
set
{
}
}
public DateTime? createdDateTime { get; set; }
[DataMember(Name = "changed")]
[XmlAttribute(AttributeName = "changed")]
public string changed
{
get
{
if (this.changedDateTime.HasValue)
{
return this.changedDateTime.Value.ToString("s");
}
return null;
}
set
{
}
}
public DateTime? changedDateTime { get; set; }
[DataMember(Name = "coverArt")]
[XmlAttribute(AttributeName = "coverArt")]
public string coverArt { get; set; }
[DataMember(Name = "allowedUser")]
[XmlElement(ElementName = "allowedUser")]
public string[] allowedUser { get; set; }
[DataMember(Name = "entry")]
[XmlElement(ElementName = "entry")]
public song[] entry { get; set; }
public Playlist()
{
this.allowedUser = new string[0];
this.entry = new song[0];
}
}
}

View file

@ -1,146 +0,0 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class PodcastsXmlResponse : BaseResponse
{
[DataMember(Name = "podcasts")]
public Podcasts[] podcasts { get; set; }
}
[DataContract]
public class PodcastsJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public PodcastsJsonResponse subsonicresponse { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class PodcastsJsonResponse : BaseResponse
{
[DataMember(Name = "podcasts")]
public Podcasts[] podcasts { get; set; }
}
[DataContract]
public class Podcasts
{
[XmlElement(ElementName = "channel")]
public Channel[] channel { get; set; }
}
[DataContract]
public class Channel
{
[XmlAttribute(AttributeName = "id")]
public string id { get; set; }
[XmlAttribute(AttributeName = "url")]
public string url { get; set; }
[XmlAttribute(AttributeName = "title")]
public string title { get; set; }
[XmlAttribute(AttributeName = "description")]
public string description { get; set; }
[XmlAttribute(AttributeName = "coverArt")]
public string coverArt { get; set; }
[XmlAttribute(AttributeName = "originalImageUrl")]
public string originalImageUrl { get; set; }
[XmlAttribute(AttributeName = "status")]
public string status { get; set; }
[XmlElement(ElementName = "episode")]
public Episode[] episode { get; set; }
}
[DataContract]
public class Episode
{
[XmlAttribute(AttributeName = "id")]
public string id { get; set; }
[XmlAttribute(AttributeName = "streamId")]
public string streamId { get; set; }
[XmlAttribute(AttributeName = "channelId")]
public string channelId { get; set; }
[XmlAttribute(AttributeName = "title")]
public string title { get; set; }
[XmlAttribute(AttributeName = "description")]
public string description { get; set; }
[XmlAttribute(AttributeName = "publishDate")]
public string publishDate { get; set; }
[XmlAttribute(AttributeName = "status")]
public string status { get; set; }
[XmlAttribute(AttributeName = "parent")]
public string parent { get; set; }
[XmlAttribute(AttributeName = "isDir")]
public string isDir { get; set; }
[XmlAttribute(AttributeName = "album")]
public string album { get; set; }
[XmlAttribute(AttributeName = "artist")]
public string artist { get; set; }
[XmlAttribute(AttributeName = "year")]
public string year { get; set; }
[XmlAttribute(AttributeName = "genre")]
public string genre { get; set; }
[XmlAttribute(AttributeName = "coverArt")]
public string coverArt { get; set; }
[XmlAttribute(AttributeName = "size")]
public string size { get; set; }
[XmlAttribute(AttributeName = "contentType")]
public string contentType { get; set; }
[XmlAttribute(AttributeName = "suffix")]
public string suffix { get; set; }
[XmlAttribute(AttributeName = "duration")]
public string duration { get; set; }
[XmlAttribute(AttributeName = "bitRate")]
public string bitRate { get; set; }
[XmlAttribute(AttributeName = "isVideo")]
public string isVideo { get; set; }
[XmlAttribute(AttributeName = "created")]
public string created { get; set; }
[XmlAttribute(AttributeName = "artistId")]
public string artistId { get; set; }
[XmlAttribute(AttributeName = "type")]
public string type { get; set; }
[XmlAttribute(AttributeName = "path")]
public string path { get; set; }
}
}

View file

@ -1,40 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class RandomSongsXmlResponse : BaseResponse
{
[DataMember(Name = "randomSongs")]
public randomSongs randomSongs { get; set; }
}
[DataContract]
public class RandomSongsJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public RandomSongsJsonResponse subsonicresponse { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class RandomSongsJsonResponse : BaseResponse
{
[DataMember(Name = "randomSongs")]
public randomSongs randomSongs { get; set; }
}
[DataContract]
public class randomSongs
{
[DataMember(Name = "song")]
public song[] song { get; set; }
}
}

View file

@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class Search2XMLResponse : BaseResponse
{
[XmlElement(ElementName = "searchResult2")]
public searchResult2 searchResult2 { get; set; }
}
[DataContract]
public class Search2JsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public searchResult2JsonResponse subsonicresponse { get; set; }
}
[DataContract]
public class searchResult2JsonResponse : BaseResponse
{
[DataMember(Name = "searchResult2")]
public searchResult2 searchResult2 { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class Search3XMLResponse : BaseResponse
{
[XmlElement(ElementName = "searchResult3")]
public searchResult2 searchResult3 { get; set; }
}
[DataContract]
public class Search3JsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public searchResult3JsonResponse subsonicresponse { get; set; }
}
[DataContract]
public class searchResult3JsonResponse : BaseResponse
{
[DataMember(Name = "searchResult3")]
public searchResult2 searchResult3 { get; set; }
}
[DataContract]
public class searchResult2
{
[DataMember(Name = "artist")]
[XmlElement(ElementName = "artist")]
public artist[] artist { get; set; }
[DataMember(Name = "album")]
[XmlElement(ElementName = "album")]
public album[] album { get; set; }
[DataMember(Name = "song")]
[XmlElement(ElementName = "song")]
public song[] song { get; set; }
}
}

View file

@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[Serializable]
public class Shortcut
{
[XmlAttribute(AttributeName = "id")]
public string id { get; set; }
[XmlAttribute(AttributeName = "name")]
public string name { get; set; }
}
}

View file

@ -1,204 +0,0 @@
using System;
using System.Runtime.Serialization;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
public class song
{
/// <summary>
/// Database ID
/// </summary>
[XmlIgnore]
public int ID { get; set; }
[DataMember(Name = "id")]
[XmlAttribute(AttributeName = "id")]
public string id { get; set; }
[DataMember(Name = "parent")]
[XmlAttribute(AttributeName = "parent")]
public string parent { get; set; }
[DataMember(Name = "title")]
[XmlAttribute(AttributeName = "title")]
public string title { get; set; }
[DataMember(Name = "album")]
[XmlAttribute(AttributeName = "album")]
public string album { get; set; }
[DataMember(Name = "artist")]
[XmlAttribute(AttributeName = "artist")]
public string artist { get; set; }
[DataMember(Name = "isDir")]
[XmlAttribute(AttributeName = "isDir")]
public bool isDir { get; set; }
[DataMember(Name = "coverArt")]
[XmlAttribute(AttributeName = "coverArt")]
public string coverArt { get; set; }
[DataMember(Name = "created")]
[XmlAttribute(AttributeName = "created")]
public string created
{
get
{
if (this.createdDateTime.HasValue)
{
return this.createdDateTime.Value.ToString("s");
}
return null;
}
set
{
}
}
[XmlIgnore]
public DateTime? createdDateTime { get; set; }
[DataMember(Name = "starred")]
[XmlAttribute(AttributeName = "starred")]
public string starred
{
get
{
if (this.starredDateTime.HasValue)
{
return this.starredDateTime.Value.ToString("s");
}
return null;
}
set
{
}
}
public bool ShouldSerializestarred()
{
return this.starredDateTime.HasValue;
}
[DataMember(Name = "duration")]
[XmlAttribute(AttributeName = "duration")]
public int duration
{
get
{
if (this.durationMilliseconds > 0)
{
var contentDurationTimeSpan = TimeSpan.FromMilliseconds((double) (this.durationMilliseconds ?? 0));
return (int) contentDurationTimeSpan.TotalSeconds;
}
return 0;
}
set
{
}
}
[XmlIgnore]
public int? durationMilliseconds { get; set; }
[DataMember(Name = "bitRate")]
[XmlAttribute(AttributeName = "bitRate")]
public int bitRate { get; set; }
[DataMember(Name = "track")]
[XmlAttribute(AttributeName = "track")]
public int track { get; set; }
[DataMember(Name = "albumMediaNumber")]
[XmlIgnore]
public short? albumMediaNumber { get; set; }
[DataMember(Name = "year")]
[XmlAttribute(AttributeName = "year")]
public int year
{
get
{
if (this.yearDateTime.HasValue)
{
return this.yearDateTime.Value.Year;
}
return 0;
}
set
{
}
}
[XmlIgnore]
public DateTime? yearDateTime { get; set; }
[DataMember(Name = "genre")]
[XmlAttribute(AttributeName = "genre")]
public string genre { get; set; }
[DataMember(Name = "size")]
[XmlAttribute(AttributeName = "size")]
public int size { get; set; }
[DataMember(Name = "suffix")]
[XmlAttribute(AttributeName = "suffix")]
public string suffix { get; set; }
[DataMember(Name = "contentType")]
[XmlAttribute(AttributeName = "contentType")]
public string contentType { get; set; }
[DataMember(Name = "path")]
[XmlAttribute(AttributeName = "path")]
public string path { get; set; }
[DataMember(Name = "albumId")]
[XmlAttribute(AttributeName = "albumId")]
public string albumId { get; set; }
[XmlIgnore]
public int albumID { get; set; }
[DataMember(Name = "artistId")]
[XmlAttribute(AttributeName = "artistId")]
public string artistId { get; set; }
[XmlIgnore]
public int artistID { get; set; }
[DataMember(Name = "type")]
[XmlAttribute(AttributeName = "type")]
public string type { get; set; }
[DataMember(Name = "playCount")]
[XmlAttribute(AttributeName = "playCount")]
public int playCount { get; set; }
[DataMember(Name = "userRating")]
[XmlAttribute(AttributeName = "userRating")]
public short userRating { get; set; }
[DataMember(Name = "averageRating")]
[XmlAttribute(AttributeName = "averageRating")]
public short averageRating { get; set; }
[XmlIgnore]
public DateTime? starredDateTime { get; set; }
[XmlIgnore]
public bool isValid { get; set; }
public song()
{
this.type = "music";
this.suffix = "mp3";
this.bitRate = 320;
this.contentType = "audio/mpeg";
this.isDir = false;
}
}
}

View file

@ -1,33 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[Serializable]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class SongXmlResponse : BaseResponse
{
[XmlElement(ElementName = "song")]
public song song { get; set; }
}
[DataContract]
public class SongJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public SongJsonResponse subsonicresponse { get; set; }
}
[DataContract]
public class SongJsonResponse : BaseResponse
{
[DataMember(Name = "song")]
public song song { get; set; }
}
}

View file

@ -1,45 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[Serializable]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class SongsByGenreXmlResponse : BaseResponse
{
[XmlElement(ElementName = "songsByGenre")]
public SongsByGenreResponse songsByGenre { get; set; }
}
[DataContract]
public class SongsByGenreJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public SongsByGenreJsonResponse subsonicresponse { get; set; }
}
[DataContract]
public class SongsByGenreJsonResponse : BaseResponse
{
[DataMember(Name = "songsByGenre")]
[XmlElement(ElementName = "songsByGenre")]
public SongsByGenreResponse songsByGenre { get; set; }
}
[DataContract]
public class SongsByGenreResponse : BaseResponse
{
[DataMember(Name = "song")]
[XmlElement(ElementName = "song")]
public song[] song { get; set; }
}
}

View file

@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class StarredXMLResponse : BaseResponse
{
[XmlElement(ElementName = "starred")]
public starredResult starred { get; set; }
}
[DataContract]
public class StarredJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public starredJsonResponse subsonicresponse { get; set; }
}
[DataContract]
public class starredJsonResponse : BaseResponse
{
[DataMember(Name = "starred")]
public starredResult starred { get; set; }
}
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class Starred2XMLResponse : BaseResponse
{
[XmlElement(ElementName = "starred2")]
public starredResult starred2 { get; set; }
}
[DataContract]
public class Starred2JsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public starred2JsonResponse subsonicresponse { get; set; }
}
[DataContract]
public class starred2JsonResponse : BaseResponse
{
[DataMember(Name = "starred2")]
public starredResult starred2 { get; set; }
}
[DataContract]
public class starredResult
{
[DataMember(Name = "artist")]
[XmlElement(ElementName = "artist")]
public artist[] artist { get; set; }
[DataMember(Name = "album")]
[XmlElement(ElementName = "album")]
public album[] album { get; set; }
[DataMember(Name = "song")]
[XmlElement(ElementName = "song")]
public song[] song { get; set; }
}
}

View file

@ -1,159 +0,0 @@
using System;
using System.Runtime.Serialization;
using System.Xml.Serialization;
namespace Roadie.Models.ThirdPartyApi.Subsonic
{
[DataContract]
[XmlRoot(ElementName = "subsonic-response", Namespace = "http://subsonic.org/restapi")]
public class UserXMLResponse : BaseResponse
{
[XmlElement(ElementName = "user")]
public User user { get; set; }
}
public class UserJsonResponseWrapper
{
[DataMember(Name = "subsonic-response")]
public UserJsonResponse subsonicresponse { get; set; }
}
public class UserJsonResponse : BaseResponse
{
[DataMember(Name = "user")]
public User user { get; set; }
}
public class User
{
/// <summary>
/// The name of the user
/// </summary>
[DataMember(Name = "username")]
[XmlAttribute(AttributeName = "username")]
public string username { get; set; }
/// <summary>
/// The email address of the user.
/// </summary>
[DataMember(Name = "email")]
[XmlAttribute(AttributeName = "email")]
public string email { get; set; }
[DataMember(Name = "scrobblingEnabled")]
[XmlAttribute(AttributeName = "scrobblingEnabled")]
public bool scrobblingEnabled { get; set; }
/// <summary>
/// Whether the user is administrator.
/// </summary>
[DataMember(Name = "adminRole")]
[XmlAttribute(AttributeName = "adminRole")]
public bool adminRole { get; set; }
/// <summary>
/// Whether the user is allowed to change personal settings and password.
/// </summary>
[DataMember(Name = "settingsRole")]
[XmlAttribute(AttributeName = "settingsRole")]
public bool settingsRole { get; set; }
/// <summary>
/// Whether the user is allowed to download files.
/// </summary>
[DataMember(Name = "downloadRole")]
[XmlAttribute(AttributeName = "downloadRole")]
public bool downloadRole { get; set; }
/// <summary>
/// Whether the user is allowed to upload files.
/// </summary>
[DataMember(Name = "uploadRole")]
[XmlAttribute(AttributeName = "uploadRole")]
public bool uploadRole { get; set; }
/// <summary>
/// Whether the user is allowed to create and delete playlists.
/// </summary>
[DataMember(Name = "playlistRole")]
[XmlAttribute(AttributeName = "playlistRole")]
public bool playlistRole { get; set; }
/// <summary>
/// Whether the user is allowed to change cover art and tags.
/// </summary>
[DataMember(Name = "coverArtRole")]
[XmlAttribute(AttributeName = "coverArtRole")]
public bool coverArtRole { get; set; }
/// <summary>
/// Whether the user is allowed to create and edit comments and ratings.
/// </summary>
[DataMember(Name = "commentRole")]
[XmlAttribute(AttributeName = "commentRole")]
public bool commentRole { get; set; }
/// <summary>
/// Whether the user is allowed to administrate Podcasts.
/// </summary>
[DataMember(Name = "podcastRole")]
[XmlAttribute(AttributeName = "podcastRole")]
public bool podcastRole { get; set; }
/// <summary>
/// Whether the user is allowed to play files.
/// </summary>
[DataMember(Name = "streamRole")]
[XmlAttribute(AttributeName = "streamRole")]
public bool streamRole { get; set; }
/// <summary>
/// Whether the user is allowed to play files in jukebox mode.
/// </summary>
[DataMember(Name = "jukeboxRole")]
[XmlAttribute(AttributeName = "jukeboxRole")]
public bool jukeboxRole { get; set; }
/// <summary>
/// Whether the user is allowed to share files with anyone.
/// </summary>
[DataMember(Name = "shareRole")]
[XmlAttribute(AttributeName = "shareRole")]
public bool shareRole { get; set; }
/// <summary>
/// Whether the user is allowed to start video conversions.
/// </summary>
[DataMember(Name = "videoConversionRole")]
[XmlAttribute(AttributeName = "videoConversionRole")]
public bool videoConversionRole { get; set; }
[DataMember(Name = "avatarLastChanged")]
[XmlAttribute(AttributeName = "avatarLastChanged")]
public DateTime avatarLastChanged { get; set; }
/// <summary>
/// IDs of the music folders the user is allowed access to. Include the parameter once for each folder.
/// </summary>
[DataMember(Name = "musicFolderId")]
[XmlAttribute(AttributeName = "musicFolderId")]
public int[] musicFolderId { get; set; }
/// <summary>
/// The maximum bit rate (in Kbps) for the user. Audio streams of higher bit rates are automatically downsampled to this bit rate. Legal values: 0 (no limit), 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320.
/// </summary>
[DataMember(Name = "maxBitRate")]
[XmlAttribute(AttributeName = "maxBitRate")]
public int? maxBitRate { get; set; }
public User()
{
this.settingsRole = true;
this.playlistRole = true;
this.commentRole = true;
this.streamRole = true;
this.shareRole = true;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,5 @@
using Newtonsoft.Json;
using Roadie.Library.Models.Statistics;
using System;
using System.Collections.Generic;
using System.Text;
@ -10,36 +11,20 @@ namespace Roadie.Library.Models.Users
{
public DataToken User { get; set; }
public string ThumbnailUrl { get; set; }
public Image Thumbnail { get; set; }
[JsonIgnore]
public DateTime? RegisteredDateTime { get; set; }
public string RegisteredOn
{
get
{
return this.RegisteredDateTime.HasValue ? this.RegisteredDateTime.Value.ToString("s") : null;
}
}
public DateTime? Registered { get; set; }
[JsonIgnore]
public DateTime? LastLoginDateTime { get; set; }
public string LastLogin
{
get
{
return this.LastLoginDateTime.HasValue ? this.LastLoginDateTime.Value.ToString("s") : null;
}
}
public DateTime? LastLoginDate { get; set; }
[JsonIgnore]
public DateTime? LastApiAccessDateTime { get; set; }
public string LastApiAccess
{
get
{
return this.LastApiAccessDateTime.HasValue ? this.LastApiAccessDateTime.Value.ToString("s") : null;
}
}
public DateTime? LastApiAccessDate { get; set; }
public DateTime? RegisteredDate { get; set; }
public bool IsEditor { get; set; }
public bool? IsPrivate { get; set; }
public UserStatistics Statistics { get; set; }
}
}

View file

@ -31,8 +31,7 @@
<ItemGroup>
<Folder Include="Factories\" />
<Folder Include="FilePlugins\" />
<Folder Include="Models\ThirdPartyApi\" />
<Folder Include="Models\ThirdPartyApi\Subsonic\" />
<Folder Include="Models\Subsonic\" />
<Folder Include="Processors\" />
<Folder Include="SearchEngines\MetaData\Audio\" />
</ItemGroup>