From 51b01d0f6d21bf31a093cf7d8f88e31aba884288 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 Sep 2013 14:53:06 -0400 Subject: updated nuget --- .../ScheduledTasks/TaskManager.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Common.Implementations') diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs index 8278c8a28..6605432fa 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs @@ -1,5 +1,4 @@ -using System.Threading.Tasks; -using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Model.Logging; @@ -8,6 +7,7 @@ using MediaBrowser.Model.Tasks; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace MediaBrowser.Common.Implementations.ScheduledTasks { @@ -77,6 +77,17 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks QueueScheduledTask(); } + /// + /// Cancels if running + /// + /// + public void CancelIfRunning() + where T : IScheduledTask + { + var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)); + ((ScheduledTaskWorker)task).CancelIfRunning(); + } + /// /// Queues the scheduled task. /// -- cgit v1.2.3 From b49764dbaafbbf11b6308ec675355696b9e58379 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 24 Sep 2013 11:08:51 -0400 Subject: fixes #555 - Have clients report seek and queuing capabilities --- MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 37 ++++++++++++++- .../Logging/NlogManager.cs | 18 +++----- .../ScheduledTasks/Tasks/DeleteLogFileTask.cs | 37 ++++++++------- .../ScheduledTasks/Tasks/ReloadLoggerTask.cs | 6 ++- MediaBrowser.Controller/Entities/Folder.cs | 5 +- .../MediaBrowser.Controller.csproj | 1 + MediaBrowser.Controller/Session/ISessionManager.cs | 7 ++- MediaBrowser.Controller/Session/PlaybackInfo.cs | 38 +++++++++++++++ MediaBrowser.Controller/Session/SessionInfo.cs | 13 ++++++ MediaBrowser.Model/ApiClient/IApiClient.cs | 4 +- MediaBrowser.Model/Session/SessionInfoDto.cs | 17 ++++++- .../Movies/FanArtMovieProvider.cs | 1 - .../Music/SoundtrackPostScanTask.cs | 4 +- MediaBrowser.Providers/TV/SeriesPostScanTask.cs | 4 +- .../Dto/DtoService.cs | 4 +- .../Library/LibraryManager.cs | 54 +++++++--------------- .../Library/Validators/PeoplePostScanTask.cs | 4 +- .../Persistence/SqliteItemRepository.cs | 15 +++--- .../Session/SessionManager.cs | 22 ++++++--- .../Session/SessionWebSocketListener.cs | 52 +++++++++++++++++---- .../WebSocket/AlchemyWebSocket.cs | 4 +- MediaBrowser.WebDashboard/ApiClient.js | 15 ++++-- MediaBrowser.WebDashboard/packages.config | 2 +- 23 files changed, 248 insertions(+), 116 deletions(-) create mode 100644 MediaBrowser.Controller/Session/PlaybackInfo.cs (limited to 'MediaBrowser.Common.Implementations') diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index ab3e2af19..9085a3ecf 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -186,7 +186,7 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "DatePlayed", Description = "The date the item was played (if any)", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] public DateTime? DatePlayed { get; set; } - + /// /// Gets or sets the id. /// @@ -224,6 +224,13 @@ namespace MediaBrowser.Api.UserLibrary [Api(Description = "Reports that a user has begun playing an item")] public class OnPlaybackStart : IReturnVoid { + public OnPlaybackStart() + { + // Have to default these until all clients have a chance to incorporate them + CanSeek = true; + QueueableMediaTypes = "Audio,Video,Book,Game"; + } + /// /// Gets or sets the user id. /// @@ -237,6 +244,20 @@ namespace MediaBrowser.Api.UserLibrary /// The id. [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] public string Id { get; set; } + + /// + /// Gets or sets a value indicating whether this is likes. + /// + /// true if likes; otherwise, false. + [ApiMember(Name = "CanSeek", Description = "Indicates if the client can seek", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")] + public bool CanSeek { get; set; } + + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "QueueableMediaTypes", Description = "A list of media types that can be queued from this item, comma delimited. Audio,Video,Book,Game", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)] + public string QueueableMediaTypes { get; set; } } /// @@ -378,6 +399,8 @@ namespace MediaBrowser.Api.UserLibrary /// The library manager. /// The user data repository. /// The item repo. + /// The session manager. + /// The dto service. /// jsonSerializer public UserLibraryService(IUserManager userManager, ILibraryManager libraryManager, IUserDataRepository userDataRepository, IItemRepository itemRepo, ISessionManager sessionManager, IDtoService dtoService) { @@ -665,7 +688,17 @@ namespace MediaBrowser.Api.UserLibrary var item = _dtoService.GetItemByDtoId(request.Id, user.Id); - _sessionManager.OnPlaybackStart(item, GetSession().Id); + var queueableMediaTypes = (request.QueueableMediaTypes ?? string.Empty); + + var info = new PlaybackInfo + { + CanSeek = request.CanSeek, + Item = item, + SessionId = GetSession().Id, + QueueableMediaTypes = queueableMediaTypes.Split(',').ToList() + }; + + _sessionManager.OnPlaybackStart(info); } /// diff --git a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs index 109e85d80..e20f9bc13 100644 --- a/MediaBrowser.Common.Implementations/Logging/NlogManager.cs +++ b/MediaBrowser.Common.Implementations/Logging/NlogManager.cs @@ -5,7 +5,6 @@ using NLog.Targets; using System; using System.IO; using System.Linq; -using System.Threading.Tasks; namespace MediaBrowser.Common.Implementations.Logging { @@ -193,17 +192,14 @@ namespace MediaBrowser.Common.Implementations.Logging if (LoggerLoaded != null) { - Task.Run(() => + try { - try - { - LoggerLoaded(this, EventArgs.Empty); - } - catch (Exception ex) - { - GetLogger("Logger").ErrorException("Error in LoggerLoaded event", ex); - } - }); + LoggerLoaded(this, EventArgs.Empty); + } + catch (Exception ex) + { + GetLogger("Logger").ErrorException("Error in LoggerLoaded event", ex); + } } } } diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs index 15f955723..bfd626adb 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/DeleteLogFileTask.cs @@ -54,33 +54,32 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// Task. public Task Execute(CancellationToken cancellationToken, IProgress progress) { - return Task.Run(() => - { - // Delete log files more than n days old - var minDateModified = DateTime.UtcNow.AddDays(-(ConfigurationManager.CommonConfiguration.LogFileRetentionDays)); + // Delete log files more than n days old + var minDateModified = DateTime.UtcNow.AddDays(-(ConfigurationManager.CommonConfiguration.LogFileRetentionDays)); + + var filesToDelete = new DirectoryInfo(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath).EnumerateFileSystemInfos("*", SearchOption.AllDirectories) + .Where(f => f.LastWriteTimeUtc < minDateModified) + .ToList(); - var filesToDelete = new DirectoryInfo(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath).EnumerateFileSystemInfos("*", SearchOption.AllDirectories) - .Where(f => f.LastWriteTimeUtc < minDateModified) - .ToList(); + var index = 0; - var index = 0; + foreach (var file in filesToDelete) + { + double percent = index; + percent /= filesToDelete.Count; - foreach (var file in filesToDelete) - { - double percent = index; - percent /= filesToDelete.Count; + progress.Report(100 * percent); - progress.Report(100 * percent); + cancellationToken.ThrowIfCancellationRequested(); - cancellationToken.ThrowIfCancellationRequested(); + File.Delete(file.FullName); - File.Delete(file.FullName); + index++; + } - index++; - } + progress.Report(100); - progress.Report(100); - }); + return Task.FromResult(true); } /// diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs index e860834ec..00928255c 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/ReloadLoggerTask.cs @@ -58,7 +58,11 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks progress.Report(0); - return Task.Run(() => LogManager.ReloadLogger(ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging ? LogSeverity.Debug : LogSeverity.Info)); + LogManager.ReloadLogger(ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging + ? LogSeverity.Debug + : LogSeverity.Info); + + return Task.FromResult(true); } /// diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 326d30bd7..0f090f587 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -16,7 +16,6 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using MoreLinq; namespace MediaBrowser.Controller.Entities { @@ -690,7 +689,7 @@ namespace MediaBrowser.Controller.Entities var options = new ParallelOptions { - MaxDegreeOfParallelism = 20 + MaxDegreeOfParallelism = 10 }; Parallel.ForEach(nonCachedChildren, options, child => @@ -805,7 +804,7 @@ namespace MediaBrowser.Controller.Entities foreach (var tuple in list) { - if (tasks.Count > 8) + if (tasks.Count > 5) { await Task.WhenAll(tasks).ConfigureAwait(false); } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index f49bd8cf0..80cf82da1 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -165,6 +165,7 @@ + diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index 1976c653a..fba1d26e8 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -47,11 +47,9 @@ namespace MediaBrowser.Controller.Session /// /// Used to report that playback has started for an item /// - /// The item. - /// The session id. + /// The info. /// Task. - /// - Task OnPlaybackStart(BaseItem item, Guid sessionId); + Task OnPlaybackStart(PlaybackInfo info); /// /// Used to report playback progress for an item @@ -59,6 +57,7 @@ namespace MediaBrowser.Controller.Session /// The item. /// The position ticks. /// if set to true [is paused]. + /// if set to true [is muted]. /// The session id. /// Task. /// diff --git a/MediaBrowser.Controller/Session/PlaybackInfo.cs b/MediaBrowser.Controller/Session/PlaybackInfo.cs new file mode 100644 index 000000000..ab3111e76 --- /dev/null +++ b/MediaBrowser.Controller/Session/PlaybackInfo.cs @@ -0,0 +1,38 @@ +using MediaBrowser.Controller.Entities; +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Session +{ + public class PlaybackInfo + { + public PlaybackInfo() + { + QueueableMediaTypes = new List(); + } + + /// + /// Gets or sets a value indicating whether this instance can seek. + /// + /// true if this instance can seek; otherwise, false. + public bool CanSeek { get; set; } + + /// + /// Gets or sets the queueable media types. + /// + /// The queueable media types. + public List QueueableMediaTypes { get; set; } + + /// + /// Gets or sets the item. + /// + /// The item. + public BaseItem Item { get; set; } + + /// + /// Gets or sets the session id. + /// + /// The session id. + public Guid SessionId { get; set; } + } +} diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index 6c0f1a085..ba6d3d0ac 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -15,8 +15,21 @@ namespace MediaBrowser.Controller.Session public SessionInfo() { WebSockets = new List(); + QueueableMediaTypes = new List(); } + /// + /// Gets or sets a value indicating whether this instance can seek. + /// + /// true if this instance can seek; otherwise, false. + public bool CanSeek { get; set; } + + /// + /// Gets or sets the queueable media types. + /// + /// The queueable media types. + public List QueueableMediaTypes { get; set; } + /// /// Gets or sets the id. /// diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 03ea79b3b..4a459cac8 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -497,9 +497,11 @@ namespace MediaBrowser.Model.ApiClient /// /// The item id. /// The user id. + /// if set to true [is seekable]. + /// The list of media types that the client is capable of queuing onto the playlist. See MediaType class. /// Task{UserItemDataDto}. /// itemId - Task ReportPlaybackStartAsync(string itemId, string userId); + Task ReportPlaybackStartAsync(string itemId, string userId, bool isSeekable, List queueableMediaTypes); /// /// Reports playback progress to the server diff --git a/MediaBrowser.Model/Session/SessionInfoDto.cs b/MediaBrowser.Model/Session/SessionInfoDto.cs index f9b0e0abd..02b7f0226 100644 --- a/MediaBrowser.Model/Session/SessionInfoDto.cs +++ b/MediaBrowser.Model/Session/SessionInfoDto.cs @@ -1,11 +1,24 @@ -using System.ComponentModel; -using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Entities; using System; +using System.Collections.Generic; +using System.ComponentModel; namespace MediaBrowser.Model.Session { public class SessionInfoDto : INotifyPropertyChanged { + /// + /// Gets or sets a value indicating whether this instance can seek. + /// + /// true if this instance can seek; otherwise, false. + public bool CanSeek { get; set; } + + /// + /// Gets or sets the queueable media types. + /// + /// The queueable media types. + public List QueueableMediaTypes { get; set; } + /// /// Gets or sets the id. /// diff --git a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs index fefcd8371..adc013699 100644 --- a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs +++ b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; diff --git a/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs b/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs index 18868d3ea..e18351248 100644 --- a/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs +++ b/MediaBrowser.Providers/Music/SoundtrackPostScanTask.cs @@ -23,7 +23,9 @@ namespace MediaBrowser.Providers.Music public Task Run(IProgress progress, CancellationToken cancellationToken) { - return Task.Run(() => RunInternal(progress, cancellationToken)); + RunInternal(progress, cancellationToken); + + return Task.FromResult(true); } private void RunInternal(IProgress progress, CancellationToken cancellationToken) diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs index a781551de..2b73ba1f7 100644 --- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -21,7 +21,9 @@ namespace MediaBrowser.Providers.TV public Task Run(IProgress progress, CancellationToken cancellationToken) { - return Task.Run(() => RunInternal(progress, cancellationToken)); + RunInternal(progress, cancellationToken); + + return Task.FromResult(true); } private void RunInternal(IProgress progress, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index e5260004a..a5f54b938 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -237,7 +237,9 @@ namespace MediaBrowser.Server.Implementations.Dto NowViewingItemId = session.NowViewingItemId, NowViewingItemName = session.NowViewingItemName, NowViewingItemType = session.NowViewingItemType, - ApplicationVersion = session.ApplicationVersion + ApplicationVersion = session.ApplicationVersion, + CanSeek = session.CanSeek, + QueueableMediaTypes = session.QueueableMediaTypes }; if (session.NowPlayingItem != null) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index a5b792726..1bc3f1094 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -829,10 +829,6 @@ namespace MediaBrowser.Server.Implementations.Library /// Task. public async Task ValidatePeople(CancellationToken cancellationToken, IProgress progress) { - const int maxTasks = 3; - - var tasks = new List(); - var people = RootFolder.RecursiveChildren .SelectMany(c => c.People) .DistinctBy(p => p.Name, StringComparer.OrdinalIgnoreCase) @@ -842,47 +838,27 @@ namespace MediaBrowser.Server.Implementations.Library foreach (var person in people) { - if (tasks.Count > maxTasks) + cancellationToken.ThrowIfCancellationRequested(); + + try { - await Task.WhenAll(tasks).ConfigureAwait(false); - tasks.Clear(); + var item = GetPerson(person.Name); - // Safe cancellation point, when there are no pending tasks - cancellationToken.ThrowIfCancellationRequested(); + await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); } - - // Avoid accessing the foreach variable within the closure - var currentPerson = person; - - tasks.Add(Task.Run(async () => + catch (IOException ex) { - cancellationToken.ThrowIfCancellationRequested(); - - try - { - var item = GetPerson(currentPerson.Name); - - await item.RefreshMetadata(cancellationToken).ConfigureAwait(false); - } - catch (IOException ex) - { - _logger.ErrorException("Error validating IBN entry {0}", ex, currentPerson.Name); - } + _logger.ErrorException("Error validating IBN entry {0}", ex, person.Name); + } - // Update progress - lock (progress) - { - numComplete++; - double percent = numComplete; - percent /= people.Count; + // Update progress + numComplete++; + double percent = numComplete; + percent /= people.Count; - progress.Report(100 * percent); - } - })); + progress.Report(100 * percent); } - await Task.WhenAll(tasks).ConfigureAwait(false); - progress.Report(100); _logger.Info("People validation complete"); @@ -956,7 +932,9 @@ namespace MediaBrowser.Server.Implementations.Library public Task ValidateMediaLibrary(IProgress progress, CancellationToken cancellationToken) { // Just run the scheduled task so that the user can see it - return Task.Run(() => _taskManager.CancelIfRunningAndQueue()); + _taskManager.CancelIfRunningAndQueue(); + + return Task.FromResult(true); } /// diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs index efefaeba3..dc96632f6 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeoplePostScanTask.cs @@ -41,7 +41,9 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public Task Run(IProgress progress, CancellationToken cancellationToken) { - return Task.Run(() => RunInternal(progress, cancellationToken)); + RunInternal(progress, cancellationToken); + + return Task.FromResult(true); } private void RunInternal(IProgress progress, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index f4f5f08e4..9c5cf6f1c 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -333,17 +333,16 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Task. public Task SaveCriticReviews(Guid itemId, IEnumerable criticReviews) { - return Task.Run(() => + if (!Directory.Exists(_criticReviewsPath)) { - if (!Directory.Exists(_criticReviewsPath)) - { - Directory.CreateDirectory(_criticReviewsPath); - } + Directory.CreateDirectory(_criticReviewsPath); + } - var path = Path.Combine(_criticReviewsPath, itemId + ".json"); + var path = Path.Combine(_criticReviewsPath, itemId + ".json"); + + _jsonSerializer.SerializeToFile(criticReviews.ToList(), path); - _jsonSerializer.SerializeToFile(criticReviews.ToList(), path); - }); + return Task.FromResult(true); } /// diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index ce757d142..65ec02d12 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -207,21 +207,29 @@ namespace MediaBrowser.Server.Implementations.Session /// /// Used to report that playback has started for an item /// - /// The item. - /// The session id. + /// The info. /// Task. - /// - public async Task OnPlaybackStart(BaseItem item, Guid sessionId) + /// info + public async Task OnPlaybackStart(PlaybackInfo info) { - if (item == null) + if (info == null) { - throw new ArgumentNullException(); + throw new ArgumentNullException("info"); + } + if (info.SessionId == Guid.Empty) + { + throw new ArgumentNullException("info"); } - var session = Sessions.First(i => i.Id.Equals(sessionId)); + var session = Sessions.First(i => i.Id.Equals(info.SessionId)); + + var item = info.Item; UpdateNowPlayingItem(session, item, false, false); + session.CanSeek = info.CanSeek; + session.QueueableMediaTypes = info.QueueableMediaTypes; + var key = item.GetUserDataKey(); var user = session.User; diff --git a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs index 2a4361e61..95eb5948f 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs @@ -101,16 +101,7 @@ namespace MediaBrowser.Server.Implementations.Session } else if (string.Equals(message.MessageType, "PlaybackStart", StringComparison.OrdinalIgnoreCase)) { - _logger.Debug("Received PlaybackStart message"); - - var session = _sessionManager.Sessions.FirstOrDefault(i => i.WebSockets.Contains(message.Connection)); - - if (session != null && session.User != null) - { - var item = _dtoService.GetItemByDtoId(message.Data); - - _sessionManager.OnPlaybackStart(item, session.Id); - } + ReportPlaybackStart(message); } else if (string.Equals(message.MessageType, "PlaybackProgress", StringComparison.OrdinalIgnoreCase)) { @@ -170,5 +161,46 @@ namespace MediaBrowser.Server.Implementations.Session return _trueTaskResult; } + + /// + /// Reports the playback start. + /// + /// The message. + private void ReportPlaybackStart(WebSocketMessageInfo message) + { + _logger.Debug("Received PlaybackStart message"); + + var session = _sessionManager.Sessions + .FirstOrDefault(i => i.WebSockets.Contains(message.Connection)); + + if (session != null && session.User != null) + { + var vals = message.Data.Split('|'); + + var item = _dtoService.GetItemByDtoId(vals[0]); + + var queueableMediaTypes = string.Empty; + var canSeek = true; + + if (vals.Length > 1) + { + canSeek = string.Equals(vals[1], "true", StringComparison.OrdinalIgnoreCase); + } + if (vals.Length > 2) + { + queueableMediaTypes = vals[2]; + } + + var info = new PlaybackInfo + { + CanSeek = canSeek, + Item = item, + SessionId = session.Id, + QueueableMediaTypes = queueableMediaTypes.Split(',').ToList() + }; + + _sessionManager.OnPlaybackStart(info); + } + } } } diff --git a/MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs b/MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs index 958201625..de998254c 100644 --- a/MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs +++ b/MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs @@ -92,7 +92,9 @@ namespace MediaBrowser.Server.Implementations.WebSocket /// Task. public Task SendAsync(byte[] bytes, WebSocketMessageType type, bool endOfMessage, CancellationToken cancellationToken) { - return Task.Run(() => UserContext.Send(bytes)); + UserContext.Send(bytes); + + return Task.FromResult(true); } /// diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index d139adfc3..189812a3c 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -3200,7 +3200,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi * @param {String} userId * @param {String} itemId */ - self.reportPlaybackStart = function (userId, itemId) { + self.reportPlaybackStart = function (userId, itemId, canSeek, queueableMediaTypes) { if (!userId) { throw new Error("null userId"); @@ -3210,17 +3210,26 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi throw new Error("null itemId"); } + canSeek = canSeek || false; + queueableMediaTypes = queueableMediaTypes || ''; + if (self.isWebSocketOpen()) { var deferred = $.Deferred(); - self.sendWebSocketMessage("PlaybackStart", itemId); + var msg = [itemId, canSeek, queueableMediaTypes]; + + self.sendWebSocketMessage("PlaybackStart", msg.join('|')); deferred.resolveWith(null, []); return deferred.promise(); } - var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId); + var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId, { + + CanSeek: canSeek, + QueueableMediaTypes: queueableMediaTypes + }); return self.ajax({ type: "POST", diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 25b4f7b47..1c5a0f818 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file -- cgit v1.2.3 From 0ab379e271afe69372806ab0e24a874d3f085456 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 24 Sep 2013 17:06:21 -0400 Subject: adding mono solution --- MediaBrowser.Api/MediaBrowser.Api.csproj | 34 ++++---- .../MediaBrowser.Common.Implementations.csproj | 27 ++++--- MediaBrowser.Common/MediaBrowser.Common.csproj | 23 +++--- .../MediaBrowser.Controller.csproj | 16 ++-- MediaBrowser.Model/MediaBrowser.Model.csproj | 11 +-- MediaBrowser.Mono.sln | 68 ++++++++++++++++ MediaBrowser.Mono.userprefs | 8 ++ .../MediaBrowser.Providers.csproj | 15 ++-- .../Library/Validators/GameGenresValidator.cs | 6 +- .../Library/Validators/GenresValidator.cs | 10 +-- .../Library/Validators/MusicGenresValidator.cs | 10 +-- .../Library/Validators/StudiosValidator.cs | 8 +- .../MediaBrowser.Server.Implementations.csproj | 84 +++++++++----------- MediaBrowser.Server.Mono/MainWindow.cs | 16 ++++ .../MediaBrowser.Server.Mono.csproj | 91 ++++++++++++++++++++++ MediaBrowser.Server.Mono/Program.cs | 16 ++++ .../Properties/AssemblyInfo.cs | 22 ++++++ MediaBrowser.Server.Mono/gtk-gui/MainWindow.cs | 20 +++++ MediaBrowser.Server.Mono/gtk-gui/generated.cs | 29 +++++++ MediaBrowser.Server.Mono/gtk-gui/gui.stetic | 19 +++++ .../MediaBrowser.WebDashboard.csproj | 29 ++++--- 21 files changed, 418 insertions(+), 144 deletions(-) create mode 100644 MediaBrowser.Mono.sln create mode 100644 MediaBrowser.Mono.userprefs create mode 100644 MediaBrowser.Server.Mono/MainWindow.cs create mode 100644 MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj create mode 100644 MediaBrowser.Server.Mono/Program.cs create mode 100644 MediaBrowser.Server.Mono/Properties/AssemblyInfo.cs create mode 100644 MediaBrowser.Server.Mono/gtk-gui/MainWindow.cs create mode 100644 MediaBrowser.Server.Mono/gtk-gui/generated.cs create mode 100644 MediaBrowser.Server.Mono/gtk-gui/gui.stetic (limited to 'MediaBrowser.Common.Implementations') diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 995b5cdf1..4f54b5249 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -13,6 +13,8 @@ 512 ..\ true + 10.0.0 + 2.0 true @@ -36,29 +38,25 @@ Always - - False + + + + + + + ..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll - - False + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll - - False + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll - - False + ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll - - - - - - - + @@ -131,15 +129,15 @@ - {9142eefa-7570-41e1-bfcc-468bb571af2f} + {9142EEFA-7570-41E1-BFCC-468BB571AF2F} MediaBrowser.Common - {17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2} + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2} MediaBrowser.Controller - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B} MediaBrowser.Model diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index a96f2c354..79514b5cb 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -13,6 +13,8 @@ 512 ..\ true + 10.0.0 + 2.0 true @@ -35,18 +37,6 @@ Always - - False - ..\packages\NLog.2.0.1.2\lib\net45\NLog.dll - - - False - ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll - - - False - ..\packages\SimpleInjector.2.3.5\lib\net40-client\SimpleInjector.dll - @@ -54,6 +44,15 @@ + + ..\packages\NLog.2.0.1.2\lib\net45\NLog.dll + + + ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll + + + ..\packages\SimpleInjector.2.3.5\lib\net40-client\SimpleInjector.dll + @@ -88,11 +87,11 @@ - {9142eefa-7570-41e1-bfcc-468bb571af2f} + {9142EEFA-7570-41E1-BFCC-468BB571AF2F} MediaBrowser.Common - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B} MediaBrowser.Model diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 1611c55da..8acd1a83c 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -13,6 +13,8 @@ 512 ..\ true + 10.0.0 + 2.0 true @@ -32,26 +34,19 @@ prompt 4 - - - - - - False + + + + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll - - False + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll - - False + ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll - - - @@ -113,7 +108,7 @@ - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B} MediaBrowser.Model diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index b5ad862be..0b27a350b 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -13,6 +13,8 @@ 512 ..\ true + 10.0.0 + 2.0 true @@ -42,6 +44,8 @@ x86 prompt MinimumRecommendedRules.ruleset + 4 + false bin\x86\Release\ @@ -51,12 +55,9 @@ x86 prompt MinimumRecommendedRules.ruleset + 4 - - False - ..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll - @@ -66,6 +67,9 @@ + + ..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll + @@ -174,11 +178,11 @@ - {9142eefa-7570-41e1-bfcc-468bb571af2f} + {9142EEFA-7570-41E1-BFCC-468BB571AF2F} MediaBrowser.Common - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B} MediaBrowser.Model diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 8fb471c2d..fa4fc2986 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -14,6 +14,8 @@ ..\ true ..\packages\Fody.1.17.0.0 + 10.0.0 + 2.0 true @@ -162,14 +164,13 @@ - - False - ..\packages\PropertyChanged.Fody.1.41.0.0\Lib\NET35\PropertyChanged.dll - False - + + ..\packages\PropertyChanged.Fody.1.41.0.0\Lib\NET35\PropertyChanged.dll + False + diff --git a/MediaBrowser.Mono.sln b/MediaBrowser.Mono.sln new file mode 100644 index 000000000..0dc78ca2a --- /dev/null +++ b/MediaBrowser.Mono.sln @@ -0,0 +1,68 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Model", "MediaBrowser.Model\MediaBrowser.Model.csproj", "{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Common", "MediaBrowser.Common\MediaBrowser.Common.csproj", "{9142EEFA-7570-41E1-BFCC-468BB571AF2F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Common.Implementations", "MediaBrowser.Common.Implementations\MediaBrowser.Common.Implementations.csproj", "{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Controller", "MediaBrowser.Controller\MediaBrowser.Controller.csproj", "{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Providers", "MediaBrowser.Providers\MediaBrowser.Providers.csproj", "{442B5058-DCAF-4263-BB6A-F21E31120A1B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Implementations", "MediaBrowser.Server.Implementations\MediaBrowser.Server.Implementations.csproj", "{2E781478-814D-4A48-9D80-BFF206441A65}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.WebDashboard", "MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj", "{5624B7B5-B5A7-41D8-9F10-CC5611109619}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Api", "MediaBrowser.Api\MediaBrowser.Api.csproj", "{4FD51AC5-2C16-4308-A993-C3A84F3B4582}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Mono", "MediaBrowser.Server.Mono\MediaBrowser.Server.Mono.csproj", "{A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|x86.ActiveCfg = Debug|x86 + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|x86.Build.0 = Debug|x86 + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.ActiveCfg = Release|x86 + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.Build.0 = Release|x86 + {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|x86.ActiveCfg = Debug|Any CPU + {2E781478-814D-4A48-9D80-BFF206441A65}.Debug|x86.Build.0 = Debug|Any CPU + {2E781478-814D-4A48-9D80-BFF206441A65}.Release|x86.ActiveCfg = Release|Any CPU + {2E781478-814D-4A48-9D80-BFF206441A65}.Release|x86.Build.0 = Release|Any CPU + {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|x86.ActiveCfg = Debug|Any CPU + {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|x86.Build.0 = Debug|Any CPU + {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|x86.ActiveCfg = Release|Any CPU + {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|x86.Build.0 = Release|Any CPU + {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|x86.ActiveCfg = Debug|Any CPU + {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|x86.Build.0 = Debug|Any CPU + {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|x86.ActiveCfg = Release|Any CPU + {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|x86.Build.0 = Release|Any CPU + {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|x86.ActiveCfg = Debug|Any CPU + {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|x86.Build.0 = Debug|Any CPU + {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.ActiveCfg = Release|Any CPU + {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.Build.0 = Release|Any CPU + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|x86.ActiveCfg = Debug|Any CPU + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|x86.Build.0 = Debug|Any CPU + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x86.ActiveCfg = Release|Any CPU + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x86.Build.0 = Release|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|x86.ActiveCfg = Debug|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|x86.Build.0 = Debug|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.ActiveCfg = Release|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.Build.0 = Release|Any CPU + {A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0}.Debug|x86.ActiveCfg = Debug|x86 + {A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0}.Debug|x86.Build.0 = Debug|x86 + {A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0}.Release|x86.ActiveCfg = Release|x86 + {A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0}.Release|x86.Build.0 = Release|x86 + {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|x86.ActiveCfg = Debug|Any CPU + {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|x86.Build.0 = Debug|Any CPU + {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|x86.ActiveCfg = Release|Any CPU + {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = MediaBrowser.Server.Mono\MediaBrowser.Server.Mono.csproj + EndGlobalSection +EndGlobal diff --git a/MediaBrowser.Mono.userprefs b/MediaBrowser.Mono.userprefs new file mode 100644 index 000000000..95fb57a89 --- /dev/null +++ b/MediaBrowser.Mono.userprefs @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 139c622fc..ef94d77d1 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -13,6 +13,8 @@ 512 ..\ true + 10.0.0 + 2.0 true @@ -32,10 +34,6 @@ 4 - - False - ..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll - @@ -44,6 +42,9 @@ + + ..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll + @@ -116,15 +117,15 @@ - {9142eefa-7570-41e1-bfcc-468bb571af2f} + {9142EEFA-7570-41E1-BFCC-468BB571AF2F} MediaBrowser.Common - {17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2} + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2} MediaBrowser.Controller - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B} MediaBrowser.Model diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs index eb89210ff..b9e033d23 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs @@ -41,8 +41,6 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var allItems = _libraryManager.RootFolder.RecursiveChildren.OfType().ToList(); - var userLibraries = _userManager.Users .Select(i => new Tuple>(i.Id, i.RootFolder.GetRecursiveChildren(i).OfType().ToList())) .ToList(); @@ -79,6 +77,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators { await UpdateItemByNameCounts(name, cancellationToken, masterDictionary[name]).ConfigureAwait(false); } + catch (OperationCanceledException) + { + // Don't clutter the log + } catch (Exception ex) { _logger.ErrorException("Error updating counts for {0}", ex, name); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs index 9a34dd1b0..e4d989c33 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs @@ -42,16 +42,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var allItems = _libraryManager.RootFolder.RecursiveChildren - .Where(i => !(i is IHasMusicGenres) && !(i is Game)) - .ToList(); - var userLibraries = _userManager.Users .Select(i => new Tuple>(i.Id, i.RootFolder.GetRecursiveChildren(i).Where(m => !(m is IHasMusicGenres) && !(m is Game)).ToList())) .ToList(); - var allLibraryItems = allItems; - var masterDictionary = new Dictionary>>(StringComparer.OrdinalIgnoreCase); // Populate counts of items @@ -84,6 +78,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators { await UpdateItemByNameCounts(name, cancellationToken, masterDictionary[name]).ConfigureAwait(false); } + catch (OperationCanceledException) + { + // Don't clutter the log + } catch (Exception ex) { _logger.ErrorException("Error updating counts for {0}", ex, name); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs index 1b211d5f4..1edc24762 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs @@ -42,16 +42,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var allItems = _libraryManager.RootFolder.RecursiveChildren - .Where(i => i is IHasMusicGenres) - .ToList(); - var userLibraries = _userManager.Users .Select(i => new Tuple>(i.Id, i.RootFolder.GetRecursiveChildren(i).Where(m => m is IHasMusicGenres).ToList())) .ToList(); - var allLibraryItems = allItems; - var masterDictionary = new Dictionary>>(StringComparer.OrdinalIgnoreCase); // Populate counts of items @@ -84,6 +78,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators { await UpdateItemByNameCounts(name, cancellationToken, masterDictionary[name]).ConfigureAwait(false); } + catch (OperationCanceledException) + { + // Don't clutter the log + } catch (Exception ex) { _logger.ErrorException("Error updating counts for {0}", ex, name); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs index a4d880329..05689f8e5 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs @@ -41,14 +41,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var allItems = _libraryManager.RootFolder.RecursiveChildren.ToList(); - var userLibraries = _userManager.Users .Select(i => new Tuple>(i.Id, i.RootFolder.GetRecursiveChildren(i).ToList())) .ToList(); - var allLibraryItems = allItems; - var masterDictionary = new Dictionary>>(StringComparer.OrdinalIgnoreCase); // Populate counts of items @@ -81,6 +77,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators { await UpdateItemByNameCounts(name, cancellationToken, masterDictionary[name]).ConfigureAwait(false); } + catch (OperationCanceledException) + { + // Don't clutter the log + } catch (Exception ex) { _logger.ErrorException("Error updating counts for {0}", ex, name); diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 3c2021750..e44089cc1 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -13,6 +13,8 @@ 512 ..\ true + 10.0.0 + 2.0 true @@ -35,77 +37,65 @@ ..\packages\Alchemy.2.2.1\lib\net40\Alchemy.dll - - False - ..\packages\MediaBrowser.BdInfo.1.0.0.2\lib\net45\BdInfo.dll - ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll ..\packages\Lucene.Net.3.0.3\lib\NET40\Lucene.Net.dll - - False + + + + + ..\packages\Rx-Core.2.1.30214.0\lib\Net45\System.Reactive.Core.dll + + + ..\packages\Rx-Interfaces.2.1.30214.0\lib\Net45\System.Reactive.Interfaces.dll + + + ..\packages\Rx-Linq.2.1.30214.0\lib\Net45\System.Reactive.Linq.dll + + + + + + + + ..\packages\MediaBrowser.BdInfo.1.0.0.2\lib\net45\BdInfo.dll + + ..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll - - False + ..\packages\ServiceStack.3.9.62\lib\net35\ServiceStack.dll - - False + ..\packages\ServiceStack.Api.Swagger.3.9.59\lib\net35\ServiceStack.Api.Swagger.dll - - False + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll - - False + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll - - False + ..\packages\ServiceStack.OrmLite.SqlServer.3.9.43\lib\ServiceStack.OrmLite.SqlServer.dll - - False + ..\packages\ServiceStack.Redis.3.9.43\lib\net35\ServiceStack.Redis.dll - - False + ..\packages\ServiceStack.3.9.62\lib\net35\ServiceStack.ServiceInterface.dll - - False + ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll - - - - False + ..\packages\System.Data.SQLite.x86.1.0.88.0\lib\net45\System.Data.SQLite.dll - - False + ..\packages\System.Data.SQLite.x86.1.0.88.0\lib\net45\System.Data.SQLite.Linq.dll - - - ..\packages\Rx-Core.2.1.30214.0\lib\Net45\System.Reactive.Core.dll - - - ..\packages\Rx-Interfaces.2.1.30214.0\lib\Net45\System.Reactive.Interfaces.dll - - - ..\packages\Rx-Linq.2.1.30214.0\lib\Net45\System.Reactive.Linq.dll - - - - - - @@ -223,19 +213,19 @@ - {c4d2573a-3fd3-441f-81af-174ac4cd4e1d} + {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D} MediaBrowser.Common.Implementations - {9142eefa-7570-41e1-bfcc-468bb571af2f} + {9142EEFA-7570-41E1-BFCC-468BB571AF2F} MediaBrowser.Common - {17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2} + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2} MediaBrowser.Controller - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B} MediaBrowser.Model diff --git a/MediaBrowser.Server.Mono/MainWindow.cs b/MediaBrowser.Server.Mono/MainWindow.cs new file mode 100644 index 000000000..229f44dab --- /dev/null +++ b/MediaBrowser.Server.Mono/MainWindow.cs @@ -0,0 +1,16 @@ +using System; +using Gtk; + +public partial class MainWindow: Gtk.Window +{ + public MainWindow (): base (Gtk.WindowType.Toplevel) + { + Build (); + } + + protected void OnDeleteEvent (object sender, DeleteEventArgs a) + { + Application.Quit (); + a.RetVal = true; + } +} diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj new file mode 100644 index 000000000..a97ab4fac --- /dev/null +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -0,0 +1,91 @@ + + + + Debug + x86 + 10.0.0 + 2.0 + {A7FE75CD-3CB4-4E71-A5BF-5347721EC8E0} + WinExe + MediaBrowser.Server.Mono + MediaBrowser.Server.Mono + v4.5 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + x86 + false + + + full + true + bin\Release + prompt + 4 + x86 + false + + + + + + + + + + + + + + gui.stetic + + + + + + + + + + + + + {5624B7B5-B5A7-41D8-9F10-CC5611109619} + MediaBrowser.WebDashboard + + + {2E781478-814D-4A48-9D80-BFF206441A65} + MediaBrowser.Server.Implementations + + + {442B5058-DCAF-4263-BB6A-F21E31120A1B} + MediaBrowser.Providers + + + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B} + MediaBrowser.Model + + + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2} + MediaBrowser.Controller + + + {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D} + MediaBrowser.Common.Implementations + + + {9142EEFA-7570-41E1-BFCC-468BB571AF2F} + MediaBrowser.Common + + + {4FD51AC5-2C16-4308-A993-C3A84F3B4582} + MediaBrowser.Api + + + \ No newline at end of file diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs new file mode 100644 index 000000000..72dee1162 --- /dev/null +++ b/MediaBrowser.Server.Mono/Program.cs @@ -0,0 +1,16 @@ +using System; +using Gtk; + +namespace MediaBrowser.Server.Mono +{ + class MainClass + { + public static void Main (string[] args) + { + Application.Init (); + MainWindow win = new MainWindow (); + win.Show (); + Application.Run (); + } + } +} diff --git a/MediaBrowser.Server.Mono/Properties/AssemblyInfo.cs b/MediaBrowser.Server.Mono/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..0a2e93220 --- /dev/null +++ b/MediaBrowser.Server.Mono/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle ("MediaBrowser.Server.Mono")] +[assembly: AssemblyDescription ("")] +[assembly: AssemblyConfiguration ("")] +[assembly: AssemblyCompany ("")] +[assembly: AssemblyProduct ("")] +[assembly: AssemblyCopyright ("Luke")] +[assembly: AssemblyTrademark ("")] +[assembly: AssemblyCulture ("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion ("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/MediaBrowser.Server.Mono/gtk-gui/MainWindow.cs b/MediaBrowser.Server.Mono/gtk-gui/MainWindow.cs new file mode 100644 index 000000000..c481dfc8c --- /dev/null +++ b/MediaBrowser.Server.Mono/gtk-gui/MainWindow.cs @@ -0,0 +1,20 @@ + +// This file has been generated by the GUI designer. Do not modify. +public partial class MainWindow +{ + protected virtual void Build () + { + global::Stetic.Gui.Initialize (this); + // Widget MainWindow + this.Name = "MainWindow"; + this.Title = global::Mono.Unix.Catalog.GetString ("MainWindow"); + this.WindowPosition = ((global::Gtk.WindowPosition)(4)); + if ((this.Child != null)) { + this.Child.ShowAll (); + } + this.DefaultWidth = 400; + this.DefaultHeight = 300; + this.Show (); + this.DeleteEvent += new global::Gtk.DeleteEventHandler (this.OnDeleteEvent); + } +} diff --git a/MediaBrowser.Server.Mono/gtk-gui/generated.cs b/MediaBrowser.Server.Mono/gtk-gui/generated.cs new file mode 100644 index 000000000..9ef336398 --- /dev/null +++ b/MediaBrowser.Server.Mono/gtk-gui/generated.cs @@ -0,0 +1,29 @@ + +// This file has been generated by the GUI designer. Do not modify. +namespace Stetic +{ + internal class Gui + { + private static bool initialized; + + internal static void Initialize (Gtk.Widget iconRenderer) + { + if ((Stetic.Gui.initialized == false)) { + Stetic.Gui.initialized = true; + } + } + } + + internal class ActionGroups + { + public static Gtk.ActionGroup GetActionGroup (System.Type type) + { + return Stetic.ActionGroups.GetActionGroup (type.FullName); + } + + public static Gtk.ActionGroup GetActionGroup (string name) + { + return null; + } + } +} diff --git a/MediaBrowser.Server.Mono/gtk-gui/gui.stetic b/MediaBrowser.Server.Mono/gtk-gui/gui.stetic new file mode 100644 index 000000000..d564b4446 --- /dev/null +++ b/MediaBrowser.Server.Mono/gtk-gui/gui.stetic @@ -0,0 +1,19 @@ + + + + 2.12 + + + + + + + + MainWindow + CenterOnParent + + + + + + \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 1fbc01952..6a599da45 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -13,6 +13,8 @@ 512 ..\ true + 10.0.0 + 2.0 true @@ -35,24 +37,21 @@ Always - - False - ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll - - - False - ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll - - - False - ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll - + + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll + + + ..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll + + + ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll + @@ -67,15 +66,15 @@ - {9142eefa-7570-41e1-bfcc-468bb571af2f} + {9142EEFA-7570-41E1-BFCC-468BB571AF2F} MediaBrowser.Common - {17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2} + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2} MediaBrowser.Controller - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B} MediaBrowser.Model -- cgit v1.2.3 From fe5a9232c84cea113336005b3c7cbd7fe77a2d80 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 24 Sep 2013 20:54:51 -0400 Subject: moved a few things for mono --- .../Archiving/ZipClient.cs | 87 ++++++ .../BaseApplicationHost.cs | 59 ++-- .../MediaBrowser.Common.Implementations.csproj | 4 + .../packages.config | 1 + MediaBrowser.Model/IO/IZipClient.cs | 16 ++ MediaBrowser.Mono.userprefs | 13 +- .../EntryPoints/UdpServerEntryPoint.cs | 97 +++++++ .../MediaBrowser.Server.Implementations.csproj | 1 + .../FFMpeg/FFMpegDownloader.cs | 36 +++ .../MediaBrowser.Server.Mono.csproj | 28 ++ MediaBrowser.Server.Mono/Native/Assemblies.cs | 22 ++ MediaBrowser.Server.Mono/Native/Autorun.cs | 20 ++ .../Native/HttpMessageHandlerFactory.cs | 25 ++ MediaBrowser.Server.Mono/Native/NativeApp.cs | 25 ++ .../Native/ServerAuthorization.cs | 26 ++ MediaBrowser.Server.Mono/Native/Sqlite.cs | 36 +++ MediaBrowser.Server.Mono/gtk-gui/gui.stetic | 1 + MediaBrowser.ServerApplication/App.xaml.cs | 53 ---- MediaBrowser.ServerApplication/ApplicationHost.cs | 136 +++------ .../EntryPoints/StartupWizard.cs | 14 +- .../EntryPoints/UdpServerEntryPoint.cs | 95 ------- .../FFMpeg/FFMpegDownloader.cs | 302 ++++++++++++++++++++ .../FFMpeg/FFMpegInfo.cs | 24 ++ ...0904-git-f974289-win32-static.7z.REMOVED.git-id | 1 + .../Implementations/FFMpegDownloader.cs | 315 --------------------- .../Implementations/ZipClient.cs | 48 ---- ...0904-git-f974289-win32-static.7z.REMOVED.git-id | 1 - MediaBrowser.ServerApplication/MainStartup.cs | 1 - MediaBrowser.ServerApplication/MainWindow.xaml.cs | 17 +- .../MediaBrowser.ServerApplication.csproj | 26 +- .../Native/Assemblies.cs | 25 ++ MediaBrowser.ServerApplication/Native/Autorun.cs | 31 ++ .../Native/BrowserLauncher.cs | 68 +++++ .../Native/HttpMessageHandlerFactory.cs | 26 ++ MediaBrowser.ServerApplication/Native/NativeApp.cs | 25 ++ .../Native/RegisterServer.bat | 28 ++ .../Native/ServerAuthorization.cs | 56 ++++ MediaBrowser.ServerApplication/Native/Sqlite.cs | 36 +++ MediaBrowser.ServerApplication/RegisterServer.bat | 28 -- MediaBrowser.ServerApplication/packages.config | 2 - 40 files changed, 1158 insertions(+), 697 deletions(-) create mode 100644 MediaBrowser.Common.Implementations/Archiving/ZipClient.cs create mode 100644 MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs create mode 100644 MediaBrowser.Server.Mono/FFMpeg/FFMpegDownloader.cs create mode 100644 MediaBrowser.Server.Mono/Native/Assemblies.cs create mode 100644 MediaBrowser.Server.Mono/Native/Autorun.cs create mode 100644 MediaBrowser.Server.Mono/Native/HttpMessageHandlerFactory.cs create mode 100644 MediaBrowser.Server.Mono/Native/NativeApp.cs create mode 100644 MediaBrowser.Server.Mono/Native/ServerAuthorization.cs create mode 100644 MediaBrowser.Server.Mono/Native/Sqlite.cs delete mode 100644 MediaBrowser.ServerApplication/EntryPoints/UdpServerEntryPoint.cs create mode 100644 MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs create mode 100644 MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs create mode 100644 MediaBrowser.ServerApplication/FFMpeg/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id delete mode 100644 MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs delete mode 100644 MediaBrowser.ServerApplication/Implementations/ZipClient.cs delete mode 100644 MediaBrowser.ServerApplication/Implementations/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id create mode 100644 MediaBrowser.ServerApplication/Native/Assemblies.cs create mode 100644 MediaBrowser.ServerApplication/Native/Autorun.cs create mode 100644 MediaBrowser.ServerApplication/Native/BrowserLauncher.cs create mode 100644 MediaBrowser.ServerApplication/Native/HttpMessageHandlerFactory.cs create mode 100644 MediaBrowser.ServerApplication/Native/NativeApp.cs create mode 100644 MediaBrowser.ServerApplication/Native/RegisterServer.bat create mode 100644 MediaBrowser.ServerApplication/Native/ServerAuthorization.cs create mode 100644 MediaBrowser.ServerApplication/Native/Sqlite.cs delete mode 100644 MediaBrowser.ServerApplication/RegisterServer.bat (limited to 'MediaBrowser.Common.Implementations') diff --git a/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs new file mode 100644 index 000000000..39690eb07 --- /dev/null +++ b/MediaBrowser.Common.Implementations/Archiving/ZipClient.cs @@ -0,0 +1,87 @@ +using MediaBrowser.Model.IO; +using SharpCompress.Archive.SevenZip; +using SharpCompress.Common; +using SharpCompress.Reader; +using System.IO; + +namespace MediaBrowser.Common.Implementations.Archiving +{ + /// + /// Class DotNetZipClient + /// + public class ZipClient : IZipClient + { + /// + /// Extracts all. + /// + /// The source file. + /// The target path. + /// if set to true [overwrite existing files]. + public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles) + { + using (var fileStream = File.OpenRead(sourceFile)) + { + ExtractAll(fileStream, targetPath, overwriteExistingFiles); + } + } + + /// + /// Extracts all. + /// + /// The source. + /// The target path. + /// if set to true [overwrite existing files]. + public void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles) + { + using (var reader = ReaderFactory.Open(source)) + { + var options = ExtractOptions.ExtractFullPath; + + if (overwriteExistingFiles) + { + options = options | ExtractOptions.Overwrite; + } + + reader.WriteAllToDirectory(targetPath, options); + } + } + + /// + /// Extracts all from7z. + /// + /// The source file. + /// The target path. + /// if set to true [overwrite existing files]. + public void ExtractAllFrom7z(string sourceFile, string targetPath, bool overwriteExistingFiles) + { + using (var fileStream = File.OpenRead(sourceFile)) + { + ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles); + } + } + + /// + /// Extracts all from7z. + /// + /// The source. + /// The target path. + /// if set to true [overwrite existing files]. + public void ExtractAllFrom7z(Stream source, string targetPath, bool overwriteExistingFiles) + { + using (var archive = SevenZipArchive.Open(source)) + { + using (var reader = archive.ExtractAllEntries()) + { + var options = ExtractOptions.ExtractFullPath; + + if (overwriteExistingFiles) + { + options = options | ExtractOptions.Overwrite; + } + + reader.WriteAllToDirectory(targetPath, options); + } + } + } + } +} diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index c0ac6a4b3..0d96df9a2 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; +using MediaBrowser.Common.Implementations.Archiving; using MediaBrowser.Common.Implementations.NetworkManagement; using MediaBrowser.Common.Implementations.ScheduledTasks; using MediaBrowser.Common.Implementations.Security; @@ -10,6 +11,7 @@ using MediaBrowser.Common.Plugins; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Common.Security; using MediaBrowser.Common.Updates; +using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Updates; @@ -149,6 +151,12 @@ namespace MediaBrowser.Common.Implementations /// The installation manager. protected IInstallationManager InstallationManager { get; set; } + /// + /// Gets or sets the zip client. + /// + /// The zip client. + protected IZipClient ZipClient { get; set; } + /// /// Initializes a new instance of the class. /// @@ -202,12 +210,27 @@ namespace MediaBrowser.Common.Implementations { Resolve().AddTasks(GetExports(false)); - Task.Run(() => ConfigureAutoRunAtStartup()); + Task.Run(() => ConfigureAutorun()); ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated; }); } + /// + /// Configures the autorun. + /// + private void ConfigureAutorun() + { + try + { + ConfigureAutoRunAtStartup(ConfigurationManager.CommonConfiguration.RunAtStartup); + } + catch (Exception ex) + { + Logger.ErrorException("Error configuring autorun", ex); + } + } + /// /// Gets the composable part assemblies. /// @@ -281,6 +304,9 @@ namespace MediaBrowser.Common.Implementations InstallationManager = new InstallationManager(Logger, this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, NetworkManager, ConfigurationManager); RegisterSingleInstance(InstallationManager); + + ZipClient = new ZipClient(); + RegisterSingleInstance(ZipClient); }); } @@ -453,11 +479,6 @@ namespace MediaBrowser.Common.Implementations } } - /// - /// Defines the full path to our shortcut in the start menu - /// - protected abstract string ProductShortcutPath { get; } - /// /// Handles the ConfigurationUpdated event of the ConfigurationManager control. /// @@ -466,32 +487,10 @@ namespace MediaBrowser.Common.Implementations /// protected virtual void OnConfigurationUpdated(object sender, EventArgs e) { - ConfigureAutoRunAtStartup(); + ConfigureAutorun(); } - /// - /// Configures the auto run at startup. - /// - private void ConfigureAutoRunAtStartup() - { - if (ConfigurationManager.CommonConfiguration.RunAtStartup) - { - //Copy our shortut into the startup folder for this user - File.Copy(ProductShortcutPath, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), Path.GetFileName(ProductShortcutPath) ?? "MBstartup.lnk"), true); - } - else - { - //Remove our shortcut from the startup folder for this user - try - { - File.Delete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), Path.GetFileName(ProductShortcutPath) ?? "MBstartup.lnk")); - } - catch (FileNotFoundException) - { - //This is okay - trying to remove it anyway - } - } - } + protected abstract void ConfigureAutoRunAtStartup(bool autorun); /// /// Removes the plugin. diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index 79514b5cb..11da950f7 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -37,6 +37,9 @@ Always + + ..\packages\sharpcompress.0.10.1.3\lib\net40\SharpCompress.dll + @@ -58,6 +61,7 @@ Properties\SharedVersion.cs + diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index 4be861cce..d03cb14e0 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/MediaBrowser.Model/IO/IZipClient.cs b/MediaBrowser.Model/IO/IZipClient.cs index c9e7e0db6..694c393aa 100644 --- a/MediaBrowser.Model/IO/IZipClient.cs +++ b/MediaBrowser.Model/IO/IZipClient.cs @@ -22,5 +22,21 @@ namespace MediaBrowser.Model.IO /// The target path. /// if set to true [overwrite existing files]. void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles); + + /// + /// Extracts all from7z. + /// + /// The source file. + /// The target path. + /// if set to true [overwrite existing files]. + void ExtractAllFrom7z(string sourceFile, string targetPath, bool overwriteExistingFiles); + + /// + /// Extracts all from7z. + /// + /// The source. + /// The target path. + /// if set to true [overwrite existing files]. + void ExtractAllFrom7z(Stream source, string targetPath, bool overwriteExistingFiles); } } diff --git a/MediaBrowser.Mono.userprefs b/MediaBrowser.Mono.userprefs index 95fb57a89..80da5915d 100644 --- a/MediaBrowser.Mono.userprefs +++ b/MediaBrowser.Mono.userprefs @@ -1,6 +1,17 @@  - + + + + + + + + + + + + diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs new file mode 100644 index 000000000..9c1a953b1 --- /dev/null +++ b/MediaBrowser.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -0,0 +1,97 @@ +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.Udp; +using System.Net.Sockets; + +namespace MediaBrowser.Server.Implementations.EntryPoints +{ + /// + /// Class UdpServerEntryPoint + /// + public class UdpServerEntryPoint : IServerEntryPoint + { + /// + /// Gets or sets the UDP server. + /// + /// The UDP server. + private UdpServer UdpServer { get; set; } + + /// + /// The _logger + /// + private readonly ILogger _logger; + /// + /// The _network manager + /// + private readonly INetworkManager _networkManager; + /// + /// The _server configuration manager + /// + private readonly IServerConfigurationManager _serverConfigurationManager; + /// + /// The _HTTP server + /// + private readonly IHttpServer _httpServer; + + public const int PortNumber = 7359; + + /// + /// Initializes a new instance of the class. + /// + /// The logger. + /// The network manager. + /// The server configuration manager. + /// The HTTP server. + public UdpServerEntryPoint(ILogger logger, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager, IHttpServer httpServer) + { + _logger = logger; + _networkManager = networkManager; + _serverConfigurationManager = serverConfigurationManager; + _httpServer = httpServer; + } + + /// + /// Runs this instance. + /// + public void Run() + { + var udpServer = new UdpServer(_logger, _networkManager, _serverConfigurationManager, _httpServer); + + try + { + udpServer.Start(PortNumber); + + UdpServer = udpServer; + } + catch (SocketException ex) + { + _logger.ErrorException("Failed to start UDP Server", ex); + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool dispose) + { + if (dispose) + { + if (UdpServer != null) + { + UdpServer.Dispose(); + } + } + } + } +} diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index e44089cc1..f409b7205 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -113,6 +113,7 @@ + diff --git a/MediaBrowser.Server.Mono/FFMpeg/FFMpegDownloader.cs b/MediaBrowser.Server.Mono/FFMpeg/FFMpegDownloader.cs new file mode 100644 index 000000000..cc268ef07 --- /dev/null +++ b/MediaBrowser.Server.Mono/FFMpeg/FFMpegDownloader.cs @@ -0,0 +1,36 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.ServerApplication.FFMpeg +{ + public class FFMpegDownloader + { + private readonly IHttpClient _httpClient; + private readonly IApplicationPaths _appPaths; + private readonly ILogger _logger; + private readonly IZipClient _zipClient; + + public FFMpegDownloader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IZipClient zipClient) + { + _logger = logger; + _appPaths = appPaths; + _httpClient = httpClient; + _zipClient = zipClient; + } + + public Task GetFFMpegInfo() + { + return Task.FromResult (new FFMpegInfo()); + } + } +} diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index a97ab4fac..1c369daac 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -40,6 +40,9 @@ + + + @@ -52,6 +55,25 @@ + + EntryPoints\StartupWizard.cs + + + Native\BrowserLauncher.cs + + + + + + FFMpeg\FFMpegInfo.cs + + + ApplicationHost.cs + + + + + @@ -88,4 +110,10 @@ MediaBrowser.Api + + + + + + \ No newline at end of file diff --git a/MediaBrowser.Server.Mono/Native/Assemblies.cs b/MediaBrowser.Server.Mono/Native/Assemblies.cs new file mode 100644 index 000000000..eae6366e1 --- /dev/null +++ b/MediaBrowser.Server.Mono/Native/Assemblies.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Reflection; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class Assemblies + /// + public static class Assemblies + { + /// + /// Gets the assemblies with parts. + /// + /// List{Assembly}. + public static List GetAssembliesWithParts() + { + var list = new List(); + + return list; + } + } +} diff --git a/MediaBrowser.Server.Mono/Native/Autorun.cs b/MediaBrowser.Server.Mono/Native/Autorun.cs new file mode 100644 index 000000000..ee33c5967 --- /dev/null +++ b/MediaBrowser.Server.Mono/Native/Autorun.cs @@ -0,0 +1,20 @@ +using System; +using System.IO; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class Autorun + /// + public static class Autorun + { + /// + /// Configures the specified autorun. + /// + /// if set to true [autorun]. + public static void Configure(bool autorun) + { + + } + } +} diff --git a/MediaBrowser.Server.Mono/Native/HttpMessageHandlerFactory.cs b/MediaBrowser.Server.Mono/Native/HttpMessageHandlerFactory.cs new file mode 100644 index 000000000..5823a7e51 --- /dev/null +++ b/MediaBrowser.Server.Mono/Native/HttpMessageHandlerFactory.cs @@ -0,0 +1,25 @@ +using System.Net; +using System.Net.Cache; +using System.Net.Http; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class HttpMessageHandlerFactory + /// + public static class HttpMessageHandlerFactory + { + /// + /// Gets the HTTP message handler. + /// + /// if set to true [enable HTTP compression]. + /// HttpMessageHandler. + public static HttpMessageHandler GetHttpMessageHandler(bool enableHttpCompression) + { + return new HttpClientHandler + { + AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None + }; + } + } +} diff --git a/MediaBrowser.Server.Mono/Native/NativeApp.cs b/MediaBrowser.Server.Mono/Native/NativeApp.cs new file mode 100644 index 000000000..bb47f6ea4 --- /dev/null +++ b/MediaBrowser.Server.Mono/Native/NativeApp.cs @@ -0,0 +1,25 @@ + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class NativeApp + /// + public static class NativeApp + { + /// + /// Shutdowns this instance. + /// + public static void Shutdown() + { + + } + + /// + /// Restarts this instance. + /// + public static void Restart() + { + + } + } +} diff --git a/MediaBrowser.Server.Mono/Native/ServerAuthorization.cs b/MediaBrowser.Server.Mono/Native/ServerAuthorization.cs new file mode 100644 index 000000000..6f43a12c0 --- /dev/null +++ b/MediaBrowser.Server.Mono/Native/ServerAuthorization.cs @@ -0,0 +1,26 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class Authorization + /// + public static class ServerAuthorization + { + /// + /// Authorizes the server. + /// + /// The HTTP server port. + /// The HTTP server URL prefix. + /// The web socket port. + /// The UDP port. + /// The temp directory. + public static void AuthorizeServer(int httpServerPort, string httpServerUrlPrefix, int webSocketPort, int udpPort, string tempDirectory) + { + + } + } +} diff --git a/MediaBrowser.Server.Mono/Native/Sqlite.cs b/MediaBrowser.Server.Mono/Native/Sqlite.cs new file mode 100644 index 000000000..cc20952d7 --- /dev/null +++ b/MediaBrowser.Server.Mono/Native/Sqlite.cs @@ -0,0 +1,36 @@ +using System.Data; +using System.Data.SQLite; +using System.Threading.Tasks; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class Sqlite + /// + public static class Sqlite + { + /// + /// Connects to db. + /// + /// The db path. + /// Task{IDbConnection}. + /// dbPath + public static async Task OpenDatabase(string dbPath) + { + var connectionstr = new SQLiteConnectionStringBuilder + { + PageSize = 4096, + CacheSize = 4096, + SyncMode = SynchronizationModes.Normal, + DataSource = dbPath, + JournalMode = SQLiteJournalModeEnum.Wal + }; + + var connection = new SQLiteConnection(connectionstr.ConnectionString); + + await connection.OpenAsync().ConfigureAwait(false); + + return connection; + } + } +} diff --git a/MediaBrowser.Server.Mono/gtk-gui/gui.stetic b/MediaBrowser.Server.Mono/gtk-gui/gui.stetic index d564b4446..81685442c 100644 --- a/MediaBrowser.Server.Mono/gtk-gui/gui.stetic +++ b/MediaBrowser.Server.Mono/gtk-gui/gui.stetic @@ -1,6 +1,7 @@  + .. 2.12 diff --git a/MediaBrowser.ServerApplication/App.xaml.cs b/MediaBrowser.ServerApplication/App.xaml.cs index 69de391a4..706206d3a 100644 --- a/MediaBrowser.ServerApplication/App.xaml.cs +++ b/MediaBrowser.ServerApplication/App.xaml.cs @@ -154,58 +154,5 @@ namespace MediaBrowser.ServerApplication { Dispatcher.Invoke(Shutdown); } - - /// - /// Opens the dashboard page. - /// - /// The page. - /// The logged in user. - /// The configuration manager. - /// The app host. - public static void OpenDashboardPage(string page, User loggedInUser, IServerConfigurationManager configurationManager, IServerApplicationHost appHost) - { - var url = "http://localhost:" + configurationManager.Configuration.HttpServerPortNumber + "/" + - appHost.WebApplicationName + "/dashboard/" + page; - - OpenUrl(url); - } - - /// - /// Opens the URL. - /// - /// The URL. - public static void OpenUrl(string url) - { - var process = new Process - { - StartInfo = new ProcessStartInfo - { - FileName = url - }, - - EnableRaisingEvents = true - }; - - process.Exited += ProcessExited; - - try - { - process.Start(); - } - catch (Exception ex) - { - MessageBox.Show("There was an error launching your web browser. Please check your defualt browser settings."); - } - } - - /// - /// Processes the exited. - /// - /// The sender. - /// The instance containing the event data. - static void ProcessExited(object sender, EventArgs e) - { - ((Process)sender).Dispose(); - } } } diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index e96516603..d0f7da73d 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -24,7 +24,6 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Controller.Session; using MediaBrowser.Controller.Sorting; -using MediaBrowser.IsoMounter; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; @@ -36,6 +35,7 @@ using MediaBrowser.Server.Implementations.BdInfo; using MediaBrowser.Server.Implementations.Configuration; using MediaBrowser.Server.Implementations.Drawing; using MediaBrowser.Server.Implementations.Dto; +using MediaBrowser.Server.Implementations.EntryPoints; using MediaBrowser.Server.Implementations.HttpServer; using MediaBrowser.Server.Implementations.IO; using MediaBrowser.Server.Implementations.Library; @@ -46,16 +46,14 @@ using MediaBrowser.Server.Implementations.Providers; using MediaBrowser.Server.Implementations.ServerManager; using MediaBrowser.Server.Implementations.Session; using MediaBrowser.Server.Implementations.WebSocket; -using MediaBrowser.ServerApplication.Implementations; +using MediaBrowser.ServerApplication.FFMpeg; +using MediaBrowser.ServerApplication.Native; using MediaBrowser.WebDashboard.Api; using System; using System.Collections.Generic; -using System.Data.SQLite; -using System.Diagnostics; +using System.Data; using System.IO; using System.Linq; -using System.Net; -using System.Net.Cache; using System.Net.Http; using System.Reflection; using System.Threading; @@ -68,8 +66,6 @@ namespace MediaBrowser.ServerApplication /// public class ApplicationHost : BaseApplicationHost, IServerApplicationHost { - internal const int UdpServerPort = 7359; - /// /// Gets the server kernel. /// @@ -142,11 +138,6 @@ namespace MediaBrowser.ServerApplication /// The provider manager. private IProviderManager ProviderManager { get; set; } /// - /// Gets or sets the zip client. - /// - /// The zip client. - private IZipClient ZipClient { get; set; } - /// /// Gets or sets the HTTP server. /// /// The HTTP server. @@ -175,14 +166,6 @@ namespace MediaBrowser.ServerApplication private IItemRepository ItemRepository { get; set; } private INotificationsRepository NotificationsRepository { get; set; } - /// - /// The full path to our startmenu shortcut - /// - protected override string ProductShortcutPath - { - get { return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Media Browser 3", "Media Browser Server.lnk"); } - } - private Task _httpServerCreationTask; /// @@ -256,9 +239,6 @@ namespace MediaBrowser.ServerApplication RegisterSingleInstance(() => new BdInfoExaminer()); - ZipClient = new ZipClient(); - RegisterSingleInstance(ZipClient); - var mediaEncoderTask = RegisterMediaEncoder(); UserDataRepository = new SqliteUserDataRepository(ApplicationPaths, JsonSerializer, LogManager); @@ -322,7 +302,7 @@ namespace MediaBrowser.ServerApplication /// Task. private async Task RegisterMediaEncoder() { - var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient).GetFFMpegInfo().ConfigureAwait(false); + var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient).GetFFMpegInfo().ConfigureAwait(false); MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), ApplicationPaths, JsonSerializer, info.Path, info.ProbePath, info.Version); RegisterSingleInstance(MediaEncoder); @@ -407,27 +387,14 @@ namespace MediaBrowser.ServerApplication /// The db path. /// Task{IDbConnection}. /// dbPath - private static async Task ConnectToDb(string dbPath) + private static Task ConnectToDb(string dbPath) { if (string.IsNullOrEmpty(dbPath)) { throw new ArgumentNullException("dbPath"); } - var connectionstr = new SQLiteConnectionStringBuilder - { - PageSize = 4096, - CacheSize = 4096, - SyncMode = SynchronizationModes.Normal, - DataSource = dbPath, - JournalMode = SQLiteJournalModeEnum.Wal - }; - - var connection = new SQLiteConnection(connectionstr.ConnectionString); - - await connection.OpenAsync().ConfigureAwait(false); - - return connection; + return Sqlite.OpenDatabase(dbPath); } /// @@ -479,7 +446,7 @@ namespace MediaBrowser.ServerApplication IsoManager.AddParts(GetExports()); SessionManager.AddParts(GetExports()); - + ImageProcessor.AddParts(GetExports()); } @@ -530,7 +497,6 @@ namespace MediaBrowser.ServerApplication { NotifyPendingRestart(); } - } /// @@ -547,7 +513,7 @@ namespace MediaBrowser.ServerApplication Logger.ErrorException("Error sending server restart web socket message", ex); } - MainStartup.Restart(); + NativeApp.Restart(); } /// @@ -571,44 +537,44 @@ namespace MediaBrowser.ServerApplication /// IEnumerable{Assembly}. protected override IEnumerable GetComposablePartAssemblies() { + var list = Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly) + .Select(LoadAssembly) + .Where(a => a != null) + .ToList(); + // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that // This will prevent the .dll file from getting locked, and allow us to replace it when needed - foreach (var pluginAssembly in Directory - .EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly) - .Select(LoadAssembly).Where(a => a != null)) - { - yield return pluginAssembly; - } // Include composable parts in the Api assembly - yield return typeof(ApiEntryPoint).Assembly; + list.Add(typeof(ApiEntryPoint).Assembly); // Include composable parts in the Dashboard assembly - yield return typeof(DashboardInfo).Assembly; + list.Add(typeof(DashboardInfo).Assembly); // Include composable parts in the Model assembly - yield return typeof(SystemInfo).Assembly; + list.Add(typeof(SystemInfo).Assembly); // Include composable parts in the Common assembly - yield return typeof(IApplicationHost).Assembly; + list.Add(typeof(IApplicationHost).Assembly); // Include composable parts in the Controller assembly - yield return typeof(Kernel).Assembly; + list.Add(typeof(Kernel).Assembly); // Include composable parts in the Providers assembly - yield return typeof(ImagesByNameProvider).Assembly; + list.Add(typeof(ImagesByNameProvider).Assembly); // Common implementations - yield return typeof(TaskManager).Assembly; + list.Add(typeof(TaskManager).Assembly); // Server implementations - yield return typeof(ServerApplicationPaths).Assembly; + list.Add(typeof(ServerApplicationPaths).Assembly); - // Pismo - yield return typeof(PismoIsoManager).Assembly; + list.AddRange(Assemblies.GetAssembliesWithParts()); // Include composable parts in the running assembly - yield return GetType().Assembly; + list.Add(GetType().Assembly); + + return list; } private readonly string _systemId = Environment.MachineName.GetMD5().ToString(); @@ -667,7 +633,7 @@ namespace MediaBrowser.ServerApplication Logger.ErrorException("Error sending server shutdown web socket message", ex); } - MainStartup.Shutdown(); + NativeApp.Shutdown(); } /// @@ -677,36 +643,16 @@ namespace MediaBrowser.ServerApplication { Logger.Info("Requesting administrative access to authorize http server"); - // Create a temp file path to extract the bat file to - var tmpFile = Path.Combine(ConfigurationManager.CommonApplicationPaths.TempDirectory, Guid.NewGuid() + ".bat"); - - // Extract the bat file - using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MediaBrowser.ServerApplication.RegisterServer.bat")) + try { - using (var fileStream = File.Create(tmpFile)) - { - stream.CopyTo(fileStream); - } + ServerAuthorization.AuthorizeServer(ServerConfigurationManager.Configuration.HttpServerPortNumber, + HttpServerUrlPrefix, ServerConfigurationManager.Configuration.LegacyWebSocketPortNumber, + UdpServerEntryPoint.PortNumber, + ConfigurationManager.CommonApplicationPaths.TempDirectory); } - - var startInfo = new ProcessStartInfo - { - FileName = tmpFile, - - Arguments = string.Format("{0} {1} {2} {3}", ServerConfigurationManager.Configuration.HttpServerPortNumber, - HttpServerUrlPrefix, - UdpServerPort, - ServerConfigurationManager.Configuration.LegacyWebSocketPortNumber), - - CreateNoWindow = true, - WindowStyle = ProcessWindowStyle.Hidden, - Verb = "runas", - ErrorDialog = false - }; - - using (var process = Process.Start(startInfo)) + catch (Exception ex) { - process.WaitForExit(); + Logger.ErrorException("Error authorizing server", ex); } } @@ -716,8 +662,7 @@ namespace MediaBrowser.ServerApplication /// The cancellation token. /// The progress. /// Task{CheckForUpdateResult}. - public override async Task CheckForApplicationUpdate(CancellationToken cancellationToken, - IProgress progress) + public override async Task CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress progress) { var availablePackages = await InstallationManager.GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); @@ -748,11 +693,12 @@ namespace MediaBrowser.ServerApplication /// HttpMessageHandler. protected override HttpMessageHandler GetHttpMessageHandler(bool enableHttpCompression) { - return new WebRequestHandler - { - CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate), - AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None - }; + return HttpMessageHandlerFactory.GetHttpMessageHandler(enableHttpCompression); + } + + protected override void ConfigureAutoRunAtStartup(bool autorun) + { + Autorun.Configure(autorun); } } } diff --git a/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs b/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs index 87578ef84..1a5f9e2c3 100644 --- a/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs +++ b/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs @@ -3,9 +3,10 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; -using System.ComponentModel; +using System; using System.Linq; -using System.Windows; +using System.Windows.Forms; +using MediaBrowser.ServerApplication.Native; namespace MediaBrowser.ServerApplication.EntryPoints { @@ -31,9 +32,10 @@ namespace MediaBrowser.ServerApplication.EntryPoints /// /// The app host. /// The user manager. - public StartupWizard(IServerApplicationHost appHost, IUserManager userManager, IServerConfigurationManager configurationManager) + public StartupWizard(IServerApplicationHost appHost, IUserManager userManager, IServerConfigurationManager configurationManager, ILogger logger) { _appHost = appHost; + _logger = logger; _userManager = userManager; _configurationManager = configurationManager; } @@ -58,9 +60,9 @@ namespace MediaBrowser.ServerApplication.EntryPoints try { - App.OpenDashboardPage("wizardstart.html", user, _configurationManager, _appHost); + BrowserLauncher.OpenDashboardPage("wizardstart.html", user, _configurationManager, _appHost, _logger); } - catch (Win32Exception ex) + catch (Exception ex) { _logger.ErrorException("Error launching startup wizard", ex); @@ -75,4 +77,4 @@ namespace MediaBrowser.ServerApplication.EntryPoints { } } -} +} \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/EntryPoints/UdpServerEntryPoint.cs b/MediaBrowser.ServerApplication/EntryPoints/UdpServerEntryPoint.cs deleted file mode 100644 index 595d5c89f..000000000 --- a/MediaBrowser.ServerApplication/EntryPoints/UdpServerEntryPoint.cs +++ /dev/null @@ -1,95 +0,0 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Model.Logging; -using MediaBrowser.Server.Implementations.Udp; -using System.Net.Sockets; - -namespace MediaBrowser.ServerApplication.EntryPoints -{ - /// - /// Class UdpServerEntryPoint - /// - public class UdpServerEntryPoint : IServerEntryPoint - { - /// - /// Gets or sets the UDP server. - /// - /// The UDP server. - private UdpServer UdpServer { get; set; } - - /// - /// The _logger - /// - private readonly ILogger _logger; - /// - /// The _network manager - /// - private readonly INetworkManager _networkManager; - /// - /// The _server configuration manager - /// - private readonly IServerConfigurationManager _serverConfigurationManager; - /// - /// The _HTTP server - /// - private readonly IHttpServer _httpServer; - - /// - /// Initializes a new instance of the class. - /// - /// The logger. - /// The network manager. - /// The server configuration manager. - /// The HTTP server. - public UdpServerEntryPoint(ILogger logger, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager, IHttpServer httpServer) - { - _logger = logger; - _networkManager = networkManager; - _serverConfigurationManager = serverConfigurationManager; - _httpServer = httpServer; - } - - /// - /// Runs this instance. - /// - public void Run() - { - var udpServer = new UdpServer(_logger, _networkManager, _serverConfigurationManager, _httpServer); - - try - { - udpServer.Start(ApplicationHost.UdpServerPort); - - UdpServer = udpServer; - } - catch (SocketException ex) - { - _logger.ErrorException("Failed to start UDP Server", ex); - } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - if (UdpServer != null) - { - UdpServer.Dispose(); - } - } - } - } -} diff --git a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs new file mode 100644 index 000000000..c43a85c87 --- /dev/null +++ b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs @@ -0,0 +1,302 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.IO; +using MediaBrowser.Common.Net; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.ServerApplication.FFMpeg +{ + public class FFMpegDownloader + { + private readonly IHttpClient _httpClient; + private readonly IApplicationPaths _appPaths; + private readonly ILogger _logger; + private readonly IZipClient _zipClient; + + private const string Version = "ffmpeg20130904"; + + private readonly string[] _fontUrls = new[] + { + "https://www.dropbox.com/s/pj847twf7riq0j7/ARIALUNI.7z?dl=1" + }; + + private readonly string[] _ffMpegUrls = new[] + { + "https://raw.github.com/MediaBrowser/MediaBrowser/master/MediaBrowser.ServerApplication/Implementations/ffmpeg-20130904-git-f974289-win32-static.7z", + + "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20130904-git-f974289-win32-static.7z", + "https://www.dropbox.com/s/a81cb2ob23fwcfs/ffmpeg-20130904-git-f974289-win32-static.7z?dl=1" + }; + + public FFMpegDownloader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IZipClient zipClient) + { + _logger = logger; + _appPaths = appPaths; + _httpClient = httpClient; + _zipClient = zipClient; + } + + public async Task GetFFMpegInfo() + { + var versionedDirectoryPath = Path.Combine(GetMediaToolsPath(true), Version); + + var info = new FFMpegInfo + { + ProbePath = Path.Combine(versionedDirectoryPath, "ffprobe.exe"), + Path = Path.Combine(versionedDirectoryPath, "ffmpeg.exe"), + Version = Version + }; + + if (!Directory.Exists(versionedDirectoryPath)) + { + Directory.CreateDirectory(versionedDirectoryPath); + } + + var tasks = new List(); + + if (!File.Exists(info.ProbePath) || !File.Exists(info.Path)) + { + tasks.Add(DownloadFFMpeg(info)); + } + + tasks.Add(DownloadFonts(versionedDirectoryPath)); + + await Task.WhenAll(tasks).ConfigureAwait(false); + + return info; + } + + private async Task DownloadFFMpeg(FFMpegInfo info) + { + foreach (var url in _ffMpegUrls) + { + try + { + var tempFile = await DownloadFFMpeg(info, url).ConfigureAwait(false); + + ExtractFFMpeg(tempFile, Path.GetDirectoryName(info.Path)); + return; + } + catch (HttpException ex) + { + + } + } + + throw new ApplicationException("Unable to download required components. Please try again later."); + } + + private Task DownloadFFMpeg(FFMpegInfo info, string url) + { + return _httpClient.GetTempFile(new HttpRequestOptions + { + Url = url, + CancellationToken = CancellationToken.None, + Progress = new Progress(), + + // Make it look like a browser + // Try to hide that we're direct linking + UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.47 Safari/537.36" + }); + } + + private void ExtractFFMpeg(string tempFile, string targetFolder) + { + _logger.Debug("Extracting ffmpeg from {0}", tempFile); + + var tempFolder = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString()); + + if (!Directory.Exists(tempFolder)) + { + Directory.CreateDirectory(tempFolder); + } + + try + { + Extract7zArchive(tempFile, tempFolder); + + var files = Directory.EnumerateFiles(tempFolder, "*.exe", SearchOption.AllDirectories).ToList(); + + foreach (var file in files) + { + File.Copy(file, Path.Combine(targetFolder, Path.GetFileName(file))); + } + } + finally + { + DeleteFile(tempFile); + } + } + + private void Extract7zArchive(string archivePath, string targetPath) + { + _zipClient.ExtractAllFrom7z(archivePath, targetPath, true); + } + + private void DeleteFile(string path) + { + try + { + File.Delete(path); + } + catch (IOException ex) + { + _logger.ErrorException("Error deleting temp file {0}", ex, path); + } + } + + /// + /// Extracts the fonts. + /// + /// The target path. + private async Task DownloadFonts(string targetPath) + { + try + { + var fontsDirectory = Path.Combine(targetPath, "fonts"); + + if (!Directory.Exists(fontsDirectory)) + { + Directory.CreateDirectory(fontsDirectory); + } + + const string fontFilename = "ARIALUNI.TTF"; + + var fontFile = Path.Combine(fontsDirectory, fontFilename); + + if (!File.Exists(fontFile)) + { + await DownloadFontFile(fontsDirectory, fontFilename).ConfigureAwait(false); + } + + await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false); + } + catch (HttpException ex) + { + // Don't let the server crash because of this + _logger.ErrorException("Error downloading ffmpeg font files", ex); + } + catch (Exception ex) + { + // Don't let the server crash because of this + _logger.ErrorException("Error writing ffmpeg font files", ex); + } + } + + /// + /// Downloads the font file. + /// + /// The fonts directory. + /// The font filename. + /// Task. + private async Task DownloadFontFile(string fontsDirectory, string fontFilename) + { + var existingFile = Directory + .EnumerateFiles(_appPaths.ProgramDataPath, fontFilename, SearchOption.AllDirectories) + .FirstOrDefault(); + + if (existingFile != null) + { + try + { + File.Copy(existingFile, Path.Combine(fontsDirectory, fontFilename), true); + return; + } + catch (IOException ex) + { + // Log this, but don't let it fail the operation + _logger.ErrorException("Error copying file", ex); + } + } + + string tempFile = null; + + foreach (var url in _fontUrls) + { + try + { + tempFile = await _httpClient.GetTempFile(new HttpRequestOptions + { + Url = url, + Progress = new Progress() + + }).ConfigureAwait(false); + + break; + } + catch (Exception ex) + { + // The core can function without the font file, so handle this + _logger.ErrorException("Failed to download ffmpeg font file from {0}", ex, url); + } + } + + if (string.IsNullOrEmpty(tempFile)) + { + return; + } + + Extract7zArchive(tempFile, fontsDirectory); + + try + { + File.Delete(tempFile); + } + catch (IOException ex) + { + // Log this, but don't let it fail the operation + _logger.ErrorException("Error deleting temp file {0}", ex, tempFile); + } + } + + /// + /// Writes the font config file. + /// + /// The fonts directory. + /// Task. + private async Task WriteFontConfigFile(string fontsDirectory) + { + const string fontConfigFilename = "fonts.conf"; + var fontConfigFile = Path.Combine(fontsDirectory, fontConfigFilename); + + if (!File.Exists(fontConfigFile)) + { + var contents = string.Format("{0}ArialArial Unicode MS", fontsDirectory); + + var bytes = Encoding.UTF8.GetBytes(contents); + + using (var fileStream = new FileStream(fontConfigFile, FileMode.Create, FileAccess.Write, + FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, + FileOptions.Asynchronous)) + { + await fileStream.WriteAsync(bytes, 0, bytes.Length); + } + } + } + + /// + /// Gets the media tools path. + /// + /// if set to true [create]. + /// System.String. + private string GetMediaToolsPath(bool create) + { + var path = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg"); + + if (create && !Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + + return path; + } + } +} diff --git a/MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs b/MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs new file mode 100644 index 000000000..147a9f771 --- /dev/null +++ b/MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs @@ -0,0 +1,24 @@ +namespace MediaBrowser.ServerApplication.FFMpeg +{ + /// + /// Class FFMpegInfo + /// + public class FFMpegInfo + { + /// + /// Gets or sets the path. + /// + /// The path. + public string Path { get; set; } + /// + /// Gets or sets the probe path. + /// + /// The probe path. + public string ProbePath { get; set; } + /// + /// Gets or sets the version. + /// + /// The version. + public string Version { get; set; } + } +} \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/FFMpeg/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id b/MediaBrowser.ServerApplication/FFMpeg/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id new file mode 100644 index 000000000..9f83b949b --- /dev/null +++ b/MediaBrowser.ServerApplication/FFMpeg/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id @@ -0,0 +1 @@ +8f1dfd62d31e48c31bef4b9ccc0e514f46650a79 \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs b/MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs deleted file mode 100644 index 1bc0b90f0..000000000 --- a/MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs +++ /dev/null @@ -1,315 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; -using SharpCompress.Archive.SevenZip; -using SharpCompress.Common; -using SharpCompress.Reader; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.ServerApplication.Implementations -{ - public class FFMpegDownloader - { - private readonly IHttpClient _httpClient; - private readonly IApplicationPaths _appPaths; - private readonly ILogger _logger; - - private const string Version = "ffmpeg20130904"; - - private readonly string[] _fontUrls = new[] - { - "https://www.dropbox.com/s/pj847twf7riq0j7/ARIALUNI.7z?dl=1" - }; - - private readonly string[] _ffMpegUrls = new[] - { - "https://raw.github.com/MediaBrowser/MediaBrowser/master/MediaBrowser.ServerApplication/Implementations/ffmpeg-20130904-git-f974289-win32-static.7z", - - "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20130904-git-f974289-win32-static.7z", - "https://www.dropbox.com/s/a81cb2ob23fwcfs/ffmpeg-20130904-git-f974289-win32-static.7z?dl=1" - }; - - public FFMpegDownloader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient) - { - _logger = logger; - _appPaths = appPaths; - _httpClient = httpClient; - } - - public async Task GetFFMpegInfo() - { - var versionedDirectoryPath = Path.Combine(GetMediaToolsPath(true), Version); - - var info = new FFMpegInfo - { - ProbePath = Path.Combine(versionedDirectoryPath, "ffprobe.exe"), - Path = Path.Combine(versionedDirectoryPath, "ffmpeg.exe"), - Version = Version - }; - - if (!Directory.Exists(versionedDirectoryPath)) - { - Directory.CreateDirectory(versionedDirectoryPath); - } - - var tasks = new List(); - - if (!File.Exists(info.ProbePath) || !File.Exists(info.Path)) - { - tasks.Add(DownloadFFMpeg(info)); - } - - tasks.Add(DownloadFonts(versionedDirectoryPath)); - - await Task.WhenAll(tasks).ConfigureAwait(false); - - return info; - } - - private async Task DownloadFFMpeg(FFMpegInfo info) - { - foreach (var url in _ffMpegUrls) - { - try - { - var tempFile = await DownloadFFMpeg(info, url).ConfigureAwait(false); - - ExtractFFMpeg(tempFile, Path.GetDirectoryName(info.Path)); - return; - } - catch (HttpException ex) - { - - } - } - - throw new ApplicationException("Unable to download required components. Please try again later."); - } - - private Task DownloadFFMpeg(FFMpegInfo info, string url) - { - return _httpClient.GetTempFile(new HttpRequestOptions - { - Url = url, - CancellationToken = CancellationToken.None, - Progress = new Progress(), - - // Make it look like a browser - // Try to hide that we're direct linking - UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.47 Safari/537.36" - }); - } - - private void ExtractFFMpeg(string tempFile, string targetFolder) - { - _logger.Debug("Extracting ffmpeg from {0}", tempFile); - - var tempFolder = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString()); - - if (!Directory.Exists(tempFolder)) - { - Directory.CreateDirectory(tempFolder); - } - - try - { - Extract7zArchive(tempFile, tempFolder); - - var files = Directory.EnumerateFiles(tempFolder, "*.exe", SearchOption.AllDirectories).ToList(); - - foreach (var file in files) - { - File.Copy(file, Path.Combine(targetFolder, Path.GetFileName(file))); - } - } - finally - { - DeleteFile(tempFile); - } - } - - private void Extract7zArchive(string archivePath, string targetPath) - { - using (var archive = SevenZipArchive.Open(archivePath)) - { - using (var reader = archive.ExtractAllEntries()) - { - reader.WriteAllToDirectory(targetPath, ExtractOptions.ExtractFullPath | ExtractOptions.Overwrite); - } - } - } - - private void DeleteFile(string path) - { - try - { - File.Delete(path); - } - catch (IOException ex) - { - _logger.ErrorException("Error deleting temp file {0}", ex, path); - } - } - - /// - /// Extracts the fonts. - /// - /// The target path. - private async Task DownloadFonts(string targetPath) - { - try - { - var fontsDirectory = Path.Combine(targetPath, "fonts"); - - if (!Directory.Exists(fontsDirectory)) - { - Directory.CreateDirectory(fontsDirectory); - } - - const string fontFilename = "ARIALUNI.TTF"; - - var fontFile = Path.Combine(fontsDirectory, fontFilename); - - if (!File.Exists(fontFile)) - { - await DownloadFontFile(fontsDirectory, fontFilename).ConfigureAwait(false); - } - - await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false); - } - catch (HttpException ex) - { - // Don't let the server crash because of this - _logger.ErrorException("Error downloading ffmpeg font files", ex); - } - catch (Exception ex) - { - // Don't let the server crash because of this - _logger.ErrorException("Error writing ffmpeg font files", ex); - } - } - - /// - /// Downloads the font file. - /// - /// The fonts directory. - /// The font filename. - /// Task. - private async Task DownloadFontFile(string fontsDirectory, string fontFilename) - { - var existingFile = Directory - .EnumerateFiles(_appPaths.ProgramDataPath, fontFilename, SearchOption.AllDirectories) - .FirstOrDefault(); - - if (existingFile != null) - { - try - { - File.Copy(existingFile, Path.Combine(fontsDirectory, fontFilename), true); - return; - } - catch (IOException ex) - { - // Log this, but don't let it fail the operation - _logger.ErrorException("Error copying file", ex); - } - } - - string tempFile = null; - - foreach (var url in _fontUrls) - { - try - { - tempFile = await _httpClient.GetTempFile(new HttpRequestOptions - { - Url = url, - Progress = new Progress() - - }).ConfigureAwait(false); - - break; - } - catch (Exception ex) - { - // The core can function without the font file, so handle this - _logger.ErrorException("Failed to download ffmpeg font file from {0}", ex, url); - } - } - - if (string.IsNullOrEmpty(tempFile)) - { - return; - } - - Extract7zArchive(tempFile, fontsDirectory); - - try - { - File.Delete(tempFile); - } - catch (IOException ex) - { - // Log this, but don't let it fail the operation - _logger.ErrorException("Error deleting temp file {0}", ex, tempFile); - } - } - - /// - /// Writes the font config file. - /// - /// The fonts directory. - /// Task. - private async Task WriteFontConfigFile(string fontsDirectory) - { - const string fontConfigFilename = "fonts.conf"; - var fontConfigFile = Path.Combine(fontsDirectory, fontConfigFilename); - - if (!File.Exists(fontConfigFile)) - { - var contents = string.Format("{0}ArialArial Unicode MS", fontsDirectory); - - var bytes = Encoding.UTF8.GetBytes(contents); - - using (var fileStream = new FileStream(fontConfigFile, FileMode.Create, FileAccess.Write, - FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, - FileOptions.Asynchronous)) - { - await fileStream.WriteAsync(bytes, 0, bytes.Length); - } - } - } - - /// - /// Gets the media tools path. - /// - /// if set to true [create]. - /// System.String. - private string GetMediaToolsPath(bool create) - { - var path = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg"); - - if (create && !Directory.Exists(path)) - { - Directory.CreateDirectory(path); - } - - return path; - } - } - - public class FFMpegInfo - { - public string Path { get; set; } - public string ProbePath { get; set; } - public string Version { get; set; } - } -} diff --git a/MediaBrowser.ServerApplication/Implementations/ZipClient.cs b/MediaBrowser.ServerApplication/Implementations/ZipClient.cs deleted file mode 100644 index e9e8645e9..000000000 --- a/MediaBrowser.ServerApplication/Implementations/ZipClient.cs +++ /dev/null @@ -1,48 +0,0 @@ -using MediaBrowser.Model.IO; -using SharpCompress.Common; -using SharpCompress.Reader; -using System.IO; - -namespace MediaBrowser.ServerApplication.Implementations -{ - /// - /// Class DotNetZipClient - /// - public class ZipClient : IZipClient - { - /// - /// Extracts all. - /// - /// The source file. - /// The target path. - /// if set to true [overwrite existing files]. - public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles) - { - using (var fileStream = File.OpenRead(sourceFile)) - { - ExtractAll(fileStream, targetPath, overwriteExistingFiles); - } - } - - /// - /// Extracts all. - /// - /// The source. - /// The target path. - /// if set to true [overwrite existing files]. - public void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles) - { - using (var reader = ReaderFactory.Open(source)) - { - var options = ExtractOptions.ExtractFullPath; - - if (overwriteExistingFiles) - { - options = options | ExtractOptions.Overwrite; - } - - reader.WriteAllToDirectory(targetPath, options); - } - } - } -} diff --git a/MediaBrowser.ServerApplication/Implementations/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id b/MediaBrowser.ServerApplication/Implementations/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id deleted file mode 100644 index 9f83b949b..000000000 --- a/MediaBrowser.ServerApplication/Implementations/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8f1dfd62d31e48c31bef4b9ccc0e514f46650a79 \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index e9c1fdc99..55fa60ed2 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -11,7 +11,6 @@ using System.IO; using System.Linq; using System.ServiceProcess; using System.Threading; -using System.Threading.Tasks; using System.Windows; namespace MediaBrowser.ServerApplication diff --git a/MediaBrowser.ServerApplication/MainWindow.xaml.cs b/MediaBrowser.ServerApplication/MainWindow.xaml.cs index 4c9c065e6..c22c35be8 100644 --- a/MediaBrowser.ServerApplication/MainWindow.xaml.cs +++ b/MediaBrowser.ServerApplication/MainWindow.xaml.cs @@ -12,6 +12,7 @@ using System.Diagnostics; using System.Linq; using System.Windows; using System.Windows.Threading; +using MediaBrowser.ServerApplication.Native; namespace MediaBrowser.ServerApplication { @@ -188,19 +189,19 @@ namespace MediaBrowser.ServerApplication /// The instance containing the event data. void cmdApiDocs_Click(object sender, EventArgs e) { - App.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" + - _appHost.WebApplicationName + "/metadata"); + BrowserLauncher.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" + + _appHost.WebApplicationName + "/metadata", _logger); } void cmdSwaggerApiDocs_Click(object sender, EventArgs e) { - App.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" + - _appHost.WebApplicationName + "/swagger-ui/index.html"); + BrowserLauncher.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" + + _appHost.WebApplicationName + "/swagger-ui/index.html", _logger); } void cmdGithubWiki_Click(object sender, EventArgs e) { - App.OpenUrl("https://github.com/MediaBrowser/MediaBrowser/wiki"); + BrowserLauncher.OpenUrl("https://github.com/MediaBrowser/MediaBrowser/wiki", _logger); } /// @@ -254,7 +255,7 @@ namespace MediaBrowser.ServerApplication /// private void OpenDashboard(User loggedInUser) { - App.OpenDashboardPage("dashboard.html", loggedInUser, _configurationManager, _appHost); + BrowserLauncher.OpenDashboardPage("dashboard.html", loggedInUser, _configurationManager, _appHost, _logger); } /// @@ -264,7 +265,7 @@ namespace MediaBrowser.ServerApplication /// The instance containing the event data. private void cmVisitCT_click(object sender, RoutedEventArgs e) { - App.OpenUrl("http://community.mediabrowser.tv/"); + BrowserLauncher.OpenUrl("http://community.mediabrowser.tv/", _logger); } /// @@ -275,7 +276,7 @@ namespace MediaBrowser.ServerApplication private void cmdBrowseLibrary_click(object sender, RoutedEventArgs e) { var user = _userManager.Users.FirstOrDefault(u => u.Configuration.IsAdministrator); - App.OpenDashboardPage("index.html", user, _configurationManager, _appHost); + BrowserLauncher.OpenDashboardPage("index.html", user, _configurationManager, _appHost, _logger); } /// diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 793489c1f..61ec19dd5 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -130,10 +130,6 @@ False ..\packages\MediaBrowser.IsoMounting.3.0.56\lib\net45\MediaBrowser.IsoMounter.dll - - False - ..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll - False ..\packages\NLog.2.0.1.2\lib\net45\NLog.dll @@ -168,9 +164,6 @@ False ..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll - - ..\packages\sharpcompress.0.10.1.3\lib\net40\SharpCompress.dll - False ..\packages\SimpleInjector.2.3.5\lib\net40-client\SimpleInjector.dll @@ -190,7 +183,6 @@ - @@ -212,12 +204,19 @@ Component - - + + + + + + + + Component + SplashWindow.xaml @@ -245,7 +244,6 @@ Code - LibraryExplorer.xaml @@ -281,15 +279,15 @@ Resources.Designer.cs - - + + SettingsSingleFileGenerator Settings.Designer.cs - + diff --git a/MediaBrowser.ServerApplication/Native/Assemblies.cs b/MediaBrowser.ServerApplication/Native/Assemblies.cs new file mode 100644 index 000000000..b43dc1a10 --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/Assemblies.cs @@ -0,0 +1,25 @@ +using MediaBrowser.IsoMounter; +using System.Collections.Generic; +using System.Reflection; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class Assemblies + /// + public static class Assemblies + { + /// + /// Gets the assemblies with parts. + /// + /// List{Assembly}. + public static List GetAssembliesWithParts() + { + var list = new List(); + + list.Add(typeof(PismoIsoManager).Assembly); + + return list; + } + } +} diff --git a/MediaBrowser.ServerApplication/Native/Autorun.cs b/MediaBrowser.ServerApplication/Native/Autorun.cs new file mode 100644 index 000000000..d1c02db84 --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/Autorun.cs @@ -0,0 +1,31 @@ +using System; +using System.IO; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class Autorun + /// + public static class Autorun + { + /// + /// Configures the specified autorun. + /// + /// if set to true [autorun]. + public static void Configure(bool autorun) + { + var shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Media Browser 3", "Media Browser Server.lnk"); + + if (autorun) + { + //Copy our shortut into the startup folder for this user + File.Copy(shortcutPath, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), Path.GetFileName(shortcutPath) ?? "MBstartup.lnk"), true); + } + else + { + //Remove our shortcut from the startup folder for this user + File.Delete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), Path.GetFileName(shortcutPath) ?? "MBstartup.lnk")); + } + } + } +} diff --git a/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs new file mode 100644 index 000000000..e7d041d15 --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs @@ -0,0 +1,68 @@ +using MediaBrowser.Controller; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Logging; +using System; +using System.Diagnostics; +using System.Windows.Forms; + +namespace MediaBrowser.ServerApplication.Native +{ + public static class BrowserLauncher + { + /// + /// Opens the dashboard page. + /// + /// The page. + /// The logged in user. + /// The configuration manager. + /// The app host. + public static void OpenDashboardPage(string page, User loggedInUser, IServerConfigurationManager configurationManager, IServerApplicationHost appHost, ILogger logger) + { + var url = "http://localhost:" + configurationManager.Configuration.HttpServerPortNumber + "/" + + appHost.WebApplicationName + "/dashboard/" + page; + + OpenUrl(url, logger); + } + + /// + /// Opens the URL. + /// + /// The URL. + public static void OpenUrl(string url, ILogger logger) + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = url + }, + + EnableRaisingEvents = true + }; + + process.Exited += ProcessExited; + + try + { + process.Start(); + } + catch (Exception ex) + { + logger.ErrorException("Error launching url: {0}", ex, url); + + MessageBox.Show("There was an error launching your web browser. Please check your default browser settings."); + } + } + + /// + /// Processes the exited. + /// + /// The sender. + /// The instance containing the event data. + private static void ProcessExited(object sender, EventArgs e) + { + ((Process)sender).Dispose(); + } + } +} diff --git a/MediaBrowser.ServerApplication/Native/HttpMessageHandlerFactory.cs b/MediaBrowser.ServerApplication/Native/HttpMessageHandlerFactory.cs new file mode 100644 index 000000000..4bbcc9ea0 --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/HttpMessageHandlerFactory.cs @@ -0,0 +1,26 @@ +using System.Net; +using System.Net.Cache; +using System.Net.Http; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class HttpMessageHandlerFactory + /// + public static class HttpMessageHandlerFactory + { + /// + /// Gets the HTTP message handler. + /// + /// if set to true [enable HTTP compression]. + /// HttpMessageHandler. + public static HttpMessageHandler GetHttpMessageHandler(bool enableHttpCompression) + { + return new WebRequestHandler + { + CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate), + AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None + }; + } + } +} diff --git a/MediaBrowser.ServerApplication/Native/NativeApp.cs b/MediaBrowser.ServerApplication/Native/NativeApp.cs new file mode 100644 index 000000000..ea4218afc --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/NativeApp.cs @@ -0,0 +1,25 @@ + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class NativeApp + /// + public static class NativeApp + { + /// + /// Shutdowns this instance. + /// + public static void Shutdown() + { + MainStartup.Shutdown(); + } + + /// + /// Restarts this instance. + /// + public static void Restart() + { + MainStartup.Restart(); + } + } +} diff --git a/MediaBrowser.ServerApplication/Native/RegisterServer.bat b/MediaBrowser.ServerApplication/Native/RegisterServer.bat new file mode 100644 index 000000000..d762dfaf7 --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/RegisterServer.bat @@ -0,0 +1,28 @@ +rem %1 = http server port +rem %2 = http server url +rem %3 = udp server port +rem %4 = tcp server port (web socket) + +if [%1]==[] GOTO DONE + +netsh advfirewall firewall delete rule name="Port %1" protocol=TCP localport=%1 +netsh advfirewall firewall add rule name="Port %1" dir=in action=allow protocol=TCP localport=%1 + +if [%2]==[] GOTO DONE + +netsh http del urlacl url="%2" user="NT AUTHORITY\Authenticated Users" +netsh http add urlacl url="%2" user="NT AUTHORITY\Authenticated Users" + +if [%3]==[] GOTO DONE + +netsh advfirewall firewall delete rule name="Port %3" protocol=UDP localport=%3 +netsh advfirewall firewall add rule name="Port %3" dir=in action=allow protocol=UDP localport=%3 + +if [%4]==[] GOTO DONE + +netsh advfirewall firewall delete rule name="Port %4" protocol=TCP localport=%4 +netsh advfirewall firewall add rule name="Port %4" dir=in action=allow protocol=TCP localport=%4 + + +:DONE +Exit \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs b/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs new file mode 100644 index 000000000..91f0974eb --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs @@ -0,0 +1,56 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class Authorization + /// + public static class ServerAuthorization + { + /// + /// Authorizes the server. + /// + /// The HTTP server port. + /// The HTTP server URL prefix. + /// The web socket port. + /// The UDP port. + /// The temp directory. + public static void AuthorizeServer(int httpServerPort, string httpServerUrlPrefix, int webSocketPort, int udpPort, string tempDirectory) + { + // Create a temp file path to extract the bat file to + var tmpFile = Path.Combine(tempDirectory, Guid.NewGuid() + ".bat"); + + // Extract the bat file + using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(typeof(ServerAuthorization).Namespace + ".RegisterServer.bat")) + { + using (var fileStream = File.Create(tmpFile)) + { + stream.CopyTo(fileStream); + } + } + + var startInfo = new ProcessStartInfo + { + FileName = tmpFile, + + Arguments = string.Format("{0} {1} {2} {3}", httpServerPort, + httpServerUrlPrefix, + udpPort, + webSocketPort), + + CreateNoWindow = true, + WindowStyle = ProcessWindowStyle.Hidden, + Verb = "runas", + ErrorDialog = false + }; + + using (var process = Process.Start(startInfo)) + { + process.WaitForExit(); + } + } + } +} diff --git a/MediaBrowser.ServerApplication/Native/Sqlite.cs b/MediaBrowser.ServerApplication/Native/Sqlite.cs new file mode 100644 index 000000000..cc20952d7 --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/Sqlite.cs @@ -0,0 +1,36 @@ +using System.Data; +using System.Data.SQLite; +using System.Threading.Tasks; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class Sqlite + /// + public static class Sqlite + { + /// + /// Connects to db. + /// + /// The db path. + /// Task{IDbConnection}. + /// dbPath + public static async Task OpenDatabase(string dbPath) + { + var connectionstr = new SQLiteConnectionStringBuilder + { + PageSize = 4096, + CacheSize = 4096, + SyncMode = SynchronizationModes.Normal, + DataSource = dbPath, + JournalMode = SQLiteJournalModeEnum.Wal + }; + + var connection = new SQLiteConnection(connectionstr.ConnectionString); + + await connection.OpenAsync().ConfigureAwait(false); + + return connection; + } + } +} diff --git a/MediaBrowser.ServerApplication/RegisterServer.bat b/MediaBrowser.ServerApplication/RegisterServer.bat deleted file mode 100644 index d762dfaf7..000000000 --- a/MediaBrowser.ServerApplication/RegisterServer.bat +++ /dev/null @@ -1,28 +0,0 @@ -rem %1 = http server port -rem %2 = http server url -rem %3 = udp server port -rem %4 = tcp server port (web socket) - -if [%1]==[] GOTO DONE - -netsh advfirewall firewall delete rule name="Port %1" protocol=TCP localport=%1 -netsh advfirewall firewall add rule name="Port %1" dir=in action=allow protocol=TCP localport=%1 - -if [%2]==[] GOTO DONE - -netsh http del urlacl url="%2" user="NT AUTHORITY\Authenticated Users" -netsh http add urlacl url="%2" user="NT AUTHORITY\Authenticated Users" - -if [%3]==[] GOTO DONE - -netsh advfirewall firewall delete rule name="Port %3" protocol=UDP localport=%3 -netsh advfirewall firewall add rule name="Port %3" dir=in action=allow protocol=UDP localport=%3 - -if [%4]==[] GOTO DONE - -netsh advfirewall firewall delete rule name="Port %4" protocol=TCP localport=%4 -netsh advfirewall firewall add rule name="Port %4" dir=in action=allow protocol=TCP localport=%4 - - -:DONE -Exit \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index 137483ef1..e680b556f 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -4,14 +4,12 @@ - - \ No newline at end of file -- cgit v1.2.3