Eric Reed 12 years ago
commit 67f2b1b2ba

@ -39,17 +39,17 @@
<Reference Include="MoreLinq">
<HintPath>..\packages\morelinq.1.0.15631-beta\lib\net35\MoreLinq.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Common, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Common, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Common.3.9.43\lib\net35\ServiceStack.Common.dll</HintPath>
<HintPath>..\packages\ServiceStack.Common.3.9.44\lib\net35\ServiceStack.Common.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Interfaces, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Interfaces, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Common.3.9.43\lib\net35\ServiceStack.Interfaces.dll</HintPath>
<HintPath>..\packages\ServiceStack.Common.3.9.44\lib\net35\ServiceStack.Interfaces.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Text, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Text, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Text.3.9.43\lib\net35\ServiceStack.Text.dll</HintPath>
<HintPath>..\packages\ServiceStack.Text.3.9.44\lib\net35\ServiceStack.Text.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />

@ -258,7 +258,7 @@ namespace MediaBrowser.Api.Playback.Progressive
// webm
if (videoCodec.Equals("libvpx", StringComparison.OrdinalIgnoreCase))
{
args = "-quality realtime -speed 0 -qmin 0 -qmax 30 -profile:v 0 -slices 8";
args = "-speed 16 -quality good -profile:v 0 -slices 8";
}
// asf/wmv

