mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-01-15 03:42:04 +01:00
Eleminated redundant code that was used for loading/applying reference lists in CSV or TXT/CHL format.
335 lines
9.3 KiB
C#
335 lines
9.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace ChanSort.Api
|
|
{
|
|
/// <summary>
|
|
/// Reads a reference list from a .csv file with the format
|
|
/// [dummy1],ProgramNr,[dummy2],UID,ChannelName[,SignalSource,FavAndFlags]
|
|
/// </summary>
|
|
public class CsvFileSerializer : SerializerBase
|
|
{
|
|
private static readonly List<string> Columns = new List<string>
|
|
{
|
|
"OldPosition",
|
|
"Position",
|
|
"Name",
|
|
"OriginalNetworkId",
|
|
"TransportStreamId",
|
|
"ServiceId",
|
|
"Favorites",
|
|
"Skip",
|
|
"Lock",
|
|
"Hidden"
|
|
};
|
|
|
|
#region ctor()
|
|
|
|
public CsvFileSerializer(string fileName) : base(fileName)
|
|
{
|
|
this.Features.ChannelNameEdit = ChannelNameEditMode.All;
|
|
this.Features.CanSkipChannels = true;
|
|
this.Features.CanDeleteChannels = true;
|
|
this.Features.CanHaveGaps = true;
|
|
this.Features.EncryptedFlagEdit = false;
|
|
this.DataRoot.SortedFavorites = false;
|
|
this.DataRoot.SupportedFavorites = Favorites.A | Favorites.B | Favorites.C | Favorites.D | Favorites.E;
|
|
}
|
|
|
|
#endregion
|
|
|
|
public override string DisplayName => "ChanSort .csv Reference List Loader";
|
|
|
|
#region Load()
|
|
|
|
public override void Load()
|
|
{
|
|
using (var stream = new StreamReader(this.FileName))
|
|
{
|
|
var lineNr = 0;
|
|
var line = "";
|
|
try
|
|
{
|
|
while ((line = stream.ReadLine()) != null)
|
|
this.ReadChannel(line, ++lineNr);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new FileLoadException($"Error in reference file line #{lineNr}: {line}", ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ReadChannel()
|
|
|
|
private void ReadChannel(string line, int lineNr)
|
|
{
|
|
var parts = CsvFile.Parse(line, ',');
|
|
if (parts.Count < 5) return;
|
|
int programNr;
|
|
if (!int.TryParse(parts[1], out programNr)) return;
|
|
var uid = parts[3];
|
|
if (uid.StartsWith("S")) // remove satellite orbital position from UID ... not all TV models provide this information
|
|
uid = "S" + uid.Substring(uid.IndexOf('-'));
|
|
var signalSource = GetSignalSource(ref programNr, uid, parts);
|
|
if (signalSource == 0)
|
|
return;
|
|
|
|
var channelList = this.GetChannelList(signalSource);
|
|
if (channelList == null)
|
|
return;
|
|
|
|
var name = parts[4];
|
|
var channel = new ChannelInfo(signalSource, lineNr, programNr, name);
|
|
|
|
var uidParts = uid.Split('-');
|
|
if (uidParts.Length >= 4)
|
|
{
|
|
int val;
|
|
if (int.TryParse(uidParts[1], out val))
|
|
channel.OriginalNetworkId = val;
|
|
if (int.TryParse(uidParts[2], out val))
|
|
channel.TransportStreamId = val;
|
|
if (int.TryParse(uidParts[3], out val))
|
|
channel.ServiceId = val;
|
|
}
|
|
|
|
if (parts.Count >= 7)
|
|
ApplyFlags(channel, parts[6]);
|
|
|
|
this.DataRoot.AddChannel(channelList, channel);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetSignalSource()
|
|
|
|
private static SignalSource GetSignalSource(ref int slot, string uid, IList<string> parts)
|
|
{
|
|
// new lists store a bitmask which defines the type of channel and list it came from
|
|
if (parts.Count >= 6 && parts[5].Length >= 4)
|
|
{
|
|
SignalSource s = 0;
|
|
var code = parts[5];
|
|
if (code[0] == 'A') s |= SignalSource.Analog;
|
|
else if (code[0] == 'D') s |= SignalSource.Digital;
|
|
|
|
if (code[1] == 'A') s |= SignalSource.Antenna;
|
|
else if (code[1] == 'C') s |= SignalSource.Cable;
|
|
else if (code[1] == 'S') s |= SignalSource.Sat;
|
|
else if (code[1] == 'I') s |= SignalSource.IP;
|
|
|
|
if (code[2] == 'T') s |= SignalSource.Tv;
|
|
else if (code[2] == 'R') s |= SignalSource.Radio;
|
|
|
|
s |= (SignalSource) (int.Parse(code.Substring(3)) << 12);
|
|
return s;
|
|
}
|
|
|
|
// compatibility for older lists
|
|
var isTv = slot < 0x4000;
|
|
slot &= 0x3FFFF;
|
|
SignalSource signalSource;
|
|
switch (uid[0])
|
|
{
|
|
case 'S':
|
|
signalSource = SignalSource.DvbS;
|
|
break;
|
|
case 'C':
|
|
signalSource = SignalSource.DvbCT;
|
|
break;
|
|
case 'A':
|
|
signalSource = SignalSource.AnalogCT;
|
|
break;
|
|
case 'H':
|
|
signalSource = SignalSource.HdPlusD;
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
signalSource |= isTv ? SignalSource.Tv : SignalSource.Radio;
|
|
return signalSource;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetChannelList()
|
|
|
|
private ChannelList GetChannelList(SignalSource signalSource)
|
|
{
|
|
var channelList = this.DataRoot.GetChannelList(signalSource);
|
|
if (channelList == null)
|
|
{
|
|
channelList = new ChannelList(signalSource, CreateCaption(signalSource));
|
|
channelList.VisibleColumnFieldNames = Columns;
|
|
this.DataRoot.AddChannelList(channelList);
|
|
}
|
|
return channelList;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region CreateCaption()
|
|
|
|
private string CreateCaption(SignalSource signalSource)
|
|
{
|
|
var sb = new StringBuilder();
|
|
if ((signalSource & SignalSource.DvbT) == SignalSource.DvbT)
|
|
sb.Append("DVB-T");
|
|
else if ((signalSource & SignalSource.DvbC) == SignalSource.DvbC)
|
|
sb.Append("DVB-C");
|
|
else if ((signalSource & SignalSource.DvbS) == SignalSource.DvbS)
|
|
sb.Append("DVB-S");
|
|
else if ((signalSource & SignalSource.IP) == SignalSource.IP)
|
|
sb.Append("IP");
|
|
else if ((signalSource & SignalSource.Digital) == SignalSource.Digital)
|
|
sb.Append("DVB");
|
|
else if ((signalSource & SignalSource.Analog) == SignalSource.Analog)
|
|
sb.Append("Analog");
|
|
|
|
sb.Append(" ");
|
|
if ((signalSource & SignalSource.Tv) == SignalSource.Tv)
|
|
sb.Append("TV");
|
|
else if ((signalSource & SignalSource.Radio) == SignalSource.Radio)
|
|
sb.Append("Radio");
|
|
else
|
|
sb.Append("Data");
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ApplyFlags()
|
|
|
|
private void ApplyFlags(ChannelInfo channel, string flags)
|
|
{
|
|
channel.Lock = false;
|
|
channel.Skip = false;
|
|
channel.Hidden = false;
|
|
|
|
foreach (var c in flags)
|
|
{
|
|
switch (c)
|
|
{
|
|
case '1':
|
|
channel.Favorites |= Favorites.A;
|
|
break;
|
|
case '2':
|
|
channel.Favorites |= Favorites.B;
|
|
break;
|
|
case '3':
|
|
channel.Favorites |= Favorites.C;
|
|
break;
|
|
case '4':
|
|
channel.Favorites |= Favorites.D;
|
|
break;
|
|
case '5':
|
|
channel.Favorites |= Favorites.E;
|
|
break;
|
|
case 'L':
|
|
channel.Lock = true;
|
|
break;
|
|
case 'S':
|
|
channel.Skip = true;
|
|
break;
|
|
case 'H':
|
|
channel.Hidden = true;
|
|
break;
|
|
case 'D':
|
|
channel.IsDeleted = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region EncodeSignalSource()
|
|
|
|
private static string EncodeSignalSource(SignalSource signalSource)
|
|
{
|
|
var sb = new StringBuilder();
|
|
if ((signalSource & SignalSource.Analog) != 0) sb.Append('A');
|
|
else sb.Append('D');
|
|
|
|
if ((signalSource & SignalSource.Antenna) != 0) sb.Append('A');
|
|
else if ((signalSource & SignalSource.Cable) != 0) sb.Append('C');
|
|
else if ((signalSource & SignalSource.Sat) != 0) sb.Append('S');
|
|
else sb.Append("I");
|
|
|
|
if ((signalSource & SignalSource.Radio) != 0) sb.Append('R');
|
|
else sb.Append('T');
|
|
|
|
sb.Append((int) signalSource >> 12);
|
|
return sb.ToString();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region EncodeFavoritesAndFlags()
|
|
|
|
private static string EncodeFavoritesAndFlags(ChannelInfo channel)
|
|
{
|
|
var sb = new StringBuilder();
|
|
if ((channel.Favorites & Favorites.A) != 0) sb.Append('1');
|
|
if ((channel.Favorites & Favorites.B) != 0) sb.Append('2');
|
|
if ((channel.Favorites & Favorites.C) != 0) sb.Append('3');
|
|
if ((channel.Favorites & Favorites.D) != 0) sb.Append('4');
|
|
if ((channel.Favorites & Favorites.E) != 0) sb.Append('5');
|
|
if (channel.Lock) sb.Append('L');
|
|
if (channel.Skip) sb.Append('S');
|
|
if (channel.Hidden) sb.Append('H');
|
|
if (channel.IsDeleted) sb.Append('D');
|
|
return sb.ToString();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Save()
|
|
|
|
public override void Save(string tvDataFile)
|
|
{
|
|
Save(tvDataFile, this.DataRoot);
|
|
this.FileName = tvDataFile;
|
|
}
|
|
|
|
public static void Save(string tvDataFile, DataRoot dataRoot)
|
|
{
|
|
using (var stream = new StreamWriter(tvDataFile))
|
|
{
|
|
Save(stream, dataRoot);
|
|
}
|
|
}
|
|
|
|
public static void Save(StreamWriter stream, DataRoot dataRoot)
|
|
{
|
|
foreach (var channelList in dataRoot.ChannelLists)
|
|
{
|
|
if (channelList.IsMixedSourceFavoritesList) // these pseudo-lists would create dupes for all channels
|
|
continue;
|
|
|
|
foreach (var channel in channelList.GetChannelsByNewOrder())
|
|
{
|
|
if (channel.NewProgramNr == -1)
|
|
continue;
|
|
var line = string.Format("{0},{1},{2},{3},\"{4}\",{5},{6}",
|
|
"", // past: channel.RecordIndex,
|
|
channel.NewProgramNr,
|
|
"", // past: channel.TransportStreamId,
|
|
channel.Uid,
|
|
channel.Name,
|
|
EncodeSignalSource(channel.SignalSource),
|
|
EncodeFavoritesAndFlags(channel));
|
|
stream.WriteLine(line);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |