Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Tim Hobbs 2014-03-30 19:42:45 -07:00
commit 5693327a20
26 changed files with 702 additions and 225 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>
/// Class CulturesService
/// </summary>
@ -62,6 +70,13 @@ namespace MediaBrowser.Api
return ToOptimizedSerializedResultUsingCache(result);
}
public object Get(GetLocalizationOptions request)
{
var result = _localization.GetLocalizationOptions().ToList();
return ToOptimizedSerializedResultUsingCache(result);
}
/// <summary>
/// Gets the specified request.
/// </summary>

View file

@ -1242,19 +1242,9 @@ namespace MediaBrowser.Api.Playback
}
else if (i == 14)
{
if (videoRequest != null)
{
videoRequest.Framerate = int.Parse(val, UsCulture);
}
request.StartTimeTicks = long.Parse(val, UsCulture);
}
else if (i == 15)
{
if (videoRequest != null)
{
request.StartTimeTicks = long.Parse(val, UsCulture);
}
}
else if (i == 16)
{
if (videoRequest != null)
{

View file

@ -276,7 +276,7 @@ namespace MediaBrowser.Api.Playback.Hls
? 0
: ((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);

View file

@ -1,7 +1,7 @@
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Localization
{
@ -31,5 +31,42 @@ namespace MediaBrowser.Controller.Localization
/// <param name="rating">The rating.</param>
/// <returns>System.Int32.</returns>
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();
/// <summary>
/// Gets the java script localization dictionary.
/// </summary>
/// <param name="culture">The culture.</param>
/// <returns>Dictionary{System.StringSystem.String}.</returns>
Dictionary<string, string> GetJavaScriptLocalizationDictionary(string culture);
}
}

View file

@ -218,6 +218,8 @@ namespace MediaBrowser.Model.Configuration
public string ServerName { get; set; }
public string WanDdns { get; set; }
public string UICulture { get; set; }
public DlnaOptions DlnaOptions { get; set; }
/// <summary>
@ -281,6 +283,8 @@ namespace MediaBrowser.Model.Configuration
MetadataOptions = options.ToArray();
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>
public string ThreeLetterISORegionName { get; set; }
}
public class LocalizatonOption
{
public string Name { get; set; }
public string Value { get; set; }
}
}

View file

@ -257,8 +257,12 @@ namespace MediaBrowser.Server.Implementations.IO
InternalBufferSize = 32767
};
newWatcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.DirectoryName |
NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Size;
newWatcher.NotifyFilter = NotifyFilters.CreationTime |
NotifyFilters.DirectoryName |
NotifyFilters.FileName |
NotifyFilters.LastWrite |
NotifyFilters.Size |
NotifyFilters.Attributes;
newWatcher.Created += watcher_Changed;
newWatcher.Deleted += watcher_Changed;

View file

@ -0,0 +1,21 @@
{
"SettingsSaved": "Settings saved.",
"AddUser": "Add User",
"Users": "Users",
"Delete": "Delete",
"Administrator": "Administrator",
"Password": "Password",
"CreatePassword": "Create Password",
"DeleteImage": "Delete Image",
"DeleteImageConfirmation": "Are you sure you wish to delete this image?",
"FileReadCancelled": "The file read has been cancelled.",
"FileNotFound": "File not found.",
"FileReadError": "An error occurred while reading the file.",
"DeleteUser": "Delete User",
"DeleteUserConfirmation": "Are you sure you wish to delete {0}?",
"PasswordResetHeader": "Password Reset",
"PasswordResetComplete": "The password has been reset.",
"PasswordResetConfirmation": "Are you sure you wish to reset the password?",
"PasswordSaved": "Password saved.",
"PasswordMatchError": "Password and password confirmation must match."
}

View file

@ -0,0 +1,21 @@
{
"SettingsSaved": "Settings saved.",
"AddUser": "Add User",
"Users": "Users",
"Delete": "Delete",
"Administrator": "Administrator",
"Password": "Password",
"CreatePassword": "Create Password",
"DeleteImage": "Delete Image",
"DeleteImageConfirmation": "Are you sure you wish to delete this image?",
"FileReadCancelled": "The file read has been cancelled.",
"FileNotFound": "File not found.",
"FileReadError": "An error occurred while reading the file.",
"DeleteUser": "Delete User",
"DeleteUserConfirmation": "Are you sure you wish to delete {0}?",
"PasswordResetHeader": "Password Reset",
"PasswordResetComplete": "The password has been reset.",
"PasswordResetConfirmation": "Are you sure you wish to reset the password?",
"PasswordSaved": "Password saved.",
"PasswordMatchError": "Password and password confirmation must match."
}

