Merge branch 'master' of git://github.com/kayone/NzbDrone

Conflicts:
	NzbDrone.Core.Test/ParserTest.cs
This commit is contained in:
Mark McDowall 2011-04-19 20:02:44 -07:00
commit 5107a02f5e
45 changed files with 39670 additions and 7046 deletions

View File

@ -113,7 +113,7 @@ namespace NzbDrone.Core.Test
///////////////////////////////////////// /////////////////////////////////////////
//Constants //Constants
const string fileName = "WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi"; const string fileName = "WEEDS.S03E01.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi";
const int seasonNumber = 3; const int seasonNumber = 3;
const int episodeNumner = 01; const int episodeNumner = 01;

View File

@ -93,6 +93,7 @@
<Compile Include="AutoMoq\Unity\AutoMockingContainerExtension.cs"> <Compile Include="AutoMoq\Unity\AutoMockingContainerExtension.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="TimerProviderTest.cs" />
<Compile Include="SyncProviderTest.cs" /> <Compile Include="SyncProviderTest.cs" />
<Compile Include="RootDirProviderTest.cs" /> <Compile Include="RootDirProviderTest.cs" />
<Compile Include="IndexerProviderTest.cs" /> <Compile Include="IndexerProviderTest.cs" />

View File

@ -1,4 +1,4 @@
using System; using System.Threading;
using MbUnit.Framework; using MbUnit.Framework;
using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Repository.Quality;
@ -15,6 +15,7 @@ namespace NzbDrone.Core.Test
*/ */
[Test] [Test]
[Timeout(1)]
[Row("Sonny.With.a.Chance.S02E15", 2, 15)] [Row("Sonny.With.a.Chance.S02E15", 2, 15)]
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, 1)] [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, 1)]
[Row("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", 1, 3)] [Row("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", 1, 3)]
@ -40,6 +41,7 @@ namespace NzbDrone.Core.Test
} }
[Test] [Test]
[Timeout(1)]
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", QualityTypes.BDRip)] [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", QualityTypes.BDRip)]
[Row("WEEDS.S03E01-06.DUAL.BDRip.AC3.-HELLYWOOD", QualityTypes.BDRip)] [Row("WEEDS.S03E01-06.DUAL.BDRip.AC3.-HELLYWOOD", QualityTypes.BDRip)]
[Row("Two.and.a.Half.Men.S08E05.720p.HDTV.X264-DIMENSION", QualityTypes.HDTV)] [Row("Two.and.a.Half.Men.S08E05.720p.HDTV.X264-DIMENSION", QualityTypes.HDTV)]
@ -66,9 +68,10 @@ namespace NzbDrone.Core.Test
} }
[Test] [Test]
[Timeout(1)]
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, new[] { 1, 2, 3, 4, 5, 6 })] [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, new[] { 1, 2, 3, 4, 5, 6 })]
[Row("Two.and.a.Half.Men.103.104.720p.HDTV.X264-DIMENSION", 1, new[] {3, 4})] [Row("Two.and.a.Half.Men.103.104.720p.HDTV.X264-DIMENSION", 1, new[] { 3, 4 })]
[Row("Weeds.S03E01.S03E02.720p.HDTV.X264-DIMENSION", 3, new[] {1, 2})] [Row("Weeds.S03E01.S03E02.720p.HDTV.X264-DIMENSION", 3, new[] { 1, 2 })]
[Row("The Borgias S01e01 e02 ShoHD On Demand 1080i DD5 1 ALANiS", 1, new[] { 1, 2 })] [Row("The Borgias S01e01 e02 ShoHD On Demand 1080i DD5 1 ALANiS", 1, new[] { 1, 2 })]
[Row("Big Time Rush 1x01 to 10 480i DD2 0 Sianto", 1, new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 })] [Row("Big Time Rush 1x01 to 10 480i DD2 0 Sianto", 1, new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 })]
[Row("White.Collar.2x04.2x05.720p.BluRay-FUTV", 2, new[] { 4, 5 })] [Row("White.Collar.2x04.2x05.720p.BluRay-FUTV", 2, new[] { 4, 5 })]

View File

@ -0,0 +1,110 @@
using System;
using System.Linq;
using System.Collections.Generic;
using AutoMoq;
using MbUnit.Framework;
using Moq;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Providers.Timers;
namespace NzbDrone.Core.Test
{
[TestFixture]
// ReSharper disable InconsistentNaming
public class TimerProviderTest
{
[Test]
public void Run_Timers()
{
IEnumerable<ITimer> fakeTimers = new List<ITimer> { new FakeTimer() };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
mocker.SetConstant(fakeTimers);
var timerProvider = mocker.Resolve<TimerProvider>();
timerProvider.Initialize();
timerProvider.Run();
}
[Test]
public void Init_Timers()
{
var fakeTimer = new FakeTimer();
IEnumerable<ITimer> fakeTimers = new List<ITimer> { fakeTimer };
var mocker = new AutoMoqer();
mocker.SetConstant(MockLib.GetEmptyRepository());
mocker.SetConstant(fakeTimers);
var timerProvider = mocker.Resolve<TimerProvider>();
timerProvider.Initialize();
var timers = timerProvider.All();
//Assert
Assert.Count(1, timers);
Assert.AreEqual(fakeTimer.DefaultInterval, timers[0].Interval);
Assert.AreEqual(fakeTimer.Name, timers[0].Name);
Assert.AreEqual(fakeTimer.GetType().ToString(), timers[0].TypeName);
Assert.AreEqual(DateTime.MinValue, timers[0].LastExecution);
Assert.IsTrue(timers[0].Enable);
}
[Test]
public void Init_Timers_only_registers_once()
{
var repo = MockLib.GetEmptyRepository();
for (int i = 0; i < 2; i++)
{
var fakeTimer = new FakeTimer();
IEnumerable<ITimer> fakeTimers = new List<ITimer> { fakeTimer };
var mocker = new AutoMoqer();
mocker.SetConstant(repo);
mocker.SetConstant(fakeTimers);
var timerProvider = mocker.Resolve<TimerProvider>();
timerProvider.Initialize();
}
var mocker2 = new AutoMoqer();
mocker2.SetConstant(repo);
var assertTimerProvider = mocker2.Resolve<TimerProvider>();
var timers = assertTimerProvider.All();
//Assert
Assert.Count(1, timers);
}
}
public class FakeTimer : ITimer
{
public string Name
{
get { return "FakeTimer"; }
}
public int DefaultInterval
{
get { return 15; }
}
public void Start()
{
}
}
}

View File

