/// <summary> /// Refreshes the EPG. /// </summary> /// <param name="state">The state.</param> protected void RefreshEPG(object state) { EpgImportResult results = new EpgImportResult(); Thread.CurrentThread.Name = Name; Thread.CurrentThread.Priority = ThreadPriority.Lowest; Thread.CurrentThread.IsBackground = true; Log.WriteFile("Starting EPG refresh job on thread #{0}", Thread.CurrentThread.ManagedThreadId); Log.WriteFile("UTC time is {0}, local time is {1} (DST is {2})", DateTime.Now.ToUniversalTime(), DateTime.Now.ToLocalTime(), DateTime.Now.IsDaylightSavingTime()); Log.WriteFile("Rename Existing Channels is set to: {0}, with Template: {1}.", PluginSettings.RenameExistingChannels.ToString(), PluginSettings.ChannelNameTemplate); Log.WriteFile("Add New Digital Channels is set to: {0}, with External Input: {1}.", PluginSettings.AddNewChannels.ToString(), PluginSettings.ExternalInput.ToString()); Log.WriteFile("Add New Digital Channels Country is set to: {0}.", PluginSettings.ExternalInputCountry.ToString()); Log.WriteFile("Add New Analog Channels is set to: {0}, with External Input: {1}.", PluginSettings.AddAnalogChannels.ToString(), PluginSettings.ExternalInput.ToString()); Log.WriteFile("Channel Sorting is set to: {0}.", PluginSettings.SortChannelsByNumber.ToString()); Log.WriteFile("Allow Channel Matching without Frequency is set to: {0}.", PluginSettings.AllowChannelNumberOnlyMapping.ToString()); Log.WriteFile("Delete Channels with No EPG Mapping is set to: {0}.", PluginSettings.DeleteChannelsWithNoEPGMapping.ToString()); if (string.IsNullOrEmpty(PluginSettings.Username) || string.IsNullOrEmpty(PluginSettings.Password)) { Log.WriteFile(MSG_BAD_USERNAME); Log.WriteFile("-Username: "******" -Password: "******"http://webservices.schedulesdirect.tmsdatadirect.com")) { Log.WriteFile("Not connected to Internet or unable to connect to the WebService at this time, skipping update"); ScheduleNextRetrievalTime(false); NotifyPopUp(MSG_NO_INTERNET); return; } // Import initiator try { PrepareForEpgImport(); results = RunEpgImport(); FinalizeEpgImport(results); } catch (System.Net.WebException ex) { Log.WriteFile(ex.ToString()); RollbackEpgImport(); // Check to see if we failed because our login information was incorrect System.Net.HttpWebResponse httpWebResponse = ex.Response as System.Net.HttpWebResponse; if (httpWebResponse != null && httpWebResponse.StatusCode == System.Net.HttpStatusCode.Unauthorized) { Notify(MSG_ACCESS_DENIED); } else if (httpWebResponse != null && httpWebResponse.StatusCode == System.Net.HttpStatusCode.NotFound) { Notify(MSG_WEBSVC_NOCONN); } } catch (InvalidOperationException ex) { // This means the user has no lineup or their subscription is expired Log.WriteFile(ex.ToString()); RollbackEpgImport(); Notify(MSG_NO_LINEUP); } catch (Exception ex) { Log.WriteFile(ex.ToString()); RollbackEpgImport(); } finally { ScheduleNextRetrievalTime(); } // Check if we managed to process any channels, if not, this probably means they didn't do an autotune if (results.ChannelsProcessed == 0) { Notify(MSG_NO_CHANNELS); } // Check for subscription expiration and notify user. You cannot renew until 7 days before expiration. // Once it has expired, we'll not be able to connect to download listings TimeSpan expires = (results.SubscriptionExpiration - DateTime.Now); if (expires.Days >= 0 && expires.Days < 7) { Notify(MSG_EXPIRES, expires.Days); } else if (PluginSettings.NotifyOnCompletion && results.ChannelsProcessed > 0 && GetLastProgramEntry() > DateTime.Now) { NotifyPopUp(MSG_EPG_UPDATED, GetLastProgramEntry()); } }
/// <summary> /// Runs the epg import. /// </summary> /// <returns>DateTime of the subscription expiration</returns> protected EpgImportResult RunEpgImport() { int UPDATE_HOURS = PluginSettings.LastMinuteGuideHours; // 24; SchedulesDirect.SoapEntities.DownloadResults listingData; EpgImportResult result = new EpgImportResult(); DateTime lastDbEntry; DateTime startDate; DateTime endDate; string channelHash; int programCount; bool lineupHasChanged = false; // Get the end time of the latest program entry in the Epg before we start any imports lastDbEntry = GetLastProgramEntry(); using (SchedulesDirect.SchedulesDirectWebService webService = new SchedulesDirect.SchedulesDirectWebService(PluginSettings.Username, PluginSettings.Password)) { #region Update Epg with next 24 hours worth of data for last minute changes startDate = DateTime.Now; endDate = startDate.AddHours(UPDATE_HOURS); Log.WriteFile("Requesting {0} hours of program listings from [{1}] to [{2}]", UPDATE_HOURS, startDate, endDate); // The Using is sometimes covering the WebException, so handle it here try { listingData = webService.Download(startDate, endDate); result.SubscriptionExpiration = listingData.SubscriptionExpiration; result.Messages = listingData.Messages; result.UpdateRequired = false; } catch (System.Net.WebException ex) { CheckWebException(ex, true); return result; } catch (Exception ex) { Log.WriteFile("WARNING: Appears there is a problem with the WebService, {0} Inner: {1}", ex.ToString(), ex.InnerException.ToString()); return result; } if (listingData.Data.Stations == null) { Log.WriteFile("WARNING: Skipping schedule import, appears there is a problem with the WebService"); return result; } // Determine if there have been any changes in the SchedulesDirect channel lineup channelHash = GetStationsHash(listingData.Data.Stations); if (!PluginSettings.ChannelFingerprint.Equals(channelHash)) lineupHasChanged = true; // Log any messages sent by SchedulesDirect to us foreach (string msg in listingData.Messages) Log.WriteFile("schedulesdirect msg: {0}", msg); // If debug mode is enabled, write the data to disk for analysis if (PluginSettings.DebugMode) WriteXTVD(listingData.Data, String.Format(@"{0}\MediaPortal TV Server\schedulesdirectupdate.xml", Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData))); //WriteXTVD(listingData.Data, @"log\schedulesdirectupdate.xml"); // Instantiate an EPG listing importer to do the actual import work using (Import.EpgListingsImporter epgListingsImporter = new Import.EpgListingsImporter(listingData)) { epgListingsImporter.ChannelNameTemplate = PluginSettings.ChannelNameTemplate; epgListingsImporter.CreateChannels = PluginSettings.AddNewChannels; epgListingsImporter.RenameChannels = PluginSettings.RenameExistingChannels; epgListingsImporter.AllowChannelNumberOnlyMapping = PluginSettings.AllowChannelNumberOnlyMapping; epgListingsImporter.ExternalInputCountry = PluginSettings.ExternalInputCountry; epgListingsImporter.ExternalInput = PluginSettings.ExternalInput; epgListingsImporter.AllowChannelSorting = PluginSettings.SortChannelsByNumber; epgListingsImporter.CreateAnalogChannels = PluginSettings.AddAnalogChannels; epgListingsImporter.RemapChannelsOnLineupChange = PluginSettings.RemapChannelsOnLineupChange; epgListingsImporter.AddExtraInformationToShowDescription = PluginSettings.AddExtraDataToShowDescription; epgListingsImporter.LineupHasChanged = lineupHasChanged; epgListingsImporter.Delay = 10; result.ChannelsProcessed = epgListingsImporter.ImportChannels(); Log.WriteFile("Sucessfully processed {0} of {1} channels", result.ChannelsProcessed, listingData.Data.Stations.List.Count); if (result.ChannelsProcessed == 0) { Log.WriteFile("WARNING: Skipping schedule import (no channels sucessfully processed)"); return result; } else { programCount = epgListingsImporter.ImportPrograms(); Log.WriteFile("Sucessfully Imported {0} of {1} schedule entries", programCount, listingData.Data.Schedules.List.Count); } } #endregion #region Full Epg update // Determine if there have been any changes in the Schedules Direct channel lineup //channelHash = GetStationsHash(listingData.Data.Stations); if (!lineupHasChanged) { Log.WriteFile("No changes detected in Schedules Direct channel lineup"); // Set start of full grab to the end of the first grab or the midnight of the last epg program in db if later startDate = (lastDbEntry.Date > endDate ? lastDbEntry.Date : endDate); } else { Log.WriteFile("Detected a change in Schedules Direct channel lineup fingerprint, resetting start date"); PluginSettings.ChannelFingerprint = channelHash; startDate = endDate; // Set the start date to the previous end update end date (e.g. 24 hours from now) } // Add user selected number of GuideDays to midnight today to get the desired end date endDate = DateTime.Now.Date.AddDays(PluginSettings.GuideDays); // endDate could have been set to < startDate if getting only 1 day of data if (endDate < startDate) { endDate = startDate.Date.AddDays((double)1); } // Check to see if we already have enough data in the EPG without asking for more. This could happen if // the user changes the config to ask for less days or if other import mechanisms have been used. if ((endDate < lastDbEntry) && !lineupHasChanged) { Log.WriteFile("Already have enough guide data, skipping data request"); return result; } // Download program listings // The Using is sometimes covering the WebException, so handle it here try { Log.WriteFile("Requesting program listings from [{0}] to [{1}]", startDate, endDate); listingData = webService.Download(startDate, endDate); } catch (System.Net.WebException ex) { CheckWebException(ex, true); return result; } catch (Exception ex) { Log.WriteFile("WARNING: Appears there is a problem with the WebService, {0} Inner: {1}", ex.ToString(), ex.InnerException.ToString()); return result; } // Log any messages sent by Schedules Direct foreach (string msg in listingData.Messages) Log.WriteFile("Schedules Direct message: {0}", msg); // If debug mode is enabled, write the data to disk for analysis if (PluginSettings.DebugMode) WriteXTVD(listingData.Data, String.Format(@"{0}\MediaPortal TV Server\SchedulesDirect.xml", Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData))); //WriteXTVD(listingData.Data, @"log\SchedulesDirect.xml"); using (Import.EpgListingsImporter epgListingsImporter = new Import.EpgListingsImporter(listingData)) { epgListingsImporter.Delay = 10; epgListingsImporter.CreateChannels = PluginSettings.AddNewChannels; programCount = epgListingsImporter.ImportPrograms(); Log.WriteFile("Imported {0} of {1} schedule entries", programCount, listingData.Data.Schedules.List.Count); Log.WriteFile("Last program entry in database was {0}, now {1}", lastDbEntry, GetLastProgramEntry()); } #endregion result.StartOfUpdateRange = startDate; result.EndOfUpdateRange = endDate; result.UpdateRequired = true; return result; } }
/// <summary> /// Finalizes the EPG import by /// commiting the database transaction /// removing overlapping programs /// enabling event generation /// notifyng the user of sucess or subscription expiration /// </summary> protected void FinalizeEpgImport(EpgImportResult results) { //Log.WriteFile("Removing any overlapping programs"); //RemoveOverLappingPrograms(); //TVDatabase.RemoveOverlappingPrograms(); // Remove Channels with no EPG Mapping? if (PluginSettings.DeleteChannelsWithNoEPGMapping) { Log.WriteFile("Checking for channels with no EPG mapping to delete"); int rnbr = RemoveChannelsWithNoEPGMapping(); Log.WriteFile("Channels with no EPG Mapping Removed: {0}", rnbr); } //Log.WriteFile("Removing any Overlapping programs"); //RemoveOverLappingPrograms(); //Log.WriteFile("Check for Overlapping programs completed"); // TODO: This does not work as expected, but is much faster // Try to determine another way. //const int UPDATE_HOURS = 24; //Log.WriteFile("Checking for Overlapping programs in the next {0} hours of program listings", UPDATE_HOURS); //// Always check the next 24 hours for overlaps //RemoveOverLappingPrograms(DateTime.Now, DateTime.Now.AddHours(UPDATE_HOURS)); //if (results.UpdateRequired) //{ // Log.WriteFile("Checking for overlapping programs from [{0}] to [{1}]", results.StartOfUpdateRange, results.EndOfUpdateRange); // RemoveOverLappingPrograms(results.StartOfUpdateRange, results.EndOfUpdateRange); //} //Log.WriteFile("Committing the transaction"); //TVDatabase.CommitTransaction(); //TVDatabase.RemoveOverlappingPrograms(); //TVDatabase.SupressEvents = false; // Reload the Television EPG //MediaPortal.GUI.TV.GUITVHome.Navigator.ReLoad(); }