Merge pull request #325 from jellyfin/dev

Master 3.5.2-5
This commit is contained in:
Joshua M. Boniface 2018-12-30 01:04:27 -05:00 committed by GitHub
commit 76b647e0a8
75 changed files with 840 additions and 433 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
CONTRIBUTORS.md merge=union

View File

@ -1,68 +0,0 @@
[CmdletBinding()]
param(
[switch]$InstallFFMPEG,
[switch]$GenerateZip,
[string]$InstallLocation = "$Env:AppData/JellyFin-Server/",
[ValidateSet('Debug','Release')][string]$BuildType = 'Release',
[ValidateSet('Quiet','Minimal', 'Normal')][string]$DotNetVerbosity = 'Minimal',
[ValidateSet('win','win7', 'win8','win81','win10')][string]$WindowsVersion = 'win',
[ValidateSet('x64','x86', 'arm', 'arm64')][string]$Architecture = 'x64'
)
function Build-JellyFin {
if($Architecture -eq 'arm64'){
if($WindowsVersion -ne 'win10'){
Write-Error "arm64 only supported with Windows10 Version"
exit
}
}
if($Architecture -eq 'arm'){
if($WindowsVersion -notin @('win10','win81','win8')){
Write-Error "arm only supported with Windows 8 or higher"
exit
}
}
dotnet publish -c $BuildType -r "$windowsversion-$Architecture" MediaBrowser.sln -o $InstallLocation -v $DotNetVerbosity
}
function Install-FFMPEG {
param(
[string]$InstallLocation,
[string]$Architecture
)
Write-Verbose "Checking Architecture"
if($Architecture -notin @('x86','x64')){
Write-Warning "No builds available for your selected architecture of $Architecture"
Write-Warning "FFMPEG will not be installed"
}elseif($Architecture -eq 'x64'){
Write-Verbose "Downloading 64 bit FFMPEG"
Invoke-WebRequest -Uri https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-4.1-win64-static.zip -UseBasicParsing -OutFile "$env:TEMP/fmmpeg.zip" | Write-Verbose
}else{
Write-Verbose "Downloading 32 bit FFMPEG"
Invoke-WebRequest -Uri https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-4.1-win32-static.zip -UseBasicParsing -OutFile "$env:TEMP/fmmpeg.zip" | Write-Verbose
}
Expand-Archive "$env:TEMP/fmmpeg.zip" -DestinationPath "$env:TEMP/ffmpeg/" | Write-Verbose
if($Architecture -eq 'x64'){
Write-Verbose "Copying Binaries to Jellyfin location"
Get-ChildItem "$env:temp/ffmpeg/ffmpeg-4.1-win64-static/bin" | ForEach-Object {
Copy-Item $_.FullName -Destination $installLocation | Write-Verbose
}
}else{
Write-Verbose "Copying Binaries to Jellyfin location"
Get-ChildItem "$env:temp/ffmpeg/ffmpeg-4.1-win32-static/bin" | ForEach-Object {
Copy-Item $_.FullName -Destination $installLocation | Write-Verbose
}
}
Remove-Item "$env:TEMP/ffmpeg/" -Recurse -Force -ErrorAction Continue | Write-Verbose
Remove-Item "$env:TEMP/fmmpeg.zip" -Force -ErrorAction Continue | Write-Verbose
}
Write-Verbose "Starting Build Process: Selected Environment is $WindowsVersion-$Architecture"
Build-JellyFin
if($InstallFFMPEG.IsPresent -or ($InstallFFMPEG -eq $true)){
Write-Verbose "Starting FFMPEG Install"
Install-FFMPEG $InstallLocation $Architecture
}
if($GenerateZip.IsPresent -or ($GenerateZip -eq $true)){
Compress-Archive -Path $InstallLocation -DestinationPath "$InstallLocation/jellyfin.zip" -Force
}
Write-Verbose "Finished"

View File

@ -1,4 +0,0 @@
1. Don't sneakily relicense free software.
2. Don't continually nag users to give you money.
3. Don't hide binary blobs in otherwise free software.
4. Don't needlessly obfuscate the build process or any other part of free software.

View File

@ -4,6 +4,9 @@
- [nvllsvm](https://github.com/nvllsvm)
- [JustAMan](https://github.com/JustAMan)
- [dcrdev](https://github.com/dcrdev)
- [EraYaN](https://github.com/EraYaN)
- [flemse](https://github.com/flemse)
- [bfayers](https://github.com/bfayers)
# Emby Contributors

View File

@ -467,7 +467,7 @@ namespace Emby.Dlna.ContentDirectory
IsMissing = false,
ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name },
IsFolder = isFolder,
MediaTypes = mediaTypes.ToArray(mediaTypes.Count),
MediaTypes = mediaTypes.ToArray(),
DtoOptions = GetDtoOptions()
});
}
@ -676,7 +676,7 @@ namespace Emby.Dlna.ContentDirectory
return new QueryResult<ServerItem>
{
Items = list.ToArray(list.Count),
Items = list.ToArray(),
TotalRecordCount = list.Count
};
}
@ -754,7 +754,7 @@ namespace Emby.Dlna.ContentDirectory
return new QueryResult<ServerItem>
{
Items = list.ToArray(list.Count),
Items = list.ToArray(),
TotalRecordCount = list.Count
};
}
@ -859,7 +859,7 @@ namespace Emby.Dlna.ContentDirectory
return new QueryResult<ServerItem>
{
Items = list.ToArray(list.Count),
Items = list.ToArray(),
TotalRecordCount = list.Count
};
}
@ -1026,7 +1026,7 @@ namespace Emby.Dlna.ContentDirectory
var result = new QueryResult<BaseItem>
{
TotalRecordCount = genresResult.TotalRecordCount,
Items = genresResult.Items.Select(i => i.Item1).ToArray(genresResult.Items.Length)
Items = genresResult.Items.Select(i => i.Item1).ToArray()
};
return ToResult(result);
@ -1044,7 +1044,7 @@ namespace Emby.Dlna.ContentDirectory
var result = new QueryResult<BaseItem>
{
TotalRecordCount = genresResult.TotalRecordCount,
Items = genresResult.Items.Select(i => i.Item1).ToArray(genresResult.Items.Length)
Items = genresResult.Items.Select(i => i.Item1).ToArray()
};
return ToResult(result);
@ -1062,7 +1062,7 @@ namespace Emby.Dlna.ContentDirectory
var result = new QueryResult<BaseItem>
{
TotalRecordCount = artists.TotalRecordCount,
Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length)
Items = artists.Items.Select(i => i.Item1).ToArray()
};
return ToResult(result);
@ -1080,7 +1080,7 @@ namespace Emby.Dlna.ContentDirectory
var result = new QueryResult<BaseItem>
{
TotalRecordCount = artists.TotalRecordCount,
Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length)
Items = artists.Items.Select(i => i.Item1).ToArray()
};
return ToResult(result);
@ -1099,7 +1099,7 @@ namespace Emby.Dlna.ContentDirectory
var result = new QueryResult<BaseItem>
{
TotalRecordCount = artists.TotalRecordCount,
Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length)
Items = artists.Items.Select(i => i.Item1).ToArray()
};
return ToResult(result);
@ -1247,7 +1247,7 @@ namespace Emby.Dlna.ContentDirectory
{
var serverItems = result
.Select(i => new ServerItem(i))
.ToArray(result.Length);
.ToArray();
return new QueryResult<ServerItem>
{

View File

@ -512,7 +512,7 @@ namespace Emby.Dlna.Didl
streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildAudioItem(new AudioOptions
{
ItemId = audio.Id,
MediaSources = sources.ToArray(sources.Count),
MediaSources = sources.ToArray(),
Profile = _profile,
DeviceId = deviceId
});

View File

@ -941,7 +941,7 @@ namespace Emby.Dlna.PlayTo
if (room != null && !string.IsNullOrWhiteSpace(room.Value))
friendlyNames.Add(room.Value);
deviceProperties.Name = string.Join(" ", friendlyNames.ToArray(friendlyNames.Count));
deviceProperties.Name = string.Join(" ", friendlyNames.ToArray());
var model = document.Descendants(uPnpNamespaces.ud.GetName("modelName")).FirstOrDefault();
if (model != null)

View File

@ -571,7 +571,7 @@ namespace Emby.Dlna.PlayTo
StreamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger()).BuildAudioItem(new AudioOptions
{
ItemId = item.Id,
MediaSources = mediaSources.ToArray(mediaSources.Count),
MediaSources = mediaSources.ToArray(),
Profile = profile,
DeviceId = deviceId,
MaxBitrate = profile.MaxStreamingBitrate,

View File

@ -173,7 +173,7 @@ namespace Emby.Dlna.Profiles
Value = value
});
XmlRootAttributes = list.ToArray(list.Count);
XmlRootAttributes = list.ToArray();
}
}
}

View File

@ -242,7 +242,7 @@ namespace Emby.Dlna.Service
}
var originalHeaders = request.Headers;
var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray(originalHeaders.Count));
var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
Logger.Debug("Control request. Headers: {0}", headers);
}

View File

@ -564,7 +564,7 @@ namespace Emby.Drawing
var cacheKeys = imageEnhancers.Select(i => i.GetConfigurationCacheKey(item, imageType)).ToList();
cacheKeys.Add(originalImagePath + dateModified.Ticks);
return string.Join("|", cacheKeys.ToArray(cacheKeys.Count)).GetMD5().ToString("N");
return string.Join("|", cacheKeys.ToArray()).GetMD5().ToString("N");
}
private async Task<ValueTuple<string, DateTime>> GetSupportedImage(string originalImagePath, DateTime dateModified)
@ -919,4 +919,4 @@ namespace Emby.Drawing
}
}
}
}
}

View File

@ -466,7 +466,7 @@ namespace Emby.Server.Implementations.Activity
{
Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name),
Type = NotificationType.TaskFailed.ToString(),
Overview = string.Join(Environment.NewLine, vals.ToArray(vals.Count)),
Overview = string.Join(Environment.NewLine, vals.ToArray()),
ShortOverview = runningTime,
Severity = LogSeverity.Error
});

View File