View file

@ -0,0 +1,21 @@
{
"SettingsSaved": "Configura\u00e7\u00f5es guardadas.",
"AddUser": "Adicionar Utilizador",
"Users": "Utilizadores",
"Delete": "Apagar",
"Administrator": "Administrador",
"Password": "Senha",
"CreatePassword": "Criar Senha",
"DeleteImage": "Apagar Imagem",
"DeleteImageConfirmation": "Tem a certeza que pretende apagar a imagem?",
"FileReadCancelled": "The file read has been cancelled.",
"FileNotFound": "Ficheiro n\u00e3o encontrado",
"FileReadError": "Ocorreu um erro ao ler o ficheiro.",
"DeleteUser": "Apagar Utilizador",
"DeleteUserConfirmation": "Tem a certeza que pretende apagar {0}?",
"PasswordResetHeader": "Password Reset",
"PasswordResetComplete": "The password has been reset.",
"PasswordResetConfirmation": "Are you sure you wish to reset the password?",
"PasswordSaved": "Senha guardada.",
"PasswordMatchError": "Password and password confirmation must match."
}

View file

@ -1,9 +1,9 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Serialization;
using MoreLinq;
using System;
using System.Collections.Concurrent;
@ -11,6 +11,8 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using MediaBrowser.Common.Extensions;
namespace MediaBrowser.Server.Implementations.Localization
{
@ -33,15 +35,17 @@ namespace MediaBrowser.Server.Implementations.Localization
new ConcurrentDictionary<string, Dictionary<string, ParentalRating>>(StringComparer.OrdinalIgnoreCase);
private readonly IFileSystem _fileSystem;
private readonly IJsonSerializer _jsonSerializer;
/// <summary>
/// Initializes a new instance of the <see cref="LocalizationManager"/> class.
/// </summary>
/// <param name="configurationManager">The configuration manager.</param>
public LocalizationManager(IServerConfigurationManager configurationManager, IFileSystem fileSystem)
public LocalizationManager(IServerConfigurationManager configurationManager, IFileSystem fileSystem, IJsonSerializer jsonSerializer)
{
_configurationManager = configurationManager;
_fileSystem = fileSystem;
_jsonSerializer = jsonSerializer;
ExtractAll();
}
@ -241,5 +245,112 @@ namespace MediaBrowser.Server.Implementations.Localization
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"},
new LocalizatonOption{ Name="German", Value="de"},
new LocalizatonOption{ Name="Portuguese (Portugal)", Value="pt-PT"},
new LocalizatonOption{ Name="Russian", Value="ru"}
}.OrderBy(i => i.Name);
}
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": "Ende",
"LabelVisitCommunity": "Besuche die Community",
"LabelGithubWiki": "Github Wiki",
"LabelSwagger": "Swagger",
"LabelStandard": "Standard",
"LabelViewApiDocumentation": "Zeige Api Dokumentation",
"LabelBrowseLibrary": "Durchsuche Bibliothek",
"LabelConfigureMediaBrowser": "Konfiguriere Media Browser",
"LabelOpenLibraryViewer": "\u00d6ffne Bibliothekenansicht",
"LabelRestartServer": "Server neustarten",
"LabelShowLogWindow": "Zeige Log Fenster",
"LabelPrevious": "Vorheriges",
"LabelFinish": "Ende",
"LabelNext": "N\u00e4chstes",
"LabelYoureDone": "Du bist fertig!"
}

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

@ -0,0 +1,17 @@
{
"LabelExit": "Sair",
"LabelVisitCommunity": "Visitar a Comunidade",
"LabelGithubWiki": "Wiki Github",
"LabelSwagger": "Swagger",
"LabelStandard": "Padr\u00e3o",
"LabelViewApiDocumentation": "Ver Documenta\u00e7\u00e3o da API",
"LabelBrowseLibrary": "Navegar na Biblioteca",
"LabelConfigureMediaBrowser": "Configurar Media Browser",
"LabelOpenLibraryViewer": "Abrir Visualizador da Biblioteca",
"LabelRestartServer": "Reiniciar Servidor",
"LabelShowLogWindow": "Mostrar Janela de Log",
"LabelPrevious": "Anterior",
"LabelFinish": "Terminar",
"LabelNext": "Seguinte",
"LabelYoureDone": "Concluiu!"
}

