add more device options

pull/702/head
Luke Pulverenti 10 years ago
parent f3539686bd
commit 314a51dff3

@ -34,7 +34,7 @@ namespace MediaBrowser.Api.Devices
[Route("/Devices/CameraUploads", "POST", Summary = "Uploads content")]
public class PostCameraUpload : IRequiresRequestStream, IReturnVoid
{
[ApiMember(Name = "Id", Description = "Device Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
[ApiMember(Name = "DeviceId", Description = "Device Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public string DeviceId { get; set; }
[ApiMember(Name = "Album", Description = "Album", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
@ -87,8 +87,7 @@ namespace MediaBrowser.Api.Devices
public void Post(PostCameraUpload request)
{
var deviceId = request.DeviceId;
var deviceId = Request.QueryString["DeviceId"];
var album = Request.QueryString["Album"];
var fullPath = Request.QueryString["FullPath"];
var name = Request.QueryString["Name"];

@ -986,7 +986,7 @@ namespace MediaBrowser.Api.Playback
StartStreamingLog(transcodingJob, state, process.StandardError.BaseStream, state.LogFileStream);
// Wait for the file to exist before proceeeding
while (!File.Exists(outputPath))
while (!File.Exists(outputPath) && !transcodingJob.HasExited)
{
await Task.Delay(100, cancellationTokenSource.Token).ConfigureAwait(false);
}

@ -308,6 +308,8 @@ namespace MediaBrowser.Api.Playback.Progressive
string useragent = null;
state.RemoteHttpHeaders.TryGetValue("User-Agent", out useragent);
var trySupportSeek = false;
var options = new HttpRequestOptions
{
Url = state.MediaPath,
@ -316,25 +318,39 @@ namespace MediaBrowser.Api.Playback.Progressive
CancellationToken = cancellationTokenSource.Token
};
if (!string.IsNullOrWhiteSpace(Request.QueryString["Range"]))
if (trySupportSeek)
{
options.RequestHeaders["Range"] = Request.QueryString["Range"];
if (!string.IsNullOrWhiteSpace(Request.QueryString["Range"]))
{
options.RequestHeaders["Range"] = Request.QueryString["Range"];
}
}
var response = await HttpClient.GetResponse(options).ConfigureAwait(false);
foreach (var name in new[] { "Content-Length", "Content-Range", "Accept-Ranges" })
if (trySupportSeek)
{
var val = response.Headers[name];
if (!string.IsNullOrWhiteSpace(val))
foreach (var name in new[] {"Content-Range", "Accept-Ranges"})
{
responseHeaders[name] = val;
var val = response.Headers[name];
if (!string.IsNullOrWhiteSpace(val))
{
responseHeaders[name] = val;
}
}
}
else
{
responseHeaders["Accept-Ranges"] = "none";
}
if (response.ContentLength.HasValue)
{
responseHeaders["Content-Length"] = response.ContentLength.Value.ToString(UsCulture);
}
if (isHeadRequest)
{
using (response.Content)
using (response)
{
return ResultFactory.GetResult(new byte[] { }, response.ContentType, responseHeaders);
}

@ -53,9 +53,9 @@ namespace MediaBrowser.Api.Playback
/// <returns>Task.</returns>
public async Task WriteToAsync(Stream responseStream)
{
using (var remoteStream = _response.Content)
using (_response)
{
await remoteStream.CopyToAsync(responseStream, 819200).ConfigureAwait(false);
await _response.Content.CopyToAsync(responseStream, 819200).ConfigureAwait(false);
}
}
}

@ -398,7 +398,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
options.CancellationToken.ThrowIfCancellationRequested();
return GetResponseInfo(httpResponse, httpResponse.GetResponseStream(), GetContentLength(httpResponse));
return GetResponseInfo(httpResponse, httpResponse.GetResponseStream(), GetContentLength(httpResponse), httpResponse);
}
using (var response = await httpWebRequest.GetResponseAsync().ConfigureAwait(false))
@ -417,7 +417,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
memoryStream.Position = 0;
return GetResponseInfo(httpResponse, memoryStream, memoryStream.Length);
return GetResponseInfo(httpResponse, memoryStream, memoryStream.Length, null);
}
}
}
@ -480,9 +480,9 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
return exception;
}
private HttpResponseInfo GetResponseInfo(HttpWebResponse httpResponse, Stream content, long? contentLength)
private HttpResponseInfo GetResponseInfo(HttpWebResponse httpResponse, Stream content, long? contentLength, IDisposable disposable)
{
return new HttpResponseInfo
return new HttpResponseInfo(disposable)
{
Content = content,

@ -114,6 +114,7 @@ namespace MediaBrowser.Common.Net
RequestHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
LogRequest = true;
CacheMode = CacheMode.None;
}
public void SetPostData(IDictionary<string,string> values)

@ -1,4 +1,5 @@
using System.Collections.Specialized;
using System;
using System.Collections.Specialized;
using System.IO;
using System.Net;
@ -7,7 +8,7 @@ namespace MediaBrowser.Common.Net
/// <summary>
/// Class HttpResponseInfo
/// </summary>
public class HttpResponseInfo
public class HttpResponseInfo : IDisposable
{
/// <summary>
/// Gets or sets the type of the content.
@ -50,5 +51,23 @@ namespace MediaBrowser.Common.Net
/// </summary>
/// <value>The headers.</value>
public NameValueCollection Headers { get; set; }
private readonly IDisposable _disposable;
public HttpResponseInfo(IDisposable disposable)
{
_disposable = disposable;
}
public HttpResponseInfo()
{
}
public void Dispose()
{
if (_disposable != null)
{
_disposable.Dispose();
}
}
}
}

@ -13,9 +13,10 @@ namespace MediaBrowser.Controller.Devices
/// </summary>
/// <param name="reportedId">The reported identifier.</param>
/// <param name="name">The name.</param>
/// <param name="appName">Name of the application.</param>
/// <param name="usedByUserId">The used by user identifier.</param>
/// <returns>Task.</returns>
Task RegisterDevice(string reportedId, string name, string usedByUserId);
Task RegisterDevice(string reportedId, string name, string appName, string usedByUserId);
/// <summary>
/// Saves the capabilities.

@ -1,4 +1,5 @@

using System.Collections.Generic;
namespace MediaBrowser.Controller.Entities
{
/// <summary>
@ -7,5 +8,7 @@ namespace MediaBrowser.Controller.Entities
public interface ICollectionFolder
{
string CollectionType { get; }
string Path { get; }
IEnumerable<string> PhysicalLocations { get; }
}
}

@ -3,7 +3,6 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Entities
@ -60,7 +59,7 @@ namespace MediaBrowser.Controller.Entities
CollectionType.Trailers
};
var collectionFolder = folder as CollectionFolder;
var collectionFolder = folder as ICollectionFolder;
if (collectionFolder == null)
{
@ -70,30 +69,4 @@ namespace MediaBrowser.Controller.Entities
return standaloneTypes.Contains(collectionFolder.CollectionType ?? string.Empty);
}
}
public class SpecialFolder : Folder
{
public SpecialFolderType SpecialFolderType { get; set; }
public string ItemTypeName { get; set; }
public string ParentId { get; set; }
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{
var parent = (Folder)LibraryManager.GetItemById(new Guid(ParentId));
if (SpecialFolderType == SpecialFolderType.ItemsByType)
{
var items = parent.GetRecursiveChildren(user, includeLinkedChildren);
return items.Where(i => string.Equals(i.GetType().Name, ItemTypeName, StringComparison.OrdinalIgnoreCase));
}
return new List<BaseItem>();
}
}
public enum SpecialFolderType
{
ItemsByType = 1
}
}