@ -189,13 +189,13 @@ namespace Emby.Server.Implementations.Activity
var whereTextWithoutPaging = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
" where " + string.Join(" AND ", whereClauses.ToArray());
if (startIndex.HasValue && startIndex.Value > 0)
{
var pagingWhereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
" where " + string.Join(" AND ", whereClauses.ToArray());
whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLog {0} ORDER BY DateCreated DESC LIMIT {1})",
pagingWhereText,
@ -204,7 +204,7 @@ namespace Emby.Server.Implementations.Activity
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
" where " + string.Join(" AND ", whereClauses.ToArray());
commandText += whereText;
@ -249,7 +249,7 @@ namespace Emby.Server.Implementations.Activity
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
}
result.Items = list.ToArray(list.Count);
result.Items = list.ToArray();
return result;
}, ReadTransactionMode);

View File

@ -728,7 +728,7 @@ namespace Emby.Server.Implementations
Logger.Info("ServerId: {0}", SystemId);
var entryPoints = GetExports<IServerEntryPoint>().ToList();
var entryPoints = GetExports<IServerEntryPoint>();
RunEntryPoints(entryPoints, true);
Logger.Info("Core startup complete");
@ -1962,6 +1962,7 @@ namespace Emby.Server.Implementations
public async Task<SystemInfo> GetSystemInfo(CancellationToken cancellationToken)
{
var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
var wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false);
return new SystemInfo
{
@ -1984,8 +1985,7 @@ namespace Emby.Server.Implementations
CanSelfRestart = CanSelfRestart,
CanSelfUpdate = CanSelfUpdate,
CanLaunchWebBrowser = CanLaunchWebBrowser,
// TODO - remove WanAddress
WanAddress = "0.0.0.0",
WanAddress = wanAddress,
HasUpdateAvailable = HasUpdateAvailable,
SupportsAutoRunAtStartup = SupportsAutoRunAtStartup,
TranscodingTempPath = ApplicationPaths.TranscodingTempPath,
@ -2012,14 +2012,13 @@ namespace Emby.Server.Implementations
public async Task<PublicSystemInfo> GetPublicSystemInfo(CancellationToken cancellationToken)
{
var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
var wanAddress = await GetWanApiUrl(cancellationToken).ConfigureAwait(false);
return new PublicSystemInfo
{
Version = ApplicationVersion.ToString(),
Id = SystemId,
OperatingSystem = EnvironmentInfo.OperatingSystem.ToString(),
// TODO - remove WanAddress
WanAddress = "0.0.0.0",
WanAddress = wanAddress,
ServerName = FriendlyName,
LocalAddress = localAddress
};
@ -2060,6 +2059,32 @@ namespace Emby.Server.Implementations
return null;
}
public async Task<string> GetWanApiUrl(CancellationToken cancellationToken)
{
var url = "http://ipv4.icanhazip.com";
try
{
using (var response = await HttpClient.Get(new HttpRequestOptions
{
Url = url,
LogErrorResponseBody = false,
LogErrors = false,
LogRequest = false,
TimeoutMs = 10000,
BufferContent = false,
CancellationToken = cancellationToken
}))
{
return GetLocalApiUrl(response.ReadToEnd().Trim());
}
}
catch(Exception ex)
{
Logger.ErrorException("Error getting WAN Ip address information", ex);
}
return null;
}
public string GetLocalApiUrl(IpAddressInfo ipAddress)
{
if (ipAddress.AddressFamily == IpAddressFamily.InterNetworkV6)

View File

@ -239,7 +239,7 @@ namespace Emby.Server.Implementations.Channels
all = all.Take(query.Limit.Value).ToList();
}
var returnItems = all.ToArray(all.Count);
var returnItems = all.ToArray();
if (query.RefreshLatestChannelItems)
{
@ -1011,7 +1011,7 @@ namespace Emby.Server.Implementations.Channels
{
item.Name = info.Name;
item.Genres = info.Genres.ToArray();
item.Studios = info.Studios.ToArray(info.Studios.Count);
item.Studios = info.Studios.ToArray();
item.CommunityRating = info.CommunityRating;
item.Overview = info.Overview;
item.IndexNumber = info.IndexNumber;
@ -1021,7 +1021,7 @@ namespace Emby.Server.Implementations.Channels
item.ProviderIds = info.ProviderIds;
item.OfficialRating = info.OfficialRating;
item.DateCreated = info.DateCreated ?? DateTime.UtcNow;
item.Tags = info.Tags.ToArray(info.Tags.Count);
item.Tags = info.Tags.ToArray();
item.OriginalTitle = info.OriginalTitle;
}
else if (info.Type == ChannelItemType.Folder && info.FolderType == ChannelFolderType.Container)
@ -1043,7 +1043,7 @@ namespace Emby.Server.Implementations.Channels
var hasAlbumArtists = item as IHasAlbumArtist;
if (hasAlbumArtists != null)
{
hasAlbumArtists.AlbumArtists = info.AlbumArtists.ToArray(info.AlbumArtists.Count);
hasAlbumArtists.AlbumArtists = info.AlbumArtists.ToArray();
}
var trailer = item as Trailer;

View File

@ -219,7 +219,7 @@ namespace Emby.Server.Implementations.Collections
{
var newList = collection.LinkedChildren.ToList();
newList.AddRange(list);
collection.LinkedChildren = newList.ToArray(newList.Count);
collection.LinkedChildren = newList.ToArray();
collection.UpdateRatingToItems(linkedChildrenList);

View File

@ -1148,7 +1148,7 @@ namespace Emby.Server.Implementations.Data
}
}
item.ImageInfos = list.ToArray(list.Count);
item.ImageInfos = list.ToArray();
}
public string ToValueString(ItemImageInfo image)
@ -2566,7 +2566,7 @@ namespace Emby.Server.Implementations.Data
excludeIds.Add(item.Id);
excludeIds.AddRange(item.ExtraIds);
query.ExcludeItemIds = excludeIds.ToArray(excludeIds.Count);
query.ExcludeItemIds = excludeIds.ToArray();
query.ExcludeProviderIds = item.ProviderIds;
}
@ -2587,7 +2587,7 @@ namespace Emby.Server.Implementations.Data
list.Add(builder.ToString());
}
return list.ToArray(list.Count);
return list.ToArray();
}
private void BindSearchParams(InternalItemsQuery query, IStatement statement)
@ -2666,7 +2666,7 @@ namespace Emby.Server.Implementations.Data
if (groups.Count > 0)
{
return " Group by " + string.Join(",", groups.ToArray(groups.Count));
return " Group by " + string.Join(",", groups.ToArray());
}
return string.Empty;
@ -2703,7 +2703,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
" where " + string.Join(" AND ", whereClauses.ToArray());
commandText += whereText;
@ -2761,7 +2761,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
" where " + string.Join(" AND ", whereClauses.ToArray());
commandText += whereText;
@ -2938,7 +2938,7 @@ namespace Emby.Server.Implementations.Data
var returnList = GetItemList(query);
return new QueryResult<BaseItem>
{
Items = returnList.ToArray(returnList.Count),
Items = returnList.ToArray(),
TotalRecordCount = returnList.Count
};
}
@ -2961,7 +2961,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
" where " + string.Join(" AND ", whereClauses.ToArray());
var whereTextWithoutPaging = whereText;
@ -3079,7 +3079,7 @@ namespace Emby.Server.Implementations.Data
LogQueryTime("GetItems", commandText, now);
result.Items = list.ToArray(list.Count);
result.Items = list.ToArray();
return result;
}, ReadTransactionMode);
@ -3227,7 +3227,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
" where " + string.Join(" AND ", whereClauses.ToArray());
commandText += whereText;
@ -3299,7 +3299,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
" where " + string.Join(" AND ", whereClauses.ToArray());
commandText += whereText;
@ -3372,7 +3372,7 @@ namespace Emby.Server.Implementations.Data
var returnList = GetItemIdsList(query);
return new QueryResult<Guid>
{
Items = returnList.ToArray(returnList.Count),
Items = returnList.ToArray(),
TotalRecordCount = returnList.Count
};
}
@ -3387,7 +3387,7 @@ namespace Emby.Server.Implementations.Data
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
" where " + string.Join(" AND ", whereClauses.ToArray());
var whereTextWithoutPaging = whereText;
@ -3495,7 +3495,7 @@ namespace Emby.Server.Implementations.Data
LogQueryTime("GetItemIds", commandText, now);
result.Items = list.ToArray(list.Count);
result.Items = list.ToArray();
return result;
}, ReadTransactionMode);
@ -3690,7 +3690,7 @@ namespace Emby.Server.Implementations.Data
statement.TryBind("@IsMovie", true);
}
whereClauses.Add("(" + string.Join(" OR ", programAttribtues.ToArray(programAttribtues.Count)) + ")");
whereClauses.Add("(" + string.Join(" OR ", programAttribtues.ToArray()) + ")");
}
else if (query.IsMovie.HasValue)
{
@ -5813,7 +5813,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
result.TotalRecordCount = list.Count;
}
result.Items = list.ToArray(list.Count);
result.Items = list.ToArray();
return result;

View File

@ -289,7 +289,7 @@ namespace Emby.Server.Implementations.Devices
var list = history.FilesUploaded.ToList();
list.Add(file);
history.FilesUploaded = list.ToArray(list.Count);
history.FilesUploaded = list.ToArray();
_json.SerializeToFile(history, path);
}
@ -501,4 +501,4 @@ namespace Emby.Server.Implementations.Devices
return config.GetConfiguration<DevicesOptions>("devices");
}
}
}
}

View File

@ -648,7 +648,7 @@ namespace Emby.Server.Implementations.Dto
}
}
dto.People = list.ToArray(list.Count);
dto.People = list.ToArray();
}
/// <summary>

View File

@ -12,7 +12,6 @@ using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Threading;
using Mono.Nat;
using MediaBrowser.Model.Extensions;
using System.Threading;
namespace Emby.Server.Implementations.EntryPoints
@ -59,7 +58,7 @@ namespace Emby.Server.Implementations.EntryPoints
values.Add(_appHost.EnableHttps.ToString());
values.Add((config.EnableRemoteAccess).ToString());
return string.Join("|", values.ToArray(values.Count));
return string.Join("|", values.ToArray());
}
void _config_ConfigurationUpdated(object sender, EventArgs e)
@ -316,4 +315,4 @@ namespace Emby.Server.Implementations.EntryPoints
}
}
}
}
}

View File

@ -58,7 +58,7 @@ namespace Emby.Server.Implementations.EntryPoints
session.ApplicationVersion
};
var key = string.Join("_", keys.ToArray(keys.Count)).GetMD5();
var key = string.Join("_", keys.ToArray()).GetMD5();
ClientInfo info;
if (!_apps.TryGetValue(key, out info))

View File