View file

@ -0,0 +1,17 @@
{
"LabelExit": "\u0412\u044b\u0445\u043e\u0434",
"LabelVisitCommunity": "\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u044c \u0421\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e",
"LabelGithubWiki": "\u0412\u0438\u043a\u0438 \u043d\u0430 Github",
"LabelSwagger": "\u041e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u0435",
"LabelStandard": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439",
"LabelViewApiDocumentation": "\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e API",
"LabelBrowseLibrary": "\u041e\u0431\u043e\u0437\u0440\u0435\u0432\u0430\u0442\u0435\u043b\u044c \u041c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438",
"LabelConfigureMediaBrowser": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Media Browser",
"LabelOpenLibraryViewer": "\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u041c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438",
"LabelRestartServer": "\u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440",
"LabelShowLogWindow": "\u041e\u043a\u043d\u043e \u0416\u0443\u0440\u043d\u0430\u043b\u0430",
"LabelPrevious": "\u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0435",
"LabelFinish": "\u0417\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c",
"LabelNext": "\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435",
"LabelYoureDone": "\u0412\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0438!"
}

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,14 @@
<EmbeddedResource Include="Localization\Ratings\ru.txt" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Localization\JavaScript\javascript.json" />
<EmbeddedResource Include="Localization\Server\server.json" />
<EmbeddedResource Include="Localization\Server\de.json" />
<EmbeddedResource Include="Localization\Server\pt_PT.json" />
<EmbeddedResource Include="Localization\Server\ru.json" />
<EmbeddedResource Include="Localization\JavaScript\en_US.json" />
<EmbeddedResource Include="Localization\JavaScript\pt_PT.json" />
<EmbeddedResource Include="Localization\Server\en_US.json" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
@ -386,6 +394,7 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<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.

View file

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

View file

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

View file

@ -253,7 +253,7 @@ namespace MediaBrowser.ServerApplication
{
//Application.EnableVisualStyles();
//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();
}

View file

