Skip to content

Instantly share code, notes, and snippets.

@jakobz
Created May 22, 2018 15:02
Show Gist options
  • Select an option

  • Save jakobz/d7070f049fa2ddc62f08d4dc87c8f904 to your computer and use it in GitHub Desktop.

Select an option

Save jakobz/d7070f049fa2ddc62f08d4dc87c8f904 to your computer and use it in GitHub Desktop.
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