diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index ab205d6ebf..0dfd812c3a 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -84,10 +84,28 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MediaBrowser.Api/Reports/Common/HeaderMetadata.cs b/MediaBrowser.Api/Reports/Common/HeaderMetadata.cs
new file mode 100644
index 0000000000..3cb8f722d2
--- /dev/null
+++ b/MediaBrowser.Api/Reports/Common/HeaderMetadata.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MediaBrowser.Api.Reports
+{
+ public enum HeaderMetadata
+ {
+ None,
+ Name,
+ PremiereDate,
+ DateAdded,
+ ReleaseDate,
+ Runtime,
+ PlayCount,
+ Season,
+ SeasonNumber,
+ Series,
+ Network,
+ Year,
+ ParentalRating,
+ CommunityRating,
+ Trailers,
+ Specials,
+ GameSystem,
+ Players,
+ AlbumArtist,
+ Album,
+ Disc,
+ Track,
+ Audio,
+ EmbeddedImage,
+ Video,
+ Resolution,
+ Subtitles,
+ Genres,
+ Countries,
+ StatusImage,
+ Tracks,
+ EpisodeSeries,
+ EpisodeSeason,
+ AudioAlbumArtist,
+ MusicArtist,
+ AudioAlbum,
+ Status
+ }
+}
diff --git a/MediaBrowser.Api/Reports/Common/ItemViewType.cs b/MediaBrowser.Api/Reports/Common/ItemViewType.cs
new file mode 100644
index 0000000000..3e09a290dc
--- /dev/null
+++ b/MediaBrowser.Api/Reports/Common/ItemViewType.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MediaBrowser.Api.Reports
+{
+ public enum ItemViewType
+ {
+ None,
+ Detail,
+ Edit,
+ List,
+ ItemByNameDetails,
+ StatusImage,
+ EmbeddedImage,
+ SubtitleImage,
+ TrailersImage,
+ SpecialsImage
+ }
+}
diff --git a/MediaBrowser.Api/Reports/Common/ReportBuilderBase.cs b/MediaBrowser.Api/Reports/Common/ReportBuilderBase.cs
new file mode 100644
index 0000000000..ad1b1e1a6e
--- /dev/null
+++ b/MediaBrowser.Api/Reports/Common/ReportBuilderBase.cs
@@ -0,0 +1,229 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Channels;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Entities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Api.Reports
+{
+ /// A report builder base.
+ public class ReportBuilderBase
+ {
+ ///
+ /// Initializes a new instance of the MediaBrowser.Api.Reports.ReportBuilderBase class.
+ /// Manager for library.
+ public ReportBuilderBase(ILibraryManager libraryManager)
+ {
+ _libraryManager = libraryManager;
+ }
+
+ /// Manager for library.
+ protected readonly ILibraryManager _libraryManager;
+
+ /// Gets audio stream.
+ /// The item.
+ /// The audio stream.
+ protected string GetAudioStream(BaseItem item)
+ {
+ var stream = GetStream(item, MediaStreamType.Audio);
+ if (stream != null)
+ return stream.Codec.ToUpper() == "DCA" ? stream.Profile : stream.Codec.
+ ToUpper();
+
+ return string.Empty;
+ }
+
+ /// Gets an episode.
+ /// The item.
+ /// The episode.
+ protected string GetEpisode(BaseItem item)
+ {
+
+ if (item.GetClientTypeName() == ChannelMediaContentType.Episode.ToString() && item.ParentIndexNumber != null)
+ return "Season " + item.ParentIndexNumber;
+ else
+ return item.Name;
+ }
+
+ /// Gets a genre.
+ /// The name.
+ /// The genre.
+ protected Genre GetGenre(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ return null;
+ return _libraryManager.GetGenre(name);
+ }
+
+ /// Gets genre identifier.
+ /// The name.
+ /// The genre identifier.
+ protected string GetGenreID(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ return string.Empty;
+ return string.Format("{0:N}",
+ GetGenre(name).Id);
+ }
+
+ /// Gets list as string.
+ /// The items.
+ /// The list as string.
+ protected string GetListAsString(List items)
+ {
+ return String.Join("; ", items);
+ }
+
+ /// Gets media source information.
+ /// The item.
+ /// The media source information.
+ protected MediaSourceInfo GetMediaSourceInfo(BaseItem item)
+ {
+ var mediaSource = item as IHasMediaSources;
+ if (mediaSource != null)
+ return mediaSource.GetMediaSources(false).FirstOrDefault(n => n.Type == MediaSourceType.Default);
+
+ return null;
+ }
+
+ /// Gets an object.
+ /// Generic type parameter.
+ /// Type of the r.
+ /// The item.
+ /// The function.
+ /// The default value.
+ /// The object.
+ protected R GetObject(BaseItem item, Func function, R defaultValue = default(R)) where T : class
+ {
+ var value = item as T;
+ if (value != null && function != null)
+ return function(value);
+ else
+ return defaultValue;
+ }
+
+ /// Gets a person.
+ /// The name.
+ /// The person.
+ protected Person GetPerson(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ return null;
+ return _libraryManager.GetPerson(name);
+ }
+
+ /// Gets person identifier.
+ /// The name.
+ /// The person identifier.
+ protected string GetPersonID(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ return string.Empty;
+ return string.Format("{0:N}",
+ GetPerson(name).Id);
+ }
+
+ /// Gets runtime date time.
+ /// The runtime.
+ /// The runtime date time.
+ protected DateTime? GetRuntimeDateTime(long? runtime)
+ {
+ if (runtime.HasValue)
+ return new DateTime(runtime.Value);
+ return null;
+ }
+
+ /// Gets series production year.
+ /// The item.
+ /// The series production year.
+ protected string GetSeriesProductionYear(BaseItem item)
+ {
+
+ string productionYear = item.ProductionYear.ToString();
+ var series = item as Series;
+ if (series == null)
+ {
+ if (item.ProductionYear == null || item.ProductionYear == 0)
+ return string.Empty;
+ return productionYear;
+ }
+
+ if (series.Status == SeriesStatus.Continuing)
+ return productionYear += "-Present";
+
+ if (series.EndDate != null && series.EndDate.Value.Year != series.ProductionYear)
+ return productionYear += "-" + series.EndDate.Value.Year;
+
+ return productionYear;
+ }
+
+ /// Gets a stream.
+ /// The item.
+ /// Type of the stream.
+ /// The stream.
+ protected MediaStream GetStream(BaseItem item, MediaStreamType streamType)
+ {
+ var itemInfo = GetMediaSourceInfo(item);
+ if (itemInfo != null)
+ return itemInfo.MediaStreams.FirstOrDefault(n => n.Type == streamType);
+
+ return null;
+ }
+
+ /// Gets a studio.
+ /// The name.
+ /// The studio.
+ protected Studio GetStudio(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ return null;
+ return _libraryManager.GetStudio(name);
+ }
+
+ /// Gets studio identifier.
+ /// The name.
+ /// The studio identifier.
+ protected string GetStudioID(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ return string.Empty;
+ return string.Format("{0:N}",
+ GetStudio(name).Id);
+ }
+
+ /// Gets video resolution.
+ /// The item.
+ /// The video resolution.
+ protected string GetVideoResolution(BaseItem item)
+ {
+ var stream = GetStream(item,
+ MediaStreamType.Video);
+ if (stream != null && stream.Width != null)
+ return string.Format("{0} * {1}",
+ stream.Width,
+ (stream.Height != null ? stream.Height.ToString() : "-"));
+
+ return string.Empty;
+ }
+
+ /// Gets video stream.
+ /// The item.
+ /// The video stream.
+ protected string GetVideoStream(BaseItem item)
+ {
+ var stream = GetStream(item, MediaStreamType.Video);
+ if (stream != null)
+ return stream.Codec.ToUpper();
+
+ return string.Empty;
+ }
+
+ }
+}
diff --git a/MediaBrowser.Api/Reports/Common/ReportExportType.cs b/MediaBrowser.Api/Reports/Common/ReportExportType.cs
new file mode 100644
index 0000000000..05f27f72ef
--- /dev/null
+++ b/MediaBrowser.Api/Reports/Common/ReportExportType.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MediaBrowser.Api.Reports
+{
+ public enum ReportExportType
+ {
+ CSV,
+ Excel
+ }
+}
diff --git a/MediaBrowser.Api/Reports/Common/ReportFieldType.cs b/MediaBrowser.Api/Reports/Common/ReportFieldType.cs
new file mode 100644
index 0000000000..9ecbfc326a
--- /dev/null
+++ b/MediaBrowser.Api/Reports/Common/ReportFieldType.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MediaBrowser.Api.Reports
+{
+ public enum ReportFieldType
+ {
+ String,
+ Boolean,
+ Date,
+ Time,
+ DateTime,
+ Int,
+ Image,
+ Object
+ }
+}
diff --git a/MediaBrowser.Api/Reports/Common/ReportHeaderIdType.cs b/MediaBrowser.Api/Reports/Common/ReportHeaderIdType.cs
new file mode 100644
index 0000000000..58c1181510
--- /dev/null
+++ b/MediaBrowser.Api/Reports/Common/ReportHeaderIdType.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MediaBrowser.Api.Reports
+{
+ public enum ReportHeaderIdType
+ {
+ Row,
+ Item
+ }
+}
diff --git a/MediaBrowser.Api/Reports/Common/ReportHelper.cs b/MediaBrowser.Api/Reports/Common/ReportHelper.cs
new file mode 100644
index 0000000000..306b3e7493
--- /dev/null
+++ b/MediaBrowser.Api/Reports/Common/ReportHelper.cs
@@ -0,0 +1,99 @@
+using MediaBrowser.Controller.Entities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Api.Reports
+{
+ public class ReportHelper
+ {
+ /// Gets java script localized string.
+ /// The phrase.
+ /// The java script localized string.
+ public static string GetJavaScriptLocalizedString(string phrase)
+ {
+ var dictionary = BaseItem.LocalizationManager.GetJavaScriptLocalizationDictionary(BaseItem.ConfigurationManager.Configuration.UICulture);
+
+ string value;
+
+ if (dictionary.TryGetValue(phrase, out value))
+ {
+ return value;
+ }
+
+ return phrase;
+ }
+
+ /// Gets server localized string.
+ /// The phrase.
+ /// The server localized string.
+ public static string GetServerLocalizedString(string phrase)
+ {
+ return BaseItem.LocalizationManager.GetLocalizedString(phrase, BaseItem.ConfigurationManager.Configuration.UICulture);
+ }
+
+ /// Gets row type.
+ /// The type.
+ /// The row type.
+ public static ReportViewType GetRowType(string rowType)
+ {
+ if (string.IsNullOrEmpty(rowType))
+ return ReportViewType.BaseItem;
+
+ ReportViewType rType;
+
+ if (!Enum.TryParse(rowType, out rType))
+ return ReportViewType.BaseItem;
+
+ return rType;
+ }
+
+ /// Gets header metadata type.
+ /// The header.
+ /// The header metadata type.
+ public static HeaderMetadata GetHeaderMetadataType(string header)
+ {
+ if (string.IsNullOrEmpty(header))
+ return HeaderMetadata.None;
+
+ HeaderMetadata rType;
+
+ if (!Enum.TryParse(header, out rType))
+ return HeaderMetadata.None;
+
+ return rType;
+ }
+
+ /// Convert field to string.
+ /// Generic type parameter.
+ /// The value.
+ /// Type of the field.
+ /// The field converted to string.
+ public static string ConvertToString(T value, ReportFieldType fieldType)
+ {
+ if (value == null)
+ return "";
+ switch (fieldType)
+ {
+ case ReportFieldType.String:
+ return value.ToString();
+ case ReportFieldType.Boolean:
+ return value.ToString();
+ case ReportFieldType.Date:
+ return string.Format("{0:d}", value);
+ case ReportFieldType.Time:
+ return string.Format("{0:t}", value);
+ case ReportFieldType.DateTime:
+ return string.Format("{0:d}", value);
+ case ReportFieldType.Int:
+ return string.Format("", value);
+ default:
+ if (value is Guid)
+ return string.Format("{0:N}", value);
+ return value.ToString();
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Api/Reports/Common/ReportViewType.cs b/MediaBrowser.Api/Reports/Common/ReportViewType.cs
new file mode 100644
index 0000000000..efdfcb0e79
--- /dev/null
+++ b/MediaBrowser.Api/Reports/Common/ReportViewType.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MediaBrowser.Api.Reports
+{
+ public enum ReportViewType
+ {
+ MusicArtist,
+ MusicAlbum,
+ Book,
+ BoxSet,
+ Episode,
+ Game,
+ Video,
+ Movie,
+ MusicVideo,
+ Trailer,
+ Season,
+ Series,
+ Audio,
+ BaseItem,
+ Artist
+ }
+}
diff --git a/MediaBrowser.Api/Reports/Data/ReportBuilder.cs b/MediaBrowser.Api/Reports/Data/ReportBuilder.cs
new file mode 100644
index 0000000000..bf1c280b17
--- /dev/null
+++ b/MediaBrowser.Api/Reports/Data/ReportBuilder.cs
@@ -0,0 +1,589 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Localization;
+using MediaBrowser.Model.Channels;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Querying;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Api.Reports
+{
+ /// A report builder.
+ ///
+ public class ReportBuilder : ReportBuilderBase
+ {
+
+ ///
+ /// Initializes a new instance of the MediaBrowser.Api.Reports.ReportBuilder class.
+ /// Manager for library.
+ public ReportBuilder(ILibraryManager libraryManager)
+ : base(libraryManager)
+ {
+ }
+
+ private Func GetBoolString = s => s == true ? "x" : "";
+
+ public ReportResult GetReportResult(BaseItem[] items, ReportViewType reportRowType, BaseReportRequest request)
+ {
+ List headersMetadata = this.GetFilteredReportHeaderMetadata(reportRowType, request);
+
+ var headers = GetReportHeaders(reportRowType, headersMetadata);
+ var rows = GetReportRows(items, headersMetadata);
+
+ ReportResult result = new ReportResult { Headers = headers };
+ HeaderMetadata groupBy = ReportHelper.GetHeaderMetadataType(request.GroupBy);
+ int i = headers.FindIndex(x => x.FieldName == groupBy);
+ if (groupBy != HeaderMetadata.None && i > 0)
+ {
+ var rowsGroup = rows.SelectMany(x => x.Columns[i].Name.Split(';'), (x, g) => new { Genre = g.Trim(), Rows = x })
+ .GroupBy(x => x.Genre)
+ .OrderBy(x => x.Key)
+ .Select(x => new ReportGroup { Name = x.Key, Rows = x.Select(r => r.Rows).ToList() });
+
+ result.Groups = rowsGroup.ToList();
+ result.IsGrouped = true;
+ }
+ else
+ {
+ result.Rows = rows;
+ result.IsGrouped = false;
+ }
+
+ return result;
+ }
+
+ public List GetReportHeaders(ReportViewType reportRowType, BaseReportRequest request)
+ {
+ List headersMetadata = this.GetReportHeaders(reportRowType);
+ if (request != null && !string.IsNullOrEmpty(request.ReportColumns))
+ {
+ List headersMetadataFiltered = this.GetFilteredReportHeaderMetadata(reportRowType, request);
+ foreach (ReportHeader reportHeader in headersMetadata)
+ {
+ if (!headersMetadataFiltered.Contains(reportHeader.FieldName))
+ {
+ reportHeader.Visible = false;
+ }
+ }
+
+
+ }
+
+ return headersMetadata;
+ }
+
+ public List GetReportHeaders(ReportViewType reportRowType, List headersMetadata = null)
+ {
+ if (headersMetadata == null)
+ headersMetadata = this.GetDefaultReportHeaderMetadata(reportRowType);
+
+ List> options = new List>();
+ foreach (HeaderMetadata header in headersMetadata)
+ {
+ options.Add(GetReportOption(header));
+ }
+
+
+ List headers = new List();
+ foreach (ReportOptions option in options)
+ {
+ headers.Add(option.Header);
+ }
+ return headers;
+ }
+
+ private List GetReportRows(IEnumerable items, List headersMetadata)
+ {
+ List> options = new List>();
+ foreach (HeaderMetadata header in headersMetadata)
+ {
+ options.Add(GetReportOption(header));
+ }
+
+ var rows = new List();
+
+ foreach (BaseItem item in items)
+ {
+ ReportRow rRow = GetRow(item);
+ foreach (ReportOptions option in options)
+ {
+ object itemColumn = option.Column != null ? option.Column(item, rRow) : "";
+ object itemId = option.ItemID != null ? option.ItemID(item) : "";
+ ReportItem rItem = new ReportItem
+ {
+ Name = ReportHelper.ConvertToString(itemColumn, option.Header.HeaderFieldType),
+ Id = ReportHelper.ConvertToString(itemId, ReportFieldType.Object)
+ };
+ rRow.Columns.Add(rItem);
+ }
+
+ rows.Add(rRow);
+ }
+
+ return rows;
+ }
+
+ /// Gets a row.
+ /// The item.
+ /// The row.
+ private ReportRow GetRow(BaseItem item)
+ {
+ var hasTrailers = item as IHasTrailers;
+ var hasSpecialFeatures = item as IHasSpecialFeatures;
+ var video = item as Video;
+ ReportRow rRow = new ReportRow
+ {
+ Id = item.Id.ToString("N"),
+ HasLockData = item.IsLocked,
+ IsUnidentified = item.IsUnidentified,
+ HasLocalTrailer = hasTrailers != null ? hasTrailers.GetTrailerIds().Count() > 0 : false,
+ HasImageTagsPrimary = (item.ImageInfos != null && item.ImageInfos.Count(n => n.Type == ImageType.Primary) > 0),
+ HasImageTagsBackdrop = (item.ImageInfos != null && item.ImageInfos.Count(n => n.Type == ImageType.Backdrop) > 0),
+ HasImageTagsLogo = (item.ImageInfos != null && item.ImageInfos.Count(n => n.Type == ImageType.Logo) > 0),
+ HasSpecials = hasSpecialFeatures != null ? hasSpecialFeatures.SpecialFeatureIds.Count > 0 : false,
+ HasSubtitles = video != null ? video.HasSubtitles : false,
+ RowType = ReportHelper.GetRowType(item.GetClientTypeName())
+ };
+ return rRow;
+ }
+ public List GetFilteredReportHeaderMetadata(ReportViewType reportRowType, BaseReportRequest request)
+ {
+ if (request != null && !string.IsNullOrEmpty(request.ReportColumns))
+ {
+ var s = request.ReportColumns.Split('|').Select(x => ReportHelper.GetHeaderMetadataType(x)).Where(x => x != HeaderMetadata.None);
+ return s.ToList();
+ }
+ else
+ return this.GetDefaultReportHeaderMetadata(reportRowType);
+
+ }
+
+ public List GetDefaultReportHeaderMetadata(ReportViewType reportRowType)
+ {
+ switch (reportRowType)
+ {
+ case ReportViewType.Season:
+ return new List
+ {
+ HeaderMetadata.StatusImage,
+ HeaderMetadata.Series,
+ HeaderMetadata.Season,
+ HeaderMetadata.SeasonNumber,
+ HeaderMetadata.DateAdded,
+ HeaderMetadata.Year,
+ HeaderMetadata.Genres
+ };
+
+ case ReportViewType.Series:
+ return new List
+ {
+ HeaderMetadata.StatusImage,
+ HeaderMetadata.Name,
+ HeaderMetadata.Network,
+ HeaderMetadata.DateAdded,
+ HeaderMetadata.Year,
+ HeaderMetadata.Genres,
+ HeaderMetadata.ParentalRating,
+ HeaderMetadata.CommunityRating,
+ HeaderMetadata.Runtime,
+ HeaderMetadata.Trailers,
+ HeaderMetadata.Specials
+ };
+
+ case ReportViewType.MusicAlbum:
+ return new List
+ {
+ HeaderMetadata.StatusImage,
+ HeaderMetadata.Name,
+ HeaderMetadata.AlbumArtist,
+ HeaderMetadata.DateAdded,
+ HeaderMetadata.ReleaseDate,
+ HeaderMetadata.Tracks,
+ HeaderMetadata.Year,
+ HeaderMetadata.Genres
+ };
+
+ case ReportViewType.MusicArtist:
+ return new List
+ {
+ HeaderMetadata.StatusImage,
+ HeaderMetadata.MusicArtist,
+ HeaderMetadata.Countries,
+ HeaderMetadata.DateAdded,
+ HeaderMetadata.Year,
+ HeaderMetadata.Genres
+ };
+
+ case ReportViewType.Game:
+ return new List
+ {
+ HeaderMetadata.StatusImage,
+ HeaderMetadata.Name,
+ HeaderMetadata.GameSystem,
+ HeaderMetadata.DateAdded,
+ HeaderMetadata.ReleaseDate,
+ HeaderMetadata.ParentalRating,
+ HeaderMetadata.CommunityRating,
+ HeaderMetadata.Players,
+ HeaderMetadata.Year,
+ HeaderMetadata.Genres,
+ HeaderMetadata.Trailers
+ };
+
+ case ReportViewType.Movie:
+ return new List
+ {
+ HeaderMetadata.StatusImage,
+ HeaderMetadata.Name,
+ HeaderMetadata.DateAdded,
+ HeaderMetadata.ReleaseDate,
+ HeaderMetadata.Year,
+ HeaderMetadata.Genres,
+ HeaderMetadata.ParentalRating,
+ HeaderMetadata.CommunityRating,
+ HeaderMetadata.Runtime,
+ HeaderMetadata.Video,
+ HeaderMetadata.Resolution,
+ HeaderMetadata.Audio,
+ HeaderMetadata.Subtitles,
+ HeaderMetadata.Trailers,
+ HeaderMetadata.Specials
+ };
+
+ case ReportViewType.Book:
+ return new List
+ {
+ HeaderMetadata.StatusImage,
+ HeaderMetadata.Name,
+ HeaderMetadata.DateAdded,
+ HeaderMetadata.ReleaseDate,
+ HeaderMetadata.Year,
+ HeaderMetadata.Genres,
+ HeaderMetadata.ParentalRating,
+ HeaderMetadata.CommunityRating
+ };
+
+ case ReportViewType.BoxSet:
+ return new List
+ {
+ HeaderMetadata.StatusImage,
+ HeaderMetadata.Name,
+ HeaderMetadata.DateAdded,
+ HeaderMetadata.ReleaseDate,
+ HeaderMetadata.Year,
+ HeaderMetadata.Genres,
+ HeaderMetadata.ParentalRating,
+ HeaderMetadata.CommunityRating,
+ HeaderMetadata.Trailers
+ };
+
+ case ReportViewType.Audio:
+ return new List
+ {
+ HeaderMetadata.StatusImage,
+ HeaderMetadata.Name,
+ HeaderMetadata.AudioAlbumArtist,
+ HeaderMetadata.AudioAlbum,
+ HeaderMetadata.Disc,
+ HeaderMetadata.Track,
+ HeaderMetadata.DateAdded,
+ HeaderMetadata.ReleaseDate,
+ HeaderMetadata.Year,
+ HeaderMetadata.Genres,
+ HeaderMetadata.ParentalRating,
+ HeaderMetadata.CommunityRating,
+ HeaderMetadata.Runtime,
+ HeaderMetadata.Audio
+ };
+
+ case ReportViewType.Episode:
+ return new List
+ {
+ HeaderMetadata.StatusImage,
+ HeaderMetadata.Name,
+ HeaderMetadata.EpisodeSeries,
+ HeaderMetadata.Season,
+ HeaderMetadata.DateAdded,
+ HeaderMetadata.ReleaseDate,
+ HeaderMetadata.Year,
+ HeaderMetadata.Genres,
+ HeaderMetadata.ParentalRating,
+ HeaderMetadata.CommunityRating,
+ HeaderMetadata.Runtime,
+ HeaderMetadata.Video,
+ HeaderMetadata.Resolution,
+ HeaderMetadata.Audio,
+ HeaderMetadata.Subtitles,
+ HeaderMetadata.Trailers,
+ HeaderMetadata.Specials
+ };
+
+ case ReportViewType.Video:
+ case ReportViewType.MusicVideo:
+ case ReportViewType.Trailer:
+ case ReportViewType.BaseItem:
+ default:
+ return new List
+ {
+ HeaderMetadata.StatusImage,
+ HeaderMetadata.Name,
+ HeaderMetadata.DateAdded,
+ HeaderMetadata.ReleaseDate,
+ HeaderMetadata.Year,
+ HeaderMetadata.Genres,
+ HeaderMetadata.ParentalRating,
+ HeaderMetadata.CommunityRating,
+ HeaderMetadata.Runtime,
+ HeaderMetadata.Video,
+ HeaderMetadata.Resolution,
+ HeaderMetadata.Audio,
+ HeaderMetadata.Subtitles,
+ HeaderMetadata.Trailers,
+ HeaderMetadata.Specials
+ };
+
+ }
+
+ }
+
+ /// Gets report option.
+ /// The header.
+ /// The sort field.
+ /// The report option.
+ private ReportOptions GetReportOption(HeaderMetadata header, string sortField = "")
+ {
+ ReportHeader reportHeader = new ReportHeader
+ {
+ HeaderFieldType = ReportFieldType.String,
+ SortField = sortField,
+ Type = "",
+ ItemViewType = ItemViewType.None
+ };
+
+ Func column = null;
+ Func itemId = null;
+ HeaderMetadata internalHeader = header;
+
+ switch (header)
+ {
+ case HeaderMetadata.StatusImage:
+ reportHeader.ItemViewType = ItemViewType.StatusImage;
+ internalHeader = HeaderMetadata.Status;
+ reportHeader.CanGroup = false;
+ break;
+
+ case HeaderMetadata.Name:
+ column = (i, r) => i.Name;
+ reportHeader.ItemViewType = ItemViewType.Detail;
+ reportHeader.SortField = "SortName";
+ break;
+
+ case HeaderMetadata.DateAdded:
+ column = (i, r) => i.DateCreated;
+ reportHeader.SortField = "DateCreated,SortName";
+ reportHeader.HeaderFieldType = ReportFieldType.DateTime;
+ reportHeader.Type = "";
+ break;
+
+ case HeaderMetadata.PremiereDate:
+ case HeaderMetadata.ReleaseDate:
+ column = (i, r) => i.PremiereDate;
+ reportHeader.HeaderFieldType = ReportFieldType.DateTime;
+ reportHeader.SortField = "ProductionYear,PremiereDate,SortName";
+ break;
+
+ case HeaderMetadata.Runtime:
+ column = (i, r) => this.GetRuntimeDateTime(i.RunTimeTicks);
+ reportHeader.HeaderFieldType = ReportFieldType.Time;
+ reportHeader.SortField = "Runtime,SortName";
+ break;
+
+ case HeaderMetadata.PlayCount:
+ reportHeader.HeaderFieldType = ReportFieldType.Int;
+ break;
+
+ case HeaderMetadata.Season:
+ column = (i, r) => this.GetEpisode(i);
+ reportHeader.ItemViewType = ItemViewType.Detail;
+ reportHeader.SortField = "SortName";
+ break;
+
+ case HeaderMetadata.SeasonNumber:
+ column = (i, r) => i.IndexNumber;
+ reportHeader.SortField = "IndexNumber";
+ reportHeader.HeaderFieldType = ReportFieldType.Int;
+ break;
+
+ case HeaderMetadata.Series:
+ column = (i, r) => this.GetObject(i, (x) => x.SeriesName);
+ reportHeader.ItemViewType = ItemViewType.Detail;
+ reportHeader.SortField = "SeriesSortName,SortName";
+ break;
+
+ case HeaderMetadata.EpisodeSeries:
+ column = (i, r) => this.GetObject(i, (x) => x.SeriesName);
+ reportHeader.ItemViewType = ItemViewType.Detail;
+ itemId = (i) =>
+ {
+ Series series = this.GetObject(i, (x) => x.Series);
+ if (series == null)
+ return string.Empty;
+ return series.Id;
+ };
+ reportHeader.SortField = "SeriesSortName,SortName";
+ internalHeader = HeaderMetadata.Series;
+ break;
+
+ case HeaderMetadata.EpisodeSeason:
+ column = (i, r) => this.GetObject(i, (x) => x.SeriesName);
+ reportHeader.ItemViewType = ItemViewType.Detail;
+ itemId = (i) =>
+ {
+ Season season = this.GetObject(i, (x) => x.Season);
+ if (season == null)
+ return string.Empty;
+ return season.Id;
+ };
+ reportHeader.SortField = "SortName";
+ internalHeader = HeaderMetadata.Season;
+ break;
+
+ case HeaderMetadata.Network:
+ column = (i, r) => this.GetListAsString(i.Studios);
+ itemId = (i) => this.GetStudioID(i.Studios.FirstOrDefault());
+ reportHeader.ItemViewType = ItemViewType.ItemByNameDetails;
+ reportHeader.SortField = "Studio,SortName";
+ break;
+
+ case HeaderMetadata.Year:
+ column = (i, r) => this.GetSeriesProductionYear(i);
+ reportHeader.SortField = "ProductionYear,PremiereDate,SortName";
+ break;
+
+ case HeaderMetadata.ParentalRating:
+ column = (i, r) => i.OfficialRating;
+ reportHeader.SortField = "OfficialRating,SortName";
+ break;
+
+ case HeaderMetadata.CommunityRating:
+ column = (i, r) => i.CommunityRating;
+ reportHeader.SortField = "CommunityRating,SortName";
+ break;
+
+ case HeaderMetadata.Trailers:
+ column = (i, r) => this.GetBoolString(r.HasLocalTrailer);
+ reportHeader.ItemViewType = ItemViewType.TrailersImage;
+ break;
+
+ case HeaderMetadata.Specials:
+ column = (i, r) => this.GetBoolString(r.HasSpecials);
+ reportHeader.ItemViewType = ItemViewType.SpecialsImage;
+ break;
+
+ case HeaderMetadata.GameSystem:
+ column = (i, r) => this.GetObject(i, (x) => x.GameSystem);
+ reportHeader.SortField = "GameSystem,SortName";
+ break;
+
+ case HeaderMetadata.Players:
+ column = (i, r) => this.GetObject(i, (x) => x.PlayersSupported);
+ reportHeader.SortField = "Players,GameSystem,SortName";
+ break;
+
+ case HeaderMetadata.AlbumArtist:
+ column = (i, r) => this.GetObject(i, (x) => x.AlbumArtist);
+ itemId = (i) => this.GetPersonID(this.GetObject(i, (x) => x.AlbumArtist));
+ reportHeader.ItemViewType = ItemViewType.Detail;
+ reportHeader.SortField = "AlbumArtist,Album,SortName";
+
+ break;
+ case HeaderMetadata.MusicArtist:
+ column = (i, r) => this.GetObject(i, (x) => x.GetLookupInfo().Name);
+ reportHeader.ItemViewType = ItemViewType.Detail;
+ reportHeader.SortField = "AlbumArtist,Album,SortName";
+ internalHeader = HeaderMetadata.AlbumArtist;
+ break;
+ case HeaderMetadata.AudioAlbumArtist:
+ column = (i, r) => this.GetListAsString(this.GetObject