using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Extensions;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
namespace MediaBrowser.Plugins.Trailers
{
///
/// Fetches Apple's list of current movie trailers
///
public static class AppleTrailerListingDownloader
{
///
/// The trailer feed URL
///
private const string TrailerFeedUrl = "http://trailers.apple.com/trailers/home/xml/current_720p.xml";
///
/// Downloads a list of trailer info's from the apple url
///
/// Task{List{TrailerInfo}}.
public static async Task> GetTrailerList(CancellationToken cancellationToken)
{
var stream = await Kernel.Instance.HttpManager.Get(TrailerFeedUrl, Kernel.Instance.ResourcePools.AppleTrailerVideos, cancellationToken).ConfigureAwait(false);
var list = new List();
using (var reader = XmlReader.Create(stream, new XmlReaderSettings { Async = true }))
{
await reader.MoveToContentAsync().ConfigureAwait(false);
while (await reader.ReadAsync().ConfigureAwait(false))
{
cancellationToken.ThrowIfCancellationRequested();
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "movieinfo":
var trailer = FetchTrailerInfo(reader.ReadSubtree());
list.Add(trailer);
break;
}
}
}
}
return list;
}
///
/// Fetches trailer info from an xml node
///
/// The reader.
/// TrailerInfo.
private static TrailerInfo FetchTrailerInfo(XmlReader reader)
{
var trailerInfo = new TrailerInfo { };
reader.MoveToContent();
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "info":
FetchInfo(reader.ReadSubtree(), trailerInfo);
break;
case "cast":
FetchCast(reader.ReadSubtree(), trailerInfo);
break;
case "genre":
FetchGenres(reader.ReadSubtree(), trailerInfo);
break;
case "poster":
FetchPosterUrl(reader.ReadSubtree(), trailerInfo);
break;
case "preview":
FetchTrailerUrl(reader.ReadSubtree(), trailerInfo);
break;
default:
reader.Skip();
break;
}
}
}
return trailerInfo;
}
private static readonly CultureInfo USCulture = new CultureInfo("en-US");
///
/// Fetches from the info node
///
/// The reader.
/// The info.
private static void FetchInfo(XmlReader reader, TrailerInfo info)
{
reader.MoveToContent();
reader.Read();
while (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "title":
info.Video.Name = reader.ReadStringSafe();
break;
case "runtime":
{
var runtime = reader.ReadStringSafe();
if (!string.IsNullOrWhiteSpace(runtime))
{
if (runtime.StartsWith(":", StringComparison.OrdinalIgnoreCase))
{
runtime = "0" + runtime;
}
TimeSpan runtimeTimeSpan;
if (TimeSpan.TryParse(runtime, USCulture, out runtimeTimeSpan))
{
info.Video.RunTimeTicks = runtimeTimeSpan.Ticks;
}
}
break;
}
case "rating":
info.Video.OfficialRating = reader.ReadStringSafe();
break;
case "studio":
{
var studio = reader.ReadStringSafe();
if (!string.IsNullOrWhiteSpace(studio))
{
info.Video.AddStudio(studio);
}
break;
}
case "postdate":
{
DateTime date;
if (DateTime.TryParse(reader.ReadStringSafe(), USCulture, DateTimeStyles.None, out date))
{
info.PostDate = date;
}
break;
}
case "releasedate":
{
var val = reader.ReadStringSafe();
if (!string.IsNullOrWhiteSpace(val))
{
DateTime date;
if (DateTime.TryParse(val, USCulture, DateTimeStyles.None, out date))
{
info.Video.PremiereDate = date;
info.Video.ProductionYear = date.Year;
}
}
break;
}
case "director":
{
var directors = reader.ReadStringSafe() ?? string.Empty;
foreach (var director in directors.Split(',', StringSplitOptions.RemoveEmptyEntries))
{
var name = director.Trim();
if (!string.IsNullOrWhiteSpace(name))
{
info.Video.AddPerson(new PersonInfo { Name = name, Type = PersonType.Director });
}
}
break;
}
case "description":
info.Video.Overview = reader.ReadStringSafe();
break;
default:
reader.Skip();
break;
}
}
}
///
/// Fetches from the genre node
///
/// The reader.
/// The info.
private static void FetchGenres(XmlReader reader, TrailerInfo info)
{
reader.MoveToContent();
reader.Read();
while (reader.IsStartElement())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "name":
info.Video.AddGenre(reader.ReadStringSafe());
break;
default:
reader.Skip();
break;
}
}
}
}
///
/// Fetches from the cast node
///
/// The reader.
/// The info.
private static void FetchCast(XmlReader reader, TrailerInfo info)
{
reader.MoveToContent();
reader.Read();
while (reader.IsStartElement())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "name":
info.Video.AddPerson(new PersonInfo { Name = reader.ReadStringSafe(), Type = PersonType.Actor });
break;
default:
reader.Skip();
break;
}
}
}
}
///
/// Fetches from the preview node
///
/// The reader.
/// The info.
private static void FetchTrailerUrl(XmlReader reader, TrailerInfo info)
{
reader.MoveToContent();
reader.Read();
while (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "large":
info.TrailerUrl = reader.ReadStringSafe();
break;
default:
reader.Skip();
break;
}
}
}
///
/// Fetches from the poster node
///
/// The reader.
/// The info.
private static void FetchPosterUrl(XmlReader reader, TrailerInfo info)
{
reader.MoveToContent();
reader.Read();
while (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "location":
info.ImageUrl = reader.ReadStringSafe();
break;
case "xlarge":
info.HdImageUrl = reader.ReadStringSafe();
break;
default:
reader.Skip();
break;
}
}
}
}
}