add localization stub

This commit is contained in:
Luke Pulverenti 2014-03-30 21:00:47 -04:00
parent 59a4d3c953
commit 5a014b093c
18 changed files with 537 additions and 212 deletions

View File

@ -31,6 +31,14 @@ namespace MediaBrowser.Api
{ {
} }
/// <summary>
/// Class ParentalRatings
/// </summary>
[Route("/Localization/Options", "GET", Summary = "Gets localization options")]
public class GetLocalizationOptions : IReturn<List<LocalizatonOption>>
{
}
/// <summary> /// <summary>
/// Class CulturesService /// Class CulturesService
/// </summary> /// </summary>
@ -62,6 +70,13 @@ namespace MediaBrowser.Api
return ToOptimizedSerializedResultUsingCache(result); return ToOptimizedSerializedResultUsingCache(result);
} }
public object Get(GetLocalizationOptions request)
{
var result = _localization.GetLocalizationOptions().ToList();
return ToOptimizedSerializedResultUsingCache(result);
}
/// <summary> /// <summary>
/// Gets the specified request. /// Gets the specified request.
/// </summary> /// </summary>

View File

@ -276,7 +276,7 @@ namespace MediaBrowser.Api.Playback.Hls
? 0 ? 0
: ((GetHlsVideoStream)state.VideoRequest).TimeStampOffsetMs; : ((GetHlsVideoStream)state.VideoRequest).TimeStampOffsetMs;
var itsOffset = itsOffsetMs == 0 ? string.Empty : string.Format("-itsoffset {0} ", TimeSpan.FromMilliseconds(itsOffsetMs).TotalSeconds); var itsOffset = itsOffsetMs == 0 ? string.Empty : string.Format("-itsoffset {0} ", TimeSpan.FromMilliseconds(itsOffsetMs).TotalSeconds.ToString(UsCulture));
var threads = GetNumberOfThreads(state, false); var threads = GetNumberOfThreads(state, false);

View File

@ -1,7 +1,7 @@
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Globalization;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Localization namespace MediaBrowser.Controller.Localization
{ {
@ -31,5 +31,35 @@ namespace MediaBrowser.Controller.Localization
/// <param name="rating">The rating.</param> /// <param name="rating">The rating.</param>
/// <returns>System.Int32.</returns> /// <returns>System.Int32.</returns>
int? GetRatingLevel(string rating); int? GetRatingLevel(string rating);
/// <summary>
/// Gets the localized string.
/// </summary>
/// <param name="phrase">The phrase.</param>
/// <param name="culture">The culture.</param>
/// <returns>System.String.</returns>
string GetLocalizedString(string phrase, string culture);
/// <summary>
/// Gets the localized string.
/// </summary>
/// <param name="phrase">The phrase.</param>
/// <returns>System.String.</returns>
string GetLocalizedString(string phrase);
/// <summary>
/// Localizes the document.
/// </summary>
/// <param name="document">The document.</param>
/// <param name="culture">The culture.</param>
/// <param name="tokenBuilder">The token builder.</param>
/// <returns>System.String.</returns>
string LocalizeDocument(string document, string culture, Func<string, string> tokenBuilder);
/// <summary>
/// Gets the localization options.
/// </summary>
/// <returns>IEnumerable{LocalizatonOption}.</returns>
IEnumerable<LocalizatonOption> GetLocalizationOptions();
} }
} }

View File

@ -218,6 +218,8 @@ namespace MediaBrowser.Model.Configuration
public string ServerName { get; set; } public string ServerName { get; set; }
public string WanDdns { get; set; } public string WanDdns { get; set; }
public string UICulture { get; set; }
public DlnaOptions DlnaOptions { get; set; } public DlnaOptions DlnaOptions { get; set; }
/// <summary> /// <summary>
@ -281,6 +283,8 @@ namespace MediaBrowser.Model.Configuration
MetadataOptions = options.ToArray(); MetadataOptions = options.ToArray();
DlnaOptions = new DlnaOptions(); DlnaOptions = new DlnaOptions();
UICulture = "en-us";
} }
} }

View File

@ -30,4 +30,10 @@ namespace MediaBrowser.Model.Globalization
/// <value>The name of the three letter ISO region.</value> /// <value>The name of the three letter ISO region.</value>
public string ThreeLetterISORegionName { get; set; } public string ThreeLetterISORegionName { get; set; }
} }
public class LocalizatonOption
{
public string Name { get; set; }
public string Value { get; set; }
}
} }

View File

@ -0,0 +1,3 @@
{
"LabelTest": "Text"
}

View File