@ -10,6 +10,7 @@ using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Providers.Indexer; using NzbDrone.Core.Providers.Indexer;
using NzbDrone.Core.Providers.Timers;
using NzbDrone.Core.Repository; using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Repository.Quality;
using SubSonic.DataProviders; using SubSonic.DataProviders;
@ -22,7 +23,6 @@ namespace NzbDrone.Core
private static StandardKernel _kernel; private static StandardKernel _kernel;
private static readonly Object KernelLock = new object(); private static readonly Object KernelLock = new object();
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static string _startupPath;
public static String AppPath public static String AppPath
{ {
@ -36,21 +36,6 @@ namespace NzbDrone.Core
} }
} }
public static string ExecutablePath
{
get
{
//var uri = new Uri(Assembly.EscapedCodeBase);
//return Path.GetDirectoryName(uri.LocalPath);
return Directory.GetCurrentDirectory();
}
}
public static string StartupPath
{
get { return _startupPath; }
}
public static StandardKernel NinjectKernel public static StandardKernel NinjectKernel
{ {
get get
@ -70,19 +55,16 @@ namespace NzbDrone.Core
Logger.Debug("Binding Ninject's Kernel"); Logger.Debug("Binding Ninject's Kernel");
_kernel = new StandardKernel(); _kernel = new StandardKernel();
//Store the startup path
_startupPath = AppPath;
//Sqlite //Sqlite
var AppDataPath = new DirectoryInfo(Path.Combine(AppPath, "App_Data")); var appDataPath = new DirectoryInfo(Path.Combine(AppPath, "App_Data"));
if (!AppDataPath.Exists) AppDataPath.Create(); if (!appDataPath.Exists) appDataPath.Create();
string connectionString = String.Format("Data Source={0};Version=3;", string connectionString = String.Format("Data Source={0};Version=3;",
Path.Combine(AppDataPath.FullName, "nzbdrone.db")); Path.Combine(appDataPath.FullName, "nzbdrone.db"));
var dbProvider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite"); var dbProvider = ProviderFactory.GetProvider(connectionString, "System.Data.SQLite");
string logConnectionString = String.Format("Data Source={0};Version=3;", string logConnectionString = String.Format("Data Source={0};Version=3;",
Path.Combine(AppDataPath.FullName, "log.db")); Path.Combine(appDataPath.FullName, "log.db"));
var logDbProvider = ProviderFactory.GetProvider(logConnectionString, "System.Data.SQLite"); var logDbProvider = ProviderFactory.GetProvider(logConnectionString, "System.Data.SQLite");
@ -99,7 +81,6 @@ namespace NzbDrone.Core
_kernel.Bind<HttpProvider>().ToSelf().InSingletonScope(); _kernel.Bind<HttpProvider>().ToSelf().InSingletonScope();
_kernel.Bind<SeriesProvider>().ToSelf().InSingletonScope(); _kernel.Bind<SeriesProvider>().ToSelf().InSingletonScope();
_kernel.Bind<SeasonProvider>().ToSelf().InSingletonScope(); _kernel.Bind<SeasonProvider>().ToSelf().InSingletonScope();
_kernel.Bind<RssSyncProvider>().ToSelf().InSingletonScope();
_kernel.Bind<EpisodeProvider>().ToSelf().InSingletonScope(); _kernel.Bind<EpisodeProvider>().ToSelf().InSingletonScope();
_kernel.Bind<UpcomingEpisodesProvider>().ToSelf().InSingletonScope(); _kernel.Bind<UpcomingEpisodesProvider>().ToSelf().InSingletonScope();
_kernel.Bind<DiskProvider>().ToSelf().InSingletonScope(); _kernel.Bind<DiskProvider>().ToSelf().InSingletonScope();
@ -127,12 +108,6 @@ namespace NzbDrone.Core
ForceMigration(_kernel.Get<IRepository>()); ForceMigration(_kernel.Get<IRepository>());
SetupDefaultQualityProfiles(_kernel.Get<IRepository>()); //Setup the default QualityProfiles on start-up SetupDefaultQualityProfiles(_kernel.Get<IRepository>()); //Setup the default QualityProfiles on start-up
//Get the Timers going
var config = _kernel.Get<ConfigProvider>();
var timer = _kernel.Get<TimerProvider>();
timer.SetRssSyncTimer(Convert.ToInt32(config.GetValue("SyncFrequency", "15", true)));
timer.StartRssSyncTimer();
BindIndexers(); BindIndexers();
} }
} }
@ -157,7 +132,7 @@ namespace NzbDrone.Core
} }
/// <summary> /// <summary>
/// This method forces IISExpress process to exit with the host application /// Forces IISExpress process to exit with the host application
/// </summary> /// </summary>
public static void DedicateToHost() public static void DedicateToHost()
{ {
@ -190,7 +165,6 @@ namespace NzbDrone.Core
Process.GetCurrentProcess().Kill(); Process.GetCurrentProcess().Kill();
} }
private static void SetupDefaultQualityProfiles(IRepository repository) private static void SetupDefaultQualityProfiles(IRepository repository)
{ {
var sd = new QualityProfile var sd = new QualityProfile

View File

@ -1,14 +0,0 @@
using System;
namespace NzbDrone.Core.Helpers
{
public static class ServerHelper
{
public static string GetServerHostname()
{
//Both these seem to return the same result... Is on better than the other?
return Environment.MachineName;
//return Dns.GetHostName();
}
}
}

View File

@ -163,15 +163,18 @@
<Compile Include="Helpers\EpisodeRenameHelper.cs" /> <Compile Include="Helpers\EpisodeRenameHelper.cs" />
<Compile Include="Helpers\EpisodeSortingHelper.cs" /> <Compile Include="Helpers\EpisodeSortingHelper.cs" />
<Compile Include="Helpers\SceneNameHelper.cs" /> <Compile Include="Helpers\SceneNameHelper.cs" />
<Compile Include="Helpers\ServerHelper.cs" />
<Compile Include="Instrumentation\LogLevel.cs" /> <Compile Include="Instrumentation\LogLevel.cs" />
<Compile Include="Instrumentation\LogProvider.cs" /> <Compile Include="Instrumentation\LogProvider.cs" />
<Compile Include="Instrumentation\SubsonicTarget.cs" /> <Compile Include="Instrumentation\SubsonicTarget.cs" />
<Compile Include="Instrumentation\ExceptioneerTarget.cs" /> <Compile Include="Instrumentation\ExceptioneerTarget.cs" />
<Compile Include="Instrumentation\NlogWriter.cs" /> <Compile Include="Instrumentation\NlogWriter.cs" />
<Compile Include="Providers\Indexer\NzbMatrixProvider.cs" /> <Compile Include="Providers\Indexer\NzbMatrixProvider.cs" />
<Compile Include="Providers\Timers\TimerProvider.cs" />
<Compile Include="Providers\Indexer\NewzbinProvider.cs" /> <Compile Include="Providers\Indexer\NewzbinProvider.cs" />
<Compile Include="Providers\Indexer\NzbsRUsProvider.cs" /> <Compile Include="Providers\Indexer\NzbsRUsProvider.cs" />
<Compile Include="Providers\Timers\ITimer.cs" />
<Compile Include="Providers\Timers\RssSyncTimer.cs" />
<Compile Include="Repository\TimerSetting.cs" />
<Compile Include="Repository\IndexerSetting.cs" /> <Compile Include="Repository\IndexerSetting.cs" />
<Compile Include="Model\EpisodeParseResult.cs" /> <Compile Include="Model\EpisodeParseResult.cs" />
<Compile Include="Model\EpisodeRenameModel.cs" /> <Compile Include="Model\EpisodeRenameModel.cs" />
@ -188,12 +191,10 @@
<Compile Include="Providers\HistoryProvider.cs" /> <Compile Include="Providers\HistoryProvider.cs" />
<Compile Include="Providers\BacklogProvider.cs" /> <Compile Include="Providers\BacklogProvider.cs" />
<Compile Include="Providers\IndexerProvider.cs" /> <Compile Include="Providers\IndexerProvider.cs" />
<Compile Include="Providers\RssSyncProvider.cs" />
<Compile Include="Providers\PostProcessingProvider.cs" /> <Compile Include="Providers\PostProcessingProvider.cs" />
<Compile Include="Providers\QualityProvider.cs" /> <Compile Include="Providers\QualityProvider.cs" />
<Compile Include="Providers\RenameProvider.cs" /> <Compile Include="Providers\RenameProvider.cs" />
<Compile Include="Providers\RootDirProvider.cs" /> <Compile Include="Providers\RootDirProvider.cs" />
<Compile Include="Providers\TimerProvider.cs" />
<Compile Include="Providers\UpcomingEpisodesProvider.cs" /> <Compile Include="Providers\UpcomingEpisodesProvider.cs" />
<Compile Include="Providers\XbmcProvider.cs" /> <Compile Include="Providers\XbmcProvider.cs" />
<Compile Include="Repository\EpisodeFile.cs" /> <Compile Include="Repository\EpisodeFile.cs" />

View File

@ -144,7 +144,7 @@ namespace NzbDrone.Core
if (match.Count != 0) if (match.Count != 0)
{ {
var seriesName = NormalizeTitle(match[0].Groups["title"].Value); var seriesName = NormalizeTitle(match[0].Groups["title"].Value);
var year = 0; int year;
Int32.TryParse(match[0].Groups["year"].Value, out year); Int32.TryParse(match[0].Groups["year"].Value, out year);
if (year < 1900 || year > DateTime.Now.Year + 1) if (year < 1900 || year > DateTime.Now.Year + 1)
@ -158,12 +158,11 @@ namespace NzbDrone.Core
{ {
SeriesTitle = seriesName, SeriesTitle = seriesName,
SeasonNumber = seasonNumber, SeasonNumber = seasonNumber,
Year = year Year = year,
Quality = ParseQuality(title)
}; };
result.Quality = ParseQuality(title);
Logger.Trace("Season Parsed. {0}", result); Logger.Trace("Season Parsed. {0}", result);
return result; return result;
} }
@ -188,14 +187,7 @@ namespace NzbDrone.Core
if (match.Count != 0) if (match.Count != 0)
{ {
var seriesName = NormalizeTitle(match[0].Groups["title"].Value); var seriesName = NormalizeTitle(match[0].Groups["title"].Value);
var year = 0;
Int32.TryParse(match[0].Groups["year"].Value, out year);
if (year < 1900 || year > DateTime.Now.Year + 1)
{
year = 0;
}
Logger.Trace("Series Parsed. {0}", seriesName); Logger.Trace("Series Parsed. {0}", seriesName);
return seriesName; return seriesName;
} }
@ -289,11 +281,10 @@ namespace NzbDrone.Core
return NormalizeRegex.Replace(title, String.Empty).ToLower(); return NormalizeRegex.Replace(title, String.Empty).ToLower();
} }
//Note: changing case on path is a problem for running on mono/*nix
//Not going to change the casing any more... Looks Ugly in UI anyways :P
public static string NormalizePath(string path) public static string NormalizePath(string path)
{ {
if (String.IsNullOrEmpty(path)) if (String.IsNullOrWhiteSpace(path))
throw new ArgumentException("Path can not be null or empty"); throw new ArgumentException("Path can not be null or empty");
var info = new FileInfo(path); var info = new FileInfo(path);

View File

@ -107,22 +107,28 @@ namespace NzbDrone.Core.Providers.Indexer
if (!_seriesProvider.IsMonitored(parseResult.SeriesId)) if (!_seriesProvider.IsMonitored(parseResult.SeriesId))
{ {
Logger.Debug("{0} is present in the DB but not tracked. skipping.", parseResult.SeriesTitle); Logger.Debug("{0} is present in the DB but not tracked. skipping.", parseResult.SeriesTitle);
return;
} }
if (!_seriesProvider.QualityWanted(parseResult.SeriesId, parseResult.Quality)) if (!_seriesProvider.QualityWanted(parseResult.SeriesId, parseResult.Quality))
{ {
Logger.Debug("Post doesn't meet the quality requirements [{0}]. skipping.", parseResult.Quality); Logger.Debug("Post doesn't meet the quality requirements [{0}]. skipping.", parseResult.Quality);
return;
} }
if (_seasonProvider.IsIgnored(parseResult.SeriesId, parseResult.SeasonNumber)) if (_seasonProvider.IsIgnored(parseResult.SeriesId, parseResult.SeasonNumber))
{ {
Logger.Debug("Season {0} is currently set to ignore. skipping.", parseResult.SeasonNumber); Logger.Debug("Season {0} is currently set to ignore. skipping.", parseResult.SeasonNumber);
return;
} }
if (!_episodeProvider.IsNeeded(parseResult)) if (!_episodeProvider.IsNeeded(parseResult))
{ {
Logger.Debug("Episode {0} is not needed. skipping.", parseResult); Logger.Debug("Episode {0} is not needed. skipping.", parseResult);
return;
} }
//Should probably queue item to download
} }
} }