@ -825,7 +825,7 @@ namespace Emby.Server.Implementations.HttpServer
});
}
return routes.ToArray(routes.Count);
return routes.ToArray();
}
public Func<string, object> GetParseFn(Type propertyType)
@ -954,4 +954,4 @@ namespace Emby.Server.Implementations.HttpServer
_listener.Start(UrlPrefixes);
}
}
}
}

View File

@ -112,12 +112,15 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
private IHasHeaders GetHttpResult(IRequest requestContext, byte[] content, string contentType, bool addCachePrevention, IDictionary<string, string> responseHeaders = null)
{
string compressionType = null;
bool isHeadRequest = false;
if (requestContext != null) {
compressionType = GetCompressionType(requestContext, content, contentType);
isHeadRequest = string.Equals(requestContext.Verb, "head", StringComparison.OrdinalIgnoreCase);
}
IHasHeaders result;
var compressionType = requestContext == null ? null : GetCompressionType(requestContext, content, contentType);
var isHeadRequest = string.Equals(requestContext.Verb, "head", StringComparison.OrdinalIgnoreCase);
if (string.IsNullOrEmpty(compressionType))
{
var contentLength = content.Length;
@ -791,4 +794,4 @@ namespace Emby.Server.Implementations.HttpServer
{
byte[] Compress(byte[] content);
}
}
}

View File

@ -2,6 +2,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
// TODO: @bond Remove
namespace SharpCifs.Util.Sharpen
{
internal static class Collections<T>

View File

@ -730,7 +730,7 @@ namespace Emby.Server.Implementations.Library
_fileSystem.CreateDirectory(rootFolderPath);
var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ?? (AggregateFolder)ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath));
var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ?? ((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath))).DeepCopy<Folder,AggregateFolder>();
// In case program data folder was moved
if (!string.Equals(rootFolder.Path, rootFolderPath, StringComparison.Ordinal))
@ -799,7 +799,7 @@ namespace Emby.Server.Implementations.Library
if (tmpItem == null)
{
tmpItem = (UserRootFolder)ResolvePath(_fileSystem.GetDirectoryInfo(userRootPath));
tmpItem = ((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(userRootPath))).DeepCopy<Folder,UserRootFolder>();
}
// In case program data folder was moved
@ -1493,7 +1493,7 @@ namespace Emby.Server.Implementations.Library
return new QueryResult<BaseItem>
{
Items = list.ToArray(list.Count)
Items = list.ToArray()
};
}

View File

@ -161,8 +161,8 @@ namespace Emby.Server.Implementations.Library
var searchQuery = new InternalItemsQuery(user)
{
SearchTerm = searchTerm,
ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count),
IncludeItemTypes = includeItemTypes.ToArray(includeItemTypes.Count),
ExcludeItemTypes = excludeItemTypes.ToArray(),
IncludeItemTypes = includeItemTypes.ToArray(),
Limit = query.Limit,
IncludeItemsByName = string.IsNullOrEmpty(query.ParentId),
ParentId = string.IsNullOrEmpty(query.ParentId) ? Guid.Empty : new Guid(query.ParentId),

View File

@ -354,7 +354,7 @@ namespace Emby.Server.Implementations.Library
Limit = limit * 5,
IsPlayed = isPlayed,
DtoOptions = options,
MediaTypes = mediaTypes.ToArray(mediaTypes.Count)
MediaTypes = mediaTypes.ToArray()
};
if (parents.Count == 0)

View File

@ -139,7 +139,7 @@ namespace Emby.Server.Implementations.LiveTv
dto.ProgramId = GetInternalProgramId(info.ProgramId).ToString("N");
}
dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days.ToArray(info.Days.Count));
dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days.ToArray());
FillImages(dto, info.Name, info.SeriesId);

View File

@ -1140,7 +1140,7 @@ namespace Emby.Server.Implementations.LiveTv
var dtoOptions = new DtoOptions();
var fields = dtoOptions.Fields.ToList();
fields.Remove(ItemFields.BasicSyncInfo);
dtoOptions.Fields = fields.ToArray(fields.Count);
dtoOptions.Fields = fields.ToArray();
progress.Report(100);
}
@ -1458,16 +1458,16 @@ namespace Emby.Server.Implementations.LiveTv
{
MediaTypes = new[] { MediaType.Video },
Recursive = true,
AncestorIds = folderIds.ToArray(folderIds.Count),
AncestorIds = folderIds.ToArray(),
IsFolder = false,
IsVirtualItem = false,
Limit = limit,
StartIndex = query.StartIndex,
OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) },
EnableTotalRecordCount = query.EnableTotalRecordCount,
IncludeItemTypes = includeItemTypes.ToArray(includeItemTypes.Count),
ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count),
Genres = genres.ToArray(genres.Count),
IncludeItemTypes = includeItemTypes.ToArray(),
ExcludeItemTypes = excludeItemTypes.ToArray(),
Genres = genres.ToArray(),
DtoOptions = dtoOptions
});
@ -1791,7 +1791,7 @@ namespace Emby.Server.Implementations.LiveTv
var returnArray = returnList
.OrderBy(i => i.StartDate)
.ToArray(returnList.Count);
.ToArray();
return new QueryResult<TimerInfoDto>
{
@ -2338,7 +2338,7 @@ namespace Emby.Server.Implementations.LiveTv
fields.Remove(ItemFields.CanDownload);
fields.Remove(ItemFields.DisplayPreferencesId);
fields.Remove(ItemFields.Etag);
options.Fields = fields.ToArray(fields.Count);
options.Fields = fields.ToArray();
}
public Folder GetInternalLiveTvFolder(CancellationToken cancellationToken)
@ -2373,7 +2373,7 @@ namespace Emby.Server.Implementations.LiveTv
{
info.Id = Guid.NewGuid().ToString("N");
list.Add(info);
config.TunerHosts = list.ToArray(list.Count);
config.TunerHosts = list.ToArray();
}
else
{
@ -2412,7 +2412,7 @@ namespace Emby.Server.Implementations.LiveTv
{
info.Id = Guid.NewGuid().ToString("N");
list.Add(info);
config.ListingProviders = list.ToArray(list.Count);
config.ListingProviders = list.ToArray();
}
else
{
@ -2451,7 +2451,7 @@ namespace Emby.Server.Implementations.LiveTv
Name = tunerChannelId,
Value = providerChannelId
});
listingsProviderInfo.ChannelMappings = list.ToArray(list.Count);
listingsProviderInfo.ChannelMappings = list.ToArray();
}
_config.SaveConfiguration("livetv", config);
@ -2602,4 +2602,4 @@ namespace Emby.Server.Implementations.LiveTv
return folders.Cast<BaseItem>().ToList();
}
}
}
}

View File

@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.LiveTv
openKeys.Add(item.GetType().Name);
openKeys.Add(item.Id.ToString("N"));
openKeys.Add(source.Id ?? string.Empty);
source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray(openKeys.Count));
source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray());
}
// Dummy this up so that direct play checks can still run

View File

@ -706,7 +706,7 @@ namespace Emby.Server.Implementations.Networking
public async Task<IpAddressInfo[]> GetHostAddressesAsync(string host)
{
var addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false);
return addresses.Select(ToIpAddressInfo).ToArray(addresses.Length);
return addresses.Select(ToIpAddressInfo).ToArray();
}
/// <summary>

View File

@ -208,7 +208,7 @@ namespace Emby.Server.Implementations.Playlists
var newList = playlist.LinkedChildren.ToList();
newList.AddRange(list);
playlist.LinkedChildren = newList.ToArray(newList.Count);
playlist.LinkedChildren = newList.ToArray();
playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
@ -290,7 +290,7 @@ namespace Emby.Server.Implementations.Playlists
newList.Insert(newIndex, item);
}
playlist.LinkedChildren = newList.ToArray(newList.Count);
playlist.LinkedChildren = newList.ToArray();
playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);

View File

@ -145,7 +145,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
_fileSystem.CreateDirectory(parentPath);
_fileSystem.WriteAllText(failHistoryPath, string.Join("|", previouslyFailedImages.ToArray(previouslyFailedImages.Count)));
_fileSystem.WriteAllText(failHistoryPath, string.Join("|", previouslyFailedImages.ToArray()));
}
numComplete++;

View File

@ -1,142 +0,0 @@
using MediaBrowser.Common;
using MediaBrowser.Common.Updates;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Progress;
using MediaBrowser.Model.Tasks;
namespace Emby.Server.Implementations.ScheduledTasks
{
/// <summary>
/// Plugin Update Task
/// </summary>
public class PluginUpdateTask : IScheduledTask, IConfigurableScheduledTask
{
/// <summary>
/// The _logger
/// </summary>
private readonly ILogger _logger;
private readonly IInstallationManager _installationManager;
private readonly IApplicationHost _appHost;
public PluginUpdateTask(ILogger logger, IInstallationManager installationManager, IApplicationHost appHost)
{
_logger = logger;
_installationManager = installationManager;
_appHost = appHost;
}
/// <summary>
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
return new[] {
// At startup
new TaskTriggerInfo {Type = TaskTriggerInfo.TriggerStartup},
// Every so often
new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks}
};
}
public string Key
{
get { return "PluginUpdates"; }
}
/// <summary>
/// Update installed plugins
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
/// <returns>Task.</returns>
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
{
progress.Report(0);
var packagesToInstall = (await _installationManager.GetAvailablePluginUpdates(_appHost.ApplicationVersion, true, cancellationToken).ConfigureAwait(false)).ToList();
progress.Report(10);
var numComplete = 0;
foreach (var package in packagesToInstall)
{
cancellationToken.ThrowIfCancellationRequested();
try
{
await _installationManager.InstallPackage(package, true, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
// InstallPackage has it's own inner cancellation token, so only throw this if it's ours
if (cancellationToken.IsCancellationRequested)
{
throw;
}
}
catch (HttpException ex)
{
_logger.ErrorException("Error downloading {0}", ex, package.name);
}
catch (IOException ex)
{
_logger.ErrorException("Error updating {0}", ex, package.name);
}
// Update progress
lock (progress)
{
numComplete++;
double percent = numComplete;
percent /= packagesToInstall.Count;
progress.Report(90 * percent + 10);
}
}
progress.Report(100);
}
/// <summary>
/// Gets the name of the task
/// </summary>
/// <value>The name.</value>
public string Name
{
get { return "Check for plugin updates"; }
}
/// <summary>
/// Gets the description.
/// </summary>
/// <value>The description.</value>
public string Description
{
get { return "Downloads and installs updates for plugins that are configured to update automatically."; }
}
public string Category
{
get { return "Application"; }
}
public bool IsHidden => true;
public bool IsEnabled => true;
public bool IsLogged => true;
}
}