@ -1,9 +1,9 @@
using MediaBrowser.Common.IO; using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Localization;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Serialization;
using MoreLinq; using MoreLinq;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@ -11,6 +11,8 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Server.Implementations.Localization namespace MediaBrowser.Server.Implementations.Localization
{ {
@ -33,15 +35,17 @@ namespace MediaBrowser.Server.Implementations.Localization
new ConcurrentDictionary<string, Dictionary<string, ParentalRating>>(StringComparer.OrdinalIgnoreCase); new ConcurrentDictionary<string, Dictionary<string, ParentalRating>>(StringComparer.OrdinalIgnoreCase);
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly IJsonSerializer _jsonSerializer;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="LocalizationManager"/> class. /// Initializes a new instance of the <see cref="LocalizationManager"/> class.
/// </summary> /// </summary>
/// <param name="configurationManager">The configuration manager.</param> /// <param name="configurationManager">The configuration manager.</param>
public LocalizationManager(IServerConfigurationManager configurationManager, IFileSystem fileSystem) public LocalizationManager(IServerConfigurationManager configurationManager, IFileSystem fileSystem, IJsonSerializer jsonSerializer)
{ {
_configurationManager = configurationManager; _configurationManager = configurationManager;
_fileSystem = fileSystem; _fileSystem = fileSystem;
_jsonSerializer = jsonSerializer;
ExtractAll(); ExtractAll();
} }
@ -241,5 +245,108 @@ namespace MediaBrowser.Server.Implementations.Localization
return value == null ? (int?)null : value.Value; return value == null ? (int?)null : value.Value;
} }
public string GetLocalizedString(string phrase)
{
return GetLocalizedString(phrase, _configurationManager.Configuration.UICulture);
}
public string GetLocalizedString(string phrase, string culture)
{
var dictionary = GetLocalizationDictionary(culture);
string value;
if (dictionary.TryGetValue(phrase, out value))
{
return value;
}
return phrase;
}
private readonly ConcurrentDictionary<string, Dictionary<string, string>> _dictionaries =
new ConcurrentDictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
public Dictionary<string, string> GetLocalizationDictionary(string culture)
{
const string prefix = "Server";
var key = prefix + culture;
return _dictionaries.GetOrAdd(key, k => GetDictionary(prefix, culture, "server.json"));
}
public Dictionary<string, string> GetJavaScriptLocalizationDictionary(string culture)
{
const string prefix = "JavaScript";
var key = prefix + culture;
return _dictionaries.GetOrAdd(key, k => GetDictionary(prefix, culture, "javascript.json"));
}
private Dictionary<string, string> GetDictionary(string prefix, string culture, string baseFilename)
{
var dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var assembly = GetType().Assembly;
var namespaceName = GetType().Namespace + "." + prefix;
CopyInto(dictionary, namespaceName + "." + baseFilename, assembly);
CopyInto(dictionary, namespaceName + "." + GetResourceFilename(culture), assembly);
return dictionary;
}
private void CopyInto(IDictionary<string, string> dictionary, string resourcePath, Assembly assembly)
{
using (var stream = assembly.GetManifestResourceStream(resourcePath))
{
if (stream != null)
{
var dict = _jsonSerializer.DeserializeFromStream<Dictionary<string, string>>(stream);
foreach (var key in dict.Keys)
{
dictionary[key] = dict[key];
}
}
}
}
private string GetResourceFilename(string culture)
{
var parts = culture.Split('-');
if (parts.Length == 2)
{
culture = parts[0].ToLower() + "_" + parts[1].ToUpper();
}
else
{
culture = culture.ToLower();
}
return culture + ".json";
}
public IEnumerable<LocalizatonOption> GetLocalizationOptions()
{
return new List<LocalizatonOption>
{
new LocalizatonOption{ Name="English (United States)", Value="en-us"}
};
}
public string LocalizeDocument(string document, string culture, Func<string,string> tokenBuilder)
{
foreach (var pair in GetLocalizationDictionary(culture).ToList())
{
var token = tokenBuilder(pair.Key);
document = document.Replace(token, pair.Value, StringComparison.Ordinal);
}
return document;
}
} }
} }

View File

@ -0,0 +1,17 @@
{
"LabelExit": "Exit",
"LabelVisitCommunity": "Visit Community",
"LabelGithubWiki": "Github Wiki",
"LabelSwagger": "Swagger",
"LabelStandard": "Standard",
"LabelViewApiDocumentation": "View Api Documentation",
"LabelBrowseLibrary": "Browse Library",
"LabelConfigureMediaBrowser": "Configure Media Browser",
"LabelOpenLibraryViewer": "Open Library Viewer",
"LabelRestartServer": "Restart Server",
"LabelShowLogWindow": "Show Log Window",
"LabelPrevious": "Previous",
"LabelFinish": "Finish",
"LabelNext": "Next",
"LabelYoureDone": "You're Done!"
}

View File

@ -282,6 +282,8 @@
<EmbeddedResource Include="Localization\Ratings\ru.txt" /> <EmbeddedResource Include="Localization\Ratings\ru.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Localization\JavaScript\javascript.json" />
<EmbeddedResource Include="Localization\Server\server.json" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -386,6 +388,7 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\nuget.targets" Condition=" '$(ConfigurationName)' != 'Release Mono' " /> <Import Project="$(SolutionDir)\.nuget\nuget.targets" Condition=" '$(ConfigurationName)' != 'Release Mono' " />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -170,7 +170,7 @@ namespace MediaBrowser.ServerApplication
private ILiveTvManager LiveTvManager { get; set; } private ILiveTvManager LiveTvManager { get; set; }
private ILocalizationManager LocalizationManager { get; set; } internal ILocalizationManager LocalizationManager { get; set; }
private IEncodingManager EncodingManager { get; set; } private IEncodingManager EncodingManager { get; set; }
private IChannelManager ChannelManager { get; set; } private IChannelManager ChannelManager { get; set; }
@ -421,6 +421,9 @@ namespace MediaBrowser.ServerApplication
RegisterSingleInstance(ServerConfigurationManager); RegisterSingleInstance(ServerConfigurationManager);
LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager, JsonSerializer);
RegisterSingleInstance(LocalizationManager);
RegisterSingleInstance<IWebSocketServer>(() => new AlchemyServer(Logger)); RegisterSingleInstance<IWebSocketServer>(() => new AlchemyServer(Logger));
RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer()); RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer());
@ -472,9 +475,6 @@ namespace MediaBrowser.ServerApplication
ServerManager = new ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager); ServerManager = new ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager);
RegisterSingleInstance(ServerManager); RegisterSingleInstance(ServerManager);
LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager);
RegisterSingleInstance(LocalizationManager);
var innerProgress = new ActionableProgress<double>(); var innerProgress = new ActionableProgress<double>();
innerProgress.RegisterAction(p => progress.Report((.75 * p) + 15)); innerProgress.RegisterAction(p => progress.Report((.75 * p) + 15));

View File