View File

@ -48,7 +48,7 @@ namespace NzbDrone.Core.Providers
return _repository.Single<IndexerSetting>(s => s.IndexProviderType == type.ToString()); return _repository.Single<IndexerSetting>(s => s.IndexProviderType == type.ToString());
} }
public IndexerSetting GetSettings(int id) public virtual IndexerSetting GetSettings(int id)
{ {
return _repository.Single<IndexerSetting>(s => s.Id == id); return _repository.Single<IndexerSetting>(s => s.Id == id);
} }

View File

@ -1,9 +0,0 @@
namespace NzbDrone.Core.Providers
{
public class RssSyncProvider
{
public virtual void Begin()
{
}
}
}

View File

@ -51,7 +51,7 @@ namespace NzbDrone.Core.Providers
XDocument xDoc = XDocument.Parse(response); XDocument xDoc = XDocument.Parse(response);
//If an Error Occurred, retuyrn) //If an Error Occurred, return)
if (xDoc.Descendants("error").Count() != 0) if (xDoc.Descendants("error").Count() != 0)
return false; return false;

View File

@ -1,130 +0,0 @@
using System;
using System.Timers;
using NLog;
namespace NzbDrone.Core.Providers
{
public class TimerProvider
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly EpisodeProvider _episodeProvider;
private readonly MediaFileProvider _mediaFileProvider;
private readonly Timer _minuteTimer;
private readonly RssSyncProvider _rssSyncProvider;
private readonly Timer _rssSyncTimer;
private readonly SeasonProvider _seasonProvider;
private readonly SeriesProvider _seriesProvider;
private DateTime _rssSyncNextInterval;
public TimerProvider(RssSyncProvider rssSyncProvider, SeriesProvider seriesProvider,
SeasonProvider seasonProvider, EpisodeProvider episodeProvider,
MediaFileProvider mediaFileProvider)
{
_rssSyncProvider = rssSyncProvider;
_seriesProvider = seriesProvider;
_seasonProvider = seasonProvider;
_episodeProvider = episodeProvider;
_mediaFileProvider = mediaFileProvider;
_rssSyncTimer = new Timer();
_minuteTimer = new Timer(60000);
}
public virtual void ResetRssSyncTimer()
{
double interval = _rssSyncTimer.Interval;
_rssSyncTimer.Interval = interval;
}
public virtual void StartRssSyncTimer()
{
if (_rssSyncTimer.Interval < 900000)
//If Timer is less than 15 minutes, throw an error! This should also be handled when saving the config, though a user could by-pass it by editing the DB directly... TNO (Trust No One)
{
Logger.Error("RSS Sync Frequency is invalid, please set the interval first");
throw new InvalidOperationException("RSS Sync Frequency Invalid");
}
_rssSyncTimer.Elapsed += RunRssSync;
_rssSyncTimer.Start();
_rssSyncNextInterval = DateTime.Now.AddMilliseconds(_rssSyncTimer.Interval);
}
public virtual void StopRssSyncTimer()
{
_rssSyncTimer.Stop();
}
public virtual void SetRssSyncTimer(int minutes)
{
long ms = minutes*60*1000;
_rssSyncTimer.Interval = ms;
}
public virtual TimeSpan RssSyncTimeLeft()
{
return _rssSyncNextInterval.Subtract(DateTime.Now);
}
public virtual DateTime NextRssSyncTime()
{
return _rssSyncNextInterval;
}
public virtual void StartMinuteTimer()
{
_minuteTimer.Elapsed += MinuteTimer_Elapsed;
_minuteTimer.Start();
}
public virtual void StopMinuteTimer()
{
_minuteTimer.Stop();
}
private void RunRssSync(object obj, ElapsedEventArgs args)
{
_rssSyncNextInterval = DateTime.Now.AddMilliseconds(_rssSyncTimer.Interval);
_rssSyncProvider.Begin();
}
private void MinuteTimer_Elapsed(object obj, ElapsedEventArgs args)
{
//Check to see if anything should be run at this time, if so run it
var now = DateTime.Now;
//Daily (Except Sunday) 03:00 - Update the lastest season for all TV Shows
if (now.Hour == 3 && now.Minute == 0 && now.DayOfWeek != DayOfWeek.Sunday)
{
foreach (var series in _seriesProvider.GetAllSeries())
{
var season = _seasonProvider.GetLatestSeason(series.SeriesId);
_episodeProvider.RefreshEpisodeInfo(season);
}
}
//Sunday 03:00 - Update all TV Shows
if (now.Hour == 3 && now.Minute == 0 && now.DayOfWeek == DayOfWeek.Sunday)
{
foreach (var series in _seriesProvider.GetAllSeries())
{
_episodeProvider.RefreshEpisodeInfo(series.SeriesId);
}
}
//Daily 00:00 (Midnight) - Cleanup (removed) EpisodeFiles + Scan for New EpisodeFiles
if (now.Hour == 0 && now.Minute == 0)
{
foreach (var series in _seriesProvider.GetAllSeries())
{
_mediaFileProvider.CleanUp(series.EpisodeFiles);
_mediaFileProvider.Scan(series);
}
}
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,11 @@
namespace NzbDrone.Core.Providers.Timers
{
public interface ITimer
{
string Name { get; }
int DefaultInterval { get; }
void Start();
}
}

View File

@ -0,0 +1,39 @@
using System.Linq;
using NLog;
namespace NzbDrone.Core.Providers.Timers
{
public class RssSyncTimer : ITimer
{
private readonly IndexerProvider _indexerProvider;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public RssSyncTimer(IndexerProvider indexerProvider)
{
_indexerProvider = indexerProvider;
}
public string Name
{
get { return "RSS Sync"; }
}
public int DefaultInterval
{
get { return 15; }
}
public void Start()
{
Logger.Info("Doing Things!!!!");
var indexers = _indexerProvider.AllIndexers().Where(c => c.Enable);
foreach (var indexerSetting in indexers)
{
}
}
}
}

View File

@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using NLog;
using NzbDrone.Core.Repository;
using SubSonic.Repository;
namespace NzbDrone.Core.Providers.Timers
{
public class TimerProvider
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly IRepository _repository;
private readonly IEnumerable<ITimer> _timerJobs;
private static readonly object ExecutionLock = new object();
private static bool _isRunning;
public TimerProvider(IRepository repository, IEnumerable<ITimer> timerJobs)
{
_repository = repository;
_timerJobs = timerJobs;
}
public TimerProvider() { }
public virtual List<TimerSetting> All()
{
return _repository.All<TimerSetting>().ToList();
}
public virtual void SaveSettings(TimerSetting settings)
{
if (settings.Id == 0)
{
Logger.Debug("Adding timer settings for {0}", settings.Name);
_repository.Add(settings);
}
else
{
Logger.Debug("Updating timer settings for {0}", settings.Name);
_repository.Update(settings);
}
}
public virtual void Run()
{
lock (ExecutionLock)
{
if (_isRunning)
{
Logger.Info("Another instance of timer is already running. Ignoring request.");
return;
}
_isRunning = true;
}
Logger.Trace("Getting list of timers needing to be executed");
var pendingTimers = All().Where(
t => t.Enable &&
(DateTime.Now - t.LastExecution) > TimeSpan.FromMinutes(t.Interval)
);
foreach (var pendingTimer in pendingTimers)
{
Logger.Info("Attempting to start timer [{0}]. Last executing {1}", pendingTimer.Name, pendingTimer.LastExecution);
var timerClass = _timerJobs.Where(t => t.GetType().ToString() == pendingTimer.TypeName).FirstOrDefault();
ForceExecute(timerClass.GetType());
}
}
public void ForceExecute(Type timerType)
{
var timerClass = _timerJobs.Where(t => t.GetType() == timerType).FirstOrDefault();
if (timerClass == null)
{
Logger.Error("Unable to locate implantation for [{0}]. Make sure its properly registered.", timerType.ToString());
return;
}
try
{
var sw = Stopwatch.StartNew();
timerClass.Start();
sw.Stop();
Logger.Info("timer [{0}] finished executing successfully. Duration {1}", timerClass.Name, sw.Elapsed.ToString());
}
catch (Exception e)
{
Logger.Error("An error has occurred while executing timer job " + timerClass.Name, e);
}
}
public virtual void Initialize()
{
Logger.Info("Initializing timer jobs. Count {0}", _timerJobs.Count());
var currentTimer = All();
foreach (var timer in _timerJobs)
{
var timerProviderLocal = timer;
if (!currentTimer.Exists(c => c.TypeName == timerProviderLocal.GetType().ToString()))
{
var settings = new TimerSetting()
{
Enable = true,
TypeName = timer.GetType().ToString(),
Name = timerProviderLocal.Name,
Interval = timerProviderLocal.DefaultInterval,
LastExecution = DateTime.MinValue
};
SaveSettings(settings);
}
}
}
}
}

View File

@ -23,13 +23,13 @@ namespace NzbDrone.Core.Providers
public virtual void Notify(string header, string message) public virtual void Notify(string header, string message)
{ {
//Get time in seconds and convert to ms //Get time in seconds and convert to ms
var time = Convert.ToInt32(_configProvider.GetValue("XbmcDisplayTime", "3", true))*1000; var time = Convert.ToInt32(_configProvider.GetValue("XbmcDisplayTime", "3", true)) * 1000;
var command = String.Format("ExecBuiltIn(Notification({0},{1},{2}))", header, message, time); var command = String.Format("ExecBuiltIn(Notification({0},{1},{2}))", header, message, time);
if (Convert.ToBoolean(_configProvider.GetValue("XbmcNotificationImage", false, true))) if (Convert.ToBoolean(_configProvider.GetValue("XbmcNotificationImage", false, true)))
{ {
//Todo: Get the actual port that NzbDrone is running on... //Todo: Get the actual port that NzbDrone is running on...
var serverInfo = String.Format("http://{0}:{1}", ServerHelper.GetServerHostname(), "8989"); var serverInfo = String.Format("http://{0}:{1}", Environment.MachineName, "8989");
var imageUrl = String.Format("{0}/Content/XbmcNotification.png", serverInfo); var imageUrl = String.Format("{0}/Content/XbmcNotification.png", serverInfo);
command = String.Format("ExecBuiltIn(Notification({0},{1},{2}, {3}))", header, message, time, imageUrl); command = String.Format("ExecBuiltIn(Notification({0},{1},{2}, {3}))", header, message, time, imageUrl);

View File

@ -41,7 +41,7 @@ namespace NzbDrone.Core.Repository.Quality
foreach (var q in Allowed) foreach (var q in Allowed)
{ {
result += (int) q + "|"; result += (int)q + "|";
} }
return result.Trim('|'); return result.Trim('|');
} }
@ -51,12 +51,12 @@ namespace NzbDrone.Core.Repository.Quality
Allowed = new List<QualityTypes>(qualities.Length); Allowed = new List<QualityTypes>(qualities.Length);
foreach (var quality in qualities) foreach (var quality in qualities)
{ {
Allowed.Add((QualityTypes) Convert.ToInt32(quality)); Allowed.Add((QualityTypes)Convert.ToInt32(quality));
} }
} }
} }
[SubSonicToManyRelation] [SubSonicToManyRelation]
public virtual List<string> Series { get; private set; } public virtual List<Series> Series { get; private set; }
} }
} }

