예제 #1
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);
        }