@ -16,18 +16,16 @@ namespace MediaBrowser.ServerApplication
{ {
private readonly IJsonSerializer _jsonSerializer; private readonly IJsonSerializer _jsonSerializer;
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
private readonly IDisplayPreferencesRepository _displayPreferencesManager;
private readonly IItemRepository _itemRepository; private readonly IItemRepository _itemRepository;
private User _currentUser; private User _currentUser;
public LibraryViewer(IJsonSerializer jsonSerializer, IUserManager userManager, ILibraryManager libraryManager, IDisplayPreferencesRepository displayPreferencesManager, IItemRepository itemRepo) public LibraryViewer(IJsonSerializer jsonSerializer, IUserManager userManager, ILibraryManager libraryManager, IItemRepository itemRepo)
{ {
InitializeComponent(); InitializeComponent();
_jsonSerializer = jsonSerializer; _jsonSerializer = jsonSerializer;
_libraryManager = libraryManager; _libraryManager = libraryManager;
_displayPreferencesManager = displayPreferencesManager;
_itemRepository = itemRepo; _itemRepository = itemRepo;
foreach (var user in userManager.Users) foreach (var user in userManager.Users)
@ -44,7 +42,7 @@ namespace MediaBrowser.ServerApplication
if (e.Node != null) if (e.Node != null)
{ {
var item = (BaseItem)e.Node.Tag; var item = (BaseItem)e.Node.Tag;
lblType.Text = "Type: " + item.GetType().Name; lblType.Text = item.GetType().Name;
var json = FormatJson(_jsonSerializer.SerializeToString(item)); var json = FormatJson(_jsonSerializer.SerializeToString(item));

View File

@ -253,7 +253,7 @@ namespace MediaBrowser.ServerApplication
{ {
//Application.EnableVisualStyles(); //Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false); //Application.SetCompatibleTextRenderingDefault(false);
_serverNotifyIcon = new ServerNotifyIcon(_appHost.LogManager, _appHost, _appHost.ServerConfigurationManager, _appHost.UserManager, _appHost.LibraryManager, _appHost.JsonSerializer, _appHost.DisplayPreferencesRepository, _appHost.ItemRepository); _serverNotifyIcon = new ServerNotifyIcon(_appHost.LogManager, _appHost, _appHost.ServerConfigurationManager, _appHost.UserManager, _appHost.LibraryManager, _appHost.JsonSerializer, _appHost.DisplayPreferencesRepository, _appHost.ItemRepository, _appHost.LocalizationManager);
Application.Run(); Application.Run();
} }

View File

@ -4,6 +4,7 @@ using System.Windows.Forms;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
@ -41,6 +42,7 @@ namespace MediaBrowser.ServerApplication
private readonly IJsonSerializer _jsonSerializer; private readonly IJsonSerializer _jsonSerializer;
private readonly IDisplayPreferencesRepository _displayPreferencesManager; private readonly IDisplayPreferencesRepository _displayPreferencesManager;
private readonly IItemRepository _itemRepository; private readonly IItemRepository _itemRepository;
private readonly ILocalizationManager _localization;
private LogForm _logForm; private LogForm _logForm;
public bool Visible public bool Visible
@ -56,10 +58,17 @@ namespace MediaBrowser.ServerApplication
} }
} }
public ServerNotifyIcon(ILogManager logManager, IServerApplicationHost appHost, IServerConfigurationManager configurationManager, IUserManager userManager, ILibraryManager libraryManager, IJsonSerializer jsonSerializer, IDisplayPreferencesRepository displayPreferencesManager, IItemRepository itemRepo) public ServerNotifyIcon(ILogManager logManager,
IServerApplicationHost appHost,
IServerConfigurationManager configurationManager,
IUserManager userManager, ILibraryManager libraryManager,
IJsonSerializer jsonSerializer,
IDisplayPreferencesRepository displayPreferencesManager,
IItemRepository itemRepo, ILocalizationManager localization)
{ {
_logger = logManager.GetLogger("MainWindow"); _logger = logManager.GetLogger("MainWindow");
_itemRepository = itemRepo; _itemRepository = itemRepo;
_localization = localization;
_appHost = appHost; _appHost = appHost;
_logManager = logManager; _logManager = logManager;
_configurationManager = configurationManager; _configurationManager = configurationManager;
@ -118,20 +127,17 @@ namespace MediaBrowser.ServerApplication
// //
cmdExit.Name = "cmdExit"; cmdExit.Name = "cmdExit";
cmdExit.Size = new System.Drawing.Size(208, 22); cmdExit.Size = new System.Drawing.Size(208, 22);
cmdExit.Text = "Exit";
// //
// cmdCommunity // cmdCommunity
// //
cmdCommunity.Name = "cmdCommunity"; cmdCommunity.Name = "cmdCommunity";
cmdCommunity.Size = new System.Drawing.Size(208, 22); cmdCommunity.Size = new System.Drawing.Size(208, 22);
cmdCommunity.Text = "Visit Community";
// //
// cmdLogWindow // cmdLogWindow
// //
cmdLogWindow.CheckOnClick = true; cmdLogWindow.CheckOnClick = true;
cmdLogWindow.Name = "cmdLogWindow"; cmdLogWindow.Name = "cmdLogWindow";
cmdLogWindow.Size = new System.Drawing.Size(208, 22); cmdLogWindow.Size = new System.Drawing.Size(208, 22);
cmdLogWindow.Text = "Show Log Window";
// //
// toolStripSeparator1 // toolStripSeparator1
// //
@ -142,13 +148,11 @@ namespace MediaBrowser.ServerApplication
// //
cmdRestart.Name = "cmdRestart"; cmdRestart.Name = "cmdRestart";
cmdRestart.Size = new System.Drawing.Size(208, 22); cmdRestart.Size = new System.Drawing.Size(208, 22);
cmdRestart.Text = "Restart Server";
// //
// cmdLibraryExplorer // cmdLibraryExplorer
// //
cmdLibraryExplorer.Name = "cmdLibraryExplorer"; cmdLibraryExplorer.Name = "cmdLibraryExplorer";
cmdLibraryExplorer.Size = new System.Drawing.Size(208, 22); cmdLibraryExplorer.Size = new System.Drawing.Size(208, 22);
cmdLibraryExplorer.Text = "Open Library Explorer";
// //
// toolStripSeparator2 // toolStripSeparator2
// //
@ -159,13 +163,11 @@ namespace MediaBrowser.ServerApplication
// //
cmdConfigure.Name = "cmdConfigure"; cmdConfigure.Name = "cmdConfigure";
cmdConfigure.Size = new System.Drawing.Size(208, 22); cmdConfigure.Size = new System.Drawing.Size(208, 22);
cmdConfigure.Text = "Configure Media Browser";
// //
// cmdBrowse // cmdBrowse
// //
cmdBrowse.Name = "cmdBrowse"; cmdBrowse.Name = "cmdBrowse";
cmdBrowse.Size = new System.Drawing.Size(208, 22); cmdBrowse.Size = new System.Drawing.Size(208, 22);
cmdBrowse.Text = "Browse Library";
// //
// cmdApiDocs // cmdApiDocs
// //
@ -175,25 +177,21 @@ namespace MediaBrowser.ServerApplication
cmdGtihub}); cmdGtihub});
cmdApiDocs.Name = "cmdApiDocs"; cmdApiDocs.Name = "cmdApiDocs";
cmdApiDocs.Size = new System.Drawing.Size(208, 22); cmdApiDocs.Size = new System.Drawing.Size(208, 22);
cmdApiDocs.Text = "View Api Documentation";
// //
// cmdStandardDocs // cmdStandardDocs
// //
cmdStandardDocs.Name = "cmdStandardDocs"; cmdStandardDocs.Name = "cmdStandardDocs";
cmdStandardDocs.Size = new System.Drawing.Size(136, 22); cmdStandardDocs.Size = new System.Drawing.Size(136, 22);
cmdStandardDocs.Text = "Standard";
// //
// cmdSwagger // cmdSwagger
// //
cmdSwagger.Name = "cmdSwagger"; cmdSwagger.Name = "cmdSwagger";
cmdSwagger.Size = new System.Drawing.Size(136, 22); cmdSwagger.Size = new System.Drawing.Size(136, 22);
cmdSwagger.Text = "Swagger";
// //
// cmdGtihub // cmdGtihub
// //
cmdGtihub.Name = "cmdGtihub"; cmdGtihub.Name = "cmdGtihub";
cmdGtihub.Size = new System.Drawing.Size(136, 22); cmdGtihub.Size = new System.Drawing.Size(136, 22);
cmdGtihub.Text = "Github Wiki";
cmdExit.Click += cmdExit_Click; cmdExit.Click += cmdExit_Click;
cmdRestart.Click += cmdRestart_Click; cmdRestart.Click += cmdRestart_Click;
@ -211,6 +209,8 @@ namespace MediaBrowser.ServerApplication
_logManager.LoggerLoaded += LoadLogWindow; _logManager.LoggerLoaded += LoadLogWindow;
_configurationManager.ConfigurationUpdated += Instance_ConfigurationUpdated; _configurationManager.ConfigurationUpdated += Instance_ConfigurationUpdated;
LocalizeText();
if (_appHost.IsFirstRun) if (_appHost.IsFirstRun)
{ {
Action action = () => notifyIcon1.ShowBalloonTip(5000, "Media Browser", "Welcome to Media Browser Server!", ToolTipIcon.Info); Action action = () => notifyIcon1.ShowBalloonTip(5000, "Media Browser", "Welcome to Media Browser Server!", ToolTipIcon.Info);
@ -219,6 +219,24 @@ namespace MediaBrowser.ServerApplication
} }
} }
private void LocalizeText()
{
_uiCulture = _configurationManager.Configuration.UICulture;
cmdExit.Text = _localization.GetLocalizedString("LabelExit");
cmdCommunity.Text = _localization.GetLocalizedString("LabelVisitCommunity");
cmdGtihub.Text = _localization.GetLocalizedString("LabelGithubWiki");
cmdSwagger.Text = _localization.GetLocalizedString("LabelSwagger");
cmdStandardDocs.Text = _localization.GetLocalizedString("LabelStandard");
cmdApiDocs.Text = _localization.GetLocalizedString("LabelViewApiDocumentation");
cmdBrowse.Text = _localization.GetLocalizedString("LabelBrowseLibrary");
cmdConfigure.Text = _localization.GetLocalizedString("LabelConfigureMediaBrowser");
cmdLibraryExplorer.Text = _localization.GetLocalizedString("LabelOpenLibraryViewer");
cmdRestart.Text = _localization.GetLocalizedString("LabelRestartServer");
cmdLogWindow.Text = _localization.GetLocalizedString("LabelShowLogWindow");
}
private string _uiCulture;
/// <summary> /// <summary>
/// Handles the ConfigurationUpdated event of the Instance control. /// Handles the ConfigurationUpdated event of the Instance control.
/// </summary> /// </summary>
@ -226,6 +244,12 @@ namespace MediaBrowser.ServerApplication
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
void Instance_ConfigurationUpdated(object sender, EventArgs e) void Instance_ConfigurationUpdated(object sender, EventArgs e)
{ {
if (!string.Equals(_configurationManager.Configuration.UICulture, _uiCulture,
StringComparison.OrdinalIgnoreCase))
{
LocalizeText();
}
Action action = () => Action action = () =>
{ {
var isLogWindowOpen = _logForm != null; var isLogWindowOpen = _logForm != null;
@ -307,7 +331,7 @@ namespace MediaBrowser.ServerApplication
void cmdLibraryExplorer_Click(object sender, EventArgs e) void cmdLibraryExplorer_Click(object sender, EventArgs e)
{ {
new LibraryViewer(_jsonSerializer, _userManager, _libraryManager, _displayPreferencesManager, _itemRepository).Show(); new LibraryViewer(_jsonSerializer, _userManager, _libraryManager, _itemRepository).Show();
} }
void cmdRestart_Click(object sender, EventArgs e) void cmdRestart_Click(object sender, EventArgs e)

View File

@ -121,9 +121,9 @@
this.lblStatus.Location = new System.Drawing.Point(3, 0); this.lblStatus.Location = new System.Drawing.Point(3, 0);
this.lblStatus.MaximumSize = new System.Drawing.Size(0, 100); this.lblStatus.MaximumSize = new System.Drawing.Size(0, 100);
this.lblStatus.Name = "lblStatus"; this.lblStatus.Name = "lblStatus";
this.lblStatus.Size = new System.Drawing.Size(599, 59); this.lblStatus.Size = new System.Drawing.Size(469, 59);
this.lblStatus.TabIndex = 0; this.lblStatus.TabIndex = 0;
this.lblStatus.Text = "Loading Media Browser Server"; this.lblStatus.Text = "Loading Media Browser";
this.lblStatus.UseWaitCursor = true; this.lblStatus.UseWaitCursor = true;
// //
// panel1 // panel1

View File

@ -3,6 +3,7 @@ using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
@ -15,6 +16,8 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using WebMarkupMin.Core.Minifiers;
using WebMarkupMin.Core.Settings;
namespace MediaBrowser.WebDashboard.Api namespace MediaBrowser.WebDashboard.Api
{ {
@ -96,6 +99,7 @@ namespace MediaBrowser.WebDashboard.Api
private readonly IServerConfigurationManager _serverConfigurationManager; private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly ILocalizationManager _localization;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DashboardService" /> class. /// Initializes a new instance of the <see cref="DashboardService" /> class.
@ -103,11 +107,12 @@ namespace MediaBrowser.WebDashboard.Api
/// <param name="appHost">The app host.</param> /// <param name="appHost">The app host.</param>
/// <param name="serverConfigurationManager">The server configuration manager.</param> /// <param name="serverConfigurationManager">The server configuration manager.</param>
/// <param name="fileSystem">The file system.</param> /// <param name="fileSystem">The file system.</param>
public DashboardService(IServerApplicationHost appHost, IServerConfigurationManager serverConfigurationManager, IFileSystem fileSystem) public DashboardService(IServerApplicationHost appHost, IServerConfigurationManager serverConfigurationManager, IFileSystem fileSystem, ILocalizationManager localization)
{ {
_appHost = appHost; _appHost = appHost;
_serverConfigurationManager = serverConfigurationManager; _serverConfigurationManager = serverConfigurationManager;
_fileSystem = fileSystem; _fileSystem = fileSystem;
_localization = localization;
} }
/// <summary> /// <summary>
@ -148,7 +153,7 @@ namespace MediaBrowser.WebDashboard.Api
{ {
var page = ServerEntryPoint.Instance.PluginConfigurationPages.First(p => p.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase)); var page = ServerEntryPoint.Instance.PluginConfigurationPages.First(p => p.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase));
return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), page.Plugin.AssemblyDateLastModified, null, MimeTypes.GetMimeType("page.html"), () => ModifyHtml(page.GetHtmlStream())); return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), page.Plugin.AssemblyDateLastModified, null, MimeTypes.GetMimeType("page.html"), () => ModifyHtml(page.GetHtmlStream(), null));
} }
/// <summary> /// <summary>
@ -210,13 +215,16 @@ namespace MediaBrowser.WebDashboard.Api
var contentType = MimeTypes.GetMimeType(path); var contentType = MimeTypes.GetMimeType(path);
var isHtml = IsHtml(path);
var localizationCulture = isHtml ? GetLocalizationCulture() : null;
// Don't cache if not configured to do so // Don't cache if not configured to do so
// But always cache images to simulate production // But always cache images to simulate production
if (!_serverConfigurationManager.Configuration.EnableDashboardResponseCaching && if (!_serverConfigurationManager.Configuration.EnableDashboardResponseCaching &&
!contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) && !contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) &&
!contentType.StartsWith("font/", StringComparison.OrdinalIgnoreCase)) !contentType.StartsWith("font/", StringComparison.OrdinalIgnoreCase))
{ {
return ResultFactory.GetResult(GetResourceStream(path).Result, contentType); return ResultFactory.GetResult(GetResourceStream(path, isHtml, localizationCulture).Result, contentType);
} }
TimeSpan? cacheDuration = null; TimeSpan? cacheDuration = null;
@ -230,17 +238,24 @@ namespace MediaBrowser.WebDashboard.Api
var assembly = GetType().Assembly.GetName(); var assembly = GetType().Assembly.GetName();
var cacheKey = (assembly.Version + path).GetMD5(); var cacheKey = (assembly.Version + (localizationCulture ?? string.Empty) + path).GetMD5();
return ResultFactory.GetStaticResult(Request, cacheKey, null, cacheDuration, contentType, () => GetResourceStream(path)); return ResultFactory.GetStaticResult(Request, cacheKey, null, cacheDuration, contentType, () => GetResourceStream(path, isHtml, localizationCulture));
}
private string GetLocalizationCulture()
{
return _serverConfigurationManager.Configuration.UICulture;
} }
/// <summary> /// <summary>
/// Gets the resource stream. /// Gets the resource stream.
/// </summary> /// </summary>
/// <param name="path">The path.</param> /// <param name="path">The path.</param>
/// <param name="isHtml">if set to <c>true</c> [is HTML].</param>
/// <param name="localizationCulture">The localization culture.</param>
/// <returns>Task{Stream}.</returns> /// <returns>Task{Stream}.</returns>
private async Task<Stream> GetResourceStream(string path) private async Task<Stream> GetResourceStream(string path, bool isHtml, string localizationCulture)
{ {
Stream resourceStream; Stream resourceStream;
@ -259,13 +274,11 @@ namespace MediaBrowser.WebDashboard.Api
if (resourceStream != null) if (resourceStream != null)
{ {
var isHtml = IsHtml(path);
// Don't apply any caching for html pages // Don't apply any caching for html pages
// jQuery ajax doesn't seem to handle if-modified-since correctly // jQuery ajax doesn't seem to handle if-modified-since correctly
if (isHtml) if (isHtml)
{ {
resourceStream = await ModifyHtml(resourceStream).ConfigureAwait(false); resourceStream = await ModifyHtml(resourceStream, localizationCulture).ConfigureAwait(false);
} }
} }
@ -297,26 +310,48 @@ namespace MediaBrowser.WebDashboard.Api
/// </summary> /// </summary>
/// <param name="sourceStream">The source stream.</param> /// <param name="sourceStream">The source stream.</param>
/// <returns>Task{Stream}.</returns> /// <returns>Task{Stream}.</returns>
internal async Task<Stream> ModifyHtml(Stream sourceStream) private async Task<Stream> ModifyHtml(Stream sourceStream, string localizationCulture)
{ {
string html; using (sourceStream)
using (var memoryStream = new MemoryStream())
{ {
await sourceStream.CopyToAsync(memoryStream).ConfigureAwait(false); string html;
html = Encoding.UTF8.GetString(memoryStream.ToArray()); using (var memoryStream = new MemoryStream())
{
await sourceStream.CopyToAsync(memoryStream).ConfigureAwait(false);
html = Encoding.UTF8.GetString(memoryStream.ToArray());
if (!string.IsNullOrWhiteSpace(localizationCulture))
{
html = _localization.LocalizeDocument(html, localizationCulture, GetLocalizationToken);
}
try
{
var minifier = new HtmlMinifier(new HtmlMinificationSettings(true));
html = minifier.Minify(html).MinifiedContent;
}
catch (Exception ex)
{
Logger.ErrorException("Error minifying html", ex);
}
}
var version = GetType().Assembly.GetName().Version;
html = html.Replace("<head>", "<head>" + GetMetaTags() + GetCommonCss(version) + GetCommonJavascript(version));
var bytes = Encoding.UTF8.GetBytes(html);
return new MemoryStream(bytes);
} }
}
var version = GetType().Assembly.GetName().Version; private string GetLocalizationToken(string phrase)
{
html = html.Replace("<head>", "<head>" + GetMetaTags() + GetCommonCss(version) + GetCommonJavascript(version)); return "${" + phrase + "}";
var bytes = Encoding.UTF8.GetBytes(html);
sourceStream.Dispose();
return new MemoryStream(bytes);
} }
/// <summary> /// <summary>
@ -393,154 +428,200 @@ namespace MediaBrowser.WebDashboard.Api
/// <returns>Task{Stream}.</returns> /// <returns>Task{Stream}.</returns>
private async Task<Stream> GetAllJavascript() private async Task<Stream> GetAllJavascript()
{ {
var scriptFiles = new[]
{
"extensions.js",
"site.js",
"librarybrowser.js",
"librarylist.js",
"editorsidebar.js",
"librarymenu.js",
"chromecast.js",
"contextmenu.js",
"mediacontroller.js",
"mediaplayer.js",
"mediaplayer-video.js",
"ratingdialog.js",
"aboutpage.js",
"allusersettings.js",
"alphapicker.js",
"addpluginpage.js",
"advancedconfigurationpage.js",
"advancedpaths.js",
"advancedserversettings.js",
"metadataadvanced.js",
"appsplayback.js",
"appsweather.js",
"autoorganizetv.js",
"autoorganizelog.js",
"channels.js",
"channelitems.js",
"dashboardinfo.js",
"dashboardpage.js",
"directorybrowser.js",
"dlnaprofile.js",
"dlnaprofiles.js",
"dlnasettings.js",
"editcollectionitems.js",
"edititemmetadata.js",
"edititempeople.js",
"edititemimages.js",
"encodingsettings.js",
"gamesrecommendedpage.js",
"gamesystemspage.js",
"gamespage.js",
"gamegenrepage.js",
"gamestudiospage.js",
"indexpage.js",
"itembynamedetailpage.js",
"itemdetailpage.js",
"itemgallery.js",
"itemlistpage.js",
"librarypathmapping.js",
"libraryreport.js",
"librarysettings.js",
"livetvchannel.js",
"livetvchannels.js",
"livetvguide.js",
"livetvnewrecording.js",
"livetvprogram.js",
"livetvrecording.js",
"livetvrecordinglist.js",
"livetvrecordings.js",
"livetvtimer.js",
"livetvseriestimer.js",
"livetvseriestimers.js",
"livetvsettings.js",
"livetvsuggested.js",
"livetvstatus.js",
"livetvtimers.js",
"loginpage.js",
"logpage.js",
"medialibrarypage.js",
"metadataconfigurationpage.js",
"metadataimagespage.js",
"moviegenres.js",
"moviecollections.js",
"movies.js",
"movieslatest.js",
"moviepeople.js",
"moviesrecommended.js",
"moviestudios.js",
"movietrailers.js",
"musicalbums.js",
"musicalbumartists.js",
"musicartists.js",
"musicgenres.js",
"musicrecommended.js",
"musicvideos.js",
"notifications.js",
"playlist.js",
"plugincatalogpage.js",
"pluginspage.js",
"pluginupdatespage.js",
"remotecontrol.js",
"scheduledtaskpage.js",
"scheduledtaskspage.js",
"search.js",
"songs.js",
"supporterkeypage.js",
"supporterpage.js",
"episodes.js",
"tvgenres.js",
"tvlatest.js",
"tvpeople.js",
"tvrecommended.js",
"tvshows.js",
"tvstudios.js",
"tvupcoming.js",
"useredit.js",
"userpassword.js",
"userimagepage.js",
"userprofilespage.js",
"usersettings.js",
"userparentalcontrol.js",
"wizardfinishpage.js",
"wizardimagesettings.js",
"wizardservice.js",
"wizardstartpage.js",
"wizardsettings.js",
"wizarduserpage.js"
};
var memoryStream = new MemoryStream(); var memoryStream = new MemoryStream();
var newLineBytes = Encoding.UTF8.GetBytes(Environment.NewLine); var newLineBytes = Encoding.UTF8.GetBytes(Environment.NewLine);
// jQuery + jQuery mobile
await AppendResource(memoryStream, "thirdparty/jquery-2.0.3.min.js", newLineBytes).ConfigureAwait(false); await AppendResource(memoryStream, "thirdparty/jquery-2.0.3.min.js", newLineBytes).ConfigureAwait(false);
await AppendResource(memoryStream, "thirdparty/jquerymobile-1.4.2/jquery.mobile-1.4.2.min.js", newLineBytes).ConfigureAwait(false); await AppendResource(memoryStream, "thirdparty/jquerymobile-1.4.2/jquery.mobile-1.4.2.min.js", newLineBytes).ConfigureAwait(false);
await AppendLocalization(memoryStream).ConfigureAwait(false);
await memoryStream.WriteAsync(newLineBytes, 0, newLineBytes.Length).ConfigureAwait(false);
// Write the version string for the dashboard comparison function
var versionString = string.Format("window.dashboardVersion='{0}';", _appHost.ApplicationVersion); var versionString = string.Format("window.dashboardVersion='{0}';", _appHost.ApplicationVersion);
var versionBytes = Encoding.UTF8.GetBytes(versionString); var versionBytes = Encoding.UTF8.GetBytes(versionString);
await memoryStream.WriteAsync(versionBytes, 0, versionBytes.Length).ConfigureAwait(false); await memoryStream.WriteAsync(versionBytes, 0, versionBytes.Length).ConfigureAwait(false);
await memoryStream.WriteAsync(newLineBytes, 0, newLineBytes.Length).ConfigureAwait(false); await memoryStream.WriteAsync(newLineBytes, 0, newLineBytes.Length).ConfigureAwait(false);
await AppendResource(memoryStream, "thirdparty/autonumeric/autoNumeric.min.js", newLineBytes).ConfigureAwait(false); var builder = new StringBuilder();
var assembly = GetType().Assembly; var assembly = GetType().Assembly;
await AppendResource(assembly, memoryStream, "MediaBrowser.WebDashboard.ApiClient.js", newLineBytes).ConfigureAwait(false); using (var stream = assembly.GetManifestResourceStream("MediaBrowser.WebDashboard.ApiClient.js"))
foreach (var file in scriptFiles)
{ {
await AppendResource(memoryStream, "scripts/" + file, newLineBytes).ConfigureAwait(false); using (var streamReader = new StreamReader(stream))
{
var text = await streamReader.ReadToEndAsync().ConfigureAwait(false);
builder.Append(text);
builder.Append(Environment.NewLine);
}
} }
foreach (var file in GetScriptFiles())
{
var path = GetDashboardResourcePath("scripts/" + file);
using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
{
using (var streamReader = new StreamReader(fs))
{
var text = await streamReader.ReadToEndAsync().ConfigureAwait(false);
builder.Append(text);
builder.Append(Environment.NewLine);
}
}
}
var js = builder.ToString();
try
{
var result = new CrockfordJsMinifier().Minify(js, false, Encoding.UTF8);
js = result.MinifiedContent;
}
catch (Exception ex)
{
Logger.ErrorException("Error minifying javascript", ex);
}
var bytes = Encoding.UTF8.GetBytes(js);
await memoryStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
memoryStream.Position = 0; memoryStream.Position = 0;
return memoryStream; return memoryStream;
} }
private IEnumerable<string> GetScriptFiles()
{
return new[]
{
"extensions.js",
"site.js",
"librarybrowser.js",
"librarylist.js",
"editorsidebar.js",
"librarymenu.js",
"chromecast.js",
"contextmenu.js",
"mediacontroller.js",
"mediaplayer.js",
"mediaplayer-video.js",
"ratingdialog.js",
"aboutpage.js",
"allusersettings.js",
"alphapicker.js",
"addpluginpage.js",
"advancedconfigurationpage.js",
"advancedpaths.js",
"advancedserversettings.js",
"metadataadvanced.js",
"appsplayback.js",
"appsweather.js",
"autoorganizetv.js",
"autoorganizelog.js",
"channels.js",
"channelitems.js",
"dashboardinfo.js",
"dashboardpage.js",
"directorybrowser.js",
"dlnaprofile.js",
"dlnaprofiles.js",
"dlnasettings.js",
"editcollectionitems.js",
"edititemmetadata.js",
"edititempeople.js",
"edititemimages.js",
"encodingsettings.js",
"gamesrecommendedpage.js",
"gamesystemspage.js",
"gamespage.js",
"gamegenrepage.js",
"gamestudiospage.js",
"indexpage.js",
"itembynamedetailpage.js",
"itemdetailpage.js",
"itemgallery.js",
"itemlistpage.js",
"librarypathmapping.js",
"libraryreport.js",
"librarysettings.js",
"livetvchannel.js",
"livetvchannels.js",
"livetvguide.js",
"livetvnewrecording.js",
"livetvprogram.js",
"livetvrecording.js",
"livetvrecordinglist.js",
"livetvrecordings.js",
"livetvtimer.js",
"livetvseriestimer.js",
"livetvseriestimers.js",
"livetvsettings.js",
"livetvsuggested.js",
"livetvstatus.js",
"livetvtimers.js",
"loginpage.js",
"logpage.js",
"medialibrarypage.js",
"metadataconfigurationpage.js",
"metadataimagespage.js",
"moviegenres.js",
"moviecollections.js",
"movies.js",
"movieslatest.js",
"moviepeople.js",
"moviesrecommended.js",
"moviestudios.js",
"movietrailers.js",
"musicalbums.js",
"musicalbumartists.js",
"musicartists.js",
"musicgenres.js",
"musicrecommended.js",
"musicvideos.js",
"notifications.js",
"playlist.js",
"plugincatalogpage.js",
"pluginspage.js",
"pluginupdatespage.js",
"remotecontrol.js",
"scheduledtaskpage.js",
"scheduledtaskspage.js",
"search.js",
"songs.js",
"supporterkeypage.js",
"supporterpage.js",
"episodes.js",
"tvgenres.js",
"tvlatest.js",
"tvpeople.js",
"tvrecommended.js",
"tvshows.js",
"tvstudios.js",
"tvupcoming.js",
"useredit.js",
"userpassword.js",
"userimagepage.js",
"userprofilespage.js",
"usersettings.js",
"userparentalcontrol.js",
"wizardfinishpage.js",
"wizardimagesettings.js",
"wizardservice.js",
"wizardstartpage.js",
"wizardsettings.js",
"wizarduserpage.js"
};
}
private async Task AppendLocalization(Stream stream)
{
}
/// <summary> /// <summary>
/// Gets all CSS. /// Gets all CSS.
/// </summary> /// </summary>
@ -568,37 +649,42 @@ namespace MediaBrowser.WebDashboard.Api
"icons.css" "icons.css"
}; };
var memoryStream = new MemoryStream(); var builder = new StringBuilder();
var newLineBytes = Encoding.UTF8.GetBytes(Environment.NewLine);
foreach (var file in files) foreach (var file in files)
{ {
await AppendResource(memoryStream, "css/" + file, newLineBytes).ConfigureAwait(false); var path = GetDashboardResourcePath("css/" + file);
using (var fs = _fileSystem.GetFileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
{
using (var streamReader = new StreamReader(fs))
{
var text = await streamReader.ReadToEndAsync().ConfigureAwait(false);
builder.Append(text);
builder.Append(Environment.NewLine);
}
}
} }
var css = builder.ToString();
try
{
var result = new KristensenCssMinifier().Minify(builder.ToString(), false, Encoding.UTF8);
//css = result.MinifiedContent;
}
catch (Exception ex)
{
Logger.ErrorException("Error minifying css", ex);
}
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(css));
memoryStream.Position = 0; memoryStream.Position = 0;
return memoryStream; return memoryStream;
} }
/// <summary>
/// Appends the resource.
/// </summary>
/// <param name="assembly">The assembly.</param>
/// <param name="outputStream">The output stream.</param>
/// <param name="path">The path.</param>
/// <param name="newLineBytes">The new line bytes.</param>
/// <returns>Task.</returns>
private async Task AppendResource(Assembly assembly, Stream outputStream, string path, byte[] newLineBytes)
{
using (var stream = assembly.GetManifestResourceStream(path))
{
await stream.CopyToAsync(outputStream).ConfigureAwait(false);
await outputStream.WriteAsync(newLineBytes, 0, newLineBytes.Length).ConfigureAwait(false);
}
}
/// <summary> /// <summary>
/// Appends the resource. /// Appends the resource.
/// </summary> /// </summary>

