Jackett/src/Jackett/Services/ConfigurationService.cs

278 lines
10 KiB
C#
Raw Normal View History

using Jackett.Utils;
using Newtonsoft.Json.Linq;
2015-07-19 13:22:50 +00:00
using NLog;
2015-07-19 00:27:41 +00:00
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
2015-07-24 21:38:31 +00:00
using System.Security.AccessControl;
using System.Security.Principal;
2015-07-19 00:27:41 +00:00
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Jackett.Services
{
public interface IConfigurationService
{
string GetContentFolder();
string GetVersion();
string GetIndexerConfigDir();
string GetAppDataFolder();
string GetSonarrConfigFile();
2015-07-19 13:22:50 +00:00
T GetConfig<T>();
void SaveConfig<T>(T config);
string ApplicationFolder();
List<string> GetCardigannDefinitionsFolders();
void CreateOrMigrateSettings();
void PerformMigration();
2015-07-19 00:27:41 +00:00
}
2015-07-19 16:35:56 +00:00
public class ConfigurationService : IConfigurationService
2015-07-19 00:27:41 +00:00
{
2015-07-19 13:22:50 +00:00
private ISerializeService serializeService;
private Logger logger;
private IProcessService processService;
2015-07-19 13:22:50 +00:00
public ConfigurationService(ISerializeService s, IProcessService p, Logger l)
2015-07-19 00:27:41 +00:00
{
2015-07-19 13:22:50 +00:00
serializeService = s;
logger = l;
processService = p;
2015-07-19 13:22:50 +00:00
CreateOrMigrateSettings();
}
public void CreateOrMigrateSettings()
2015-07-19 13:22:50 +00:00
{
try
2015-07-19 00:27:41 +00:00
{
2015-07-19 13:22:50 +00:00
if (!Directory.Exists(GetAppDataFolder()))
{
2015-07-24 21:38:31 +00:00
var dir = Directory.CreateDirectory(GetAppDataFolder());
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
{
var access = dir.GetAccessControl();
access.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow));
Directory.SetAccessControl(GetAppDataFolder(), access);
}
2015-07-19 13:22:50 +00:00
}
logger.Info("App config/log directory: " + GetAppDataFolder());
2015-07-19 00:27:41 +00:00
}
2015-07-19 13:22:50 +00:00
catch (Exception ex)
{
throw new Exception("Could not create settings directory. " + ex.Message);
}
2015-07-24 21:38:31 +00:00
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
2015-07-19 13:22:50 +00:00
{
2015-07-24 21:38:31 +00:00
try
2015-07-19 13:22:50 +00:00
{
2015-07-24 21:38:31 +00:00
string oldDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Jackett");
if (Directory.Exists(oldDir))
2015-07-19 13:22:50 +00:00
{
2015-07-24 21:38:31 +00:00
// On Windows we need admin permissions to migrate as they were made with admin permissions.
if (ServerUtil.IsUserAdministrator())
2015-07-19 13:22:50 +00:00
{
PerformMigration();
2015-07-19 13:22:50 +00:00
}
else
2015-07-19 16:35:56 +00:00
{
try
{
processService.StartProcessAndLog(Application.ExecutablePath, "--MigrateSettings", true);
}
catch
{
Engine.Logger.Error("Unable to migrate settings when not running as administrator.");
Environment.ExitCode = 1;
return;
}
2015-07-19 16:35:56 +00:00
}
2015-07-24 21:38:31 +00:00
}
else
{
PerformMigration();
2015-07-19 13:22:50 +00:00
}
2015-07-24 21:38:31 +00:00
}
catch (Exception ex)
{
logger.Error("ERROR could not migrate settings directory " + ex);
2015-07-19 13:22:50 +00:00
}
}
}
public void PerformMigration()
{
var oldDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Jackett");
2015-07-24 21:38:31 +00:00
if (Directory.Exists(oldDir))
{
2015-11-10 22:02:02 +00:00
foreach (var file in Directory.GetFiles(oldDir, "*", SearchOption.AllDirectories))
{
2015-07-24 21:38:31 +00:00
var path = file.Replace(oldDir, "");
var destPath = GetAppDataFolder() + path;
var destFolder = Path.GetDirectoryName(destPath);
if (!Directory.Exists(destFolder))
{
var dir = Directory.CreateDirectory(destFolder);
var access = dir.GetAccessControl();
access.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow));
Directory.SetAccessControl(destFolder, access);
}
if (!File.Exists(destPath))
{
File.Copy(file, destPath);
// The old files were created when running as admin so make sure they are editable by normal users / services.
if (System.Environment.OSVersion.Platform != PlatformID.Unix)
{
var access = File.GetAccessControl(destPath);
access.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow));
File.SetAccessControl(destPath, access);
}
}
}
2015-07-24 21:38:31 +00:00
Directory.Delete(oldDir, true);
}
}
2015-07-19 13:22:50 +00:00
public T GetConfig<T>()
{
var type = typeof(T);
var fullPath = Path.Combine(GetAppDataFolder(), type.Name + ".json");
try
{
if (!File.Exists(fullPath))
{
logger.Debug("Config file does not exist: " + fullPath);
return default(T);
}
return serializeService.DeSerialise<T>(File.ReadAllText(fullPath));
}
2015-07-19 16:35:56 +00:00
catch (Exception e)
2015-07-19 00:27:41 +00:00
{
2015-07-19 13:22:50 +00:00
logger.Error(e, "Error reading config file " + fullPath);
return default(T);
2015-07-19 00:27:41 +00:00
}
}
2015-07-19 13:22:50 +00:00
public void SaveConfig<T>(T config)
{
var type = typeof(T);
var fullPath = Path.Combine(GetAppDataFolder(), type.Name + ".json");
try
{
var json = serializeService.Serialise(config);
if (!Directory.Exists(GetAppDataFolder()))
Directory.CreateDirectory(GetAppDataFolder());
File.WriteAllText(fullPath, json);
}
catch (Exception e)
{
2016-10-01 17:53:43 +00:00
logger.Error(e, "Error writing config file " + fullPath);
2015-07-19 13:22:50 +00:00
}
}
public string ApplicationFolder()
{
return Path.GetDirectoryName(Application.ExecutablePath);
}
public string GetContentFolder()
{
// If we are debugging we can use the non copied content.
string dir = Path.Combine(ApplicationFolder(), "Content"); ;
#if DEBUG
// When we are running in debug use the source files
var sourcePath = Path.GetFullPath(Path.Combine(ApplicationFolder(), "..\\..\\..\\Jackett\\Content"));
if (Directory.Exists(sourcePath))
2015-07-19 13:22:50 +00:00
{
dir = sourcePath;
2015-07-19 13:22:50 +00:00
}
#endif
return dir;
}
public List<string> GetCardigannDefinitionsFolders()
{
List<string> dirs = new List<string>();
if (System.Environment.OSVersion.Platform == PlatformID.Unix)
{
dirs.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "cardigann/definitions/"));
dirs.Add("/etc/xdg/cardigan/definitions/");
}
else
{
dirs.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "cardigann\\definitions\\"));
dirs.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "cardigann\\definitions\\"));
}
// If we are debugging we can use the non copied definitions.
string dir = Path.Combine(ApplicationFolder(), "Definitions"); ;
#if DEBUG
// When we are running in debug use the source files
var sourcePath = Path.GetFullPath(Path.Combine(ApplicationFolder(), "..\\..\\..\\Jackett\\Definitions"));
if (Directory.Exists(sourcePath))
{
dir = sourcePath;
}
#endif
dirs.Add(dir);
return dirs;
2015-07-19 13:22:50 +00:00
}
2015-07-19 00:27:41 +00:00
public string GetVersion()
{
return Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
public string GetAppDataFolder()
{
2015-07-19 13:22:50 +00:00
return GetAppDataFolderStatic();
}
/// <summary>
/// This is needed for the logger prior to ioc setup.
/// </summary>
/// <returns></returns>
public static string GetAppDataFolderStatic()
{
if (!string.IsNullOrWhiteSpace(Startup.CustomDataFolder))
{
return Startup.CustomDataFolder;
}
if (System.Environment.OSVersion.Platform == PlatformID.Unix)
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Jackett");
}
else
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Jackett");
}
2015-07-19 00:27:41 +00:00
}
public string GetIndexerConfigDir()
{
2015-07-19 16:35:56 +00:00
return Path.Combine(GetAppDataFolder(), "Indexers");
2015-07-19 00:27:41 +00:00
}
public string GetConfigFile()
{
return Path.Combine(GetAppDataFolder(), "config.json");
}
public string GetSonarrConfigFile()
{
return Path.Combine(GetAppDataFolder(), "sonarr_api.json");
}
}
}