View File

@ -9,7 +9,6 @@ using MediaBrowser.Common.Events;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Progress;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
@ -276,7 +275,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
get
{
var triggers = InternalTriggers;
return triggers.Select(i => i.Item1).ToArray(triggers.Length);
return triggers.Select(i => i.Item1).ToArray();
}
set
{
@ -290,7 +289,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
SaveTriggers(triggerList);
InternalTriggers = triggerList.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray(triggerList.Length);
InternalTriggers = triggerList.Select(i => new Tuple<TaskTriggerInfo, ITaskTrigger>(i, GetTrigger(i))).ToArray();
}
}

View File

@ -241,7 +241,7 @@ namespace Emby.Server.Implementations.Security
var whereTextWithoutPaging = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count));
" where " + string.Join(" AND ", whereClauses.ToArray());
commandText += whereTextWithoutPaging;
@ -298,7 +298,7 @@ namespace Emby.Server.Implementations.Security
}
}
result.Items = list.ToArray(list.Count);
result.Items = list.ToArray();
return result;
}, ReadTransactionMode);

View File

@ -181,7 +181,7 @@ namespace Emby.Server.Implementations.Services
}
if (reqFilters.Count > 0)
actionCtx.RequestFilters = reqFilters.OrderBy(i => i.Priority).ToArray(reqFilters.Count);
actionCtx.RequestFilters = reqFilters.OrderBy(i => i.Priority).ToArray();
actions.Add(actionCtx);
}
@ -220,4 +220,4 @@ namespace Emby.Server.Implementations.Services
}
}
}
}
}

View File

@ -132,13 +132,13 @@ namespace Emby.Server.Implementations.Services
}
}
var components = componentsList.ToArray(componentsList.Count);
var components = componentsList.ToArray();
this.TotalComponentsCount = components.Length;
this.literalsToMatch = new string[this.TotalComponentsCount];
this.variablesNames = new string[this.TotalComponentsCount];
this.isWildcard = new bool[this.TotalComponentsCount];
this.componentsWithSeparators = hasSeparators.ToArray(hasSeparators.Count);
this.componentsWithSeparators = hasSeparators.ToArray();
this.PathComponentsCount = this.componentsWithSeparators.Length;
string firstLiteralMatch = null;
@ -297,7 +297,7 @@ namespace Emby.Server.Implementations.Services
if (mi != null && mi.IsStatic) continue;
pis.Add(pi);
}
return pis.ToArray(pis.Count);
return pis.ToArray();
}
/// <summary>
@ -463,7 +463,7 @@ namespace Emby.Server.Implementations.Services
}
}
withPathInfoParts = totalComponents.ToArray(totalComponents.Count);
withPathInfoParts = totalComponents.ToArray();
return true;
}
@ -574,4 +574,4 @@ namespace Emby.Server.Implementations.Services
}
}
}
}
}

View File

@ -1042,7 +1042,7 @@ namespace Emby.Server.Implementations.Session
command.PlayCommand = PlayCommand.PlayNow;
}
command.ItemIds = items.Select(i => i.Id).ToArray(items.Count);
command.ItemIds = items.Select(i => i.Id).ToArray();
if (user != null)
{
@ -1070,7 +1070,7 @@ namespace Emby.Server.Implementations.Session
if (episodes.Count > 0)
{
command.ItemIds = episodes.Select(i => i.Id).ToArray(episodes.Count);
command.ItemIds = episodes.Select(i => i.Id).ToArray();
}
}
}
@ -1316,7 +1316,7 @@ namespace Emby.Server.Implementations.Session
UserName = user.Name
});
session.AdditionalUsers = list.ToArray(list.Count);
session.AdditionalUsers = list.ToArray();
}
}
@ -1345,7 +1345,7 @@ namespace Emby.Server.Implementations.Session
var list = session.AdditionalUsers.ToList();
list.Remove(user);
session.AdditionalUsers = list.ToArray(list.Count);
session.AdditionalUsers = list.ToArray();
}
}
@ -1669,7 +1669,7 @@ namespace Emby.Server.Implementations.Session
fields.Remove(ItemFields.Tags);
fields.Remove(ItemFields.ExtraIds);
dtoOptions.Fields = fields.ToArray(fields.Count);
dtoOptions.Fields = fields.ToArray();
_itemInfoDtoOptions = dtoOptions;
}

View File

@ -143,7 +143,7 @@ namespace MediaBrowser.Api
{
var list = options.Fields.ToList();
list.Add(Model.Querying.ItemFields.RecursiveItemCount);
options.Fields = list.ToArray(list.Count);
options.Fields = list.ToArray();
}
if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
@ -156,7 +156,7 @@ namespace MediaBrowser.Api
{
var list = options.Fields.ToList();
list.Add(Model.Querying.ItemFields.ChildCount);
options.Fields = list.ToArray(list.Count);
options.Fields = list.ToArray();
}
}

View File

@ -974,7 +974,7 @@ namespace MediaBrowser.Api.LiveTv
fields.Remove(ItemFields.CanDownload);
fields.Remove(ItemFields.DisplayPreferencesId);
fields.Remove(ItemFields.Etag);
options.Fields = fields.ToArray(fields.Count);
options.Fields = fields.ToArray();
}
public object Get(GetChannel request)
@ -1265,4 +1265,4 @@ namespace MediaBrowser.Api.LiveTv
return _liveTvManager.ResetTuner(request.Id, CancellationToken.None);
}
}
}
}

View File

@ -123,7 +123,7 @@ namespace MediaBrowser.Api.Movies
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
Limit = request.Limit,
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IncludeItemTypes = itemTypes.ToArray(),
IsMovie = true,
SimilarTo = item,
EnableGroupByMetadataKey = true,
@ -177,12 +177,12 @@ namespace MediaBrowser.Api.Movies
var likedMovies = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IncludeItemTypes = itemTypes.ToArray(),
IsMovie = true,
OrderBy = new[] { ItemSortBy.Random }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
Limit = 10,
IsFavoriteOrLiked = true,
ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id).ToArray(recentlyPlayedMovies.Count),
ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id).ToArray(),
EnableGroupByMetadataKey = true,
ParentId = parentIdGuid,
Recursive = true,
@ -265,7 +265,7 @@ namespace MediaBrowser.Api.Movies
// Account for duplicates by imdb id, since the database doesn't support this yet
Limit = itemLimit + 2,
PersonTypes = new[] { PersonType.Director },
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IncludeItemTypes = itemTypes.ToArray(),
IsMovie = true,
EnableGroupByMetadataKey = true,
DtoOptions = dtoOptions
@ -305,7 +305,7 @@ namespace MediaBrowser.Api.Movies
Person = name,
// Account for duplicates by imdb id, since the database doesn't support this yet
Limit = itemLimit + 2,
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IncludeItemTypes = itemTypes.ToArray(),
IsMovie = true,
EnableGroupByMetadataKey = true,
DtoOptions = dtoOptions
@ -343,7 +343,7 @@ namespace MediaBrowser.Api.Movies
var similar = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
Limit = itemLimit,
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IncludeItemTypes = itemTypes.ToArray(),
IsMovie = true,
SimilarTo = item,
EnableGroupByMetadataKey = true,

View File

@ -11,7 +11,6 @@ using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Api
{
@ -81,7 +80,7 @@ namespace MediaBrowser.Api
var query = new InternalItemsQuery(user)
{
IncludeItemTypes = includeTypes.Select(i => i.Name).ToArray(includeTypes.Length),
IncludeItemTypes = includeTypes.Select(i => i.Name).ToArray(),
Recursive = true,
DtoOptions = dtoOptions
};

View File

@ -206,7 +206,7 @@ namespace MediaBrowser.Api.UserLibrary
return new QueryResult<BaseItemDto>
{
Items = dtos.ToArray(result.Items.Length),
Items = dtos.ToArray(),
TotalRecordCount = result.TotalRecordCount
};
}

View File

@ -93,7 +93,7 @@ namespace MediaBrowser.Api.UserLibrary
fields.Add(ItemFields.PrimaryImageAspectRatio);
fields.Add(ItemFields.DisplayPreferencesId);
fields.Remove(ItemFields.BasicSyncInfo);
dtoOptions.Fields = fields.ToArray(fields.Count);
dtoOptions.Fields = fields.ToArray();
var user = _userManager.GetUserById(request.UserId);

View File

@ -1295,7 +1295,7 @@ namespace MediaBrowser.Controller.Entities
}
}
return string.Join("/", terms.ToArray(terms.Count));
return string.Join("/", terms.ToArray());
}
/// <summary>
@ -1536,7 +1536,7 @@ namespace MediaBrowser.Controller.Entities
{
var newThemeVideos = LoadThemeVideos(fileSystemChildren, options.DirectoryService);
var newThemeVideoIds = newThemeVideos.Select(i => i.Id).ToArray(newThemeVideos.Length);
var newThemeVideoIds = newThemeVideos.Select(i => i.Id).ToArray();
var themeVideosChanged = !item.ThemeVideoIds.SequenceEqual(newThemeVideoIds);
@ -1573,7 +1573,7 @@ namespace MediaBrowser.Controller.Entities
private async Task<bool> RefreshThemeSongs(BaseItem item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var newThemeSongs = LoadThemeSongs(fileSystemChildren, options.DirectoryService);
var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToArray(newThemeSongs.Length);
var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToArray();
var themeSongsChanged = !item.ThemeSongIds.SequenceEqual(newThemeSongIds);
@ -2110,9 +2110,8 @@ namespace MediaBrowser.Controller.Entities
}
else
{
var list = current.ToArray(current.Length + 1);
list[list.Length - 1] = name;
Studios = list;
var list =
Studios = current.Concat(new [] { name }).ToArray();
}
}
}
@ -2252,9 +2251,7 @@ namespace MediaBrowser.Controller.Entities
else
{
var currentCount = ImageInfos.Length;
var newList = ImageInfos.ToArray(currentCount + 1);
newList[currentCount] = image;
ImageInfos = newList;
ImageInfos = ImageInfos.Concat(new [] { image }) .ToArray();
}
}
@ -2269,10 +2266,7 @@ namespace MediaBrowser.Controller.Entities
if (image == null)
{
var currentCount = ImageInfos.Length;
var newList = ImageInfos.ToArray(currentCount + 1);
newList[currentCount] = GetImageInfo(file, type);
ImageInfos = newList;
ImageInfos = ImageInfos.Concat(new [] { GetImageInfo(file, type) }) .ToArray();
}
else
{
@ -2486,16 +2480,7 @@ namespace MediaBrowser.Controller.Entities
if (newImageList.Count > 0)
{
var currentCount = ImageInfos.Length;
var newList = ImageInfos.ToArray(currentCount + newImageList.Count);
foreach (var image in newImageList)
{
newList[currentCount] = GetImageInfo(image, imageType);
currentCount++;
}
ImageInfos = newList;
ImageInfos = ImageInfos.Concat(newImageList.Select(i => GetImageInfo(i, imageType))).ToArray();
}
return imageUpdated || newImageList.Count > 0;
@ -2537,7 +2522,7 @@ namespace MediaBrowser.Controller.Entities
var extensions = new List<string> { ".nfo", ".xml", ".srt", ".vtt", ".sub", ".idx", ".txt", ".edl", ".bif", ".smi", ".ttml" };
extensions.AddRange(SupportedImageExtensions);
return FileSystem.GetFiles(FileSystem.GetDirectoryName(Path), extensions.ToArray(extensions.Count), false, false)
return FileSystem.GetFiles(FileSystem.GetDirectoryName(Path), extensions.ToArray(), false, false)
.Where(i => System.IO.Path.GetFileNameWithoutExtension(i.FullName).StartsWith(filename, StringComparison.OrdinalIgnoreCase))
.ToList();
}
@ -2776,7 +2761,7 @@ namespace MediaBrowser.Controller.Entities
{
var list = GetEtagValues(user);
return string.Join("|", list.ToArray(list.Count)).GetMD5().ToString("N");
return string.Join("|", list.ToArray()).GetMD5().ToString("N");
}
protected virtual List<string> GetEtagValues(User user)

View File

@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@ -61,5 +62,46 @@ namespace MediaBrowser.Controller.Entities
item.SetImagePath(imageType, BaseItem.FileSystem.GetFileInfo(file));
}
}
/// <summary>
/// Copies all properties on object. Skips properties that do not exist.
/// </summary>
/// <param name="source">The source object.</param>
/// <param name="dest">The destination object.</param>
public static void DeepCopy<T, TU>(this T source, TU dest)
where T : BaseItem
where TU : BaseItem
{
var sourceProps = typeof (T).GetProperties().Where(x => x.CanRead).ToList();
var destProps = typeof(TU).GetProperties()
.Where(x => x.CanWrite)
.ToList();
foreach (var sourceProp in sourceProps)
{
if (destProps.Any(x => x.Name == sourceProp.Name))
{
var p = destProps.First(x => x.Name == sourceProp.Name);
p.SetValue(dest, sourceProp.GetValue(source, null), null);
}
}
}
/// <summary>
/// Copies all properties on newly created object. Skips properties that do not exist.
/// </summary>
/// <param name="source">The source object.</param>
public static TU DeepCopy<T, TU>(this T source)
where T : BaseItem
where TU : BaseItem, new()
{
var dest = new TU();
source.DeepCopy(dest);
return dest;
}
}
}

View File

@ -275,7 +275,7 @@ namespace MediaBrowser.Controller.Entities
var changed = !linkedChildren.SequenceEqual(LinkedChildren, new LinkedChildComparer(FileSystem));
LinkedChildren = linkedChildren.ToArray(linkedChildren.Count);
LinkedChildren = linkedChildren.ToArray();
var folderIds = PhysicalFolderIds;
var newFolderIds = physicalFolders.Select(i => i.Id).ToArray();

View File

@ -35,10 +35,7 @@ namespace MediaBrowser.Controller.Entities
}
else
{
var list = item.RemoteTrailers.ToArray(item.RemoteTrailers.Length + 1);
list[list.Length - 1] = mediaUrl;
item.RemoteTrailers = list;
item.RemoteTrailers = item.RemoteTrailers.Concat(new [] { mediaUrl }).ToArray();
}
}
}

View File

@ -914,7 +914,7 @@ namespace MediaBrowser.Controller.Entities
// Try to preserve order
return result.OrderBy(i => ids.IndexOf(i.Id)).ToArray();
}
return result.ToArray(result.Count);
return result.ToArray();
}
return GetItemsInternal(query).Items;
@ -1608,7 +1608,7 @@ namespace MediaBrowser.Controller.Entities
Logger.Info("Shortcut links have changed for {0}", Path);
newShortcutLinks.AddRange(LinkedChildren.Where(i => i.Type == LinkedChildType.Manual));
LinkedChildren = newShortcutLinks.ToArray(newShortcutLinks.Count);
LinkedChildren = newShortcutLinks.ToArray();
return true;
}
}

View File

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Controller.Entities
{
@ -24,10 +22,7 @@ namespace MediaBrowser.Controller.Entities
}
else
{
var list = current.ToArray(current.Length + 1);
list[list.Length - 1] = name;
item.Tags = list;
item.Tags = current.Concat(new [] { name }).ToArray();
}
}
}

View File

@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Xml;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Xml;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.LocalMetadata.Parsers
{
@ -85,7 +84,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
}
}
item.Item.LinkedChildren = list.ToArray(list.Count);
item.Item.LinkedChildren = list.ToArray();
}
public BoxSetXmlParser(ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory, IFileSystem fileSystem) : base(logger, providerManager, xmlReaderSettingsFactory, fileSystem)

View File

@ -95,7 +95,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
}
}
item.LinkedChildren = list.ToArray(list.Count);
item.LinkedChildren = list.ToArray();
}
public PlaylistXmlParser(ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory, IFileSystem fileSystem) : base(logger, providerManager, xmlReaderSettingsFactory, fileSystem)

View File

@ -1,33 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
<Compile Include="..\SharedVersion.cs"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BDInfo\BDInfo.csproj">
<Project>{88ae38df-19d7-406f-a6a9-09527719a21e}</Project>
<Name>BDInfo</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
<Name>MediaBrowser.Common</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
<Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
<Name>MediaBrowser.Controller</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
<Name>MediaBrowser.Model</Name>
</ProjectReference>
<ProjectReference Include="..\OpenSubtitlesHandler\OpenSubtitlesHandler.csproj">
<Project>{4a4402d4-e910-443b-b8fc-2c18286a2ca0}</Project>
<Name>OpenSubtitlesHandler</Name>
</ProjectReference>
<ProjectReference Include="..\BDInfo\BDInfo.csproj" />
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
<ProjectReference Include="..\OpenSubtitlesHandler\OpenSubtitlesHandler.csproj" />
</ItemGroup>
</Project>

View File

@ -246,7 +246,7 @@ namespace MediaBrowser.Model.Configuration
SortRemoveCharacters = new[] { ",", "&", "-", "{", "}", "'" };
SortRemoveWords = new[] { "the", "a", "an" };
UICulture = "en-us";
UICulture = "en-US";
MetadataOptions = new[]
{
@ -310,4 +310,4 @@ namespace MediaBrowser.Model.Configuration
public string From { get; set; }
public string To { get; set; }
}
}
}

View File

@ -101,7 +101,7 @@ namespace MediaBrowser.Model.Dlna
{
list.Add(MediaFormatProfile.MPEG_TS_JP_T);
}
return list.ToArray(list.Count);
return list.ToArray();
}
if (StringHelper.EqualsIgnoreCase(videoCodec, "h264"))
{

View File

@ -186,7 +186,7 @@ namespace MediaBrowser.Model.Dlna
list.Add(string.Format("{0}={1}", pair.Name, encodedValue));
}
string queryString = string.Join("&", list.ToArray(list.Count));
string queryString = string.Join("&", list.ToArray());
return GetUrl(baseUrl, queryString);
}

View File

@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Collections.Generic;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Extensions;
@ -104,7 +105,7 @@ namespace MediaBrowser.Model.Entities
attributes.Add("Default");
}
return string.Join(" ", attributes.ToArray(attributes.Count));
return string.Join(" ", attributes.ToArray());
}
if (Type == MediaStreamType.Video)
@ -123,7 +124,7 @@ namespace MediaBrowser.Model.Entities
attributes.Add(Codec.ToUpper());
}
return string.Join(" ", attributes.ToArray(attributes.Count));
return string.Join(" ", attributes.ToArray());
}
if (Type == MediaStreamType.Subtitle)
@ -154,7 +155,7 @@ namespace MediaBrowser.Model.Entities
attributes.Add("Forced");
}
string name = string.Join(" ", attributes.ToArray(attributes.Count));
string name = string.Join(" ", attributes.ToArray());
return name;
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
// TODO: @bond Remove
namespace MediaBrowser.Model.Extensions
{
// MoreLINQ - Extensions to LINQ to Objects
@ -42,19 +43,6 @@ namespace MediaBrowser.Model.Extensions
return source.DistinctBy(keySelector, null);
}
public static TSource[] ToArray<TSource>(this IEnumerable<TSource> source, int count)
{
if (source == null) throw new ArgumentNullException("source");
if (count < 0) throw new ArgumentOutOfRangeException("count");
var array = new TSource[count];
int i = 0;
foreach (var item in source)
{
array[i++] = item;
}
return array;
}
/// <summary>
/// Returns all distinct elements of the given source, where "distinctness"
/// is determined via a projection and the specified comparer for the projected type.

View File

@ -2,8 +2,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Model.Services
{
@ -586,7 +584,7 @@ namespace MediaBrowser.Model.Services
WriteCharBytes(bytes, ch, e);
}
byte[] buf = bytes.ToArray(bytes.Count);
byte[] buf = bytes.ToArray();
bytes = null;
return e.GetString(buf, 0, buf.Length);

View File

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Model.Services
{
@ -221,7 +220,7 @@ namespace MediaBrowser.Model.Services
public override String ToString()
{
var vals = this.Select(GetQueryStringValue).ToArray(this.Count);
var vals = this.Select(GetQueryStringValue).ToArray();
return string.Join("&", vals);
}

View File

@ -551,7 +551,7 @@ namespace MediaBrowser.Providers.Manager
{
list.Add(Path.Combine(item.ContainingFolderPath, "extrathumbs", "thumb" + outputIndex.ToString(UsCulture) + extension));
}
return list.ToArray(list.Count);
return list.ToArray();
}
if (type == ImageType.Primary)

View File

@ -522,7 +522,7 @@ namespace MediaBrowser.Providers.Manager
Type = MetadataPluginType.SubtitleFetcher
}));
summary.Plugins = pluginList.ToArray(pluginList.Count);
summary.Plugins = pluginList.ToArray();
var supportedImageTypes = imageProviders.OfType<IRemoteImageProvider>()
.SelectMany(i => i.GetSupportedImages(dummy))
@ -1160,4 +1160,4 @@ namespace MediaBrowser.Providers.Manager
}
}
}
}
}

View File

@ -145,7 +145,7 @@ namespace MediaBrowser.Providers.Movies
movie.ProductionLocations = movieData
.production_countries
.Select(i => i.name)
.ToArray(movieData.production_countries.Count);
.ToArray();
}
movie.SetProviderId(MetadataProviders.Tmdb, movieData.id.ToString(_usCulture));

View File

@ -279,7 +279,7 @@ namespace MediaBrowser.Providers.Movies
languages.Add("en");
}
return string.Join(",", languages.ToArray(languages.Count));
return string.Join(",", languages.ToArray());
}
public static string NormalizeLanguage(string language)

View File

@ -17,7 +17,6 @@ using System.Threading.Tasks;
using System.Xml;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Xml;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Providers.Music
{
@ -846,4 +845,4 @@ namespace MediaBrowser.Providers.Music
public int throttleMs { get; set; }
}
}
}
}

View File

@ -236,7 +236,7 @@ namespace MediaBrowser.Providers.TV
if (seriesInfo.networks != null)
{
series.Studios = seriesInfo.networks.Select(i => i.name).ToArray(seriesInfo.networks.Count);
series.Studios = seriesInfo.networks.Select(i => i.name).ToArray();
}
if (seriesInfo.genres != null)

View File

@ -95,7 +95,7 @@ namespace Mono.Nat.Pmp
try
{
byte[] buffer = package.ToArray(package.Count);
byte[] buffer = package.ToArray();
int attempt = 0;
int delay = PmpConstants.RetryDelay;

110
build-jellyfin.ps1 Normal file
View File

@ -0,0 +1,110 @@
[CmdletBinding()]
param(
[switch]$InstallFFMPEG,
[switch]$InstallNSSM,
[switch]$GenerateZip,
[string]$InstallLocation = "$Env:AppData/Jellyfin-Server/",
[ValidateSet('Debug','Release')][string]$BuildType = 'Release',
[ValidateSet('Quiet','Minimal', 'Normal')][string]$DotNetVerbosity = 'Minimal',
[ValidateSet('win','win7', 'win8','win81','win10')][string]$WindowsVersion = 'win',
[ValidateSet('x64','x86', 'arm', 'arm64')][string]$Architecture = 'x64'
)
#PowershellCore and *nix check to make determine which temp dir to use.
if(($PSVersionTable.PSEdition -eq 'Core') -and (-not $IsWindows)){
$TempDir = mktemp -d
}else{
$TempDir = $env:Temp
}
function Build-JellyFin {
if(($Architecture -eq 'arm64') -and ($WindowsVersion -ne 'win10')){
Write-Error "arm64 only supported with Windows10 Version"
exit
}
if(($Architecture -eq 'arm') -and ($WindowsVersion -notin @('win10','win81','win8'))){
Write-Error "arm only supported with Windows 8 or higher"
exit
}
dotnet publish -c $BuildType -r "$windowsversion-$Architecture" MediaBrowser.sln -o $InstallLocation -v $DotNetVerbosity
}
function Install-FFMPEG {
param(
[string]$InstallLocation,
[string]$Architecture
)
Write-Verbose "Checking Architecture"
if($Architecture -notin @('x86','x64')){
Write-Warning "No builds available for your selected architecture of $Architecture"
Write-Warning "FFMPEG will not be installed"
}elseif($Architecture -eq 'x64'){
Write-Verbose "Downloading 64 bit FFMPEG"
Invoke-WebRequest -Uri https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-4.1-win64-static.zip -UseBasicParsing -OutFile "$tempdir/fmmpeg.zip" | Write-Verbose
}else{
Write-Verbose "Downloading 32 bit FFMPEG"
Invoke-WebRequest -Uri https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-4.1-win32-static.zip -UseBasicParsing -OutFile "$tempdir/fmmpeg.zip" | Write-Verbose
}
Expand-Archive "$tempdir/fmmpeg.zip" -DestinationPath "$tempdir/ffmpeg/" | Write-Verbose
if($Architecture -eq 'x64'){
Write-Verbose "Copying Binaries to Jellyfin location"
Get-ChildItem "$tempdir/ffmpeg/ffmpeg-4.1-win64-static/bin" | ForEach-Object {
Copy-Item $_.FullName -Destination $installLocation | Write-Verbose
}
}else{
Write-Verbose "Copying Binaries to Jellyfin location"
Get-ChildItem "$tempdir/ffmpeg/ffmpeg-4.1-win32-static/bin" | ForEach-Object {
Copy-Item $_.FullName -Destination $installLocation | Write-Verbose
}
}
Remove-Item "$tempdir/ffmpeg/" -Recurse -Force -ErrorAction Continue | Write-Verbose
Remove-Item "$tempdir/fmmpeg.zip" -Force -ErrorAction Continue | Write-Verbose
}
function Install-NSSM {
param(
[string]$InstallLocation,
[string]$Architecture
)
Write-Verbose "Checking Architecture"
if($Architecture -notin @('x86','x64')){
Write-Warning "No builds available for your selected architecture of $Architecture"
Write-Warning "NSSM will not be installed"
}else{
Write-Verbose "Downloading NSSM"
Invoke-WebRequest -Uri https://nssm.cc/ci/nssm-2.24-101-g897c7ad.zip -UseBasicParsing -OutFile "$tempdir/nssm.zip" | Write-Verbose
}
Expand-Archive "$tempdir/nssm.zip" -DestinationPath "$tempdir/nssm/" | Write-Verbose
if($Architecture -eq 'x64'){
Write-Verbose "Copying Binaries to Jellyfin location"
Get-ChildItem "$tempdir/nssm/nssm-2.24-101-g897c7ad/win64" | ForEach-Object {
Copy-Item $_.FullName -Destination $installLocation | Write-Verbose
}
}else{
Write-Verbose "Copying Binaries to Jellyfin location"
Get-ChildItem "$tempdir/nssm/nssm-2.24-101-g897c7ad/win32" | ForEach-Object {
Copy-Item $_.FullName -Destination $installLocation | Write-Verbose
}
}
Remove-Item "$tempdir/nssm/" -Recurse -Force -ErrorAction Continue | Write-Verbose
Remove-Item "$tempdir/nssm.zip" -Force -ErrorAction Continue | Write-Verbose
}
Write-Verbose "Starting Build Process: Selected Environment is $WindowsVersion-$Architecture"
Build-JellyFin
if($InstallFFMPEG.IsPresent -or ($InstallFFMPEG -eq $true)){
Write-Verbose "Starting FFMPEG Install"
Install-FFMPEG $InstallLocation $Architecture
}
if($InstallNSSM.IsPresent -or ($InstallNSSM -eq $true)){
Write-Verbose "Starting NSSM Install"
Install-NSSM $InstallLocation $Architecture
}
Copy-Item .\install-jellyfin.ps1 $InstallLocation\install-jellyfin.ps1
Copy-Item .\installjellyfin.bat $InstallLocation\installjellyfin.bat
if($GenerateZip.IsPresent -or ($GenerateZip -eq $true)){
Compress-Archive -Path $InstallLocation -DestinationPath "$InstallLocation/jellyfin.zip" -Force
}
Write-Verbose "Finished"

7
debian/changelog vendored
View File

@ -1,3 +1,10 @@
jellyfin (3.5.2-5) unstable; urgency=medium
* Fully GPL'd release - remove tainted code from MediaBrowser.Common
* Several code cleanups and tweaks
-- Joshua Boniface <joshua@boniface.me> Fri, 28 Dec 2018 10:26:30 -0500
jellyfin (3.5.2-4) unstable; urgency=medium
* Correct manifest.json bug and vdpau

View File

@ -7,8 +7,8 @@ Type = simple
EnvironmentFile = /etc/default/jellyfin
User = jellyfin
ExecStart = /usr/bin/jellyfin -programdata ${JELLYFIN_DATA} -restartpath ${JELLYFIN_RESTART_SCRIPT} ${JELLYFIN_ADD_OPTS}
Restart = on-abort
TimeoutSec = 20
Restart = on-failure
TimeoutSec = 15
[Install]
WantedBy = multi-user.target

3
debian/rules vendored
View File

@ -2,6 +2,7 @@
CONFIG := Release
TERM := xterm
SHELL := /bin/bash
DOTNETRUNTIME := linux-x64
export DH_VERBOSE=1
export DOTNET_CLI_TELEMETRY_OPTOUT=1
@ -15,7 +16,7 @@ override_dh_auto_test:
override_dh_clistrip:
override_dh_auto_build:
dotnet publish --configuration $(CONFIG) --output='$(CURDIR)/usr/lib/jellyfin/bin' --self-contained --runtime linux-x64
dotnet publish --configuration $(CONFIG) --output='$(CURDIR)/usr/lib/jellyfin/bin' --self-contained --runtime $(DOTNETRUNTIME)
override_dh_auto_clean:
dotnet clean -maxcpucount:1 --configuration $(CONFIG) || true

460
install-jellyfin.ps1 Normal file
View File

@ -0,0 +1,460 @@
[CmdletBinding()]
param(
[Switch]$Quiet,
[Switch]$InstallAsService,
[pscredential]$ServiceUser,
[switch]$CreateDesktopShorcut,
[switch]$LaunchJellyfin,
[switch]$MigrateEmbyLibrary,
[string]$InstallLocation,
[string]$EmbyLibraryLocation,
[string]$JellyfinLibraryLocation
)
<# This form was created using POSHGUI.com a free online gui designer for PowerShell
.NAME
Install-Jellyfin
#>
#This doesn't need to be used by default anymore, but I am keeping it in as a function for future use.
function Elevate-Window {
# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
{
# We are running "as Administrator" - so change the title and background color to indicate this
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
$Host.UI.RawUI.BackgroundColor = "DarkBlue"
clear-host
}
else
{
# We are not running "as Administrator" - so relaunch as administrator
# Create a new process object that starts PowerShell
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
# Specify the current script path and name as a parameter
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
# Indicate that the process should be elevated
$newProcess.Verb = "runas";
# Start the new process
[System.Diagnostics.Process]::Start($newProcess);
# Exit from the current, unelevated, process
exit
}
}
#FIXME The install methods should be a function that takes all the params, the quiet flag should be a paramset
if($Quiet.IsPresent -or $Quiet -eq $true){
if([string]::IsNullOrEmpty($JellyfinLibraryLocation)){
$Script:JellyfinDataDir = "$env:AppData\jellyfin\"
}else{
$Script:JellyfinDataDir = $JellyfinLibraryLocation
}
if([string]::IsNullOrEmpty($InstallLocation)){
$Script:DefaultJellyfinInstallDirectory = "$env:Appdata\jellyfin\"
}else{
$Script:DefaultJellyfinInstallDirectory = $InstallLocation
}
if([string]::IsNullOrEmpty($EmbyLibraryLocation)){
$Script:defaultEmbyDataDir = "$env:Appdata\Emby-Server\data\"
}else{
$Script:defaultEmbyDataDir = $EmbyLibraryLocation
}
if($InstallAsService.IsPresent -or $InstallAsService -eq $true){
$Script:InstallAsService = $true
}else{$Script:InstallAsService = $false}
if($null -eq $ServiceUser){
$Script:InstallServiceAsUser = $false
}else{
$Script:InstallServiceAsUser = $true
$Script:UserCredentials = $ServiceUser
$Script:JellyfinDataDir = "C:\Users\$($Script:UserCredentials.UserName)\Appdata\Roaming\jellyfin\"}
if($CreateDesktopShorcut.IsPresent -or $CreateDesktopShorcut -eq $true) {$Script:CreateShortcut = $true}else{$Script:CreateShortcut = $false}
if($MigrateEmbyLibrary.IsPresent -or $MigrateEmbyLibrary -eq $true){$Script:MigrateLibrary = $true}else{$Script:MigrateLibrary = $false}
if($LaunchJellyfin.IsPresent -or $LaunchJellyfin -eq $true){$Script:StartJellyfin = $true}else{$Script:StartJellyfin = $false}
if(-not (Test-Path $Script:DefaultJellyfinInstallDirectory)){
mkdir $Script:DefaultJellyfinInstallDirectory
}
Copy-Item -Path $PSScriptRoot/* -DestinationPath "$Script:DefaultJellyfinInstallDirectory/" -Force -Recurse
if($Script:InstallAsService){
if($Script:InstallServiceAsUser){
&"$Script:DefaultJellyfinInstallDirectory\nssm.exe" install Jellyfin `"$Script:DefaultJellyfinInstallDirectory\jellyfin.exe`" -programdata `"$Script:JellyfinDataDir`"
Start-Sleep -Milliseconds 500
&sc.exe config Jellyfin obj=".\$($Script:UserCredentials.UserName)" password="$($Script:UserCredentials.GetNetworkCredential().Password)"
&"$Script:DefaultJellyfinInstallDirectory\nssm.exe" set Jellyfin Start SERVICE_DELAYED_AUTO_START
}else{
&"$Script:DefaultJellyfinInstallDirectory\nssm.exe" install Jellyfin `"$Script:DefaultJellyfinInstallDirectory\jellyfin.exe`" -programdata `"$Script:JellyfinDataDir`"
Start-Sleep -Milliseconds 500
#&"$Script:DefaultJellyfinInstallDirectory\nssm.exe" set Jellyfin ObjectName $Script:UserCredentials.UserName $Script:UserCredentials.GetNetworkCredential().Password
#Set-Service -Name Jellyfin -Credential $Script:UserCredentials
&"$Script:DefaultJellyfinInstallDirectory\nssm.exe" set Jellyfin Start SERVICE_DELAYED_AUTO_START
}
}
if($Script:MigrateLibrary){
Copy-Item -Path $Script:defaultEmbyDataDir/config -Destination $Script:JellyfinDataDir -force -Recurse
Copy-Item -Path $Script:defaultEmbyDataDir/cache -Destination $Script:JellyfinDataDir -force -Recurse
Copy-Item -Path $Script:defaultEmbyDataDir/data -Destination $Script:JellyfinDataDir -force -Recurse
Copy-Item -Path $Script:defaultEmbyDataDir/metadata -Destination $Script:JellyfinDataDir -force -Recurse
Copy-Item -Path $Script:defaultEmbyDataDir/root -Destination $Script:JellyfinDataDir -force -Recurse
}
if($Script:CreateShortcut){
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$Home\Desktop\Jellyfin.lnk")
$Shortcut.TargetPath = "$Script:DefaultJellyfinInstallDirectory\jellyfin.exe"
$Shortcut.Save()
}
if($Script:StartJellyfin){
if($Script:InstallAsService){
Get-Service Jellyfin | Start-Service
}else{
Start-Process -FilePath $Script:DefaultJellyfinInstallDirectory\jellyfin.exe -PassThru
}
}
}else{
}
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Script:JellyFinDataDir = "$env:AppData\jellyfin\"
$Script:DefaultJellyfinInstallDirectory = "$env:Appdata\jellyfin\"
$Script:defaultEmbyDataDir = "$env:Appdata\Emby-Server\"
$Script:InstallAsService = $False
$Script:InstallServiceAsUser = $false
$Script:CreateShortcut = $false
$Script:MigrateLibrary = $false
$Script:StartJellyfin = $false
function InstallJellyfin {
Write-Host "Install as service: $Script:InstallAsService"
Write-Host "Install as serviceuser: $Script:InstallServiceAsUser"
Write-Host "Create Shortcut: $Script:CreateShortcut"
Write-Host "MigrateLibrary: $Script:MigrateLibrary"
$GUIElementsCollection | ForEach-Object {
$_.Enabled = $false
}
Write-Host "Making Jellyfin directory"
$ProgressBar.Minimum = 1
$ProgressBar.Maximum = 100
$ProgressBar.Value = 1
if($Script:DefaultJellyfinInstallDirectory -ne $InstallLocationBox.Text){
Write-Host "Custom Install Location Chosen: $($InstallLocationBox.Text)"
$Script:DefaultJellyfinInstallDirectory = $InstallLocationBox.Text
}
if($Script:JellyfinDataDir -ne $CustomLibraryBox.Text){
Write-Host "Custom Library Location Chosen: $($CustomLibraryBox.Text)"
$Script:JellyfinDataDir = $CustomLibraryBox.Text
}
if(-not (Test-Path $Script:DefaultJellyfinInstallDirectory)){
mkdir $Script:DefaultJellyfinInstallDirectory
}
Write-Host "Copying Jellyfin Data"
$progressbar.Value = 10
Copy-Item -Path $PSScriptRoot/* -Destination $Script:DefaultJellyfinInstallDirectory/ -Force -Recurse
Write-Host "Finished Copying"
$ProgressBar.Value = 50
if($Script:InstallAsService){
if($Script:InstallServiceAsUser){
Write-Host "Installing Service as user $($Script:UserCredentials.UserName)"
&"$Script:DefaultJellyfinInstallDirectory\nssm.exe" install Jellyfin `"$Script:DefaultJellyfinInstallDirectory\jellyfin.exe`" -programdata `"$Script:JellyfinDataDir`"
Start-Sleep -Milliseconds 2000
&sc.exe config Jellyfin obj=".\$($Script:UserCredentials.UserName)" password="$($Script:UserCredentials.GetNetworkCredential().Password)"
&"$Script:DefaultJellyfinInstallDirectory\nssm.exe" set Jellyfin Start SERVICE_DELAYED_AUTO_START
}else{
Write-Host "Installing Service as LocalSystem"
&"$Script:DefaultJellyfinInstallDirectory\nssm.exe" install Jellyfin `"$Script:DefaultJellyfinInstallDirectory\jellyfin.exe`" -programdata `"$Script:JellyfinDataDir`"
Start-Sleep -Milliseconds 2000
&"$Script:DefaultJellyfinInstallDirectory\nssm.exe" set Jellyfin Start SERVICE_DELAYED_AUTO_START
}
}
$progressbar.Value = 60
if($Script:MigrateLibrary){
if($Script:defaultEmbyDataDir -ne $LibraryLocationBox.Text){
Write-Host "Custom location defined for emby library: $($LibraryLocationBox.Text)"
$Script:defaultEmbyDataDir = $LibraryLocationBox.Text
}
Write-Host "Copying emby library from $Script:defaultEmbyDataDir to $Script:JellyFinDataDir"
Write-Host "This could take a while depending on the size of your library. Please be patient"
Write-Host "Copying config"
Copy-Item -Path $Script:defaultEmbyDataDir/config -Destination $Script:JellyfinDataDir -force -Recurse
Write-Host "Copying cache"
Copy-Item -Path $Script:defaultEmbyDataDir/cache -Destination $Script:JellyfinDataDir -force -Recurse
Write-Host "Copying data"
Copy-Item -Path $Script:defaultEmbyDataDir/data -Destination $Script:JellyfinDataDir -force -Recurse
Write-Host "Copying metadata"
Copy-Item -Path $Script:defaultEmbyDataDir/metadata -Destination $Script:JellyfinDataDir -force -Recurse
Write-Host "Copying root dir"
Copy-Item -Path $Script:defaultEmbyDataDir/root -Destination $Script:JellyfinDataDir -force -Recurse
}
$progressbar.Value = 80
if($Script:CreateShortcut){
Write-Host "Creating Shortcut"
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$Home\Desktop\Jellyfin.lnk")
$Shortcut.TargetPath = "$Script:DefaultJellyfinInstallDirectory\jellyfin.exe"
$Shortcut.Save()
}
$ProgressBar.Value = 90
if($Script:StartJellyfin){
if($Script:InstallAsService){
Write-Host "Starting Jellyfin Service"
Get-Service Jellyfin | Start-Service
}else{
Write-Host "Starting Jellyfin"
Start-Process -FilePath $Script:DefaultJellyfinInstallDirectory\jellyfin.exe -PassThru
}
}
$progressbar.Value = 100
Write-Host Finished
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("Operation Completed",0,"Done",0x1)
$InstallForm.Close()
}
function ServiceBoxCheckChanged {
if($InstallAsServiceCheck.Checked){
$Script:InstallAsService = $true
$ServiceUserLabel.Visible = $true
$ServiceUserLabel.Enabled = $true
$ServiceUserBox.Visible = $true
$ServiceUserBox.Enabled = $true
}else{
$Script:InstallAsService = $false
$ServiceUserLabel.Visible = $false
$ServiceUserLabel.Enabled = $false
$ServiceUserBox.Visible = $false
$ServiceUserBox.Enabled = $false
}
}
function UserSelect {
if($ServiceUserBox.Text -eq 'Local System')
{
$Script:InstallServiceAsUser = $false
$Script:UserCredentials = $null
$ServiceUserBox.Items.RemoveAt(1)
$ServiceUserBox.Items.Add("Custom User")
}elseif($ServiceUserBox.Text -eq 'Custom User'){
$Script:InstallServiceAsUser = $true
$Script:UserCredentials = Get-Credential -Message "Please enter the credentials of the user you with to run Jellyfin Service as" -UserName $env:USERNAME
$ServiceUserBox.Items[1] = "$($Script:UserCredentials.UserName)"
}
}
function CreateShortcutBoxCheckChanged {
if($CreateShortcutCheck.Checked){
$Script:CreateShortcut = $true
}else{
$Script:CreateShortcut = $False
}
}
function StartJellyFinBoxCheckChanged {
if($StartProgramCheck.Checked){
$Script:StartJellyfin = $true
}else{
$Script:StartJellyfin = $false
}
}
function CustomLibraryCheckChanged {
if($CustomLibraryCheck.Checked){
$Script:UseCustomLibrary = $true
$CustomLibraryBox.Enabled = $true
}else{
$Script:UseCustomLibrary = $false
$CustomLibraryBox.Enabled = $false
}
}
function MigrateLibraryCheckboxChanged {
if($MigrateLibraryCheck.Checked){
$Script:MigrateLibrary = $true
$LibraryMigrationLabel.Visible = $true
$LibraryMigrationLabel.Enabled = $true
$LibraryLocationBox.Visible = $true
$LibraryLocationBox.Enabled = $true
}else{
$Script:MigrateLibrary = $false
$LibraryMigrationLabel.Visible = $false
$LibraryMigrationLabel.Enabled = $false
$LibraryLocationBox.Visible = $false
$LibraryLocationBox.Enabled = $false
}
}
#region begin GUI{
$InstallForm = New-Object system.Windows.Forms.Form
$InstallForm.ClientSize = '320,240'
$InstallForm.text = "Terrible Jellyfin Installer"
$InstallForm.TopMost = $false
$GUIElementsCollection = @()
$InstallButton = New-Object system.Windows.Forms.Button
$InstallButton.text = "Install"
$InstallButton.width = 60
$InstallButton.height = 30
$InstallButton.location = New-Object System.Drawing.Point(5,5)
$InstallButton.Font = 'Microsoft Sans Serif,10'
$GUIElementsCollection += $InstallButton
$ProgressBar = New-Object system.Windows.Forms.ProgressBar
$ProgressBar.width = 245
$ProgressBar.height = 30
$ProgressBar.location = New-Object System.Drawing.Point(70,5)
$InstallLocationLabel = New-Object system.Windows.Forms.Label
$InstallLocationLabel.text = "Install Location"
$InstallLocationLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft
$InstallLocationLabel.AutoSize = $true
$InstallLocationLabel.width = 100
$InstallLocationLabel.height = 20
$InstallLocationLabel.location = New-Object System.Drawing.Point(5,50)
$InstallLocationLabel.Font = 'Microsoft Sans Serif,10'
$GUIElementsCollection += $InstallLocationLabel
$InstallLocationBox = New-Object system.Windows.Forms.TextBox
$InstallLocationBox.multiline = $false
$InstallLocationBox.width = 205
$InstallLocationBox.height = 20
$InstallLocationBox.location = New-Object System.Drawing.Point(110,50)
$InstallLocationBox.Text = $Script:DefaultJellyfinInstallDirectory
$InstallLocationBox.Font = 'Microsoft Sans Serif,10'
$GUIElementsCollection += $InstallLocationBox
$CustomLibraryCheck = New-Object system.Windows.Forms.CheckBox
$CustomLibraryCheck.text = "Custom Library Location:"
$CustomLibraryCheck.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft
$CustomLibraryCheck.AutoSize = $false
$CustomLibraryCheck.width = 180
$CustomLibraryCheck.height = 20
$CustomLibraryCheck.location = New-Object System.Drawing.Point(5,75)
$CustomLibraryCheck.Font = 'Microsoft Sans Serif,10'
$GUIElementsCollection += $CustomLibraryCheck
$CustomLibraryBox = New-Object system.Windows.Forms.TextBox
$CustomLibraryBox.multiline = $false
$CustomLibraryBox.width = 130
$CustomLibraryBox.height = 20
$CustomLibraryBox.location = New-Object System.Drawing.Point(185,75)
$CustomLibraryBox.Text = $Script:JellyFinDataDir
$CustomLibraryBox.Font = 'Microsoft Sans Serif,10'
$CustomLibraryBox.Enabled = $false
$GUIElementsCollection += $CustomLibraryBox
$InstallAsServiceCheck = New-Object system.Windows.Forms.CheckBox
$InstallAsServiceCheck.text = "Install as Service"
$InstallAsServiceCheck.AutoSize = $false
$InstallAsServiceCheck.width = 140
$InstallAsServiceCheck.height = 20
$InstallAsServiceCheck.location = New-Object System.Drawing.Point(5,125)
$InstallAsServiceCheck.Font = 'Microsoft Sans Serif,10'
$GUIElementsCollection += $InstallAsServiceCheck
$ServiceUserLabel = New-Object system.Windows.Forms.Label
$ServiceUserLabel.text = "Run Service As:"
$ServiceUserLabel.AutoSize = $true
$ServiceUserLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft
$ServiceUserLabel.width = 100
$ServiceUserLabel.height = 20
$ServiceUserLabel.location = New-Object System.Drawing.Point(15,145)
$ServiceUserLabel.Font = 'Microsoft Sans Serif,10'
$ServiceUserLabel.Visible = $false
$ServiceUserLabel.Enabled = $false
$GUIElementsCollection += $ServiceUserLabel
$ServiceUserBox = New-Object system.Windows.Forms.ComboBox
$ServiceUserBox.text = "Run Service As"
$ServiceUserBox.width = 195
$ServiceUserBox.height = 20
@('Local System','Custom User') | ForEach-Object {[void] $ServiceUserBox.Items.Add($_)}
$ServiceUserBox.location = New-Object System.Drawing.Point(120,145)
$ServiceUserBox.Font = 'Microsoft Sans Serif,10'
$ServiceUserBox.Visible = $false
$ServiceUserBox.Enabled = $false
$ServiceUserBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
$GUIElementsCollection += $ServiceUserBox
$MigrateLibraryCheck = New-Object system.Windows.Forms.CheckBox
$MigrateLibraryCheck.text = "Import Emby Library"
$MigrateLibraryCheck.AutoSize = $false
$MigrateLibraryCheck.width = 160
$MigrateLibraryCheck.height = 20
$MigrateLibraryCheck.location = New-Object System.Drawing.Point(5,170)
$MigrateLibraryCheck.Font = 'Microsoft Sans Serif,10'
$GUIElementsCollection += $MigrateLibraryCheck
$LibraryMigrationLabel = New-Object system.Windows.Forms.Label
$LibraryMigrationLabel.text = "Emby Library Path"
$LibraryMigrationLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft
$LibraryMigrationLabel.AutoSize = $false
$LibraryMigrationLabel.width = 120
$LibraryMigrationLabel.height = 20
$LibraryMigrationLabel.location = New-Object System.Drawing.Point(15,190)
$LibraryMigrationLabel.Font = 'Microsoft Sans Serif,10'
$LibraryMigrationLabel.Visible = $false
$LibraryMigrationLabel.Enabled = $false
$GUIElementsCollection += $LibraryMigrationLabel
$LibraryLocationBox = New-Object system.Windows.Forms.TextBox
$LibraryLocationBox.multiline = $false
$LibraryLocationBox.width = 175
$LibraryLocationBox.height = 20
$LibraryLocationBox.location = New-Object System.Drawing.Point(140,190)
$LibraryLocationBox.Text = $Script:defaultEmbyDataDir
$LibraryLocationBox.Font = 'Microsoft Sans Serif,10'
$LibraryLocationBox.Visible = $false
$LibraryLocationBox.Enabled = $false
$GUIElementsCollection += $LibraryLocationBox
$CreateShortcutCheck = New-Object system.Windows.Forms.CheckBox
$CreateShortcutCheck.text = "Desktop Shortcut"
$CreateShortcutCheck.AutoSize = $false
$CreateShortcutCheck.width = 150
$CreateShortcutCheck.height = 20
$CreateShortcutCheck.location = New-Object System.Drawing.Point(5,215)
$CreateShortcutCheck.Font = 'Microsoft Sans Serif,10'
$GUIElementsCollection += $CreateShortcutCheck
$StartProgramCheck = New-Object system.Windows.Forms.CheckBox
$StartProgramCheck.text = "Start Jellyfin"
$StartProgramCheck.AutoSize = $false
$StartProgramCheck.width = 160
$StartProgramCheck.height = 20
$StartProgramCheck.location = New-Object System.Drawing.Point(160,215)
$StartProgramCheck.Font = 'Microsoft Sans Serif,10'
$GUIElementsCollection += $StartProgramCheck
$InstallForm.controls.AddRange($GUIElementsCollection)
$InstallForm.Controls.Add($ProgressBar)
#region gui events {
$InstallButton.Add_Click({ InstallJellyfin })
$CustomLibraryCheck.Add_CheckedChanged({CustomLibraryCheckChanged})
$InstallAsServiceCheck.Add_CheckedChanged({ServiceBoxCheckChanged})
$ServiceUserBox.Add_SelectedValueChanged({ UserSelect })
$MigrateLibraryCheck.Add_CheckedChanged({MigrateLibraryCheckboxChanged})
$CreateShortcutCheck.Add_CheckedChanged({CreateShortcutBoxCheckChanged})
$StartProgramCheck.Add_CheckedChanged({StartJellyFinBoxCheckChanged})
#endregion events }
#endregion GUI }
[void]$InstallForm.ShowDialog()

1
install.bat Normal file
View File

@ -0,0 +1 @@
powershell.exe -executionpolicy Bypass -file install-jellyfin.ps1

22
new-file-header.txt Normal file
View File

@ -0,0 +1,22 @@
### This header should be used to start new files.
### It provides an explicit per-file license reference that should be present on all new files.
### To use this header, delete these lines and the following empty line, modify <filename> to
### the proper full path, and then add new code following the header and a single empty line.
// <filename>
// Part of the Jellyfin project (https://jellyfin.media)
//
// All copyright belongs to the Jellyfin contributors; a full list can
// be found in the file CONTRIBUTORS.md
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.