예제 #1
0
        private static void DownloadImageResponses(int start = 0)
        {
            // reject 0 requests
            if (imageQueue.Count - start < 1)
            {
                return;
            }

            // build the array of series to request images for
            var series = new string[Math.Min(imageQueue.Count - start, MaxImgQueries)];

            for (var i = 0; i < series.Length; ++i)
            {
                series[i] = imageQueue[start + i];
            }

            // request images from Schedules Direct
            var responses = SdApi.GetArtwork(series);

            if (responses != null)
            {
                Parallel.ForEach(responses, (response) =>
                {
                    imageResponses.Add(response);
                });
            }
        }
예제 #2
0
        public frmLineups()
        {
            InitializeComponent();

            // get current lineups
            _oldLineups = SdApi.GetSubscribedLineups();
            if (_oldLineups?.Lineups == null || (_oldLineups.Lineups.Count == 0))
            {
                return;
            }

            // populate listview with current lineups
            foreach (var lineup in _oldLineups.Lineups)
            {
                listView1.Items.Add(new ListViewItem(new[] { lineup.Transport, lineup.Name, lineup.Location, lineup.Lineup })
                {
                    Tag         = lineup.Lineup,
                    ToolTipText = lineup.Lineup
                });
            }

            // adjust components for screen dpi
            using (var g = CreateGraphics())
            {
                if ((int)g.DpiX == 96 && (int)g.DpiY == 96)
                {
                    return;
                }
                // adjust column widths for list views
                foreach (ColumnHeader column in listView1.Columns)
                {
                    column.Width = (int)(column.Width * g.DpiX / 96) - 1;
                }
            }
        }
예제 #3
0
        private static void DownloadGenericSeriesDescriptions(int start = 0)
        {
            // reject 0 requests
            if (seriesDescriptionQueue.Count - start < 1)
            {
                return;
            }

            // build the array of series to request descriptions for
            var series = new string[Math.Min(seriesDescriptionQueue.Count - start, MaxImgQueries)];

            for (var i = 0; i < series.Length; ++i)
            {
                series[i] = seriesDescriptionQueue[start + i];
            }

            // request descriptions from Schedules Direct
            var responses = SdApi.GetGenericDescriptions(series);

            if (responses != null)
            {
                Parallel.ForEach(responses, (response) =>
                {
                    seriesDescriptionResponses.TryAdd(response.Key, response.Value);
                });
            }
        }
예제 #4
0
        private static void DownloadProgramResponses(int start)
        {
            // reject 0 requests
            if (programQueue.Count - start < 1)
            {
                return;
            }

            // build the array of programs to request for
            var programs = new string[Math.Min(programQueue.Count - start, MaxQueries)];

            for (var i = 0; i < programs.Length; ++i)
            {
                programs[i] = programQueue[start + i];
            }

            // request programs from Schedules Direct
            var responses = SdApi.GetPrograms(programs);

            if (responses != null)
            {
                Parallel.ForEach(responses, (response) =>
                {
                    programResponses.Add(response);
                });
            }
        }
예제 #5
0
        private void GetSatellites()
        {
            var satcom = SdApi.GetAvailableSatellites();

            for (var i = 0; i < satcom.Count; ++i)
            {
                _headends.Add(new SubscribedLineup()
                {
                    Transport = "DVB-S",
                    Name      = satcom[i].lineup,
                    Location  = null,
                    Lineup    = satcom[i].lineup
                });
                listBox1.Items.Add(satcom[i].lineup);
            }
        }
예제 #6
0
        private void btnApply_Click(object sender, EventArgs e)
        {
            // determine deletions first
            if (_oldLineups?.Lineups != null)
            {
                foreach (var lineup in _oldLineups.Lineups)
                {
                    var delete = listView1.Items.Cast <ListViewItem>().All(item => (string)item.Tag != lineup.Lineup);
                    if (delete)
                    {
                        SdApi.RemoveLineup(lineup.Lineup);
                    }
                }
            }

            // add the new lineups
            foreach (ListViewItem item in listView1.Items)
            {
                var add = true;
                if (_oldLineups?.Lineups != null)
                {
                    if (_oldLineups.Lineups.Any(lineup => (string)item.Tag == lineup.Lineup))
                    {
                        add = false;
                    }
                }

                if (!add)
                {
                    continue;
                }
                if (SdApi.AddLineup((string)item.Tag))
                {
                    NewLineups.Add((string)item.Tag);
                }
                else
                {
                    MessageBox.Show($"Failed to add lineup \"{(string) item.Tag}\" to your account. Check the log for more details.");
                }
            }
            Cancel = false;
            Close();
        }
