Created
May 22, 2018 15:02
-
-
Save jakobz/d7070f049fa2ddc62f08d4dc87c8f904 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Globalization; | |
| using System.Linq; | |
| using System.Text.RegularExpressions; | |
| using Epam.Api.Eco; | |
| using Location = Edu.AppTools.Data.Models.Location; | |
| using Room = Edu.AppTools.Data.Models.Room; | |
| namespace Edu.AppTools.Service.Locations.Rooms | |
| { | |
| internal class RoomsParser | |
| { | |
| /// <summary> | |
| /// Gets room name | |
| /// </summary> | |
| /// <returns></returns> | |
| public static Room ParseADRoom(ADRoom room, IList<Location> locations) | |
| { | |
| var result = CoreParseRoom(room, locations); | |
| return result; | |
| } | |
| private static Location GetParentLocationForParsedRoom(ParsedRoom parsedRoom, IList<Location> locations) | |
| { | |
| Location location = null; | |
| if (!parsedRoom.IsApartment && !parsedRoom.IsVirtual) | |
| { | |
| var city = locations.FirstOrDefault(x => | |
| x.LocationType == LocationType.City && x.Name != null && | |
| x.Name.Equals(parsedRoom.City, StringComparison.CurrentCultureIgnoreCase)); | |
| if (city == null) | |
| return null; | |
| location = city; | |
| if (!string.IsNullOrWhiteSpace(parsedRoom.Office)) | |
| { | |
| var officeParts = parsedRoom.Office.Split(',', ' ', '.').Where(x => !string.IsNullOrWhiteSpace(x)) | |
| .Select(x => x.Trim()).ToArray(); | |
| var office = locations.FirstOrDefault(x => | |
| x.LocationType == LocationType.Office && x.Name != null && | |
| (x.Name.StartsWith(parsedRoom.Office, true, CultureInfo.CurrentCulture) && | |
| city.Id == x.ParentLocationId || officeParts.All(y => x.Name.Contains(y)))); | |
| if (office != null) | |
| { | |
| location = office; | |
| } | |
| } | |
| } | |
| return location; | |
| } | |
| private static Room CoreParseRoom(ADRoom adRoom, IList<Location> locations) | |
| { | |
| adRoom.DisplayName = adRoom.DisplayName.Trim(); | |
| var parsedRoom = new ParsedRoom | |
| { | |
| DisplayName = adRoom.DisplayName, | |
| Email = adRoom.Email, | |
| ResourceCapacity = adRoom.ResourceCapacity, | |
| ResourceDisplay = adRoom.ResourceDisplay | |
| }; | |
| var match = Regex.Match(adRoom.DisplayName, @"^Room\s*-\s*(.+)$"); | |
| if (match.Success) // room | |
| { | |
| parsedRoom.IsApartment = false; | |
| string[] parts; | |
| var location = match.Groups[1].Value; | |
| match = Regex.Match(location, @"Virtual(?:\s*-\s*|,)\s*(.+)$"); | |
| if (match.Success) | |
| { | |
| parsedRoom.IsVirtual = true; | |
| location = match.Groups[1].Value; | |
| parts = location.Split(','); | |
| if (parts.Length > 1) | |
| { | |
| parsedRoom.City = parts[0].Trim(); | |
| parsedRoom.RoomName = string.Join(",", parts.Skip(1)).Trim(); | |
| } | |
| else | |
| { | |
| parsedRoom.RoomName = parts[0].Trim(); | |
| } | |
| } | |
| else | |
| { | |
| parsedRoom.IsVirtual = false; | |
| // replace for "Gdansk, ODC, Grunwaldzka, 472B, 7th fl., II-1, Platinum - for Meeting" | |
| if (location.Contains(", ODC,")) | |
| { | |
| location = location.Replace(", ODC,", ","); | |
| } | |
| location = location | |
| .Replace("Hvezdova", "Hvеzdova") // it is the fix for ASCII native code in the text | |
| .Replace("Pevchesky", "Pevcheskiy") | |
| //"Room - Gdansk, Grunwaldzka 472B, 7th fl., Shenzhen - for Meeting" | |
| .Replace("Grunwaldzka 472", "Grunwaldzka, 472") | |
| .Replace("Silina str.", "Silina") // fix for match to office from "Telescope" | |
| .Replace("Auezov str.", "Auezov") // fix for match to office from "Telescope" | |
| .Replace("Bora-Komorowskiego", "Ul. Bora-Komorowskiego") | |
| // fix for match to office from "Telescope" | |
| .Replace("2950 31st, 130", "2950 31st St, Suite 130") | |
| //"Room - San Francisco, 222 Kearny Street, Suite 308, Tupac - for Meeting" | |
| .Replace("222 Kearny Street", "Kearny St., 222") | |
| //"Room - Guadalajara, PN8110, Room 1 - for Meeting" | |
| .Replace("PN8110", "Periferico Norte 8110") | |
| //"Room - Shenzhen, 8F, Blk 8 Vision, ODC C - for Meeting" | |
| .Replace("8F, Blk 8 Vision", "Vision Hi-Tech Park, Blk 8") | |
| //"Room - Newtown, #1 - for Meeting" | |
| .Replace("Newtown", "Newtown, University Dr., 41"); | |
| parts = location.Split(",".ToArray()); | |
| parsedRoom.City = parts[0].Trim(); | |
| if (string.Compare(parts[0], "Minsk", StringComparison.InvariantCultureIgnoreCase) == 0) | |
| { | |
| if (parts.Length > 2) | |
| { | |
| parsedRoom.Office = parts[1].Trim(); | |
| parsedRoom.RoomName = string.Join(",", parts.Skip(2)).Trim(); | |
| } | |
| else | |
| { | |
| // broken room | |
| if (parts.Length == 2 && parts[1].Contains("R40")) | |
| { | |
| parsedRoom.Office = "R40"; | |
| parsedRoom.RoomName = (parts[1].Length > 6 ? parts[1].Substring(6) : parts[1]).Trim(); | |
| } | |
| } | |
| } | |
| if (parts.Length > 3) | |
| { | |
| if (IsFloorDescription(parts[2])) | |
| { | |
| parsedRoom.Office = parts[1].Trim(); | |
| parsedRoom.RoomName = string.Join(",", parts.Skip(2)).Trim(); | |
| } | |
| else | |
| { | |
| var parsedOfficeName = Regex.Match(parts[1], @"^.+\s+\d+\w*$"); | |
| if (parsedOfficeName.Success) | |
| { | |
| parsedRoom.Office = $"{parts[1]}".Trim(); | |
| parsedRoom.RoomName = string.Join(",", parts.Skip(2)).Trim(); | |
| } | |
| else | |
| { | |
| parsedRoom.Office = $"{parts[1]}, {parts[2].Trim()}".Trim(); | |
| parsedRoom.RoomName = string.Join(",", parts.Skip(3)).Trim(); | |
| } | |
| } | |
| } | |
| else | |
| { | |
| parsedRoom.Office = parts.Length > 2 ? parts[1].Trim() : null; | |
| parsedRoom.RoomName = string.Join(",", parts.Skip(parts.Length > 2 ? 2 : 1)).Trim(); | |
| } | |
| // Комнаты без запятой в конце, с отсутствующим именем, будут отображаться как "- for conference" | |
| if (parsedRoom.Office != null && AddressesToFix.ContainsKey(parsedRoom.Office)) | |
| { | |
| var newAddress = AddressesToFix[parsedRoom.Office]; | |
| var diff = newAddress.Length - parsedRoom.Office.Length; | |
| parsedRoom.RoomName = | |
| (parsedRoom.RoomName.Length > diff | |
| ? parsedRoom.RoomName.Substring(diff) | |
| : parsedRoom.RoomName).Trim(); | |
| parsedRoom.Office = newAddress; | |
| } | |
| } | |
| } | |
| else // apartment or something else | |
| { | |
| var apartmentMatch = Regex.Match(adRoom.DisplayName, @"^Apartment\s-\s(.+)$"); | |
| if (apartmentMatch.Success) | |
| { | |
| parsedRoom.IsApartment = true; | |
| var location = apartmentMatch.Groups[1].Value; | |
| var parts = location.Split(','); | |
| parsedRoom.City = parts[0].Trim(); | |
| parsedRoom.RoomName = location; | |
| } | |
| } | |
| if (parsedRoom.Office != null && Offices.ContainsKey(parsedRoom.Office)) | |
| { | |
| parsedRoom.Office = Offices[parsedRoom.Office]; | |
| } | |
| if (parsedRoom.City != null && CitiesToFix.ContainsKey(parsedRoom.City)) | |
| { | |
| parsedRoom.City = CitiesToFix[parsedRoom.City]; | |
| } | |
| var room = ConvertToRoom(parsedRoom, locations); | |
| return room; | |
| } | |
| private static Room ConvertToRoom(ParsedRoom parsedRoom, IList<Location> locations) | |
| { | |
| var result = new Room | |
| { | |
| RoomName = parsedRoom.RoomName, | |
| DisplayName = parsedRoom.DisplayName, | |
| Email = parsedRoom.Email, | |
| ResourceCapacity = parsedRoom.ResourceCapacity, | |
| ResourceDisplay = parsedRoom.ResourceDisplay, | |
| IsVirtual = parsedRoom.IsVirtual, | |
| IsApartment = parsedRoom.IsApartment, | |
| IsDeleted = false | |
| }; | |
| var parentLocationId = GetParentLocationForParsedRoom(parsedRoom, locations); | |
| result.ParentLocationId = parentLocationId?.Id; | |
| return result; | |
| } | |
| private static bool IsFloorDescription(string text) | |
| { | |
| return Regex.IsMatch(text, @".*((\d{1,3}(st|nd|rd|th) fl(oor|.))|(floor \d{1,3})|(grand fl(oor|.)))", | |
| RegexOptions.IgnoreCase); | |
| } | |
| //decode address (like in Telescope) from office short name | |
| private static readonly IDictionary<string, string> Offices = new Dictionary<string, string> | |
| { | |
| {"R40", "Radialnaya, 40"}, | |
| {"R36", "Radialnaya, 36"}, | |
| {"N177", "Nezavisimosti, 177"}, | |
| {"N186", "Nezavisimosti, 186"}, | |
| {"N58", "Nezavisimosti, 58"}, | |
| {"D5", "Dzerzhinskogo, 5"}, | |
| {"H29", "Horugey, 29"}, | |
| {"K1/1", "Kuprevicha, 1/1"}, | |
| {"K1/2", "Kuprevicha, 1/2"}, | |
| {"K1/3", "Kuprevicha, 1/3"}, | |
| {"K10", "Kuprevicha, 10"}, | |
| {"K3", "Kuprevicha, 3"}, | |
| {"K3V", "Kuprevicha, 3V"}, | |
| {"F25G", "Filimonova, 25G"}, | |
| {"L4", "Lozhinskaya, 4"}, | |
| {"G472", "Grunwaldzka, 472"}, | |
| {"T150", "Tirazhnaya, 150"}, | |
| {"Z29", "Zhukova, 29"} | |
| }; | |
| private static readonly IDictionary<string, string> CitiesToFix = new Dictionary<string, string> | |
| { | |
| ["Vinnytsya"] = "Vinnytsia" | |
| }; | |
| private static readonly IDictionary<string, string> AddressesToFix = new Dictionary<string, string> | |
| { | |
| {"Auezov", "Auezov, 8"}, | |
| {"Moskovskoe sh.", "Moskovskoe sh., 39.5"}, | |
| {"Ul. Kielecka", "Ul. Kielecka, 1/2"}, | |
| {"Middlesex St", "Middlesex St, 114"}, | |
| {"Khorenatsi", "Khorenatsi, 15"} | |
| }; | |
| private class ParsedRoom | |
| { | |
| public string Email { get; set; } | |
| public string DisplayName { get; set; } | |
| public int? ResourceCapacity { get; set; } | |
| public string ResourceDisplay { get; set; } | |
| public bool IsVirtual { get; set; } | |
| public bool IsApartment { get; set; } | |
| public string City { get; set; } | |
| public string Office { get; set; } | |
| public string RoomName { get; set; } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment