/// <summary> /// Finds the TV channel. /// </summary> /// <param name="station">The station.</param> /// <param name="map">The map.</param> /// <returns>TVChannel found or null</returns> protected Channel FindTVChannel(SchedulesDirect.SoapEntities.TVStation station, SchedulesDirect.SoapEntities.TVStationMap map, bool LineupIsLocalBroadcast) { string strTvChannel; int idTvChannel; /* Log.WriteFile("Attempting Channel Find/Match for: Callsign: {0}, Map Channel: {1}, Map Major {2}, Map Minor: {3}, Map StationID: {4} ", station.CallSign, map.Channel, map.ChannelMajor, map.ChannelMinor, map.StationId); */ string xmlTvId = BuildXmlTvId(LineupIsLocalBroadcast, station, map); #region Check if the channel is already in EPG mapping database //Log.WriteFile("GetEPGMapping: {0} for {1}", station.Name, station.ID + XMLTVID); if (GetEPGMapping(xmlTvId, out idTvChannel, out strTvChannel)) { Log.WriteFile("Channel {0} was found as {1} in EPG mapping database", station.Name, strTvChannel); FixDigitalTerrestrialChannelMap(idTvChannel, station, ref map); return Channel.Retrieve(idTvChannel); } #endregion #region Try locating the channel by callsign //Log.WriteFile("GetChannelByName: {0}", station.CallSign); if (GetChannelByName(station.CallSign, out idTvChannel) == true) { Channel mpChannel = Channel.Retrieve(idTvChannel); Log.WriteFile("Matched channel {0} to {1} using CallSign", station.CallSign, mpChannel.DisplayName); FixDigitalTerrestrialChannelMap(idTvChannel, station, ref map); return mpChannel; } #endregion #region Iterate through each channel looking for a match foreach (Channel mpChannel in _mpChannelCache) { // Get the TuningDetail for the Channel System.Collections.IList chDetailList = (System.Collections.IList)mpChannel.ReferringTuningDetail(); if (chDetailList.Count <= 0) continue; TuningDetail chDetail = (TuningDetail)chDetailList[0]; // Only look at non-mapped channels if (String.IsNullOrEmpty(mpChannel.ExternalId)) { // Check for an ATSC major/minor channel number match ATSCChannel atscChannel = new ATSCChannel(); if (LineupIsLocalBroadcast && GetATSCChannel(mpChannel, ref atscChannel)) { if (map.ChannelMajor == atscChannel.MajorChannel && map.ChannelMinor == atscChannel.MinorChannel) { Log.WriteFile("Matched channel {0} to {1} by ATSC channel ({2}-{3})", station.CallSign, mpChannel.DisplayName, atscChannel.MajorChannel, atscChannel.MinorChannel); return mpChannel; } } // If the Lineup is a LocalBroadcast we want to give preference to // searching by Broadcast Number // else give preference to the Major Channel Number else if (LineupIsLocalBroadcast && !station.IsDigitalTerrestrial) { // Not an ATSC channel so check for an over-the-air //(by checking it has a frequency) broadcast channel number match if (chDetail.ChannelNumber == station.BroadcastChannelNumber) { if (chDetail.Frequency != 0 || _allowChannelNumberMapping) { Log.WriteFile("Matched channel {0} to {1} by OTA broadcast channel ({2})", station.CallSign, chDetail.Name, chDetail.ChannelNumber); return mpChannel; } } } else if (!LineupIsLocalBroadcast) { // Check for an over-the-air (by checking it has a frequency) // major channel number match if (chDetail.ChannelNumber == map.ChannelMajor) { if (chDetail.Frequency != 0 || _allowChannelNumberMapping) { Log.WriteFile("Matched channel {0} to {1} by lineup channel ({2})", station.CallSign, chDetail.Name, chDetail.ChannelNumber); return mpChannel; } } } } } #endregion #region Check the UnMapped Channels if the lineup has changed foreach (Channel mpChannel in _mpUnMappedChannelCache) { string[] xIds = mpChannel.ExternalId.Split(new char[] { '.' }); string[] cIds = xmlTvId.Split(new char[] { '.' }); if (xIds[1].ToLower() == cIds[1].ToLower()) { _mpUnMappedChannelCache.Remove(mpChannel); return mpChannel; } } #endregion #region Iterate through each channel again looking @ MajorChannel Number even if it is a local broadcast foreach (Channel mpChannel in _mpChannelCache) { if (!String.IsNullOrEmpty(mpChannel.ExternalId)) continue; System.Collections.IList chDetailList = (System.Collections.IList)mpChannel.ReferringTuningDetail(); if (chDetailList.Count <= 0) continue; TuningDetail chDetail = (TuningDetail)chDetailList[0]; if (LineupIsLocalBroadcast && !station.IsDigitalTerrestrial && chDetail.Frequency != 0) { // Check for an over-the-air (by checking it has a frequency) major channel number match if (chDetail.ChannelNumber == map.ChannelMajor) { Log.WriteFile("Matched channel {0} to {1} by lineup channel ({2})", station.CallSign, chDetail.Name, chDetail.ChannelNumber); return mpChannel; } } else if (!LineupIsLocalBroadcast) { // Not an ATSC channel so check for an over-the-air (by checking it has a frequency) broadcast channel number match if (chDetail.ChannelNumber == station.BroadcastChannelNumber) { Log.WriteFile("Matched channel {0} to {1} by OTA broadcast channel ({2})", station.CallSign, chDetail.Name, chDetail.ChannelNumber); return mpChannel; } } } #endregion return null; }
/// <summary> /// Fills in the ATSCChannel detail from the provided TuningDetail. /// </summary> /// <param name="idTvChannel">The Channel Database ID</param> /// <param name="station">The station</param> /// <param name="map">The map</param> /// <returns>true if a fix was completed on the map.ChannelMajor and map.ChannelMinor else false</returns> protected bool FixDigitalTerrestrialChannelMap(int idTvChannel, SchedulesDirect.SoapEntities.TVStation station, ref SchedulesDirect.SoapEntities.TVStationMap map) { if (station.IsDigitalTerrestrial && map.ChannelMinor <= 0) { ATSCChannel atscEPGChannel = new ATSCChannel(); Channel mpChannel = Channel.Retrieve(idTvChannel); if (GetATSCChannel(mpChannel, ref atscEPGChannel)) { map.ChannelMajor = atscEPGChannel.MajorChannel; map.ChannelMinor = atscEPGChannel.MinorChannel; return true; } } return false; }
/// <summary> /// Creates a XmlTvId string using the SchedulesDirect ID + (BroadcastChannel or ChannelString) and the XMLTVID constant /// </summary> /// <param name="IsLocalBroadcast">True if the TVStation is a Local Broadcast</param> /// <param name="tvStation">The TVStation</param> /// <param name="tvStationMap">The TVStationMap</param> /// <returns></returns> protected string BuildXmlTvId(bool IsLocalBroadcast, SchedulesDirect.SoapEntities.TVStation tvStation, SchedulesDirect.SoapEntities.TVStationMap tvStationMap) { string xmlId = tvStation.ID; if (IsLocalBroadcast && tvStation.BroadcastChannelNumber > 0 && !tvStation.IsDigitalTerrestrial) xmlId += "." + tvStation.BroadcastChannelNumber.ToString() + XMLTVID; else xmlId += "." + tvStationMap.ChannelString + XMLTVID; return xmlId; }
/// <summary> /// Builds the name of the channel based on the template. /// </summary> /// <param name="tvStation">The tv station.</param> /// <param name="tvStationMap">The tv station map.</param> /// <returns></returns> protected string BuildChannelName(SchedulesDirect.SoapEntities.TVStation tvStation, SchedulesDirect.SoapEntities.TVStationMap tvStationMap) { string channelName = string.Empty; if (tvStation != null && tvStationMap != null) { channelName = this._channelNameTemplate.ToLower(System.Globalization.CultureInfo.CurrentCulture); channelName = channelName.Replace("{callsign}", tvStation.CallSign); channelName = channelName.Replace("{name}", tvStation.Name); channelName = channelName.Replace("{affiliate}", tvStation.Affiliate); channelName = channelName.Replace("{number}", tvStationMap.Channel); // debug //channelName = channelName + " BCNbr: " + tvStation.BroadcastChannelNumber.ToString(); //channelName = channelName + " CMajr: " + tvStationMap.ChannelMajor.ToString(); } return channelName; }
/// <summary> /// Initializes a new instance of the <see cref="T:EpgListingsImporter"/> class. /// </summary> /// <param name="results">The results.</param> public EpgListingsImporter(SchedulesDirect.SoapEntities.DownloadResults results) { this._results = results; }
/// <summary> /// Writes the Schedules Direct XML data structure to a file. /// </summary> /// <param name="listingData">The XTVD entity.</param> /// <param name="filename">The filename.</param> private static void WriteXTVD(SchedulesDirect.SoapEntities.XTVD listingData, string filename) { Log.WriteFile("Debug mode enabled - dumping data to SchedulesDirect.xml"); System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings(); settings.Indent = true; using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(filename, settings)) { listingData.WriteTo(writer); } }
/// <summary> /// Gets a MD5 hash for the collection of stations and returns as a Base64 string /// </summary> /// <param name="tvStations">The tv stations.</param> /// <returns>Base64 string</returns> protected static string GetStationsHash(SchedulesDirect.SoapEntities.TVStations tvStations) { // We create a string with all the ID values from the channels and return an base64 MD5 hash System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); StringBuilder sb = new StringBuilder(); tvStations.List.Sort(); // Sort the list so order changes will not effect the hash foreach (SchedulesDirect.SoapEntities.TVStation tvStation in tvStations.List) { sb.Append(tvStation.ID); } return Convert.ToBase64String(md5.ComputeHash(Encoding.Unicode.GetBytes(sb.ToString()))); }