From d91c63c55324df395743d6104ba18a27ace01231 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 2 Apr 2016 00:29:48 -0400 Subject: update ffmpeg info --- .../Native/WindowsApp.cs | 30 +++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 164037dc5..056258f96 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Reflection; using CommonIO; using MediaBrowser.Controller.Power; +using MediaBrowser.Server.Startup.Common.FFMpeg; namespace MediaBrowser.ServerApplication.Native { @@ -30,7 +31,7 @@ namespace MediaBrowser.ServerApplication.Native } list.Add(GetType().Assembly); - + return list; } @@ -124,5 +125,32 @@ namespace MediaBrowser.ServerApplication.Native { return new WindowsPowerManagement(_logger); } + + public FFMpegInstallInfo GetFfmpegInstallInfo() + { + var info = new FFMpegInstallInfo(); + + info.FFMpegFilename = "ffmpeg.exe"; + info.FFProbeFilename = "ffprobe.exe"; + info.Version = "20160401"; + info.ArchiveType = "7z"; + info.IsEmbedded = true; + info.DownloadUrls = GetDownloadUrls(); + + return info; + } + + private string[] GetDownloadUrls() + { + switch (Environment.SystemArchitecture) + { + case Architecture.X86_X64: + return new[] { "MediaBrowser.ServerApplication.ffmpeg.ffmpegx64.7z" }; + case Architecture.X86: + return new[] { "MediaBrowser.ServerApplication.ffmpeg.ffmpegx86.7z" }; + } + + return new string[] { }; + } } } -- cgit v1.2.3 From 91ee2e22a82773a86832a0ce96a309403ab3bb78 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 3 Apr 2016 13:34:52 -0400 Subject: update components --- .../MediaBrowser.ServerApplication.csproj | 1 - MediaBrowser.ServerApplication/Native/Autorun.cs | 35 ---------------------- .../Native/WindowsApp.cs | 18 ++++++++++- 3 files changed, 17 insertions(+), 37 deletions(-) delete mode 100644 MediaBrowser.ServerApplication/Native/Autorun.cs (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index a654bd2b5..f1a2915fe 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -110,7 +110,6 @@ MainForm.cs - diff --git a/MediaBrowser.ServerApplication/Native/Autorun.cs b/MediaBrowser.ServerApplication/Native/Autorun.cs deleted file mode 100644 index 4d3f66b91..000000000 --- a/MediaBrowser.ServerApplication/Native/Autorun.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.IO; -using CommonIO; - -namespace MediaBrowser.ServerApplication.Native -{ - /// - /// Class Autorun - /// - public static class Autorun - { - /// - /// Configures the specified autorun. - /// - /// if set to true [autorun]. - /// The file system. - public static void Configure(bool autorun, IFileSystem fileSystem) - { - var shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Emby", "Emby Server.lnk"); - - var startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup); - - if (autorun) - { - //Copy our shortut into the startup folder for this user - File.Copy(shortcutPath, Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk"), true); - } - else - { - //Remove our shortcut from the startup folder for this user - fileSystem.DeleteFile(Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk")); - } - } - } -} diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 056258f96..146a4372b 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Server.Startup.Common; using MediaBrowser.ServerApplication.Networking; using System.Collections.Generic; +using System.IO; using System.Reflection; using CommonIO; using MediaBrowser.Controller.Power; @@ -108,7 +109,22 @@ namespace MediaBrowser.ServerApplication.Native public void ConfigureAutoRun(bool autorun) { - Autorun.Configure(autorun, _fileSystem); + var shortcutPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.StartMenu), "Emby", "Emby Server.lnk"); + + var startupPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Startup); + + if (autorun) + { + //Copy our shortut into the startup folder for this user + var targetPath = Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk"); + _fileSystem.CreateDirectory(Path.GetDirectoryName(targetPath)); + File.Copy(shortcutPath, targetPath, true); + } + else + { + //Remove our shortcut from the startup folder for this user + _fileSystem.DeleteFile(Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "Emby Server.lnk")); + } } public INetworkManager CreateNetworkManager(ILogger logger) -- cgit v1.2.3 From baca0d6244185facf899c15ce39e5e858c6f7df3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 11 Apr 2016 00:24:16 -0400 Subject: update scroll styles --- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- MediaBrowser.ServerApplication/MainStartup.cs | 1 + .../MediaBrowser.ServerApplication.csproj | 1 + .../Native/LnkShortcutHandler.cs | 402 +++++++++++++++++++++ 4 files changed, 405 insertions(+), 1 deletion(-) create mode 100644 MediaBrowser.ServerApplication/Native/LnkShortcutHandler.cs (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 26aae285d..438c5cf23 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -686,7 +686,7 @@ namespace MediaBrowser.Controller.Entities get { var id = DisplayParentId; - if (!id.HasValue) + if (!id.HasValue || id.Value == Guid.Empty) { return null; } diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index 5f528926b..ac1b7ca99 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -217,6 +217,7 @@ namespace MediaBrowser.ServerApplication { var fileSystem = new WindowsFileSystem(new PatternsLogger(logManager.GetLogger("FileSystem"))); fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); + //fileSystem.AddShortcutHandler(new LnkShortcutHandler(fileSystem)); var nativeApp = new WindowsApp(fileSystem, _logger) { diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index f1a2915fe..26a9cd8b3 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -110,6 +110,7 @@ MainForm.cs + diff --git a/MediaBrowser.ServerApplication/Native/LnkShortcutHandler.cs b/MediaBrowser.ServerApplication/Native/LnkShortcutHandler.cs new file mode 100644 index 000000000..67d2e83f0 --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/LnkShortcutHandler.cs @@ -0,0 +1,402 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using System.Threading.Tasks; +using CommonIO; + +namespace MediaBrowser.ServerApplication.Native +{ + public class LnkShortcutHandler : IShortcutHandler + { + public string Extension + { + get { return ".lnk"; } + } + + public string Resolve(string shortcutPath) + { + var link = new ShellLink(); + ((IPersistFile)link).Load(shortcutPath, NativeMethods.STGM_READ); + // ((IShellLinkW)link).Resolve(hwnd, 0) + var sb = new StringBuilder(NativeMethods.MAX_PATH); + WIN32_FIND_DATA data; + ((IShellLinkW)link).GetPath(sb, sb.Capacity, out data, 0); + return sb.ToString(); + } + + public void Create(string shortcutPath, string targetPath) + { + throw new NotImplementedException(); + } + } + + /// + /// Class NativeMethods + /// + [SuppressUnmanagedCodeSecurity] + public static class NativeMethods + { + /// + /// The MA x_ PATH + /// + public const int MAX_PATH = 260; + /// + /// The MA x_ ALTERNATE + /// + public const int MAX_ALTERNATE = 14; + /// + /// The INVALI d_ HANDL e_ VALUE + /// + public static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); + /// + /// The STG m_ READ + /// + public const uint STGM_READ = 0; + } + + /// + /// Struct FILETIME + /// + [StructLayout(LayoutKind.Sequential)] + public struct FILETIME + { + /// + /// The dw low date time + /// + public uint dwLowDateTime; + /// + /// The dw high date time + /// + public uint dwHighDateTime; + } + + /// + /// Struct WIN32_FIND_DATA + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct WIN32_FIND_DATA + { + /// + /// The dw file attributes + /// + public FileAttributes dwFileAttributes; + /// + /// The ft creation time + /// + public FILETIME ftCreationTime; + /// + /// The ft last access time + /// + public FILETIME ftLastAccessTime; + /// + /// The ft last write time + /// + public FILETIME ftLastWriteTime; + /// + /// The n file size high + /// + public int nFileSizeHigh; + /// + /// The n file size low + /// + public int nFileSizeLow; + /// + /// The dw reserved0 + /// + public int dwReserved0; + /// + /// The dw reserved1 + /// + public int dwReserved1; + + /// + /// The c file name + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeMethods.MAX_PATH)] + public string cFileName; + + /// + /// This will always be null when FINDEX_INFO_LEVELS = basic + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NativeMethods.MAX_ALTERNATE)] + public string cAlternate; + + /// + /// Gets or sets the path. + /// + /// The path. + public string Path { get; set; } + + /// + /// Returns a that represents this instance. + /// + /// A that represents this instance. + public override string ToString() + { + return Path ?? string.Empty; + } + } + + /// + /// Enum SLGP_FLAGS + /// + [Flags] + public enum SLGP_FLAGS + { + /// + /// Retrieves the standard short (8.3 format) file name + /// + SLGP_SHORTPATH = 0x1, + /// + /// Retrieves the Universal Naming Convention (UNC) path name of the file + /// + SLGP_UNCPRIORITY = 0x2, + /// + /// Retrieves the raw path name. A raw path is something that might not exist and may include environment variables that need to be expanded + /// + SLGP_RAWPATH = 0x4 + } + /// + /// Enum SLR_FLAGS + /// + [Flags] + public enum SLR_FLAGS + { + /// + /// Do not display a dialog box if the link cannot be resolved. When SLR_NO_UI is set, + /// the high-order word of fFlags can be set to a time-out value that specifies the + /// maximum amount of time to be spent resolving the link. The function returns if the + /// link cannot be resolved within the time-out duration. If the high-order word is set + /// to zero, the time-out duration will be set to the default value of 3,000 milliseconds + /// (3 seconds). To specify a value, set the high word of fFlags to the desired time-out + /// duration, in milliseconds. + /// + SLR_NO_UI = 0x1, + /// + /// Obsolete and no longer used + /// + SLR_ANY_MATCH = 0x2, + /// + /// If the link object has changed, update its path and list of identifiers. + /// If SLR_UPDATE is set, you do not need to call IPersistFile::IsDirty to determine + /// whether or not the link object has changed. + /// + SLR_UPDATE = 0x4, + /// + /// Do not update the link information + /// + SLR_NOUPDATE = 0x8, + /// + /// Do not execute the search heuristics + /// + SLR_NOSEARCH = 0x10, + /// + /// Do not use distributed link tracking + /// + SLR_NOTRACK = 0x20, + /// + /// Disable distributed link tracking. By default, distributed link tracking tracks + /// removable media across multiple devices based on the volume name. It also uses the + /// Universal Naming Convention (UNC) path to track remote file systems whose drive letter + /// has changed. Setting SLR_NOLINKINFO disables both types of tracking. + /// + SLR_NOLINKINFO = 0x40, + /// + /// Call the Microsoft Windows Installer + /// + SLR_INVOKE_MSI = 0x80 + } + + /// + /// The IShellLink interface allows Shell links to be created, modified, and resolved + /// + [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")] + public interface IShellLinkW + { + /// + /// Retrieves the path and file name of a Shell link object + /// + /// The PSZ file. + /// The CCH max path. + /// The PFD. + /// The f flags. + void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out WIN32_FIND_DATA pfd, SLGP_FLAGS fFlags); + /// + /// Retrieves the list of item identifiers for a Shell link object + /// + /// The ppidl. + void GetIDList(out IntPtr ppidl); + /// + /// Sets the pointer to an item identifier list (PIDL) for a Shell link object. + /// + /// The pidl. + void SetIDList(IntPtr pidl); + /// + /// Retrieves the description string for a Shell link object + /// + /// Name of the PSZ. + /// Name of the CCH max. + void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName); + /// + /// Sets the description for a Shell link object. The description can be any application-defined string + /// + /// Name of the PSZ. + void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); + /// + /// Retrieves the name of the working directory for a Shell link object + /// + /// The PSZ dir. + /// The CCH max path. + void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath); + /// + /// Sets the name of the working directory for a Shell link object + /// + /// The PSZ dir. + void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); + /// + /// Retrieves the command-line arguments associated with a Shell link object + /// + /// The PSZ args. + /// The CCH max path. + void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath); + /// + /// Sets the command-line arguments for a Shell link object + /// + /// The PSZ args. + void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); + /// + /// Retrieves the hot key for a Shell link object + /// + /// The pw hotkey. + void GetHotkey(out short pwHotkey); + /// + /// Sets a hot key for a Shell link object + /// + /// The w hotkey. + void SetHotkey(short wHotkey); + /// + /// Retrieves the show command for a Shell link object + /// + /// The pi show CMD. + void GetShowCmd(out int piShowCmd); + /// + /// Sets the show command for a Shell link object. The show command sets the initial show state of the window. + /// + /// The i show CMD. + void SetShowCmd(int iShowCmd); + /// + /// Retrieves the location (path and index) of the icon for a Shell link object + /// + /// The PSZ icon path. + /// The CCH icon path. + /// The pi icon. + void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, + int cchIconPath, out int piIcon); + /// + /// Sets the location (path and index) of the icon for a Shell link object + /// + /// The PSZ icon path. + /// The i icon. + void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); + /// + /// Sets the relative path to the Shell link object + /// + /// The PSZ path rel. + /// The dw reserved. + void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved); + /// + /// Attempts to find the target of a Shell link, even if it has been moved or renamed + /// + /// The HWND. + /// The f flags. + void Resolve(IntPtr hwnd, SLR_FLAGS fFlags); + /// + /// Sets the path and file name of a Shell link object + /// + /// The PSZ file. + void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); + + } + + /// + /// Interface IPersist + /// + [ComImport, Guid("0000010c-0000-0000-c000-000000000046"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IPersist + { + /// + /// Gets the class ID. + /// + /// The p class ID. + [PreserveSig] + void GetClassID(out Guid pClassID); + } + + /// + /// Interface IPersistFile + /// + [ComImport, Guid("0000010b-0000-0000-C000-000000000046"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IPersistFile : IPersist + { + /// + /// Gets the class ID. + /// + /// The p class ID. + new void GetClassID(out Guid pClassID); + /// + /// Determines whether this instance is dirty. + /// + [PreserveSig] + int IsDirty(); + + /// + /// Loads the specified PSZ file name. + /// + /// Name of the PSZ file. + /// The dw mode. + [PreserveSig] + void Load([In, MarshalAs(UnmanagedType.LPWStr)] + string pszFileName, uint dwMode); + + /// + /// Saves the specified PSZ file name. + /// + /// Name of the PSZ file. + /// if set to true [remember]. + [PreserveSig] + void Save([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName, + [In, MarshalAs(UnmanagedType.Bool)] bool remember); + + /// + /// Saves the completed. + /// + /// Name of the PSZ file. + [PreserveSig] + void SaveCompleted([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName); + + /// + /// Gets the cur file. + /// + /// Name of the PPSZ file. + [PreserveSig] + void GetCurFile([In, MarshalAs(UnmanagedType.LPWStr)] string ppszFileName); + } + + // CLSID_ShellLink from ShlGuid.h + /// + /// Class ShellLink + /// + [ + ComImport, + Guid("00021401-0000-0000-C000-000000000046") + ] + public class ShellLink + { + } +} -- cgit v1.2.3 From 9807448fce0bba3b1aaf9fcb249efc5efe7b3146 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Apr 2016 14:38:36 -0400 Subject: update sleep prevention --- .../People/MovieDbPersonProvider.cs | 2 +- MediaBrowser.Server.Mono/Native/BaseMonoApp.cs | 5 +++ .../EntryPoints/KeepServerAwake.cs | 31 ++++++++--------- MediaBrowser.Server.Startup.Common/INativeApp.cs | 2 ++ MediaBrowser.ServerApplication/MainStartup.cs | 5 +++ MediaBrowser.ServerApplication/Native/Standby.cs | 40 ++++++++++++++-------- .../Native/WindowsApp.cs | 8 ++++- MediaBrowser.ServerApplication/ServerNotifyIcon.cs | 7 +++- 8 files changed, 67 insertions(+), 33 deletions(-) (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs index 2b37d0462..40ce6ad47 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs @@ -97,7 +97,7 @@ namespace MediaBrowser.Providers.People var requestCount = _requestCount; - if (requestCount >= 30) + if (requestCount >= 40) { //_logger.Debug("Throttling Tmdb people"); diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index 6d19c3275..72c191121 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -69,6 +69,11 @@ namespace MediaBrowser.Server.Mono.Native } + public void AllowSystemStandby() + { + + } + public List GetAssembliesWithParts() { var list = new List(); diff --git a/MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs b/MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs index 20d4c6b2a..dbfd6f4e8 100644 --- a/MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs +++ b/MediaBrowser.Server.Startup.Common/EntryPoints/KeepServerAwake.cs @@ -27,28 +27,27 @@ namespace MediaBrowser.Server.Startup.Common.EntryPoints _timer = new PeriodicTimer(obj => { var now = DateTime.UtcNow; - if (_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 15)) + var nativeApp = ((ApplicationHost)_appHost).NativeApp; + + try + { + if (_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 15)) + { + nativeApp.PreventSystemStandby(); + } + else + { + nativeApp.AllowSystemStandby(); + } + } + catch (Exception ex) { - KeepAlive(); + _logger.ErrorException("Error resetting system standby timer", ex); } }, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); } - private void KeepAlive() - { - var nativeApp = ((ApplicationHost)_appHost).NativeApp; - - try - { - nativeApp.PreventSystemStandby(); - } - catch (Exception ex) - { - _logger.ErrorException("Error resetting system standby timer", ex); - } - } - public void Dispose() { if (_timer != null) diff --git a/MediaBrowser.Server.Startup.Common/INativeApp.cs b/MediaBrowser.Server.Startup.Common/INativeApp.cs index 121d4192e..00f987d3c 100644 --- a/MediaBrowser.Server.Startup.Common/INativeApp.cs +++ b/MediaBrowser.Server.Startup.Common/INativeApp.cs @@ -93,6 +93,8 @@ namespace MediaBrowser.Server.Startup.Common /// void PreventSystemStandby(); + void AllowSystemStandby(); + /// /// Gets the power management. /// diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index f83c7d545..4dc8a47f5 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -321,6 +321,11 @@ namespace MediaBrowser.ServerApplication } } + public static void Invoke(Action action) + { + _serverNotifyIcon.Invoke(action); + } + /// /// Starts the service. /// diff --git a/MediaBrowser.ServerApplication/Native/Standby.cs b/MediaBrowser.ServerApplication/Native/Standby.cs index 274c72b25..919709538 100644 --- a/MediaBrowser.ServerApplication/Native/Standby.cs +++ b/MediaBrowser.ServerApplication/Native/Standby.cs @@ -1,4 +1,5 @@ -using System.Runtime.InteropServices; +using System; +using System.Runtime.InteropServices; namespace MediaBrowser.ServerApplication.Native { @@ -7,11 +8,33 @@ namespace MediaBrowser.ServerApplication.Native /// public static class Standby { - public static void PreventSystemStandby() + public static void PreventSleepAndMonitorOff() { - SystemHelper.ResetStandbyTimer(); + NativeMethods.SetThreadExecutionState(NativeMethods.ES_CONTINUOUS | NativeMethods.ES_SYSTEM_REQUIRED | NativeMethods.ES_DISPLAY_REQUIRED); } + public static void PreventSleep() + { + NativeMethods.SetThreadExecutionState(NativeMethods.ES_CONTINUOUS | NativeMethods.ES_SYSTEM_REQUIRED); + } + + // Clear EXECUTION_STATE flags to allow the system to sleep and turn off monitor normally + public static void AllowSleep() + { + NativeMethods.SetThreadExecutionState(NativeMethods.ES_CONTINUOUS); + } + + internal static class NativeMethods + { + // Import SetThreadExecutionState Win32 API and necessary flags + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + public static extern uint SetThreadExecutionState(uint esFlags); + public const uint ES_CONTINUOUS = 0x80000000; + public const uint ES_SYSTEM_REQUIRED = 0x00000001; + public const uint ES_DISPLAY_REQUIRED = 0x00000002; + } + + [Flags] internal enum EXECUTION_STATE : uint { ES_NONE = 0, @@ -21,16 +44,5 @@ namespace MediaBrowser.ServerApplication.Native ES_AWAYMODE_REQUIRED = 0x00000040, ES_CONTINUOUS = 0x80000000 } - - public class SystemHelper - { - [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] - static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); - - public static void ResetStandbyTimer() - { - EXECUTION_STATE es = SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED); - } - } } } diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 146a4372b..ff5fe4d84 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -5,6 +5,7 @@ using MediaBrowser.ServerApplication.Networking; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Windows.Forms; using CommonIO; using MediaBrowser.Controller.Power; using MediaBrowser.Server.Startup.Common.FFMpeg; @@ -134,7 +135,12 @@ namespace MediaBrowser.ServerApplication.Native public void PreventSystemStandby() { - Standby.PreventSystemStandby(); + MainStartup.Invoke(Standby.PreventSleep); + } + + public void AllowSystemStandby() + { + MainStartup.Invoke(Standby.AllowSleep); } public IPowerManagement GetPowerManagement() diff --git a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs index 673c6cddd..2146274af 100644 --- a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs +++ b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs @@ -36,10 +36,15 @@ namespace MediaBrowser.ServerApplication set { Action act = () => notifyIcon1.Visible = false; - contextMenuStrip1.Invoke(act); + Invoke(act); } } + public void Invoke(Action action) + { + contextMenuStrip1.Invoke(action); + } + public ServerNotifyIcon(ILogManager logManager, IServerApplicationHost appHost, IServerConfigurationManager configurationManager, -- cgit v1.2.3 From ebf0eeb3bd68cd5532e965167936537223521658 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Apr 2016 23:03:49 -0400 Subject: update browser launcher --- MediaBrowser.Controller/IServerApplicationHost.cs | 4 +- MediaBrowser.Server.Mono/Native/BaseMonoApp.cs | 5 ++ .../ApplicationHost.cs | 5 ++ .../Browser/BrowserLauncher.cs | 59 ++++++---------------- .../EntryPoints/StartupWizard.cs | 2 +- MediaBrowser.Server.Startup.Common/INativeApp.cs | 2 + MediaBrowser.ServerApplication/MainStartup.cs | 2 +- .../Native/WindowsApp.cs | 41 ++++++++++++++- MediaBrowser.ServerApplication/ServerNotifyIcon.cs | 8 +-- 9 files changed, 76 insertions(+), 52 deletions(-) (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index e4eecec18..65eed1a23 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.Controller public interface IServerApplicationHost : IApplicationHost { event EventHandler HasUpdateAvailableChanged; - + /// /// Gets the system info. /// @@ -86,5 +86,7 @@ namespace MediaBrowser.Controller /// The ip address. /// System.String. string GetLocalApiUrl(IPAddress ipAddress); + + void LaunchUrl(string url); } } diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index 72c191121..fbfef9a34 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -222,6 +222,11 @@ namespace MediaBrowser.Server.Mono.Native return GetInfo(Environment); } + public void LaunchUrl(string url) + { + throw new NotImplementedException(); + } + public static FFMpegInstallInfo GetInfo(NativeEnvironment environment) { var info = new FFMpegInstallInfo(); diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 93dbe2945..2e2b42ba2 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -1404,5 +1404,10 @@ namespace MediaBrowser.Server.Startup.Common return externalDns; } } + + public void LaunchUrl(string url) + { + NativeApp.LaunchUrl(url); + } } } diff --git a/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs b/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs index a4504f25a..db48d1110 100644 --- a/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs +++ b/MediaBrowser.Server.Startup.Common/Browser/BrowserLauncher.cs @@ -15,87 +15,58 @@ namespace MediaBrowser.Server.Startup.Common.Browser /// /// The page. /// The app host. - /// The logger. - public static void OpenDashboardPage(string page, IServerApplicationHost appHost, ILogger logger) + public static void OpenDashboardPage(string page, IServerApplicationHost appHost) { var url = appHost.GetLocalApiUrl("localhost") + "/web/" + page; - OpenUrl(url, logger); + OpenUrl(appHost, url); } /// /// Opens the community. /// - /// The logger. - public static void OpenCommunity(ILogger logger) + public static void OpenCommunity(IServerApplicationHost appHost) { - OpenUrl("http://emby.media/community", logger); + OpenUrl(appHost, "http://emby.media/community"); } /// /// Opens the web client. /// /// The app host. - /// The logger. - public static void OpenWebClient(IServerApplicationHost appHost, ILogger logger) + public static void OpenWebClient(IServerApplicationHost appHost) { - OpenDashboardPage("index.html", appHost, logger); + OpenDashboardPage("index.html", appHost); } /// /// Opens the dashboard. /// /// The app host. - /// The logger. - public static void OpenDashboard(IServerApplicationHost appHost, ILogger logger) + public static void OpenDashboard(IServerApplicationHost appHost) { - OpenDashboardPage("dashboard.html", appHost, logger); + OpenDashboardPage("dashboard.html", appHost); } /// /// Opens the URL. /// /// The URL. - /// The logger. - private static void OpenUrl(string url, ILogger logger) + private static void OpenUrl(IServerApplicationHost appHost, string url) { - var process = new Process - { - StartInfo = new ProcessStartInfo - { - FileName = url - }, - - EnableRaisingEvents = true, - }; - - process.Exited += ProcessExited; - try { - process.Start(); + appHost.LaunchUrl(url); + } + catch (NotImplementedException) + { + } catch (Exception ex) { - logger.ErrorException("Error launching url: {0}", ex, url); - - Console.WriteLine("Error launching url: {0}", ex.Message); + Console.WriteLine("Error launching url: " + url); Console.WriteLine(ex.Message); - -//#if !__MonoCS__ -// System.Windows.Forms.MessageBox.Show("There was an error launching your web browser. Please check your default browser settings."); -//#endif } } - - /// - /// 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.Server.Startup.Common/EntryPoints/StartupWizard.cs b/MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs index 854fa44c1..f9d173c59 100644 --- a/MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs +++ b/MediaBrowser.Server.Startup.Common/EntryPoints/StartupWizard.cs @@ -46,7 +46,7 @@ namespace MediaBrowser.Server.Startup.Common.EntryPoints /// private void LaunchStartupWizard() { - BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost, _logger); + BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost); } /// diff --git a/MediaBrowser.Server.Startup.Common/INativeApp.cs b/MediaBrowser.Server.Startup.Common/INativeApp.cs index 00f987d3c..c0758b47f 100644 --- a/MediaBrowser.Server.Startup.Common/INativeApp.cs +++ b/MediaBrowser.Server.Startup.Common/INativeApp.cs @@ -102,5 +102,7 @@ namespace MediaBrowser.Server.Startup.Common IPowerManagement GetPowerManagement(); FFMpegInstallInfo GetFfmpegInstallInfo(); + + void LaunchUrl(string url); } } diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index 4dc8a47f5..454c415a1 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -317,7 +317,7 @@ namespace MediaBrowser.ServerApplication { if (e.Reason == SessionSwitchReason.SessionLogon) { - BrowserLauncher.OpenDashboard(_appHost, _logger); + BrowserLauncher.OpenDashboard(_appHost); } } diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index ff5fe4d84..10cd59436 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -1,14 +1,17 @@ -using MediaBrowser.Common.Net; +using System; +using MediaBrowser.Common.Net; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Startup.Common; using MediaBrowser.ServerApplication.Networking; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Reflection; using System.Windows.Forms; using CommonIO; using MediaBrowser.Controller.Power; using MediaBrowser.Server.Startup.Common.FFMpeg; +using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem; namespace MediaBrowser.ServerApplication.Native { @@ -162,6 +165,42 @@ namespace MediaBrowser.ServerApplication.Native return info; } + public void LaunchUrl(string url) + { + 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); + + throw; + } + } + + /// + /// Processes the exited. + /// + /// The sender. + /// The instance containing the event data. + private static void ProcessExited(object sender, EventArgs e) + { + ((Process)sender).Dispose(); + } + private string[] GetDownloadUrls() { switch (Environment.SystemArchitecture) diff --git a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs index 2146274af..27816db5a 100644 --- a/MediaBrowser.ServerApplication/ServerNotifyIcon.cs +++ b/MediaBrowser.ServerApplication/ServerNotifyIcon.cs @@ -168,7 +168,7 @@ namespace MediaBrowser.ServerApplication void notifyIcon1_DoubleClick(object sender, EventArgs e) { - BrowserLauncher.OpenDashboard(_appHost, _logger); + BrowserLauncher.OpenDashboard(_appHost); } private void LocalizeText() @@ -199,17 +199,17 @@ namespace MediaBrowser.ServerApplication void cmdBrowse_Click(object sender, EventArgs e) { - BrowserLauncher.OpenWebClient(_appHost, _logger); + BrowserLauncher.OpenWebClient(_appHost); } void cmdCommunity_Click(object sender, EventArgs e) { - BrowserLauncher.OpenCommunity(_logger); + BrowserLauncher.OpenCommunity(_appHost); } void cmdConfigure_Click(object sender, EventArgs e) { - BrowserLauncher.OpenDashboard(_appHost, _logger); + BrowserLauncher.OpenDashboard(_appHost); } void cmdRestart_Click(object sender, EventArgs e) -- cgit v1.2.3 From a4d1c9e6e48f63121cc51abda61ed46d7f6a72cf Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 1 May 2016 17:48:37 -0400 Subject: update sqlite --- .../Notifications/INotificationsRepository.cs | 6 - .../Persistence/IDisplayPreferencesRepository.cs | 6 - .../Persistence/IItemRepository.cs | 6 - .../Persistence/IUserDataRepository.cs | 6 - .../Providers/IProviderRepository.cs | 6 - .../Activity/ActivityRepository.cs | 4 +- .../MediaBrowser.Server.Implementations.csproj | 6 +- .../Notifications/SqliteNotificationsRepository.cs | 4 +- .../Persistence/DataExtensions.cs | 182 +++++++++++++++++ .../Persistence/IDbConnector.cs | 10 + .../SqliteDisplayPreferencesRepository.cs | 4 +- .../Persistence/SqliteExtensions.cs | 218 --------------------- .../SqliteFileOrganizationRepository.cs | 4 +- .../Persistence/SqliteProviderInfoRepository.cs | 4 +- .../Persistence/SqliteUserDataRepository.cs | 4 +- .../Persistence/SqliteUserRepository.cs | 6 +- .../Security/AuthenticationRepository.cs | 4 +- .../Social/SharingRepository.cs | 4 +- .../Sync/SyncRepository.cs | 4 +- .../MediaBrowser.Server.Mono.csproj | 5 + MediaBrowser.Server.Mono/Native/BaseMonoApp.cs | 11 +- MediaBrowser.Server.Mono/Native/NativeApp.cs | 7 +- .../Native/SqliteExtensions.cs | 62 ++++++ MediaBrowser.Server.Mono/Program.cs | 2 +- .../ApplicationHost.cs | 55 ++---- MediaBrowser.Server.Startup.Common/INativeApp.cs | 3 + .../MediaBrowser.ServerApplication.csproj | 25 +-- .../Native/SqliteExtensions.cs | 62 ++++++ .../Native/WindowsApp.cs | 6 + MediaBrowser.ServerApplication/packages.config | 2 +- 30 files changed, 401 insertions(+), 327 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs create mode 100644 MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs delete mode 100644 MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs create mode 100644 MediaBrowser.Server.Mono/Native/SqliteExtensions.cs create mode 100644 MediaBrowser.ServerApplication/Native/SqliteExtensions.cs (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Controller/Notifications/INotificationsRepository.cs b/MediaBrowser.Controller/Notifications/INotificationsRepository.cs index 6ad4a5377..cd587a509 100644 --- a/MediaBrowser.Controller/Notifications/INotificationsRepository.cs +++ b/MediaBrowser.Controller/Notifications/INotificationsRepository.cs @@ -19,12 +19,6 @@ namespace MediaBrowser.Controller.Notifications /// Occurs when [notifications marked read]. /// event EventHandler NotificationsMarkedRead; - - /// - /// Opens the connection to the repository - /// - /// Task. - Task Initialize(); /// /// Gets the notifications. diff --git a/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs b/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs index 17de730cb..abf96994f 100644 --- a/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs +++ b/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs @@ -11,12 +11,6 @@ namespace MediaBrowser.Controller.Persistence /// public interface IDisplayPreferencesRepository : IRepository { - /// - /// Opens the connection to the repository - /// - /// Task. - Task Initialize(); - /// /// Saves display preferences for an item /// diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 15df1f649..7bcc36958 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -13,12 +13,6 @@ namespace MediaBrowser.Controller.Persistence /// public interface IItemRepository : IRepository { - /// - /// Opens the connection to the repository - /// - /// Task. - Task Initialize(); - /// /// Saves an item /// diff --git a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs index 2a904be0d..2e165f416 100644 --- a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs +++ b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs @@ -11,12 +11,6 @@ namespace MediaBrowser.Controller.Persistence /// public interface IUserDataRepository : IRepository { - /// - /// Opens the connection to the repository - /// - /// Task. - Task Initialize(); - /// /// Saves the user data. /// diff --git a/MediaBrowser.Controller/Providers/IProviderRepository.cs b/MediaBrowser.Controller/Providers/IProviderRepository.cs index 1f77d0ca1..891275d77 100644 --- a/MediaBrowser.Controller/Providers/IProviderRepository.cs +++ b/MediaBrowser.Controller/Providers/IProviderRepository.cs @@ -21,11 +21,5 @@ namespace MediaBrowser.Controller.Providers /// The cancellation token. /// Task. Task SaveMetadataStatus(MetadataStatus status, CancellationToken cancellationToken); - - /// - /// Initializes this instance. - /// - /// Task. - Task Initialize(); } } diff --git a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs index 85ab76182..b0e05a5bc 100644 --- a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs +++ b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs @@ -27,11 +27,11 @@ namespace MediaBrowser.Server.Implementations.Activity _appPaths = appPaths; } - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "activitylog.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 43f5d741b..aff3a5e16 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -78,9 +78,6 @@ - - ..\ThirdParty\System.Data.SQLite.ManagedOnly\1.0.94.0\System.Data.SQLite.dll - @@ -261,6 +258,8 @@ + + @@ -275,7 +274,6 @@ - diff --git a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs index 7302431e1..cecf03ddf 100644 --- a/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs +++ b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs @@ -32,11 +32,11 @@ namespace MediaBrowser.Server.Implementations.Notifications _appPaths = appPaths; } - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "notifications.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs new file mode 100644 index 000000000..103b75f84 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs @@ -0,0 +1,182 @@ +using System.Text; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; +using System; +using System.Data; +using System.IO; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.Persistence +{ + static class DataExtensions + { + /// + /// Determines whether the specified conn is open. + /// + /// The conn. + /// true if the specified conn is open; otherwise, false. + public static bool IsOpen(this IDbConnection conn) + { + return conn.State == ConnectionState.Open; + } + + public static IDataParameter GetParameter(this IDbCommand cmd, int index) + { + return (IDataParameter)cmd.Parameters[index]; + } + + public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name, DbType type) + { + var param = cmd.CreateParameter(); + + param.ParameterName = name; + param.DbType = type; + + paramCollection.Add(param); + + return param; + } + + public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name) + { + var param = cmd.CreateParameter(); + + param.ParameterName = name; + + paramCollection.Add(param); + + return param; + } + + + /// + /// Gets a stream from a DataReader at a given ordinal + /// + /// The reader. + /// The ordinal. + /// Stream. + /// reader + public static Stream GetMemoryStream(this IDataReader reader, int ordinal) + { + if (reader == null) + { + throw new ArgumentNullException("reader"); + } + + var memoryStream = new MemoryStream(); + var num = 0L; + var array = new byte[4096]; + long bytes; + do + { + bytes = reader.GetBytes(ordinal, num, array, 0, array.Length); + memoryStream.Write(array, 0, (int)bytes); + num += bytes; + } + while (bytes > 0L); + memoryStream.Position = 0; + return memoryStream; + } + + /// + /// Runs the queries. + /// + /// The connection. + /// The queries. + /// The logger. + /// true if XXXX, false otherwise + /// queries + public static void RunQueries(this IDbConnection connection, string[] queries, ILogger logger) + { + if (queries == null) + { + throw new ArgumentNullException("queries"); + } + + using (var tran = connection.BeginTransaction()) + { + try + { + using (var cmd = connection.CreateCommand()) + { + foreach (var query in queries) + { + cmd.Transaction = tran; + cmd.CommandText = query; + cmd.ExecuteNonQuery(); + } + } + + tran.Commit(); + } + catch (Exception e) + { + logger.ErrorException("Error running queries", e); + tran.Rollback(); + throw; + } + } + } + + public static void Attach(IDbConnection db, string path, string alias) + { + using (var cmd = db.CreateCommand()) + { + cmd.CommandText = string.Format("attach '{0}' as {1};", path, alias); + cmd.ExecuteNonQuery(); + } + } + + /// + /// Serializes to bytes. + /// + /// The json. + /// The obj. + /// System.Byte[][]. + /// obj + public static byte[] SerializeToBytes(this IJsonSerializer json, object obj) + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + + using (var stream = new MemoryStream()) + { + json.SerializeToStream(obj, stream); + return stream.ToArray(); + } + } + + public static void AddColumn(this IDbConnection connection, ILogger logger, string table, string columnName, string type) + { + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "PRAGMA table_info(" + table + ")"; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + if (!reader.IsDBNull(1)) + { + var name = reader.GetString(1); + + if (string.Equals(name, columnName, StringComparison.OrdinalIgnoreCase)) + { + return; + } + } + } + } + } + + var builder = new StringBuilder(); + + builder.AppendLine("alter table " + table); + builder.AppendLine("add column " + columnName + " " + type); + + connection.RunQueries(new[] { builder.ToString() }, logger); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs new file mode 100644 index 000000000..cac9fe983 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs @@ -0,0 +1,10 @@ +using System.Data; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.Persistence +{ + public interface IDbConnector + { + Task Connect(string dbPath); + } +} diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs index 45e0304c1..6077cfdba 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs @@ -52,11 +52,11 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "displaypreferences.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs deleted file mode 100644 index 4fb1e07dd..000000000 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs +++ /dev/null @@ -1,218 +0,0 @@ -using System.Text; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Serialization; -using System; -using System.Data; -using System.Data.SQLite; -using System.IO; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.Persistence -{ - /// - /// Class SQLiteExtensions - /// - static class SqliteExtensions - { - /// - /// Determines whether the specified conn is open. - /// - /// The conn. - /// true if the specified conn is open; otherwise, false. - public static bool IsOpen(this IDbConnection conn) - { - return conn.State == ConnectionState.Open; - } - - public static IDataParameter GetParameter(this IDbCommand cmd, int index) - { - return (IDataParameter)cmd.Parameters[index]; - } - - public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name, DbType type) - { - var param = cmd.CreateParameter(); - - param.ParameterName = name; - param.DbType = type; - - paramCollection.Add(param); - - return param; - } - - public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name) - { - var param = cmd.CreateParameter(); - - param.ParameterName = name; - - paramCollection.Add(param); - - return param; - } - - - /// - /// Gets a stream from a DataReader at a given ordinal - /// - /// The reader. - /// The ordinal. - /// Stream. - /// reader - public static Stream GetMemoryStream(this IDataReader reader, int ordinal) - { - if (reader == null) - { - throw new ArgumentNullException("reader"); - } - - var memoryStream = new MemoryStream(); - var num = 0L; - var array = new byte[4096]; - long bytes; - do - { - bytes = reader.GetBytes(ordinal, num, array, 0, array.Length); - memoryStream.Write(array, 0, (int)bytes); - num += bytes; - } - while (bytes > 0L); - memoryStream.Position = 0; - return memoryStream; - } - - /// - /// Runs the queries. - /// - /// The connection. - /// The queries. - /// The logger. - /// true if XXXX, false otherwise - /// queries - public static void RunQueries(this IDbConnection connection, string[] queries, ILogger logger) - { - if (queries == null) - { - throw new ArgumentNullException("queries"); - } - - using (var tran = connection.BeginTransaction()) - { - try - { - using (var cmd = connection.CreateCommand()) - { - foreach (var query in queries) - { - cmd.Transaction = tran; - cmd.CommandText = query; - cmd.ExecuteNonQuery(); - } - } - - tran.Commit(); - } - catch (Exception e) - { - logger.ErrorException("Error running queries", e); - tran.Rollback(); - throw; - } - } - } - - /// - /// Connects to db. - /// - /// The db path. - /// The logger. - /// Task{IDbConnection}. - /// dbPath - public static async Task ConnectToDb(string dbPath, ILogger logger) - { - if (string.IsNullOrEmpty(dbPath)) - { - throw new ArgumentNullException("dbPath"); - } - - logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); - - var connectionstr = new SQLiteConnectionStringBuilder - { - PageSize = 4096, - CacheSize = 2000, - SyncMode = SynchronizationModes.Full, - DataSource = dbPath, - JournalMode = SQLiteJournalModeEnum.Wal - }; - - var connection = new SQLiteConnection(connectionstr.ConnectionString); - - await connection.OpenAsync().ConfigureAwait(false); - - return connection; - } - - public static void Attach(IDbConnection db, string path, string alias) - { - using (var cmd = db.CreateCommand()) - { - cmd.CommandText = string.Format("attach '{0}' as {1};", path, alias); - cmd.ExecuteNonQuery(); - } - } - - /// - /// Serializes to bytes. - /// - /// The json. - /// The obj. - /// System.Byte[][]. - /// obj - public static byte[] SerializeToBytes(this IJsonSerializer json, object obj) - { - if (obj == null) - { - throw new ArgumentNullException("obj"); - } - - using (var stream = new MemoryStream()) - { - json.SerializeToStream(obj, stream); - return stream.ToArray(); - } - } - - public static void AddColumn(this IDbConnection connection, ILogger logger, string table, string columnName, string type) - { - using (var cmd = connection.CreateCommand()) - { - cmd.CommandText = "PRAGMA table_info(" + table + ")"; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - while (reader.Read()) - { - if (!reader.IsDBNull(1)) - { - var name = reader.GetString(1); - - if (string.Equals(name, columnName, StringComparison.OrdinalIgnoreCase)) - { - return; - } - } - } - } - } - - var builder = new StringBuilder(); - - builder.AppendLine("alter table " + table); - builder.AppendLine("add column " + columnName + " " + type); - - connection.RunQueries(new[] { builder.ToString() }, logger); - } - } -} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs index 2d5aad04d..037776997 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs @@ -35,11 +35,11 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "fileorganization.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs index dbceda727..40d5c9586 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs @@ -39,11 +39,11 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "refreshinfo.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs index 63c41c71f..33a2b1187 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs @@ -37,11 +37,11 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "userdata_v2.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs index 9bd7e47f3..f7ca39a54 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs @@ -43,12 +43,12 @@ namespace MediaBrowser.Server.Implementations.Persistence /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "users.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); - + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); + string[] queries = { "create table if not exists users (guid GUID primary key, data BLOB)", diff --git a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs index b932f0cac..e8d9814ec 100644 --- a/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs +++ b/MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs @@ -27,11 +27,11 @@ namespace MediaBrowser.Server.Implementations.Security _appPaths = appPaths; } - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "authentication.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs b/MediaBrowser.Server.Implementations/Social/SharingRepository.cs index d6d7f021a..317743eb1 100644 --- a/MediaBrowser.Server.Implementations/Social/SharingRepository.cs +++ b/MediaBrowser.Server.Implementations/Social/SharingRepository.cs @@ -26,11 +26,11 @@ namespace MediaBrowser.Server.Implementations.Social /// Opens the connection to the database /// /// Task. - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "shares.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 965c081eb..6d31663b9 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -39,11 +39,11 @@ namespace MediaBrowser.Server.Implementations.Sync _appPaths = appPaths; } - public async Task Initialize() + public async Task Initialize(IDbConnector dbConnector) { var dbFile = Path.Combine(_appPaths.DataPath, "sync14.db"); - _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); string[] queries = { diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index 48d2df7ce..b71877e17 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -76,12 +76,17 @@ ..\ThirdParty\MediaBrowser.IsoMounting.Linux\MediaBrowser.IsoMounting.Linux.dll + + + ..\ThirdParty\System.Data.SQLite.ManagedOnly\1.0.94.0\System.Data.SQLite.dll + Properties\SharedVersion.cs + diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index fbfef9a34..a012a19a3 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Reflection; using System.Text.RegularExpressions; using MediaBrowser.Controller.Power; +using MediaBrowser.Server.Implementations.Persistence; using MediaBrowser.Server.Startup.Common.FFMpeg; using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem; @@ -17,9 +18,12 @@ namespace MediaBrowser.Server.Mono.Native public abstract class BaseMonoApp : INativeApp { protected StartupOptions StartupOptions { get; private set; } - protected BaseMonoApp(StartupOptions startupOptions) + protected ILogger Logger { get; private set; } + + protected BaseMonoApp(StartupOptions startupOptions, ILogger logger) { StartupOptions = startupOptions; + Logger = logger; } /// @@ -227,6 +231,11 @@ namespace MediaBrowser.Server.Mono.Native throw new NotImplementedException(); } + public IDbConnector GetDbConnector() + { + return new DbConnector(Logger); + } + public static FFMpegInstallInfo GetInfo(NativeEnvironment environment) { var info = new FFMpegInstallInfo(); diff --git a/MediaBrowser.Server.Mono/Native/NativeApp.cs b/MediaBrowser.Server.Mono/Native/NativeApp.cs index c73a96497..c0874a1d8 100644 --- a/MediaBrowser.Server.Mono/Native/NativeApp.cs +++ b/MediaBrowser.Server.Mono/Native/NativeApp.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Server.Startup.Common; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Startup.Common; namespace MediaBrowser.Server.Mono.Native { @@ -7,8 +8,8 @@ namespace MediaBrowser.Server.Mono.Native /// internal class NativeApp : BaseMonoApp { - public NativeApp(StartupOptions startupOptions) - : base(startupOptions) + public NativeApp(StartupOptions startupOptions, ILogger logger) + : base(startupOptions, logger) { } diff --git a/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs b/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs new file mode 100644 index 000000000..385a7d0c5 --- /dev/null +++ b/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs @@ -0,0 +1,62 @@ +using System; +using System.Data; +using System.Data.SQLite; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.Persistence; + +namespace MediaBrowser.Server.Mono.Native +{ + /// + /// Class SQLiteExtensions + /// + static class SqliteExtensions + { + /// + /// Connects to db. + /// + /// The db path. + /// The logger. + /// Task{IDbConnection}. + /// dbPath + public static async Task ConnectToDb(string dbPath, ILogger logger) + { + if (string.IsNullOrEmpty(dbPath)) + { + throw new ArgumentNullException("dbPath"); + } + + logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); + + var connectionstr = new SQLiteConnectionStringBuilder + { + PageSize = 4096, + CacheSize = 2000, + SyncMode = SynchronizationModes.Full, + DataSource = dbPath, + JournalMode = SQLiteJournalModeEnum.Wal + }; + + var connection = new SQLiteConnection(connectionstr.ConnectionString); + + await connection.OpenAsync().ConfigureAwait(false); + + return connection; + } + } + + public class DbConnector : IDbConnector + { + private readonly ILogger _logger; + + public DbConnector(ILogger logger) + { + _logger = logger; + } + + public Task Connect(string dbPath) + { + return SqliteExtensions.ConnectToDb(dbPath, _logger); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs index 2a0609449..32de45242 100644 --- a/MediaBrowser.Server.Mono/Program.cs +++ b/MediaBrowser.Server.Mono/Program.cs @@ -79,7 +79,7 @@ namespace MediaBrowser.Server.Mono var fileSystem = new ManagedFileSystem(new PatternsLogger(logManager.GetLogger("FileSystem")), false, false); fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); - var nativeApp = new NativeApp(options); + var nativeApp = new NativeApp(options, logManager.GetLogger("App")); _appHost = new ApplicationHost(appPaths, logManager, options, fileSystem, "emby.mono.zip", nativeApp); diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index fd6dee0f6..2d56a1575 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -410,13 +410,16 @@ namespace MediaBrowser.Server.Startup.Common UserRepository = await GetUserRepository().ConfigureAwait(false); RegisterSingleInstance(UserRepository); - DisplayPreferencesRepository = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths); + var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths); + DisplayPreferencesRepository = displayPreferencesRepo; RegisterSingleInstance(DisplayPreferencesRepository); - ItemRepository = new SqliteItemRepository(ApplicationPaths, JsonSerializer, LogManager); + var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager); + ItemRepository = itemRepo; RegisterSingleInstance(ItemRepository); - ProviderRepository = new SqliteProviderInfoRepository(LogManager, ApplicationPaths); + var providerRepo = new SqliteProviderInfoRepository(LogManager, ApplicationPaths); + ProviderRepository = providerRepo; RegisterSingleInstance(ProviderRepository); FileOrganizationRepository = await GetFileOrganizationRepository().ConfigureAwait(false); @@ -541,7 +544,7 @@ namespace MediaBrowser.Server.Startup.Common RegisterSingleInstance(NativeApp.GetPowerManagement()); var sharingRepo = new SharingRepository(LogManager, ApplicationPaths); - await sharingRepo.Initialize().ConfigureAwait(false); + await sharingRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); RegisterSingleInstance(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this)); RegisterSingleInstance(new SsdpHandler(LogManager.GetLogger("SsdpHandler"), ServerConfigurationManager, this)); @@ -557,9 +560,11 @@ namespace MediaBrowser.Server.Startup.Common SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager); RegisterSingleInstance(SubtitleEncoder); - - await ConfigureDisplayPreferencesRepositories().ConfigureAwait(false); - await ConfigureItemRepositories().ConfigureAwait(false); + + await displayPreferencesRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await itemRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await providerRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; await ConfigureUserDataRepositories().ConfigureAwait(false); await ConfigureNotificationsRepository().ConfigureAwait(false); progress.Report(100); @@ -658,7 +663,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); return repo; } @@ -677,7 +682,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new SqliteFileOrganizationRepository(LogManager, ServerConfigurationManager.ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); return repo; } @@ -686,7 +691,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new AuthenticationRepository(LogManager, ServerConfigurationManager.ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); return repo; } @@ -695,7 +700,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new ActivityRepository(LogManager, ServerConfigurationManager.ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); return repo; } @@ -704,7 +709,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new SyncRepository(LogManager, JsonSerializer, ServerConfigurationManager.ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); return repo; } @@ -717,35 +722,13 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); NotificationsRepository = repo; RegisterSingleInstance(NotificationsRepository); } - /// - /// Configures the repositories. - /// - /// Task. - private async Task ConfigureDisplayPreferencesRepositories() - { - await DisplayPreferencesRepository.Initialize().ConfigureAwait(false); - } - - /// - /// Configures the item repositories. - /// - /// Task. - private async Task ConfigureItemRepositories() - { - await ItemRepository.Initialize().ConfigureAwait(false); - - await ProviderRepository.Initialize().ConfigureAwait(false); - - ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; - } - /// /// Configures the user data repositories. /// @@ -754,7 +737,7 @@ namespace MediaBrowser.Server.Startup.Common { var repo = new SqliteUserDataRepository(LogManager, ApplicationPaths); - await repo.Initialize().ConfigureAwait(false); + await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); ((UserDataManager)UserDataManager).Repository = repo; } diff --git a/MediaBrowser.Server.Startup.Common/INativeApp.cs b/MediaBrowser.Server.Startup.Common/INativeApp.cs index c0758b47f..c13d3624e 100644 --- a/MediaBrowser.Server.Startup.Common/INativeApp.cs +++ b/MediaBrowser.Server.Startup.Common/INativeApp.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Logging; using System.Collections.Generic; using System.Reflection; using MediaBrowser.Controller.Power; +using MediaBrowser.Server.Implementations.Persistence; using MediaBrowser.Server.Startup.Common.FFMpeg; namespace MediaBrowser.Server.Startup.Common @@ -104,5 +105,7 @@ namespace MediaBrowser.Server.Startup.Common FFMpegInstallInfo GetFfmpegInstallInfo(); void LaunchUrl(string url); + + IDbConnector GetDbConnector(); } } diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 291e63dac..f544a149d 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -13,6 +13,8 @@ 512 ..\ + + AnyCPU @@ -81,9 +83,9 @@ - - False - ..\packages\System.Data.SQLite.Core.1.0.94.0\lib\net45\System.Data.SQLite.dll + + ..\packages\System.Data.SQLite.Core.1.0.101.0\lib\net46\System.Data.SQLite.dll + True @@ -112,6 +114,7 @@ + @@ -156,14 +159,6 @@ - - x64\SQLite.Interop.dll - PreserveNewest - - - x86\SQLite.Interop.dll - PreserveNewest - MediaBrowser.InstallUtil.dll PreserveNewest @@ -1116,6 +1111,13 @@ + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + - \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs new file mode 100644 index 000000000..1cde2ea13 --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs @@ -0,0 +1,62 @@ +using System; +using System.Data; +using System.Data.SQLite; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.Persistence; + +namespace MediaBrowser.ServerApplication.Native +{ + /// + /// Class SQLiteExtensions + /// + static class SqliteExtensions + { + /// + /// Connects to db. + /// + /// The db path. + /// The logger. + /// Task{IDbConnection}. + /// dbPath + public static async Task ConnectToDb(string dbPath, ILogger logger) + { + if (string.IsNullOrEmpty(dbPath)) + { + throw new ArgumentNullException("dbPath"); + } + + logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); + + var connectionstr = new SQLiteConnectionStringBuilder + { + PageSize = 4096, + CacheSize = 2000, + SyncMode = SynchronizationModes.Full, + DataSource = dbPath, + JournalMode = SQLiteJournalModeEnum.Wal + }; + + var connection = new SQLiteConnection(connectionstr.ConnectionString); + + await connection.OpenAsync().ConfigureAwait(false); + + return connection; + } + } + + public class DbConnector : IDbConnector + { + private readonly ILogger _logger; + + public DbConnector(ILogger logger) + { + _logger = logger; + } + + public Task Connect(string dbPath) + { + return SqliteExtensions.ConnectToDb(dbPath, _logger); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 10cd59436..808c7558e 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -10,6 +10,7 @@ using System.Reflection; using System.Windows.Forms; using CommonIO; using MediaBrowser.Controller.Power; +using MediaBrowser.Server.Implementations.Persistence; using MediaBrowser.Server.Startup.Common.FFMpeg; using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem; @@ -191,6 +192,11 @@ namespace MediaBrowser.ServerApplication.Native } } + public IDbConnector GetDbConnector() + { + return new DbConnector(_logger); + } + /// /// Processes the exited. /// diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index 1c86a02ae..2d4baae25 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -3,5 +3,5 @@ - + \ No newline at end of file -- cgit v1.2.3 From 99084edabeb1787f28496dffa55fbb260e34ae81 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 8 May 2016 23:13:38 -0400 Subject: update windows ffmpeg --- MediaBrowser.Api/ApiEntryPoint.cs | 8 ++- MediaBrowser.Api/LiveTv/LiveTvService.cs | 20 ++++++- MediaBrowser.Api/Movies/MoviesService.cs | 1 - MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs | 5 +- MediaBrowser.Api/UserLibrary/ItemsService.cs | 3 +- MediaBrowser.Controller/Entities/Audio/Audio.cs | 6 --- .../Entities/Audio/MusicAlbum.cs | 9 ++++ .../Entities/Audio/MusicArtist.cs | 9 ++++ MediaBrowser.Controller/Entities/BaseItem.cs | 11 ++++ MediaBrowser.Controller/Entities/Folder.cs | 49 +++++++++++------ MediaBrowser.Controller/Entities/IHasMetadata.cs | 2 + .../Entities/InternalItemsQuery.cs | 2 + MediaBrowser.Controller/Entities/MusicVideo.cs | 6 --- MediaBrowser.Controller/Entities/TV/Season.cs | 9 ++++ MediaBrowser.Controller/Entities/TV/Series.cs | 9 ++++ MediaBrowser.Controller/Entities/UserRootFolder.cs | 5 -- MediaBrowser.Controller/Playlists/Playlist.cs | 9 ++++ MediaBrowser.Model/LiveTv/ProgramQuery.cs | 3 ++ .../LiveTv/RecommendedProgramQuery.cs | 9 +++- MediaBrowser.Providers/Manager/MetadataService.cs | 61 +++++++++++++++++++-- .../Music/MusicBrainzArtistProvider.cs | 29 +++++++--- .../Dto/DtoService.cs | 33 ++++-------- .../Library/LibraryManager.cs | 14 +++-- .../LiveTv/EmbyTV/EmbyTV.cs | 18 ++++++- .../LiveTv/LiveTvManager.cs | 10 ++-- .../Persistence/SqliteItemRepository.cs | 62 ++++++++++++++++++++-- .../Sorting/DateLastMediaAddedComparer.cs | 8 +-- .../MediaBrowser.ServerApplication.csproj | 2 - .../Native/WindowsApp.cs | 17 ++++-- .../ffmpeg/ffmpegx64.7z.REMOVED.git-id | 1 - .../ffmpeg/ffmpegx86.7z.REMOVED.git-id | 1 - 31 files changed, 330 insertions(+), 101 deletions(-) delete mode 100644 MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id delete mode 100644 MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 66ca8c25d..a677bc600 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -488,13 +488,17 @@ namespace MediaBrowser.Api { try { - Logger.Info("Killing ffmpeg process for {0}", job.Path); + Logger.Info("Stopping ffmpeg process with q command for {0}", job.Path); //process.Kill(); process.StandardInput.WriteLine("q"); // Need to wait because killing is asynchronous - process.WaitForExit(5000); + if (!process.WaitForExit(5000)) + { + Logger.Info("Killing ffmpeg process for {0}", job.Path); + process.Kill(); + } } catch (Exception ex) { diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index ebcf8fbea..d3a4558c8 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -254,6 +254,8 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] public bool? EnableImages { get; set; } + public bool EnableTotalRecordCount { get; set; } + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int? ImageTypeLimit { get; set; } @@ -266,12 +268,24 @@ namespace MediaBrowser.Api.LiveTv /// The fields. [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Fields { get; set; } + + public GetPrograms() + { + EnableTotalRecordCount = true; + } } [Route("/LiveTv/Programs/Recommended", "GET", Summary = "Gets available live tv epgs..")] [Authenticated] public class GetRecommendedPrograms : IReturn>, IHasDtoOptions { + public bool EnableTotalRecordCount { get; set; } + + public GetRecommendedPrograms() + { + EnableTotalRecordCount = true; + } + [ApiMember(Name = "UserId", Description = "Optional filter by user id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string UserId { get; set; } @@ -662,7 +676,8 @@ namespace MediaBrowser.Api.LiveTv { ChannelIds = (request.ChannelIds ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToArray(), UserId = request.UserId, - HasAired = request.HasAired + HasAired = request.HasAired, + EnableTotalRecordCount = request.EnableTotalRecordCount }; if (!string.IsNullOrEmpty(request.MinStartDate)) @@ -709,7 +724,8 @@ namespace MediaBrowser.Api.LiveTv HasAired = request.HasAired, IsMovie = request.IsMovie, IsKids = request.IsKids, - IsSports = request.IsSports + IsSports = request.IsSports, + EnableTotalRecordCount = request.EnableTotalRecordCount }; var result = await _liveTvManager.GetRecommendedPrograms(query, GetDtoOptions(request), CancellationToken.None).ConfigureAwait(false); diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 9590971d0..786615cc3 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -196,7 +196,6 @@ namespace MediaBrowser.Api.Movies var parentIds = new string[] { }; var list = _libraryManager.GetItemList(query, parentIds) - .DistinctBy(i => i.PresentationUniqueKey, StringComparer.OrdinalIgnoreCase) .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N")) .ToList(); diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs index 6867f6308..aee1a8d54 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs @@ -12,6 +12,7 @@ namespace MediaBrowser.Api.UserLibrary protected BaseItemsRequest() { EnableImages = true; + EnableTotalRecordCount = true; } /// @@ -104,7 +105,9 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "IsInBoxSet", Description = "Optional filter by items that are in boxsets, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] public bool? IsInBoxSet { get; set; } - + + public bool EnableTotalRecordCount { get; set; } + /// /// Skips over a given number of items within the results. Use for paging. /// diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 7d2029cab..ff937078e 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -230,7 +230,8 @@ namespace MediaBrowser.Api.UserLibrary ParentId = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId), ParentIndexNumber = request.ParentIndexNumber, AiredDuringSeason = request.AiredDuringSeason, - AlbumArtistStartsWithOrGreater = request.AlbumArtistStartsWithOrGreater + AlbumArtistStartsWithOrGreater = request.AlbumArtistStartsWithOrGreater, + EnableTotalRecordCount = request.EnableTotalRecordCount }; if (!string.IsNullOrWhiteSpace(request.Ids)) diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index fd56a6746..c34a884ff 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -40,12 +40,6 @@ namespace MediaBrowser.Controller.Entities.Audio public List AlbumArtists { get; set; } - /// - /// Gets or sets the album. - /// - /// The album. - public string Album { get; set; } - [IgnoreDataMember] public bool IsThemeMedia { diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 5cb4e8c9d..615276e83 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -48,6 +48,15 @@ namespace MediaBrowser.Controller.Entities.Audio } } + [IgnoreDataMember] + public override bool SupportsCumulativeRunTimeTicks + { + get + { + return true; + } + } + [IgnoreDataMember] public List AllArtists { diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 6f6f124db..610497661 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -34,6 +34,15 @@ namespace MediaBrowser.Controller.Entities.Audio } } + [IgnoreDataMember] + public override bool SupportsCumulativeRunTimeTicks + { + get + { + return true; + } + } + [IgnoreDataMember] public override bool SupportsAddingToPlaylist { diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 2e968c880..cd021d2ab 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -69,6 +69,12 @@ namespace MediaBrowser.Controller.Entities public List ImageInfos { get; set; } + /// + /// Gets or sets the album. + /// + /// The album. + public string Album { get; set; } + /// /// Gets or sets the channel identifier. /// @@ -1175,6 +1181,11 @@ namespace MediaBrowser.Controller.Entities get { return Id.ToString("N"); } } + public virtual bool RequiresRefresh() + { + return false; + } + private string _userDataKey; /// /// Gets the user data key. diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 978fd7fed..457a0b3ab 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -28,6 +28,9 @@ namespace MediaBrowser.Controller.Entities public List ThemeSongIds { get; set; } public List ThemeVideoIds { get; set; } + [IgnoreDataMember] + public DateTime? DateLastMediaAdded { get; set; } + public Folder() { LinkedChildren = new List(); @@ -55,6 +58,36 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public virtual bool SupportsCumulativeRunTimeTicks + { + get + { + return false; + } + } + + [IgnoreDataMember] + public virtual bool SupportsDateLastMediaAdded + { + get + { + return false; + } + } + + public override bool RequiresRefresh() + { + var baseResult = base.RequiresRefresh(); + + if (SupportsCumulativeRunTimeTicks && !RunTimeTicks.HasValue) + { + baseResult = true; + } + + return baseResult; + } + [IgnoreDataMember] public override string FileNameWithoutExtension { @@ -789,11 +822,6 @@ namespace MediaBrowser.Controller.Entities Logger.Debug("Query requires post-filtering due to ItemSortBy.AiredEpisodeOrder"); return true; } - if (query.SortBy.Contains(ItemSortBy.Album, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.Album"); - return true; - } if (query.SortBy.Contains(ItemSortBy.AlbumArtist, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.AlbumArtist"); @@ -809,11 +837,6 @@ namespace MediaBrowser.Controller.Entities Logger.Debug("Query requires post-filtering due to ItemSortBy.Budget"); return true; } - if (query.SortBy.Contains(ItemSortBy.DateLastContentAdded, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.DateLastContentAdded"); - return true; - } if (query.SortBy.Contains(ItemSortBy.GameSystem, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.GameSystem"); @@ -1086,12 +1109,6 @@ namespace MediaBrowser.Controller.Entities return true; } - if (query.AlbumNames.Length > 0) - { - Logger.Debug("Query requires post-filtering due to AlbumNames"); - return true; - } - if (query.ArtistNames.Length > 0) { Logger.Debug("Query requires post-filtering due to ArtistNames"); diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs index 1f680b35f..c7940c8a9 100644 --- a/MediaBrowser.Controller/Entities/IHasMetadata.cs +++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs @@ -49,5 +49,7 @@ namespace MediaBrowser.Controller.Entities /// /// true if [supports people]; otherwise, false. bool SupportsPeople { get; } + + bool RequiresRefresh(); } } diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 385ee81e9..5236b0a27 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -137,10 +137,12 @@ namespace MediaBrowser.Controller.Entities public string AncestorWithPresentationUniqueKey { get; set; } public bool GroupByPresentationUniqueKey { get; set; } + public bool EnableTotalRecordCount { get; set; } public InternalItemsQuery() { GroupByPresentationUniqueKey = true; + EnableTotalRecordCount = true; AlbumNames = new string[] { }; ArtistNames = new string[] { }; diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs index bf4c2559c..7119828e2 100644 --- a/MediaBrowser.Controller/Entities/MusicVideo.cs +++ b/MediaBrowser.Controller/Entities/MusicVideo.cs @@ -9,12 +9,6 @@ namespace MediaBrowser.Controller.Entities { public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasProductionLocations, IHasBudget, IHasLookupInfo { - /// - /// Gets or sets the album. - /// - /// The album. - public string Album { get; set; } - /// /// Gets or sets the budget. /// diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 4e6128527..ac8cc0ee2 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -32,6 +32,15 @@ namespace MediaBrowser.Controller.Entities.TV } } + [IgnoreDataMember] + public override bool SupportsDateLastMediaAdded + { + get + { + return true; + } + } + [IgnoreDataMember] public override Guid? DisplayParentId { diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 680af1843..f8cdab8ce 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -48,6 +48,15 @@ namespace MediaBrowser.Controller.Entities.TV } } + [IgnoreDataMember] + public override bool SupportsDateLastMediaAdded + { + get + { + return true; + } + } + public bool DisplaySpecialsWithSeasons { get; set; } public List LocalTrailerIds { get; set; } diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index 8ce39c697..b9e997d17 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -102,10 +102,5 @@ namespace MediaBrowser.Controller.Entities LibraryManager.RegisterItem(item); } } - - public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user) - { - // Nothing meaninful here and will only waste resources - } } } diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index cd0c5dc1c..003cbcfcd 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -39,6 +39,15 @@ namespace MediaBrowser.Controller.Playlists } } + [IgnoreDataMember] + public override bool SupportsCumulativeRunTimeTicks + { + get + { + return true; + } + } + public override bool IsAuthorizedToDelete(User user) { return true; diff --git a/MediaBrowser.Model/LiveTv/ProgramQuery.cs b/MediaBrowser.Model/LiveTv/ProgramQuery.cs index 7a877e356..0141191c1 100644 --- a/MediaBrowser.Model/LiveTv/ProgramQuery.cs +++ b/MediaBrowser.Model/LiveTv/ProgramQuery.cs @@ -14,8 +14,11 @@ namespace MediaBrowser.Model.LiveTv ChannelIds = new string[] { }; SortBy = new string[] { }; Genres = new string[] { }; + EnableTotalRecordCount = true; } + public bool EnableTotalRecordCount { get; set; } + /// /// Fields to return within the items, in addition to basic information /// diff --git a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs index e83a8fda6..0e6d081a1 100644 --- a/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs +++ b/MediaBrowser.Model/LiveTv/RecommendedProgramQuery.cs @@ -13,7 +13,14 @@ namespace MediaBrowser.Model.LiveTv public bool? EnableImages { get; set; } public int? ImageTypeLimit { get; set; } public ImageType[] EnableImageTypes { get; set; } - + + public bool EnableTotalRecordCount { get; set; } + + public RecommendedProgramQuery() + { + EnableTotalRecordCount = true; + } + /// /// Gets or sets the user identifier. /// diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index ae48c996a..218127ab9 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -310,6 +310,11 @@ namespace MediaBrowser.Providers.Manager return true; } + if (item is MusicVideo) + { + return true; + } + return false; } @@ -390,7 +395,6 @@ namespace MediaBrowser.Providers.Manager return _cachedTask; } - private readonly Task _cachedResult = Task.FromResult(ItemUpdateType.None); /// /// Befores the save. /// @@ -398,9 +402,58 @@ namespace MediaBrowser.Providers.Manager /// if set to true [is full refresh]. /// Type of the current update. /// ItemUpdateType. - protected virtual Task BeforeSave(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) + protected virtual async Task BeforeSave(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) + { + var updateType = ItemUpdateType.None; + + updateType |= SaveCumulativeRunTimeTicks(item, isFullRefresh, currentUpdateType); + updateType |= SaveDateLastMediaAdded(item, isFullRefresh, currentUpdateType); + + return updateType; + } + + private ItemUpdateType SaveCumulativeRunTimeTicks(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) + { + var updateType = ItemUpdateType.None; + + if (isFullRefresh || currentUpdateType > ItemUpdateType.None) + { + var folder = item as Folder; + if (folder != null && folder.SupportsCumulativeRunTimeTicks) + { + var ticks = folder.GetRecursiveChildren(i => !i.IsFolder).Select(i => i.RunTimeTicks ?? 0).Sum(); + + if (!folder.RunTimeTicks.HasValue || folder.RunTimeTicks.Value != ticks) + { + folder.RunTimeTicks = ticks; + updateType = ItemUpdateType.MetadataEdit; + } + } + } + + return updateType; + } + + private ItemUpdateType SaveDateLastMediaAdded(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) { - return _cachedResult; + var updateType = ItemUpdateType.None; + + if (isFullRefresh || currentUpdateType > ItemUpdateType.None) + { + var folder = item as Folder; + if (folder != null && folder.SupportsDateLastMediaAdded) + { + var date = folder.GetRecursiveChildren(i => !i.IsFolder).Select(i => i.DateCreated).Max(); + + if (!folder.DateLastMediaAdded.HasValue || folder.DateLastMediaAdded.Value != date) + { + folder.DateLastMediaAdded = date; + updateType = ItemUpdateType.MetadataEdit; + } + } + } + + return updateType; } /// @@ -420,7 +473,7 @@ namespace MediaBrowser.Providers.Manager : status.DateLastMetadataRefresh ?? default(DateTime); // Run all if either of these flags are true - var runAllProviders = options.ReplaceAllMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || dateLastRefresh == default(DateTime); + var runAllProviders = options.ReplaceAllMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || dateLastRefresh == default(DateTime) || item.RequiresRefresh(); if (!runAllProviders) { diff --git a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs index ad900123e..2eb65f4e5 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs +++ b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs @@ -62,12 +62,25 @@ namespace MediaBrowser.Providers.Music private IEnumerable GetResultsFromResponse(XmlDocument doc) { - var ns = new XmlNamespaceManager(doc.NameTable); - ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#"); + //var ns = new XmlNamespaceManager(doc.NameTable); + //ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#"); var list = new List(); - var nodes = doc.SelectNodes("//mb:artist-list/mb:artist", ns); + var docElem = doc.DocumentElement; + + if (docElem == null) + { + return list; + } + + var artistList = docElem.FirstChild; + if (artistList == null) + { + return list; + } + + var nodes = artistList.ChildNodes; if (nodes != null) { @@ -79,11 +92,13 @@ namespace MediaBrowser.Providers.Music string mbzId = node.Attributes["id"].Value; - var nameNode = node.SelectSingleNode("//mb:name", ns); - - if (nameNode != null) + foreach (var child in node.ChildNodes.Cast()) { - name = nameNode.InnerText; + if (string.Equals(child.Name, "name", StringComparison.OrdinalIgnoreCase)) + { + name = node.InnerText; + break; + } } if (!string.IsNullOrWhiteSpace(mbzId) && !string.IsNullOrWhiteSpace(name)) diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 0aec3230d..32610a6ad 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -499,6 +499,16 @@ namespace MediaBrowser.Server.Implementations.Dto } } + if (fields.Contains(ItemFields.CumulativeRunTimeTicks)) + { + dto.CumulativeRunTimeTicks = dto.RunTimeTicks; + } + + if (fields.Contains(ItemFields.DateLastMediaAdded)) + { + dto.DateLastMediaAdded = folder.DateLastMediaAdded; + } + dto.UserData.Played = dto.UserData.PlayedPercentage.HasValue && dto.UserData.PlayedPercentage.Value >= 100; } @@ -1613,9 +1623,7 @@ namespace MediaBrowser.Server.Implementations.Dto { var recursiveItemCount = 0; var unplayed = 0; - long runtime = 0; - DateTime? dateLastMediaAdded = null; double totalPercentPlayed = 0; double totalSyncPercent = 0; var addSyncInfo = fields.Contains(ItemFields.SyncInfo); @@ -1632,15 +1640,6 @@ namespace MediaBrowser.Server.Implementations.Dto // Loop through each recursive child foreach (var child in children) { - if (!dateLastMediaAdded.HasValue) - { - dateLastMediaAdded = child.DateCreated; - } - else - { - dateLastMediaAdded = new[] { dateLastMediaAdded.Value, child.DateCreated }.Max(); - } - var userdata = _userDataRepository.GetUserData(user, child); recursiveItemCount++; @@ -1669,8 +1668,6 @@ namespace MediaBrowser.Server.Implementations.Dto unplayed++; } - runtime += child.RunTimeTicks ?? 0; - if (addSyncInfo) { double percent = 0; @@ -1709,16 +1706,6 @@ namespace MediaBrowser.Server.Implementations.Dto } } } - - if (runtime > 0 && fields.Contains(ItemFields.CumulativeRunTimeTicks)) - { - dto.CumulativeRunTimeTicks = runtime; - } - - if (fields.Contains(ItemFields.DateLastMediaAdded)) - { - dto.DateLastMediaAdded = dateLastMediaAdded; - } } /// diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index f9bf3446f..c95b30172 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1354,12 +1354,20 @@ namespace MediaBrowser.Server.Implementations.Library AddUserToQuery(query, query.User); } - var initialResult = ItemRepository.GetItemIds(query); + if (query.EnableTotalRecordCount) + { + var initialResult = ItemRepository.GetItemIds(query); + + return new QueryResult + { + TotalRecordCount = initialResult.TotalRecordCount, + Items = initialResult.Items.Select(GetItemById).Where(i => i != null).ToArray() + }; + } return new QueryResult { - TotalRecordCount = initialResult.TotalRecordCount, - Items = initialResult.Items.Select(GetItemById).Where(i => i != null).ToArray() + Items = ItemRepository.GetItemIdsList(query).Select(GetItemById).Where(i => i != null).ToArray() }; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index c5920d3d6..b5e8ad79a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -760,7 +760,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (info.IsMovie) { var customRecordingPath = config.MovieRecordingPath; - if ((string.IsNullOrWhiteSpace(customRecordingPath) || string.Equals(customRecordingPath, recordPath, StringComparison.OrdinalIgnoreCase)) && config.EnableRecordingSubfolders) + var allowSubfolder = true; + if (!string.IsNullOrWhiteSpace(customRecordingPath)) + { + allowSubfolder = string.Equals(customRecordingPath, recordPath, StringComparison.OrdinalIgnoreCase); + recordPath = customRecordingPath; + } + + if (allowSubfolder && config.EnableRecordingSubfolders) { recordPath = Path.Combine(recordPath, "Movies"); } @@ -775,7 +782,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV else if (info.IsSeries) { var customRecordingPath = config.SeriesRecordingPath; - if ((string.IsNullOrWhiteSpace(customRecordingPath) || string.Equals(customRecordingPath, recordPath, StringComparison.OrdinalIgnoreCase)) && config.EnableRecordingSubfolders) + var allowSubfolder = true; + if (!string.IsNullOrWhiteSpace(customRecordingPath)) + { + allowSubfolder = string.Equals(customRecordingPath, recordPath, StringComparison.OrdinalIgnoreCase); + recordPath = customRecordingPath; + } + + if (allowSubfolder && config.EnableRecordingSubfolders) { recordPath = Path.Combine(recordPath, "Series"); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index eec8328f8..175eed66c 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -886,7 +886,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv StartIndex = query.StartIndex, Limit = query.Limit, SortBy = query.SortBy, - SortOrder = query.SortOrder ?? SortOrder.Ascending + SortOrder = query.SortOrder ?? SortOrder.Ascending, + EnableTotalRecordCount = query.EnableTotalRecordCount }; if (query.HasAired.HasValue) @@ -924,7 +925,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv IsAiring = query.IsAiring, IsMovie = query.IsMovie, IsSports = query.IsSports, - IsKids = query.IsKids + IsKids = query.IsKids, + EnableTotalRecordCount = query.EnableTotalRecordCount }; if (query.HasAired.HasValue) @@ -1263,11 +1265,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv private async Task CleanDatabaseInternal(List currentIdList, string[] validTypes, IProgress progress, CancellationToken cancellationToken) { - var list = _itemRepo.GetItemIds(new InternalItemsQuery + var list = _itemRepo.GetItemIdsList(new InternalItemsQuery { IncludeItemTypes = validTypes - }).Items.ToList(); + }).ToList(); var numComplete = 0; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 09739f8a9..180bd3547 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -85,7 +85,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _updateInheritedRatingCommand; private IDbCommand _updateInheritedTagsCommand; - public const int LatestSchemaVersion = 76; + public const int LatestSchemaVersion = 77; /// /// Initializes a new instance of the class. @@ -235,6 +235,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(Logger, "TypedBaseItems", "SlugName", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "OriginalTitle", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "PrimaryVersionId", "Text"); + _connection.AddColumn(Logger, "TypedBaseItems", "DateLastMediaAdded", "DATETIME"); + _connection.AddColumn(Logger, "TypedBaseItems", "Album", "Text"); + _connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT"); string[] postQueries = @@ -351,7 +354,9 @@ namespace MediaBrowser.Server.Implementations.Persistence "TrailerTypes", "DateModifiedDuringLastRefresh", "OriginalTitle", - "PrimaryVersionId" + "PrimaryVersionId", + "DateLastMediaAdded", + "Album" }; private readonly string[] _mediaStreamSaveColumns = @@ -463,7 +468,9 @@ namespace MediaBrowser.Server.Implementations.Persistence "PresentationUniqueKey", "SlugName", "OriginalTitle", - "PrimaryVersionId" + "PrimaryVersionId", + "DateLastMediaAdded", + "Album" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -824,6 +831,18 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = null; } + var folder = item as Folder; + if (folder != null && folder.DateLastMediaAdded.HasValue) + { + _saveItemCommand.GetParameter(index++).Value = folder.DateLastMediaAdded.Value; + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + + _saveItemCommand.GetParameter(index++).Value = item.Album; + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -1217,6 +1236,17 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + var folder = item as Folder; + if (folder != null && !reader.IsDBNull(54)) + { + folder.DateLastMediaAdded = reader.GetDateTime(54).ToUniversalTime(); + } + + if (!reader.IsDBNull(55)) + { + item.Album = reader.GetString(55); + } + return item; } @@ -1777,6 +1807,10 @@ namespace MediaBrowser.Server.Implementations.Persistence { return new Tuple("played", false); } + if (string.Equals(name, ItemSortBy.DateLastContentAdded, StringComparison.OrdinalIgnoreCase)) + { + return new Tuple("DateLastMediaAdded", false); + } return new Tuple(name, false); } @@ -2484,7 +2518,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (query.MediaTypes.Length == 1) { whereClauses.Add("MediaType=@MediaTypes"); - cmd.Parameters.Add(cmd, "@MediaTypes", DbType.String).Value = query.MediaTypes[0].ToString(); + cmd.Parameters.Add(cmd, "@MediaTypes", DbType.String).Value = query.MediaTypes[0]; } if (query.MediaTypes.Length > 1) { @@ -2493,6 +2527,26 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("MediaType in (" + val + ")"); } + if (query.AlbumNames.Length > 0) + { + var clause = "("; + + var index = 0; + foreach (var name in query.AlbumNames) + { + if (index > 0) + { + clause += " OR "; + } + clause += "Album=@AlbumName" + index; + index++; + cmd.Parameters.Add(cmd, "@AlbumName" + index, DbType.String).Value = name; + } + + clause += ")"; + whereClauses.Add(clause); + } + //var enableItemsByName = query.IncludeItemsByName ?? query.IncludeItemTypes.Length > 0; var enableItemsByName = query.IncludeItemsByName ?? false; diff --git a/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs index 68cd44ec9..5c51f5e0f 100644 --- a/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs @@ -49,10 +49,10 @@ namespace MediaBrowser.Server.Implementations.Sorting if (folder != null) { - return folder.GetRecursiveChildren(User, i => !i.IsFolder) - .Select(i => i.DateCreated) - .OrderByDescending(i => i) - .FirstOrDefault(); + if (folder.DateLastMediaAdded.HasValue) + { + return folder.DateLastMediaAdded.Value; + } } return x.DateCreated; diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index f544a149d..366d4b608 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -142,8 +142,6 @@ - - diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 808c7558e..271b02d9a 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -158,9 +158,9 @@ namespace MediaBrowser.ServerApplication.Native info.FFMpegFilename = "ffmpeg.exe"; info.FFProbeFilename = "ffprobe.exe"; - info.Version = "20160401"; + info.Version = "20160508"; info.ArchiveType = "7z"; - info.IsEmbedded = true; + info.IsEmbedded = false; info.DownloadUrls = GetDownloadUrls(); return info; @@ -212,11 +212,18 @@ namespace MediaBrowser.ServerApplication.Native switch (Environment.SystemArchitecture) { case Architecture.X86_X64: - return new[] { "MediaBrowser.ServerApplication.ffmpeg.ffmpegx64.7z" }; + return new[] + { + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160508-win64.7z", + "https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20160508-git-caee88d-win64-static.7z" + }; case Architecture.X86: - return new[] { "MediaBrowser.ServerApplication.ffmpeg.ffmpegx86.7z" }; + return new[] + { + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160508-win32.7z", + "https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20160508-git-caee88d-win32-static.7z" + }; } - return new string[] { }; } } diff --git a/MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id b/MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id deleted file mode 100644 index b0542b75f..000000000 --- a/MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9dc10b022537738edce7eb71aa8dd4adbfee2c7b \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id b/MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id deleted file mode 100644 index 3939ec44d..000000000 --- a/MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -00fa1afa35fbd0a7e97ad7956e42ae17f6882f64 \ No newline at end of file -- cgit v1.2.3 From 673746621f7ed792c41dcd888a5b6e47b17ca2cb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 10 May 2016 12:18:05 -0400 Subject: fix DeviceDiscovery --- MediaBrowser.Controller/Entities/BaseItem.cs | 19 ------------------- MediaBrowser.Controller/Entities/IHasUserData.cs | 6 ------ MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs | 5 ----- .../Library/UserDataManager.cs | 9 +++++---- .../Sync/SyncJobProcessor.cs | 3 ++- MediaBrowser.ServerApplication/Native/WindowsApp.cs | 10 +++++----- 6 files changed, 12 insertions(+), 40 deletions(-) (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index cd021d2ab..1c8817afe 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1186,23 +1186,6 @@ namespace MediaBrowser.Controller.Entities return false; } - private string _userDataKey; - /// - /// Gets the user data key. - /// - /// System.String. - public string GetUserDataKey() - { - if (string.IsNullOrWhiteSpace(_userDataKey)) - { - var key = GetUserDataKeys().First(); - _userDataKey = key; - return key; - } - - return _userDataKey; - } - public virtual List GetUserDataKeys() { var list = new List(); @@ -1229,7 +1212,6 @@ namespace MediaBrowser.Controller.Entities public void AfterMetadataRefresh() { _sortName = null; - _userDataKey = null; } /// @@ -2074,7 +2056,6 @@ namespace MediaBrowser.Controller.Entities /// public virtual bool BeforeMetadataRefresh() { - _userDataKey = null; _sortName = null; var hasChanges = false; diff --git a/MediaBrowser.Controller/Entities/IHasUserData.cs b/MediaBrowser.Controller/Entities/IHasUserData.cs index 3e0fa3f1d..244b319bd 100644 --- a/MediaBrowser.Controller/Entities/IHasUserData.cs +++ b/MediaBrowser.Controller/Entities/IHasUserData.cs @@ -8,12 +8,6 @@ namespace MediaBrowser.Controller.Entities /// public interface IHasUserData : IHasId { - /// - /// Gets the user data key. - /// - /// System.String. - string GetUserDataKey(); - List GetUserDataKeys(); /// diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs index 5e0baa1f6..1eda79f02 100644 --- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs +++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs @@ -125,11 +125,6 @@ namespace MediaBrowser.Dlna.Ssdp args.EndPoint = endPoint; args.LocalEndPoint = new IPEndPoint(localIp, 0); - if (_ssdpHandler.IgnoreMessage(args, true)) - { - return; - } - _ssdpHandler.LogMessageReceived(args, true); TryCreateDevice(args); diff --git a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs index 0fabbf54a..f637160be 100644 --- a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs @@ -10,6 +10,7 @@ using MediaBrowser.Model.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -199,22 +200,22 @@ namespace MediaBrowser.Server.Implementations.Library public UserItemData GetUserData(IHasUserData user, IHasUserData item) { - return GetUserData(user.Id, item.GetUserDataKey()); + return GetUserData(user.Id, item.GetUserDataKeys().First()); } public UserItemData GetUserData(string userId, IHasUserData item) { - return GetUserData(userId, item.GetUserDataKey()); + return GetUserData(userId, item.GetUserDataKeys().First()); } public UserItemData GetUserData(Guid userId, IHasUserData item) { - return GetUserData(userId, item.GetUserDataKey()); + return GetUserData(userId, item.GetUserDataKeys().First()); } public UserItemDataDto GetUserDataDto(IHasUserData item, User user) { - var userData = GetUserData(user.Id, item.GetUserDataKey()); + var userData = GetUserData(user.Id, item.GetUserDataKeys().First()); var dto = GetUserItemDataDto(userData); item.FillUserDataDtoValues(dto, userData, user); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 379e2f056..bbba06870 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -345,7 +345,8 @@ namespace MediaBrowser.Server.Implementations.Sync if (!folder.IsPreSorted) { - items = items.OrderBy(i => i.SortName).ToArray(); + items = _libraryManager.Sort(items, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending) + .ToArray(); } return items; diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 271b02d9a..f5abcf336 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -158,7 +158,7 @@ namespace MediaBrowser.ServerApplication.Native info.FFMpegFilename = "ffmpeg.exe"; info.FFProbeFilename = "ffprobe.exe"; - info.Version = "20160508"; + info.Version = "20160410"; info.ArchiveType = "7z"; info.IsEmbedded = false; info.DownloadUrls = GetDownloadUrls(); @@ -214,14 +214,14 @@ namespace MediaBrowser.ServerApplication.Native case Architecture.X86_X64: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160508-win64.7z", - "https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20160508-git-caee88d-win64-static.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win64.7z", + "https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20160409-git-0c90b2e-win64-static.7z" }; case Architecture.X86: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160508-win32.7z", - "https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20160508-git-caee88d-win32-static.7z" + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win32.7z", + "https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20160409-git-0c90b2e-win32-static.7z" }; } return new string[] { }; -- cgit v1.2.3 From 93bf60c9e221564e5d0580174c9e45d135758fe7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 May 2016 13:51:49 -0400 Subject: add db connect logging --- MediaBrowser.ServerApplication/Native/SqliteExtensions.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs index 1cde2ea13..4e6c82495 100644 --- a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs +++ b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs @@ -54,9 +54,18 @@ namespace MediaBrowser.ServerApplication.Native _logger = logger; } - public Task Connect(string dbPath) + public async Task Connect(string dbPath) { - return SqliteExtensions.ConnectToDb(dbPath, _logger); + try + { + return await SqliteExtensions.ConnectToDb(dbPath, _logger).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error opening database {0}", ex, dbPath); + + throw; + } } } } \ No newline at end of file -- cgit v1.2.3 From 977f62336be3c54fc33b3476d80d3cce4c0b244c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 31 May 2016 14:07:54 -0400 Subject: update storage of genres, studios, tags, & keywords --- MediaBrowser.Api/ItemUpdateService.cs | 6 +--- MediaBrowser.Api/SimilarItemsHelper.cs | 8 +----- MediaBrowser.Controller/Entities/BaseItem.cs | 3 ++ MediaBrowser.Controller/Entities/IHasKeywords.cs | 31 -------------------- .../Entities/InternalItemsQuery.cs | 2 ++ .../Entities/KeywordExtensions.cs | 21 ++++++++++++++ MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 9 +----- MediaBrowser.Controller/Entities/Movies/Movie.cs | 4 +-- MediaBrowser.Controller/Entities/Trailer.cs | 4 +-- .../MediaBrowser.Controller.csproj | 2 +- .../Providers/BaseItemXmlParser.cs | 8 ++---- .../Savers/XmlSaverHelpers.cs | 18 +++++------- MediaBrowser.Providers/Manager/ProviderUtils.cs | 10 ++----- .../Movies/GenericMovieDbInfo.cs | 6 +--- .../Dto/DtoService.cs | 11 +------- .../Intros/DefaultIntroProvider.cs | 8 +----- .../Persistence/SqliteItemRepository.cs | 33 +++++++++++++++++----- .../Native/SqliteExtensions.cs | 2 +- .../Native/SqliteExtensions.cs | 2 +- MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs | 8 ++---- MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs | 8 ++---- 21 files changed, 78 insertions(+), 126 deletions(-) delete mode 100644 MediaBrowser.Controller/Entities/IHasKeywords.cs create mode 100644 MediaBrowser.Controller/Entities/KeywordExtensions.cs (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index 5bb4ed5f0..36e8a504c 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -298,11 +298,7 @@ namespace MediaBrowser.Api hasShortOverview.ShortOverview = request.ShortOverview; } - var hasKeywords = item as IHasKeywords; - if (hasKeywords != null) - { - hasKeywords.Keywords = request.Keywords; - } + item.Keywords = request.Keywords; if (request.Studios != null) { diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs index 277bba1dd..76bc16a96 100644 --- a/MediaBrowser.Api/SimilarItemsHelper.cs +++ b/MediaBrowser.Api/SimilarItemsHelper.cs @@ -127,13 +127,7 @@ namespace MediaBrowser.Api private static IEnumerable GetKeywords(BaseItem item) { - var hasTags = item as IHasKeywords; - if (hasTags != null) - { - return hasTags.Keywords; - } - - return new List(); + return item.Keywords; } /// diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 2a00ce992..78f1828ea 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -37,6 +37,7 @@ namespace MediaBrowser.Controller.Entities { protected BaseItem() { + Keywords = new List(); Tags = new List(); Genres = new List(); Studios = new List(); @@ -811,6 +812,8 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public List Tags { get; set; } + public List Keywords { get; set; } + /// /// Gets or sets the home page URL. /// diff --git a/MediaBrowser.Controller/Entities/IHasKeywords.cs b/MediaBrowser.Controller/Entities/IHasKeywords.cs deleted file mode 100644 index ab9eb4aee..000000000 --- a/MediaBrowser.Controller/Entities/IHasKeywords.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MediaBrowser.Controller.Entities -{ - public interface IHasKeywords - { - /// - /// Gets or sets the keywords. - /// - /// The keywords. - List Keywords { get; set; } - } - - public static class KeywordExtensions - { - public static void AddKeyword(this IHasKeywords item, string name) - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentNullException("name"); - } - - if (!item.Keywords.Contains(name, StringComparer.OrdinalIgnoreCase)) - { - item.Keywords.Add(name); - } - } - } -} diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 823f4066c..7e38d7ed9 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -33,6 +33,7 @@ namespace MediaBrowser.Controller.Entities public string[] ExcludeTags { get; set; } public string[] ExcludeInheritedTags { get; set; } public string[] Genres { get; set; } + public string[] Keywords { get; set; } public bool? IsMissing { get; set; } public bool? IsUnaired { get; set; } @@ -151,6 +152,7 @@ namespace MediaBrowser.Controller.Entities OfficialRatings = new string[] { }; SortBy = new string[] { }; MediaTypes = new string[] { }; + Keywords = new string[] { }; IncludeItemTypes = new string[] { }; ExcludeItemTypes = new string[] { }; Genres = new string[] { }; diff --git a/MediaBrowser.Controller/Entities/KeywordExtensions.cs b/MediaBrowser.Controller/Entities/KeywordExtensions.cs new file mode 100644 index 000000000..5c9afdf3d --- /dev/null +++ b/MediaBrowser.Controller/Entities/KeywordExtensions.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq; + +namespace MediaBrowser.Controller.Entities +{ + public static class KeywordExtensions + { + public static void AddKeyword(this BaseItem item, string name) + { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentNullException("name"); + } + + if (!item.Keywords.Contains(name, StringComparer.OrdinalIgnoreCase)) + { + item.Keywords.Add(name); + } + } + } +} diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 09a9d97bc..4effc162e 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Controller.Entities.Movies /// /// Class BoxSet /// - public class BoxSet : Folder, IHasTrailers, IHasKeywords, IHasDisplayOrder, IHasLookupInfo, IHasShares + public class BoxSet : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo, IHasShares { public List Shares { get; set; } @@ -26,7 +26,6 @@ namespace MediaBrowser.Controller.Entities.Movies RemoteTrailerIds = new List(); DisplayOrder = ItemSortBy.PremiereDate; - Keywords = new List(); Shares = new List(); } @@ -47,12 +46,6 @@ namespace MediaBrowser.Controller.Entities.Movies /// The remote trailers. public List RemoteTrailers { get; set; } - /// - /// Gets or sets the tags. - /// - /// The tags. - public List Keywords { get; set; } - /// /// Gets or sets the display order. /// diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 605221dcd..c7a833c58 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Controller.Entities.Movies /// /// Class Movie /// - public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping, IHasOriginalTitle + public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping, IHasOriginalTitle { public List SpecialFeatureIds { get; set; } @@ -32,7 +32,6 @@ namespace MediaBrowser.Controller.Entities.Movies ThemeSongIds = new List(); ThemeVideoIds = new List(); Taglines = new List(); - Keywords = new List(); ProductionLocations = new List(); } @@ -42,7 +41,6 @@ namespace MediaBrowser.Controller.Entities.Movies public List LocalTrailerIds { get; set; } public List RemoteTrailerIds { get; set; } - public List Keywords { get; set; } public List RemoteTrailers { get; set; } diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 74645bbe9..eab5ab679 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.Controller.Entities /// /// Class Trailer /// - public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTaglines, IHasMetascore, IHasOriginalTitle, IHasLookupInfo + public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasTaglines, IHasMetascore, IHasOriginalTitle, IHasLookupInfo { public List ProductionLocations { get; set; } @@ -31,8 +31,6 @@ namespace MediaBrowser.Controller.Entities public List RemoteTrailers { get; set; } - public List Keywords { get; set; } - [IgnoreDataMember] public bool IsLocalTrailer { diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 4d9999b37..b15bb94c7 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -142,7 +142,7 @@ - + diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index 1014fc2ee..aaa440060 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -816,11 +816,7 @@ namespace MediaBrowser.Controller.Providers { using (var subtree = reader.ReadSubtree()) { - var hasTags = item as IHasKeywords; - if (hasTags != null) - { - FetchFromKeywordsNode(subtree, hasTags); - } + FetchFromKeywordsNode(subtree, item); } break; } @@ -1099,7 +1095,7 @@ namespace MediaBrowser.Controller.Providers } } - private void FetchFromKeywordsNode(XmlReader reader, IHasKeywords item) + private void FetchFromKeywordsNode(XmlReader reader, BaseItem item) { reader.MoveToContent(); diff --git a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs index be81d21d2..ca19b403a 100644 --- a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs @@ -609,20 +609,16 @@ namespace MediaBrowser.LocalMetadata.Savers } } - var hasKeywords = item as IHasKeywords; - if (hasKeywords != null) + if (item.Keywords.Count > 0) { - if (hasKeywords.Keywords.Count > 0) - { - builder.Append(""); - - foreach (var tag in hasKeywords.Keywords) - { - builder.Append("" + SecurityElement.Escape(tag) + ""); - } + builder.Append(""); - builder.Append(""); + foreach (var tag in item.Keywords) + { + builder.Append("" + SecurityElement.Escape(tag) + ""); } + + builder.Append(""); } var people = libraryManager.GetPeople(item); diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs index 59a2da460..a6f02f3f7 100644 --- a/MediaBrowser.Providers/Manager/ProviderUtils.cs +++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs @@ -165,15 +165,9 @@ namespace MediaBrowser.Providers.Manager if (!lockedFields.Contains(MetadataFields.Keywords)) { - var sourceHasKeywords = source as IHasKeywords; - var targetHasKeywords = target as IHasKeywords; - - if (sourceHasKeywords != null && targetHasKeywords != null) + if (replaceData || target.Keywords.Count == 0) { - if (replaceData || targetHasKeywords.Keywords.Count == 0) - { - targetHasKeywords.Keywords = sourceHasKeywords.Keywords; - } + target.Keywords = source.Keywords; } } diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs index d13716cba..3b3065893 100644 --- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs +++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs @@ -314,11 +314,7 @@ namespace MediaBrowser.Providers.Movies if (movieData.keywords != null && movieData.keywords.keywords != null) { - var hasTags = movie as IHasKeywords; - if (hasTags != null) - { - hasTags.Keywords = movieData.keywords.keywords.Select(i => i.name).ToList(); - } + movie.Keywords = movieData.keywords.keywords.Select(i => i.name).ToList(); } if (movieData.trailers != null && movieData.trailers.youtube != null && diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index eb868d363..bfcdb2a26 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -983,16 +983,7 @@ namespace MediaBrowser.Server.Implementations.Dto if (fields.Contains(ItemFields.Keywords)) { - var hasTags = item as IHasKeywords; - if (hasTags != null) - { - dto.Keywords = hasTags.Keywords; - } - - if (dto.Keywords == null) - { - dto.Keywords = new List(); - } + dto.Keywords = item.Keywords; } if (fields.Contains(ItemFields.ProductionLocations)) diff --git a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs index 49012c65a..df128a90b 100644 --- a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs +++ b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs @@ -433,13 +433,7 @@ namespace MediaBrowser.Server.Implementations.Intros private static IEnumerable GetKeywords(BaseItem item) { - var hasTags = item as IHasKeywords; - if (hasTags != null) - { - return hasTags.Keywords; - } - - return new List(); + return item.Keywords; } public IEnumerable GetAllIntroFiles() diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 1de0ea710..a85bf1c81 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -87,7 +87,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _updateInheritedRatingCommand; private IDbCommand _updateInheritedTagsCommand; - public const int LatestSchemaVersion = 80; + public const int LatestSchemaVersion = 82; /// /// Initializes a new instance of the class. @@ -2489,8 +2489,8 @@ namespace MediaBrowser.Server.Implementations.Persistence var index = 0; foreach (var item in query.Genres) { - clauses.Add("Genres like @Genres" + index); - cmd.Parameters.Add(cmd, "@Genres" + index, DbType.String).Value = "%" + item + "%"; + clauses.Add("@Genre" + index + " in (select value from itemvalues where ItemId=Guid and Type=2)"); + cmd.Parameters.Add(cmd, "@Genre" + index, DbType.String).Value = item; index++; } var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; @@ -2503,8 +2503,8 @@ namespace MediaBrowser.Server.Implementations.Persistence var index = 0; foreach (var item in query.Tags) { - clauses.Add("Tags like @Tags" + index); - cmd.Parameters.Add(cmd, "@Tags" + index, DbType.String).Value = "%" + item + "%"; + clauses.Add("@Tag" + index + " in (select value from itemvalues where ItemId=Guid and Type=4)"); + cmd.Parameters.Add(cmd, "@Tag" + index, DbType.String).Value = item; index++; } var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; @@ -2517,8 +2517,22 @@ namespace MediaBrowser.Server.Implementations.Persistence var index = 0; foreach (var item in query.Studios) { - clauses.Add("Studios like @Studios" + index); - cmd.Parameters.Add(cmd, "@Studios" + index, DbType.String).Value = "%" + item + "%"; + clauses.Add("@Studio" + index + " in (select value from itemvalues where ItemId=Guid and Type=3)"); + cmd.Parameters.Add(cmd, "@Studio" + index, DbType.String).Value = item; + index++; + } + var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; + whereClauses.Add(clause); + } + + if (query.Keywords.Length > 0) + { + var clauses = new List(); + var index = 0; + foreach (var item in query.Keywords) + { + clauses.Add("@Keyword" + index + " in (select value from itemvalues where ItemId=Guid and Type=5)"); + cmd.Parameters.Add(cmd, "@Keyword" + index, DbType.String).Value = item; index++; } var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; @@ -3233,6 +3247,11 @@ namespace MediaBrowser.Server.Implementations.Persistence list.AddRange(hasAlbumArtist.AlbumArtists.Select(i => new Tuple(1, i))); } + list.AddRange(item.Genres.Select(i => new Tuple(2, i))); + list.AddRange(item.Studios.Select(i => new Tuple(3, i))); + list.AddRange(item.Tags.Select(i => new Tuple(4, i))); + list.AddRange(item.Keywords.Select(i => new Tuple(5, i))); + return list; } diff --git a/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs b/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs index 385a7d0c5..ca2327282 100644 --- a/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs +++ b/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs @@ -32,7 +32,7 @@ namespace MediaBrowser.Server.Mono.Native { PageSize = 4096, CacheSize = 2000, - SyncMode = SynchronizationModes.Full, + SyncMode = SynchronizationModes.Normal, DataSource = dbPath, JournalMode = SQLiteJournalModeEnum.Wal }; diff --git a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs index 4e6c82495..bdf5c3323 100644 --- a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs +++ b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs @@ -32,7 +32,7 @@ namespace MediaBrowser.ServerApplication.Native { PageSize = 4096, CacheSize = 2000, - SyncMode = SynchronizationModes.Full, + SyncMode = SynchronizationModes.Normal, DataSource = dbPath, JournalMode = SQLiteJournalModeEnum.Wal }; diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index d020a73fe..ad1c6802d 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -932,13 +932,9 @@ namespace MediaBrowser.XbmcMetadata.Parsers { var val = reader.ReadElementContentAsString(); - var hasKeywords = item as IHasKeywords; - if (hasKeywords != null) + if (!string.IsNullOrWhiteSpace(val)) { - if (!string.IsNullOrWhiteSpace(val)) - { - hasKeywords.AddKeyword(val); - } + item.AddKeyword(val); } break; } diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index d2e09d4eb..5bb9577ff 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -752,13 +752,9 @@ namespace MediaBrowser.XbmcMetadata.Savers } } - var hasKeywords = item as IHasKeywords; - if (hasKeywords != null) + foreach (var tag in item.Keywords) { - foreach (var tag in hasKeywords.Keywords) - { - writer.WriteElementString("plotkeyword", tag); - } + writer.WriteElementString("plotkeyword", tag); } var hasAwards = item as IHasAwards; -- cgit v1.2.3 From e1f562e16ff585b440a43029efe9db314b4de965 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 1 Jun 2016 01:50:00 -0400 Subject: calculate similarity at database level --- MediaBrowser.Api/GamesService.cs | 41 +++-- MediaBrowser.Api/Movies/MoviesService.cs | 114 +++++--------- MediaBrowser.Api/TvShowsService.cs | 41 +++-- .../Entities/InternalItemsQuery.cs | 2 + .../Persistence/IDbConnector.cs | 1 + .../Persistence/SqliteExtensions.cs | 175 +++++++++++++++++++++ .../Persistence/SqliteItemRepository.cs | 80 +++++++--- .../MediaBrowser.Server.Mono.csproj | 5 +- MediaBrowser.Server.Mono/Native/DbConnector.cs | 29 ++++ .../Native/SqliteExtensions.cs | 62 -------- .../MediaBrowser.ServerApplication.csproj | 5 +- .../Native/DbConnector.cs | 38 +++++ .../Native/SqliteExtensions.cs | 71 --------- 13 files changed, 409 insertions(+), 255 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs create mode 100644 MediaBrowser.Server.Mono/Native/DbConnector.cs delete mode 100644 MediaBrowser.Server.Mono/Native/SqliteExtensions.cs create mode 100644 MediaBrowser.ServerApplication/Native/DbConnector.cs delete mode 100644 MediaBrowser.ServerApplication/Native/SqliteExtensions.cs (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index 387771b6d..cb77e62ad 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using MediaBrowser.Model.Querying; namespace MediaBrowser.Api { @@ -187,18 +188,40 @@ namespace MediaBrowser.Api /// System.Object. public object Get(GetSimilarGames request) { + var result = GetSimilarItemsResult(request); + + return ToOptimizedSerializedResultUsingCache(result); + } + + private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) + { + var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; + + var item = string.IsNullOrEmpty(request.Id) ? + (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : + _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); + + var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user) + { + Limit = request.Limit, + IncludeItemTypes = new[] + { + typeof(Game).Name + }, + SimilarTo = item + + }).ToList(); + var dtoOptions = GetDtoOptions(request); - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, - _itemRepo, - _libraryManager, - _userDataRepository, - _dtoService, - Logger, - request, new[] { typeof(Game) }, - SimilarItemsHelper.GetSimiliarityScore); + var result = new QueryResult + { + Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), - return ToOptimizedSerializedResultUsingCache(result); + TotalRecordCount = itemsResult.Count + }; + + return result; } } } diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index ce36dd2ac..ff18d440c 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -111,18 +111,16 @@ namespace MediaBrowser.Api.Movies /// /// The request. /// System.Object. - public async Task Get(GetSimilarMovies request) + public object Get(GetSimilarMovies request) { - var result = await GetSimilarItemsResult( - request, SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); + var result = GetSimilarItemsResult(request); return ToOptimizedSerializedResultUsingCache(result); } - public async Task Get(GetSimilarTrailers request) + public object Get(GetSimilarTrailers request) { - var result = await GetSimilarItemsResult( - request, SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); + var result = GetSimilarItemsResult(request); return ToOptimizedSerializedResultUsingCache(result); } @@ -131,42 +129,16 @@ namespace MediaBrowser.Api.Movies { var user = _userManager.GetUserById(request.UserId); - var query = new InternalItemsQuery(user) - { - IncludeItemTypes = new[] - { - typeof(Movie).Name, - typeof(Trailer).Name, - //typeof(LiveTvProgram).Name - }, - // IsMovie = true - }; - - var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId }; - var movies = _libraryManager.GetItemList(query, parentIds) - .OrderBy(i => (int)i.SourceType); - - var listEligibleForSuggestion = new List(); - - var list = movies.ToList(); - - listEligibleForSuggestion.AddRange(list); - - listEligibleForSuggestion = listEligibleForSuggestion - .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) - .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase) - .ToList(); - var dtoOptions = GetDtoOptions(request); dtoOptions.Fields = request.GetItemFields().ToList(); - var result = GetRecommendationCategories(user, request.ParentId, listEligibleForSuggestion, request.CategoryLimit, request.ItemLimit, dtoOptions); + var result = GetRecommendationCategories(user, request.ParentId, request.CategoryLimit, request.ItemLimit, dtoOptions); return ToOptimizedResult(result); } - private async Task GetSimilarItemsResult(BaseGetSimilarItemsFromItem request, Func, List, BaseItem, int> getSimilarityScore) + private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; @@ -174,57 +146,32 @@ namespace MediaBrowser.Api.Movies (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); - var query = new InternalItemsQuery(user) + var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user) { + Limit = request.Limit, IncludeItemTypes = new[] { - typeof(Movie).Name, - typeof(Trailer).Name, - //typeof(LiveTvProgram).Name + typeof(Movie).Name, + typeof(Trailer).Name, + typeof(LiveTvProgram).Name }, - //IsMovie = true - }; - - var list = _libraryManager.GetItemList(query) - .OrderBy(i => (int)i.SourceType) - .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N")) - .ToList(); - - if (item is Video) - { - var imdbId = item.GetProviderId(MetadataProviders.Imdb); - - // Use imdb id to try to filter duplicates of the same item - if (!string.IsNullOrWhiteSpace(imdbId)) - { - list = list - .Where(i => !string.Equals(imdbId, i.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase)) - .ToList(); - } - } - - var items = SimilarItemsHelper.GetSimilaritems(item, _libraryManager, list, getSimilarityScore).ToList(); - - IEnumerable returnItems = items; - - if (request.Limit.HasValue) - { - returnItems = returnItems.Take(request.Limit.Value); - } + IsMovie = true, + SimilarTo = item + }).ToList(); var dtoOptions = GetDtoOptions(request); - var result = new ItemsResult + var result = new QueryResult { - Items = _dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ToArray(), + Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), - TotalRecordCount = items.Count + TotalRecordCount = itemsResult.Count }; return result; } - private IEnumerable GetRecommendationCategories(User user, string parentId, List allMovies, int categoryLimit, int itemLimit, DtoOptions dtoOptions) + private IEnumerable GetRecommendationCategories(User user, string parentId, int categoryLimit, int itemLimit, DtoOptions dtoOptions) { var categories = new List(); @@ -260,7 +207,7 @@ namespace MediaBrowser.Api.Movies IsFavoriteOrLiked = true, ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray() - }, parentIds); + }, parentIds).ToList(); var mostRecentMovies = recentlyPlayedMovies.Take(6).ToList(); // Get recently played directors @@ -273,8 +220,8 @@ namespace MediaBrowser.Api.Movies .OrderBy(i => Guid.NewGuid()) .ToList(); - var similarToRecentlyPlayed = GetSimilarTo(user, allMovies, recentlyPlayedMovies.Take(7).OrderBy(i => Guid.NewGuid()), itemLimit, dtoOptions, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator(); - var similarToLiked = GetSimilarTo(user, allMovies, likedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToLikedItem).GetEnumerator(); + var similarToRecentlyPlayed = GetSimilarTo(user, recentlyPlayedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator(); + var similarToLiked = GetSimilarTo(user, likedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToLikedItem).GetEnumerator(); var hasDirectorFromRecentlyPlayed = GetWithDirector(user, recentDirectors, itemLimit, dtoOptions, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator(); var hasActorFromRecentlyPlayed = GetWithActor(user, recentActors, itemLimit, dtoOptions, RecommendationType.HasActorFromRecentlyPlayed).GetEnumerator(); @@ -389,14 +336,23 @@ namespace MediaBrowser.Api.Movies } } - private IEnumerable GetSimilarTo(User user, List allMovies, IEnumerable baselineItems, int itemLimit, DtoOptions dtoOptions, RecommendationType type) + private IEnumerable GetSimilarTo(User user, List baselineItems, int itemLimit, DtoOptions dtoOptions, RecommendationType type) { foreach (var item in baselineItems) { - var similar = SimilarItemsHelper - .GetSimilaritems(item, _libraryManager, allMovies, SimilarItemsHelper.GetSimiliarityScore) - .Take(itemLimit) - .ToList(); + var similar = _libraryManager.GetItemList(new InternalItemsQuery(user) + { + Limit = itemLimit, + IncludeItemTypes = new[] + { + typeof(Movie).Name, + typeof(Trailer).Name, + typeof(LiveTvProgram).Name + }, + IsMovie = true, + SimilarTo = item + + }).ToList(); if (similar.Count > 0) { diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index aa0485d57..5ccfede1e 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -12,6 +12,7 @@ using ServiceStack; using System; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Model.Dto; namespace MediaBrowser.Api { @@ -273,18 +274,40 @@ namespace MediaBrowser.Api /// System.Object. public object Get(GetSimilarShows request) { + var result = GetSimilarItemsResult(request); + + return ToOptimizedSerializedResultUsingCache(result); + } + + private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) + { + var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; + + var item = string.IsNullOrEmpty(request.Id) ? + (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : + _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); + + var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user) + { + Limit = request.Limit, + IncludeItemTypes = new[] + { + typeof(Series).Name + }, + SimilarTo = item + + }).ToList(); + var dtoOptions = GetDtoOptions(request); - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, - _itemRepo, - _libraryManager, - _userDataManager, - _dtoService, - Logger, - request, new[] { typeof(Series) }, - SimilarItemsHelper.GetSimiliarityScore); + var result = new QueryResult + { + Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), - return ToOptimizedSerializedResultUsingCache(result); + TotalRecordCount = itemsResult.Count + }; + + return result; } public object Get(GetUpcomingEpisodes request) diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index f3f05a08f..0047a13b2 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -19,6 +19,8 @@ namespace MediaBrowser.Controller.Entities public User User { get; set; } + public BaseItem SimilarTo { get; set; } + public bool? IsFolder { get; set; } public bool? IsFavorite { get; set; } public bool? IsFavoriteOrLiked { get; set; } diff --git a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs index cac9fe983..985d79a0a 100644 --- a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs +++ b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs @@ -6,5 +6,6 @@ namespace MediaBrowser.Server.Implementations.Persistence public interface IDbConnector { Task Connect(string dbPath); + void BindSimilarityScoreFunction(IDbConnection connection); } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs new file mode 100644 index 000000000..5e07bac31 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SQLite; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; + +namespace MediaBrowser.Server.Implementations.Persistence +{ + /// + /// Class SQLiteExtensions + /// + public static class SqliteExtensions + { + /// + /// Connects to db. + /// + /// The db path. + /// The logger. + /// Task{IDbConnection}. + /// dbPath + public static async Task ConnectToDb(string dbPath, ILogger logger) + { + if (string.IsNullOrEmpty(dbPath)) + { + throw new ArgumentNullException("dbPath"); + } + + logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); + + var connectionstr = new SQLiteConnectionStringBuilder + { + PageSize = 4096, + CacheSize = 2000, + SyncMode = SynchronizationModes.Normal, + DataSource = dbPath, + JournalMode = SQLiteJournalModeEnum.Wal + }; + + var connection = new SQLiteConnection(connectionstr.ConnectionString); + + await connection.OpenAsync().ConfigureAwait(false); + + return connection; + } + + public static void BindGetSimilarityScore(IDbConnection connection, ILogger logger) + { + var sqlConnection = (SQLiteConnection) connection; + SimiliarToFunction.Logger = logger; + sqlConnection.BindFunction(new SimiliarToFunction()); + } + + public static void BindFunction(this SQLiteConnection connection, SQLiteFunction function) + { + var attributes = function.GetType().GetCustomAttributes(typeof(SQLiteFunctionAttribute), true).Cast().ToArray(); + if (attributes.Length == 0) + { + throw new InvalidOperationException("SQLiteFunction doesn't have SQLiteFunctionAttribute"); + } + connection.BindFunction(attributes[0], function); + } + } + + [SQLiteFunction(Name = "GetSimilarityScore", Arguments = 12, FuncType = FunctionType.Scalar)] + public class SimiliarToFunction : SQLiteFunction + { + internal static ILogger Logger; + + public override object Invoke(object[] args) + { + var score = 0; + + var inputOfficialRating = args[0] as string; + var rowOfficialRating = args[1] as string; + if (!string.IsNullOrWhiteSpace(inputOfficialRating) && string.Equals(inputOfficialRating, rowOfficialRating)) + { + score += 10; + } + + long? inputYear = args[2] == null ? (long?)null : (long)args[2]; + long? rowYear = args[3] == null ? (long?)null : (long)args[3]; + + if (inputYear.HasValue && rowYear.HasValue) + { + var diff = Math.Abs(inputYear.Value - rowYear.Value); + + // Add if they came out within the same decade + if (diff < 10) + { + score += 2; + } + + // And more if within five years + if (diff < 5) + { + score += 2; + } + } + + // genres + score += GetListScore(args, 4, 5); + + // tags + score += GetListScore(args, 6, 7); + + // keywords + score += GetListScore(args, 8, 9); + + // studios + score += GetListScore(args, 10, 11, 3); + + + // TODO: People + // var item2PeopleNames = allPeople.Where(i => i.ItemId == item2.Id) + //.Select(i => i.Name) + //.Where(i => !string.IsNullOrWhiteSpace(i)) + //.DistinctNames() + //.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); + + // points += item1People.Where(i => item2PeopleNames.ContainsKey(i.Name)).Sum(i => + // { + // if (string.Equals(i.Type, PersonType.Director, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Director, StringComparison.OrdinalIgnoreCase)) + // { + // return 5; + // } + // if (string.Equals(i.Type, PersonType.Actor, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Actor, StringComparison.OrdinalIgnoreCase)) + // { + // return 3; + // } + // if (string.Equals(i.Type, PersonType.Composer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Composer, StringComparison.OrdinalIgnoreCase)) + // { + // return 3; + // } + // if (string.Equals(i.Type, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase)) + // { + // return 3; + // } + // if (string.Equals(i.Type, PersonType.Writer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Writer, StringComparison.OrdinalIgnoreCase)) + // { + // return 2; + // } + + // return 1; + // }); + + // return points; + + //Logger.Debug("Returning score {0}", score); + return score; + } + + private int GetListScore(object[] args, int index1, int index2, int value = 10) + { + var score = 0; + + var inputGenres = args[index1] as string; + var rowGenres = args[index2] as string; + var inputGenreList = string.IsNullOrWhiteSpace(inputGenres) ? new string[] { } : inputGenres.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); + var rowGenresList = string.IsNullOrWhiteSpace(rowGenres) ? new string[] { } : rowGenres.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); + + foreach (var genre in inputGenreList) + { + if (rowGenresList.Contains(genre, StringComparer.OrdinalIgnoreCase)) + { + score += value; + } + } + + return score; + } + } +} diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 3149352a9..131158dd2 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -15,6 +15,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Runtime.Serialization; +using System.Text; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Extensions; @@ -258,6 +259,8 @@ namespace MediaBrowser.Server.Implementations.Persistence new MediaStreamColumns(_connection, Logger).AddColumns(); DataExtensions.Attach(_connection, Path.Combine(_config.ApplicationPaths.DataPath, "userdata_v2.db"), "UserDataDb"); + + dbConnector.BindSimilarityScoreFunction(_connection); } private readonly string[] _retriveItemColumns = @@ -1575,7 +1578,7 @@ namespace MediaBrowser.Server.Implementations.Persistence return false; } - private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] startColumns) + private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] startColumns, IDbCommand cmd) { var list = startColumns.ToList(); @@ -1590,6 +1593,45 @@ namespace MediaBrowser.Server.Implementations.Persistence list.Add("UserDataDb.UserData.rating"); } + if (query.SimilarTo != null) + { + var item = query.SimilarTo; + + var builder = new StringBuilder(); + builder.Append("GetSimilarityScore("); + + builder.Append("@ItemOfficialRating,"); + builder.Append("OfficialRating,"); + + builder.Append("@ItemProductionYear,"); + builder.Append("ProductionYear,"); + + builder.Append("@ItemGenres,"); + builder.Append("Genres,"); + + builder.Append("@ItemTags,"); + builder.Append("Tags,"); + + builder.Append("@ItemKeywords,"); + builder.Append("(select group_concat((Select Value from ItemValues where ItemId=Guid and Type=5), '|')),"); + + builder.Append("@ItemStudios,"); + builder.Append("Studios"); + builder.Append(") as SimilarityScore"); + + list.Add(builder.ToString()); + cmd.Parameters.Add(cmd, "@ItemOfficialRating", DbType.String).Value = item.OfficialRating; + cmd.Parameters.Add(cmd, "@ItemProductionYear", DbType.Int32).Value = item.ProductionYear ?? -1; + cmd.Parameters.Add(cmd, "@ItemGenres", DbType.String).Value = string.Join("|", item.Genres.ToArray()); + cmd.Parameters.Add(cmd, "@ItemTags", DbType.String).Value = string.Join("|", item.Tags.ToArray()); + cmd.Parameters.Add(cmd, "@ItemKeywords", DbType.String).Value = string.Join("|", item.Keywords.ToArray()); + cmd.Parameters.Add(cmd, "@ItemStudios", DbType.String).Value = string.Join("|", item.Studios.ToArray()); + + var excludeIds = query.ExcludeItemIds.ToList(); + excludeIds.Add(item.Id.ToString("N")); + query.ExcludeItemIds = excludeIds.ToArray(); + } + return list.ToArray(); } @@ -1616,7 +1658,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns)) + " from TypedBaseItems"; + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns, cmd)) + " from TypedBaseItems"; cmd.CommandText += GetJoinUserDataText(query); if (EnableJoinUserData(query)) @@ -1706,7 +1748,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns)) + " from TypedBaseItems"; + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns, cmd)) + " from TypedBaseItems"; cmd.CommandText += GetJoinUserDataText(query); if (EnableJoinUserData(query)) @@ -1789,6 +1831,15 @@ namespace MediaBrowser.Server.Implementations.Persistence private string GetOrderByText(InternalItemsQuery query) { + if (query.SimilarTo != null) + { + if (query.SortBy == null || query.SortBy.Length == 0) + { + query.SortBy = new[] { "SimilarityScore", "Random" }; + query.SortOrder = SortOrder.Descending; + } + } + if (query.SortBy == null || query.SortBy.Length == 0) { return string.Empty; @@ -1879,7 +1930,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" })) + " from TypedBaseItems"; + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" }, cmd)) + " from TypedBaseItems"; cmd.CommandText += GetJoinUserDataText(query); if (EnableJoinUserData(query)) @@ -2022,7 +2073,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" })) + " from TypedBaseItems"; + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" }, cmd)) + " from TypedBaseItems"; var whereClauses = GetWhereClauses(query, cmd); cmd.CommandText += GetJoinUserDataText(query); @@ -2148,24 +2199,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } else { - if (query.IsMovie.Value) - { - var typeClauses = new List(); - var typeIndex = 0; - foreach (var type in alternateTypes) - { - var paramName = "@AlternateType" + typeIndex.ToString(CultureInfo.InvariantCulture); - typeClauses.Add("Type=" + paramName); - cmd.Parameters.Add(cmd, paramName, DbType.String).Value = type; - typeIndex++; - } - - whereClauses.Add("(IsMovie=@IsMovie OR " + string.Join(" OR ", typeClauses.ToArray()) + ")"); - } - else - { - whereClauses.Add("(IsMovie is null OR IsMovie=@IsMovie)"); - } + whereClauses.Add("(IsMovie is null OR IsMovie=@IsMovie)"); } cmd.Parameters.Add(cmd, "@IsMovie", DbType.Boolean).Value = query.IsMovie; } diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index b71877e17..45071c9d9 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -82,11 +82,14 @@ + + Native\SqliteExtensions.cs + Properties\SharedVersion.cs - + diff --git a/MediaBrowser.Server.Mono/Native/DbConnector.cs b/MediaBrowser.Server.Mono/Native/DbConnector.cs new file mode 100644 index 000000000..536cd7322 --- /dev/null +++ b/MediaBrowser.Server.Mono/Native/DbConnector.cs @@ -0,0 +1,29 @@ +using System; +using System.Data; +using System.Data.SQLite; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.Persistence; + +namespace MediaBrowser.Server.Mono.Native +{ + public class DbConnector : IDbConnector + { + private readonly ILogger _logger; + + public DbConnector(ILogger logger) + { + _logger = logger; + } + + public void BindSimilarityScoreFunction(IDbConnection connection) + { + SqliteExtensions.BindGetSimilarityScore(connection, _logger); + } + + public Task Connect(string dbPath) + { + return SqliteExtensions.ConnectToDb(dbPath, _logger); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs b/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs deleted file mode 100644 index ca2327282..000000000 --- a/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Data; -using System.Data.SQLite; -using System.Threading.Tasks; -using MediaBrowser.Model.Logging; -using MediaBrowser.Server.Implementations.Persistence; - -namespace MediaBrowser.Server.Mono.Native -{ - /// - /// Class SQLiteExtensions - /// - static class SqliteExtensions - { - /// - /// Connects to db. - /// - /// The db path. - /// The logger. - /// Task{IDbConnection}. - /// dbPath - public static async Task ConnectToDb(string dbPath, ILogger logger) - { - if (string.IsNullOrEmpty(dbPath)) - { - throw new ArgumentNullException("dbPath"); - } - - logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); - - var connectionstr = new SQLiteConnectionStringBuilder - { - PageSize = 4096, - CacheSize = 2000, - SyncMode = SynchronizationModes.Normal, - DataSource = dbPath, - JournalMode = SQLiteJournalModeEnum.Wal - }; - - var connection = new SQLiteConnection(connectionstr.ConnectionString); - - await connection.OpenAsync().ConfigureAwait(false); - - return connection; - } - } - - public class DbConnector : IDbConnector - { - private readonly ILogger _logger; - - public DbConnector(ILogger logger) - { - _logger = logger; - } - - public Task Connect(string dbPath) - { - return SqliteExtensions.ConnectToDb(dbPath, _logger); - } - } -} \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 366d4b608..35660b2b1 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -97,6 +97,9 @@ + + Native\SqliteExtensions.cs + Properties\SharedVersion.cs @@ -114,7 +117,7 @@ - + diff --git a/MediaBrowser.ServerApplication/Native/DbConnector.cs b/MediaBrowser.ServerApplication/Native/DbConnector.cs new file mode 100644 index 000000000..f93cad62c --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/DbConnector.cs @@ -0,0 +1,38 @@ +using System; +using System.Data; +using System.Data.SQLite; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.Persistence; + +namespace MediaBrowser.ServerApplication.Native +{ + public class DbConnector : IDbConnector + { + private readonly ILogger _logger; + + public DbConnector(ILogger logger) + { + _logger = logger; + } + + public void BindSimilarityScoreFunction(IDbConnection connection) + { + SqliteExtensions.BindGetSimilarityScore(connection, _logger); + } + + public async Task Connect(string dbPath) + { + try + { + return await SqliteExtensions.ConnectToDb(dbPath, _logger).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error opening database {0}", ex, dbPath); + + throw; + } + } + } +} \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs deleted file mode 100644 index bdf5c3323..000000000 --- a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Data; -using System.Data.SQLite; -using System.Threading.Tasks; -using MediaBrowser.Model.Logging; -using MediaBrowser.Server.Implementations.Persistence; - -namespace MediaBrowser.ServerApplication.Native -{ - /// - /// Class SQLiteExtensions - /// - static class SqliteExtensions - { - /// - /// Connects to db. - /// - /// The db path. - /// The logger. - /// Task{IDbConnection}. - /// dbPath - public static async Task ConnectToDb(string dbPath, ILogger logger) - { - if (string.IsNullOrEmpty(dbPath)) - { - throw new ArgumentNullException("dbPath"); - } - - logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); - - var connectionstr = new SQLiteConnectionStringBuilder - { - PageSize = 4096, - CacheSize = 2000, - SyncMode = SynchronizationModes.Normal, - DataSource = dbPath, - JournalMode = SQLiteJournalModeEnum.Wal - }; - - var connection = new SQLiteConnection(connectionstr.ConnectionString); - - await connection.OpenAsync().ConfigureAwait(false); - - return connection; - } - } - - public class DbConnector : IDbConnector - { - private readonly ILogger _logger; - - public DbConnector(ILogger logger) - { - _logger = logger; - } - - public async Task Connect(string dbPath) - { - try - { - return await SqliteExtensions.ConnectToDb(dbPath, _logger).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error opening database {0}", ex, dbPath); - - throw; - } - } - } -} \ No newline at end of file -- cgit v1.2.3 From 68613fcb5b50438928a0c7756022d79b6ec4753d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 4 Jun 2016 13:14:43 -0400 Subject: remove dead code --- MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs | 1 - MediaBrowser.Server.Mono/Native/DbConnector.cs | 5 ----- MediaBrowser.ServerApplication/Native/DbConnector.cs | 5 ----- 3 files changed, 11 deletions(-) (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs index 985d79a0a..cac9fe983 100644 --- a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs +++ b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs @@ -6,6 +6,5 @@ namespace MediaBrowser.Server.Implementations.Persistence public interface IDbConnector { Task Connect(string dbPath); - void BindSimilarityScoreFunction(IDbConnection connection); } } diff --git a/MediaBrowser.Server.Mono/Native/DbConnector.cs b/MediaBrowser.Server.Mono/Native/DbConnector.cs index 536cd7322..3230f92f9 100644 --- a/MediaBrowser.Server.Mono/Native/DbConnector.cs +++ b/MediaBrowser.Server.Mono/Native/DbConnector.cs @@ -16,11 +16,6 @@ namespace MediaBrowser.Server.Mono.Native _logger = logger; } - public void BindSimilarityScoreFunction(IDbConnection connection) - { - SqliteExtensions.BindGetSimilarityScore(connection, _logger); - } - public Task Connect(string dbPath) { return SqliteExtensions.ConnectToDb(dbPath, _logger); diff --git a/MediaBrowser.ServerApplication/Native/DbConnector.cs b/MediaBrowser.ServerApplication/Native/DbConnector.cs index f93cad62c..48ba7d0e7 100644 --- a/MediaBrowser.ServerApplication/Native/DbConnector.cs +++ b/MediaBrowser.ServerApplication/Native/DbConnector.cs @@ -16,11 +16,6 @@ namespace MediaBrowser.ServerApplication.Native _logger = logger; } - public void BindSimilarityScoreFunction(IDbConnection connection) - { - SqliteExtensions.BindGetSimilarityScore(connection, _logger); - } - public async Task Connect(string dbPath) { try -- cgit v1.2.3 From 3ba9d3c12f71208cb45d58b93b7c472780a5d541 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 10 Jun 2016 12:45:04 -0400 Subject: update channel mapping --- MediaBrowser.Api/LiveTv/LiveTvService.cs | 8 +++++--- MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 2 ++ .../Library/MediaSourceManager.cs | 4 ++++ .../LiveTv/Listings/SchedulesDirect.cs | 14 +++++++++++--- .../Persistence/IDbConnector.cs | 2 +- .../Persistence/SqliteExtensions.cs | 4 ++-- .../Persistence/SqliteItemRepository.cs | 2 +- MediaBrowser.Server.Mono/Native/DbConnector.cs | 4 ++-- MediaBrowser.ServerApplication/Native/DbConnector.cs | 4 ++-- 9 files changed, 30 insertions(+), 14 deletions(-) (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index ddc389f03..b2f0704ea 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -578,7 +578,9 @@ namespace MediaBrowser.Api.LiveTv { var config = GetConfiguration(); - var listingProvider = config.ListingProviders.First(i => string.Equals(request.ProviderId, i.Id, StringComparison.OrdinalIgnoreCase)); + var listingsProviderInfo = config.ListingProviders.First(i => string.Equals(request.ProviderId, i.Id, StringComparison.OrdinalIgnoreCase)); + + var listingsProviderName = _liveTvManager.ListingProviders.First(i => string.Equals(i.Type, listingsProviderInfo.Type, StringComparison.OrdinalIgnoreCase)).Name; var tunerChannels = await _liveTvManager.GetChannelsForListingsProvider(request.ProviderId, CancellationToken.None) .ConfigureAwait(false); @@ -586,7 +588,7 @@ namespace MediaBrowser.Api.LiveTv var providerChannels = await _liveTvManager.GetChannelsFromListingsProviderData(request.ProviderId, CancellationToken.None) .ConfigureAwait(false); - var mappings = listingProvider.ChannelMappings.ToList(); + var mappings = listingsProviderInfo.ChannelMappings.ToList(); var result = new ChannelMappingOptions { @@ -601,7 +603,7 @@ namespace MediaBrowser.Api.LiveTv Mappings = mappings, - ProviderName = "Schedules Direct" + ProviderName = listingsProviderName }; return ToOptimizedResult(result); diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 9cb0476ba..ffba3097c 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -390,6 +390,8 @@ namespace MediaBrowser.Controller.LiveTv Task> GetChannelsForListingsProvider(string id, CancellationToken cancellationToken); Task> GetChannelsFromListingsProviderData(string id, CancellationToken cancellationToken); + List ListingProviders { get;} + event EventHandler> SeriesTimerCancelled; event EventHandler> TimerCancelled; event EventHandler> TimerCreated; diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index 0ef7efe1b..1bcb02ac3 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -73,6 +73,10 @@ namespace MediaBrowser.Server.Implementations.Library { return false; } + if (string.Equals(stream.Codec, "ssa", StringComparison.OrdinalIgnoreCase)) + { + return false; + } return true; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 6443440c8..e37109c14 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -879,6 +879,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings throw new Exception("ListingsId required"); } + await AddMetadata(info, new List(), cancellationToken).ConfigureAwait(false); + var token = await GetToken(info, cancellationToken); if (string.IsNullOrWhiteSpace(token)) @@ -886,8 +888,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings throw new Exception("token required"); } - ClearPairCache(listingsId); - var httpOptions = new HttpRequestOptions() { Url = ApiUrl + "/lineups/" + listingsId, @@ -921,10 +921,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } channelNumber = channelNumber.TrimStart('0'); + var name = channelNumber; + var station = GetStation(listingsId, channelNumber, null); + + if (station != null) + { + name = station.name; + } + list.Add(new ChannelInfo { Number = channelNumber, - Name = map.channel + Name = name }); } } diff --git a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs index cac9fe983..2092f830a 100644 --- a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs +++ b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs @@ -5,6 +5,6 @@ namespace MediaBrowser.Server.Implementations.Persistence { public interface IDbConnector { - Task Connect(string dbPath); + Task Connect(string dbPath, int? cacheSize = null); } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs index dd2f15cfd..2f3f34aa4 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs @@ -23,7 +23,7 @@ namespace MediaBrowser.Server.Implementations.Persistence /// The logger. /// Task{IDbConnection}. /// dbPath - public static async Task ConnectToDb(string dbPath, ILogger logger) + public static async Task ConnectToDb(string dbPath, int? cacheSize, ILogger logger) { if (string.IsNullOrEmpty(dbPath)) { @@ -35,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.Persistence var connectionstr = new SQLiteConnectionStringBuilder { PageSize = 4096, - CacheSize = 2000, + CacheSize = cacheSize ?? 2000, SyncMode = SynchronizationModes.Normal, DataSource = dbPath, JournalMode = SQLiteJournalModeEnum.Wal diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index a4cb0c48b..071951018 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -127,7 +127,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { var dbFile = Path.Combine(_config.ApplicationPaths.DataPath, "library.db"); - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); + _connection = await dbConnector.Connect(dbFile, 6000).ConfigureAwait(false); var createMediaStreamsTableCommand = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, Title TEXT NULL, TimeBase TEXT NULL, CodecTimeBase TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))"; diff --git a/MediaBrowser.Server.Mono/Native/DbConnector.cs b/MediaBrowser.Server.Mono/Native/DbConnector.cs index 3230f92f9..7553dbe1a 100644 --- a/MediaBrowser.Server.Mono/Native/DbConnector.cs +++ b/MediaBrowser.Server.Mono/Native/DbConnector.cs @@ -16,9 +16,9 @@ namespace MediaBrowser.Server.Mono.Native _logger = logger; } - public Task Connect(string dbPath) + public Task Connect(string dbPath, int? cacheSize = null) { - return SqliteExtensions.ConnectToDb(dbPath, _logger); + return SqliteExtensions.ConnectToDb(dbPath, cacheSize, _logger); } } } \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/Native/DbConnector.cs b/MediaBrowser.ServerApplication/Native/DbConnector.cs index 48ba7d0e7..6001ac3c0 100644 --- a/MediaBrowser.ServerApplication/Native/DbConnector.cs +++ b/MediaBrowser.ServerApplication/Native/DbConnector.cs @@ -16,11 +16,11 @@ namespace MediaBrowser.ServerApplication.Native _logger = logger; } - public async Task Connect(string dbPath) + public async Task Connect(string dbPath, int? cacheSize = null) { try { - return await SqliteExtensions.ConnectToDb(dbPath, _logger).ConfigureAwait(false); + return await SqliteExtensions.ConnectToDb(dbPath, cacheSize, _logger).ConfigureAwait(false); } catch (Exception ex) { -- cgit v1.2.3 From dc5c15c60b598a58c924daa350dfaf9f6b7d1c17 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 11 Jun 2016 11:56:15 -0400 Subject: update elements --- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 2 + .../Activity/ActivityRepository.cs | 248 ++++++++++----------- .../EntryPoints/ExternalPortForwarding.cs | 36 ++- .../IO/FileRefresher.cs | 11 +- MediaBrowser.Server.Mono/Native/DbConnector.cs | 4 +- .../ApplicationHost.cs | 34 +-- .../Native/DbConnector.cs | 13 +- MediaBrowser.WebDashboard/Api/DashboardService.cs | 4 +- 8 files changed, 183 insertions(+), 169 deletions(-) (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index bbb9bf6de..cd9a7b1f0 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -101,6 +101,7 @@ namespace MediaBrowser.Dlna.PlayTo } var uri = new Uri(location); + _logger.Debug("Attempting to create PlayToController from location {0}", location); var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false); if (device.RendererCommands == null) @@ -112,6 +113,7 @@ namespace MediaBrowser.Dlna.PlayTo } } + _logger.Debug("Logging session activity from location {0}", location); var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null) .ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs index b0e05a5bc..d6ae381e9 100644 --- a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs +++ b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs @@ -15,25 +15,19 @@ namespace MediaBrowser.Server.Implementations.Activity { public class ActivityRepository : BaseSqliteRepository, IActivityRepository { - private IDbConnection _connection; - private readonly IServerApplicationPaths _appPaths; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private IDbCommand _saveActivityCommand; - - public ActivityRepository(ILogManager logManager, IServerApplicationPaths appPaths) - : base(logManager) + public ActivityRepository(ILogManager logManager, IServerApplicationPaths appPaths, IDbConnector connector) + : base(logManager, connector) { - _appPaths = appPaths; + DbFilePath = Path.Combine(appPaths.DataPath, "activitylog.db"); } - public async Task Initialize(IDbConnector dbConnector) + public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "activitylog.db"); - - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); - - string[] queries = { + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + string[] queries = { "create table if not exists ActivityLogEntries (Id GUID PRIMARY KEY, Name TEXT, Overview TEXT, ShortOverview TEXT, Type TEXT, ItemId TEXT, UserId TEXT, DateCreated DATETIME, LogSeverity TEXT)", "create index if not exists idx_ActivityLogEntries on ActivityLogEntries(Id)", @@ -44,25 +38,8 @@ namespace MediaBrowser.Server.Implementations.Activity "pragma shrink_memory" }; - _connection.RunQueries(queries, Logger); - - PrepareStatements(); - } - - private void PrepareStatements() - { - _saveActivityCommand = _connection.CreateCommand(); - _saveActivityCommand.CommandText = "replace into ActivityLogEntries (Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Id, @Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"; - - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@Id"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@Name"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@Overview"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@ShortOverview"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@Type"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@ItemId"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@UserId"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@DateCreated"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@LogSeverity"); + connection.RunQueries(queries, Logger); + } } private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLogEntries"; @@ -79,128 +56,145 @@ namespace MediaBrowser.Server.Implementations.Activity throw new ArgumentNullException("entry"); } - await WriteLock.WaitAsync().ConfigureAwait(false); + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + using (var saveActivityCommand = connection.CreateCommand()) + { + saveActivityCommand.CommandText = "replace into ActivityLogEntries (Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Id, @Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"; - IDbTransaction transaction = null; + saveActivityCommand.Parameters.Add(saveActivityCommand, "@Id"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@Name"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@Overview"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@ShortOverview"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@Type"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@ItemId"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@UserId"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@DateCreated"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@LogSeverity"); - try - { - transaction = _connection.BeginTransaction(); + IDbTransaction transaction = null; - var index = 0; + try + { + transaction = connection.BeginTransaction(); - _saveActivityCommand.GetParameter(index++).Value = new Guid(entry.Id); - _saveActivityCommand.GetParameter(index++).Value = entry.Name; - _saveActivityCommand.GetParameter(index++).Value = entry.Overview; - _saveActivityCommand.GetParameter(index++).Value = entry.ShortOverview; - _saveActivityCommand.GetParameter(index++).Value = entry.Type; - _saveActivityCommand.GetParameter(index++).Value = entry.ItemId; - _saveActivityCommand.GetParameter(index++).Value = entry.UserId; - _saveActivityCommand.GetParameter(index++).Value = entry.Date; - _saveActivityCommand.GetParameter(index++).Value = entry.Severity.ToString(); + var index = 0; - _saveActivityCommand.Transaction = transaction; + saveActivityCommand.GetParameter(index++).Value = new Guid(entry.Id); + saveActivityCommand.GetParameter(index++).Value = entry.Name; + saveActivityCommand.GetParameter(index++).Value = entry.Overview; + saveActivityCommand.GetParameter(index++).Value = entry.ShortOverview; + saveActivityCommand.GetParameter(index++).Value = entry.Type; + saveActivityCommand.GetParameter(index++).Value = entry.ItemId; + saveActivityCommand.GetParameter(index++).Value = entry.UserId; + saveActivityCommand.GetParameter(index++).Value = entry.Date; + saveActivityCommand.GetParameter(index++).Value = entry.Severity.ToString(); - _saveActivityCommand.ExecuteNonQuery(); + saveActivityCommand.Transaction = transaction; - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } + saveActivityCommand.ExecuteNonQuery(); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save record:", e); + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); - } + throw; + } + catch (Exception e) + { + Logger.ErrorException("Failed to save record:", e); - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); - } + if (transaction != null) + { + transaction.Rollback(); + } - WriteLock.Release(); + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + } + } } } public QueryResult GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit) { - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = BaseActivitySelectText; - - var whereClauses = new List(); - - if (minDate.HasValue) + using (var cmd = connection.CreateCommand()) { - whereClauses.Add("DateCreated>=@DateCreated"); - cmd.Parameters.Add(cmd, "@DateCreated", DbType.Date).Value = minDate.Value; - } + cmd.CommandText = BaseActivitySelectText; - var whereTextWithoutPaging = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + var whereClauses = new List(); - if (startIndex.HasValue && startIndex.Value > 0) - { - var pagingWhereText = whereClauses.Count == 0 ? + if (minDate.HasValue) + { + whereClauses.Add("DateCreated>=@DateCreated"); + cmd.Parameters.Add(cmd, "@DateCreated", DbType.Date).Value = minDate.Value; + } + + var whereTextWithoutPaging = whereClauses.Count == 0 ? string.Empty : " where " + string.Join(" AND ", whereClauses.ToArray()); - - whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLogEntries {0} ORDER BY DateCreated DESC LIMIT {1})", - pagingWhereText, - startIndex.Value.ToString(_usCulture))); - } - - var whereText = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += whereText; + if (startIndex.HasValue && startIndex.Value > 0) + { + var pagingWhereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += " ORDER BY DateCreated DESC"; + whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLogEntries {0} ORDER BY DateCreated DESC LIMIT {1})", + pagingWhereText, + startIndex.Value.ToString(_usCulture))); + } - if (limit.HasValue) - { - cmd.CommandText += " LIMIT " + limit.Value.ToString(_usCulture); - } + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += "; select count (Id) from ActivityLogEntries" + whereTextWithoutPaging; + cmd.CommandText += whereText; - var list = new List(); - var count = 0; + cmd.CommandText += " ORDER BY DateCreated DESC"; - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) - { - while (reader.Read()) + if (limit.HasValue) { - list.Add(GetEntry(reader)); + cmd.CommandText += " LIMIT " + limit.Value.ToString(_usCulture); } - if (reader.NextResult() && reader.Read()) + cmd.CommandText += "; select count (Id) from ActivityLogEntries" + whereTextWithoutPaging; + + var list = new List(); + var count = 0; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { - count = reader.GetInt32(0); + while (reader.Read()) + { + list.Add(GetEntry(reader)); + } + + if (reader.NextResult() && reader.Read()) + { + count = reader.GetInt32(0); + } } - } - return new QueryResult() - { - Items = list.ToArray(), - TotalRecordCount = count - }; + return new QueryResult() + { + Items = list.ToArray(), + TotalRecordCount = count + }; + } } } @@ -260,19 +254,5 @@ namespace MediaBrowser.Server.Implementations.Activity return info; } - - protected override void CloseConnection() - { - if (_connection != null) - { - if (_connection.IsOpen()) - { - _connection.Close(); - } - - _connection.Dispose(); - _connection = null; - } - } } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 5777a0af7..50ad3cfbc 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -93,7 +93,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints NatUtility.UnhandledException += NatUtility_UnhandledException; NatUtility.StartDiscovery(); - _timer = new PeriodicTimer(s => _createdRules = new List(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); + _timer = new PeriodicTimer(ClearCreatedRules, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); _ssdp.MessageReceived += _ssdp_MessageReceived; @@ -102,12 +102,43 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _isStarted = true; } + private void ClearCreatedRules(object state) + { + _createdRules = new List(); + _usnsHandled = new List(); + } + void _ssdp_MessageReceived(object sender, SsdpMessageEventArgs e) { var endpoint = e.EndPoint as IPEndPoint; - if (endpoint != null && e.LocalEndPoint != null) + if (endpoint == null || e.LocalEndPoint == null) { + return; + } + + string usn; + if (!e.Headers.TryGetValue("USN", out usn)) usn = string.Empty; + + string nt; + if (!e.Headers.TryGetValue("NT", out nt)) nt = string.Empty; + + // Filter device type + if (usn.IndexOf("WANIPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && + nt.IndexOf("WANIPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && + usn.IndexOf("WANPPPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && + nt.IndexOf("WANPPPConnection:", StringComparison.OrdinalIgnoreCase) == -1) + { + return; + } + + var identifier = string.IsNullOrWhiteSpace(usn) ? nt : usn; + + if (!_usnsHandled.Contains(identifier)) + { + _usnsHandled.Add(identifier); + + _logger.Debug("Calling Nat.Handle on " + identifier); NatUtility.Handle(e.LocalEndPoint.Address, e.Message, endpoint, NatProtocol.Upnp); } } @@ -151,6 +182,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints } private List _createdRules = new List(); + private List _usnsHandled = new List(); private void CreateRules(INatDevice device) { // On some systems the device discovered event seems to fire repeatedly diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs index 18c52ab29..4bea6ad34 100644 --- a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs +++ b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs @@ -93,8 +93,15 @@ namespace MediaBrowser.Server.Implementations.IO private async void OnTimerCallback(object state) { + List paths; + + lock (_timerLock) + { + paths = _affectedPaths.ToList(); + } + // Extend the timer as long as any of the paths are still being written to. - if (_affectedPaths.Any(IsFileLocked)) + if (paths.Any(IsFileLocked)) { Logger.Info("Timer extended."); RestartTimer(); @@ -108,7 +115,7 @@ namespace MediaBrowser.Server.Implementations.IO try { - await ProcessPathChanges(_affectedPaths.ToList()).ConfigureAwait(false); + await ProcessPathChanges(paths.ToList()).ConfigureAwait(false); } catch (Exception ex) { diff --git a/MediaBrowser.Server.Mono/Native/DbConnector.cs b/MediaBrowser.Server.Mono/Native/DbConnector.cs index 7553dbe1a..5ad3ecfef 100644 --- a/MediaBrowser.Server.Mono/Native/DbConnector.cs +++ b/MediaBrowser.Server.Mono/Native/DbConnector.cs @@ -16,9 +16,9 @@ namespace MediaBrowser.Server.Mono.Native _logger = logger; } - public Task Connect(string dbPath, int? cacheSize = null) + public Task Connect(string dbPath, bool isReadOnly, bool enablePooling = false, int? cacheSize = null) { - return SqliteExtensions.ConnectToDb(dbPath, cacheSize, _logger); + return SqliteExtensions.ConnectToDb(dbPath, isReadOnly, enablePooling, cacheSize, _logger); } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index f344e6f1c..9e869478c 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -424,11 +424,11 @@ namespace MediaBrowser.Server.Startup.Common UserRepository = await GetUserRepository().ConfigureAwait(false); RegisterSingleInstance(UserRepository); - var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths); + var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths, NativeApp.GetDbConnector()); DisplayPreferencesRepository = displayPreferencesRepo; RegisterSingleInstance(DisplayPreferencesRepository); - var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager); + var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, NativeApp.GetDbConnector()); ItemRepository = itemRepo; RegisterSingleInstance(ItemRepository); @@ -553,8 +553,8 @@ namespace MediaBrowser.Server.Startup.Common RegisterSingleInstance(NativeApp.GetPowerManagement()); - var sharingRepo = new SharingRepository(LogManager, ApplicationPaths); - await sharingRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + var sharingRepo = new SharingRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector()); + await sharingRepo.Initialize().ConfigureAwait(false); RegisterSingleInstance(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this)); RegisterSingleInstance(new SsdpHandler(LogManager.GetLogger("SsdpHandler"), ServerConfigurationManager, this)); @@ -571,7 +571,7 @@ namespace MediaBrowser.Server.Startup.Common SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager); RegisterSingleInstance(SubtitleEncoder); - await displayPreferencesRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await displayPreferencesRepo.Initialize().ConfigureAwait(false); await ConfigureUserDataRepositories().ConfigureAwait(false); await itemRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; @@ -670,9 +670,9 @@ namespace MediaBrowser.Server.Startup.Common { try { - var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer); + var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer, NativeApp.GetDbConnector()); - await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await repo.Initialize().ConfigureAwait(false); return repo; } @@ -689,7 +689,7 @@ namespace MediaBrowser.Server.Startup.Common /// Task{IUserRepository}. private async Task GetFileOrganizationRepository() { - var repo = new SqliteFileOrganizationRepository(LogManager, ServerConfigurationManager.ApplicationPaths); + var repo = new SqliteFileOrganizationRepository(LogManager, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector()); await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); @@ -698,27 +698,27 @@ namespace MediaBrowser.Server.Startup.Common private async Task GetAuthenticationRepository() { - var repo = new AuthenticationRepository(LogManager, ServerConfigurationManager.ApplicationPaths); + var repo = new AuthenticationRepository(LogManager, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector()); - await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await repo.Initialize().ConfigureAwait(false); return repo; } private async Task GetActivityLogRepository() { - var repo = new ActivityRepository(LogManager, ServerConfigurationManager.ApplicationPaths); + var repo = new ActivityRepository(LogManager, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector()); - await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await repo.Initialize().ConfigureAwait(false); return repo; } private async Task GetSyncRepository() { - var repo = new SyncRepository(LogManager, JsonSerializer, ServerConfigurationManager.ApplicationPaths); + var repo = new SyncRepository(LogManager, JsonSerializer, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector()); - await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await repo.Initialize().ConfigureAwait(false); return repo; } @@ -729,9 +729,9 @@ namespace MediaBrowser.Server.Startup.Common /// Task. private async Task ConfigureNotificationsRepository() { - var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths); + var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector()); - await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await repo.Initialize().ConfigureAwait(false); NotificationsRepository = repo; @@ -744,7 +744,7 @@ namespace MediaBrowser.Server.Startup.Common /// Task. private async Task ConfigureUserDataRepositories() { - var repo = new SqliteUserDataRepository(LogManager, ApplicationPaths); + var repo = new SqliteUserDataRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector()); await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); diff --git a/MediaBrowser.ServerApplication/Native/DbConnector.cs b/MediaBrowser.ServerApplication/Native/DbConnector.cs index 6001ac3c0..9aaa96a80 100644 --- a/MediaBrowser.ServerApplication/Native/DbConnector.cs +++ b/MediaBrowser.ServerApplication/Native/DbConnector.cs @@ -16,18 +16,9 @@ namespace MediaBrowser.ServerApplication.Native _logger = logger; } - public async Task Connect(string dbPath, int? cacheSize = null) + public Task Connect(string dbPath, bool isReadOnly, bool enablePooling = false, int? cacheSize = null) { - try - { - return await SqliteExtensions.ConnectToDb(dbPath, cacheSize, _logger).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error opening database {0}", ex, dbPath); - - throw; - } + return SqliteExtensions.ConnectToDb(dbPath, isReadOnly, enablePooling, cacheSize, _logger); } } } \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 904953cfc..809c3f1a5 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -342,7 +342,9 @@ namespace MediaBrowser.WebDashboard.Api if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { - DeleteFoldersByName(Path.Combine(bowerPath, "emby-webcomponents"), "fonts"); + DeleteFoldersByName(Path.Combine(bowerPath, "emby-webcomponents", "fonts"), "montserrat"); + DeleteFoldersByName(Path.Combine(bowerPath, "emby-webcomponents", "fonts"), "opensans"); + DeleteFoldersByName(Path.Combine(bowerPath, "emby-webcomponents", "fonts"), "roboto"); } _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "jquery", "src"), true); -- cgit v1.2.3 From 7498b7b5b7e2f7ddf380df1f47421d26c8171418 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 16 Jun 2016 13:23:06 -0400 Subject: update urls --- MediaBrowser.ServerApplication/Native/WindowsApp.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index f5abcf336..c99b0f9af 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -214,13 +214,11 @@ namespace MediaBrowser.ServerApplication.Native case Architecture.X86_X64: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win64.7z", "https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20160409-git-0c90b2e-win64-static.7z" }; case Architecture.X86: return new[] { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win32.7z", "https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20160409-git-0c90b2e-win32-static.7z" }; } -- cgit v1.2.3 From bcfe86dd16e66e2e0510b1e752b4067c3fa991d3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 16 Jun 2016 14:18:38 -0400 Subject: update GetChildCount --- MediaBrowser.Controller/Entities/Audio/MusicArtist.cs | 9 +++++++++ .../FFMpeg/FFMpegInstallInfo.cs | 1 - .../FFMpeg/FFMpegLoader.cs | 16 ---------------- MediaBrowser.ServerApplication/Native/WindowsApp.cs | 1 - 4 files changed, 9 insertions(+), 18 deletions(-) (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index c1743c749..950701687 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -79,6 +79,15 @@ namespace MediaBrowser.Controller.Entities.Audio } } + public override int GetChildCount(User user) + { + if (IsAccessedByName) + { + return 0; + } + return base.GetChildCount(user); + } + public override bool IsSaveLocalMetadataEnabled() { if (IsAccessedByName) diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInstallInfo.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInstallInfo.cs index 1ce1b55c2..a2a44f805 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInstallInfo.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegInstallInfo.cs @@ -8,7 +8,6 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg public string FFProbeFilename { get; set; } public string ArchiveType { get; set; } public string[] DownloadUrls { get; set; } - public bool IsEmbedded { get; set; } public FFMpegInstallInfo() { diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs index ee284fdc5..fc74d1f25 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs @@ -197,22 +197,6 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg private async Task DownloadFFMpeg(FFMpegInstallInfo downloadinfo, string directory, IProgress progress) { - if (downloadinfo.IsEmbedded) - { - var tempFile = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString()); - _fileSystem.CreateDirectory(Path.GetDirectoryName(tempFile)); - - using (var stream = _ownerAssembly.GetManifestResourceStream(downloadinfo.DownloadUrls[0])) - { - using (var fs = _fileSystem.GetFileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read, true)) - { - await stream.CopyToAsync(fs).ConfigureAwait(false); - } - } - ExtractFFMpeg(downloadinfo, tempFile, directory); - return; - } - foreach (var url in downloadinfo.DownloadUrls) { progress.Report(0); diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index c99b0f9af..19974256d 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -160,7 +160,6 @@ namespace MediaBrowser.ServerApplication.Native info.FFProbeFilename = "ffprobe.exe"; info.Version = "20160410"; info.ArchiveType = "7z"; - info.IsEmbedded = false; info.DownloadUrls = GetDownloadUrls(); return info; -- cgit v1.2.3 From aee9d294304679e536a106a68af1f7a7c7db4191 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 17 Jun 2016 09:21:34 -0400 Subject: update urls --- MediaBrowser.ServerApplication/Native/WindowsApp.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 19974256d..2ea5064a4 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -213,15 +213,17 @@ namespace MediaBrowser.ServerApplication.Native case Architecture.X86_X64: return new[] { + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win64.7z", "https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20160409-git-0c90b2e-win64-static.7z" }; case Architecture.X86: return new[] { + "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win32.7z", "https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20160409-git-0c90b2e-win32-static.7z" }; } return new string[] { }; } } -} +} \ No newline at end of file -- cgit v1.2.3 From cffc9417c7a25263a194615096685bd8ef1e37b2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 23 Jun 2016 13:04:18 -0400 Subject: update startup wizard --- MediaBrowser.Api/ConfigurationService.cs | 20 +++++- MediaBrowser.Api/ItemLookupService.cs | 13 ++++ MediaBrowser.Api/StartupWizardService.cs | 9 ++- MediaBrowser.Api/System/SystemService.cs | 6 +- MediaBrowser.Api/UserLibrary/ItemsService.cs | 16 +++-- .../MediaEncoding/IMediaEncoder.cs | 2 + MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 72 +++++++++++++++++----- .../MediaBrowser.Model.Portable.csproj | 3 + .../MediaBrowser.Model.net35.csproj | 3 + MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + MediaBrowser.Model/System/Architecture.cs | 9 +++ MediaBrowser.Model/System/SystemInfo.cs | 2 + MediaBrowser.Providers/Movies/MovieDbSearch.cs | 24 ++++++-- .../Persistence/SqliteItemRepository.cs | 3 +- MediaBrowser.Server.Mono/Native/BaseMonoApp.cs | 9 +-- .../ApplicationHost.cs | 14 +++-- .../FFMpeg/FFMpegLoader.cs | 18 ++---- .../NativeEnvironment.cs | 10 +-- .../Native/WindowsApp.cs | 27 +------- .../MediaBrowser.WebDashboard.csproj | 9 +++ 20 files changed, 186 insertions(+), 84 deletions(-) create mode 100644 MediaBrowser.Model/System/Architecture.cs (limited to 'MediaBrowser.ServerApplication/Native') diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs index 446415fbb..9c8120de7 100644 --- a/MediaBrowser.Api/ConfigurationService.cs +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -9,7 +9,9 @@ using ServiceStack.Web; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Api { @@ -71,6 +73,14 @@ namespace MediaBrowser.Api } + [Route("/System/MediaEncoder/Path", "POST", Summary = "Updates the path to the media encoder")] + [Authenticated(Roles = "Admin", AllowBeforeStartupWizard = true)] + public class UpdateMediaEncoderPath : IReturnVoid + { + [ApiMember(Name = "Path", Description = "Path", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Path { get; set; } + } + public class ConfigurationService : BaseApiService { /// @@ -86,14 +96,22 @@ namespace MediaBrowser.Api private readonly IFileSystem _fileSystem; private readonly IProviderManager _providerManager; private readonly ILibraryManager _libraryManager; + private readonly IMediaEncoder _mediaEncoder; - public ConfigurationService(IJsonSerializer jsonSerializer, IServerConfigurationManager configurationManager, IFileSystem fileSystem, IProviderManager providerManager, ILibraryManager libraryManager) + public ConfigurationService(IJsonSerializer jsonSerializer, IServerConfigurationManager configurationManager, IFileSystem fileSystem, IProviderManager providerManager, ILibraryManager libraryManager, IMediaEncoder mediaEncoder) { _jsonSerializer = jsonSerializer; _configurationManager = configurationManager; _fileSystem = fileSystem; _providerManager = providerManager; _libraryManager = libraryManager; + _mediaEncoder = mediaEncoder; + } + + public void Post(UpdateMediaEncoderPath request) + { + var task = _mediaEncoder.UpdateEncoderPath(request.Path); + Task.WaitAll(task); } /// diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs index ad0ca68af..357ff4394 100644 --- a/MediaBrowser.Api/ItemLookupService.cs +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -38,6 +38,12 @@ namespace MediaBrowser.Api { } + [Route("/Items/RemoteSearch/Trailer", "POST")] + [Authenticated] + public class GetTrailerRemoteSearchResults : RemoteSearchQuery, IReturn> + { + } + [Route("/Items/RemoteSearch/AdultVideo", "POST")] [Authenticated] public class GetAdultVideoRemoteSearchResults : RemoteSearchQuery, IReturn> @@ -132,6 +138,13 @@ namespace MediaBrowser.Api return ToOptimizedResult(infos); } + public async Task Post(GetTrailerRemoteSearchResults request) + { + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); + + return ToOptimizedResult(result); + } + public async Task Post(GetMovieRemoteSearchResults request) { var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 93c9f8b9f..6c58228ea 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -11,6 +11,7 @@ using ServiceStack; using System; using System.Linq; using System.Threading.Tasks; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Api { @@ -52,14 +53,16 @@ namespace MediaBrowser.Api private readonly IUserManager _userManager; private readonly IConnectManager _connectManager; private readonly ILiveTvManager _liveTvManager; + private readonly IMediaEncoder _mediaEncoder; - public StartupWizardService(IServerConfigurationManager config, IServerApplicationHost appHost, IUserManager userManager, IConnectManager connectManager, ILiveTvManager liveTvManager) + public StartupWizardService(IServerConfigurationManager config, IServerApplicationHost appHost, IUserManager userManager, IConnectManager connectManager, ILiveTvManager liveTvManager, IMediaEncoder mediaEncoder) { _config = config; _appHost = appHost; _userManager = userManager; _connectManager = connectManager; _liveTvManager = liveTvManager; + _mediaEncoder = mediaEncoder; } public void Post(ReportStartupWizardComplete request) @@ -75,7 +78,8 @@ namespace MediaBrowser.Api return new StartupInfo { - SupportsRunningAsService = info.SupportsRunningAsService + SupportsRunningAsService = info.SupportsRunningAsService, + HasMediaEncoder = !string.IsNullOrWhiteSpace(_mediaEncoder.EncoderPath) }; } @@ -231,6 +235,7 @@ namespace MediaBrowser.Api public class StartupInfo { public bool SupportsRunningAsService { get; set; } + public bool HasMediaEncoder { get; set; } } public class StartupUser diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs index 346f6b32a..c2318dccb 100644 --- a/MediaBrowser.Api/System/SystemService.cs +++ b/MediaBrowser.Api/System/SystemService.cs @@ -19,7 +19,7 @@ namespace MediaBrowser.Api.System /// Class GetSystemInfo /// [Route("/System/Info", "GET", Summary = "Gets information about the server")] - [Authenticated(EscapeParentalControl = true)] + [Authenticated(EscapeParentalControl = true, AllowBeforeStartupWizard = true)] public class GetSystemInfo : IReturn { @@ -120,7 +120,7 @@ namespace MediaBrowser.Api.System try { - files = _fileSystem.GetFiles(_appPaths.LogDirectoryPath) + files = _fileSystem.GetFiles(_appPaths.LogDirectoryPath) .Where(i => string.Equals(i.Extension, ".txt", StringComparison.OrdinalIgnoreCase)) .ToList(); } @@ -146,7 +146,7 @@ namespace MediaBrowser.Api.System public Task Get(GetLogFile request) { - var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath) + var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath) .First(i => string.Equals(i.Name, request.Name, StringComparison.OrdinalIgnoreCase)); return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShare.ReadWrite); diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index f89cd0ef6..51ca2d5ca 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -119,11 +119,17 @@ namespace MediaBrowser.Api.UserLibrary // Default list type = children + var folder = item as Folder; + if (folder == null) + { + folder = user == null ? _libraryManager.RootFolder : _libraryManager.GetUserRootFolder(); + } + if (!string.IsNullOrEmpty(request.Ids)) { request.Recursive = true; var query = GetItemsQuery(request, user); - var result = await ((Folder)item).GetItems(query).ConfigureAwait(false); + var result = await folder.GetItems(query).ConfigureAwait(false); if (string.IsNullOrWhiteSpace(request.SortBy)) { @@ -138,22 +144,22 @@ namespace MediaBrowser.Api.UserLibrary if (request.Recursive) { - return await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); + return await folder.GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); } if (user == null) { - return await ((Folder)item).GetItems(GetItemsQuery(request, null)).ConfigureAwait(false); + return await folder.GetItems(GetItemsQuery(request, null)).ConfigureAwait(false); } var userRoot = item as UserRootFolder; if (userRoot == null) { - return await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); + return await folder.GetItems(GetItemsQuery(request, user)).ConfigureAwait(false); } - IEnumerable items = ((Folder)item).GetChildren(user, true); + IEnumerable items = folder.GetChildren(user, true); var itemsArray = items.ToArray(); diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index c00f76f22..77ba1685f 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -130,5 +130,7 @@ namespace MediaBrowser.Controller.MediaEncoding string EscapeSubtitleFilterPath(string path); void Init(); + + Task UpdateEncoderPath(string path); } } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 39a233856..f8321f6cd 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -23,6 +23,7 @@ using System.Threading.Tasks; using CommonIO; using MediaBrowser.Model.Configuration; using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; namespace MediaBrowser.MediaEncoding.Encoder { @@ -118,6 +119,35 @@ namespace MediaBrowser.MediaEncoding.Encoder } } + public async Task UpdateEncoderPath(string path) + { + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentNullException("path"); + } + + if (!File.Exists(path) && !Directory.Exists(path)) + { + throw new ResourceNotFoundException(); + } + + var newPaths = GetEncoderPaths(path); + if (string.IsNullOrWhiteSpace(newPaths.Item1)) + { + throw new ResourceNotFoundException("ffmpeg not found"); + } + if (string.IsNullOrWhiteSpace(newPaths.Item2)) + { + throw new ResourceNotFoundException("ffprobe not found"); + } + + var config = GetEncodingOptions(); + config.EncoderAppPath = path; + ConfigurationManager.SaveConfiguration("encoding", config); + + Init(); + } + private void ConfigureEncoderPaths() { if (_hasExternalEncoder) @@ -131,46 +161,60 @@ namespace MediaBrowser.MediaEncoding.Encoder { appPath = Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "ffmpeg"); } + var newPaths = GetEncoderPaths(appPath); + + if (!string.IsNullOrWhiteSpace(newPaths.Item1) && !string.IsNullOrWhiteSpace(newPaths.Item2)) + { + FFMpegPath = newPaths.Item1; + FFProbePath = newPaths.Item2; + } + + LogPaths(); + } + + private Tuple GetEncoderPaths(string configuredPath) + { + var appPath = configuredPath; if (!string.IsNullOrWhiteSpace(appPath)) { if (Directory.Exists(appPath)) { - SetPathsFromDirectory(appPath); + return GetPathsFromDirectory(appPath); } - else if (File.Exists(appPath)) + if (File.Exists(appPath)) { - FFMpegPath = appPath; - - SetProbePathFromEncoderPath(appPath); + return new Tuple(appPath, GetProbePathFromEncoderPath(appPath)); } } - LogPaths(); + return new Tuple(null, null); } - private void SetPathsFromDirectory(string path) + private Tuple GetPathsFromDirectory(string path) { // Since we can't predict the file extension, first try directly within the folder // If that doesn't pan out, then do a recursive search var files = Directory.GetFiles(path); - FFMpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase)); - FFProbePath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase)); + var ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase)); + var ffprobePath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase)); - if (string.IsNullOrWhiteSpace(FFMpegPath) || !File.Exists(FFMpegPath)) + if (string.IsNullOrWhiteSpace(ffmpegPath) || !File.Exists(ffmpegPath)) { files = Directory.GetFiles(path, "*", SearchOption.AllDirectories); - FFMpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase)); - SetProbePathFromEncoderPath(FFMpegPath); + ffmpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase)); + ffprobePath = GetProbePathFromEncoderPath(ffmpegPath); } + + return new Tuple(ffmpegPath, ffprobePath); } - private void SetProbePathFromEncoderPath(string appPath) + private string GetProbePathFromEncoderPath(string appPath) { - FFProbePath = Directory.GetFiles(Path.GetDirectoryName(appPath)) + return Directory.GetFiles(Path.GetDirectoryName(appPath)) .FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase)); } diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index f9d28605e..0de9fb519 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -1136,6 +1136,9 @@ Sync\SyncTarget.cs + + System\Architecture.cs + System\LogFile.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index edaa0e027..fe0b3bcae 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -1101,6 +1101,9 @@ Sync\SyncTarget.cs + + System\Architecture.cs + System\LogFile.cs diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 7c9f132db..e54273b84 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -395,6 +395,7 @@ + diff --git a/MediaBrowser.Model/System/Architecture.cs b/MediaBrowser.Model/System/Architecture.cs new file mode 100644 index 000000000..09eedddc1 --- /dev/null +++ b/MediaBrowser.Model/System/Architecture.cs @@ -0,0 +1,9 @@ +namespace MediaBrowser.Model.System +{ + public enum Architecture + { + X86 = 0, + X64 = 1, + Arm = 2 + } +} diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index 73d5961f6..868d9dc28 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -154,6 +154,8 @@ namespace MediaBrowser.Model.System public bool HasExternalEncoder { get; set; } + public Architecture SystemArchitecture { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Providers/Movies/MovieDbSearch.cs b/MediaBrowser.Providers/Movies/MovieDbSearch.cs index ceb41178e..ab2cd3bed 100644 --- a/MediaBrowser.Providers/Movies/MovieDbSearch.cs +++ b/MediaBrowser.Providers/Movies/MovieDbSearch.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Movies internal static string ApiKey = "f6bd687ffa63cd282b6ff2c6877f2669"; internal static string AcceptHeader = "application/json,image/*"; - + private readonly ILogger _logger; private readonly IJsonSerializer _json; private readonly ILibraryManager _libraryManager; @@ -54,6 +54,11 @@ namespace MediaBrowser.Providers.Movies var name = idInfo.Name; var year = idInfo.Year; + if (string.IsNullOrWhiteSpace(name)) + { + return new List(); + } + var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; @@ -73,7 +78,7 @@ namespace MediaBrowser.Providers.Movies //var searchType = item is BoxSet ? "collection" : "movie"; var results = await GetSearchResults(name, searchType, year, language, tmdbImageUrl, cancellationToken).ConfigureAwait(false); - + if (results.Count == 0) { //try in english if wasn't before @@ -123,19 +128,23 @@ namespace MediaBrowser.Providers.Movies }); } - private async Task> GetSearchResults(string name, string type, int? year, string language, string baseImageUrl, CancellationToken cancellationToken) + private Task> GetSearchResults(string name, string type, int? year, string language, string baseImageUrl, CancellationToken cancellationToken) { switch (type) { case "tv": - return await GetSearchResultsTv(name, year, language, baseImageUrl, cancellationToken); + return GetSearchResultsTv(name, year, language, baseImageUrl, cancellationToken); default: - return await GetSearchResultsGeneric(name, type, year, language, baseImageUrl, cancellationToken); + return GetSearchResultsGeneric(name, type, year, language, baseImageUrl, cancellationToken); } } private async Task> GetSearchResultsGeneric(string name, string type, int? year, string language, string baseImageUrl, CancellationToken cancellationToken) { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentException("name"); + } var url3 = string.Format(Search3, WebUtility.UrlEncode(name), ApiKey, language, type); @@ -189,6 +198,11 @@ namespace MediaBrowser.Providers.Movies private async Task> GetSearchResultsTv(string name, int? year, string language, string baseImageUrl, CancellationToken cancellationToken) { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentException("name"); + } + var url3 = string.Format(Search3, WebUtility.UrlEncode(name), ApiKey, language, "tv"); using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 992a0a2cf..784766071 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -127,7 +127,8 @@ namespace MediaBrowser.Server.Implementations.Persistence connection.RunQueries(new[] { - "pragma temp_store = memory" + "pragma temp_store = memory", + "PRAGMA main.locking_mode=EXCLUSIVE" }, Logger); diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index a012a19a3..5d7274356 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Reflection; using System.Text.RegularExpressions; using MediaBrowser.Controller.Power; +using MediaBrowser.Model.System; using MediaBrowser.Server.Implementations.Persistence; using MediaBrowser.Server.Startup.Common.FFMpeg; using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem; @@ -176,7 +177,7 @@ namespace MediaBrowser.Server.Mono.Native } else if (string.Equals(uname.machine, "x86_64", StringComparison.OrdinalIgnoreCase)) { - info.SystemArchitecture = Architecture.X86_X64; + info.SystemArchitecture = Architecture.X64; } else if (uname.machine.StartsWith("arm", StringComparison.OrdinalIgnoreCase)) { @@ -260,7 +261,7 @@ namespace MediaBrowser.Server.Mono.Native switch (environment.SystemArchitecture) { - case Architecture.X86_X64: + case Architecture.X64: info.Version = "20160124"; break; case Architecture.X86: @@ -283,7 +284,7 @@ namespace MediaBrowser.Server.Mono.Native switch (environment.SystemArchitecture) { - case Architecture.X86_X64: + case Architecture.X64: return new[] { "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/osx/ffmpeg-x64-2.8.5.7z" @@ -300,7 +301,7 @@ namespace MediaBrowser.Server.Mono.Native switch (environment.SystemArchitecture) { - case Architecture.X86_X64: + case Architecture.X64: return new[] { "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-git-20160215-64bit-static.7z" diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index e7e6a9dc3..7390fbbbc 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -647,15 +647,20 @@ namespace MediaBrowser.Server.Startup.Common /// Task. private async Task RegisterMediaEncoder(IProgress progress) { + string encoderPath = null; + string probePath = null; + var info = await new FFMpegLoader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, NativeApp.Environment, NativeApp.GetFfmpegInstallInfo()) .GetFFMpegInfo(NativeApp.Environment, _startupOptions, progress).ConfigureAwait(false); - _hasExternalEncoder = string.Equals(info.Version, "custom", StringComparison.OrdinalIgnoreCase); + encoderPath = info.EncoderPath; + probePath = info.ProbePath; + _hasExternalEncoder = string.Equals(info.Version, "external", StringComparison.OrdinalIgnoreCase); var mediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), JsonSerializer, - info.EncoderPath, - info.ProbePath, + encoderPath, + probePath, _hasExternalEncoder, ServerConfigurationManager, FileSystemManager, @@ -1145,7 +1150,8 @@ namespace MediaBrowser.Server.Startup.Common ServerName = FriendlyName, LocalAddress = localAddress, SupportsLibraryMonitor = SupportsLibraryMonitor, - HasExternalEncoder = _hasExternalEncoder + HasExternalEncoder = _hasExternalEncoder, + SystemArchitecture = NativeApp.Environment.SystemArchitecture }; } diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs index 2c393ff29..a4c50d0d8 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegLoader.cs @@ -53,13 +53,17 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg { ProbePath = customffProbePath, EncoderPath = customffMpegPath, - Version = "custom" + Version = "external" }; } var downloadInfo = _ffmpegInstallInfo; var version = downloadInfo.Version; + if (string.Equals(version, "0", StringComparison.OrdinalIgnoreCase)) + { + return new FFMpegInfo(); + } if (string.Equals(version, "path", StringComparison.OrdinalIgnoreCase)) { @@ -175,18 +179,6 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg return null; } - private async void DownloadFFMpegInBackground(FFMpegInstallInfo downloadinfo, string directory) - { - try - { - await DownloadFFMpeg(downloadinfo, directory, new Progress()).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error downloading ffmpeg", ex); - } - } - private async Task DownloadFFMpeg(FFMpegInstallInfo downloadinfo, string directory, IProgress progress) { foreach (var url in downloadinfo.DownloadUrls) diff --git a/MediaBrowser.Server.Startup.Common/NativeEnvironment.cs b/MediaBrowser.Server.Startup.Common/NativeEnvironment.cs index 5b45afe73..b30509982 100644 --- a/MediaBrowser.Server.Startup.Common/NativeEnvironment.cs +++ b/MediaBrowser.Server.Startup.Common/NativeEnvironment.cs @@ -1,4 +1,5 @@ - +using MediaBrowser.Model.System; + namespace MediaBrowser.Server.Startup.Common { public class NativeEnvironment @@ -15,11 +16,4 @@ namespace MediaBrowser.Server.Startup.Common Bsd = 2, Linux = 3 } - - public enum Architecture - { - X86 = 0, - X86_X64 = 1, - Arm = 2 - } } diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 2ea5064a4..d8b2720c2 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -10,6 +10,7 @@ using System.Reflection; using System.Windows.Forms; using CommonIO; using MediaBrowser.Controller.Power; +using MediaBrowser.Model.System; using MediaBrowser.Server.Implementations.Persistence; using MediaBrowser.Server.Startup.Common.FFMpeg; using OperatingSystem = MediaBrowser.Server.Startup.Common.OperatingSystem; @@ -53,7 +54,7 @@ namespace MediaBrowser.ServerApplication.Native return new NativeEnvironment { OperatingSystem = OperatingSystem.Windows, - SystemArchitecture = System.Environment.Is64BitOperatingSystem ? Architecture.X86_X64 : Architecture.X86, + SystemArchitecture = System.Environment.Is64BitOperatingSystem ? Architecture.X64 : Architecture.X86, OperatingSystemVersionString = System.Environment.OSVersion.VersionString }; } @@ -158,9 +159,7 @@ namespace MediaBrowser.ServerApplication.Native info.FFMpegFilename = "ffmpeg.exe"; info.FFProbeFilename = "ffprobe.exe"; - info.Version = "20160410"; - info.ArchiveType = "7z"; - info.DownloadUrls = GetDownloadUrls(); + info.Version = "0"; return info; } @@ -205,25 +204,5 @@ namespace MediaBrowser.ServerApplication.Native { ((Process)sender).Dispose(); } - - private string[] GetDownloadUrls() - { - switch (Environment.SystemArchitecture) - { - case Architecture.X86_X64: - return new[] - { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win64.7z", - "https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20160409-git-0c90b2e-win64-static.7z" - }; - case Architecture.X86: - return new[] - { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160410-win32.7z", - "https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20160409-git-0c90b2e-win32-static.7z" - }; - } - return new string[] { }; - } } } \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index bc5db0224..4eae9975a 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -374,6 +374,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -1094,6 +1100,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3