mirror of
https://github.com/Radarr/Radarr.git
synced 2024-08-19 08:49:43 +02:00
Start of AutoConfigureSab
This commit is contained in:
parent
ea2e520632
commit
a34bd818cf
3
.gitignore
vendored
3
.gitignore
vendored
@ -31,4 +31,5 @@ _ReSharper*/
|
||||
[Ll]ogs/
|
||||
/[Pp]ackage/
|
||||
#NZBDrone specific
|
||||
*.db
|
||||
*.db
|
||||
*Web.Publish.xml
|
15
NzbDrone.Core/Model/SabnzbdInfoModel.cs
Normal file
15
NzbDrone.Core/Model/SabnzbdInfoModel.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NzbDrone.Core.Model
|
||||
{
|
||||
public class SabnzbdInfoModel
|
||||
{
|
||||
public string ApiKey { get; set; }
|
||||
public int Port { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
@ -166,6 +166,8 @@
|
||||
<Compile Include="Instrumentation\SubsonicTarget.cs" />
|
||||
<Compile Include="Instrumentation\ExceptioneerTarget.cs" />
|
||||
<Compile Include="Instrumentation\NlogWriter.cs" />
|
||||
<Compile Include="Model\SabnzbdInfoModel.cs" />
|
||||
<Compile Include="Providers\AutoConfigureProvider.cs" />
|
||||
<Compile Include="Providers\Indexer\NzbMatrixProvider.cs" />
|
||||
<Compile Include="Providers\Jobs\NewSeriesUpdate.cs" />
|
||||
<Compile Include="Providers\Jobs\JobProvider.cs" />
|
||||
|
@ -1,290 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Repository.Quality;
|
||||
|
||||
namespace NzbDrone.Core
|
||||
{
|
||||
public static class Parser
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static readonly Regex[] ReportTitleRegex = new[]
|
||||
{
|
||||
new Regex(@"^(?<title>.+?)?\W?(?<year>\d{4}?)?\W+(?<airyear>\d{4})\W+(?<airmonth>\d{2})\W+(?<airday>\d{2})\W?(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
new Regex(@"^(?<title>.*?)?(?:\W?S?(?<season>\d{1,2}(?!\d+))(?:(?:\-|\.|[ex]|\s|to)+(?<episode>\d{1,2}(?!\d+)))+)+\W?(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
new Regex(@"^(?<title>.+?)?\W?(?<year>\d{4}?)?(?:\W(?<season>\d+)(?<episode>\d{2}))+\W?(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
//Supports 103/113 naming
|
||||
new Regex(@"^(?<title>.*?)?(?:\W?S?(?<season>\d{1,2}(?!\d+))(?:(?:\-|\.|[ex]|\s|to)+(?<episode>\d+))+)+\W?(?!\\)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled)
|
||||
};
|
||||
|
||||
private static readonly Regex[] SeasonReportTitleRegex = new[]
|
||||
{
|
||||
new Regex(
|
||||
@"(?<title>.+?)?\W?(?<year>\d{4}?)?\W(?:S|Season)?\W?(?<season>\d+)(?!\\)",
|
||||
RegexOptions.IgnoreCase |
|
||||
RegexOptions.Compiled),
|
||||
};
|
||||
|
||||
private static readonly Regex NormalizeRegex = new Regex(@"((^|\W)(a|an|the|and|or|of)($|\W))|\W|\b(?!(?:19\d{2}|20\d{2}))\d+\b",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// Parses a post title into list of episodes it contains
|
||||
/// </summary>
|
||||
/// <param name = "title">Title of the report</param>
|
||||
/// <returns>List of episodes contained to the post</returns>
|
||||
internal static EpisodeParseResult ParseEpisodeInfo(string title)
|
||||
{
|
||||
Logger.Trace("Parsing string '{0}'", title);
|
||||
|
||||
foreach (var regex in ReportTitleRegex)
|
||||
{
|
||||
var simpleTitle = Regex.Replace(title, @"480[i|p]|720[i|p]|1080[i|p]|[x|h]264", String.Empty, RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
var match = regex.Matches(simpleTitle);
|
||||
|
||||
if (match.Count != 0)
|
||||
{
|
||||
var seriesName = NormalizeTitle(match[0].Groups["title"].Value);
|
||||
|
||||
var airyear = 0;
|
||||
Int32.TryParse(match[0].Groups["airyear"].Value, out airyear);
|
||||
|
||||
EpisodeParseResult parsedEpisode;
|
||||
|
||||
if (airyear < 1 )
|
||||
{
|
||||
var season = 0;
|
||||
Int32.TryParse(match[0].Groups["season"].Value, out season);
|
||||
|
||||
parsedEpisode = new EpisodeParseResult
|
||||
{
|
||||
Proper = title.ToLower().Contains("proper"),
|
||||
CleanTitle = seriesName,
|
||||
SeasonNumber = season,
|
||||
Episodes = new List<int>()
|
||||
};
|
||||
|
||||
foreach (Match matchGroup in match)
|
||||
{
|
||||
var count = matchGroup.Groups["episode"].Captures.Count;
|
||||
var first = Convert.ToInt32(matchGroup.Groups["episode"].Captures[0].Value);
|
||||
var last = Convert.ToInt32(matchGroup.Groups["episode"].Captures[count - 1].Value);
|
||||
|
||||
for (int i = first; i <= last; i++)
|
||||
{
|
||||
parsedEpisode.Episodes.Add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
//Try to Parse as a daily show
|
||||
if (airyear > 0)
|
||||
{
|
||||
var airmonth = Convert.ToInt32(match[0].Groups["airmonth"].Value);
|
||||
var airday = Convert.ToInt32(match[0].Groups["airday"].Value);
|
||||
|
||||
parsedEpisode = new EpisodeParseResult
|
||||
{
|
||||
Proper = title.ToLower().Contains("proper"),
|
||||
CleanTitle = seriesName,
|
||||
AirDate = new DateTime(airyear, airmonth, airday)
|
||||
};
|
||||
}
|
||||
|
||||
//Something went wrong with this one... return null
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
parsedEpisode.Quality = ParseQuality(title);
|
||||
|
||||
Logger.Trace("Episode Parsed. {0}", parsedEpisode);
|
||||
|
||||
return parsedEpisode;
|
||||
}
|
||||
}
|
||||
Logger.Warn("Unable to parse text into episode info. {0}", title);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a post title into season it contains
|
||||
/// </summary>
|
||||
/// <param name = "title">Title of the report</param>
|
||||
/// <returns>Season information contained in the post</returns>
|
||||
internal static SeasonParseResult ParseSeasonInfo(string title)
|
||||
{
|
||||
Logger.Trace("Parsing string '{0}'", title);
|
||||
|
||||
foreach (var regex in ReportTitleRegex)
|
||||
{
|
||||
var match = regex.Matches(title);
|
||||
|
||||
if (match.Count != 0)
|
||||
{
|
||||
var seriesName = NormalizeTitle(match[0].Groups["title"].Value);
|
||||
int year;
|
||||
Int32.TryParse(match[0].Groups["year"].Value, out year);
|
||||
|
||||
if (year < 1900 || year > DateTime.Now.Year + 1)
|
||||
{
|
||||
year = 0;
|
||||
}
|
||||
|
||||
var seasonNumber = Convert.ToInt32(match[0].Groups["season"].Value);
|
||||
|
||||
var result = new SeasonParseResult
|
||||
{
|
||||
SeriesTitle = seriesName,
|
||||
SeasonNumber = seasonNumber,
|
||||
Year = year,
|
||||
Quality = ParseQuality(title)
|
||||
};
|
||||
|
||||
|
||||
Logger.Trace("Season Parsed. {0}", result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null; //Return null
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a post title to find the series that relates to it
|
||||
/// </summary>
|
||||
/// <param name = "title">Title of the report</param>
|
||||
/// <returns>Normalized Series Name</returns>
|
||||
internal static string ParseSeriesName(string title)
|
||||
{
|
||||
Logger.Trace("Parsing string '{0}'", title);
|
||||
|
||||
foreach (var regex in ReportTitleRegex)
|
||||
{
|
||||
var match = regex.Matches(title);
|
||||
|
||||
if (match.Count != 0)
|
||||
{
|
||||
var seriesName = NormalizeTitle(match[0].Groups["title"].Value);
|
||||
|
||||
Logger.Trace("Series Parsed. {0}", seriesName);
|
||||
return seriesName;
|
||||
}
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses proper status out of a report title
|
||||
/// </summary>
|
||||
/// <param name = "title">Title of the report</param>
|
||||
/// <returns></returns>
|
||||
internal static bool ParseProper(string title)
|
||||
{
|
||||
return title.ToLower().Contains("proper");
|
||||
}
|
||||
|
||||
internal static QualityTypes ParseQuality(string name)
|
||||
{
|
||||
Logger.Trace("Trying to parse quality for {0}", name);
|
||||
|
||||
var result = QualityTypes.Unknown;
|
||||
name = name.ToLowerInvariant();
|
||||
|
||||
if (name.Contains("dvd"))
|
||||
return QualityTypes.DVD;
|
||||
|
||||
if (name.Contains("bdrip") || name.Contains("brrip"))
|
||||
{
|
||||
return QualityTypes.BDRip;
|
||||
}
|
||||
|
||||
if (name.Contains("xvid") || name.Contains("divx"))
|
||||
{
|
||||
if (name.Contains("bluray"))
|
||||
{
|
||||
return QualityTypes.BDRip;
|
||||
}
|
||||
|
||||
return QualityTypes.TV;
|
||||
}
|
||||
|
||||
if (name.Contains("bluray"))
|
||||
{
|
||||
if (name.Contains("720p"))
|
||||
return QualityTypes.Bluray720;
|
||||
|
||||
if (name.Contains("1080p"))
|
||||
return QualityTypes.Bluray1080;
|
||||
|
||||
return QualityTypes.Bluray720;
|
||||
}
|
||||
if (name.Contains("web-dl"))
|
||||
return QualityTypes.WEBDL;
|
||||
if (name.Contains("x264") || name.Contains("h264") || name.Contains("720p"))
|
||||
return QualityTypes.HDTV;
|
||||
|
||||
//Based on extension
|
||||
if (result == QualityTypes.Unknown)
|
||||
{
|
||||
switch (new FileInfo(name).Extension.ToLower())
|
||||
{
|
||||
case ".avi":
|
||||
case ".xvid":
|
||||
case ".wmv":
|
||||
{
|
||||
result = QualityTypes.TV;
|
||||
break;
|
||||
}
|
||||
case ".mkv":
|
||||
{
|
||||
result = QualityTypes.HDTV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Trace("Quality Parsed:{0} Title:", result, name);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes the title. removing all non-word characters as well as common tokens
|
||||
/// such as 'the' and 'and'
|
||||
/// </summary>
|
||||
/// <param name = "title">title</param>
|
||||
/// <returns></returns>
|
||||
public static string NormalizeTitle(string title)
|
||||
{
|
||||
return NormalizeRegex.Replace(title, String.Empty).ToLower();
|
||||
}
|
||||
|
||||
|
||||
public static string NormalizePath(string path)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(path))
|
||||
throw new ArgumentException("Path can not be null or empty");
|
||||
|
||||
var info = new FileInfo(path);
|
||||
|
||||
if (info.FullName.StartsWith(@"\\")) //UNC
|
||||
{
|
||||
return info.FullName.TrimEnd('/', '\\', ' ');
|
||||
}
|
||||
|
||||
return info.FullName.Trim('/', '\\', ' ');
|
||||
}
|
||||
}
|
||||
}
|
67
NzbDrone.Core/Providers/AutoConfigureProvider.cs
Normal file
67
NzbDrone.Core/Providers/AutoConfigureProvider.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
|
||||
namespace NzbDrone.Core.Providers
|
||||
{
|
||||
public class AutoConfigureProvider
|
||||
{
|
||||
private HttpProvider _httpProvider;
|
||||
private ConfigProvider _configProvider;
|
||||
|
||||
public AutoConfigureProvider(HttpProvider httpProvider, ConfigProvider configProvider)
|
||||
{
|
||||
_httpProvider = httpProvider;
|
||||
_configProvider = configProvider;
|
||||
}
|
||||
|
||||
public SabnzbdInfoModel AutoConfigureSab(string username, string password)
|
||||
{
|
||||
//Get Output from Netstat
|
||||
var netStatOutput = String.Empty;
|
||||
//var port = GetSabnzbdPort(netStatOutput);
|
||||
var port = 2222;
|
||||
var apiKey = GetSabnzbdApiKey(port);
|
||||
|
||||
if (port > 0 && !String.IsNullOrEmpty(apiKey))
|
||||
{
|
||||
return new SabnzbdInfoModel
|
||||
{
|
||||
ApiKey = apiKey,
|
||||
Port = port,
|
||||
Username = username,
|
||||
Password = password
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private int GetSabnzbdPort(string netstatOutput)
|
||||
{
|
||||
Regex regex = new Regex(@"^(?:TCP\W+127.0.0.1:(?<port>\d+\W+).+?\r\n\W+\[sabnzbd.exe\])", RegexOptions.IgnoreCase
|
||||
| RegexOptions.Compiled);
|
||||
var match = regex.Match(netstatOutput);
|
||||
var port = 0;
|
||||
Int32.TryParse(match.Groups["port"].Value, out port);
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
private string GetSabnzbdApiKey(int port, string ipAddress = "127.0.0.1")
|
||||
{
|
||||
var request = String.Format("http://{0}:{1}/config/general/", ipAddress, port);
|
||||
var result = _httpProvider.DownloadString(request);
|
||||
|
||||
Regex regex = new Regex("\\<input\\Wtype\\=\\\"text\\\"\\Wid\\=\\\"apikey\\\"\\Wvalue\\=\\\"(?<apikey>\\w+)\\W", RegexOptions.IgnoreCase
|
||||
| RegexOptions.Compiled);
|
||||
var match = regex.Match(result);
|
||||
|
||||
return match.Groups["apikey"].Value;
|
||||
}
|
||||
}
|
||||
}
|
@ -61,13 +61,13 @@ public IndexerSetting Settings
|
||||
/// </summary>
|
||||
public void Fetch()
|
||||
{
|
||||
_logger.Info("Fetching feeds from " + Settings.Name);
|
||||
_logger.Debug("Fetching feeds from " + Settings.Name);
|
||||
|
||||
foreach (var url in Urls)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Debug("Downloading RSS " + url);
|
||||
_logger.Trace("Downloading RSS " + url);
|
||||
var feed = SyndicationFeed.Load(_httpProvider.DownloadXml(url)).Items;
|
||||
|
||||
foreach (var item in feed)
|
||||
@ -130,7 +130,7 @@ internal void ProcessItem(SyndicationItem feedItem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var sabTitle = _sabProvider.GetSabTitle(parseResult);
|
||||
|
||||
if (_sabProvider.IsInQueue(sabTitle))
|
||||
|
@ -78,7 +78,6 @@ public virtual bool RunScheduled()
|
||||
|
||||
try
|
||||
{
|
||||
Logger.Trace("Getting list of jobs needing to be executed");
|
||||
|
||||
var pendingJobs = All().Where(
|
||||
t => t.Enable &&
|
||||
@ -114,16 +113,14 @@ public bool BeginExecute(Type jobType, int targetId = 0)
|
||||
{
|
||||
if (_isRunning)
|
||||
{
|
||||
Logger.Info("Another instance of this job is already running. Ignoring request.");
|
||||
Logger.Info("Another job is already running. Ignoring request.");
|
||||
return false;
|
||||
}
|
||||
_isRunning = true;
|
||||
}
|
||||
|
||||
Logger.Info("User has requested a manual execution of {0}", jobType.Name);
|
||||
if (_jobThread == null || !_jobThread.IsAlive)
|
||||
{
|
||||
Logger.Debug("Initializing background thread");
|
||||
Logger.Trace("Initializing background thread");
|
||||
|
||||
ThreadStart starter = () =>
|
||||
{
|
||||
@ -170,7 +167,7 @@ private void Execute(Type jobType, int targetId = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Info("Starting job '{0}'. Last execution {1}", settings.Name, settings.LastExecution);
|
||||
Logger.Debug("Starting job '{0}'. Last execution {1}", settings.Name, settings.LastExecution);
|
||||
settings.LastExecution = DateTime.Now;
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
@ -180,7 +177,7 @@ private void Execute(Type jobType, int targetId = 0)
|
||||
|
||||
settings.Success = true;
|
||||
sw.Stop();
|
||||
Logger.Info("Job '{0}' successfully completed in {1} seconds", timerClass.Name, sw.Elapsed.Minutes,
|
||||
Logger.Debug("Job '{0}' successfully completed in {1} seconds", timerClass.Name, sw.Elapsed.Minutes,
|
||||
sw.Elapsed.Seconds);
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -201,7 +198,7 @@ private void Execute(Type jobType, int targetId = 0)
|
||||
/// </summary>
|
||||
public virtual void Initialize()
|
||||
{
|
||||
Logger.Info("Initializing jobs. Count {0}", _jobs.Count());
|
||||
Logger.Debug("Initializing jobs. Count {0}", _jobs.Count());
|
||||
var currentTimer = All();
|
||||
|
||||
foreach (var timer in _jobs)
|
||||
|
@ -24,14 +24,17 @@ public class SettingsController : Controller
|
||||
private readonly IndexerProvider _indexerProvider;
|
||||
private readonly QualityProvider _qualityProvider;
|
||||
private readonly RootDirProvider _rootDirProvider;
|
||||
private readonly AutoConfigureProvider _autoConfigureProvider;
|
||||
|
||||
public SettingsController(ConfigProvider configProvider, IndexerProvider indexerProvider,
|
||||
QualityProvider qualityProvider, RootDirProvider rootDirProvider)
|
||||
QualityProvider qualityProvider, RootDirProvider rootDirProvider,
|
||||
AutoConfigureProvider autoConfigureProvider)
|
||||
{
|
||||
_configProvider = configProvider;
|
||||
_indexerProvider = indexerProvider;
|
||||
_qualityProvider = qualityProvider;
|
||||
_rootDirProvider = rootDirProvider;
|
||||
_autoConfigureProvider = autoConfigureProvider;
|
||||
}
|
||||
|
||||
public ActionResult Index(string viewName)
|
||||
@ -276,6 +279,30 @@ public JsonResult DeleteQualityProfile(int profileId)
|
||||
return new JsonResult { Data = "ok" };
|
||||
}
|
||||
|
||||
public JsonResult AutoConfigureSab(string username, string password)
|
||||
{
|
||||
SabnzbdInfoModel info;
|
||||
|
||||
try
|
||||
{
|
||||
//info = _autoConfigureProvider.AutoConfigureSab(username, password);
|
||||
info = new SabnzbdInfoModel
|
||||
{
|
||||
ApiKey = "123456",
|
||||
Port = 2222
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
catch (Exception)
|
||||
{
|
||||
return new JsonResult { Data = "failed" };
|
||||
}
|
||||
|
||||
return Json(info);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult SaveGeneral(SettingsModel data)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -94,6 +94,8 @@
|
||||
<fieldset class="sub-field">
|
||||
<legend>SABnzbd</legend>
|
||||
|
||||
<button type="button" onclick="autoConfigureSab()">Auto-Configure</button>
|
||||
|
||||
<div class="config-section">
|
||||
<div class="config-group">
|
||||
<div class="config-title">@Html.LabelFor(m => m.SabHost)</div>
|
||||
@ -172,4 +174,26 @@
|
||||
</fieldset>
|
||||
}
|
||||
<div id="result"></div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
var autoConfigureSabUrl = '@Url.Action("AutoConfigureSab", "Settings")';
|
||||
|
||||
function autoConfigureSab() {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: autoConfigureSabUrl,
|
||||
data: jQuery.param({ username: $('#SabUsername').val(), password: $('#SabPassword').val() }),
|
||||
error: function (req, status, error) {
|
||||
alert("Sorry! We could not autoconfigure SABnzbd for you");
|
||||
},
|
||||
success: autoConfigureSuccess
|
||||
});
|
||||
|
||||
function autoConfigureSuccess(data) {
|
||||
$('#SabApiKey').val(data.ApiKey);
|
||||
$('#SabPort').val(data.Port);
|
||||
$('#SabUsername').val(data.Username);
|
||||
$('#SabPassword').val(data.Password);
|
||||
}
|
||||
}
|
||||
</script>
|
@ -44,7 +44,8 @@ internal static Process StartServer()
|
||||
IISProcess.StartInfo.CreateNoWindow = true;
|
||||
|
||||
|
||||
IISProcess.OutputDataReceived += (OnDataReceived);
|
||||
IISProcess.OutputDataReceived += (OnOutputDataReceived);
|
||||
IISProcess.ErrorDataReceived += (OnErrorDataReceived);
|
||||
|
||||
//Set Variables for the config file.
|
||||
Environment.SetEnvironmentVariable("NZBDRONE_PATH", Config.ProjectRoot);
|
||||
@ -60,6 +61,9 @@ internal static Process StartServer()
|
||||
|
||||
|
||||
Logger.Info("Starting process. [{0}]", IISProcess.StartInfo.FileName);
|
||||
|
||||
|
||||
|
||||
IISProcess.Start();
|
||||
|
||||
IISProcess.BeginErrorReadLine();
|
||||
@ -73,6 +77,14 @@ internal static Process StartServer()
|
||||
return IISProcess;
|
||||
}
|
||||
|
||||
private static void OnErrorDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (e == null || String.IsNullOrWhiteSpace(e.Data))
|
||||
return;
|
||||
|
||||
IISLogger.Error(e.Data);
|
||||
}
|
||||
|
||||
internal static void StopServer()
|
||||
{
|
||||
KillProcess(IISProcess);
|
||||
@ -82,7 +94,7 @@ internal static void StopServer()
|
||||
{
|
||||
string processPath = process.MainModule.FileName;
|
||||
Logger.Info("[{0}]IIS Process found. Path:{1}", process.Id, processPath);
|
||||
if (CleanPath(processPath) == CleanPath(IISExe))
|
||||
if (NormalizePath(processPath) == NormalizePath(IISExe))
|
||||
{
|
||||
Logger.Info("[{0}]Process is considered orphaned.", process.Id);
|
||||
KillProcess(process);
|
||||
@ -124,7 +136,7 @@ private static void Server(object sender, ElapsedEventArgs e)
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnDataReceived(object s, DataReceivedEventArgs e)
|
||||
private static void OnOutputDataReceived(object s, DataReceivedEventArgs e)
|
||||
{
|
||||
if (e == null || String.IsNullOrWhiteSpace(e.Data) || e.Data.StartsWith("Request started:") ||
|
||||
e.Data.StartsWith("Request ended:") || e.Data == ("IncrementMessages called"))
|
||||
@ -167,9 +179,19 @@ private static void KillProcess(Process process)
|
||||
}
|
||||
}
|
||||
|
||||
private static string CleanPath(string path)
|
||||
public static string NormalizePath(string path)
|
||||
{
|
||||
return path.ToLower().Replace("\\", "").Replace("//", "//");
|
||||
if (String.IsNullOrWhiteSpace(path))
|
||||
throw new ArgumentException("Path can not be null or empty");
|
||||
|
||||
var info = new FileInfo(path);
|
||||
|
||||
if (info.FullName.StartsWith(@"\\")) //UNC
|
||||
{
|
||||
return info.FullName.TrimEnd('/', '\\', ' ');
|
||||
}
|
||||
|
||||
return info.FullName.Trim('/', '\\', ' ').ToLower();
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
@ -25,7 +26,6 @@
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
|
@ -21,6 +21,7 @@ private static void Main()
|
||||
AppDomain.CurrentDomain.UnhandledException += ((s, e) => AppDomainException(e));
|
||||
AppDomain.CurrentDomain.ProcessExit += ProgramExited;
|
||||
AppDomain.CurrentDomain.DomainUnload += ProgramExited;
|
||||
Process.GetCurrentProcess().EnableRaisingEvents = true;
|
||||
Process.GetCurrentProcess().Exited += ProgramExited;
|
||||
|
||||
Config.ConfigureNlog();
|
||||
|
Loading…
Reference in New Issue
Block a user