@ -1,5 +1,4 @@
using System.Collections;
using MediaBrowser.Controller;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
@ -9,9 +8,10 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Search;
using ServiceStack.ServiceHost;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using System.Threading.Tasks;
namespace MediaBrowser.Api
{

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="morelinq" version="1.0.15631-beta" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.44" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.44" targetFramework="net45" />
</packages>

@ -39,9 +39,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\NLog.2.0.1.2\lib\net45\NLog.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Text, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Text, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Text.3.9.43\lib\net35\ServiceStack.Text.dll</HintPath>
<HintPath>..\packages\ServiceStack.Text.3.9.44\lib\net35\ServiceStack.Text.dll</HintPath>
</Reference>
<Reference Include="SimpleInjector, Version=2.2.1.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NLog" version="2.0.1.2" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.44" targetFramework="net45" />
<package id="SimpleInjector" version="2.2.1" targetFramework="net45" />
</packages>

@ -38,17 +38,17 @@
</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="ServiceStack.Common, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Common, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Common.3.9.43\lib\net35\ServiceStack.Common.dll</HintPath>
<HintPath>..\packages\ServiceStack.Common.3.9.44\lib\net35\ServiceStack.Common.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Interfaces, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Interfaces, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Common.3.9.43\lib\net35\ServiceStack.Interfaces.dll</HintPath>
<HintPath>..\packages\ServiceStack.Common.3.9.44\lib\net35\ServiceStack.Interfaces.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Text, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Text, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Text.3.9.43\lib\net35\ServiceStack.Text.dll</HintPath>
<HintPath>..\packages\ServiceStack.Text.3.9.44\lib\net35\ServiceStack.Text.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ServiceStack.Common" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.44" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.44" targetFramework="net45" />
</packages>

@ -22,8 +22,7 @@ namespace MediaBrowser.Controller.Entities
/// Gets or sets the users 0-10 rating
/// </summary>
/// <value>The rating.</value>
/// <exception cref="System.ArgumentOutOfRangeException">A 0-10 rating is required for UserItemData.</exception>
/// <exception cref="System.InvalidOperationException">A 0-10 rating is required for UserItemData.</exception>
/// <exception cref="System.ArgumentOutOfRangeException">Rating;A 0 to 10 rating is required for UserItemData.</exception>
public float? Rating
{
get
@ -36,7 +35,7 @@ namespace MediaBrowser.Controller.Entities
{
if (value.Value < 0 || value.Value > 10)
{
throw new ArgumentOutOfRangeException("A 0-10 rating is required for UserItemData.");
throw new ArgumentOutOfRangeException("value", "A 0 to 10 rating is required for UserItemData.");
}
}

@ -116,8 +116,8 @@
<Compile Include="Providers\IProviderManager.cs" />
<Compile Include="Providers\MediaInfo\MediaEncoderHelpers.cs" />
<Compile Include="Providers\MetadataProviderPriority.cs" />
<Compile Include="Providers\Movies\OpenMovieDatabaseProvider.cs" />
<Compile Include="Providers\Movies\RottenTomatoesMovieProvider.cs" />
<Compile Include="Providers\Movies\RottenTomatoesMovieReviewsProvider.cs" />
<Compile Include="Providers\Music\FanArtArtistByNameProvider.cs" />
<Compile Include="Providers\Music\LastfmAlbumProvider.cs" />
<Compile Include="Providers\Music\FanArtAlbumProvider.cs" />

@ -148,7 +148,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
/// </summary>
/// <param name="val">The val.</param>
/// <returns>System.String[][].</returns>
private string[] Split(string val)
private IEnumerable<string> Split(string val)
{
// Only use the comma as a delimeter if there are no slashes or pipes.
// We want to be careful not to split names that have commas in them

@ -975,8 +975,8 @@ namespace MediaBrowser.Controller.Providers.Movies
boxset.OfficialRating = firstChild != null ? firstChild.OfficialRating : null;
}
if (movie.RunTimeTicks == null && movieData.runtime > 0)
movie.RunTimeTicks = TimeSpan.FromMinutes(movieData.runtime).Ticks;
//if (movie.RunTimeTicks == null && movieData.runtime > 0)
// movie.RunTimeTicks = TimeSpan.FromMinutes(movieData.runtime).Ticks;
//studios
if (movieData.production_companies != null)

@ -7,21 +7,15 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers.Movies
{
/// <summary>
/// Class RottenTomatoesMovieProvider
/// </summary>
public class RottenTomatoesMovieReviewsProvider : BaseMetadataProvider
public class OpenMovieDatabaseProvider : BaseMetadataProvider
{
// http://developer.rottentomatoes.com/iodocs
private const string MoviesReviews = @"movies/{1}/reviews.json?review_type=top_critic&page_limit=10&page=1&country=us&apikey={0}";
private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
/// <summary>
/// Gets the json serializer.
@ -35,14 +29,7 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <value>The HTTP client.</value>
protected IHttpClient HttpClient { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="RottenTomatoesMovieProvider"/> class.
/// </summary>
/// <param name="logManager">The log manager.</param>
/// <param name="configurationManager">The configuration manager.</param>
/// <param name="jsonSerializer">The json serializer.</param>
/// <param name="httpClient">The HTTP client.</param>
public RottenTomatoesMovieReviewsProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient)
public OpenMovieDatabaseProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient)
: base(logManager, configurationManager)
{
JsonSerializer = jsonSerializer;
@ -57,7 +44,7 @@ namespace MediaBrowser.Controller.Providers.Movies
{
get
{
return "5";
return "6";
}
}
@ -92,15 +79,14 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
public override bool Supports(BaseItem item)
{
return false;
var trailer = item as Trailer;
// Don't support local trailers
if (trailer != null)
{
return !trailer.IsLocalTrailer;
}
// Don't support local trailers
return item is Movie;
}
@ -136,7 +122,7 @@ namespace MediaBrowser.Controller.Providers.Movies
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
{
// Refresh if rt id has changed
if (providerInfo.Data != GetComparisonData(item.GetProviderId(MetadataProviders.RottenTomatoes)))
if (providerInfo.Data != GetComparisonData(item.GetProviderId(MetadataProviders.Imdb)))
{
return true;
}
@ -144,13 +130,8 @@ namespace MediaBrowser.Controller.Providers.Movies
return base.NeedsRefreshInternal(item, providerInfo);
}
/// <summary>
/// Fetches metadata and returns true or false indicating if any work that requires persistence was done
/// </summary>
/// <param name="item">The item.</param>
/// <param name="force">if set to <c>true</c> [force].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{System.Boolean}.</returns>
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
public override async Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
{
BaseProviderInfo data;
@ -161,76 +142,85 @@ namespace MediaBrowser.Controller.Providers.Movies
item.ProviderData[Id] = data;
}
var rottenTomatoesId = item.GetProviderId(MetadataProviders.RottenTomatoes);
var imdbId = item.GetProviderId(MetadataProviders.Imdb);
if (string.IsNullOrEmpty(rottenTomatoesId))
if (string.IsNullOrEmpty(imdbId))
{
data.Data = GetComparisonData(rottenTomatoesId);
data.Data = GetComparisonData(imdbId);
data.LastRefreshStatus = ProviderRefreshStatus.Success;
return true;
}
var imdbParam = imdbId.StartsWith("tt", StringComparison.OrdinalIgnoreCase) ? imdbId : "tt" + imdbId;
var url = string.Format("http://www.omdbapi.com/?i={0}&tomatoes=true", imdbParam);
using (var stream = await HttpClient.Get(new HttpRequestOptions
{
Url = GetMovieReviewsUrl(rottenTomatoesId),
ResourcePool = RottenTomatoesMovieProvider.Current.RottenTomatoesResourcePool,
Url = url,
ResourcePool = _resourcePool,
CancellationToken = cancellationToken,
EnableResponseCache = true
}).ConfigureAwait(false))
{
var result = JsonSerializer.DeserializeFromStream<RootObject>(stream);
var result = JsonSerializer.DeserializeFromStream<RTReviewList>(stream);
int tomatoMeter;
item.CriticReviews = result.reviews.Select(rtReview => new ItemReview
if (!string.IsNullOrEmpty(result.tomatoMeter) && int.TryParse(result.tomatoMeter, NumberStyles.Integer, UsCulture, out tomatoMeter))
{
ReviewerName = rtReview.critic,
Publisher = rtReview.publication,
Date = DateTime.Parse(rtReview.date).ToUniversalTime(),
Caption = rtReview.quote,
Url = rtReview.links.review,
Likes = string.Equals(rtReview.freshness, "fresh", StringComparison.OrdinalIgnoreCase)
}).ToList();
item.CriticRating = tomatoMeter;
}
if (!string.IsNullOrEmpty(result.tomatoConsensus)
&& !string.Equals(result.tomatoConsensus, "n/a", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(result.tomatoConsensus, "No consensus yet.", StringComparison.OrdinalIgnoreCase))
{
item.CriticRatingSummary = result.tomatoConsensus;
}
}
data.Data = GetComparisonData(rottenTomatoesId);
data.Data = GetComparisonData(item.GetProviderId(MetadataProviders.Imdb));
data.LastRefreshStatus = ProviderRefreshStatus.Success;
SetLastRefreshed(item, DateTime.UtcNow);
return true;
}
// Utility functions to get the URL of the API calls
private string GetMovieReviewsUrl(string rtId)
{
return RottenTomatoesMovieProvider.BasicUrl + string.Format(MoviesReviews, RottenTomatoesMovieProvider.ApiKey, rtId);
}
// Data contract classes for use with the Rotten Tomatoes API
protected class RTReviewList
{
public int total { get; set; }
public List<RTReview> reviews { get; set; }
}
protected class RTReview
{
public string critic { get; set; }
public string date { get; set; }
public string freshness { get; set; }
public string publication { get; set; }
public string quote { get; set; }
public RTReviewLink links { get; set; }
public string original_score { get; set; }
}
protected class RTReviewLink
protected class RootObject
{
public string review { get; set; }
public string Title { get; set; }
public string Year { get; set; }
public string Rated { get; set; }
public string Released { get; set; }
public string Runtime { get; set; }
public string Genre { get; set; }
public string Director { get; set; }
public string Writer { get; set; }
public string Actors { get; set; }
public string Plot { get; set; }
public string Poster { get; set; }
public string imdbRating { get; set; }
public string imdbVotes { get; set; }
public string imdbID { get; set; }
public string Type { get; set; }
public string tomatoMeter { get; set; }
public string tomatoImage { get; set; }
public string tomatoRating { get; set; }
public string tomatoReviews { get; set; }
public string tomatoFresh { get; set; }
public string tomatoRotten { get; set; }
public string tomatoConsensus { get; set; }
public string tomatoUserMeter { get; set; }
public string tomatoUserRating { get; set; }
public string tomatoUserReviews { get; set; }
public string DVD { get; set; }
public string BoxOffice { get; set; }
public string Production { get; set; }
public string Website { get; set; }
public string Response { get; set; }
}
}
}

@ -17,23 +17,18 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <summary>
/// Class RottenTomatoesMovieProvider
/// </summary>
public class RottenTomatoesMovieProvider : BaseMetadataProvider
public class RottenTomatoesProvider : BaseMetadataProvider
{
// http://developer.rottentomatoes.com/iodocs
/// <summary>
/// The API key
/// </summary>
internal const string ApiKey = "x9wjnvv39ntjmt9zs95nm7bg";
internal const string BasicUrl = @"http://api.rottentomatoes.com/api/public/v1.0/";
private const string MovieImdb = @"movie_alias.json?id={1}&type=imdb&apikey={0}";
private const string MoviesReviews = @"movies/{1}/reviews.json?review_type=top_critic&page_limit=10&page=1&country=us&apikey={0}";
internal static RottenTomatoesMovieProvider Current { get; private set; }
private const string ApiKey = "x9wjnvv39ntjmt9zs95nm7bg";
/// <summary>
/// The _rotten tomatoes resource pool
/// </summary>
internal readonly SemaphoreSlim RottenTomatoesResourcePool = new SemaphoreSlim(1, 1);
private const string BasicUrl = @"http://api.rottentomatoes.com/api/public/v1.0/";
private const string MovieImdb = @"movie_alias.json?id={1}&type=imdb&apikey={0}";
private readonly SemaphoreSlim _rottenTomatoesResourcePool = new SemaphoreSlim(1, 1);
/// <summary>
/// Gets the json serializer.
@ -54,12 +49,11 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <param name="configurationManager">The configuration manager.</param>
/// <param name="jsonSerializer">The json serializer.</param>
/// <param name="httpClient">The HTTP client.</param>
public RottenTomatoesMovieProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient)
public RottenTomatoesProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient)
: base(logManager, configurationManager)
{
JsonSerializer = jsonSerializer;
HttpClient = httpClient;
Current = this;
}
/// <summary>
@ -136,7 +130,7 @@ namespace MediaBrowser.Controller.Providers.Movies
get
{
// Run after moviedb and xml providers
return MetadataProviderPriority.Third;
return MetadataProviderPriority.Last;
}
}
@ -148,7 +142,7 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
{
// Refresh if imdb id has changed
// Refresh if rt id has changed
if (providerInfo.Data != GetComparisonData(item.GetProviderId(MetadataProviders.Imdb)))
{
return true;
@ -183,11 +177,54 @@ namespace MediaBrowser.Controller.Providers.Movies
return true;
}
await FetchRottenTomatoesId(item, cancellationToken).ConfigureAwait(false);
using (var stream = await HttpClient.Get(new HttpRequestOptions
{
Url = GetMovieReviewsUrl(item.GetProviderId(MetadataProviders.RottenTomatoes)),
ResourcePool = _rottenTomatoesResourcePool,
CancellationToken = cancellationToken,
EnableResponseCache = true
}).ConfigureAwait(false))
{
var result = JsonSerializer.DeserializeFromStream<RTReviewList>(stream);
item.CriticReviews = result.reviews.Select(rtReview => new ItemReview
{
ReviewerName = rtReview.critic,
Publisher = rtReview.publication,
Date = DateTime.Parse(rtReview.date).ToUniversalTime(),
Caption = rtReview.quote,
Url = rtReview.links.review,
Likes = string.Equals(rtReview.freshness, "fresh", StringComparison.OrdinalIgnoreCase)
}).ToList();
}
data.Data = GetComparisonData(item.GetProviderId(MetadataProviders.Imdb));
data.LastRefreshStatus = ProviderRefreshStatus.Success;
SetLastRefreshed(item, DateTime.UtcNow);
return true;
}
/// <summary>
/// Fetches the rotten tomatoes id.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
private async Task FetchRottenTomatoesId(BaseItem item, CancellationToken cancellationToken)
{
var imdbId = item.GetProviderId(MetadataProviders.Imdb);
// Have IMDB Id
using (var stream = await HttpClient.Get(new HttpRequestOptions
{
Url = GetMovieImdbUrl(imdbId),
ResourcePool = RottenTomatoesResourcePool,
ResourcePool = _rottenTomatoesResourcePool,
CancellationToken = cancellationToken,
EnableResponseCache = true
@ -201,23 +238,18 @@ namespace MediaBrowser.Controller.Providers.Movies
item.CriticRatingSummary = hit.critics_consensus;
item.CriticRating = float.Parse(hit.ratings.critics_score);
data.Data = GetComparisonData(hit.alternate_ids.imdb);
item.SetProviderId(MetadataProviders.Imdb, hit.alternate_ids.imdb);
item.SetProviderId(MetadataProviders.RottenTomatoes, hit.id);
}
}
data.Data = GetComparisonData(imdbId);
data.LastRefreshStatus = ProviderRefreshStatus.Success;
SetLastRefreshed(item, DateTime.UtcNow);
return true;
}
// Utility functions to get the URL of the API calls
private string GetMovieReviewsUrl(string rtId)
{
return BasicUrl + string.Format(MoviesReviews, ApiKey, rtId);
}
private string GetMovieImdbUrl(string imdbId)
{
return BasicUrl + string.Format(MovieImdb, ApiKey, imdbId.TrimStart('t'));
@ -225,6 +257,28 @@ namespace MediaBrowser.Controller.Providers.Movies
// Data contract classes for use with the Rotten Tomatoes API
protected class RTReviewList
{
public int total { get; set; }
public List<RTReview> reviews { get; set; }
}
protected class RTReview
{
public string critic { get; set; }
public string date { get; set; }
public string freshness { get; set; }
public string publication { get; set; }
public string quote { get; set; }
public RTReviewLink links { get; set; }
public string original_score { get; set; }
}
protected class RTReviewLink
{
public string review { get; set; }
}
protected class RTSearchResults
{
public int total { get; set; }
@ -263,5 +317,6 @@ namespace MediaBrowser.Controller.Providers.Movies
{
public string imdb { get; set; }
}
}
}

@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <summary>
/// The meta file name
/// </summary>
protected const string MetaFileName = "mbperson.json";
protected const string MetaFileName = "tmdb3.json";
protected readonly IProviderManager ProviderManager;
@ -66,6 +66,22 @@ namespace MediaBrowser.Controller.Providers.Movies
return item is Person;
}
protected override bool RefreshOnVersionChange
{
get
{
return true;
}
}
protected override string ProviderVersion
{
get
{
return "2";
}
}
/// <summary>
/// Needses the refresh internal.
/// </summary>
@ -74,6 +90,11 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
{
if (RefreshOnVersionChange && !String.Equals(ProviderVersion, providerInfo.ProviderVersion))
{
return true;
}
//we fetch if either info or image needed and haven't already tried recently
return (string.IsNullOrEmpty(item.PrimaryImagePath) || !item.ResolveArgs.ContainsMetaFileByName(MetaFileName))
&& DateTime.Today.Subtract(providerInfo.LastRefreshed).TotalDays > ConfigurationManager.Configuration.MetadataRefreshDays;
@ -91,7 +112,6 @@ namespace MediaBrowser.Controller.Providers.Movies
cancellationToken.ThrowIfCancellationRequested();
var person = (Person)item;
var tasks = new List<Task>();
var id = person.GetProviderId(MetadataProviders.Tmdb);
@ -105,20 +125,7 @@ namespace MediaBrowser.Controller.Providers.Movies
if (!string.IsNullOrEmpty(id))
{
//get info only if not already saved
if (!item.ResolveArgs.ContainsMetaFileByName(MetaFileName))
{
tasks.Add(FetchInfo(person, id, cancellationToken));
}
//get image only if not already there
if (string.IsNullOrEmpty(item.PrimaryImagePath))
{
tasks.Add(FetchImages(person, id, cancellationToken));
}
//and wait for them to complete
await Task.WhenAll(tasks).ConfigureAwait(false);
await FetchInfo(person, id, cancellationToken).ConfigureAwait(false);
}
else
{
@ -150,6 +157,8 @@ namespace MediaBrowser.Controller.Providers.Movies
}
}
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
/// <summary>
/// Gets the TMDB id.
/// </summary>
@ -180,7 +189,7 @@ namespace MediaBrowser.Controller.Providers.Movies
{
}
return searchResult != null && searchResult.Total_Results > 0 ? searchResult.Results[0].Id.ToString() : null;
return searchResult != null && searchResult.Total_Results > 0 ? searchResult.Results[0].Id.ToString(UsCulture) : null;
}
/// <summary>
@ -192,12 +201,12 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <returns>Task.</returns>
private async Task FetchInfo(Person person, string id, CancellationToken cancellationToken)
{
string url = string.Format(@"http://api.themoviedb.org/3/person/{1}?api_key={0}", MovieDbProvider.ApiKey, id);
string url = string.Format(@"http://api.themoviedb.org/3/person/{1}?api_key={0}&append_to_response=credits,images", MovieDbProvider.ApiKey, id);
PersonResult searchResult = null;
try
{
using (Stream json = await HttpClient.Get(new HttpRequestOptions
using (var json = await HttpClient.Get(new HttpRequestOptions
{
Url = url,
CancellationToken = cancellationToken,
@ -207,10 +216,7 @@ namespace MediaBrowser.Controller.Providers.Movies
}).ConfigureAwait(false))
{
if (json != null)
{
searchResult = JsonSerializer.DeserializeFromStream<PersonResult>(json);
}
searchResult = JsonSerializer.DeserializeFromStream<PersonResult>(json);
}
}
catch (HttpException)
@ -219,7 +225,7 @@ namespace MediaBrowser.Controller.Providers.Movies
cancellationToken.ThrowIfCancellationRequested();
if (searchResult != null && searchResult.Biography != null)
if (searchResult != null)
{
ProcessInfo(person, searchResult);
@ -231,6 +237,8 @@ namespace MediaBrowser.Controller.Providers.Movies
await ProviderManager.SaveToLibraryFilesystem(person, Path.Combine(person.MetaLocation, MetaFileName), memoryStream, cancellationToken);
Logger.Debug("TmdbPersonProvider downloaded and saved information for {0}", person.Name);
await FetchImages(person, searchResult.images, cancellationToken).ConfigureAwait(false);
}
}
@ -241,99 +249,73 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <param name="searchResult">The search result.</param>
protected void ProcessInfo(Person person, PersonResult searchResult)
{
person.Overview = searchResult.Biography;
person.Overview = searchResult.biography;
DateTime date;
if (DateTime.TryParseExact(searchResult.Birthday, "yyyy-MM-dd", new CultureInfo("en-US"), DateTimeStyles.None, out date))
if (DateTime.TryParseExact(searchResult.birthday, "yyyy-MM-dd", new CultureInfo("en-US"), DateTimeStyles.None, out date))
{
person.PremiereDate = date.ToUniversalTime();
}
if (DateTime.TryParseExact(searchResult.Deathday, "yyyy-MM-dd", new CultureInfo("en-US"), DateTimeStyles.None, out date))
if (DateTime.TryParseExact(searchResult.deathday, "yyyy-MM-dd", new CultureInfo("en-US"), DateTimeStyles.None, out date))
{
person.EndDate = date.ToUniversalTime();
}
if (!string.IsNullOrEmpty(searchResult.Homepage))
if (!string.IsNullOrEmpty(searchResult.homepage))
{
person.HomePageUrl = searchResult.Homepage;
person.HomePageUrl = searchResult.homepage;
}
if (!string.IsNullOrEmpty(searchResult.Place_Of_Birth))
if (!string.IsNullOrEmpty(searchResult.place_of_birth))
{
person.AddProductionLocation(searchResult.Place_Of_Birth);
person.AddProductionLocation(searchResult.place_of_birth);
}
person.SetProviderId(MetadataProviders.Tmdb, searchResult.Id.ToString());
person.SetProviderId(MetadataProviders.Tmdb, searchResult.id.ToString(UsCulture));
}
/// <summary>
/// Fetches the images.
/// </summary>
/// <param name="person">The person.</param>
/// <param name="id">The id.</param>
/// <param name="searchResult">The search result.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
private async Task FetchImages(Person person, string id, CancellationToken cancellationToken)
private async Task FetchImages(Person person, Images searchResult, CancellationToken cancellationToken)
{
string url = string.Format(@"http://api.themoviedb.org/3/person/{1}/images?api_key={0}", MovieDbProvider.ApiKey, id);
PersonImages searchResult = null;
try
{
using (Stream json = await HttpClient.Get(new HttpRequestOptions
{
Url = url,
CancellationToken = cancellationToken,
ResourcePool = MovieDbProvider.Current.MovieDbResourcePool,
AcceptHeader = MovieDbProvider.AcceptHeader,
EnableResponseCache = true
}).ConfigureAwait(false))
{
if (json != null)
{
searchResult = JsonSerializer.DeserializeFromStream<PersonImages>(json);
}
}
}
catch (HttpException)
{
}
if (searchResult != null && searchResult.Profiles.Count > 0)
if (searchResult != null && searchResult.profiles.Count > 0)
{
//get our language
var profile =
searchResult.Profiles.FirstOrDefault(
searchResult.profiles.FirstOrDefault(
p =>
!string.IsNullOrEmpty(p.Iso_639_1) &&
p.Iso_639_1.Equals(ConfigurationManager.Configuration.PreferredMetadataLanguage,
!string.IsNullOrEmpty(GetIso639(p)) &&
GetIso639(p).Equals(ConfigurationManager.Configuration.PreferredMetadataLanguage,
StringComparison.OrdinalIgnoreCase));
if (profile == null)
{
//didn't find our language - try first null one
profile =
searchResult.Profiles.FirstOrDefault(
searchResult.profiles.FirstOrDefault(
p =>
!string.IsNullOrEmpty(p.Iso_639_1) &&
p.Iso_639_1.Equals(ConfigurationManager.Configuration.PreferredMetadataLanguage,
!string.IsNullOrEmpty(GetIso639(p)) &&
GetIso639(p).Equals(ConfigurationManager.Configuration.PreferredMetadataLanguage,
StringComparison.OrdinalIgnoreCase));
}
if (profile == null)
{
//still nothing - just get first one
profile = searchResult.Profiles[0];
profile = searchResult.profiles[0];
}
if (profile != null)
{
var tmdbSettings = await MovieDbProvider.Current.TmdbSettings.ConfigureAwait(false);
var img = await DownloadAndSaveImage(person, tmdbSettings.images.base_url + ConfigurationManager.Configuration.TmdbFetchedProfileSize + profile.File_Path,
"folder" + Path.GetExtension(profile.File_Path), cancellationToken).ConfigureAwait(false);
var img = await DownloadAndSaveImage(person, tmdbSettings.images.base_url + ConfigurationManager.Configuration.TmdbFetchedProfileSize + profile.file_path,
"folder" + Path.GetExtension(profile.file_path), cancellationToken).ConfigureAwait(false);
if (!string.IsNullOrEmpty(img))
{
@ -343,6 +325,11 @@ namespace MediaBrowser.Controller.Providers.Movies
}
}
private string GetIso639(Profile p)
{
return p.iso_639_1 == null ? string.Empty : p.iso_639_1.ToString();
}
/// <summary>
/// Downloads the and save image.
/// </summary>
@ -373,7 +360,7 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <summary>
/// Class PersonSearchResult
/// </summary>
public class PersonSearchResult
protected class PersonSearchResult
{
/// <summary>
/// Gets or sets a value indicating whether this <see cref="PersonSearchResult" /> is adult.
@ -400,7 +387,7 @@ namespace MediaBrowser.Controller.Providers.Movies
/// <summary>
/// Class PersonSearchResults
/// </summary>
public class PersonSearchResults
protected class PersonSearchResults
{
/// <summary>
/// Gets or sets the page.
@ -424,110 +411,65 @@ namespace MediaBrowser.Controller.Providers.Movies
public int Total_Results { get; set; }
}
/// <summary>
/// Class PersonResult
/// </summary>
public class PersonResult
protected class Cast
{
/// <summary>
/// Gets or sets a value indicating whether this <see cref="PersonResult" /> is adult.
/// </summary>
/// <value><c>true</c> if adult; otherwise, <c>false</c>.</value>
public bool Adult { get; set; }
/// <summary>
/// Gets or sets the also_ known_ as.
/// </summary>
/// <value>The also_ known_ as.</value>
public List<object> Also_Known_As { get; set; }
/// <summary>
/// Gets or sets the biography.
/// </summary>
/// <value>The biography.</value>
public string Biography { get; set; }
/// <summary>
/// Gets or sets the birthday.
/// </summary>
/// <value>The birthday.</value>
public string Birthday { get; set; }
/// <summary>
/// Gets or sets the deathday.
/// </summary>
/// <value>The deathday.</value>
public string Deathday { get; set; }
/// <summary>
/// Gets or sets the homepage.
/// </summary>
/// <value>The homepage.</value>
public string Homepage { get; set; }
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
public int Id { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the place_ of_ birth.
/// </summary>
/// <value>The place_ of_ birth.</value>
public string Place_Of_Birth { get; set; }
/// <summary>
/// Gets or sets the profile_ path.
/// </summary>
/// <value>The profile_ path.</value>
public string Profile_Path { get; set; }
public int id { get; set; }
public string title { get; set; }
public string character { get; set; }
public string original_title { get; set; }
public string poster_path { get; set; }
public string release_date { get; set; }
public bool adult { get; set; }
}
/// <summary>
/// Class PersonProfile
/// </summary>
public class PersonProfile
protected class Crew
{
/// <summary>
/// Gets or sets the aspect_ ratio.
/// </summary>
/// <value>The aspect_ ratio.</value>
public double Aspect_Ratio { get; set; }
/// <summary>
/// Gets or sets the file_ path.
/// </summary>
/// <value>The file_ path.</value>
public string File_Path { get; set; }
/// <summary>
/// Gets or sets the height.
/// </summary>
/// <value>The height.</value>
public int Height { get; set; }
/// <summary>
/// Gets or sets the iso_639_1.
/// </summary>
/// <value>The iso_639_1.</value>
public string Iso_639_1 { get; set; }
/// <summary>
/// Gets or sets the width.
/// </summary>
/// <value>The width.</value>
public int Width { get; set; }
public int id { get; set; }
public string title { get; set; }
public string original_title { get; set; }
public string department { get; set; }
public string job { get; set; }
public string poster_path { get; set; }
public string release_date { get; set; }
public bool adult { get; set; }
}
/// <summary>
/// Class PersonImages
/// </summary>
public class PersonImages
protected class Credits
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
public int Id { get; set; }
/// <summary>
/// Gets or sets the profiles.
/// </summary>
/// <value>The profiles.</value>
public List<PersonProfile> Profiles { get; set; }
public List<Cast> cast { get; set; }
public List<Crew> crew { get; set; }
}
protected class Profile
{
public string file_path { get; set; }
public int width { get; set; }
public int height { get; set; }
public object iso_639_1 { get; set; }
public double aspect_ratio { get; set; }
}
protected class Images
{
public List<Profile> profiles { get; set; }
}
protected class PersonResult
{
public bool adult { get; set; }
public List<object> also_known_as { get; set; }
public string biography { get; set; }
public string birthday { get; set; }
public string deathday { get; set; }
public string homepage { get; set; }
public int id { get; set; }
public string imdb_id { get; set; }
public string name { get; set; }
public string place_of_birth { get; set; }
public double popularity { get; set; }
public string profile_path { get; set; }
public Credits credits { get; set; }
public Images images { get; set; }
}
#endregion

@ -1,4 +1,5 @@
using MediaBrowser.Common.Net;
using System.Globalization;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
@ -99,6 +100,8 @@ namespace MediaBrowser.Controller.Providers.Music
return base.NeedsRefreshInternal(item, providerInfo);
}
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
/// <summary>
/// Fetches metadata and returns true or false indicating if any work that requires persistence was done
/// </summary>
@ -178,7 +181,7 @@ namespace MediaBrowser.Controller.Providers.Music
Logger.Debug("FanArtProvider getting Backdrop for " + item.Name);
try
{
item.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(item, path, ("Backdrop" + (numBackdrops > 0 ? numBackdrops.ToString() : "") + ".jpg"), SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
item.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(item, path, ("Backdrop" + (numBackdrops > 0 ? numBackdrops.ToString(UsCulture) : "") + ".jpg"), SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
numBackdrops++;
if (numBackdrops >= ConfigurationManager.Configuration.MaxBackdrops) break;
}

@ -55,15 +55,18 @@ namespace MediaBrowser.Controller.Providers.Music
// Try to find the id using last fm
var result = await FindIdFromLastFm(item, cancellationToken).ConfigureAwait(false);
if (!string.IsNullOrEmpty(result.Item1))
if (result != null)
{
return result.Item1;
}
if (!string.IsNullOrEmpty(result.Item1))
{
return result.Item1;
}
// If there were no artists returned at all, then don't bother with musicbrainz
if (!result.Item2)
{
return null;
// If there were no artists returned at all, then don't bother with musicbrainz
if (!result.Item2)
{
return null;
}
}
try

@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Providers.Music
/// </summary>
public abstract class LastfmBaseProvider : BaseMetadataProvider
{
protected static readonly SemaphoreSlim LastfmResourcePool = new SemaphoreSlim(5, 5);
protected static readonly SemaphoreSlim LastfmResourcePool = new SemaphoreSlim(4, 4);
/// <summary>
/// Initializes a new instance of the <see cref="LastfmBaseProvider" /> class.

@ -1,4 +1,5 @@
using MediaBrowser.Common.Extensions;
using System.Globalization;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
@ -364,6 +365,8 @@ namespace MediaBrowser.Controller.Providers.TV
}
}
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
/// <summary>
/// Fetches the images.
/// </summary>
@ -455,7 +458,7 @@ namespace MediaBrowser.Controller.Providers.TV
var p = b.SelectSingleNode("./BannerPath");
if (p != null)
{
var bdName = "backdrop" + (bdNo > 0 ? bdNo.ToString() : "");
var bdName = "backdrop" + (bdNo > 0 ? bdNo.ToString(UsCulture) : "");
if (ConfigurationManager.Configuration.RefreshItemImages || !series.HasLocalImage(bdName))
{
try

@ -48,21 +48,21 @@
<Reference Include="MoreLinq">
<HintPath>..\packages\morelinq.1.0.15631-beta\lib\net35\MoreLinq.dll</HintPath>
</Reference>
<Reference Include="ServiceStack, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.3.9.43\lib\net35\ServiceStack.dll</HintPath>
<HintPath>..\packages\ServiceStack.3.9.44\lib\net35\ServiceStack.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Api.Swagger, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Api.Swagger, Version=3.9.45.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Api.Swagger.3.9.43\lib\net35\ServiceStack.Api.Swagger.dll</HintPath>
<HintPath>..\packages\ServiceStack.Api.Swagger.3.9.45\lib\net35\ServiceStack.Api.Swagger.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Common, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Common, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Common.3.9.43\lib\net35\ServiceStack.Common.dll</HintPath>
<HintPath>..\packages\ServiceStack.Common.3.9.44\lib\net35\ServiceStack.Common.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Interfaces, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Interfaces, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Common.3.9.43\lib\net35\ServiceStack.Interfaces.dll</HintPath>
<HintPath>..\packages\ServiceStack.Common.3.9.44\lib\net35\ServiceStack.Interfaces.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.OrmLite, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -76,13 +76,13 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Redis.3.9.43\lib\net35\ServiceStack.Redis.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.ServiceInterface, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.ServiceInterface, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.3.9.43\lib\net35\ServiceStack.ServiceInterface.dll</HintPath>
<HintPath>..\packages\ServiceStack.3.9.44\lib\net35\ServiceStack.ServiceInterface.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Text, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Text, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Text.3.9.43\lib\net35\ServiceStack.Text.dll</HintPath>
<HintPath>..\packages\ServiceStack.Text.3.9.44\lib\net35\ServiceStack.Text.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
@ -203,20 +203,19 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="x64\SQLite.Interop.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="x86\SQLite.Interop.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<EmbeddedResource Include="MediaEncoder\readme.txt" />
<Content Include="README.txt" />
<Content Include="swagger-ui\css\hightlight.default.css" />
<Content Include="swagger-ui\css\screen.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="swagger-ui\images\logo_small.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="swagger-ui\images\pet_store_api.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="swagger-ui\images\throbber.gif">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="swagger-ui\images\wordnik_api.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -226,13 +225,16 @@
<Content Include="swagger-ui\lib\backbone-min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="swagger-ui\lib\handlebars.runtime-1.0.0.beta.6.js">
<Content Include="swagger-ui\lib\handlebars-1.0.rc.1.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="swagger-ui\lib\jquery.ba-bbq.min.js">
<Content Include="swagger-ui\lib\highlight.7.3.pack.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="swagger-ui\lib\jquery-1.8.0.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="swagger-ui\lib\jquery.min.js">
<Content Include="swagger-ui\lib\jquery.ba-bbq.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="swagger-ui\lib\jquery.slideto.min.js">
@ -253,6 +255,13 @@
<Content Include="swagger-ui\swagger-ui.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="x64\SQLite.Interop.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="x86\SQLite.Interop.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<EmbeddedResource Include="MediaEncoder\readme.txt" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="MediaEncoder\fonts\ARIALUNI.TTF" />

@ -1,41 +0,0 @@
ServiceStack services should be available under '/api' path. If it's a brand new MVC project
install NuGet Package: ServiceStack.Host.Mvc. The package prepares ServiceStack default services. Make sure
that you added ignore for MVC routes:
routes.IgnoreRoute("api/{*pathInfo}");
If it's MVC4 project, then don't forget to disable WebAPI:
//WebApiConfig.Register(GlobalConfiguration.Configuration);
Enable Swagger plugin in AppHost.cs with:
public override void Configure(Container container)
{
...
Plugins.Add(new SwaggerFeature());
// uncomment CORS feature if it's has to be available from external sites
//Plugins.Add(new CorsFeature());
...
}
Compile it. Now you can access swagger UI with:
http://localost:port/swagger-ui/index.html
or
http://yoursite/swagger-ui/index.html
For more info about ServiceStack please visit: http://www.servicestack.net
Feel free to ask questions about ServiceStack on:
http://stackoverflow.com/
or on the mailing Group at:
http://groups.google.com/group/servicestack
Enjoy!

@ -7,12 +7,12 @@
<package id="Rx-Core" version="2.1.30214.0" targetFramework="net45" />
<package id="Rx-Interfaces" version="2.1.30214.0" targetFramework="net45" />
<package id="Rx-Linq" version="2.1.30214.0" targetFramework="net45" />
<package id="ServiceStack" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Api.Swagger" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack" version="3.9.44" targetFramework="net45" />
<package id="ServiceStack.Api.Swagger" version="3.9.45" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.44" targetFramework="net45" />
<package id="ServiceStack.OrmLite.SqlServer" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Redis" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.44" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="System.Data.SQLite" version="1.0.85.0" targetFramework="net45" />
</packages>

@ -0,0 +1,135 @@
/*
Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
*/
pre code {
display: block; padding: 0.5em;
background: #F0F0F0;
}
pre code,
pre .subst,
pre .tag .title,
pre .lisp .title,
pre .clojure .built_in,
pre .nginx .title {
color: black;
}
pre .string,
pre .title,
pre .constant,
pre .parent,
pre .tag .value,
pre .rules .value,
pre .rules .value .number,
pre .preprocessor,
pre .ruby .symbol,
pre .ruby .symbol .string,
pre .aggregate,
pre .template_tag,
pre .django .variable,
pre .smalltalk .class,
pre .addition,
pre .flow,
pre .stream,
pre .bash .variable,
pre .apache .tag,
pre .apache .cbracket,
pre .tex .command,
pre .tex .special,
pre .erlang_repl .function_or_atom,
pre .markdown .header {
color: #800;
}
pre .comment,
pre .annotation,
pre .template_comment,
pre .diff .header,
pre .chunk,
pre .markdown .blockquote {
color: #888;
}
pre .number,
pre .date,
pre .regexp,
pre .literal,
pre .smalltalk .symbol,
pre .smalltalk .char,
pre .go .constant,
pre .change,
pre .markdown .bullet,
pre .markdown .link_url {
color: #080;
}
pre .label,
pre .javadoc,
pre .ruby .string,
pre .decorator,
pre .filter .argument,
pre .localvars,
pre .array,
pre .attr_selector,
pre .important,
pre .pseudo,
pre .pi,
pre .doctype,
pre .deletion,
pre .envvar,
pre .shebang,
pre .apache .sqbracket,
pre .nginx .built_in,
pre .tex .formula,
pre .erlang_repl .reserved,
pre .prompt,
pre .markdown .link_label,
pre .vhdl .attribute,
pre .clojure .attribute,
pre .coffeescript .property {
color: #88F
}
pre .keyword,
pre .id,
pre .phpdoc,
pre .title,
pre .built_in,
pre .aggregate,
pre .css .tag,
pre .javadoctag,
pre .phpdoc,
pre .yardoctag,
pre .smalltalk .class,
pre .winutils,
pre .bash .variable,
pre .apache .tag,
pre .go .typename,
pre .tex .command,
pre .markdown .strong,
pre .request,
pre .status {
font-weight: bold;
}
pre .markdown .emphasis {
font-style: italic;
}
pre .nginx .built_in {
font-weight: normal;
}
pre .coffeescript .javascript,
pre .javascript .xml,
pre .tex .formula,
pre .xml .javascript,
pre .xml .vbscript,
pre .xml .css,
pre .xml .cdata {
opacity: 0.5;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

@ -1,52 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<title>Swagger UI</title>
<link href='http://fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/>
<link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/>
<link href='css/hightlight.default.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
<script src='lib/jquery.min.js' type='text/javascript'></script>
<script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='lib/handlebars.runtime-1.0.0.beta.6.js' type='text/javascript'></script>
<script src='lib/handlebars-1.0.rc.1.js' type='text/javascript'></script>
<script src='lib/underscore-min.js' type='text/javascript'></script>
<script src='lib/backbone-min.js' type='text/javascript'></script>
<script src='lib/swagger.js' type='text/javascript'></script>
<script src='swagger-ui.js' type='text/javascript'></script>
<style type="text/css">
.swagger-ui-wrap {
max-width: 960px;
margin-left: auto;
margin-right: auto;
}
.icon-btn {
cursor: pointer;
}
#message-bar {
min-height: 30px;
text-align: center;
padding-top: 10px;
}
.message-success {
color: #89BF04;
}
.message-fail {
color: #cc0000;
}
</style>
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
<script type="text/javascript">
$(function () {
window.swaggerUi = new SwaggerUi({
discoveryUrl:'../resources',
apiKey:"",
$(function () {
window.swaggerUi = new SwaggerUi({
discoveryUrl: "../resources",
apiKey:"special-key",
dom_id:"swagger-ui-container",
supportHeaderParams: false,
supportedSubmitMethods: ['get', 'post', 'put']
supportedSubmitMethods: ['get', 'post', 'put'],
onComplete: function(swaggerApi, swaggerUi){
if(console) {
console.log("Loaded SwaggerUI")
console.log(swaggerApi);
console.log(swaggerUi);
}
$('pre code').each(function(i, e) {hljs.highlightBlock(e)});
},
onFailure: function(data) {
if(console) {
console.log("Unable to Load SwaggerUI");
console.log(data);
}
},
docExpansion: "none"
});
window.swaggerUi.load();

@ -1,223 +0,0 @@
// lib/handlebars/base.js
var Handlebars = {};
Handlebars.VERSION = "1.0.beta.6";
Handlebars.helpers = {};
Handlebars.partials = {};
Handlebars.registerHelper = function(name, fn, inverse) {
if(inverse) { fn.not = inverse; }
this.helpers[name] = fn;
};
Handlebars.registerPartial = function(name, str) {
this.partials[name] = str;
};
Handlebars.registerHelper('helperMissing', function(arg) {
if(arguments.length === 2) {
return undefined;
} else {
throw new Error("Could not find property '" + arg + "'");
}
});
var toString = Object.prototype.toString, functionType = "[object Function]";
Handlebars.registerHelper('blockHelperMissing', function(context, options) {
var inverse = options.inverse || function() {}, fn = options.fn;
var ret = "";
var type = toString.call(context);
if(type === functionType) { context = context.call(this); }
if(context === true) {
return fn(this);
} else if(context === false || context == null) {
return inverse(this);
} else if(type === "[object Array]") {
if(context.length > 0) {
for(var i=0, j=context.length; i<j; i++) {
ret = ret + fn(context[i]);
}
} else {
ret = inverse(this);
}
return ret;
} else {
return fn(context);
}
});
Handlebars.registerHelper('each', function(context, options) {
var fn = options.fn, inverse = options.inverse;
var ret = "";
if(context && context.length > 0) {
for(var i=0, j=context.length; i<j; i++) {
ret = ret + fn(context[i]);
}
} else {
ret = inverse(this);
}
return ret;
});
Handlebars.registerHelper('if', function(context, options) {
var type = toString.call(context);
if(type === functionType) { context = context.call(this); }
if(!context || Handlebars.Utils.isEmpty(context)) {
return options.inverse(this);
} else {
return options.fn(this);
}
});
Handlebars.registerHelper('unless', function(context, options) {
var fn = options.fn, inverse = options.inverse;
options.fn = inverse;
options.inverse = fn;
return Handlebars.helpers['if'].call(this, context, options);
});
Handlebars.registerHelper('with', function(context, options) {
return options.fn(context);
});
Handlebars.registerHelper('log', function(context) {
Handlebars.log(context);
});
;
// lib/handlebars/utils.js
Handlebars.Exception = function(message) {
var tmp = Error.prototype.constructor.apply(this, arguments);
for (var p in tmp) {
if (tmp.hasOwnProperty(p)) { this[p] = tmp[p]; }
}
this.message = tmp.message;
};
Handlebars.Exception.prototype = new Error;
// Build out our basic SafeString type
Handlebars.SafeString = function(string) {
this.string = string;
};
Handlebars.SafeString.prototype.toString = function() {
return this.string.toString();
};
(function() {
var escape = {
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#x27;",
"`": "&#x60;"
};
var badChars = /&(?!\w+;)|[<>"'`]/g;
var possible = /[&<>"'`]/;
var escapeChar = function(chr) {
return escape[chr] || "&amp;";
};
Handlebars.Utils = {
escapeExpression: function(string) {
// don't escape SafeStrings, since they're already safe
if (string instanceof Handlebars.SafeString) {
return string.toString();
} else if (string == null || string === false) {
return "";
}
if(!possible.test(string)) { return string; }
return string.replace(badChars, escapeChar);
},
isEmpty: function(value) {
if (typeof value === "undefined") {
return true;
} else if (value === null) {
return true;
} else if (value === false) {
return true;
} else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
return true;
} else {
return false;
}
}
};
})();;
// lib/handlebars/runtime.js
Handlebars.VM = {
template: function(templateSpec) {
// Just add water
var container = {
escapeExpression: Handlebars.Utils.escapeExpression,
invokePartial: Handlebars.VM.invokePartial,
programs: [],
program: function(i, fn, data) {
var programWrapper = this.programs[i];
if(data) {
return Handlebars.VM.program(fn, data);
} else if(programWrapper) {
return programWrapper;
} else {
programWrapper = this.programs[i] = Handlebars.VM.program(fn);
return programWrapper;
}
},
programWithDepth: Handlebars.VM.programWithDepth,
noop: Handlebars.VM.noop
};
return function(context, options) {
options = options || {};
return templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
};
},
programWithDepth: function(fn, data, $depth) {
var args = Array.prototype.slice.call(arguments, 2);
return function(context, options) {
options = options || {};
return fn.apply(this, [context, options.data || data].concat(args));
};
},
program: function(fn, data) {
return function(context, options) {
options = options || {};
return fn(context, options.data || data);
};
},
noop: function() { return ""; },
invokePartial: function(partial, name, context, helpers, partials, data) {
options = { helpers: helpers, partials: partials, data: data };
if(partial === undefined) {
throw new Handlebars.Exception("The partial " + name + " could not be found");
} else if(partial instanceof Function) {
return partial(context, options);
} else if (!Handlebars.compile) {
throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
} else {
partials[name] = Handlebars.compile(partial);
return partials[name](context, options);
}
}
};
Handlebars.template = Handlebars.VM.template;
;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.3.3
// Generated by CoffeeScript 1.4.0
(function() {
var SwaggerApi, SwaggerOperation, SwaggerRequest, SwaggerResource,
var SwaggerApi, SwaggerModel, SwaggerModelProperty, SwaggerOperation, SwaggerRequest, SwaggerResource,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
SwaggerApi = (function() {
@ -40,6 +40,8 @@
}
this.failure = options.failure != null ? options.failure : function() {};
this.progress = options.progress != null ? options.progress : function() {};
this.headers = options.headers != null ? options.headers : {};
this.booleanValues = options.booleanValues != null ? options.booleanValues : new Array('true', 'false');
this.discoveryUrl = this.suffixApiKey(this.discoveryUrl);
if (options.success != null) {
this.build();
@ -51,6 +53,9 @@
this.progress('fetching resource list: ' + this.discoveryUrl);
return jQuery.getJSON(this.discoveryUrl, function(response) {
var res, resource, _i, _j, _len, _len1, _ref, _ref1;
if (response.apiVersion != null) {
_this.apiVersion = response.apiVersion;
}
if ((response.basePath != null) && jQuery.trim(response.basePath).length > 0) {
_this.basePath = response.basePath;
if (_this.basePath.match(/^HTTP/i) == null) {
@ -61,8 +66,8 @@
_this.basePath = _this.discoveryUrl.substring(0, _this.discoveryUrl.lastIndexOf('/'));
log('derived basepath from discoveryUrl as ' + _this.basePath);
}
_this.resources = {};
_this.resourcesArray = [];
_this.apis = {};
_this.apisArray = [];
if (response.resourcePath != null) {
_this.resourcePath = response.resourcePath;
res = null;
@ -76,8 +81,8 @@
}
}
if (res != null) {
_this.resources[res.name] = res;
_this.resourcesArray.push(res);
_this.apis[res.name] = res;
_this.apisArray.push(res);
res.ready = true;
_this.selfReflect();
}
@ -86,28 +91,37 @@
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
resource = _ref1[_j];
res = new SwaggerResource(resource, _this);
_this.resources[res.name] = res;
_this.resourcesArray.push(res);
_this.apis[res.name] = res;
_this.apisArray.push(res);
}
}
return _this;
}).error(function(error) {
return _this.fail(error.status + ' : ' + error.statusText + ' ' + _this.discoveryUrl);
if (_this.discoveryUrl.substring(0, 4) !== 'http') {
return _this.fail('Please specify the protocol for ' + _this.discoveryUrl);
} else if (error.status === 0) {
return _this.fail('Can\'t read from server. It may not have the appropriate access-control-origin settings.');
} else if (error.status === 404) {
return _this.fail('Can\'t read swagger JSON from ' + _this.discoveryUrl);
} else {
return _this.fail(error.status + ' : ' + error.statusText + ' ' + _this.discoveryUrl);
}
});
};
SwaggerApi.prototype.selfReflect = function() {
var resource, resource_name, _ref;
if (this.resources == null) {
if (this.apis == null) {
return false;
}
_ref = this.resources;
_ref = this.apis;
for (resource_name in _ref) {
resource = _ref[resource_name];
if (resource.ready == null) {
return false;
}
}
this.setConsolidatedModels();
this.ready = true;
if (this.success != null) {
return this.success();
@ -119,6 +133,29 @@
throw message;
};
SwaggerApi.prototype.setConsolidatedModels = function() {
var model, modelName, resource, resource_name, _i, _len, _ref, _ref1, _results;
this.modelsArray = [];
this.models = {};
_ref = this.apis;
for (resource_name in _ref) {
resource = _ref[resource_name];
for (modelName in resource.models) {
if (!(this.models[modelName] != null)) {
this.models[modelName] = resource.models[modelName];
this.modelsArray.push(resource.models[modelName]);
}
}
}
_ref1 = this.modelsArray;
_results = [];
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
model = _ref1[_i];
_results.push(model.setReferencedModels(this.models));
}
return _results;
};
SwaggerApi.prototype.suffixApiKey = function(url) {
var sep;
if ((this.api_key != null) && jQuery.trim(this.api_key).length > 0 && (url != null)) {
@ -131,7 +168,7 @@
SwaggerApi.prototype.help = function() {
var operation, operation_name, parameter, resource, resource_name, _i, _len, _ref, _ref1, _ref2;
_ref = this.resources;
_ref = this.apis;
for (resource_name in _ref) {
resource = _ref[resource_name];
console.log(resource_name);
@ -166,8 +203,11 @@
this.basePath = this.api.basePath;
this.operations = {};
this.operationsArray = [];
this.modelsArray = [];
this.models = {};
if ((resourceObj.operations != null) && (this.api.resourcePath != null)) {
this.api.progress('reading resource ' + this.name + ' operations');
this.api.progress('reading resource ' + this.name + ' models and operations');
this.addModels(resourceObj.models);
this.addOperations(resourceObj.path, resourceObj.operations);
this.api[this.name] = this;
} else {
@ -182,6 +222,7 @@
_this.basePath = response.basePath;
_this.basePath = _this.basePath.replace(/\/$/, '');
}
_this.addModels(response.models);
if (response.apis) {
_ref = response.apis;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@ -193,18 +234,42 @@
_this.ready = true;
return _this.api.selfReflect();
}).error(function(error) {
return _this.fail(error.status + ' : ' + error.statusText + ' ' + _this.url);
return _this.api.fail("Unable to read api '" + _this.name + "' from path " + _this.url + " (server returned " + error.statusText + ")");
});
}
}
SwaggerResource.prototype.addModels = function(models) {
var model, modelName, swaggerModel, _i, _len, _ref, _results;
if (models != null) {
for (modelName in models) {
if (!(this.models[modelName] != null)) {
swaggerModel = new SwaggerModel(modelName, models[modelName]);
this.modelsArray.push(swaggerModel);
this.models[modelName] = swaggerModel;
}
}
_ref = this.modelsArray;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
model = _ref[_i];
_results.push(model.setReferencedModels(this.models));
}
return _results;
}
};
SwaggerResource.prototype.addOperations = function(resource_path, ops) {
var o, op, _i, _len, _results;
var consumes, o, op, _i, _len, _results;
if (ops) {
_results = [];
for (_i = 0, _len = ops.length; _i < _len; _i++) {
o = ops[_i];
op = new SwaggerOperation(o.nickname, resource_path, o.httpMethod, o.parameters, o.summary, o.notes, this);
consumes = o.consumes;
if (o.supportedContentTypes) {
consumes = o.supportedContentTypes;
}
op = new SwaggerOperation(o.nickname, resource_path, o.httpMethod, o.parameters, o.summary, o.notes, o.responseClass, o.errorResponses, this, o.consumes, o.produces);
this.operations[op.nickname] = op;
_results.push(this.operationsArray.push(op));
}
@ -231,10 +296,143 @@
})();
SwaggerModel = (function() {
function SwaggerModel(modelName, obj) {
var propertyName;
this.name = obj.id != null ? obj.id : modelName;
this.properties = [];
for (propertyName in obj.properties) {
this.properties.push(new SwaggerModelProperty(propertyName, obj.properties[propertyName]));
}
}
SwaggerModel.prototype.setReferencedModels = function(allModels) {
var prop, _i, _len, _ref, _results;
_ref = this.properties;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
prop = _ref[_i];
if (allModels[prop.dataType] != null) {
_results.push(prop.refModel = allModels[prop.dataType]);
} else if ((prop.refDataType != null) && (allModels[prop.refDataType] != null)) {
_results.push(prop.refModel = allModels[prop.refDataType]);
} else {
_results.push(void 0);
}
}
return _results;
};
SwaggerModel.prototype.getMockSignature = function(prefix, modelsToIgnore) {
var classClose, classOpen, prop, propertiesStr, returnVal, strong, strongClose, stronger, _i, _j, _len, _len1, _ref, _ref1;
propertiesStr = [];
_ref = this.properties;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
prop = _ref[_i];
propertiesStr.push(prop.toString());
}
strong = '<span style="font-weight: bold; color: #000; font-size: 1.0em">';
stronger = '<span style="font-weight: bold; color: #000; font-size: 1.1em">';
strongClose = '</span>';
classOpen = strong + 'class ' + this.name + '(' + strongClose;
classClose = strong + ')' + strongClose;
returnVal = classOpen + '<span>' + propertiesStr.join('</span>, <span>') + '</span>' + classClose;
if (prefix != null) {
returnVal = stronger + prefix + strongClose + '<br/>' + returnVal;
}
if (!modelsToIgnore) {
modelsToIgnore = [];
}
modelsToIgnore.push(this);
_ref1 = this.properties;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
prop = _ref1[_j];
if ((prop.refModel != null) && (modelsToIgnore.indexOf(prop.refModel)) === -1) {
returnVal = returnVal + ('<br>' + prop.refModel.getMockSignature(void 0, modelsToIgnore));
}
}
return returnVal;
};
SwaggerModel.prototype.createJSONSample = function(modelToIgnore) {
var prop, result, _i, _len, _ref;
result = {};
_ref = this.properties;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
prop = _ref[_i];
result[prop.name] = prop.getSampleValue(modelToIgnore);
}
return result;
};
return SwaggerModel;
})();
SwaggerModelProperty = (function() {
function SwaggerModelProperty(name, obj) {
this.name = name;
this.dataType = obj.type;
this.isArray = this.dataType.toLowerCase() === 'array';
this.descr = obj.description;
if (obj.items != null) {
if (obj.items.type != null) {
this.refDataType = obj.items.type;
}
if (obj.items.$ref != null) {
this.refDataType = obj.items.$ref;
}
}
this.dataTypeWithRef = this.refDataType != null ? this.dataType + '[' + this.refDataType + ']' : this.dataType;
if (obj.allowableValues != null) {
this.valueType = obj.allowableValues.valueType;
this.values = obj.allowableValues.values;
if (this.values != null) {
this.valuesString = "'" + this.values.join("' or '") + "'";
}
}
}
SwaggerModelProperty.prototype.getSampleValue = function(modelToIgnore) {
var result;
if ((this.refModel != null) && (!(this.refModel === modelToIgnore))) {
result = this.refModel.createJSONSample(this.refModel);
} else {
if (this.isArray) {
result = this.refDataType;
} else {
result = this.dataType;
}
}
if (this.isArray) {
return [result];
} else {
return result;
}
};
SwaggerModelProperty.prototype.toString = function() {
var str;
str = this.name + ': ' + this.dataTypeWithRef;
if (this.values != null) {
str += " = ['" + this.values.join("' or '") + "']";
}
if (this.descr != null) {
str += ' {' + this.descr + '}';
}
return str;
};
return SwaggerModelProperty;
})();
SwaggerOperation = (function() {
function SwaggerOperation(nickname, path, httpMethod, parameters, summary, notes, resource) {
var parameter, v, _i, _j, _len, _len1, _ref, _ref1,
function SwaggerOperation(nickname, path, httpMethod, parameters, summary, notes, responseClass, errorResponses, resource, consumes, produces) {
var parameter, v, _i, _j, _len, _len1, _ref, _ref1, _ref2,
_this = this;
this.nickname = nickname;
this.path = path;
@ -242,7 +440,11 @@
this.parameters = parameters != null ? parameters : [];
this.summary = summary;
this.notes = notes;
this.responseClass = responseClass;
this.errorResponses = errorResponses;
this.resource = resource;
this.consumes = consumes;
this.produces = produces;
this["do"] = __bind(this["do"], this);
if (this.nickname == null) {
@ -258,10 +460,24 @@
this.httpMethod = this.httpMethod.toLowerCase();
this.isGetMethod = this.httpMethod === "get";
this.resourceName = this.resource.name;
_ref = this.parameters;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
parameter = _ref[_i];
if (((_ref = this.responseClass) != null ? _ref.toLowerCase() : void 0) === 'void') {
this.responseClass = void 0;
}
if (this.responseClass != null) {
this.responseClassSignature = this.getSignature(this.responseClass, this.resource.models);
this.responseSampleJSON = this.getSampleJSON(this.responseClass, this.resource.models);
}
this.errorResponses = this.errorResponses || [];
_ref1 = this.parameters;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
parameter = _ref1[_i];
parameter.name = parameter.name || parameter.dataType;
if (parameter.dataType.toLowerCase() === 'boolean') {
parameter.allowableValues = {};
parameter.allowableValues.values = this.resource.api.booleanValues;
}
parameter.signature = this.getSignature(parameter.dataType, this.resource.models);
parameter.sampleJSON = this.getSampleJSON(parameter.dataType, this.resource.models);
if (parameter.allowableValues != null) {
if (parameter.allowableValues.valueType === "RANGE") {
parameter.isRange = true;
@ -270,9 +486,9 @@
}
if (parameter.allowableValues.values != null) {
parameter.allowableValues.descriptiveValues = [];
_ref1 = parameter.allowableValues.values;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
v = _ref1[_j];
_ref2 = parameter.allowableValues.values;
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
v = _ref2[_j];
if ((parameter.defaultValue != null) && parameter.defaultValue === v) {
parameter.allowableValues.descriptiveValues.push({
value: v,
@ -293,6 +509,40 @@
};
}
SwaggerOperation.prototype.isListType = function(dataType) {
if (dataType.indexOf('[') >= 0) {
return dataType.substring(dataType.indexOf('[') + 1, dataType.indexOf(']'));
} else {
return void 0;
}
};
SwaggerOperation.prototype.getSignature = function(dataType, models) {
var isPrimitive, listType;
listType = this.isListType(dataType);
isPrimitive = ((listType != null) && models[listType]) || (models[dataType] != null) ? false : true;
if (isPrimitive) {
return dataType;
} else {
if (listType != null) {
return models[listType].getMockSignature(dataType);
} else {
return models[dataType].getMockSignature(dataType);
}
}
};
SwaggerOperation.prototype.getSampleJSON = function(dataType, models) {
var isPrimitive, listType, val;
listType = this.isListType(dataType);
isPrimitive = ((listType != null) && models[listType]) || (models[dataType] != null) ? false : true;
val = isPrimitive ? void 0 : (listType != null ? models[listType].createJSONSample() : models[dataType].createJSONSample());
if (val) {
val = listType ? [val] : val;
return JSON.stringify(val, null, 2);
}
};
SwaggerOperation.prototype["do"] = function(args, callback, error) {
var body, headers;
if (args == null) {
@ -333,7 +583,7 @@
};
SwaggerOperation.prototype.urlify = function(args, includeApiKey) {
var param, queryParams, url, _i, _len, _ref;
var param, queryParams, reg, url, _i, _len, _ref;
if (includeApiKey == null) {
includeApiKey = true;
}
@ -343,7 +593,8 @@
param = _ref[_i];
if (param.paramType === 'path') {
if (args[param.name]) {
url = url.replace("{" + param.name + "}", encodeURIComponent(args[param.name]));
reg = new RegExp('\{' + param.name + '[^\}]*\}', 'gi');
url = url.replace(reg, encodeURIComponent(args[param.name]));
delete args[param.name];
} else {
throw "" + param.name + " is a required path param.";
@ -354,9 +605,9 @@
args[this.apiKeyName] = this.resource.api.api_key;
}
if (this.supportHeaderParams()) {
queryParams = jQuery.param(this.getQueryParams(args));
queryParams = jQuery.param(this.getQueryParams(args, includeApiKey));
} else {
queryParams = jQuery.param(this.getQueryAndHeaderParams(args));
queryParams = jQuery.param(this.getQueryAndHeaderParams(args, includeApiKey));
}
if ((queryParams != null) && queryParams.length > 0) {
url += "?" + queryParams;
@ -394,7 +645,7 @@
};
SwaggerOperation.prototype.getMatchingParams = function(paramTypes, args, includeApiKey) {
var matchingParams, param, _i, _len, _ref;
var matchingParams, name, param, value, _i, _len, _ref, _ref1;
matchingParams = {};
_ref = this.parameters;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@ -406,6 +657,13 @@
if (includeApiKey && (this.resource.api.api_key != null) && this.resource.api.api_key.length > 0) {
matchingParams[this.resource.api.apiKeyName] = this.resource.api.api_key;
}
if (jQuery.inArray('header', paramTypes) >= 0) {
_ref1 = this.resource.api.headers;
for (name in _ref1) {
value = _ref1[name];
matchingParams[name] = value;
}
}
return matchingParams;
};

File diff suppressed because one or more lines are too long

@ -138,17 +138,32 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MediaBrowser.IsoMounting.3.0.51\lib\net45\pfmclrapi.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Common, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack">
<HintPath>..\packages\ServiceStack.3.9.44\lib\net35\ServiceStack.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Common, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Common.3.9.43\lib\net35\ServiceStack.Common.dll</HintPath>
<HintPath>..\packages\ServiceStack.Common.3.9.44\lib\net35\ServiceStack.Common.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Interfaces, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Interfaces, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Common.3.9.43\lib\net35\ServiceStack.Interfaces.dll</HintPath>
<HintPath>..\packages\ServiceStack.Common.3.9.44\lib\net35\ServiceStack.Interfaces.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.OrmLite">
<HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.44\lib\ServiceStack.OrmLite.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.OrmLite.SqlServer">
<HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.44\lib\ServiceStack.OrmLite.SqlServer.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Redis">
<HintPath>..\packages\ServiceStack.Redis.3.9.44\lib\net35\ServiceStack.Redis.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.ServiceInterface">
<HintPath>..\packages\ServiceStack.3.9.44\lib\net35\ServiceStack.ServiceInterface.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Text, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Text, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Text.3.9.43\lib\net35\ServiceStack.Text.dll</HintPath>
<HintPath>..\packages\ServiceStack.Text.3.9.44\lib\net35\ServiceStack.Text.dll</HintPath>
</Reference>
<Reference Include="SimpleInjector, Version=2.2.1.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>

@ -5,7 +5,10 @@
<package id="MahApps.Metro" version="0.11.0.17-ALPHA" targetFramework="net45" />
<package id="MediaBrowser.IsoMounting" version="3.0.51" targetFramework="net45" />
<package id="NLog" version="2.0.1.2" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack" version="3.9.44" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.44" targetFramework="net45" />
<package id="ServiceStack.OrmLite.SqlServer" version="3.9.44" targetFramework="net45" />
<package id="ServiceStack.Redis" version="3.9.44" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.44" targetFramework="net45" />
<package id="SimpleInjector" version="2.2.1" targetFramework="net45" />
</packages>

@ -35,17 +35,17 @@
<RunPostBuildEvent>Always</RunPostBuildEvent>
</PropertyGroup>
<ItemGroup>
<Reference Include="ServiceStack.Common, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Common, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Common.3.9.43\lib\net35\ServiceStack.Common.dll</HintPath>
<HintPath>..\packages\ServiceStack.Common.3.9.44\lib\net35\ServiceStack.Common.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Interfaces, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Interfaces, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Common.3.9.43\lib\net35\ServiceStack.Interfaces.dll</HintPath>
<HintPath>..\packages\ServiceStack.Common.3.9.44\lib\net35\ServiceStack.Interfaces.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Text, Version=3.9.43.0, Culture=neutral, processorArchitecture=MSIL">
<Reference Include="ServiceStack.Text, Version=3.9.44.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ServiceStack.Text.3.9.43\lib\net35\ServiceStack.Text.dll</HintPath>
<HintPath>..\packages\ServiceStack.Text.3.9.44\lib\net35\ServiceStack.Text.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
@ -111,6 +111,9 @@
<Content Include="dashboard-ui\css\images\items\searchhints\tv.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\media\settings.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\rotten.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.99" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.43" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.44" targetFramework="net45" />
<package id="ServiceStack.Text" version="3.9.44" targetFramework="net45" />
</packages>
Loading…
Cancel
Save