public ImportLog Run() { var log = new ImportLog(); var existingItems = _googlePlacesItemProcessor.GetExistItems(); var existingItemsDtos = _mapper.Map <IEnumerable <ItemDto> >(existingItems); var placesSearchLog = new List <ImportLogEntry>(); var itemsWithPlaceId = _googlePlacesService.PopulateGooglePlacesIds(existingItemsDtos, true, ref placesSearchLog); var itemsWithPlaceData = _googlePlacesService.PopulateGooglePlacesData(itemsWithPlaceId, ref placesSearchLog); log.Entries.AddRange(placesSearchLog); foreach (var itemDto in itemsWithPlaceData) { var sw = new Stopwatch(); sw.Start(); try { var item = _googlePlacesItemProcessor.ProcessItem(itemDto); sw.Stop(); var importLogEntry = new ImportLogEntry { Level = MessageLevel.Info, Action = ImportAction.Imported, Id = item.Id, Message = $"{itemDto.CompanyName} - Google Place data has been imported successfully, time taken is {sw.ElapsedMilliseconds} m" }; WriteToLog(importLogEntry); log.Entries.Add(importLogEntry); } catch (ImportLogException e) { var importLogEntry = e.Entry; WriteToLog(importLogEntry); log.Entries.Add(importLogEntry); } catch (Exception e) { var importLogEntry = new ImportLogEntry { Level = MessageLevel.Error, Message = $"{this.GetType()}: {e.GetAllMessages()} {e.StackTrace}" }; WriteToLog(importLogEntry); log.Entries.Add(importLogEntry); } } return(log); }
private void WriteToLog(ImportLogEntry importLogEntry) { switch (importLogEntry.Level) { case MessageLevel.Error: Logger.Error(importLogEntry.Message); break; case MessageLevel.Critical: Logger.Fatal(importLogEntry.Message); break; default: Logger.Info(importLogEntry.Message); break; } }
public IEnumerable <ItemDto> PopulateGooglePlacesIds(IEnumerable <ItemDto> existingItems, bool reSearchPlaceId, ref List <ImportLogEntry> logEntries) { ConcurrentBag <ItemDto> items; IEnumerable <ItemDto> itemsToSearchPlaceId; var logs = new ConcurrentBag <ImportLogEntry>(); var baseUrl = GooglePlacesSettings.GooglePlaceSearchRequest; var key = GooglePlacesSettings.GoogleApiKey; if (reSearchPlaceId) { itemsToSearchPlaceId = existingItems; items = new ConcurrentBag <ItemDto>(); } else { itemsToSearchPlaceId = existingItems.Where(x => x.GooglePlaceData == null || string.IsNullOrWhiteSpace(x.GooglePlaceData.PlaceId)); items = new ConcurrentBag <ItemDto>(existingItems.Where(x => x.GooglePlaceData != null && !string.IsNullOrWhiteSpace(x.GooglePlaceData.PlaceId))); } try { Parallel.ForEach(itemsToSearchPlaceId, item => { if (item.GooglePlaceData == null) { item.GooglePlaceData = new GooglePlaceDto(); } var searchString = HttpUtility.UrlEncode( $"{item.CompanyName} {item.AddressLine1} {item.City} {item.County} {item.Postcode}"); var requestUrl = string.Format(baseUrl, key, searchString, item.Latitude.ToString(CultureInfo.InvariantCulture), item.Longitude.ToString(CultureInfo.InvariantCulture)); var request = WebRequest.Create(requestUrl); try { var responseStream = request.GetResponse().GetResponseStream(); string responseText; using (var sr = new StreamReader(responseStream)) { responseText = sr.ReadToEnd(); } var searchResults = JsonConvert.DeserializeObject <GooglePlacesSearchResponse>(responseText); if (searchResults.Candidates != null && searchResults.Candidates.Count(x => !x.PermanentlyClosed) == 1) { item.GooglePlaceData.PlaceId = searchResults.Candidates.First(x => !x.PermanentlyClosed).PlaceId; items.Add(item); } else { if (searchResults.Candidates != null && searchResults.Candidates.Count(x => !x.PermanentlyClosed) > 1) { var logEntry = new ImportLogEntry { Message = $"{item.CompanyName} - Multiple Google Place IDs found: {string.Join(", ", searchResults.Candidates.Select(x => x.PlaceId))}\nRequest: {requestUrl}", Action = ImportAction.Rejected, Level = MessageLevel.Info }; this.Logger.Info(logEntry.Message); logs.Add(logEntry); } else if (searchResults.Candidates != null && searchResults.Candidates.Any(x => x.PermanentlyClosed)) { var logEntry = new ImportLogEntry { Message = $"{item.CompanyName} - Google Place is permanently closed\nRequest: {requestUrl}", Action = ImportAction.Rejected, Level = MessageLevel.Info }; this.Logger.Info(logEntry.Message); logs.Add(logEntry); } else { var logEntry = new ImportLogEntry { Message = $"{item.CompanyName} - No Google Place IDs found\nRequest: {requestUrl}", Action = ImportAction.Rejected, Level = MessageLevel.Info }; this.Logger.Info(logEntry.Message); logs.Add(logEntry); } } } catch (Exception exception) { var logEntry = new ImportLogEntry { Message = $"{item.CompanyName} - error while searching by Google Place ID\nRequest: {requestUrl}", Action = ImportAction.Rejected, Level = MessageLevel.Info }; this.Logger.Error(logEntry.Message, exception); logs.Add(logEntry); } }); } catch (Exception exception) { var logEntry = new ImportLogEntry { Message = $"Error searching Google Place IDs", Action = ImportAction.Undefined, Level = MessageLevel.Error }; this.Logger.Error(logEntry.Message, exception); logs.Add(logEntry); } logEntries.AddRange(logs); return(items); }
public IEnumerable <ItemDto> PopulateGooglePlacesData(IEnumerable <ItemDto> existingItems, ref List <ImportLogEntry> logEntries) { var baseUrl = GooglePlacesSettings.GooglePlaceSearchRequest; var key = GooglePlacesSettings.GoogleApiKey; var items = new ConcurrentBag <ItemDto>(); var logs = new ConcurrentBag <ImportLogEntry>(); var basicFields = GooglePlacesSettings.GooglePlaceBasicDataFields; // "name,url,formatted_address" var contactFields = GooglePlacesSettings.GooglePlaceContactDataFields; // "formatted_phone_number,opening_hours" var atmosphereFields = GooglePlacesSettings.GooglePlaceAtmosphereDataFields; // "rating" Int32 basicDataCacheMinutes = GooglePlacesSettings.GooglePlaceBasicDataCacheMinutes; // 10080 Int32 contactDataCacheMinutes = GooglePlacesSettings.GooglePlaceContactDataCacheMinutes; // 10080 Int32 atmosphereDataCacheMinutes = GooglePlacesSettings.GooglePlaceAtmosphereDataCacheMinutes; // 10080 if (basicDataCacheMinutes <= 0 || contactDataCacheMinutes <= 0 || atmosphereDataCacheMinutes <= 0 || string.IsNullOrWhiteSpace(basicFields) || string.IsNullOrWhiteSpace(contactFields) || string.IsNullOrWhiteSpace(atmosphereFields)) { var logEntry = new ImportLogEntry { Message = $"Google Places Data import settings are incomplete or empty", Action = ImportAction.Undefined, Level = MessageLevel.Error }; this.Logger.Error(logEntry.Message); logEntries.Add(logEntry); return(new List <ItemDto>()); } try { Parallel.ForEach(existingItems, item => { var fields = new List <string>(); if (item.GooglePlaceData.BasicDataImported.AddMinutes(basicDataCacheMinutes) < DateTime.Now) { fields.Add(basicFields); } if (item.GooglePlaceData.ContactDataImported.AddMinutes(contactDataCacheMinutes) < DateTime.Now) { fields.Add(contactFields); } if (item.GooglePlaceData.AtmosphereDataImported.AddMinutes(atmosphereDataCacheMinutes) < DateTime.Now) { fields.Add(atmosphereFields); } if (fields.Any()) { var allFields = string.Join(",", fields); var requestUrl = string.Format(baseUrl, key, item.GooglePlaceData.PlaceId, allFields); var request = WebRequest.Create(requestUrl); try { var responseStream = request.GetResponse().GetResponseStream(); string responseText; using (var sr = new StreamReader(responseStream)) { responseText = sr.ReadToEnd(); } var placeData = JsonConvert.DeserializeObject <GooglePlacesGetByIdResponse>(responseText); if (fields.Contains(basicFields, StringComparer.OrdinalIgnoreCase)) { item.GooglePlaceData.BasicFormattedAddress = placeData?.Result?.FormattedAddress; item.GooglePlaceData.BasicName = placeData?.Result?.Name; item.GooglePlaceData.BasicUrl = placeData?.Result?.Url; item.GooglePlaceData.BasicDataImported = DateTime.Now; } if (fields.Contains(contactFields, StringComparer.OrdinalIgnoreCase)) { item.GooglePlaceData.ContactFormattedPhoneNumber = placeData?.Result?.FormattedPhoneNumber; item.GooglePlaceData.ContactOpeningHours = placeData?.Result?.OpeningHours?.WeekdayText != null ? string.Join("\r\n", placeData.Result.OpeningHours.WeekdayText) : null; item.GooglePlaceData.ContactDataImported = DateTime.Now; } if (fields.Contains(atmosphereFields, StringComparer.OrdinalIgnoreCase)) { item.GooglePlaceData.AtmosphereRating = placeData?.Result?.Rating ?? Decimal.Zero; item.GooglePlaceData.AtmosphereDataImported = DateTime.Now; } items.Add(item); } catch (Exception exception) { var logEntry = new ImportLogEntry { Message = $"{item.CompanyName} - error while getting Google Place Data\nRequest: {requestUrl}", Action = ImportAction.Rejected, Level = MessageLevel.Info }; this.Logger.Error(logEntry.Message, exception); logs.Add(logEntry); } } }); } catch (Exception exception) { var logEntry = new ImportLogEntry { Message = $"Error while getting Google Places Data", Action = ImportAction.Undefined, Level = MessageLevel.Error }; this.Logger.Error(logEntry.Message, exception); logs.Add(logEntry); } return(items); }