View File

@ -18,9 +18,9 @@ namespace NzbDrone.Core.Repository
public DayOfWeek? LastDiskSync { get; set; } public DayOfWeek? LastDiskSync { get; set; }
[SubSonicToManyRelation] [SubSonicToManyRelation]
public virtual List<Episode> Episodes { get; private set; } public virtual List<Episode> Episodes { get; protected set; }
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)] [SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
public virtual Series Series { get; private set; } public virtual Series Series { get; protected set; }
} }
} }

View File

@ -45,15 +45,15 @@ namespace NzbDrone.Core.Repository
public DateTime? LastDiskSync { get; set; } public DateTime? LastDiskSync { get; set; }
[SubSonicToOneRelation(ThisClassContainsJoinKey = true, JoinKeyName = "QualityProfileId")] [SubSonicToOneRelation(ThisClassContainsJoinKey = true, JoinKeyName = "QualityProfileId")]
public virtual QualityProfile QualityProfile { get; private set; } public virtual QualityProfile QualityProfile { get; protected set; }
[SubSonicToManyRelation] [SubSonicToManyRelation]
public virtual List<Season> Seasons { get; private set; } public virtual List<Season> Seasons { get; protected set; }
[SubSonicToManyRelation] [SubSonicToManyRelation]
public virtual List<Episode> Episodes { get; private set; } public virtual List<Episode> Episodes { get; protected set; }
[SubSonicToManyRelation] [SubSonicToManyRelation]
public virtual List<EpisodeFile> EpisodeFiles { get; private set; } public virtual List<EpisodeFile> EpisodeFiles { get; protected set; }
} }
} }

View File

@ -0,0 +1,23 @@
using System;
using SubSonic.SqlGeneration.Schema;
namespace NzbDrone.Core.Repository
{
public class TimerSetting
{
[SubSonicPrimaryKey(true)]
public Int32 Id { get; set; }
public Boolean Enable { get; set; }
public String TypeName { get; set; }
public String Name { get; set; }
public Int32 Interval { get; set; }
public DateTime LastExecution { get; set; }
public Boolean Success { get; set; }
}
}

View File