@ -21,6 +21,11 @@ namespace MediaBrowser.Model.Devices
/// <value>The last name of the user.</value>
public string LastUserName { get; set; }
/// <summary>
/// Gets or sets the name of the application.
/// </summary>
/// <value>The name of the application.</value>
public string AppName { get; set; }
/// <summary>
/// Gets or sets the last user identifier.
/// </summary>
/// <value>The last user identifier.</value>

@ -5,6 +5,7 @@ namespace MediaBrowser.Model.Devices
{
public string[] EnabledCameraUploadDevices { get; set; }
public string CameraUploadPath { get; set; }
public bool EnableCameraUploadSubfolders { get; set; }
public DevicesOptions()
{

@ -74,6 +74,9 @@ namespace MediaBrowser.Model.Dlna
public bool RequiresPlainVideoItems { get; set; }
public bool RequiresPlainFolders { get; set; }
public bool SupportsDirectRemoteContent { get; set; }
public bool SupportsCustomHttpHeaders { get; set; }
public XmlAttribute[] XmlRootAttributes { get; set; }
/// <summary>

@ -82,7 +82,14 @@ namespace MediaBrowser.Model.Dlna
// If that doesn't produce anything, just take the first
foreach (StreamInfo i in streams)
{
if (i.IsDirectStream)
if (i.PlayMethod == PlayMethod.DirectPlay)
{
return i;
}
}
foreach (StreamInfo i in streams)
{
if (i.PlayMethod == PlayMethod.DirectStream)
{
return i;
}
@ -249,11 +256,11 @@ namespace MediaBrowser.Model.Dlna
if (IsEligibleForDirectPlay(item, maxBitrateSetting, subtitleStream, options))
{
// See if it can be direct played
DirectPlayProfile directPlay = GetVideoDirectPlayProfile(options.Profile, item, videoStream, audioStream);
var directPlay = GetVideoDirectPlayProfile(options.Profile, item, videoStream, audioStream);
if (directPlay != null)
{
playlistItem.PlayMethod = PlayMethod.DirectStream;
playlistItem.PlayMethod = directPlay.Value;
playlistItem.Container = item.Container;
if (subtitleStream != null)
@ -366,7 +373,7 @@ namespace MediaBrowser.Model.Dlna
return 128000;
}
private DirectPlayProfile GetVideoDirectPlayProfile(DeviceProfile profile,
private PlayMethod? GetVideoDirectPlayProfile(DeviceProfile profile,
MediaSourceInfo mediaSource,
MediaStream videoStream,
MediaStream audioStream)
@ -487,7 +494,21 @@ namespace MediaBrowser.Model.Dlna
}
}
return directPlay;
if (mediaSource.Protocol == MediaProtocol.Http)
{
if (!profile.SupportsDirectRemoteContent)
{
return null;
}
if (mediaSource.RequiredHttpHeaders.Count > 0 && !profile.SupportsCustomHttpHeaders)
{
return null;
}
return PlayMethod.DirectPlay;
}
return PlayMethod.DirectStream;
}
private bool IsEligibleForDirectPlay(MediaSourceInfo item,

@ -1,5 +1,4 @@
using System.Globalization;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
@ -7,6 +6,7 @@ using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Session;
using System;
using System.Collections.Generic;
using System.Globalization;
namespace MediaBrowser.Model.Dlna
{
@ -89,6 +89,11 @@ namespace MediaBrowser.Model.Dlna
public string ToDlnaUrl(string baseUrl)
{
if (PlayMethod == PlayMethod.DirectPlay)
{
return MediaSource.Path;
}
if (string.IsNullOrEmpty(baseUrl))
{
throw new ArgumentNullException(baseUrl);

@ -186,13 +186,6 @@ namespace MediaBrowser.Server.Implementations.Channels
private double? GetDownloadLimit(ChannelOptions channelOptions)
{
if (!_security.IsMBSupporter)
{
const double limit = .5;
return Math.Min(channelOptions.DownloadSizeLimit ?? limit, limit);
}
return channelOptions.DownloadSizeLimit;
}

@ -29,7 +29,7 @@ namespace MediaBrowser.Server.Implementations.Devices
_config = config;
}
public Task RegisterDevice(string reportedId, string name, string usedByUserId)
public Task RegisterDevice(string reportedId, string name, string appName, string usedByUserId)
{
var device = GetDevice(reportedId) ?? new DeviceInfo
{
@ -37,6 +37,7 @@ namespace MediaBrowser.Server.Implementations.Devices
};
device.Name = name;
device.AppName = appName;
if (!string.IsNullOrWhiteSpace(usedByUserId))
{
@ -115,12 +116,21 @@ namespace MediaBrowser.Server.Implementations.Devices
{
var config = _config.GetUploadOptions();
var device = GetDevice(deviceId);
if (!string.IsNullOrWhiteSpace(config.CameraUploadPath))
{
return config.CameraUploadPath;
}
return Path.Combine(_config.CommonApplicationPaths.DataPath, "camerauploads");
var path = Path.Combine(_config.CommonApplicationPaths.DataPath, "camerauploads");
if (config.EnableCameraUploadSubfolders)
{
path = Path.Combine(path, _fileSystem.GetValidFilename(device.Name));
}
return path;
}
}

@ -1501,7 +1501,7 @@ namespace MediaBrowser.Server.Implementations.Library
.Select(i => i.RootFolder)
.Distinct()
.SelectMany(i => i.Children)
.OfType<CollectionFolder>()
.OfType<ICollectionFolder>()
.Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path))
.Select(i => i.CollectionType)
.Where(i => !string.IsNullOrEmpty(i))

@ -29,11 +29,22 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
}
protected static string[] ImageExtensions = { ".tiff", ".jpeg", ".jpg", ".png", ".aiff" };
private static readonly string[] IgnoreFiles =
{
"folder",
"thumb",
"landscape",
"fanart",
"backdrop",
"poster"
};
internal static bool IsImageFile(string path)
{
var filename = Path.GetFileName(path);
var filename = Path.GetFileNameWithoutExtension(path) ?? string.Empty;
return !string.Equals(filename, "folder.jpg", StringComparison.OrdinalIgnoreCase)
return !IgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase)
&& ImageExtensions.Contains(Path.GetExtension(path) ?? string.Empty, StringComparer.OrdinalIgnoreCase);
}

@ -1047,7 +1047,7 @@
"AppDeviceValues": "App: {0}, Device: {1}",
"ProviderValue": "Provider: {0}",
"LabelChannelDownloadSizeLimit": "Download size limit (GB):",
"LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder. Downloading beyond 500MB requires an active supporter membership.",
"LabelChannelDownloadSizeLimitHelpText": "Limit the size of the channel download folder.",
"HeaderRecentActivity": "Recent Activity",
"HeaderPeople": "People",
"HeaderDownloadPeopleMetadataFor": "Download biography and images for:",
@ -1222,6 +1222,8 @@
"TitleDevices": "Devices",
"HeaderCameraUploadHelp": "Automatically upload photos and videos taken from your mobile devices into Media Browser.",
"MessageNoDevicesSupportCameraUpload": "You currently don't have any devices that support camera upload.",
"LabelUploadPath": "Upload path:",
"LabelUploadPathHelp": "Select a custom upload path, if desired. If unspecified an internal data folder will be used."
"LabelCameraUploadPath": "Camera upload path:",
"LabelCameraUploadPathHelp": "Select a custom upload path, if desired. If unspecified a default folder will be used.",
"LabelCreateCameraUploadSubfolder": "Create a sub-folder for each device",
"LabelCreateCameraUploadSubfolderHelp": "Specific folders can be assigned to devices by clicking on the device on the Devices page."
}

@ -422,7 +422,7 @@ namespace MediaBrowser.Server.Implementations.Session
if (!string.IsNullOrEmpty(deviceId))
{
var userIdString = userId.HasValue ? userId.Value.ToString("N") : null;
await _deviceManager.RegisterDevice(deviceId, deviceName, userIdString).ConfigureAwait(false);
await _deviceManager.RegisterDevice(deviceId, deviceName, clientType, userIdString).ConfigureAwait(false);
}
}

