diff --git a/NzbDrone.Core/Parser.cs b/NzbDrone.Core/Parser.cs
index b9b995f55..e691f15af 100644
--- a/NzbDrone.Core/Parser.cs
+++ b/NzbDrone.Core/Parser.cs
@@ -8,7 +8,7 @@ using NzbDrone.Core.Repository.Quality;
namespace NzbDrone.Core
{
- internal static class Parser
+ public static class Parser
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
@@ -239,7 +239,7 @@ namespace NzbDrone.Core
///
/// title
///
- internal static string NormalizeTitle(string title)
+ public static string NormalizeTitle(string title)
{
return NormalizeRegex.Replace(title, String.Empty).ToLower();
}
diff --git a/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline.sln b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline.sln
new file mode 100644
index 000000000..fb3d3020c
--- /dev/null
+++ b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NzbDrone.Tvdb.Offline", "NzbDrone.Tvdb.Offline\NzbDrone.Tvdb.Offline.csproj", "{9B00D86A-6A39-44D2-9D66-32D9D07882E8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9B00D86A-6A39-44D2-9D66-32D9D07882E8}.Debug|x86.ActiveCfg = Debug|x86
+ {9B00D86A-6A39-44D2-9D66-32D9D07882E8}.Debug|x86.Build.0 = Debug|x86
+ {9B00D86A-6A39-44D2-9D66-32D9D07882E8}.Release|x86.ActiveCfg = Release|x86
+ {9B00D86A-6A39-44D2-9D66-32D9D07882E8}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Ionic.Zip.dll b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Ionic.Zip.dll
new file mode 100644
index 000000000..7b11577fa
Binary files /dev/null and b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Ionic.Zip.dll differ
diff --git a/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline.csproj b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline.csproj
new file mode 100644
index 000000000..8d495b1d6
--- /dev/null
+++ b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline.csproj
@@ -0,0 +1,87 @@
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {9B00D86A-6A39-44D2-9D66-32D9D07882E8}
+ Exe
+ Properties
+ NzbDrone.Tvdb.Offline
+ NzbDrone.Tvdb.Offline
+ v4.0
+
+
+ 512
+
+
+ x86
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x86
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ False
+ .\Ionic.Zip.dll
+
+
+ ..\..\NzbDrone.Core\Libraries\NLog.dll
+
+
+ ..\..\NzbDrone.Core\Libraries\NLog.Extended.dll
+
+
+ ..\..\NzbDrone.Core\bin\Debug\NzbDrone.Core.dll
+
+
+ ..\..\NzbDrone.Core\Libraries\SubSonic.Core.dll
+
+
+
+
+ ..\..\NzbDrone.Core\Libraries\System.Data.SQLite.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Program.cs b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Program.cs
new file mode 100644
index 000000000..31b56b80e
--- /dev/null
+++ b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Program.cs
@@ -0,0 +1,181 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Xml.Linq;
+using Ionic.Zip;
+using NLog;
+using NLog.Config;
+using SubSonic.DataProviders;
+using SubSonic.Repository;
+
+namespace NzbDrone.Tvdb.Offline
+{
+ class Program
+ {
+ static Logger _logger = LogManager.GetLogger("Main");
+ private static DirectoryInfo _target;
+ private static DirectoryInfo _temp;
+
+
+ static void Main(string[] args)
+ {
+ SetupLogger();
+ _logger.Info("Starting TVDB Offline...");
+ GetPath(args);
+
+ Start();
+
+
+ Console.WriteLine("Press any key to exit...");
+ Console.ReadLine();
+ }
+
+
+ private static void Start()
+ {
+ _logger.Info("Starting to generate offline DB...");
+ var files = _target.GetFiles("*.zip");
+ _logger.Info("Total number of files found {0}", files.Count());
+
+ var list = new Dictionary();
+
+ var repo = InitSubsonic();
+ decimal progress = 0;
+ foreach (var fileInfo in files)
+ {
+ Console.Write("\r{0:0.0}%", progress * 100 / files.Count());
+ var series = ProcessFile(fileInfo, repo);
+ if (series != null)
+ {
+ if (!list.ContainsKey(series.SeriesId))
+ {
+ list.Add(series.SeriesId, series);
+ }
+ else
+ {
+ Console.WriteLine();
+ _logger.Warn("Conflict {0} <=> {1}", list[series.SeriesId], series);
+ }
+ }
+ progress++;
+ }
+
+ _logger.Info("Writing series to DB");
+ repo.AddMany(list.Values);
+ _logger.Info("DB is fully created");
+
+
+ }
+
+ private static Series ProcessFile(FileInfo fileInfo, IRepository repo)
+ {
+ try
+ {
+
+
+ _logger.Debug("Processing " + fileInfo.Name);
+ using (ZipFile zip = ZipFile.Read(fileInfo.FullName))
+ {
+
+ ZipEntry e = zip["en.xml"];
+ if (e == null)
+ {
+ _logger.Warn("File {0} didn't contain an en.xml file", fileInfo.Name);
+ return null;
+ }
+
+ var stream = e.OpenReader();
+ var seriesElement = XDocument.Load(stream).Descendants("Series").First();
+
+ var series = new Series();
+ series.SeriesId = (int)seriesElement.Element("id");
+
+ series.AirsDayOfWeek = seriesElement.Element("Airs_DayOfWeek").Value;
+ series.AirTimes = seriesElement.Element("Airs_Time").Value;
+ series.Overview = seriesElement.Element("Overview").Value;
+ series.Status = seriesElement.Element("Status").Value;
+ series.Title = seriesElement.Element("SeriesName").Value;
+
+ int ratingCount;
+ Int32.TryParse(seriesElement.Element("RatingCount").Value, out ratingCount);
+ series.RateCount = ratingCount;
+
+ decimal rating;
+ Decimal.TryParse(seriesElement.Element("Rating").Value, out rating);
+ series.RateCount = ratingCount;
+
+ series.CleanTitle = Core.Parser.NormalizeTitle(series.Title);
+ series.Path = fileInfo.Name;
+
+ return series;
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.Error("Unable to process file. {0}. {1}", fileInfo.Name, e.Message);
+ return null;
+ }
+
+
+ }
+
+ private static IRepository InitSubsonic()
+ {
+ var path = Path.Combine(_temp.FullName, "series_data.db");
+ _logger.Info("Creating Database file at {0}", path);
+
+ if (File.Exists(path))
+ {
+ File.Delete(path);
+ }
+
+ string logConnectionString = String.Format("Data Source={0};Version=3;", path);
+ var provider = ProviderFactory.GetProvider(logConnectionString, "System.Data.SQLite");
+
+ return new SimpleRepository(provider, SimpleRepositoryOptions.RunMigrations);
+ }
+
+ private static void GetPath(string[] args)
+ {
+ if (args == null || args.Count() == 0 || string.IsNullOrWhiteSpace(args[0]))
+ {
+ _logger.Warn("Please provide a valid target path");
+ Environment.Exit(0);
+ }
+
+ _target = new DirectoryInfo(args[0]);
+
+ if (!_target.Exists)
+ {
+ _logger.Warn("Directory '{0}' doesn't exist.", _target.FullName);
+ Environment.Exit(0);
+ }
+
+ _logger.Info("Target Path '[{0}]'", _target.FullName);
+
+ _logger.Debug("Creating temporary folder");
+ _temp = _target.CreateSubdirectory("temp");
+ }
+
+
+ private static void SetupLogger()
+ {
+
+ LogManager.ThrowExceptions = true;
+
+ try
+ {
+ LogManager.Configuration = new XmlLoggingConfiguration("log.config", false);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ }
+
+ }
+ }
+}
diff --git a/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Properties/AssemblyInfo.cs b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..f69bd9a85
--- /dev/null
+++ b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("NzbDrone.Tvdb.Offline")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("NzbDrone.Tvdb.Offline")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("20805934-73f9-4a27-93c5-bb17f42435cd")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Series.cs b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Series.cs
new file mode 100644
index 000000000..0a8bbac1d
--- /dev/null
+++ b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/Series.cs
@@ -0,0 +1,35 @@
+using System;
+using SubSonic.SqlGeneration.Schema;
+
+namespace NzbDrone.Tvdb.Offline
+{
+ public class Series
+ {
+ [SubSonicPrimaryKey(false)]
+ public virtual int SeriesId { get; set; }
+
+ public string Title { get; set; }
+
+ public string CleanTitle { get; set; }
+
+ public string Status { get; set; }
+
+ public string Overview { get; set; }
+
+ public string AirsDayOfWeek { get; set; }
+
+ public String AirTimes { get; set; }
+
+ public int RateCount { get; set; }
+
+ public decimal Rating { get; set; }
+
+ [SubSonicIgnore]
+ public String Path { get; set; }
+
+ public override string ToString()
+ {
+ return string.Format("[{0}:{1} {2}]", SeriesId, Title, Path);
+ }
+ }
+}
\ No newline at end of file
diff --git a/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/app.config b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/app.config
new file mode 100644
index 000000000..760540c2c
--- /dev/null
+++ b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/app.config
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/log.config b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/log.config
new file mode 100644
index 000000000..c9b059f68
--- /dev/null
+++ b/NzbDrone.Tvdb.Offline/NzbDrone.Tvdb.Offline/log.config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/clo b/clo
new file mode 100644
index 000000000..aaafc779a
--- /dev/null
+++ b/clo
@@ -0,0 +1,30 @@
+* [31maf705cb[m -[33m (HEAD, origin/master, origin/HEAD, master)[m cleaned up history/log grid UI [32m(20 seconds ago) [1;34m[m
+* [31me896af5[m -[33m[m ReSharper code cleanup [32m(17 minutes ago) [1;34m[m
+* [31m8cade43[m -[33m[m Application will automatically restart on db error. [32m(32 minutes ago) [1;34m[m
+* [31mfcf5197[m -[33m[m Removed IConfigProvider, ISeasonProvider, ISyncProvider [32m(86 minutes ago) [1;34m[m
+* [31m7efbfdb[m -[33m[m removed IEpisodeProvider, ILogProvider [32m(3 hours ago) [1;34m[m
+* [31m8fbc79c[m -[33m[m Merge branch 'mark-fork' [32m(4 hours ago) [1;34m[m
+[32m|[m[33m\[m
+[32m|[m * [31m0a7f7fc[m -[33m (mark/master, mark-fork)[m Added tests for RootDirProvider. [32m(5 hours ago) [1;34m[m
+[32m|[m * [31mbfeb7b3[m -[33m[m Merge branch 'master' of git://github.com/kayone/NzbDrone [32m(7 hours ago) [1;34m[m
+[32m|[m [34m|[m[35m\[m
+[32m|[m * [35m|[m [31m1a9948d[m -[33m[m Removed IDiskProvider. [32m(27 hours ago) [1;34m[m
+[32m|[m * [35m|[m [31me5413d6[m -[33m[m Removed IRenameProvider. [32m(27 hours ago) [1;34m[m
+[32m|[m * [35m|[m [31m29690d9[m -[33m[m Removed IRssSyncProvider & IBacklogProvider [32m(27 hours ago) [1;34m[m
+[32m|[m * [35m|[m [31m0d95302[m -[33m[m Removed IHistoryProvider. [32m(27 hours ago) [1;34m[m
+[32m|[m * [35m|[m [31mc25af59[m -[33m[m Removed ISeriesProvider [32m(27 hours ago) [1;34m[m
+[32m|[m * [35m|[m [31mbd0a7a5[m -[33m[m Removed INotificationProvider [32m(27 hours ago) [1;34m[m
+[32m|[m * [35m|[m [31m4426072[m -[33m[m Merge branch 'master' of git://github.com/kayone/NzbDrone [32m(34 hours ago) [1;34m[m
+[32m|[m [36m|[m[1;31m\[m [35m\[m
+* [36m|[m [1;31m|[m [35m|[m [31m1cc44ed[m -[33m[m fixed some build issues/notification issues [32m(4 hours ago) [1;34m[m
+[35m|[m [36m|[m[35m_[m[1;31m|[m[35m/[m
+[35m|[m[35m/[m[36m|[m [1;31m|[m
+* [36m|[m [1;31m|[m [31mce11986[m -[33m[m Merge branch 'mark-fork' [32m(34 hours ago) [1;34m[m
+[1;31m|[m[36m\[m [36m\[m [1;31m\[m
+[1;31m|[m [36m|[m[36m/[m [1;31m/[m
+[1;31m|[m [36m|[m [1;31m/[m
+[1;31m|[m [36m|[m[1;31m/[m
+[1;31m|[m[1;31m/[m[36m|[m
+[1;31m|[m * [31mf52b399[m -[33m[m Removed IExternalNotificationProvider [32m(35 hours ago) [1;34m[m
+[1;31m|[m * [31mc77a88d[m -[33m[m Removed IDownloadProvider [32m(35 hours ago) [1;34m[m
+[1;31m|[m * [31m0ee4f8c[m -[33m[m Removed IPostProcessingProvider [32m(2 days ago) [1;34m[m
\ No newline at end of file