Merge branch 'master' of git://github.com/kayone/NzbDrone
Conflicts: NzbDrone.Core.Test/ParserTest.cs
This commit is contained in:
commit
5107a02f5e
|
@ -113,7 +113,7 @@ namespace NzbDrone.Core.Test
|
|||
/////////////////////////////////////////
|
||||
|
||||
//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 episodeNumner = 01;
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
<Compile Include="AutoMoq\Unity\AutoMockingContainerExtension.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="TimerProviderTest.cs" />
|
||||
<Compile Include="SyncProviderTest.cs" />
|
||||
<Compile Include="RootDirProviderTest.cs" />
|
||||
<Compile Include="IndexerProviderTest.cs" />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using MbUnit.Framework;
|
||||
using NzbDrone.Core.Repository.Quality;
|
||||
|
||||
|
@ -15,6 +15,7 @@ namespace NzbDrone.Core.Test
|
|||
*/
|
||||
|
||||
[Test]
|
||||
[Timeout(1)]
|
||||
[Row("Sonny.With.a.Chance.S02E15", 2, 15)]
|
||||
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, 1)]
|
||||
[Row("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", 1, 3)]
|
||||
|
@ -40,6 +41,7 @@ namespace NzbDrone.Core.Test
|
|||
}
|
||||
|
||||
[Test]
|
||||
[Timeout(1)]
|
||||
[Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.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)]
|
||||
|
@ -66,9 +68,10 @@ namespace NzbDrone.Core.Test
|
|||
}
|
||||
|
||||
[Test]
|
||||
[Timeout(1)]
|
||||
[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("Weeds.S03E01.S03E02.720p.HDTV.X264-DIMENSION", 3, new[] {1, 2})]
|
||||
[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("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("White.Collar.2x04.2x05.720p.BluRay-FUTV", 2, new[] { 4, 5 })]
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ using NzbDrone.Core.Instrumentation;
|
|||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Core.Providers.Indexer;
|
||||
using NzbDrone.Core.Providers.Timers;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Core.Repository.Quality;
|
||||
using SubSonic.DataProviders;
|
||||
|
@ -22,7 +23,6 @@ namespace NzbDrone.Core
|
|||
private static StandardKernel _kernel;
|
||||
private static readonly Object KernelLock = new object();
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private static string _startupPath;
|
||||
|
||||
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
|
||||
{
|
||||
get
|
||||
|
@ -70,19 +55,16 @@ namespace NzbDrone.Core
|
|||
Logger.Debug("Binding Ninject's Kernel");
|
||||
_kernel = new StandardKernel();
|
||||
|
||||
//Store the startup path
|
||||
_startupPath = AppPath;
|
||||
|
||||
//Sqlite
|
||||
var AppDataPath = new DirectoryInfo(Path.Combine(AppPath, "App_Data"));
|
||||
if (!AppDataPath.Exists) AppDataPath.Create();
|
||||
var appDataPath = new DirectoryInfo(Path.Combine(AppPath, "App_Data"));
|
||||
if (!appDataPath.Exists) appDataPath.Create();
|
||||
|
||||
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");
|
||||
|
||||
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");
|
||||
|
||||
|
||||
|
@ -99,7 +81,6 @@ namespace NzbDrone.Core
|
|||
_kernel.Bind<HttpProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<SeriesProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<SeasonProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<RssSyncProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<EpisodeProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<UpcomingEpisodesProvider>().ToSelf().InSingletonScope();
|
||||
_kernel.Bind<DiskProvider>().ToSelf().InSingletonScope();
|
||||
|
@ -127,12 +108,6 @@ namespace NzbDrone.Core
|
|||
ForceMigration(_kernel.Get<IRepository>());
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +132,7 @@ namespace NzbDrone.Core
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method forces IISExpress process to exit with the host application
|
||||
/// Forces IISExpress process to exit with the host application
|
||||
/// </summary>
|
||||
public static void DedicateToHost()
|
||||
{
|
||||
|
@ -190,7 +165,6 @@ namespace NzbDrone.Core
|
|||
Process.GetCurrentProcess().Kill();
|
||||
}
|
||||
|
||||
|
||||
private static void SetupDefaultQualityProfiles(IRepository repository)
|
||||
{
|
||||
var sd = new QualityProfile
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -163,15 +163,18 @@
|
|||
<Compile Include="Helpers\EpisodeRenameHelper.cs" />
|
||||
<Compile Include="Helpers\EpisodeSortingHelper.cs" />
|
||||
<Compile Include="Helpers\SceneNameHelper.cs" />
|
||||
<Compile Include="Helpers\ServerHelper.cs" />
|
||||
<Compile Include="Instrumentation\LogLevel.cs" />
|
||||
<Compile Include="Instrumentation\LogProvider.cs" />
|
||||
<Compile Include="Instrumentation\SubsonicTarget.cs" />
|
||||
<Compile Include="Instrumentation\ExceptioneerTarget.cs" />
|
||||
<Compile Include="Instrumentation\NlogWriter.cs" />
|
||||
<Compile Include="Providers\Indexer\NzbMatrixProvider.cs" />
|
||||
<Compile Include="Providers\Timers\TimerProvider.cs" />
|
||||
<Compile Include="Providers\Indexer\NewzbinProvider.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="Model\EpisodeParseResult.cs" />
|
||||
<Compile Include="Model\EpisodeRenameModel.cs" />
|
||||
|
@ -188,12 +191,10 @@
|
|||
<Compile Include="Providers\HistoryProvider.cs" />
|
||||
<Compile Include="Providers\BacklogProvider.cs" />
|
||||
<Compile Include="Providers\IndexerProvider.cs" />
|
||||
<Compile Include="Providers\RssSyncProvider.cs" />
|
||||
<Compile Include="Providers\PostProcessingProvider.cs" />
|
||||
<Compile Include="Providers\QualityProvider.cs" />
|
||||
<Compile Include="Providers\RenameProvider.cs" />
|
||||
<Compile Include="Providers\RootDirProvider.cs" />
|
||||
<Compile Include="Providers\TimerProvider.cs" />
|
||||
<Compile Include="Providers\UpcomingEpisodesProvider.cs" />
|
||||
<Compile Include="Providers\XbmcProvider.cs" />
|
||||
<Compile Include="Repository\EpisodeFile.cs" />
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace NzbDrone.Core
|
|||
if (match.Count != 0)
|
||||
{
|
||||
var seriesName = NormalizeTitle(match[0].Groups["title"].Value);
|
||||
var year = 0;
|
||||
int year;
|
||||
Int32.TryParse(match[0].Groups["year"].Value, out year);
|
||||
|
||||
if (year < 1900 || year > DateTime.Now.Year + 1)
|
||||
|
@ -158,12 +158,11 @@ namespace NzbDrone.Core
|
|||
{
|
||||
SeriesTitle = seriesName,
|
||||
SeasonNumber = seasonNumber,
|
||||
Year = year
|
||||
Year = year,
|
||||
Quality = ParseQuality(title)
|
||||
};
|
||||
|
||||
|
||||
result.Quality = ParseQuality(title);
|
||||
|
||||
Logger.Trace("Season Parsed. {0}", result);
|
||||
return result;
|
||||
}
|
||||
|
@ -188,14 +187,7 @@ namespace NzbDrone.Core
|
|||
if (match.Count != 0)
|
||||
{
|
||||
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);
|
||||
return seriesName;
|
||||
}
|
||||
|
@ -289,11 +281,10 @@ namespace NzbDrone.Core
|
|||
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)
|
||||
{
|
||||
if (String.IsNullOrEmpty(path))
|
||||
if (String.IsNullOrWhiteSpace(path))
|
||||
throw new ArgumentException("Path can not be null or empty");
|
||||
|
||||
var info = new FileInfo(path);
|
||||
|
|
|
@ -107,22 +107,28 @@ namespace NzbDrone.Core.Providers.Indexer
|
|||
if (!_seriesProvider.IsMonitored(parseResult.SeriesId))
|
||||
{
|
||||
Logger.Debug("{0} is present in the DB but not tracked. skipping.", parseResult.SeriesTitle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_seriesProvider.QualityWanted(parseResult.SeriesId, parseResult.Quality))
|
||||
{
|
||||
Logger.Debug("Post doesn't meet the quality requirements [{0}]. skipping.", parseResult.Quality);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_seasonProvider.IsIgnored(parseResult.SeriesId, parseResult.SeasonNumber))
|
||||
{
|
||||
Logger.Debug("Season {0} is currently set to ignore. skipping.", parseResult.SeasonNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_episodeProvider.IsNeeded(parseResult))
|
||||
{
|
||||
Logger.Debug("Episode {0} is not needed. skipping.", parseResult);
|
||||
return;
|
||||
}
|
||||
|
||||
//Should probably queue item to download
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace NzbDrone.Core.Providers
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
namespace NzbDrone.Core.Providers
|
||||
{
|
||||
public class RssSyncProvider
|
||||
{
|
||||
public virtual void Begin()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -51,7 +51,7 @@ namespace NzbDrone.Core.Providers
|
|||
|
||||
XDocument xDoc = XDocument.Parse(response);
|
||||
|
||||
//If an Error Occurred, retuyrn)
|
||||
//If an Error Occurred, return)
|
||||
if (xDoc.Descendants("error").Count() != 0)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace NzbDrone.Core.Providers.Timers
|
||||
{
|
||||
public interface ITimer
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
int DefaultInterval { get; }
|
||||
|
||||
void Start();
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -23,13 +23,13 @@ namespace NzbDrone.Core.Providers
|
|||
public virtual void Notify(string header, string message)
|
||||
{
|
||||
//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);
|
||||
|
||||
if (Convert.ToBoolean(_configProvider.GetValue("XbmcNotificationImage", false, true)))
|
||||
{
|
||||
//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);
|
||||
command = String.Format("ExecBuiltIn(Notification({0},{1},{2}, {3}))", header, message, time, imageUrl);
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace NzbDrone.Core.Repository.Quality
|
|||
|
||||
foreach (var q in Allowed)
|
||||
{
|
||||
result += (int) q + "|";
|
||||
result += (int)q + "|";
|
||||
}
|
||||
return result.Trim('|');
|
||||
}
|
||||
|
@ -51,12 +51,12 @@ namespace NzbDrone.Core.Repository.Quality
|
|||
Allowed = new List<QualityTypes>(qualities.Length);
|
||||
foreach (var quality in qualities)
|
||||
{
|
||||
Allowed.Add((QualityTypes) Convert.ToInt32(quality));
|
||||
Allowed.Add((QualityTypes)Convert.ToInt32(quality));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SubSonicToManyRelation]
|
||||
public virtual List<string> Series { get; private set; }
|
||||
public virtual List<Series> Series { get; private set; }
|
||||
}
|
||||
}
|
|
@ -18,9 +18,9 @@ namespace NzbDrone.Core.Repository
|
|||
public DayOfWeek? LastDiskSync { get; set; }
|
||||
|
||||
[SubSonicToManyRelation]
|
||||
public virtual List<Episode> Episodes { get; private set; }
|
||||
public virtual List<Episode> Episodes { get; protected set; }
|
||||
|
||||
[SubSonicToOneRelation(ThisClassContainsJoinKey = true)]
|
||||
public virtual Series Series { get; private set; }
|
||||
public virtual Series Series { get; protected set; }
|
||||
}
|
||||
}
|
|
@ -45,15 +45,15 @@ namespace NzbDrone.Core.Repository
|
|||
public DateTime? LastDiskSync { get; set; }
|
||||
|
||||
[SubSonicToOneRelation(ThisClassContainsJoinKey = true, JoinKeyName = "QualityProfileId")]
|
||||
public virtual QualityProfile QualityProfile { get; private set; }
|
||||
public virtual QualityProfile QualityProfile { get; protected set; }
|
||||
|
||||
[SubSonicToManyRelation]
|
||||
public virtual List<Season> Seasons { get; private set; }
|
||||
public virtual List<Season> Seasons { get; protected set; }
|
||||
|
||||
[SubSonicToManyRelation]
|
||||
public virtual List<Episode> Episodes { get; private set; }
|
||||
public virtual List<Episode> Episodes { get; protected set; }
|
||||
|
||||
[SubSonicToManyRelation]
|
||||
public virtual List<EpisodeFile> EpisodeFiles { get; private set; }
|
||||
public virtual List<EpisodeFile> EpisodeFiles { get; protected set; }
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Timers;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Web.Models;
|
||||
using Telerik.Web.Mvc;
|
||||
|
@ -19,28 +20,28 @@ namespace NzbDrone.Web.Controllers
|
|||
private readonly QualityProvider _qualityProvider;
|
||||
private readonly RenameProvider _renameProvider;
|
||||
private readonly RootDirProvider _rootDirProvider;
|
||||
private readonly RssSyncProvider _rssSyncProvider;
|
||||
private readonly SeriesProvider _seriesProvider;
|
||||
private readonly SyncProvider _syncProvider;
|
||||
private readonly TvDbProvider _tvDbProvider;
|
||||
private readonly TimerProvider _timerProvider;
|
||||
//
|
||||
// GET: /Series/
|
||||
|
||||
public SeriesController(SyncProvider syncProvider, SeriesProvider seriesProvider,
|
||||
EpisodeProvider episodeProvider, RssSyncProvider rssSyncProvider,
|
||||
EpisodeProvider episodeProvider,
|
||||
QualityProvider qualityProvider, MediaFileProvider mediaFileProvider,
|
||||
RenameProvider renameProvider, RootDirProvider rootDirProvider,
|
||||
TvDbProvider tvDbProvider)
|
||||
TvDbProvider tvDbProvider, TimerProvider timerProvider)
|
||||
{
|
||||
_seriesProvider = seriesProvider;
|
||||
_episodeProvider = episodeProvider;
|
||||
_syncProvider = syncProvider;
|
||||
_rssSyncProvider = rssSyncProvider;
|
||||
_qualityProvider = qualityProvider;
|
||||
_mediaFileProvider = mediaFileProvider;
|
||||
_renameProvider = renameProvider;
|
||||
_rootDirProvider = rootDirProvider;
|
||||
_tvDbProvider = tvDbProvider;
|
||||
_timerProvider = timerProvider;
|
||||
}
|
||||
|
||||
public ActionResult Index()
|
||||
|
@ -52,13 +53,13 @@ namespace NzbDrone.Web.Controllers
|
|||
|
||||
public ActionResult RssSync()
|
||||
{
|
||||
_rssSyncProvider.Begin();
|
||||
_timerProvider.ForceExecute(typeof(RssSyncTimer));
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -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
|
||||
//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)
|
||||
tvDbSeries = new TvdbSeries {Id = 0, SeriesName = String.Empty};
|
||||
tvDbSeries = new TvdbSeries { Id = 0, SeriesName = String.Empty };
|
||||
|
||||
unmappedList.Add(new AddExistingSeriesModel
|
||||
{
|
||||
|
@ -263,7 +264,7 @@ namespace NzbDrone.Web.Controllers
|
|||
var series = _seriesProvider.GetSeries(seriesId);
|
||||
_mediaFileProvider.Scan(series);
|
||||
|
||||
return RedirectToAction("Details", new {seriesId});
|
||||
return RedirectToAction("Details", new { seriesId });
|
||||
}
|
||||
|
||||
public ActionResult RenameAll()
|
||||
|
@ -275,7 +276,7 @@ namespace NzbDrone.Web.Controllers
|
|||
public ActionResult RenameSeries(int seriesId)
|
||||
{
|
||||
_renameProvider.RenameSeries(seriesId);
|
||||
return RedirectToAction("Details", new {seriesId});
|
||||
return RedirectToAction("Details", new { seriesId });
|
||||
}
|
||||
|
||||
public ActionResult RenameSeason(int seasonId)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using System.Web.Mvc;
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Timers;
|
||||
|
||||
namespace NzbDrone.Web.Controllers
|
||||
{
|
||||
|
@ -20,7 +22,7 @@ namespace NzbDrone.Web.Controllers
|
|||
[ChildActionOnly]
|
||||
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");
|
||||
return PartialView();
|
||||
}
|
||||
|
|
|
@ -603,8 +603,9 @@
|
|||
<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.window.min.js" />
|
||||
<Content Include="Scripts\jquery-1.5.1-vsdoc.js" />
|
||||
<Content Include="Scripts\jquery-1.5.1.min.js" />
|
||||
<Content Include="Scripts\jquery-1.5.2-vsdoc.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.5.custom.min.js" />
|
||||
<Content Include="Scripts\jquery.form.js" />
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/// <reference path="jquery-1.4.1-vsdoc.js" />
|
||||
|
||||
/// <reference path="jquery-1.5.2-vsdoc.js" />
|
||||
$(function () {
|
||||
var speed = 0;
|
||||
refreshNotifications();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -16,7 +16,7 @@
|
|||
<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-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>--%>
|
||||
<asp:ContentPlaceHolder ID="headerContent" runat="server">
|
||||
</asp:ContentPlaceHolder>
|
||||
|
|
|
@ -3,4 +3,7 @@
|
|||
<package id="Ninject" version="2.2.1.0" />
|
||||
<package id="Ninject.Web.Mvc2" version="2.2.0.1" />
|
||||
<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>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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
|
@ -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
|
@ -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.
Loading…
Reference in New Issue