예제 #7
0
        private static bool GetExtendedSeriesDataForUiPlus(int start = 0)
        {
            // build the array of programs to request for
            var programs = new string[Math.Min(seriesDescriptionQueue.Count - start, MaxQueries)];

            for (var i = 0; i < programs.Length; ++i)
            {
                programs[i] = seriesDescriptionQueue[start + i];
            }

            // request programs from Schedules Direct
            var responses = SdApi.GetPrograms(programs);

            if (responses == null)
            {
                return(false);
            }

            // process request response
            var idx = 0;

            foreach (var response in responses)
            {
                if (response == null)
                {
                    Logger.WriteInformation($"Did not receive data for program {programs[idx++]}.");
                    continue;
                }
                ++idx; ++processedObjects; ReportProgress();

                // add the series extended data to the file if not already present from program builds
                if (!ModernMediaUiPlus.Programs.ContainsKey(response.ProgramId))
                {
                    AddModernMediaUiPlusProgram(response);
                }

                // add the series start air date if available
                UpdateSeriesAirdate(response.ProgramId, response.OriginalAirDate);
            }
            return(true);
        }
예제 #8
0
        private void BuildLineupServices(string lineup)
        {
            var channels = SdApi.GetLineupPreviewChannels(lineup);

            if (channels == null)
            {
                MessageBox.Show("There was an error retrieving channels for requested lineup. See trace.log file for more detail.", "Response Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            var items = channels.Select(channel => new ListViewItem(new[] { channel.Channel.TrimStart('0'), channel.Callsign, channel.Name })).ToList();

            if (items.Count > 0)
            {
                listView1.Items.AddRange(items.ToArray());
            }
            else
            {
                MessageBox.Show("There were no channels in the lineup to display.", "Empty Lineup", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }
예제 #9
0
        private void GetTransmitters(string country)
        {
            var xmitters = SdApi.GetTransmitters(country);
            var sites    = new List <string>(xmitters.Keys);

            foreach (var site in sites)
            {
                if (!xmitters.TryGetValue(site, out var lineup))
                {
                    continue;
                }
                _headends.Add(new SubscribedLineup()
                {
                    Transport = "DVB-T",
                    Name      = site,
                    Location  = null,
                    Lineup    = lineup
                });
                listBox1.Items.Add(site);
            }
        }
예제 #10
0
        private static bool GetMd5ScheduleEntries(string[] dates, int start)
        {
            // reject 0 requests
            if (SdMxf.With.Services.Count - start < 1)
            {
                return(true);
            }

            // build request for station schedules
            var requests = new ScheduleRequest[Math.Min(SdMxf.With.Services.Count - start, MaxQueries / dates.Length)];

            for (var i = 0; i < requests.Length; ++i)
            {
                requests[i] = new ScheduleRequest()
                {
                    StationId = SdMxf.With.Services[start + i].StationId,
                    Date      = dates
                };
            }

            // request schedule md5s from Schedules Direct
            var stationResponses = SdApi.GetScheduleMd5s(requests);

            if (stationResponses == null)
            {
                return(false);
            }

            // build request of daily schedules not downloaded yet
            var newRequests = new List <ScheduleRequest>();

            foreach (var request in requests)
            {
                var requestErrors = new Dictionary <int, string>();
                var mxfService    = SdMxf.GetService(request.StationId);
                if (stationResponses.TryGetValue(request.StationId, out var stationResponse))
                {
                    // if the station return is empty, go to next station
                    if (stationResponse.Count == 0)
                    {
                        var comment = $"Failed to parse the schedule Md5 return for stationId {mxfService.StationId} ({mxfService.CallSign}) on {dates[0]} and after.";
                        if (CheckSuppressWarnings(mxfService.CallSign))
                        {
                            Logger.WriteInformation(comment);
                        }
                        else
                        {
                            Logger.WriteWarning(comment);
                        }
                        processedObjects += dates.Length; ReportProgress();
                        continue;
                    }

                    // scan through all the dates returned for the station and request dates that are not cached
                    var newDateRequests = new List <string>();
                    var dupeMd5s        = new HashSet <string>();
                    foreach (var day in dates)
                    {
                        if (stationResponse.TryGetValue(day, out var dayResponse) && (dayResponse.Code == 0) && !string.IsNullOrEmpty(dayResponse.Md5))
                        {
                            var filepath = $"{Helper.Epg123CacheFolder}\\{SafeFilename(dayResponse.Md5)}";
                            var file     = new FileInfo(filepath);
                            if (file.Exists && (file.Length > 0) && !epgCache.JsonFiles.ContainsKey(dayResponse.Md5))
                            {
                                using (var reader = File.OpenText(filepath))
                                {
                                    epgCache.AddAsset(dayResponse.Md5, reader.ReadToEnd());
                                }
                            }

                            if (epgCache.JsonFiles.ContainsKey(dayResponse.Md5))
                            {
                                ++processedObjects; ReportProgress();
                                ++cachedSchedules;
                            }
                            else
                            {
                                newDateRequests.Add(day);
                            }

                            if (!ScheduleEntries.ContainsKey(dayResponse.Md5))
                            {
                                ScheduleEntries.Add(dayResponse.Md5, new[] { request.StationId, day });
                            }
                            else
                            {
                                var previous = ScheduleEntries[dayResponse.Md5][1];
                                var comment  = $"Duplicate schedule Md5 return for stationId {mxfService.StationId} ({mxfService.CallSign}) on {day} with {previous}.";
                                Logger.WriteWarning(comment);
                                dupeMd5s.Add(dayResponse.Md5);
                            }
                        }
                        else if ((dayResponse != null) && (dayResponse.Code != 0) && !requestErrors.ContainsKey(dayResponse.Code))
                        {
                            requestErrors.Add(dayResponse.Code, dayResponse.Message);
                        }
                    }

                    // clear out dupe entries
                    foreach (var dupe in dupeMd5s)
                    {
                        var previous = ScheduleEntries[dupe][1];
                        var comment  = $"Removing duplicate Md5 schedule entry for stationId {mxfService.StationId} ({mxfService.CallSign}) on {previous}.";
                        Logger.WriteWarning(comment);
                        ScheduleEntries.Remove(dupe);
                    }

                    // create the new request for the station
                    if (newDateRequests.Count > 0)
                    {
                        newRequests.Add(new ScheduleRequest()
                        {
                            StationId = request.StationId,
                            Date      = newDateRequests.ToArray()
                        });
                    }
                }
                else
                {
                    // requested station was not in response
                    Logger.WriteWarning($"Requested stationId {mxfService.StationId} ({mxfService.CallSign}) was not present in schedule Md5 response.");
                    processedObjects += dates.Length; ReportProgress();
                    continue;
                }

                if (requestErrors.Count <= 0)
                {
                    continue;
                }
                foreach (var keyValuePair in requestErrors)
                {
                    Logger.WriteError($"Requests for MD5 schedule entries of station {request.StationId} returned error code {keyValuePair.Key} , message: {keyValuePair.Value}");
                }
            }
            ReportProgress();

            // download the remaining daily schedules to the cache directory
            if (newRequests.Count > 0)
            {
                // request daily schedules from Schedules Direct
                var responses = SdApi.GetScheduleListings(newRequests.ToArray());
                if (responses == null)
                {
                    return(false);
                }

                // process the responses
                foreach (var response in responses)
                {
                    ++processedObjects; ReportProgress();
                    if (response?.Programs == null)
                    {
                        continue;
                    }
                    ++downloadedSchedules;

                    // serialize JSON directly to a file
                    if (ScheduleEntries.TryGetValue(response.Metadata.Md5, out var serviceDate))
                    {
                        using (var writer = new StringWriter())
                        {
                            try
                            {
                                var serializer = new JsonSerializer();
                                serializer.Serialize(writer, response);
                                epgCache.AddAsset(response.Metadata.Md5, writer.ToString());
                            }
                            catch
                            {
                                Logger.WriteInformation($"Failed to write station daily schedule file to cache file. station: {serviceDate[0]} ; date: {serviceDate[1]}");
                            }
                        }
                    }
                    else
                    {
                        try
                        {
                            var compare = ScheduleEntries
                                          .Where(arg => arg.Value[0].Equals(response.StationId))
                                          .Single(arg => arg.Value[1].Equals(response.Metadata.StartDate));
                            Logger.WriteWarning($"Md5 mismatch for station {compare.Value[0]} on {compare.Value[1]}. Expected: {compare.Key} - Downloaded {response.Metadata.Md5}");
                        }
                        catch
                        {
                            Logger.WriteWarning($"Md5 mismatch for station {response.StationId} on {response.Metadata.StartDate}. Downloaded {response.Metadata.Md5}");
                        }
                    }
                }
            }
            ReportProgress();
            return(true);
        }
예제 #11
0
        private static bool BuildLineupServices()
        {
            // query what lineups client is subscribed to
            var clientLineups = SdApi.GetSubscribedLineups();

            if (clientLineups == null)
            {
                return(false);
            }

            // determine if there are custom lineups to consider
            if (File.Exists(Helper.Epg123CustomLineupsXmlPath))
            {
                CustomLineups customLineups;
                using (var stream = new StreamReader(Helper.Epg123CustomLineupsXmlPath, Encoding.Default))
                {
                    var        serializer = new XmlSerializer(typeof(CustomLineups));
                    TextReader reader     = new StringReader(stream.ReadToEnd());
                    customLineups = (CustomLineups)serializer.Deserialize(reader);
                    reader.Close();
                }

                foreach (var lineup in customLineups.CustomLineup.Where(lineup => config.IncludedLineup.Contains(lineup.Lineup)))
                {
                    customLineup = lineup;

                    clientLineups.Lineups.Add(new SubscribedLineup
                    {
                        Lineup    = lineup.Lineup,
                        Name      = lineup.Name,
                        Transport = "CUSTOM",
                        Location  = lineup.Location,
                        Uri       = "CUSTOM",
                        IsDeleted = false
                    });

                    customMap = new StationChannelMap
                    {
                        Map      = new List <LineupChannel>(),
                        Stations = new List <LineupStation>(),
                        Metadata = new LineupMetadata {
                            Lineup = lineup.Lineup
                        }
                    };
                }
            }

            // reset counters
            processedObjects = 0; totalObjects = clientLineups.Lineups.Count;
            ReportProgress();

            // process lineups
            Logger.WriteMessage($"Entering BuildLineupServices() for {clientLineups.Lineups.Count} lineups.");
            foreach (var clientLineup in clientLineups.Lineups)
            {
                var flagCustom = !string.IsNullOrEmpty(clientLineup.Uri) && clientLineup.Uri.Equals("CUSTOM");
                ++processedObjects; ReportProgress();

                // request the lineup's station maps
                StationChannelMap lineupMap = null;
                if (!flagCustom)
                {
                    lineupMap = SdApi.GetStationChannelMap(clientLineup.Lineup);
                    if (lineupMap == null)
                    {
                        continue;
                    }

                    foreach (var station in lineupMap.Stations.Where(station => !AllStations.ContainsKey(station.StationId)))
                    {
                        AllStations.Add(station.StationId, station);
                    }
                }

                if (!config.IncludedLineup.Contains(clientLineup.Lineup))
                {
                    Logger.WriteVerbose($"Subscribed lineup {clientLineup.Lineup} has been EXCLUDED from download and processing.");
                    continue;
                }
                if (clientLineup.IsDeleted)
                {
                    Logger.WriteWarning($"Subscribed lineup {clientLineup.Lineup} has been DELETED at the headend.");
                    continue;
                }
                if (flagCustom)
                {
                    foreach (var station in customLineup.Station.Where(station => station.StationId != null))
                    {
                        if (AllStations.TryGetValue(station.StationId, out var lineupStation))
                        {
                            customMap.Map.Add(new LineupChannel
                            {
                                StationId = station.StationId,
                                AtscMajor = station.Number,
                                AtscMinor = station.Subnumber,
                                MatchName = station.MatchName
                            });
                            CustomStations.Add(station.StationId);
                            customMap.Stations.Add(lineupStation);
                        }
                        else if (!string.IsNullOrEmpty(station.Alternate) && AllStations.TryGetValue(station.Alternate, out lineupStation))
                        {
                            customMap.Map.Add(new LineupChannel
                            {
                                StationId = station.Alternate,
                                AtscMajor = station.Number,
                                AtscMinor = station.Subnumber,
                                MatchName = station.MatchName
                            });
                            CustomStations.Add(station.Alternate);
                            customMap.Stations.Add(lineupStation);
                        }
                    }
                    lineupMap = customMap;
                    Logger.WriteVerbose($"Successfully retrieved the station mapping for lineup {clientLineup.Lineup}.");
                }
                if (lineupMap == null)
                {
                    return(false);
                }

                var lineupIndex = SdMxf.With.Lineups.Count;
                SdMxf.With.Lineups.Add(new MxfLineup
                {
                    Index    = lineupIndex + 1,
                    LineupId = clientLineup.Lineup,
                    Name     = $"EPG123 {clientLineup.Name} ({clientLineup.Location})"
                });

                // use hashset to make sure we don't duplicate channel entries for this station
                var channelNumbers = new HashSet <string>();

                // build the services and lineup
                foreach (var station in lineupMap.Stations)
                {
                    // check if station should be downloaded and processed
                    if (!flagCustom)
                    {
                        if (station == null || (ExcludedStations.Contains(station.StationId) && !CustomStations.Contains(station.StationId)))
                        {
                            continue;
                        }
                        if (!IncludedStations.Contains(station.StationId) && !config.AutoAddNew)
                        {
                            Logger.WriteWarning($"**** Lineup {clientLineup.Name} ({clientLineup.Location}) has added station {station.StationId} ({station.Callsign}). ****");
                            continue;
                        }
                    }

                    // build the service if necessary
                    var mxfService = SdMxf.GetService(station.StationId);
                    if (string.IsNullOrEmpty(mxfService.CallSign))
                    {
                        // instantiate stationLogo and override uid
                        StationImage stationLogo = null;
                        mxfService.UidOverride = $"EPG123_{station.StationId}";

                        // determine station name for ATSC stations
                        var atsc  = false;
                        var names = station.Name.Replace("-", "").Split(' ');
                        if (!string.IsNullOrEmpty(station.Affiliate) && names.Length == 2 && names[0] == station.Callsign && $"({names[0]})" == $"{names[1]}")
                        {
                            atsc = true;
                        }

                        // add callsign and station name
                        mxfService.CallSign = CheckCustomCallsign(station.StationId) ?? station.Callsign;
                        mxfService.Name     = CheckCustomServicename(station.StationId) ?? (atsc ? $"{station.Callsign} ({station.Affiliate})" : null) ?? station.Name;

                        // add affiliate if available
                        if (!string.IsNullOrEmpty(station.Affiliate))
                        {
                            mxfService.mxfAffiliate = SdMxf.GetAffiliate(station.Affiliate);
                        }

                        // add station logo if available and allowed
                        var logoPath    = $"{Helper.Epg123LogosFolder}\\{station.Callsign}.png";
                        var urlLogoPath = logoPath.Replace($"{Helper.Epg123LogosFolder}\\", $"http://{Environment.MachineName}:{Helper.TcpPort}/logos/");
                        var customPath  = $"{Helper.Epg123LogosFolder}\\{station.Callsign}_c.png";
                        if (config.IncludeSdLogos)
                        {
                            // make sure logos directory exists
                            if (!Directory.Exists(Helper.Epg123LogosFolder))
                            {
                                Directory.CreateDirectory(Helper.Epg123LogosFolder);
                            }

                            if (station.StationLogos != null)
                            {
                                stationLogo = station.StationLogos.FirstOrDefault(arg => arg.Category != null && arg.Category.Equals(config.PreferredLogoStyle, StringComparison.OrdinalIgnoreCase)) ??
                                              station.StationLogos.FirstOrDefault(arg => arg.Category != null && arg.Category.Equals(config.AlternateLogoStyle, StringComparison.OrdinalIgnoreCase));

                                if (stationLogo != null)
                                {
                                    switch (stationLogo.Category)
                                    {
                                    case "dark":
                                        logoPath = logoPath.Replace(".png", "_d.png");
                                        break;

                                    case "gray":
                                        logoPath = logoPath.Replace(".png", "_g.png");
                                        break;

                                    case "light":
                                        logoPath = logoPath.Replace(".png", "_l.png");
                                        break;

                                    case "white":
                                        logoPath = logoPath.Replace(".png", "_w.png");
                                        break;
                                    }
                                }
                            }
                            if (stationLogo == null && !config.PreferredLogoStyle.Equals("none", StringComparison.OrdinalIgnoreCase) && !config.AlternateLogoStyle.Equals("none", StringComparison.OrdinalIgnoreCase))
                            {
                                stationLogo = station.Logo;
                            }

                            // download the logo from SD if not present in the .\logos folder
                            if (stationLogo != null && !File.Exists(logoPath))
                            {
                                var url = stationLogo.Url;

                                // download, crop & resize logo image, save and add
                                if (!string.IsNullOrEmpty(url))
                                {
                                    StationLogosToDownload.Add(new KeyValuePair <MxfService, string[]>(mxfService, new[] { logoPath, url }));
                                }
                            }

                            // add the existing logo; custom logo overrides downloaded logos
                            if (File.Exists(customPath))
                            {
                                logoPath = customPath;
                            }
                            urlLogoPath = logoPath.Replace($"{Helper.Epg123LogosFolder}\\", $"http://{Environment.MachineName}:{Helper.TcpPort}/logos/");

                            if (File.Exists(logoPath))
                            {
                                mxfService.mxfGuideImage = SdMxf.GetGuideImage(Helper.Standalone ? $"file://{logoPath}" : urlLogoPath, GetStringEncodedImage(logoPath));
                            }
                        }

                        // handle xmltv logos
                        if (config.XmltvIncludeChannelLogos.Equals("url"))
                        {
                            if (stationLogo != null)
                            {
                                mxfService.extras.Add("logo", stationLogo);
                            }
                            else if (station.Logo?.Url != null)
                            {
                                mxfService.extras.Add("logo", station.Logo);
                            }
                        }
                        else if (config.XmltvIncludeChannelLogos.Equals("local") && config.IncludeSdLogos)
                        {
                            if (File.Exists(logoPath))
                            {
                                var image = Image.FromFile(logoPath);
                                mxfService.extras.Add("logo", new StationImage
                                {
                                    Url    = Helper.Standalone ? logoPath : urlLogoPath,
                                    Height = image.Height,
                                    Width  = image.Width
                                });
                            }
                            else if (stationLogo != null)
                            {
                                mxfService.extras.Add("logo", new StationImage
                                {
                                    Url = Helper.Standalone ? logoPath : urlLogoPath
                                });
                            }
                        }
                    }

                    // match station with mapping for lineup number and subnumbers
                    foreach (var map in lineupMap.Map)
                    {
                        var number    = -1;
                        var subnumber = 0;
                        if (!map.StationId.Equals(station.StationId))
                        {
                            continue;
                        }

                        // QAM
                        if (map.ChannelMajor != 0)
                        {
                            number    = map.ChannelMajor;
                            subnumber = map.ChannelMinor;
                        }

                        // ATSC (and CUSTOM) or NTSC
                        else if (map.AtscMajor != 0)
                        {
                            number    = map.AtscMajor;
                            subnumber = map.AtscMinor;
                        }
                        else if (map.UhfVhf != 0)
                        {
                            number = map.UhfVhf;
                        }

                        // Cable or Satellite
                        else if (!string.IsNullOrEmpty(map.Channel))
                        {
                            subnumber = 0;
                            if (Regex.Match(map.Channel, @"[A-Za-z]{1}[\d]{4}").Length > 0)
                            {
                                // 4dtv has channels starting with 2 character satellite identifier
                                number = int.Parse(map.Channel.Substring(2));
                            }
                            else if (!int.TryParse(Regex.Replace(map.Channel, "[^0-9.]", ""), out number))
                            {
                                // if channel number is not a whole number, must be a decimal number
                                var numbers = Regex.Replace(map.Channel, "[^0-9.]", "").Replace('_', '.').Replace('-', '.').Split('.');
                                if (numbers.Length == 2)
                                {
                                    number    = int.Parse(numbers[0]);
                                    subnumber = int.Parse(numbers[1]);
                                }
                            }
                        }

                        string matchName = null;
                        switch (clientLineup.Transport)
                        {
                        case "CUSTOM":
                            matchName = map.MatchName;
                            break;

                        case "DVB-S":
                            var m = Regex.Match(lineupMap.Metadata.Lineup, @"\d+\.\d+");
                            if (m.Success && map.FrequencyHz > 0 && map.NetworkId > 0 && map.TransportId > 0 && map.ServiceId > 0)
                            {
                                while (map.FrequencyHz > 13000)
                                {
                                    map.FrequencyHz /= 1000;
                                }
                                matchName = $"DVBS:{m.Value.Replace(".", "")}:{map.FrequencyHz}:{map.NetworkId}:{map.TransportId}:{map.ServiceId}";
                            }
                            number    = -1;
                            subnumber = 0;
                            break;

                        case "DVB-T":
                            if (map.NetworkId > 0 && map.TransportId > 0 && map.ServiceId > 0)
                            {
                                matchName = $"DVBT:{map.NetworkId}:{map.TransportId}:{map.ServiceId}";
                            }
                            break;

                        case "Antenna":
                            if (map.AtscMajor > 0 && map.AtscMinor > 0)
                            {
                                matchName = $"OC:{map.AtscMajor}:{map.AtscMinor}";
                            }
                            break;
                        }

                        var channelNumber = $"{number}{(subnumber > 0 ? $".{subnumber}" : "")}";
                        if (channelNumbers.Add($"{channelNumber}:{station.StationId}"))
                        {
                            SdMxf.With.Lineups[lineupIndex].channels.Add(new MxfChannel
                            {
                                mxfLineup  = SdMxf.With.Lineups[lineupIndex],
                                mxfService = mxfService,
                                Number     = number,
                                SubNumber  = subnumber,
                                MatchName  = matchName
                            });
                        }
                    }
                }
            }

            if (StationLogosToDownload.Count > 0)
            {
                StationLogosDownloadComplete = false;
                Logger.WriteInformation($"Kicking off background worker to download and process {StationLogosToDownload.Count} station logos.");
                BackgroundDownloader                            = new System.ComponentModel.BackgroundWorker();
                BackgroundDownloader.DoWork                    += BackgroundDownloader_DoWork;
                BackgroundDownloader.RunWorkerCompleted        += BackgroundDownloader_RunWorkerCompleted;
                BackgroundDownloader.WorkerSupportsCancellation = true;
                BackgroundDownloader.RunWorkerAsync();
            }

            if (SdMxf.With.Services.Count > 0)
            {
                // report specific stations that are no longer available
                var missing = (from station in IncludedStations where SdMxf.With.Services.FirstOrDefault(arg => arg.StationId.Equals(station)) == null select config.StationId.Single(arg => arg.StationId.Equals(station)).CallSign).ToList();
                if (missing.Count > 0)
                {
                    MissingStations = missing.Count;
                    Logger.WriteInformation($"Stations no longer available since last configuration save are: {string.Join(", ", missing)}");
                }

                Logger.WriteMessage("Exiting BuildLineupServices(). SUCCESS.");
                return(true);
            }

            Logger.WriteError($"There are 0 stations queued for download from {clientLineups.Lineups.Count} subscribed lineups. Exiting.");
            Logger.WriteError("Check that lineups are 'INCLUDED' and stations are selected in the EPG123 GUI.");
            return(false);
        }
예제 #12
0
        public frmLineupAdd()
        {
            InitializeComponent();
            var isoCountry = System.Globalization.RegionInfo.CurrentRegion.ThreeLetterISORegionName;

            var countryResp = SdApi.GetAvailableCountries();

            if (countryResp != null)
            {
                // add the only freeview listing
                _countries.Add(new Country()
                {
                    FullName          = "Great Britain Freeview",
                    PostalCode        = "/",
                    PostalCodeExample = null,
                    ShortName         = "GBR"
                });

                // get all the region/countries
                var regions = new List <string>(countryResp.Keys);
                foreach (var country in regions.Where(region => !region.ToLower().Equals("zzz")).Select(region => countryResp[region]).SelectMany(regionCountries => regionCountries))
                {
                    _countries.Add(country);
                }

                // sort the countries
                _countries = _countries.OrderBy(o => o.FullName).ToList();
                foreach (var country in _countries)
                {
                    cmbCountries.Items.Add(country.FullName);
                }

                // add the DVB satellites
                foreach (var regionCountries in from region in regions where region.ToLower().Equals("zzz") select countryResp[region])
                {
                    _countries.Add(null); cmbCountries.Items.Add(string.Empty);
                    foreach (var country in regionCountries)
                    {
                        _countries.Add(country);
                        cmbCountries.Items.Add(country.FullName);
                    }
                }

                // add a manual option
                _countries.Add(null);
                _countries.Add(new Country()
                {
                    FullName          = "Manual lineup input...",
                    OnePostalCode     = false,
                    PostalCode        = "/[A-Z]+-[A-Z0-9]+-[A-Z0-9]+",
                    PostalCodeExample = "USA-CA00053-DEFAULT",
                    ShortName         = "EPG123"
                });
                cmbCountries.Items.Add(string.Empty); cmbCountries.Items.Add("Manual lineup input...");
            }

            var index = 0;

            for (var i = 0; i < _countries.Count; ++i)
            {
                if (_countries[i] == null)
                {
                    continue;
                }
                if (string.IsNullOrEmpty(_countries[i].ShortName) || !_countries[i].ShortName.ToUpper().Equals(isoCountry))
                {
                    continue;
                }
                index = i;
                break;
            }
            cmbCountries.SelectedIndex = index;

            // automatically fetch the zipcode as entered during TV Setup and perform a fetch
            try
            {
                using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Settings\ProgramGuide", false))
                {
                    if ((key == null) || (string.IsNullOrEmpty(key.GetValue("strLocation").ToString())))
                    {
                        return;
                    }
                    txtZipcode.Text = key.GetValue("strLocation").ToString().Split(' ')[0];
                    btnFetch_Click(btnFetch, null);
                }
            }
            catch
            {
                // ignored
            }
        }
예제 #13
0
        private void btnFetch_Click(object sender, EventArgs e)
        {
            Enabled       = false;
            UseWaitCursor = true;
            Application.DoEvents();

            // evaluate the zipcode format
            var m = Regex.Match(txtZipcode.Text.ToUpper(), _mask);

            if ((m.Length == 0) && (!string.IsNullOrEmpty(_countries[cmbCountries.SelectedIndex].PostalCodeExample)))
            {
                MessageBox.Show("Postal Code is in the wrong format for selected country.\nPlease correct entry and try again.\n", "Invalid Entry", MessageBoxButtons.OK);
            }
            else if (_countries[cmbCountries.SelectedIndex].ShortName.Equals("EPG123"))
            {
                listBox1.Items.Clear();
                listBox1.Items.Add(txtZipcode.Text);

                _headends = new List <SubscribedLineup>
                {
                    new SubscribedLineup()
                    {
                        Transport = "unknown",
                        Name      = txtZipcode.Text,
                        Location  = "unknown",
                        Lineup    = txtZipcode.Text
                    }
                };
            }
            else
            {
                listBox1.Items.Clear();
                _headends = new List <SubscribedLineup>();

                var heads = SdApi.GetHeadends(_countries[cmbCountries.SelectedIndex].ShortName, m.Value);
                if (heads == null)
                {
                    MessageBox.Show("No headends found for entered postal code and country.", "No Headend Found", MessageBoxButtons.OK);
                    return;
                }

                foreach (var head in heads)
                {
                    foreach (var lineup in head.Lineups)
                    {
                        _headends.Add(new SubscribedLineup()
                        {
                            Transport = head.Transport,
                            Name      = lineup.Name,
                            Location  = head.Location,
                            Lineup    = lineup.Lineup
                        });
                        //listBox1.Items.Add(string.Format("{0} ({1})", lineup.Name, head.Location));
                    }
                }

                if (_headends.Count > 0)
                {
                    _headends = _headends.OrderBy(o => o.Name).ToList();
                    foreach (var lineup in _headends)
                    {
                        listBox1.Items.Add($"{lineup.Name} ({lineup.Location})");
                    }
                }
            }

            UseWaitCursor = false;
            Enabled       = true;
        }
예제 #14
0
        public static void Build(epgConfig configuration)
        {
            var errString = string.Empty;

            // initialize schedules direct API
            SdApi.Initialize("EPG123");
            SdMxf.InitializeMxf();

            // copy configuration to local variable
            config = configuration;

            // initialize event buffer
            Logger.WriteInformation($"Beginning EPG123 update execution. {DateTime.Now.ToUniversalTime():u}");
            Logger.WriteVerbose($"DaysToDownload: {config.DaysToDownload} , TheTVDBNumbers : {config.TheTvdbNumbers} , PrefixEpisodeTitle: {config.PrefixEpisodeTitle} , PrefixEpisodeDescription : {config.PrefixEpisodeDescription} , AppendEpisodeDesc: {config.AppendEpisodeDesc} , OADOverride : {config.OadOverride} , SeasonEventImages : {config.SeasonEventImages} , TMDbCoverArt: {config.TMDbCoverArt} , IncludeSDLogos : {config.IncludeSdLogos} , AutoAddNew: {config.AutoAddNew} , CreateXmltv: {config.CreateXmltv} , ModernMediaUiPlusSupport: {config.ModernMediaUiPlusSupport}");

            // populate station prefixes to suppress
            suppressedPrefixes = new List <string>(config.SuppressStationEmptyWarnings.Split(','));

            // login to Schedules Direct and build the mxf file
            if (SdApi.GetToken(config.UserAccount.LoginName, config.UserAccount.PasswordHash, ref errString))
            {
                // check server status
                var susr = SdApi.GetUserStatus();
                if (susr == null)
                {
                    return;
                }
                else if (susr.SystemStatus[0].Status.ToLower().Equals("offline"))
                {
                    Logger.WriteError("Schedules Direct server is offline. Aborting update.");
                    return;
                }

                // check for latest version and update the display name that shows in About Guide
                var scvr = SdApi.GetClientVersion();
                if (scvr != null && scvr.Version != Helper.Epg123Version)
                {
                    SdMxf.Providers[0].DisplayName += $" (v{scvr.Version} Available)";
                    BrandLogo.UpdateAvailable       = true;
                }

                // make sure cache directory exists
                if (!Directory.Exists(Helper.Epg123CacheFolder))
                {
                    Directory.CreateDirectory(Helper.Epg123CacheFolder);
                }
                epgCache.LoadCache();

                // initialize tmdb api
                if (config.TMDbCoverArt)
                {
                    tmdbApi.Initialize(false);
                }

                // prepopulate keyword groups
                InitializeKeywordGroups();

                // read all included and excluded station from configuration
                PopulateIncludedExcludedStations(config.StationId);

                // if all components of the mxf file have been successfully created, save the file
                if (BuildLineupServices() && ServiceCountSafetyCheck() &&
                    GetAllScheduleEntryMd5S(config.DaysToDownload) &&
                    BuildAllProgramEntries() &&
                    BuildAllGenericSeriesInfoDescriptions() &&
                    BuildAllExtendedSeriesDataForUiPlus() &&
                    GetAllMoviePosters() &&
                    GetAllSeriesImages() &&
                    GetAllSeasonImages() &&
                    GetAllSportsImages() &&
                    BuildKeywords() &&
                    WriteMxf())
                {
                    Success = true;

                    // create the xmltv file if desired
                    if (config.CreateXmltv && CreateXmltvFile())
                    {
                        WriteXmltv();
                        ++processedObjects; ReportProgress();
                    }

                    // remove the guide images xml file
                    Helper.DeleteFile(Helper.Epg123GuideImagesXmlPath);

                    // create the ModernMedia UI+ json file if desired
                    if (config.ModernMediaUiPlusSupport)
                    {
                        ModernMediaUiPlus.WriteModernMediaUiPlusJson(config.ModernMediaUiPlusJsonFilepath ?? null);
                        ++processedObjects; ReportProgress();
                    }

                    // clean the cache folder of stale data
                    CleanCacheFolder();
                    epgCache.WriteCache();

                    Logger.WriteVerbose($"Downloaded and processed {SdApi.TotalDownloadBytes} of data from Schedules Direct.");
                    Logger.WriteVerbose($"Generated .mxf file contains {SdMxf.With.Services.Count - 1} services, {SdMxf.With.SeriesInfos.Count} series, {SdMxf.With.Seasons.Count} seasons, {SdMxf.With.Programs.Count} programs, {SdMxf.With.ScheduleEntries.Sum(x => x.ScheduleEntry.Count)} schedule entries, and {SdMxf.With.People.Count} people with {SdMxf.With.GuideImages.Count} image links.");
                    Logger.WriteInformation("Completed EPG123 update execution. SUCCESS.");
                }
            }
            else
            {
                Logger.WriteError($"Failed to retrieve token from Schedules Direct. message: {errString}");
            }
            SdMxf = null;
            GC.Collect();
            Helper.SendPipeMessage("Download Complete");
        }