using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.NetworkInformation; using System.Reflection; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; using System.Threading.Tasks; using log4net; using skyscraper5.Dvb.Psi.Model; using skyscraper5.Mpeg2; using skyscraper5.Skyscraper; using skyscraper5.Skyscraper.Headless; using skyscraper5.Skyscraper.IO; using skyscraper5.Skyscraper.IO.CrazycatStreamReader; using skyscraper5.Skyscraper.IO.TunerInterface; using skyscraper5.Skyscraper.Plugins; using skyscraper5.Skyscraper.Scraper; using skyscraper5.Skyscraper.Scraper.Storage; using skyscraper8.Skyscraper.Scraper.Storage; namespace skyscraper5 { public class Passing { public DataStorage DataStorage { get; set; } public ObjectStorage ObjectStorage { get; set; } private IStreamReader streamReader; private List tuners; private List satellitePositions; private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); public Passing() { } public bool Boot() { Ini ini = PluginManager.GetInstance().Ini; StorageConnectionManager connectionManager = StorageConnectionManager.GetInstance(); IEnumerable> allKnownFactoryNames = connectionManager.GetAllKnownFactoryNames(); foreach (Tuple knownFactoryName in allKnownFactoryNames) { logger.InfoFormat("Found {0} Storage Factory #{1}, {2}",knownFactoryName.Item2 ? "Data" : "Object",knownFactoryName.Item1,knownFactoryName.Item3); } logger.Debug("Acquiring Default Data Storage..."); DataStorageFactory dataStorageFactory = connectionManager.GetDefaultDataStorageFactory(); logger.Debug("Acquiring Default Object Storage..."); ObjectStorageFactory objectStorageFactory = connectionManager.GetDefaultObjectStorageFactory(); logger.Debug("Acquiring Data Storage..."); DataStorage = dataStorageFactory.CreateDataStorage(); if (DataStorage == null) { logger.FatalFormat("The data storage factory didn't create a data storage."); return false; } bool isEquivalent = objectStorageFactory.IsEquivalent(dataStorageFactory); if (isEquivalent) { logger.Debug("Using the Data Storage as Object Storage."); ObjectStorage = (ObjectStorage)DataStorage; } else { logger.Debug("Acquiring Object Storage..."); ObjectStorage = objectStorageFactory.CreateObjectStorage(); if (ObjectStorage == null) { logger.FatalFormat("The object storage factory didn't create an object storage."); return false; } } TunerFactoryConnectionManager tunerFactoryConnectionManager = TunerFactoryConnectionManager.GetInstance(); ReadOnlyCollection> tunerFactories = tunerFactoryConnectionManager.GetKnownFactories(); int tunerFactory = ini.ReadValue("startup", "tunerFactory", 0); KeyValuePair bootingTuner = tunerFactories.First(x => x.Key.Id == tunerFactory); if (bootingTuner.Value == null) { Console.WriteLine("The tuner factory #{0} didn't load.", tunerFactory); return false; } TunerFactoryConnectionManager.ConfigureFactoryFromIni(bootingTuner, ini); streamReader = bootingTuner.Value.CreateStreamReader(); if (streamReader == null) { Console.WriteLine("The tuner factory #{0} didn't create a stream reader."); return false; } try { streamReader.CheckForDVB(); } catch (BadImageFormatException e) { Console.WriteLine("The configured tuner factory is not suitable for the current processor architecture. Tuning won't work, therefore functionality will be severely limited. Please configure a Tuner Factory Class suitable for this processor architecture in order to get the best experience. If you need to run crazycat69's StreamReader.dll on 64-bit machines, try RemoteStreamReader."); streamReader = new NullTunerFactory().CreateStreamReader(); } List foundTuners = new List(); bool checkForDvbExEx = streamReader.CheckForDVBExEx((index, name, type) => { TunerMetadata tuner = new TunerMetadata(index, name, type); foundTuners.Add(tuner); }); foreach (TunerMetadata foundTuner in foundTuners) { streamReader.StopDVB(); bool startDvbEx = streamReader.StartDvbEx(foundTuner.Index); if (!startDvbEx) { Console.WriteLine("Failed to start {0}", foundTuner.Name); Thread.Sleep(1000); continue; } foundTuner.Caps = streamReader.GetCaps(); byte[] macBuffer = new byte[6]; bool mac = streamReader.GetMAC(macBuffer); if (!mac) { Console.WriteLine("Failed to read MAC Address of {0}", foundTuner.Name); Thread.Sleep(1000); } else { foundTuner.MacAddress = new PhysicalAddress(macBuffer); } bool stopDvb = streamReader.StopDVB(); if (!stopDvb) { Console.WriteLine("Failed to stop {0}", foundTuner.Name); Thread.Sleep(1000); continue; } ; if (DataStorage.UiTunerTestFor(foundTuner)) { DataStorage.UiTunerGetConfiguration(foundTuner); } if (tuners == null) tuners = new List(); tuners.Add(foundTuner); } satellitePositions = DataStorage.UiSatellitesListAll(); return true; } private HeadlessJob GetNextJob() { HeadlessJob headlessJob = DataStorage.GetQueuedJob(); if (headlessJob != null) { return headlessJob; } return new HeadlessJob(HeadlessJobType.BlindscanEverything); } public void Run() { while (true) { HeadlessJob headlessJob = GetNextJob(); Run(headlessJob); if (!headlessJob.isSynthetic) { DataStorage.SetQueuedJobComplete(headlessJob); } } } private void Run(HeadlessJob job) { switch (job.jobType) { case HeadlessJobType.Sleep: Thread.Sleep(job.iArg1); break; case HeadlessJobType.MassImport: DirectoryInfo di = new DirectoryInfo(job.sArg1); MassImportDirectory(di); break; case HeadlessJobType.BlindscanEverything: PerformBlindscanEverything(); break; case HeadlessJobType.ReimportByTag1: ReimportTag(job.iArg1); break; default: throw new NotImplementedException(job.jobType.ToString()); } } private void PerformBlindscanEverything() { if (tuners == null) tuners = new List(); if (tuners.Count == 0) throw new ApplicationException("I'd need to blindscan everything, but I don't have any tuners I could use!"); throw new NotImplementedException(nameof(PerformBlindscanEverything)); } private void ReimportTag(int tag1) { IReadOnlyList queue = DataStorage.ListImportFileByTag1(tag1); foreach(string filename in queue) { FileInfo fi = new FileInfo(filename); if (!fi.Exists) continue; ScrapeStream(fi); } } public void MassImportDirectory(DirectoryInfo sourceDir) { foreach (FileSystemInfo fileSystemInfo in sourceDir.GetFileSystemInfos()) { DirectoryInfo di = fileSystemInfo as DirectoryInfo; FileInfo fi = fileSystemInfo as FileInfo; if (di != null) { MassImportDirectory(di); } else if (fi != null) { if (fi.Length == 0) continue; if (!fi.Extension.ToLowerInvariant().Equals(".ts")) continue; if (DataStorage.ImportFileKnown(fi)) continue; FileStream fileStream = fi.OpenRead(); Stopwatch stopwatch = Stopwatch.StartNew(); int tstype; ScrapeStream(fileStream,true, out tstype); stopwatch.Stop(); Console.WriteLine("Importing {0} took {1}",fi.Name, stopwatch.Elapsed); DataStorage.WaitForCompletion(); DataStorage.ImportMarkFileAsKnown(fi, stopwatch.Elapsed, tstype); fileStream.Close(); } else { throw new NotImplementedException(fileSystemInfo.GetType().ToString()); } } } private void ScrapeStream(FileInfo fi) { FileStream fileStream = fi.OpenRead(); ScrapeStream(fileStream, true, out _); fileStream.Close(); fileStream.Dispose(); } private void ScrapeStream(Stream inStream, bool disk, out int tstype) { SkyscraperContext skyscraperContext = new SkyscraperContext(new TsContext(), DataStorage,ObjectStorage); skyscraperContext.SourceIsDisk = disk; skyscraperContext.InitalizeFilterChain(); skyscraperContext.IngestFromStream(inStream); skyscraperContext.Dispose(); tstype = skyscraperContext.SpecialTsType; } } }