294 lines
11 KiB
C#
294 lines
11 KiB
C#
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<TunerMetadata> tuners;
|
|
private List<SatellitePosition> 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<Tuple<int, bool, string>> allKnownFactoryNames = connectionManager.GetAllKnownFactoryNames();
|
|
foreach (Tuple<int, bool, string> 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<KeyValuePair<TunerFactoryIdAttribute, ITunerFactory>> tunerFactories = tunerFactoryConnectionManager.GetKnownFactories();
|
|
int tunerFactory = ini.ReadValue("startup", "tunerFactory", 0);
|
|
KeyValuePair<TunerFactoryIdAttribute, ITunerFactory> 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<TunerMetadata> foundTuners = new List<TunerMetadata>();
|
|
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<TunerMetadata>();
|
|
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<TunerMetadata>();
|
|
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<string> 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;
|
|
}
|
|
}
|
|
}
|