Do better to make sure hls files are cleaned up

This commit is contained in:
Luke Pulverenti 2014-05-09 00:38:12 -04:00
parent 06a11c27d9
commit 1a323767be
19 changed files with 297 additions and 85 deletions

View file

@ -71,8 +71,7 @@ namespace MediaBrowser.Api
/// </summary>
private void DeleteEncodedMediaCache()
{
foreach (var file in Directory.EnumerateFiles(_appPaths.TranscodingTempPath)
.Where(i => EntityResolutionHelper.VideoFileExtensions.Contains(Path.GetExtension(i)))
foreach (var file in Directory.EnumerateFiles(_appPaths.TranscodingTempPath, "*", SearchOption.AllDirectories)
.ToList())
{
File.Delete(file);
@ -116,11 +115,10 @@ namespace MediaBrowser.Api
/// <param name="path">The path.</param>
/// <param name="type">The type.</param>
/// <param name="process">The process.</param>
/// <param name="isVideo">if set to <c>true</c> [is video].</param>
/// <param name="startTimeTicks">The start time ticks.</param>
/// <param name="sourcePath">The source path.</param>
/// <param name="deviceId">The device id.</param>
public void OnTranscodeBeginning(string path, TranscodingJobType type, Process process, bool isVideo, long? startTimeTicks, string sourcePath, string deviceId)
public void OnTranscodeBeginning(string path, TranscodingJobType type, Process process, long? startTimeTicks, string sourcePath, string deviceId)
{
lock (_activeTranscodingJobs)
{
@ -130,7 +128,6 @@ namespace MediaBrowser.Api
Path = path,
Process = process,
ActiveRequestCount = 1,
IsVideo = isVideo,
StartTimeTicks = startTimeTicks,
SourcePath = sourcePath,
DeviceId = deviceId
@ -261,7 +258,7 @@ namespace MediaBrowser.Api
{
// This is really only needed for HLS.
// Progressive streams can stop on their own reliably
jobs.AddRange(_activeTranscodingJobs.Where(i => isVideo == i.IsVideo && string.Equals(deviceId, i.DeviceId, StringComparison.OrdinalIgnoreCase)));
jobs.AddRange(_activeTranscodingJobs.Where(i => string.Equals(deviceId, i.DeviceId, StringComparison.OrdinalIgnoreCase)));
}
foreach (var job in jobs)
@ -325,37 +322,15 @@ namespace MediaBrowser.Api
}
}
// Determine if it exited successfully
var hasExitedSuccessfully = false;
try
{
hasExitedSuccessfully = process.ExitCode == 0;
}
catch (InvalidOperationException)
{
}
catch (NotSupportedException)
{
}
// Dispose the process
process.Dispose();
// If it didn't complete successfully cleanup the partial files
// Also don't cache output from resume points
// Also don't cache video
if (!hasExitedSuccessfully || job.StartTimeTicks.HasValue || job.IsVideo)
{
DeletePartialStreamFiles(job.Path, job.Type, 0, 1500);
}
DeletePartialStreamFiles(job.Path, job.Type, 0, 1500);
}
private async void DeletePartialStreamFiles(string path, TranscodingJobType jobType, int retryCount, int delayMs)
{
if (retryCount >= 5)
if (retryCount >= 10)
{
return;
}
@ -455,7 +430,6 @@ namespace MediaBrowser.Api
/// <value>The kill timer.</value>
public Timer KillTimer { get; set; }
public bool IsVideo { get; set; }
public long? StartTimeTicks { get; set; }
public string SourcePath { get; set; }
public string DeviceId { get; set; }

View file

@ -24,6 +24,8 @@ namespace MediaBrowser.Api.DefaultTheme
[ApiMember(Name = "RecentlyPlayedGamesLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int RecentlyPlayedGamesLimit { get; set; }
public string ParentId { get; set; }
}
[Route("/MBT/DefaultTheme/TV", "GET")]
@ -49,6 +51,8 @@ namespace MediaBrowser.Api.DefaultTheme
[ApiMember(Name = "LatestEpisodeLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int LatestEpisodeLimit { get; set; }
public string ParentId { get; set; }
}
[Route("/MBT/DefaultTheme/Movies", "GET")]
@ -71,6 +75,8 @@ namespace MediaBrowser.Api.DefaultTheme
[ApiMember(Name = "LatestTrailersLimit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int LatestTrailersLimit { get; set; }
public string ParentId { get; set; }
}
[Route("/MBT/DefaultTheme/Favorites", "GET")]
@ -224,7 +230,7 @@ namespace MediaBrowser.Api.DefaultTheme
{
var user = _userManager.GetUserById(request.UserId);
var items = user.RootFolder.GetRecursiveChildren(user, i => i is Game || i is GameSystem)
var items = GetAllLibraryItems(user.Id, _userManager, _libraryManager, request.ParentId).Where(i => i is Game || i is GameSystem)
.ToList();
var gamesWithImages = items.OfType<Game>().Where(i => !string.IsNullOrEmpty(i.PrimaryImagePath)).ToList();
@ -280,7 +286,7 @@ namespace MediaBrowser.Api.DefaultTheme
var user = _userManager.GetUserById(request.UserId);
var series = user.RootFolder.GetRecursiveChildren(user)
var series = GetAllLibraryItems(user.Id, _userManager, _libraryManager, request.ParentId)
.OfType<Series>()
.ToList();
@ -403,7 +409,8 @@ namespace MediaBrowser.Api.DefaultTheme
{
var user = _userManager.GetUserById(request.UserId);
var items = user.RootFolder.GetRecursiveChildren(user, i => i is Movie || i is Trailer || i is BoxSet)
var items = GetAllLibraryItems(user.Id, _userManager, _libraryManager, request.ParentId)
.Where(i => i is Movie || i is Trailer || i is BoxSet)
.ToList();
var view = new MoviesView();

View file

@ -903,7 +903,7 @@ namespace MediaBrowser.Api.Playback
EnableRaisingEvents = true
};
ApiEntryPoint.Instance.OnTranscodeBeginning(outputPath, TranscodingJobType, process, state.IsInputVideo, state.Request.StartTimeTicks, state.MediaPath, state.Request.DeviceId);
ApiEntryPoint.Instance.OnTranscodeBeginning(outputPath, TranscodingJobType, process, state.Request.StartTimeTicks, state.MediaPath, state.Request.DeviceId);
var commandLineLogMessage = process.StartInfo.FileName + " " + process.StartInfo.Arguments;
Logger.Info(commandLineLogMessage);

View file

@ -273,9 +273,7 @@ namespace MediaBrowser.Api.Playback.Hls
const string keyFrameArg = " -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+5))";
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsExternal &&
(state.SubtitleStream.Codec.IndexOf("pgs", StringComparison.OrdinalIgnoreCase) != -1 ||
state.SubtitleStream.Codec.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) != -1);
var hasGraphicalSubs = state.SubtitleStream != null && state.SubtitleStream.IsGraphicalSubtitleStream;
var args = "-codec:v:0 " + codec + " " + GetVideoQualityParam(state, "libx264", true) + keyFrameArg;

View file

@ -168,9 +168,7 @@ namespace MediaBrowser.Api.Playback.Hls
" -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+1))" :
" -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+5))";
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsExternal &&
(state.SubtitleStream.Codec.IndexOf("pgs", StringComparison.OrdinalIgnoreCase) != -1 ||
state.SubtitleStream.Codec.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) != -1);
var hasGraphicalSubs = state.SubtitleStream != null && state.SubtitleStream.IsGraphicalSubtitleStream;
var args = "-codec:v:0 " + codec + " " + GetVideoQualityParam(state, "libx264", true) + keyFrameArg;

View file

@ -146,9 +146,7 @@ namespace MediaBrowser.Api.Playback.Progressive
args += keyFrameArg;
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsExternal &&
(state.SubtitleStream.Codec.IndexOf("pgs", StringComparison.OrdinalIgnoreCase) != -1 ||
state.SubtitleStream.Codec.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) != -1);
var hasGraphicalSubs = state.SubtitleStream != null && state.SubtitleStream.IsGraphicalSubtitleStream;
var request = state.VideoRequest;

View file

@ -305,13 +305,7 @@ namespace MediaBrowser.Controller.Entities.TV
if (!ParentIndexNumber.HasValue && !string.IsNullOrEmpty(Path))
{
ParentIndexNumber = TVUtils.GetSeasonNumberFromPath(Path);
// If a change was made record it
if (ParentIndexNumber.HasValue)
{
hasChanges = true;
}
ParentIndexNumber = TVUtils.GetSeasonNumberFromEpisodeFile(Path);
}
// If a change was made record it

View file

@ -52,14 +52,30 @@ namespace MediaBrowser.Model.Configuration
public int GetLimit(ImageType type)
{
ImageOption option = ImageOptions.FirstOrDefault(i => i.Type == type);
ImageOption option = null;
foreach (ImageOption i in ImageOptions)
{
if (i.Type == type)
{
option = i;
break;
}
}
return option == null ? 1 : option.Limit;
}
public int GetMinWidth(ImageType type)
{
ImageOption option = ImageOptions.FirstOrDefault(i => i.Type == type);
ImageOption option = null;
foreach (ImageOption i in ImageOptions)
{
if (i.Type == type)
{
option = i;
break;
}
}
return option == null ? 0 : option.MinWidth;
}

View file

@ -70,7 +70,11 @@ namespace MediaBrowser.Model.Configuration
public NotificationOption GetOptions(string type)
{
return Options.FirstOrDefault(i => string.Equals(type, i.Type, StringComparison.OrdinalIgnoreCase));
foreach (NotificationOption i in Options)
{
if (string.Equals(type, i.Type, StringComparison.OrdinalIgnoreCase)) return i;
}
return null;
}
public bool IsEnabled(string type)

View file

@ -12,6 +12,7 @@ namespace MediaBrowser.Model.Configuration
PluginUpdateInstalled,
PluginUninstalled,
NewLibraryContent,
NewLibraryContentMultiple,
ServerRestartRequired,
TaskFailed,
VideoPlayback

View file

@ -1,6 +1,5 @@
using MediaBrowser.Model.MediaInfo;
using System.Collections.Generic;
using System.Linq;
namespace MediaBrowser.Model.Dlna
{
@ -158,11 +157,21 @@ namespace MediaBrowser.Model.Dlna
if (string.IsNullOrEmpty(orgPn))
{
orgPn = GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp)
.FirstOrDefault();
foreach (string s in GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp))
{
orgPn = s;
break;
}
}
if (string.IsNullOrEmpty(orgPn))
{
// TODO: Support multiple values and return multiple headers?
orgPn = (orgPn ?? string.Empty).Split(',').FirstOrDefault();
foreach (string s in (orgPn ?? string.Empty).Split(','))
{
orgPn = s;
break;
}
}
string contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
@ -191,16 +200,12 @@ namespace MediaBrowser.Model.Dlna
return format.HasValue ? format.Value.ToString() : null;
}
private IEnumerable<string> GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestamp)
private List<string> GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestamp)
{
return new MediaFormatProfileResolver()
.ResolveVideoFormat(container,
videoCodec,
audioCodec,
width,
height,
timestamp)
.Select(i => i.ToString());
List<string> list = new List<string>();
foreach (MediaFormatProfile i in new MediaFormatProfileResolver().ResolveVideoFormat(container, videoCodec, audioCodec, width, height, timestamp))
list.Add(i.ToString());
return list;
}
}
}

