MediaPortal.cs
author StephaneLenclud
Thu, 04 Oct 2018 19:25:35 +0200
changeset 8 adff2dec03a0
parent 5 29ccfbf98e54
permissions -rw-r--r--
Fixing broken KingOfSat parser.
StephaneLenclud@2
     1
using System;
StephaneLenclud@2
     2
using System.Collections.Generic;
StephaneLenclud@2
     3
using System.Diagnostics;
StephaneLenclud@2
     4
using System.Linq;
StephaneLenclud@2
     5
using System.Text;
StephaneLenclud@2
     6
using System.Threading.Tasks;
StephaneLenclud@2
     7
using System.Xml;
StephaneLenclud@5
     8
using System.IO;
StephaneLenclud@2
     9
StephaneLenclud@2
    10
namespace SatChanGen
StephaneLenclud@2
    11
{
StephaneLenclud@2
    12
	class MediaPortal
StephaneLenclud@2
    13
	{
StephaneLenclud@2
    14
StephaneLenclud@2
    15
		public static string Polarisation(Channel aChannel)
StephaneLenclud@2
    16
		{
StephaneLenclud@2
    17
			switch (aChannel.Polarisation)
StephaneLenclud@2
    18
			{
StephaneLenclud@2
    19
				case "H":
StephaneLenclud@2
    20
					return "1";
StephaneLenclud@2
    21
				case "V":
StephaneLenclud@2
    22
					return "2";
StephaneLenclud@2
    23
				case "L": //Check that on KingOfSat
StephaneLenclud@2
    24
					return "3";
StephaneLenclud@2
    25
				case "R": //Check that on KingOfSat
StephaneLenclud@2
    26
					return "4";
StephaneLenclud@2
    27
StephaneLenclud@2
    28
				default:
StephaneLenclud@2
    29
					{
StephaneLenclud@2
    30
						Debug.Write("WARNING: Unknown Polarisation " + aChannel.Polarisation + " for " + aChannel.Name + "\n");
StephaneLenclud@2
    31
						return "-1";
StephaneLenclud@2
    32
					}
StephaneLenclud@2
    33
			}
StephaneLenclud@2
    34
StephaneLenclud@2
    35
			/*
StephaneLenclud@2
    36
			"Not Set",
StephaneLenclud@2
    37
            "Not Defined",
StephaneLenclud@2
    38
            "Horizontal",
StephaneLenclud@2
    39
            "Vertical",
StephaneLenclud@2
    40
            "Circular Left",
StephaneLenclud@2
    41
            "Circular Right"
StephaneLenclud@2
    42
			 */
StephaneLenclud@2
    43
		}
StephaneLenclud@2
    44
StephaneLenclud@2
    45
		public static string Modulation(Channel aChannel)
StephaneLenclud@2
    46
		{
StephaneLenclud@2
    47
			//Those can be worked out from TvLibrary FormDVBSTuningDetail.Designer.cs
StephaneLenclud@2
    48
StephaneLenclud@2
    49
			switch (aChannel.Modulation)
StephaneLenclud@2
    50
			{
StephaneLenclud@2
    51
				case "QPSK":
StephaneLenclud@2
    52
					return "20";
StephaneLenclud@2
    53
				case "8PSK":
StephaneLenclud@2
    54
					return "27";
StephaneLenclud@2
    55
				default:
StephaneLenclud@2
    56
				{
StephaneLenclud@2
    57
					Debug.Write("WARNING: Unknown modulation " + aChannel.Modulation + " for " + aChannel.Name + "\n");
StephaneLenclud@2
    58
					return "-1";
StephaneLenclud@2
    59
				}
StephaneLenclud@2
    60
			}
StephaneLenclud@2
    61
StephaneLenclud@2
    62
StephaneLenclud@2
    63
			/*
StephaneLenclud@2
    64
			"Not Set",
StephaneLenclud@2
    65
			"Not Defined",
StephaneLenclud@2
    66
			"16 QAM",
StephaneLenclud@2
    67
			"32 QAM",
StephaneLenclud@2
    68
			"64 QAM",
StephaneLenclud@2
    69
			"80 QAM",
StephaneLenclud@2
    70
			"96 QAM",
StephaneLenclud@2
    71
			"112 QAM",
StephaneLenclud@2
    72
			"128 QAM",
StephaneLenclud@2
    73
			"160 QAM",
StephaneLenclud@2
    74
			"192 QAM",
StephaneLenclud@2
    75
			"224 QAM",
StephaneLenclud@2
    76
			"256 QAM",
StephaneLenclud@2
    77
			"320 QAM",
StephaneLenclud@2
    78
			"384 QAM",
StephaneLenclud@2
    79
			"448 QAM",
StephaneLenclud@2
    80
			"512 QAM",
StephaneLenclud@2
    81
			"640 QAM",
StephaneLenclud@2
    82
			"768 QAM",
StephaneLenclud@2
    83
			"896 QAM",
StephaneLenclud@2
    84
			"1024 QAM",
StephaneLenclud@2
    85
			"QPSK",
StephaneLenclud@2
    86
			"BPSK",
StephaneLenclud@2
    87
			"OQPSK",
StephaneLenclud@2
    88
			"8 VSB",
StephaneLenclud@2
    89
			"16 VSB",
StephaneLenclud@2
    90
			"Analog Amplitude",
StephaneLenclud@2
    91
			"Analog Frequency",
StephaneLenclud@2
    92
			"8 PSK",
StephaneLenclud@2
    93
			"RF",
StephaneLenclud@2
    94
			"16 APSK",
StephaneLenclud@2
    95
			"32 APSK",
StephaneLenclud@2
    96
			"QPSK2 (DVB-S2)",
StephaneLenclud@2
    97
			"8 PSK2 (DVB-S2)",
StephaneLenclud@2
    98
			"DirectTV"
StephaneLenclud@2
    99
			 */
StephaneLenclud@2
   100
		}
StephaneLenclud@2
   101
StephaneLenclud@2
   102
StephaneLenclud@2
   103
		public static string FEC(Channel aChannel)
StephaneLenclud@2
   104
		{
StephaneLenclud@2
   105
			//Those can be worked out from TvLibrary FormDVBSTuningDetail.Designer.cs
StephaneLenclud@2
   106
StephaneLenclud@2
   107
			switch (aChannel.FEC)
StephaneLenclud@2
   108
			{
StephaneLenclud@2
   109
				case "1/2":
StephaneLenclud@2
   110
					return "1";
StephaneLenclud@2
   111
				case "2/3":
StephaneLenclud@2
   112
					return "2";
StephaneLenclud@2
   113
				case "3/4":
StephaneLenclud@2
   114
					return "3";
StephaneLenclud@2
   115
				case "3/5":
StephaneLenclud@2
   116
					return "4";
StephaneLenclud@2
   117
				case "4/5":
StephaneLenclud@2
   118
					return "5";
StephaneLenclud@2
   119
				case "5/6":
StephaneLenclud@2
   120
					return "6";
StephaneLenclud@2
   121
				case "5/11":
StephaneLenclud@2
   122
					return "7";
StephaneLenclud@2
   123
				case "7/8":
StephaneLenclud@2
   124
					return "8";
StephaneLenclud@2
   125
				case "1/4":
StephaneLenclud@2
   126
					return "9";
StephaneLenclud@2
   127
				case "1/3":
StephaneLenclud@2
   128
					return "10";
StephaneLenclud@2
   129
				case "2/5":
StephaneLenclud@2
   130
					return "11";
StephaneLenclud@2
   131
				case "6/7":
StephaneLenclud@2
   132
					return "12";
StephaneLenclud@2
   133
				case "8/9":
StephaneLenclud@2
   134
					return "13";
StephaneLenclud@2
   135
				case "9/10":
StephaneLenclud@2
   136
					return "14";
StephaneLenclud@2
   137
StephaneLenclud@2
   138
				default:
StephaneLenclud@2
   139
				{
StephaneLenclud@2
   140
					Debug.Write("WARNING: Unknown FEC " + aChannel.FEC + " for " + aChannel.Name + "\n");
StephaneLenclud@2
   141
					return "-1";
StephaneLenclud@2
   142
				}
StephaneLenclud@2
   143
			}
StephaneLenclud@2
   144
StephaneLenclud@2
   145
StephaneLenclud@2
   146
		}
StephaneLenclud@2
   147
StephaneLenclud@5
   148
        //
StephaneLenclud@5
   149
        //
StephaneLenclud@5
   150
        //
StephaneLenclud@4
   151
		public static void Export(List<Channel> aChannels, List<string> aTunerCards,  string aFileName, bool aAddMapping)
StephaneLenclud@2
   152
		{
StephaneLenclud@5
   153
            //Create a dictionary for our groups
StephaneLenclud@5
   154
            Dictionary<string, List<Channel>> groups = new Dictionary<string, List<Channel>>();
StephaneLenclud@5
   155
StephaneLenclud@2
   156
			XmlDocument xmlDoc = new XmlDocument();
StephaneLenclud@5
   157
            XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null);
StephaneLenclud@5
   158
            xmlDoc.AppendChild(xmlDeclaration);
StephaneLenclud@5
   159
StephaneLenclud@2
   160
			XmlNode rootElement = xmlDoc.CreateElement("tvserver");			
StephaneLenclud@2
   161
			AddAttribute(rootElement, "version", "1.0");
StephaneLenclud@2
   162
			xmlDoc.AppendChild(rootElement);
StephaneLenclud@2
   163
			//Create our channel element
StephaneLenclud@2
   164
			XmlNode nodechannels = xmlDoc.CreateElement("channels");			
StephaneLenclud@2
   165
			rootElement.AppendChild(nodechannels);
StephaneLenclud@2
   166
StephaneLenclud@2
   167
			int channelId = 0;
StephaneLenclud@5
   168
            int channelMapId = 0;
StephaneLenclud@2
   169
			foreach (Channel channel in aChannels)
StephaneLenclud@2
   170
			{
StephaneLenclud@5
   171
                //Create group if needed
StephaneLenclud@5
   172
                if (!groups.ContainsKey(channel.Category)) 
StephaneLenclud@5
   173
                {
StephaneLenclud@5
   174
                    //KeyValuePair<string, List<Channel>> entry=new KeyValuePair<string, List<Channel>>();
StephaneLenclud@5
   175
                    groups.Add(channel.Category, new List<Channel>());
StephaneLenclud@5
   176
                }
StephaneLenclud@5
   177
StephaneLenclud@5
   178
                //Add that channel to its group
StephaneLenclud@5
   179
                groups[channel.Category].Add(channel);
StephaneLenclud@5
   180
StephaneLenclud@5
   181
                //Create and populate channel element
StephaneLenclud@2
   182
				channelId++;
StephaneLenclud@2
   183
				XmlNode nodechannel = xmlDoc.CreateElement("channel");
StephaneLenclud@2
   184
				AddAttribute(nodechannel, "GrabEpg", "True");
StephaneLenclud@2
   185
				AddAttribute(nodechannel, "IdChannel", channelId);
StephaneLenclud@2
   186
				AddAttribute(nodechannel, "IsRadio", "False");
StephaneLenclud@2
   187
				AddAttribute(nodechannel, "IsTv", "True");
StephaneLenclud@5
   188
                AddAttribute(nodechannel, "LastGrabTime", "2000-1-1 0:0:0");
StephaneLenclud@2
   189
				//AddAttribute(nodechannel, "SortOrder", channel.SortOrder);
StephaneLenclud@5
   190
                //AddAttribute(nodechannel, "TimesWatched", "0");
StephaneLenclud@5
   191
                AddAttribute(nodechannel, "TotalTimeWatched", "2000-1-1 0:0:0");
StephaneLenclud@7
   192
                AddAttribute(nodechannel, "VisibleInGuide", !channel.Name.StartsWith("."));
StephaneLenclud@2
   193
				AddAttribute(nodechannel, "DisplayName", channel.Name);
StephaneLenclud@2
   194
				AddAttribute(nodechannel, "ChannelNumber", channelId);
StephaneLenclud@2
   195
StephaneLenclud@5
   196
                if (aAddMapping)
StephaneLenclud@5
   197
                {
StephaneLenclud@5
   198
                    //I don't think we can get mapping to work without having corresponding server and card definition elements
StephaneLenclud@5
   199
                    XmlNode nodeMaps = xmlDoc.CreateElement("mappings");
StephaneLenclud@5
   200
                    foreach (string tuner in aTunerCards)
StephaneLenclud@5
   201
                    {
StephaneLenclud@5
   202
                        channelMapId++;
StephaneLenclud@5
   203
                        XmlNode nodeMap = xmlDoc.CreateElement("map");
StephaneLenclud@5
   204
                        AddAttribute(nodeMap, "IdCard", tuner);
StephaneLenclud@5
   205
                        AddAttribute(nodeMap, "IdChannel", channelId);
StephaneLenclud@5
   206
                        AddAttribute(nodeMap, "IdChannelMap", channelMapId);
StephaneLenclud@5
   207
                        nodeMaps.AppendChild(nodeMap);
StephaneLenclud@5
   208
                    }
StephaneLenclud@5
   209
                    nodechannel.AppendChild(nodeMaps);
StephaneLenclud@5
   210
                }
StephaneLenclud@2
   211
StephaneLenclud@2
   212
				XmlNode nodeTuningDetails = xmlDoc.CreateElement("TuningDetails");
StephaneLenclud@2
   213
				XmlNode nodeTune = xmlDoc.CreateElement("tune");
StephaneLenclud@2
   214
				AddAttribute(nodeTune, "IdChannel", channelId);
StephaneLenclud@2
   215
				AddAttribute(nodeTune, "IdTuning", channelId);
StephaneLenclud@2
   216
				AddAttribute(nodeTune, "Bandwidth", "8"); //Weird
StephaneLenclud@2
   217
				AddAttribute(nodeTune, "ChannelNumber", "10000");
StephaneLenclud@2
   218
				AddAttribute(nodeTune, "ChannelType", "3"); //Bad hard coding, does it means DVB-S
StephaneLenclud@2
   219
				AddAttribute(nodeTune, "CountryId", "31"); //Is that Germany?
StephaneLenclud@2
   220
				AddAttribute(nodeTune, "Diseqc", "0"); //Disabled
StephaneLenclud@2
   221
				AddAttribute(nodeTune, "FreeToAir", "False"); //Can we get that from KingOfSat? Does it matter?
StephaneLenclud@2
   222
				AddAttribute(nodeTune, "Frequency", ((Int32)(Convert.ToDouble(channel.Frequency)*1000)).ToString());
StephaneLenclud@2
   223
				AddAttribute(nodeTune, "MajorChannel", "-1");
StephaneLenclud@2
   224
				AddAttribute(nodeTune, "MinorChannel", "-1");
StephaneLenclud@2
   225
				AddAttribute(nodeTune, "Modulation", Modulation(channel));
StephaneLenclud@2
   226
				AddAttribute(nodeTune, "Name", channel.Name);
StephaneLenclud@2
   227
				AddAttribute(nodeTune, "NetworkId", channel.NetworkID);
StephaneLenclud@2
   228
				AddAttribute(nodeTune, "PmtPid", channel.PMT);
StephaneLenclud@2
   229
				AddAttribute(nodeTune, "Polarisation", Polarisation(channel));
StephaneLenclud@2
   230
				AddAttribute(nodeTune, "Provider", channel.Provider); //Does that matter? Should really be SKY or CSAT
StephaneLenclud@2
   231
				AddAttribute(nodeTune, "ServiceId", channel.SID);
StephaneLenclud@2
   232
				AddAttribute(nodeTune, "SwitchingFrequency", "11700000"); //Does it matter?
StephaneLenclud@2
   233
				AddAttribute(nodeTune, "Symbolrate", channel.SymbolRate);
StephaneLenclud@2
   234
				AddAttribute(nodeTune, "TransportId", channel.TransponderID);
StephaneLenclud@2
   235
				AddAttribute(nodeTune, "TuningSource", "0"); //Is that needed?
StephaneLenclud@2
   236
				AddAttribute(nodeTune, "VideoSource", "0"); //Is that needed?
StephaneLenclud@2
   237
				AddAttribute(nodeTune, "AudioSource", "0"); //Is that needed?
StephaneLenclud@2
   238
				AddAttribute(nodeTune, "IsVCRSignal", "False");
StephaneLenclud@2
   239
				AddAttribute(nodeTune, "SatIndex", "-1");
StephaneLenclud@2
   240
				AddAttribute(nodeTune, "InnerFecRate", FEC(channel));
StephaneLenclud@2
   241
				AddAttribute(nodeTune, "Band", "0"); //Needed?
StephaneLenclud@2
   242
				AddAttribute(nodeTune, "Pilot", "-1");
StephaneLenclud@2
   243
				AddAttribute(nodeTune, "RollOff", "-1");
StephaneLenclud@2
   244
				AddAttribute(nodeTune, "Url", "");
StephaneLenclud@2
   245
				AddAttribute(nodeTune, "Bitrate", "0"); //Should we bother putting it in there?
StephaneLenclud@2
   246
				nodeTuningDetails.AppendChild(nodeTune);
StephaneLenclud@2
   247
					
StephaneLenclud@2
   248
				nodechannel.AppendChild(nodeTuningDetails);
StephaneLenclud@2
   249
StephaneLenclud@2
   250
				nodechannels.AppendChild(nodechannel);				
StephaneLenclud@2
   251
			}
StephaneLenclud@2
   252
StephaneLenclud@5
   253
            //Create groups element
StephaneLenclud@5
   254
            XmlNode nodeChannelGroups = xmlDoc.CreateElement("channelgroups");
StephaneLenclud@5
   255
            rootElement.AppendChild(nodeChannelGroups);
StephaneLenclud@2
   256
StephaneLenclud@5
   257
            int groupSortOrder = 0;
StephaneLenclud@5
   258
            foreach (KeyValuePair<string, List<Channel>> group in groups)
StephaneLenclud@5
   259
            {
StephaneLenclud@5
   260
                //Create group element
StephaneLenclud@5
   261
                XmlNode nodeChannelGroup = xmlDoc.CreateElement("channelgroup");
StephaneLenclud@5
   262
                AddAttribute(nodeChannelGroup, "GroupName", group.Key);
StephaneLenclud@5
   263
                AddAttribute(nodeChannelGroup, "SortOrder", groupSortOrder.ToString());
StephaneLenclud@5
   264
                XmlNode nodeGroupMap = xmlDoc.CreateElement("mappings");
StephaneLenclud@5
   265
                nodeChannelGroup.AppendChild(nodeGroupMap);
StephaneLenclud@5
   266
                nodeChannelGroups.AppendChild(nodeChannelGroup);
StephaneLenclud@2
   267
StephaneLenclud@5
   268
                //Sort by name
StephaneLenclud@5
   269
                List<Channel> sortedChannels = group.Value.OrderBy(o => o.Name).ToList();
StephaneLenclud@5
   270
StephaneLenclud@5
   271
                //Add each channel to its group
StephaneLenclud@5
   272
                int channelSortOrder = 0;
StephaneLenclud@5
   273
                foreach (Channel channel in sortedChannels)
StephaneLenclud@5
   274
                {
StephaneLenclud@5
   275
                    XmlNode nodeMap = xmlDoc.CreateElement("map");
StephaneLenclud@5
   276
                    AddAttribute(nodeMap, "ChannelName", channel.Name);
StephaneLenclud@5
   277
                    AddAttribute(nodeMap, "SortOrder", channelSortOrder.ToString());
StephaneLenclud@5
   278
                    nodeGroupMap.AppendChild(nodeMap);
StephaneLenclud@5
   279
                    channelSortOrder++;
StephaneLenclud@5
   280
                }
StephaneLenclud@5
   281
StephaneLenclud@5
   282
                groupSortOrder++;
StephaneLenclud@5
   283
            }
StephaneLenclud@5
   284
StephaneLenclud@5
   285
            using (TextWriter sw = new StreamWriter(aFileName, false, Encoding.UTF8)) //Set encoding
StephaneLenclud@5
   286
            {
StephaneLenclud@5
   287
                xmlDoc.Save(sw);
StephaneLenclud@5
   288
            }
StephaneLenclud@5
   289
			//xmlDoc.Save(aFileName);
StephaneLenclud@2
   290
		}
StephaneLenclud@2
   291
StephaneLenclud@2
   292
		private static void AddAttribute(XmlNode node, string tagName, string tagValue)
StephaneLenclud@2
   293
		{
StephaneLenclud@2
   294
			XmlAttribute attr = node.OwnerDocument.CreateAttribute(tagName);
StephaneLenclud@2
   295
			attr.InnerText = tagValue;
StephaneLenclud@2
   296
			node.Attributes.Append(attr);
StephaneLenclud@2
   297
		}
StephaneLenclud@2
   298
StephaneLenclud@2
   299
		private static void AddAttribute(XmlNode node, string tagName, int tagValue)
StephaneLenclud@2
   300
		{
StephaneLenclud@2
   301
			AddAttribute(node, tagName, tagValue.ToString());
StephaneLenclud@2
   302
		}
StephaneLenclud@2
   303
StephaneLenclud@2
   304
		// store DateTime Values as strings. Improves readability
StephaneLenclud@2
   305
		private static void AddAttribute(XmlNode node, string tagName, DateTime tagValue)
StephaneLenclud@2
   306
		{
StephaneLenclud@2
   307
			AddAttribute(node, tagName,
StephaneLenclud@2
   308
						 String.Format("{0}-{1}-{2} {3}:{4}:{5}", tagValue.Year, tagValue.Month, tagValue.Day, tagValue.Hour,
StephaneLenclud@2
   309
									   tagValue.Minute, tagValue.Second));
StephaneLenclud@2
   310
		}
StephaneLenclud@2
   311
StephaneLenclud@2
   312
		private static void AddAttribute(XmlNode node, string tagName, bool tagValue)
StephaneLenclud@2
   313
		{
StephaneLenclud@2
   314
			AddAttribute(node, tagName, tagValue.ToString());
StephaneLenclud@2
   315
		}
StephaneLenclud@2
   316
	}
StephaneLenclud@2
   317
}