@ -139,6 +139,23 @@ namespace MediaBrowser.WebDashboard.Api
_memoryStreamFactory = memoryStreamFactory ;
}
/// <summary>
/// Gets the dashboard UI path.
/// </summary>
/// <value>The dashboard UI path.</value>
public string DashboardUIPath
{
get
{
if ( ! string . IsNullOrEmpty ( _serverConfigurationManager . Configuration . DashboardSourcePath ) )
{
return _serverConfigurationManager . Configuration . DashboardSourcePath ;
}
return Path . Combine ( _serverConfigurationManager . ApplicationPaths . ApplicationResourcesPath , "dashboard-ui" ) ;
}
}
public object Get ( GetFavIcon request )
{
return Get ( new GetDashboardResource
@ -176,7 +193,7 @@ namespace MediaBrowser.WebDashboard.Api
if ( plugin ! = null & & stream ! = null )
{
return _resultFactory . GetStaticResult ( Request , plugin . Version . ToString ( ) . GetMD5 ( ) , null , null , MimeTypes . GetMimeType ( "page.html" ) , ( ) = > GetPackageCreator ( ) . ModifyHtml ( "dummy.html" , stream , null , _appHost . ApplicationVersion . ToString ( ) , null ) ) ;
return _resultFactory . GetStaticResult ( Request , plugin . Version . ToString ( ) . GetMD5 ( ) , null , null , MimeTypes . GetMimeType ( "page.html" ) , ( ) = > GetPackageCreator ( DashboardUIPath ) . ModifyHtml ( "dummy.html" , stream , null , _appHost . ApplicationVersion . ToString ( ) , null ) ) ;
}
throw new ResourceNotFoundException ( ) ;
@ -274,9 +291,11 @@ namespace MediaBrowser.WebDashboard.Api
path = path . Replace ( "bower_components" + _appHost . ApplicationVersion , "bower_components" , StringComparison . OrdinalIgnoreCase ) ;
var contentType = MimeTypes . GetMimeType ( path ) ;
var basePath = DashboardUIPath ;
// Bounce them to the startup wizard if it hasn't been completed yet
if ( ! _serverConfigurationManager . Configuration . IsStartupWizardCompleted & & path . IndexOf ( "wizard" , StringComparison . OrdinalIgnoreCase ) = = - 1 & & GetPackageCreator ( ) . IsCoreHtml ( path ) )
if ( ! _serverConfigurationManager . Configuration . IsStartupWizardCompleted & &
path . IndexOf ( "wizard" , StringComparison . OrdinalIgnoreCase ) = = - 1 & & GetPackageCreator ( basePath ) . IsCoreHtml ( path ) )
{
// But don't redirect if an html import is being requested.
if ( path . IndexOf ( "bower_components" , StringComparison . OrdinalIgnoreCase ) = = - 1 )
@ -296,7 +315,7 @@ namespace MediaBrowser.WebDashboard.Api
! contentType . StartsWith ( "image/" , StringComparison . OrdinalIgnoreCase ) & &
! contentType . StartsWith ( "font/" , StringComparison . OrdinalIgnoreCase ) )
{
var stream = await GetResourceStream ( path, localizationCulture ) . ConfigureAwait ( false ) ;
var stream = await GetResourceStream ( basePath, path, localizationCulture ) . ConfigureAwait ( false ) ;
return _resultFactory . GetResult ( stream , contentType ) ;
}
@ -311,7 +330,7 @@ namespace MediaBrowser.WebDashboard.Api
var cacheKey = ( _appHost . ApplicationVersion + ( localizationCulture ? ? string . Empty ) + path ) . GetMD5 ( ) ;
return await _resultFactory . GetStaticResult ( Request , cacheKey , null , cacheDuration , contentType , ( ) = > GetResourceStream ( path, localizationCulture ) ) . ConfigureAwait ( false ) ;
return await _resultFactory . GetStaticResult ( Request , cacheKey , null , cacheDuration , contentType , ( ) = > GetResourceStream ( basePath, path, localizationCulture ) ) . ConfigureAwait ( false ) ;
}
private string GetLocalizationCulture ( )
@ -322,86 +341,72 @@ namespace MediaBrowser.WebDashboard.Api
/// <summary>
/// Gets the resource stream.
/// </summary>
/// <param name="path">The path.</param>
/// <param name="localizationCulture">The localization culture.</param>
/// <returns>Task{Stream}.</returns>
private Task < Stream > GetResourceStream ( string path , string localizationCulture )
private Task < Stream > GetResourceStream ( string basePath , string virtualPath , string localizationCulture )
{
return GetPackageCreator ( )
. GetResource ( p ath, null , localizationCulture , _appHost . ApplicationVersion . ToString ( ) ) ;
return GetPackageCreator ( basePath )
. GetResource ( virtualPath , null , localizationCulture , _appHost . ApplicationVersion . ToString ( ) ) ;
}
private PackageCreator GetPackageCreator ( )
private PackageCreator GetPackageCreator ( string basePath )
{
return new PackageCreator ( _fileSystem, _logger , _serverConfigurationManager , _memoryStreamFactory ) ;
return new PackageCreator ( basePath, _fileSystem, _logger , _serverConfigurationManager , _memoryStreamFactory ) ;
}
public async Task < object > Get ( GetDashboardPackage request )
{
var mode = request . Mode ;
var path = ! string . IsNullOrWhiteSpace ( mode ) ?
Path . Combine ( _serverConfigurationManager . ApplicationPaths . ProgramDataPath , "webclient-dump" )
var inputPath = string . IsNullOrWhiteSpace ( mode ) ?
DashboardUIPath
: "C:\\dev\\emby-web-mobile-master\\dist" ;
var targetPath = ! string . IsNullOrWhiteSpace ( mode ) ?
inputPath
: "C:\\dev\\emby-web-mobile\\src" ;
try
{
_fileSystem . DeleteDirectory ( path , true ) ;
}
catch ( IOException )
{
var packageCreator = GetPackageCreator ( inputPath ) ;
}
if ( ! string . Equals ( inputPath , targetPath , StringComparison . OrdinalIgnoreCase ) )
{
try
{
_fileSystem . DeleteDirectory ( targetPath , true ) ;
}
catch ( IOException )
{
var creator = GetPackageCreator ( ) ;
}
CopyDirectory ( creator . DashboardUIPath , path ) ;
CopyDirectory ( inputPath , targetPath ) ;
}
string culture = null ;
var appVersion = _appHost . ApplicationVersion . ToString ( ) ;
// Try to trim the output size a bit
var bowerPath = Path . Combine ( path , "bower_components" ) ;
if ( ! string . IsNullOrWhiteSpace ( mode ) )
{
// Delete things that are unneeded in an attempt to keep the output as trim as possible
DeleteFoldersByName ( Path . Combine ( bowerPath , "emby-webcomponents" , "fonts" ) , "roboto" ) ;
_fileSystem . DeleteDirectory ( Path . Combine ( path , "css" , "images" , "tour" ) , true ) ;
}
await DumpHtml ( creator . DashboardUIPath , path , mode , culture , appVersion ) ;
await DumpHtml ( packageCreator , inputPath , targetPath , mode , culture , appVersion ) ;
return "" ;
}
private void DeleteFoldersByName ( string path , string name )
{
var directories = _fileSystem . GetDirectories ( path , true )
. Where ( i = > string . Equals ( i . Name , name , StringComparison . OrdinalIgnoreCase ) )
. ToList ( ) ;
foreach ( var directory in directories )
{
_fileSystem . DeleteDirectory ( directory . FullName , true ) ;
}
}
private async Task DumpHtml ( string source , string destination , string mode , string culture , string appVersion )
private async Task DumpHtml ( PackageCreator packageCreator , string source , string destination , string mode , string culture , string appVersion )
{
foreach ( var file in _fileSystem . GetFiles ( source ) )
{
var filename = file . Name ;
await DumpFile ( filename , Path . Combine ( destination , filename ) , mode , culture , appVersion ) . ConfigureAwait ( false ) ;
if ( ! string . Equals ( file . Extension , ".html" , StringComparison . OrdinalIgnoreCase ) )
{
continue ;
}
await DumpFile ( packageCreator , filename , Path . Combine ( destination , filename ) , mode , culture , appVersion ) . ConfigureAwait ( false ) ;
}
}
private async Task DumpFile ( string resourceVirtualPath , string destinationFilePath , string mode , string culture , string appVersion )
private async Task DumpFile ( PackageCreator packageCreator , string resourceVirtualPath , string destinationFilePath , string mode , string culture , string appVersion )
{
using ( var stream = await GetPackageCreator( ) . GetResource ( resourceVirtualPath , mode , culture , appVersion ) . ConfigureAwait ( false ) )
using ( var stream = await packageCreator . GetResource ( resourceVirtualPath , mode , culture , appVersion ) . ConfigureAwait ( false ) )
{
using ( var fs = _fileSystem . GetFileStream ( destinationFilePath , FileOpenMode . Create , FileAccessMode . Write , FileShareMode . Read ) )
{