View File

@ -57,6 +57,9 @@
<Reference Include="ServiceStack.Interfaces"> <Reference Include="ServiceStack.Interfaces">
<HintPath>..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll</HintPath> <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll</HintPath>
</Reference> </Reference>
<Reference Include="WebMarkupMin.Core">
<HintPath>..\packages\WebMarkupMin.Core.0.8.18\lib\net40\WebMarkupMin.Core.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\SharedVersion.cs"> <Compile Include="..\SharedVersion.cs">
@ -641,9 +644,6 @@
<Content Include="dashboard-ui\livetvseriestimers.html"> <Content Include="dashboard-ui\livetvseriestimers.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="dashboard-ui\thirdparty\autonumeric\autoNumeric.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\thirdparty\jquery-2.0.3.min.js"> <Content Include="dashboard-ui\thirdparty\jquery-2.0.3.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@ -1477,9 +1477,6 @@
<Content Include="dashboard-ui\scripts\tvstudios.js"> <Content Include="dashboard-ui\scripts\tvstudios.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="dashboard-ui\thirdparty\autonumeric\autoNumeric.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\thirdparty\jstree1.0\jquery.jstree.js"> <Content Include="dashboard-ui\thirdparty\jstree1.0\jquery.jstree.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@ -1970,6 +1967,7 @@
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.config" />
<None Include="dashboard-ui\css\fonts\OpenSans-ExtraBold.woff"> <None Include="dashboard-ui\css\fonts\OpenSans-ExtraBold.woff">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
@ -1983,6 +1981,9 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="WebMarkupMin.Configuration.xsd">
<SubType>Designer</SubType>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="webMarkupMin">
<section name="core" type="WebMarkupMin.Core.Configuration.CoreConfiguration, WebMarkupMin.Core" />
</sectionGroup>
</configSections>
<webMarkupMin xmlns="http://tempuri.org/WebMarkupMin.Configuration.xsd">
<core>
<css>
<minifiers>
<add name="NullCssMinifier" displayName="Null CSS Minifier" type="WebMarkupMin.Core.Minifiers.NullCssMinifier, WebMarkupMin.Core" />
<add name="KristensenCssMinifier" displayName="Mads Kristensen's CSS minifier" type="WebMarkupMin.Core.Minifiers.KristensenCssMinifier, WebMarkupMin.Core" />
</minifiers>
</css>
<js>
<minifiers>
<add name="NullJsMinifier" displayName="Null JS Minifier" type="WebMarkupMin.Core.Minifiers.NullJsMinifier, WebMarkupMin.Core" />
<add name="CrockfordJsMinifier" displayName="Douglas Crockford's JS Minifier" type="WebMarkupMin.Core.Minifiers.CrockfordJsMinifier, WebMarkupMin.Core" />
</minifiers>
</js>
<logging>
<loggers>
<add name="NullLogger" displayName="Null Logger" type="WebMarkupMin.Core.Loggers.NullLogger, WebMarkupMin.Core" />
<add name="ThrowExceptionLogger" displayName="Throw exception logger" type="WebMarkupMin.Core.Loggers.ThrowExceptionLogger, WebMarkupMin.Core" />
</loggers>
</logging>
</core>
</webMarkupMin>
</configuration>

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.249" targetFramework="net45" /> <package id="MediaBrowser.ApiClient.Javascript" version="3.0.249" targetFramework="net45" />
<package id="WebMarkupMin.Core" version="0.8.18" targetFramework="net45" />
</packages> </packages>