@ -564,6 +564,7 @@ namespace MediaBrowser.WebDashboard.Api
"dashboardgeneral.js",
"dashboardpage.js",
"dashboardsync.js",
"device.js",
"devices.js",
"devicesupload.js",
"directorybrowser.js",

@ -367,6 +367,9 @@
<Content Include="dashboard-ui\dashboardsync.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\device.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\devices.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -697,6 +700,9 @@
<Content Include="dashboard-ui\scripts\dashboardsync.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\device.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\devices.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
<version>3.0.476</version>
<version>3.0.477</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.476" />
<dependency id="MediaBrowser.Common" version="3.0.477" />
<dependency id="NLog" version="3.1.0.0" />
<dependency id="SimpleInjector" version="2.5.2" />
<dependency id="sharpcompress" version="0.10.2" />

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
<version>3.0.476</version>
<version>3.0.477</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Model.Signed</id>
<version>3.0.476</version>
<version>3.0.477</version>
<title>MediaBrowser.Model - Signed Edition</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
<version>3.0.476</version>
<version>3.0.477</version>
<title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.476" />
<dependency id="MediaBrowser.Common" version="3.0.477" />
</dependencies>
</metadata>
<files>

@ -17,6 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Globalization;
using System.Text;
using System.Collections.Generic;
using System.IO;
@ -131,9 +132,18 @@ namespace OpenSubtitlesHandler
{
switch (MEMBER.Name)
{
case "token": re.Token = TOKEN = MEMBER.Data.Data.ToString(); OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
case "seconds": re.Seconds = (double)MEMBER.Data.Data; OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
case "status": re.Status = MEMBER.Data.Data.ToString(); OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString()); break;
case "token":
re.Token = TOKEN = MEMBER.Data.Data.ToString();
OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
break;
case "seconds":
re.Seconds = double.Parse(MEMBER.Data.Data.ToString(), CultureInfo.InvariantCulture);
OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
break;
case "status":
re.Status = MEMBER.Data.Data.ToString();
OSHConsole.WriteLine(MEMBER.Name + "= " + MEMBER.Data.Data.ToString());
break;
}
}
return re;

Loading…
Cancel
Save