@ -1,134 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Web.Models;
namespace NzbDrone.Web.Controllers
{
public class AddSeriesController : Controller
{
public IConfigProvider ConfigProvider { get; set; }
private readonly SyncProvider _syncProvider;
private readonly RootDirProvider _rootFolderProvider;
private readonly IConfigProvider _configProvider;
private readonly QualityProvider _qualityProvider;
private readonly TvDbProvider _tvDbProvider;
private readonly SeriesProvider _seriesProvider;
public AddSeriesController(SyncProvider syncProvider, RootDirProvider rootFolderProvider, IConfigProvider configProvider,
QualityProvider qualityProvider, TvDbProvider tvDbProvider, SeriesProvider seriesProvider)
{
ConfigProvider = configProvider;
_syncProvider = syncProvider;
_rootFolderProvider = rootFolderProvider;
_configProvider = configProvider;
_qualityProvider = qualityProvider;
_tvDbProvider = tvDbProvider;
_seriesProvider = seriesProvider;
}
[HttpPost]
public JsonResult ScanNewSeries()
{
_syncProvider.BeginUpdateNewSeries();
return new JsonResult();
}
public ActionResult AddNew()
{
ViewData["RootDirs"] = _rootFolderProvider.GetAll();
ViewData["DirSep"] = Path.DirectorySeparatorChar;
var profiles = _qualityProvider.GetAllProfiles();
var selectList = new SelectList(profiles, "QualityProfileId", "Name");
var defaultQuality = Convert.ToInt32(_configProvider.DefaultQualityProfile);
var model = new AddNewSeriesModel
{
DirectorySeparatorChar = Path.DirectorySeparatorChar.ToString(),
RootDirectories = _rootFolderProvider.GetAll(),
QualityProfileId = defaultQuality,
QualitySelectList = selectList
};
return View(model);
}
public ActionResult AddExisting()
{
var unmappedList = new List<String>();
var profiles = _qualityProvider.GetAllProfiles();
var defaultQuality = Convert.ToInt32(_configProvider.DefaultQualityProfile);
var selectList = new SelectList(profiles, "QualityProfileId", "Name", defaultQuality);
ViewData["qualities"] = selectList;
foreach (var folder in _rootFolderProvider.GetAll())
{
unmappedList.AddRange(_syncProvider.GetUnmappedFolders(folder.Path));
}
return View(unmappedList);
}
public ActionResult RenderPartial(string path)
{
var suggestions = GetSuggestionList(new DirectoryInfo(path).Name);
ViewData["guid"] = Guid.NewGuid();
ViewData["path"] = path;
ViewData["javaPath"] = path.Replace(Path.DirectorySeparatorChar, '|').Replace(Path.VolumeSeparatorChar, '^');
var defaultQuality = _configProvider.DefaultQualityProfile;
var qualityProfiles = _qualityProvider.GetAllProfiles();
ViewData["quality"] = new SelectList(
qualityProfiles,
"QualityProfileId",
"Name",
defaultQuality); ;
return PartialView("AddSeriesItem", suggestions);
}
public JsonResult AddSeries(string path, int seriesId, int qualityProfileId)
{
//Get TVDB Series Name
//Create new folder for series
//Add the new series to the Database
_seriesProvider.AddSeries(path.Replace('|', Path.DirectorySeparatorChar).Replace('^', Path.VolumeSeparatorChar), seriesId, qualityProfileId);
ScanNewSeries();
return new JsonResult() { Data = "ok" };
}
[HttpPost]
public ActionResult _textLookUp(string text, int? filterMode)
{
var suggestions = GetSuggestionList(text);
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = suggestions
};
}
public SelectList GetSuggestionList(string searchString)
{
var dataVal = _tvDbProvider.SearchSeries(searchString);
//var bestResult = _tvDbProvider.GetBestMatch(dataVal.ToList(), searchString);
return new SelectList(dataVal, "Id", "SeriesName", dataVal[0].Id);
}
}
}

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Web.Mvc; using System.Web.Mvc;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Timers;
using NzbDrone.Core.Repository; using NzbDrone.Core.Repository;
using NzbDrone.Web.Models; using NzbDrone.Web.Models;
using Telerik.Web.Mvc; using Telerik.Web.Mvc;
@ -19,28 +20,28 @@ namespace NzbDrone.Web.Controllers
private readonly QualityProvider _qualityProvider; private readonly QualityProvider _qualityProvider;
private readonly RenameProvider _renameProvider; private readonly RenameProvider _renameProvider;
private readonly RootDirProvider _rootDirProvider; private readonly RootDirProvider _rootDirProvider;
private readonly RssSyncProvider _rssSyncProvider;
private readonly SeriesProvider _seriesProvider; private readonly SeriesProvider _seriesProvider;
private readonly SyncProvider _syncProvider; private readonly SyncProvider _syncProvider;
private readonly TvDbProvider _tvDbProvider; private readonly TvDbProvider _tvDbProvider;
private readonly TimerProvider _timerProvider;
// //
// GET: /Series/ // GET: /Series/
public SeriesController(SyncProvider syncProvider, SeriesProvider seriesProvider, public SeriesController(SyncProvider syncProvider, SeriesProvider seriesProvider,
EpisodeProvider episodeProvider, RssSyncProvider rssSyncProvider, EpisodeProvider episodeProvider,
QualityProvider qualityProvider, MediaFileProvider mediaFileProvider, QualityProvider qualityProvider, MediaFileProvider mediaFileProvider,
RenameProvider renameProvider, RootDirProvider rootDirProvider, RenameProvider renameProvider, RootDirProvider rootDirProvider,
TvDbProvider tvDbProvider) TvDbProvider tvDbProvider, TimerProvider timerProvider)
{ {
_seriesProvider = seriesProvider; _seriesProvider = seriesProvider;
_episodeProvider = episodeProvider; _episodeProvider = episodeProvider;
_syncProvider = syncProvider; _syncProvider = syncProvider;
_rssSyncProvider = rssSyncProvider;
_qualityProvider = qualityProvider; _qualityProvider = qualityProvider;
_mediaFileProvider = mediaFileProvider; _mediaFileProvider = mediaFileProvider;
_renameProvider = renameProvider; _renameProvider = renameProvider;
_rootDirProvider = rootDirProvider; _rootDirProvider = rootDirProvider;
_tvDbProvider = tvDbProvider; _tvDbProvider = tvDbProvider;
_timerProvider = timerProvider;
} }
public ActionResult Index() public ActionResult Index()
@ -52,13 +53,13 @@ namespace NzbDrone.Web.Controllers
public ActionResult RssSync() public ActionResult RssSync()
{ {
_rssSyncProvider.Begin(); _timerProvider.ForceExecute(typeof(RssSyncTimer));
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
public ActionResult UnMapped(string path) public ActionResult UnMapped(string path)
{ {
return View(_syncProvider.GetUnmappedFolders(path).Select(c => new MappingModel {Id = 1, Path = c}).ToList()); return View(_syncProvider.GetUnmappedFolders(path).Select(c => new MappingModel { Id = 1, Path = c }).ToList());
} }
public ActionResult LoadEpisodes(int seriesId) public ActionResult LoadEpisodes(int seriesId)
@ -121,7 +122,7 @@ namespace NzbDrone.Web.Controllers
//We still want to show this series as unmapped, but we don't know what it will be when mapped //We still want to show this series as unmapped, but we don't know what it will be when mapped
//Todo: Provide the user with a way to manually map a folder to a TvDb series (or make them rename the folder...) //Todo: Provide the user with a way to manually map a folder to a TvDb series (or make them rename the folder...)
if (tvDbSeries == null) if (tvDbSeries == null)
tvDbSeries = new TvdbSeries {Id = 0, SeriesName = String.Empty}; tvDbSeries = new TvdbSeries { Id = 0, SeriesName = String.Empty };
unmappedList.Add(new AddExistingSeriesModel unmappedList.Add(new AddExistingSeriesModel
{ {
@ -263,7 +264,7 @@ namespace NzbDrone.Web.Controllers
var series = _seriesProvider.GetSeries(seriesId); var series = _seriesProvider.GetSeries(seriesId);
_mediaFileProvider.Scan(series); _mediaFileProvider.Scan(series);
return RedirectToAction("Details", new {seriesId}); return RedirectToAction("Details", new { seriesId });
} }
public ActionResult RenameAll() public ActionResult RenameAll()
@ -275,7 +276,7 @@ namespace NzbDrone.Web.Controllers
public ActionResult RenameSeries(int seriesId) public ActionResult RenameSeries(int seriesId)
{ {
_renameProvider.RenameSeries(seriesId); _renameProvider.RenameSeries(seriesId);
return RedirectToAction("Details", new {seriesId}); return RedirectToAction("Details", new { seriesId });
} }
public ActionResult RenameSeason(int seasonId) public ActionResult RenameSeason(int seasonId)

View File

@ -1,5 +1,7 @@
using System.Web.Mvc; using System;
using System.Web.Mvc;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Timers;
namespace NzbDrone.Web.Controllers namespace NzbDrone.Web.Controllers
{ {
@ -20,7 +22,7 @@ namespace NzbDrone.Web.Controllers
[ChildActionOnly] [ChildActionOnly]
public ActionResult Footer() public ActionResult Footer()
{ {
ViewData["RssTimer"] = _timerProvider.NextRssSyncTime().ToString("yyyyMMddHHmmss"); ViewData["RssTimer"] = DateTime.Now.ToString("yyyyMMddHHmmss");
//ViewData["RssTimer"] = DateTime.Now.AddMinutes(61).AddSeconds(10).ToString("yyyyMMddHHmmss"); //ViewData["RssTimer"] = DateTime.Now.AddMinutes(61).AddSeconds(10).ToString("yyyyMMddHHmmss");
return PartialView(); return PartialView();
} }

View File

@ -603,8 +603,9 @@
<Content Include="Scripts\2011.1.315\telerik.treeview.min.js" /> <Content Include="Scripts\2011.1.315\telerik.treeview.min.js" />
<Content Include="Scripts\2011.1.315\telerik.upload.min.js" /> <Content Include="Scripts\2011.1.315\telerik.upload.min.js" />
<Content Include="Scripts\2011.1.315\telerik.window.min.js" /> <Content Include="Scripts\2011.1.315\telerik.window.min.js" />
<Content Include="Scripts\jquery-1.5.1-vsdoc.js" /> <Content Include="Scripts\jquery-1.5.2-vsdoc.js" />
<Content Include="Scripts\jquery-1.5.1.min.js" /> <Content Include="Scripts\jquery-1.5.2.js" />
<Content Include="Scripts\jquery-1.5.2.min.js" />
<Content Include="Scripts\jquery-ui-1.8.8.min.js" /> <Content Include="Scripts\jquery-ui-1.8.8.min.js" />
<Content Include="Scripts\jquery-ui-1.8.5.custom.min.js" /> <Content Include="Scripts\jquery-ui-1.8.5.custom.min.js" />
<Content Include="Scripts\jquery.form.js" /> <Content Include="Scripts\jquery.form.js" />

View File

@ -1,5 +1,4 @@
/// <reference path="jquery-1.4.1-vsdoc.js" /> /// <reference path="jquery-1.5.2-vsdoc.js" />
$(function () { $(function () {
var speed = 0; var speed = 0;
refreshNotifications(); refreshNotifications();

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

6651
NzbDrone.Web/Scripts/jquery-1.5.2-vsdoc.js vendored Normal file

File diff suppressed because it is too large Load Diff

8374
NzbDrone.Web/Scripts/jquery-1.5.2.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -16,7 +16,7 @@
<link href="../../Content/jquery-ui.css" rel="stylesheet" type="text/css" /> <link href="../../Content/jquery-ui.css" rel="stylesheet" type="text/css" />
<link href="../../Content/jquery-ui.custom.css" rel="stylesheet" type="text/css" /> <link href="../../Content/jquery-ui.custom.css" rel="stylesheet" type="text/css" />
<link href="../../Content/jquery-simpledropdown.css" rel="stylesheet" type="text/css" /> <link href="../../Content/jquery-simpledropdown.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="../../Scripts/jquery-1.5.1.min.js"></script> <script type="text/javascript" src="../../Scripts/jquery-1.5.2.min.js"></script>
<%--<script type="text/javascript" src="../../Scripts/jquery-ui-1.8.8.min.js"></script>--%> <%--<script type="text/javascript" src="../../Scripts/jquery-ui-1.8.8.min.js"></script>--%>
<asp:ContentPlaceHolder ID="headerContent" runat="server"> <asp:ContentPlaceHolder ID="headerContent" runat="server">
</asp:ContentPlaceHolder> </asp:ContentPlaceHolder>

View File

@ -3,4 +3,7 @@
<package id="Ninject" version="2.2.1.0" /> <package id="Ninject" version="2.2.1.0" />
<package id="Ninject.Web.Mvc2" version="2.2.0.1" /> <package id="Ninject.Web.Mvc2" version="2.2.0.1" />
<package id="TelerikMvcExtensions" version="2011.1.315" /> <package id="TelerikMvcExtensions" version="2011.1.315" />
<package id="jQuery" version="1.5.2" />
<package id="jQuery.vsdoc" version="1.5.2" />
<package id="jQuery.Validation" version="1.8" />
</packages> </packages>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

BIN
packages/jQuery.1.5.2/jQuery.1.5.2.nupkg vendored Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/**
* jQuery Validation Plugin 1.8.0
*
* http://bassistance.de/jquery-plugins/jquery-plugin-validation/
* http://docs.jquery.com/Plugins/Validation
*
* Copyright (c) 2006 - 2011 Jörn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
(function(c){c.extend(c.fn,{validate:function(a){if(this.length){var b=c.data(this[0],"validator");if(b)return b;b=new c.validator(a,this[0]);c.data(this[0],"validator",b);if(b.settings.onsubmit){this.find("input, button").filter(".cancel").click(function(){b.cancelSubmit=true});b.settings.submitHandler&&this.find("input, button").filter(":submit").click(function(){b.submitButton=this});this.submit(function(d){function e(){if(b.settings.submitHandler){if(b.submitButton)var f=c("<input type='hidden'/>").attr("name",
b.submitButton.name).val(b.submitButton.value).appendTo(b.currentForm);b.settings.submitHandler.call(b,b.currentForm);b.submitButton&&f.remove();return false}return true}b.settings.debug&&d.preventDefault();if(b.cancelSubmit){b.cancelSubmit=false;return e()}if(b.form()){if(b.pendingRequest){b.formSubmitted=true;return false}return e()}else{b.focusInvalid();return false}})}return b}else a&&a.debug&&window.console&&console.warn("nothing selected, can't validate, returning nothing")},valid:function(){if(c(this[0]).is("form"))return this.validate().form();
else{var a=true,b=c(this[0].form).validate();this.each(function(){a&=b.element(this)});return a}},removeAttrs:function(a){var b={},d=this;c.each(a.split(/\s/),function(e,f){b[f]=d.attr(f);d.removeAttr(f)});return b},rules:function(a,b){var d=this[0];if(a){var e=c.data(d.form,"validator").settings,f=e.rules,g=c.validator.staticRules(d);switch(a){case "add":c.extend(g,c.validator.normalizeRule(b));f[d.name]=g;if(b.messages)e.messages[d.name]=c.extend(e.messages[d.name],b.messages);break;case "remove":if(!b){delete f[d.name];
return g}var h={};c.each(b.split(/\s/),function(j,i){h[i]=g[i];delete g[i]});return h}}d=c.validator.normalizeRules(c.extend({},c.validator.metadataRules(d),c.validator.classRules(d),c.validator.attributeRules(d),c.validator.staticRules(d)),d);if(d.required){e=d.required;delete d.required;d=c.extend({required:e},d)}return d}});c.extend(c.expr[":"],{blank:function(a){return!c.trim(""+a.value)},filled:function(a){return!!c.trim(""+a.value)},unchecked:function(a){return!a.checked}});c.validator=function(a,
b){this.settings=c.extend(true,{},c.validator.defaults,a);this.currentForm=b;this.init()};c.validator.format=function(a,b){if(arguments.length==1)return function(){var d=c.makeArray(arguments);d.unshift(a);return c.validator.format.apply(this,d)};if(arguments.length>2&&b.constructor!=Array)b=c.makeArray(arguments).slice(1);if(b.constructor!=Array)b=[b];c.each(b,function(d,e){a=a.replace(RegExp("\\{"+d+"\\}","g"),e)});return a};c.extend(c.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",
validClass:"valid",errorElement:"label",focusInvalid:true,errorContainer:c([]),errorLabelContainer:c([]),onsubmit:true,ignore:[],ignoreTitle:false,onfocusin:function(a){this.lastActive=a;if(this.settings.focusCleanup&&!this.blockFocusCleanup){this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass);this.addWrapper(this.errorsFor(a)).hide()}},onfocusout:function(a){if(!this.checkable(a)&&(a.name in this.submitted||!this.optional(a)))this.element(a)},
onkeyup:function(a){if(a.name in this.submitted||a==this.lastElement)this.element(a)},onclick:function(a){if(a.name in this.submitted)this.element(a);else a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(a,b,d){c(a).addClass(b).removeClass(d)},unhighlight:function(a,b,d){c(a).removeClass(b).addClass(d)}},setDefaults:function(a){c.extend(c.validator.defaults,a)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",
url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",accept:"Please enter a value with a valid extension.",maxlength:c.validator.format("Please enter no more than {0} characters."),minlength:c.validator.format("Please enter at least {0} characters."),rangelength:c.validator.format("Please enter a value between {0} and {1} characters long."),
range:c.validator.format("Please enter a value between {0} and {1}."),max:c.validator.format("Please enter a value less than or equal to {0}."),min:c.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:false,prototype:{init:function(){function a(e){var f=c.data(this[0].form,"validator");e="on"+e.type.replace(/^validate/,"");f.settings[e]&&f.settings[e].call(f,this[0])}this.labelContainer=c(this.settings.errorLabelContainer);this.errorContext=this.labelContainer.length&&
this.labelContainer||c(this.currentForm);this.containers=c(this.settings.errorContainer).add(this.settings.errorLabelContainer);this.submitted={};this.valueCache={};this.pendingRequest=0;this.pending={};this.invalid={};this.reset();var b=this.groups={};c.each(this.settings.groups,function(e,f){c.each(f.split(/\s/),function(g,h){b[h]=e})});var d=this.settings.rules;c.each(d,function(e,f){d[e]=c.validator.normalizeRule(f)});c(this.currentForm).validateDelegate(":text, :password, :file, select, textarea",
"focusin focusout keyup",a).validateDelegate(":radio, :checkbox, select, option","click",a);this.settings.invalidHandler&&c(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler)},form:function(){this.checkForm();c.extend(this.submitted,this.errorMap);this.invalid=c.extend({},this.errorMap);this.valid()||c(this.currentForm).triggerHandler("invalid-form",[this]);this.showErrors();return this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);
return this.valid()},element:function(a){this.lastElement=a=this.clean(a);this.prepareElement(a);this.currentElements=c(a);var b=this.check(a);if(b)delete this.invalid[a.name];else this.invalid[a.name]=true;if(!this.numberOfInvalids())this.toHide=this.toHide.add(this.containers);this.showErrors();return b},showErrors:function(a){if(a){c.extend(this.errorMap,a);this.errorList=[];for(var b in a)this.errorList.push({message:a[b],element:this.findByName(b)[0]});this.successList=c.grep(this.successList,
function(d){return!(d.name in a)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){c.fn.resetForm&&c(this.currentForm).resetForm();this.submitted={};this.prepareForm();this.hideErrors();this.elements().removeClass(this.settings.errorClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b=0,d;for(d in a)b++;return b},hideErrors:function(){this.addWrapper(this.toHide).hide()},
valid:function(){return this.size()==0},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{c(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(a){}},findLastActive:function(){var a=this.lastActive;return a&&c.grep(this.errorList,function(b){return b.element.name==a.name}).length==1&&a},elements:function(){var a=this,b={};return c([]).add(this.currentForm.elements).filter(":input").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){!this.name&&
a.settings.debug&&window.console&&console.error("%o has no name assigned",this);if(this.name in b||!a.objectLength(c(this).rules()))return false;return b[this.name]=true})},clean:function(a){return c(a)[0]},errors:function(){return c(this.settings.errorElement+"."+this.settings.errorClass,this.errorContext)},reset:function(){this.successList=[];this.errorList=[];this.errorMap={};this.toShow=c([]);this.toHide=c([]);this.currentElements=c([])},prepareForm:function(){this.reset();this.toHide=this.errors().add(this.containers)},
prepareElement:function(a){this.reset();this.toHide=this.errorsFor(a)},check:function(a){a=this.clean(a);if(this.checkable(a))a=this.findByName(a.name).not(this.settings.ignore)[0];var b=c(a).rules(),d=false,e;for(e in b){var f={method:e,parameters:b[e]};try{var g=c.validator.methods[e].call(this,a.value.replace(/\r/g,""),a,f.parameters);if(g=="dependency-mismatch")d=true;else{d=false;if(g=="pending"){this.toHide=this.toHide.not(this.errorsFor(a));return}if(!g){this.formatAndAdd(a,f);return false}}}catch(h){this.settings.debug&&
window.console&&console.log("exception occured when checking element "+a.id+", check the '"+f.method+"' method",h);throw h;}}if(!d){this.objectLength(b)&&this.successList.push(a);return true}},customMetaMessage:function(a,b){if(c.metadata){var d=this.settings.meta?c(a).metadata()[this.settings.meta]:c(a).metadata();return d&&d.messages&&d.messages[b]}},customMessage:function(a,b){var d=this.settings.messages[a];return d&&(d.constructor==String?d:d[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(arguments[a]!==
undefined)return arguments[a]},defaultMessage:function(a,b){return this.findDefined(this.customMessage(a.name,b),this.customMetaMessage(a,b),!this.settings.ignoreTitle&&a.title||undefined,c.validator.messages[b],"<strong>Warning: No message defined for "+a.name+"</strong>")},formatAndAdd:function(a,b){var d=this.defaultMessage(a,b.method),e=/\$?\{(\d+)\}/g;if(typeof d=="function")d=d.call(this,b.parameters,a);else if(e.test(d))d=jQuery.format(d.replace(e,"{$1}"),b.parameters);this.errorList.push({message:d,
element:a});this.errorMap[a.name]=d;this.submitted[a.name]=d},addWrapper:function(a){if(this.settings.wrapper)a=a.add(a.parent(this.settings.wrapper));return a},defaultShowErrors:function(){for(var a=0;this.errorList[a];a++){var b=this.errorList[a];this.settings.highlight&&this.settings.highlight.call(this,b.element,this.settings.errorClass,this.settings.validClass);this.showLabel(b.element,b.message)}if(this.errorList.length)this.toShow=this.toShow.add(this.containers);if(this.settings.success)for(a=
0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight){a=0;for(b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass)}this.toHide=this.toHide.not(this.toShow);this.hideErrors();this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return c(this.errorList).map(function(){return this.element})},showLabel:function(a,
b){var d=this.errorsFor(a);if(d.length){d.removeClass().addClass(this.settings.errorClass);d.attr("generated")&&d.html(b)}else{d=c("<"+this.settings.errorElement+"/>").attr({"for":this.idOrName(a),generated:true}).addClass(this.settings.errorClass).html(b||"");if(this.settings.wrapper)d=d.hide().show().wrap("<"+this.settings.wrapper+"/>").parent();this.labelContainer.append(d).length||(this.settings.errorPlacement?this.settings.errorPlacement(d,c(a)):d.insertAfter(a))}if(!b&&this.settings.success){d.text("");
typeof this.settings.success=="string"?d.addClass(this.settings.success):this.settings.success(d)}this.toShow=this.toShow.add(d)},errorsFor:function(a){var b=this.idOrName(a);return this.errors().filter(function(){return c(this).attr("for")==b})},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(a){var b=this.currentForm;return c(document.getElementsByName(a)).map(function(d,e){return e.form==
b&&e.name==a&&e||null})},getLength:function(a,b){switch(b.nodeName.toLowerCase()){case "select":return c("option:selected",b).length;case "input":if(this.checkable(b))return this.findByName(b.name).filter(":checked").length}return a.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):true},dependTypes:{"boolean":function(a){return a},string:function(a,b){return!!c(a,b.form).length},"function":function(a,b){return a(b)}},optional:function(a){return!c.validator.methods.required.call(this,
c.trim(a.value),a)&&"dependency-mismatch"},startRequest:function(a){if(!this.pending[a.name]){this.pendingRequest++;this.pending[a.name]=true}},stopRequest:function(a,b){this.pendingRequest--;if(this.pendingRequest<0)this.pendingRequest=0;delete this.pending[a.name];if(b&&this.pendingRequest==0&&this.formSubmitted&&this.form()){c(this.currentForm).submit();this.formSubmitted=false}else if(!b&&this.pendingRequest==0&&this.formSubmitted){c(this.currentForm).triggerHandler("invalid-form",[this]);this.formSubmitted=
false}},previousValue:function(a){return c.data(a,"previousValue")||c.data(a,"previousValue",{old:null,valid:true,message:this.defaultMessage(a,"remote")})}},classRuleSettings:{required:{required:true},email:{email:true},url:{url:true},date:{date:true},dateISO:{dateISO:true},dateDE:{dateDE:true},number:{number:true},numberDE:{numberDE:true},digits:{digits:true},creditcard:{creditcard:true}},addClassRules:function(a,b){a.constructor==String?this.classRuleSettings[a]=b:c.extend(this.classRuleSettings,
a)},classRules:function(a){var b={};(a=c(a).attr("class"))&&c.each(a.split(" "),function(){this in c.validator.classRuleSettings&&c.extend(b,c.validator.classRuleSettings[this])});return b},attributeRules:function(a){var b={};a=c(a);for(var d in c.validator.methods){var e=a.attr(d);if(e)b[d]=e}b.maxlength&&/-1|2147483647|524288/.test(b.maxlength)&&delete b.maxlength;return b},metadataRules:function(a){if(!c.metadata)return{};var b=c.data(a.form,"validator").settings.meta;return b?c(a).metadata()[b]:
c(a).metadata()},staticRules:function(a){var b={},d=c.data(a.form,"validator");if(d.settings.rules)b=c.validator.normalizeRule(d.settings.rules[a.name])||{};return b},normalizeRules:function(a,b){c.each(a,function(d,e){if(e===false)delete a[d];else if(e.param||e.depends){var f=true;switch(typeof e.depends){case "string":f=!!c(e.depends,b.form).length;break;case "function":f=e.depends.call(b,b)}if(f)a[d]=e.param!==undefined?e.param:true;else delete a[d]}});c.each(a,function(d,e){a[d]=c.isFunction(e)?
e(b):e});c.each(["minlength","maxlength","min","max"],function(){if(a[this])a[this]=Number(a[this])});c.each(["rangelength","range"],function(){if(a[this])a[this]=[Number(a[this][0]),Number(a[this][1])]});if(c.validator.autoCreateRanges){if(a.min&&a.max){a.range=[a.min,a.max];delete a.min;delete a.max}if(a.minlength&&a.maxlength){a.rangelength=[a.minlength,a.maxlength];delete a.minlength;delete a.maxlength}}a.messages&&delete a.messages;return a},normalizeRule:function(a){if(typeof a=="string"){var b=
{};c.each(a.split(/\s/),function(){b[this]=true});a=b}return a},addMethod:function(a,b,d){c.validator.methods[a]=b;c.validator.messages[a]=d!=undefined?d:c.validator.messages[a];b.length<3&&c.validator.addClassRules(a,c.validator.normalizeRule(a))},methods:{required:function(a,b,d){if(!this.depend(d,b))return"dependency-mismatch";switch(b.nodeName.toLowerCase()){case "select":return(a=c(b).val())&&a.length>0;case "input":if(this.checkable(b))return this.getLength(a,b)>0;default:return c.trim(a).length>
0}},remote:function(a,b,d){if(this.optional(b))return"dependency-mismatch";var e=this.previousValue(b);this.settings.messages[b.name]||(this.settings.messages[b.name]={});e.originalMessage=this.settings.messages[b.name].remote;this.settings.messages[b.name].remote=e.message;d=typeof d=="string"&&{url:d}||d;if(this.pending[b.name])return"pending";if(e.old===a)return e.valid;e.old=a;var f=this;this.startRequest(b);var g={};g[b.name]=a;c.ajax(c.extend(true,{url:d,mode:"abort",port:"validate"+b.name,
dataType:"json",data:g,success:function(h){f.settings.messages[b.name].remote=e.originalMessage;var j=h===true;if(j){var i=f.formSubmitted;f.prepareElement(b);f.formSubmitted=i;f.successList.push(b);f.showErrors()}else{i={};h=h||f.defaultMessage(b,"remote");i[b.name]=e.message=c.isFunction(h)?h(a):h;f.showErrors(i)}e.valid=j;f.stopRequest(b,j)}},d));return"pending"},minlength:function(a,b,d){return this.optional(b)||this.getLength(c.trim(a),b)>=d},maxlength:function(a,b,d){return this.optional(b)||
this.getLength(c.trim(a),b)<=d},rangelength:function(a,b,d){a=this.getLength(c.trim(a),b);return this.optional(b)||a>=d[0]&&a<=d[1]},min:function(a,b,d){return this.optional(b)||a>=d},max:function(a,b,d){return this.optional(b)||a<=d},range:function(a,b,d){return this.optional(b)||a>=d[0]&&a<=d[1]},email:function(a,b){return this.optional(b)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(a)},
url:function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},
date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a))},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9-]+/.test(a))return false;var d=0,e=0,f=false;a=a.replace(/\D/g,"");for(var g=a.length-1;g>=
0;g--){e=a.charAt(g);e=parseInt(e,10);if(f)if((e*=2)>9)e-=9;d+=e;f=!f}return d%10==0},accept:function(a,b,d){d=typeof d=="string"?d.replace(/,/g,"|"):"png|jpe?g|gif";return this.optional(b)||a.match(RegExp(".("+d+")$","i"))},equalTo:function(a,b,d){d=c(d).unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){c(b).valid()});return a==d.val()}}});c.format=c.validator.format})(jQuery);
(function(c){var a={};if(c.ajaxPrefilter)c.ajaxPrefilter(function(d,e,f){e=d.port;if(d.mode=="abort"){a[e]&&a[e].abort();a[e]=f}});else{var b=c.ajax;c.ajax=function(d){var e=("port"in d?d:c.ajaxSettings).port;if(("mode"in d?d:c.ajaxSettings).mode=="abort"){a[e]&&a[e].abort();return a[e]=b.apply(this,arguments)}return b.apply(this,arguments)}}})(jQuery);
(function(c){!jQuery.event.special.focusin&&!jQuery.event.special.focusout&&document.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.handle.call(this,e)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)},handler:function(e){arguments[0]=c.event.fix(e);arguments[0].type=b;return c.event.handle.apply(this,arguments)}}});c.extend(c.fn,{validateDelegate:function(a,
b,d){return this.bind(b,function(e){var f=c(e.target);if(f.is(a))return d.apply(f,arguments)})}})})(jQuery);

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
param($installPath, $toolsPath, $package, $project)
$extId = "JScriptIntelliSenseParaExtension.Microsoft.039ee76c-3c7f-4281-ad23-f6528ab18623"
$extManager = [Microsoft.VisualStudio.Shell.Package]::GetGlobalService([Microsoft.VisualStudio.ExtensionManager.SVsExtensionManager])
$copyOverParaFile = $false
try {
$copyOverParaFile = $extManager.GetInstalledExtension($extId).State -eq "Enabled"
}
catch [Microsoft.VisualStudio.ExtensionManager.NotInstalledException] {
#Extension is not installed
}
if ($copyOverParaFile) {
#Copy the -vsdoc-para file over the -vsdoc file
#$projectFolder = Split-Path -Parent $project.FileName
$projectFolder = $project.Properties.Item("FullPath").Value
$paraVsDocPath = Join-Path $toolsPath jquery-1.5.2-vsdoc-para.js
$vsDocPath = Join-Path $projectFolder Scripts\jquery-1.5.2-vsdoc.js
Copy-Item $paraVsDocPath $vsDocPath -Force
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
param($installPath, $toolsPath, $package, $project)
#Forcibly delete the -vsdoc file
#$projectFolder = Split-Path -Parent $project.FileName
$projectFolder = $project.Properties.Item("FullPath").Value
$projVsDocPath = Join-Path $projectFolder Scripts\jquery-1.5.2-vsdoc.js
$origVsDocPath = Join-Path $installPath Content\Scripts\jquery-1.5.2-vsdoc.js
$origVsDocParaPath = Join-Path $toolsPath jquery-1.5.2-vsdoc-para.js
function Get-Checksum($file) {
$cryptoProvider = New-Object "System.Security.Cryptography.MD5CryptoServiceProvider"
$fileInfo = Get-Item "$file"
trap { ;
continue } $stream = $fileInfo.OpenRead()
if ($? -eq $false) {
#Write-Host "Couldn't open file for reading"
return $null
}
$bytes = $cryptoProvider.ComputeHash($stream)
$checksum = ''
foreach ($byte in $bytes) {
$checksum += $byte.ToString('x2')
}
$stream.Close() | Out-Null
return $checksum
}
if (Test-Path $projVsDocPath) {
#Copy the original -vsdoc file over the -vsdoc file modified during install
#Normal uninstall logic will then kick in
if ((Get-Checksum $projVsDocPath) -eq (Get-Checksum $origVsDocParaPath)) {
#Write-Host "Copying orig vsdoc file over"
Copy-Item $origVsDocPath $projVsDocPath -Force
}
else {
#Write-Host "vsdoc file has changed"
}
}
else {
#Write-Host "vsdoc file not found in project"
}

Binary file not shown.