View file

@ -19,9 +19,10 @@ namespace MediaBrowser.Model.Dlna
{
_all = string.Equals(filter, "*", StringComparison.OrdinalIgnoreCase);
_fields = (filter ?? string.Empty)
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.ToList();
List<string> list = new List<string>();
foreach (string s in (filter ?? string.Empty).Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))
list.Add(s);
_fields = list;
}
public bool Contains(string field)

View file

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
namespace MediaBrowser.Model.Dlna

View file

@ -1,4 +1,6 @@
using System.Diagnostics;
using System;
using System.Diagnostics;
using System.Runtime.Serialization;
namespace MediaBrowser.Model.Entities
{
@ -128,6 +130,20 @@ namespace MediaBrowser.Model.Entities
/// <value><c>true</c> if this instance is external; otherwise, <c>false</c>.</value>
public bool IsExternal { get; set; }
[IgnoreDataMember]
public bool IsGraphicalSubtitleStream
{
get
{
if (IsExternal) return false;
var codec = Codec ?? string.Empty;
return codec.IndexOf("pgs", StringComparison.OrdinalIgnoreCase) != -1 ||
codec.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) != -1;
}
}
/// <summary>
/// Gets or sets the filename.
/// </summary>

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace MediaBrowser.Model.Web
@ -24,7 +25,7 @@ namespace MediaBrowser.Model.Web
/// <param name="value">The value.</param>
public void Add(string name, int value)
{
Add(name, value.ToString());
Add(name, value.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
@ -34,7 +35,7 @@ namespace MediaBrowser.Model.Web
/// <param name="value">The value.</param>
public void Add(string name, long value)
{
Add(name, value.ToString());
Add(name, value.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
@ -44,7 +45,7 @@ namespace MediaBrowser.Model.Web
/// <param name="value">The value.</param>
public void Add(string name, double value)
{
Add(name, value.ToString());
Add(name, value.ToString(CultureInfo.InvariantCulture));
}
/// <summary>
@ -135,7 +136,7 @@ namespace MediaBrowser.Model.Web
throw new ArgumentNullException("value");
}
Add(name, string.Join(",", value.Select(v => v.ToString()).ToArray()));
Add(name, string.Join(",", value.Select(v => v.ToString(CultureInfo.InvariantCulture)).ToArray()));
}
/// <summary>
@ -188,7 +189,7 @@ namespace MediaBrowser.Model.Web
/// <param name="name">The name.</param>
/// <param name="value">The value.</param>
/// <param name="delimiter">The delimiter.</param>
/// <exception cref="System.ArgumentNullException">value</exception>
/// <exception cref="ArgumentNullException">value</exception>
public void Add(string name, IEnumerable<string> value, string delimiter)
{
if (value == null)

View file

@ -1,4 +1,5 @@
using MediaBrowser.Common.Events;
using System.Globalization;
using MediaBrowser.Common.Events;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Common.Updates;
@ -247,10 +248,10 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications
DisposeLibraryUpdateTimer();
}
var item = items.FirstOrDefault();
if (item != null)
if (items.Count == 1)
{
var item = items.First();
var notification = new NotificationRequest
{
NotificationType = NotificationType.NewLibraryContent.ToString()
@ -258,10 +259,16 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications
notification.Variables["Name"] = item.Name;
if (items.Count > 1)
await SendNotification(notification).ConfigureAwait(false);
}
else
{
var notification = new NotificationRequest
{
notification.Name = items.Count + " new library items.";
}
NotificationType = NotificationType.NewLibraryContentMultiple.ToString()
};
notification.Variables["ItemCount"] = items.Count.ToString(CultureInfo.InvariantCulture);
await SendNotification(notification).ConfigureAwait(false);
}

View file

@ -568,6 +568,7 @@
"NotificationOptionTaskFailed": "Scheduled task failure",
"NotificationOptionInstallationFailed": "Installation failure",
"NotificationOptionNewLibraryContent": "New content added",
"NotificationOptionNewLibraryContentMultiple": "New content added (multiple)",
"SendNotificationHelp": "By default, notifications are delivered to the dashboard inbox. Browse the plugin catalog to install additional notification options.",
"NotificationOptionServerRestartRequired": "Server restart required",
"LabelNotificationEnabled": "Enable this notification",
@ -716,5 +717,9 @@
"LabelDownloadLanguages": "Download languages:",
"ButtonRegister": "Register",
"LabelSkipIfAudioTrackPresent": "Skip if the default audio track matches the download language",
"LabelSkipIfAudioTrackPresentHelp": "Uncheck this to ensure all videos have subtitles, regardless of audio language."
"LabelSkipIfAudioTrackPresentHelp": "Uncheck this to ensure all videos have subtitles, regardless of audio language.",
"HeaderSendMessage": "Send Message",
"ButtonSend": "Send",
"LabelMessageText": "Message text:",
"LabelMessageTitle": "Message title:"
}

View file

@ -90,6 +90,13 @@ namespace MediaBrowser.Server.Implementations.Notifications
Variables = new List<string>{"Name"}
},
new NotificationTypeInfo
{
Type = NotificationType.NewLibraryContentMultiple.ToString(),
DefaultTitle = "{ItemCount} new items have been added to your media library.",
Variables = new List<string>{"ItemCount"}
},
new NotificationTypeInfo
{
Type = NotificationType.AudioPlayback.ToString(),

View file

@ -440,6 +440,187 @@ namespace OpenSubtitlesHandler
}
return new MethodResponseError("Fail", "Search Subtitles call failed !");
}
public static async Task<IMethodResponse> SearchSubtitlesAsync(SubtitleSearchParameters[] parameters, CancellationToken cancellationToken)
{
if (TOKEN == "")
{
OSHConsole.WriteLine("Can't do this call, 'token' value not set. Please use Log In method first.", DebugCode.Error);
return new MethodResponseError("Fail", "Can't do this call, 'token' value not set. Please use Log In method first.");
}
if (parameters == null)
{
OSHConsole.UpdateLine("No subtitle search parameter passed !!", DebugCode.Error);
return new MethodResponseError("Fail", "No subtitle search parameter passed"); ;
}
if (parameters.Length == 0)
{
OSHConsole.UpdateLine("No subtitle search parameter passed !!", DebugCode.Error);
return new MethodResponseError("Fail", "No subtitle search parameter passed"); ;
}
// Method call ..
List<IXmlRpcValue> parms = new List<IXmlRpcValue>();
// Add token param
parms.Add(new XmlRpcValueBasic(TOKEN, XmlRpcBasicValueType.String));
// Add subtitle search parameters. Each one will be like 'array' of structs.
XmlRpcValueArray array = new XmlRpcValueArray();
foreach (SubtitleSearchParameters param in parameters)
{
XmlRpcValueStruct strct = new XmlRpcValueStruct(new List<XmlRpcStructMember>());
// sublanguageid member
XmlRpcStructMember member = new XmlRpcStructMember("sublanguageid",
new XmlRpcValueBasic(param.SubLangaugeID, XmlRpcBasicValueType.String));
strct.Members.Add(member);
// moviehash member
if (param.MovieHash.Length > 0 && param.MovieByteSize > 0)
{
member = new XmlRpcStructMember("moviehash",
new XmlRpcValueBasic(param.MovieHash, XmlRpcBasicValueType.String));
strct.Members.Add(member);
// moviehash member
member = new XmlRpcStructMember("moviebytesize",
new XmlRpcValueBasic(param.MovieByteSize, XmlRpcBasicValueType.Int));
strct.Members.Add(member);
}
if (param.Query.Length > 0)
{
member = new XmlRpcStructMember("query",
new XmlRpcValueBasic(param.Query, XmlRpcBasicValueType.String));
strct.Members.Add(member);
}
if (param.Episode.Length > 0 && param.Season.Length > 0)
{
member = new XmlRpcStructMember("season",
new XmlRpcValueBasic(param.Season, XmlRpcBasicValueType.String));
strct.Members.Add(member);
member = new XmlRpcStructMember("episode",
new XmlRpcValueBasic(param.Episode, XmlRpcBasicValueType.String));
strct.Members.Add(member);
}
// imdbid member
if (param.IMDbID.Length > 0)
{
member = new XmlRpcStructMember("imdbid",
new XmlRpcValueBasic(param.IMDbID, XmlRpcBasicValueType.String));
strct.Members.Add(member);
}
// Add the struct to the array
array.Values.Add(strct);
}
// Add the array to the parameters
parms.Add(array);
// Call !
XmlRpcMethodCall call = new XmlRpcMethodCall("SearchSubtitles", parms);
OSHConsole.WriteLine("Sending SearchSubtitles request to the server ...", DebugCode.Good);
// Send the request to the server
string response = Utilities.GetStreamString(await Utilities.SendRequestAsync(XmlRpcGenerator.Generate(call), XML_PRC_USERAGENT, cancellationToken).ConfigureAwait(false));
if (!response.Contains("ERROR:"))
{
// No error occur, get and decode the response.
XmlRpcMethodCall[] calls = XmlRpcGenerator.DecodeMethodResponse(response);
if (calls.Length > 0)
{
if (calls[0].Parameters.Count > 0)
{
// We expect Struct of 3 members:
//* the first is status
//* the second is [array of structs, each one includes subtitle file].
//* the third is [double basic value] represent seconds token by server.
XmlRpcValueStruct mainStruct = (XmlRpcValueStruct)calls[0].Parameters[0];
// Create the response, we'll need it later
MethodResponseSubtitleSearch R = new MethodResponseSubtitleSearch();
// To make sure response is not currepted by server, do it in loop
foreach (XmlRpcStructMember MEMBER in mainStruct.Members)
{
if (MEMBER.Name == "status")
{
R.Status = (string)MEMBER.Data.Data;
OSHConsole.WriteLine("Status= " + R.Status);
}
else if (MEMBER.Name == "seconds")
{
R.Seconds = (double)MEMBER.Data.Data;
OSHConsole.WriteLine("Seconds= " + R.Seconds);
}
else if (MEMBER.Name == "data")
{
if (MEMBER.Data is XmlRpcValueArray)
{
OSHConsole.WriteLine("Search results: ");
XmlRpcValueArray rarray = (XmlRpcValueArray)MEMBER.Data;
foreach (IXmlRpcValue subStruct in rarray.Values)
{
if (subStruct == null) continue;
if (!(subStruct is XmlRpcValueStruct)) continue;
SubtitleSearchResult result = new SubtitleSearchResult();
foreach (XmlRpcStructMember submember in ((XmlRpcValueStruct)subStruct).Members)
{
// To avoid errors of arranged info or missing ones, let's do it with switch..
switch (submember.Name)
{
case "IDMovie": result.IDMovie = submember.Data.Data.ToString(); break;
case "IDMovieImdb": result.IDMovieImdb = submember.Data.Data.ToString(); break;
case "IDSubMovieFile": result.IDSubMovieFile = submember.Data.Data.ToString(); break;
case "IDSubtitle": result.IDSubtitle = submember.Data.Data.ToString(); break;
case "IDSubtitleFile": result.IDSubtitleFile = submember.Data.Data.ToString(); break;
case "ISO639": result.ISO639 = submember.Data.Data.ToString(); break;
case "LanguageName": result.LanguageName = submember.Data.Data.ToString(); break;
case "MovieByteSize": result.MovieByteSize = submember.Data.Data.ToString(); break;
case "MovieHash": result.MovieHash = submember.Data.Data.ToString(); break;
case "MovieImdbRating": result.MovieImdbRating = submember.Data.Data.ToString(); break;
case "MovieName": result.MovieName = submember.Data.Data.ToString(); break;
case "MovieNameEng": result.MovieNameEng = submember.Data.Data.ToString(); break;
case "MovieReleaseName": result.MovieReleaseName = submember.Data.Data.ToString(); break;
case "MovieTimeMS": result.MovieTimeMS = submember.Data.Data.ToString(); break;
case "MovieYear": result.MovieYear = submember.Data.Data.ToString(); break;
case "SubActualCD": result.SubActualCD = submember.Data.Data.ToString(); break;
case "SubAddDate": result.SubAddDate = submember.Data.Data.ToString(); break;
case "SubAuthorComment": result.SubAuthorComment = submember.Data.Data.ToString(); break;
case "SubBad": result.SubBad = submember.Data.Data.ToString(); break;
case "SubDownloadLink": result.SubDownloadLink = submember.Data.Data.ToString(); break;
case "SubDownloadsCnt": result.SubDownloadsCnt = submember.Data.Data.ToString(); break;
case "SeriesEpisode": result.SeriesEpisode = submember.Data.Data.ToString(); break;
case "SeriesSeason": result.SeriesSeason = submember.Data.Data.ToString(); break;
case "SubFileName": result.SubFileName = submember.Data.Data.ToString(); break;
case "SubFormat": result.SubFormat = submember.Data.Data.ToString(); break;
case "SubHash": result.SubHash = submember.Data.Data.ToString(); break;
case "SubLanguageID": result.SubLanguageID = submember.Data.Data.ToString(); break;
case "SubRating": result.SubRating = submember.Data.Data.ToString(); break;
case "SubSize": result.SubSize = submember.Data.Data.ToString(); break;
case "SubSumCD": result.SubSumCD = submember.Data.Data.ToString(); break;
case "UserID": result.UserID = submember.Data.Data.ToString(); break;
case "UserNickName": result.UserNickName = submember.Data.Data.ToString(); break;
case "ZipDownloadLink": result.ZipDownloadLink = submember.Data.Data.ToString(); break;
}
}
R.Results.Add(result);
OSHConsole.WriteLine(">" + result.ToString());
}
}
else// Unknown data ?
{
OSHConsole.WriteLine("Data= " + MEMBER.Data.Data.ToString(), DebugCode.Warning);
}
}
}
// Return the response to user !!
return R;
}
}
}
else
{
OSHConsole.WriteLine(response, DebugCode.Error);
return new MethodResponseError("Fail", response);
}
return new MethodResponseError("Fail", "Search Subtitles call failed !");
}
/// <summary>
/// Download subtitle file(s)
/// </summary>