/// <summary> /// compare the key of two Availability objects /// </summary> /// <param name="ava1"></param> /// <param name="ava2"></param> /// <returns></returns> public static bool isSameKey(Availability ava1, Availability ava2) { return(ava1.carrier.id == ava2.carrier.id && ava1.product.partNumber == ava2.product.partNumber && ava1.store.storeNumber == ava2.store.storeNumber); }
/// <summary> /// send email /// </summary> private static void notify(Availability[] availability, Availability[] previousAvailability, Configuration config) { // count number of available products int available_count = 0; { Dictionary <string /*part number*/, HashSet <string /*carrier id*/> > table = new Dictionary <string, HashSet <string> >(); foreach (var ava in availability) { if (!ava.isAvailable) { continue; } HashSet <string> carriers; if (table.ContainsKey(ava.product.partNumber)) { carriers = table[ava.product.partNumber]; } else { carriers = new HashSet <string>(); table.Add(ava.product.partNumber, carriers); } if (carriers.Contains(ava.carrier.id)) { continue; } carriers.Add(ava.carrier.id); available_count++; } } // compose email body string body = ""; body += "<!DOCTYPE html>"; body += "<html>"; body += "<head>"; body += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"; body += "</head>"; body += "<body style=\"font-family: 'Arial';\">"; body += "<div>"; body += "<p>"; body += "<small>Time:</small>"; body += "<br/>"; body += (DateTime.UtcNow + TimeSpan.FromHours(8)).ToString("yyyy-MM-dd HH:mm:ss") + " HKT"; body += "</p>"; body += "</div>"; body += "<div>"; body += "<p>"; body += "<small>Zip code:</small>"; body += "<br/>"; body += config.zipCode; body += "</p>"; body += "</div>"; body += "<div>"; body += "<p>"; body += "<small>Available for pickup:</small>"; body += "<br/>"; body += (available_count == 0 ? "Nothing" : (available_count + " models")); body += "</p>"; body += "</div>"; body += "<div>"; { Dictionary <string, Carrier> carriers = new Dictionary <string, Carrier>(); Dictionary <string, Product> products = new Dictionary <string, Product>(); foreach (var ava in availability) { if (!products.ContainsKey(ava.product.partNumber)) { products.Add(ava.product.partNumber, ava.product); } if (!carriers.ContainsKey(ava.carrier.id)) { carriers.Add(ava.carrier.id, ava.carrier); } } foreach (var ava in previousAvailability) { if (!products.ContainsKey(ava.product.partNumber)) { products.Add(ava.product.partNumber, ava.product); } if (!carriers.ContainsKey(ava.carrier.id)) { carriers.Add(ava.carrier.id, ava.carrier); } } foreach (var carrier in carriers.Values) { foreach (var product in products.Values) { body += "<div>"; body += "<p>"; body += product.name + " (" + carrier.name + ")"; body += "<br/>"; var ava_new_all = availability.Where(a => a.carrier.id == carrier.id && a.product.partNumber == product.partNumber && a.isAvailable).ToArray(); var ava_prev_all = previousAvailability.Where(a => a.carrier.id == carrier.id && a.product.partNumber == product.partNumber && a.isAvailable).ToArray(); bool newly_available = ava_new_all.Length > 0; bool previously_available = ava_prev_all.Length > 0; if (!newly_available && !previously_available) { body += "Unavailable<br/>"; } else { foreach (var ava_new in ava_new_all) { var ava_prev = ava_prev_all.FirstOrDefault(a => Availability.isSameKey(ava_new, a)); body += "- " + ava_new.store.name; if (ava_prev == null) // newly found { body += " <small><font color=\"blue\">[new]</font></small>"; } body += "<br/>"; } foreach (var ava_prev in ava_prev_all) { var ava_new = ava_new_all.FirstOrDefault(a => Availability.isSameKey(ava_prev, a)); if (ava_new != null) { continue; // no change, already outputted in the previous loop, skip } body += "- <strike>" + ava_prev.store.name + "</strike>"; body += "<br/>"; } } body += "</p>"; body += "</div>"; } } } body += "</div>"; body += "<div>"; body += "<p><a href=\"" + config.reserveUrl + "\">Click here to reserve</a></p>"; body += "</div>"; body += "</body>"; body += "</html>"; // send Gmail gmail = new Gmail() { GmailId = config.notification.sender, GmailPassword = config.notification.senderPassword, To = config.notification.recipients, IsHtml = true, Subject = "iPhone X pickup availability " + (DateTime.UtcNow + TimeSpan.FromHours(8)).ToString("yyyy-MM-dd HH:mm") + " HKT", Body = body }; gmail.Send(); }