@ -4,6 +4,7 @@ using System.Windows.Forms;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
@ -41,6 +42,7 @@ namespace MediaBrowser.ServerApplication
private readonly IJsonSerializer _jsonSerializer;
private readonly IDisplayPreferencesRepository _displayPreferencesManager;
private readonly IItemRepository _itemRepository;
private readonly ILocalizationManager _localization;
private LogForm _logForm;
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");
_itemRepository = itemRepo;
_localization = localization;
_appHost = appHost;
_logManager = logManager;
_configurationManager = configurationManager;
@ -118,20 +127,17 @@ namespace MediaBrowser.ServerApplication
//
cmdExit.Name = "cmdExit";
cmdExit.Size = new System.Drawing.Size(208, 22);
cmdExit.Text = "Exit";
//
// cmdCommunity
//
cmdCommunity.Name = "cmdCommunity";
cmdCommunity.Size = new System.Drawing.Size(208, 22);
cmdCommunity.Text = "Visit Community";
//
// cmdLogWindow
//
cmdLogWindow.CheckOnClick = true;
cmdLogWindow.Name = "cmdLogWindow";
cmdLogWindow.Size = new System.Drawing.Size(208, 22);
cmdLogWindow.Text = "Show Log Window";
//
// toolStripSeparator1
//
@ -142,13 +148,11 @@ namespace MediaBrowser.ServerApplication
//
cmdRestart.Name = "cmdRestart";
cmdRestart.Size = new System.Drawing.Size(208, 22);
cmdRestart.Text = "Restart Server";
//
// cmdLibraryExplorer
//
cmdLibraryExplorer.Name = "cmdLibraryExplorer";
cmdLibraryExplorer.Size = new System.Drawing.Size(208, 22);
cmdLibraryExplorer.Text = "Open Library Explorer";
//
// toolStripSeparator2
//
@ -159,13 +163,11 @@ namespace MediaBrowser.ServerApplication
//
cmdConfigure.Name = "cmdConfigure";
cmdConfigure.Size = new System.Drawing.Size(208, 22);
cmdConfigure.Text = "Configure Media Browser";
//
// cmdBrowse
//
cmdBrowse.Name = "cmdBrowse";
cmdBrowse.Size = new System.Drawing.Size(208, 22);
cmdBrowse.Text = "Browse Library";
//
// cmdApiDocs
//
@ -175,25 +177,21 @@ namespace MediaBrowser.ServerApplication
cmdGtihub});
cmdApiDocs.Name = "cmdApiDocs";
cmdApiDocs.Size = new System.Drawing.Size(208, 22);
cmdApiDocs.Text = "View Api Documentation";
//
// cmdStandardDocs
//
cmdStandardDocs.Name = "cmdStandardDocs";
cmdStandardDocs.Size = new System.Drawing.Size(136, 22);
cmdStandardDocs.Text = "Standard";
//
// cmdSwagger
//
cmdSwagger.Name = "cmdSwagger";
cmdSwagger.Size = new System.Drawing.Size(136, 22);
cmdSwagger.Text = "Swagger";
//
// cmdGtihub
//
cmdGtihub.Name = "cmdGtihub";
cmdGtihub.Size = new System.Drawing.Size(136, 22);
cmdGtihub.Text = "Github Wiki";
cmdExit.Click += cmdExit_Click;
cmdRestart.Click += cmdRestart_Click;
@ -211,6 +209,8 @@ namespace MediaBrowser.ServerApplication
_logManager.LoggerLoaded += LoadLogWindow;
_configurationManager.ConfigurationUpdated += Instance_ConfigurationUpdated;
LocalizeText();
if (_appHost.IsFirstRun)
{
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>
/// Handles the ConfigurationUpdated event of the Instance control.
/// </summary>
@ -226,6 +244,12 @@ namespace MediaBrowser.ServerApplication
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
void Instance_ConfigurationUpdated(object sender, EventArgs e)
{
if (!string.Equals(_configurationManager.Configuration.UICulture, _uiCulture,
StringComparison.OrdinalIgnoreCase))
{
LocalizeText();
}
Action action = () =>
{
var isLogWindowOpen = _logForm != null;
@ -307,7 +331,7 @@ namespace MediaBrowser.ServerApplication
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)

View file

@ -121,9 +121,9 @@
this.lblStatus.Location = new System.Drawing.Point(3, 0);
this.lblStatus.MaximumSize = new System.Drawing.Size(0, 100);
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.Text = "Loading Media Browser Server";
this.lblStatus.Text = "Loading Media Browser";
this.lblStatus.UseWaitCursor = true;
//
// panel1

View file

@ -3,9 +3,11 @@ using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using ServiceStack;
using ServiceStack.Web;
using System;
@ -15,6 +17,8 @@ using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WebMarkupMin.Core.Minifiers;
using WebMarkupMin.Core.Settings;
namespace MediaBrowser.WebDashboard.Api
{
@ -96,6 +100,8 @@ namespace MediaBrowser.WebDashboard.Api
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly IFileSystem _fileSystem;
private readonly ILocalizationManager _localization;
private readonly IJsonSerializer _jsonSerializer;
/// <summary>
/// Initializes a new instance of the <see cref="DashboardService" /> class.
@ -103,11 +109,13 @@ namespace MediaBrowser.WebDashboard.Api
/// <param name="appHost">The app host.</param>
/// <param name="serverConfigurationManager">The server configuration manager.</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, IJsonSerializer jsonSerializer)
{
_appHost = appHost;
_serverConfigurationManager = serverConfigurationManager;
_fileSystem = fileSystem;
_localization = localization;
_jsonSerializer = jsonSerializer;
}
/// <summary>
@ -148,7 +156,7 @@ namespace MediaBrowser.WebDashboard.Api
{
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>
@ -210,13 +218,16 @@ namespace MediaBrowser.WebDashboard.Api
var contentType = MimeTypes.GetMimeType(path);
var isHtml = IsHtml(path);
var localizationCulture = isHtml ? GetLocalizationCulture() : null;
// Don't cache if not configured to do so
// But always cache images to simulate production
if (!_serverConfigurationManager.Configuration.EnableDashboardResponseCaching &&
!contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) &&
if (!_serverConfigurationManager.Configuration.EnableDashboardResponseCaching &&
!contentType.StartsWith("image/", 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;
@ -230,17 +241,24 @@ namespace MediaBrowser.WebDashboard.Api
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>
/// Gets the resource stream.
/// </summary>
/// <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>
private async Task<Stream> GetResourceStream(string path)
private async Task<Stream> GetResourceStream(string path, bool isHtml, string localizationCulture)
{
Stream resourceStream;
@ -259,13 +277,11 @@ namespace MediaBrowser.WebDashboard.Api
if (resourceStream != null)
{
var isHtml = IsHtml(path);
// Don't apply any caching for html pages
// jQuery ajax doesn't seem to handle if-modified-since correctly
if (isHtml)
{
resourceStream = await ModifyHtml(resourceStream).ConfigureAwait(false);
resourceStream = await ModifyHtml(resourceStream, localizationCulture).ConfigureAwait(false);
}
}
@ -297,26 +313,48 @@ namespace MediaBrowser.WebDashboard.Api
/// </summary>
/// <param name="sourceStream">The source stream.</param>
/// <returns>Task{Stream}.</returns>
internal async Task<Stream> ModifyHtml(Stream sourceStream)
private async Task<Stream> ModifyHtml(Stream sourceStream, string localizationCulture)
{
string html;
using (var memoryStream = new MemoryStream())
using (sourceStream)
{
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;
html = html.Replace("<head>", "<head>" + GetMetaTags() + GetCommonCss(version) + GetCommonJavascript(version));
var bytes = Encoding.UTF8.GetBytes(html);
sourceStream.Dispose();
return new MemoryStream(bytes);
private string GetLocalizationToken(string phrase)
{
return "${" + phrase + "}";
}
/// <summary>
@ -393,154 +431,204 @@ namespace MediaBrowser.WebDashboard.Api
/// <returns>Task{Stream}.</returns>
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 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/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 versionBytes = Encoding.UTF8.GetBytes(versionString);
await memoryStream.WriteAsync(versionBytes, 0, versionBytes.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;
await AppendResource(assembly, memoryStream, "MediaBrowser.WebDashboard.ApiClient.js", newLineBytes).ConfigureAwait(false);
foreach (var file in scriptFiles)
using (var stream = assembly.GetManifestResourceStream("MediaBrowser.WebDashboard.ApiClient.js"))
{
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;
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",
"dashboardgeneral.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)
{
var js = "window.localizationGlossary=" + _jsonSerializer.SerializeToString(_localization.GetJavaScriptLocalizationDictionary(GetLocalizationCulture()));
var bytes = Encoding.UTF8.GetBytes(js);
await stream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
}
/// <summary>
/// Gets all CSS.
/// </summary>
@ -568,37 +656,42 @@ namespace MediaBrowser.WebDashboard.Api
"icons.css"
};
var memoryStream = new MemoryStream();
var newLineBytes = Encoding.UTF8.GetBytes(Environment.NewLine);
var builder = new StringBuilder();
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;
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>
/// Appends the resource.
/// </summary>

View file

@ -57,6 +57,9 @@
<Reference Include="ServiceStack.Interfaces">
<HintPath>..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll</HintPath>
</Reference>
<Reference Include="WebMarkupMin.Core">
<HintPath>..\packages\WebMarkupMin.Core.0.8.18\lib\net40\WebMarkupMin.Core.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\SharedVersion.cs">
@ -221,6 +224,9 @@
<Content Include="dashboard-ui\css\mediaplayer.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\dashboardgeneral.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\dashboardinfopage.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -515,6 +521,9 @@
<Content Include="dashboard-ui\scripts\contextmenu.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\dashboardgeneral.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\dashboardinfo.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -641,9 +650,6 @@
<Content Include="dashboard-ui\livetvseriestimers.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</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">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -1477,9 +1483,6 @@
<Content Include="dashboard-ui\scripts\tvstudios.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\thirdparty\autonumeric\autoNumeric.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\thirdparty\jstree1.0\jquery.jstree.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -1970,6 +1973,7 @@
</Content>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="dashboard-ui\css\fonts\OpenSans-ExtraBold.woff">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@ -1983,6 +1987,9 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
<None Include="WebMarkupMin.Configuration.xsd">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup />
<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"?>
<packages>
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.249" targetFramework="net45" />
<package id="WebMarkupMin.Core" version="0.8.18" targetFramework="net45" />
</packages>