// Desktop Application entry point public static void DesktopCrawlSite(Object pObj) { GoesUser goes_user = (GoesUser)pObj; goes_user.mAppType = GoesUser.AppType.Desktop; CrawlSite(goes_user); }
// This is how we start multiple, parallel crawls; each on its own thread public bool StartSingleSiteCrawl() { // Validate the user info GoesUser pUser = new GoesUser(); pUser.mUser_id = 0; pUser.mUsername = txtUsername.Text; pUser.mPassword = txtPassword.Text; pUser.mLocation_Name = cmboLocation.SelectedItem.ToString(); // Check the registration database if (pUser.CheckUserRegistration()) { // Start the new Thread ParameterizedThreadStart ptsd = new ParameterizedThreadStart(GoesCrawler.DesktopCrawlSite); Thread thread = new Thread(ptsd); thread.Start(pUser); lblStatus.Text = "Running"; timerVisuals.Enabled = false; return(false); } else { // Invalid user. MessageBox.Show("The username isn not valid. You need to regiter at http://www.globalEntryInterview.com.", "Validation Error"); return(false); } }
// Server Application entry point public static void AppCrawlSite(Object pObj) { Int32 pUser_id = (Int32)pObj; LogStatus(pUser_id, "Started processing for " + pUser_id.ToString()); // lblLastCrawlTime.Text = DateTime.Now.ToShortTimeString(); GoesUser goes_user = new GoesUser(); if (goes_user.GetDataForUser(pUser_id) == true) { goes_user.mAppType = GoesUser.AppType.Server; CrawlSite(goes_user); } else { LogStatus(pUser_id, "The Userprofile is not complete. Check the profile page and/or https://www.globalentryinterview.com/interview-as-a-service/", ""); RaiseCrawlComplete(null); return; } }
// Main thread for the site crawl // It's a monolithic function but follows a simple pattern // each step tries to find an HTML object and throws an exception when the object is not found public static void CrawlSite(GoesUser pUser) { using (IWebDriver driver = new FirefoxDriver()) { if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, "App Driver opened for " + pUser.mUsername); } // Start the Browser driver.Navigate().GoToUrl("https://goes-app.cbp.dhs.gov/goes/"); // Find the username object. // When this fails, the site didn't load. Most likely because the computer is offline. try { driver.FindElement(By.Id("j_username")).SendKeys(pUser.mUsername); } catch (Exception ex) { if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, "The GOES website didn't load as expected. Check your internet connection and retry.", ex.Message); } else { ShowMessage("The GOES website didn't load as expected. Check your internet connection and retry."); } RaiseCrawlComplete(null); return; } // When we find the username object, we can then populate the other fields. driver.FindElement(By.Id("j_password")).Clear(); driver.FindElement(By.Id("j_password")).SendKeys(pUser.mPassword); driver.FindElement(By.Id("SignIn")).Click(); // Get past the "I'm a Human" checkbox thingy try { driver.FindElement(By.Id("checkMe")).Click(); } catch (Exception ex) { String strErrorMessage = "GOES Username or password is not valid."; if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, strErrorMessage, ex.Message); SendErrorEmail(strErrorMessage, pUser.mEmail); } else { ShowMessage(strErrorMessage); } RaiseCrawlComplete(null); return; } // Click the Manage Appointment button // Get past the "I'm a Human" thingy try { driver.FindElement(By.Name("manageAptm")).Click(); } catch (Exception ex) { String strErrorMessage = "Manage Appointment button is not found. Has your application been approved?"; if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, strErrorMessage, ex.Message); SendErrorEmail(strErrorMessage, pUser.mEmail); } else { ShowMessage(strErrorMessage); } RaiseCrawlComplete(null); return; } DateTime dateInterview; String CurrentInterview; // Capture my current Date of the interview try { IWebElement elem = driver.FindElement(By.XPath("//*[contains(.,'Interview Date:')]")); if (elem == null) { String strErrorMessage = "The current inteview date is not found. Has your application been approved?"; if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, strErrorMessage, "None"); SendErrorEmail(strErrorMessage, pUser.mEmail); } else { ShowMessage(strErrorMessage); } RaiseCrawlComplete(null); return; } int pos = elem.Text.IndexOf("Interview Date:"); CurrentInterview = elem.Text.Substring(pos + 16, 12); dateInterview = Convert.ToDateTime(CurrentInterview); } catch (Exception ex) { String strErrorMessage = "The current inteview date is not found. Has your application been approved?"; if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, strErrorMessage, ex.Message); SendErrorEmail(strErrorMessage, pUser.mEmail); } else { ShowMessage(strErrorMessage); } RaiseCrawlComplete(null); return; } // Check for interview date in the past. This happens when someone misses their appointment. if (DateTime.Compare(dateInterview, DateTime.Now) < 0) { String strErrorMessage = "Your current inteview date is in the past. You need to manually schedule your interview the first time."; if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, strErrorMessage); SendErrorEmail(strErrorMessage, pUser.mEmail); } else { ShowMessage(strErrorMessage); } RaiseCrawlComplete(null); return; } // Click the Reschedule button try { driver.FindElement(By.Name("reschedule")).Click(); } catch (Exception ex) { String strErrorMessage = "Reschedule button is not found. Has your application been approved?"; if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, strErrorMessage, ex.Message); SendErrorEmail(strErrorMessage, pUser.mEmail); } else { ShowMessage(strErrorMessage); } RaiseCrawlComplete(null); return; } // Pick the proper location try { bool bLocationFound = false; // new SelectElement(driver.FindElement(By.Id("selectedEnrollmentCenter"))).SelectByText(pUser.mLocation_Name); ReadOnlyCollection <IWebElement> we = driver.FindElements(By.Name("selectedEnrollmentCenter")); foreach (var title in we) { String text = title.GetAttribute("title"); if (text.Trim().CompareTo(pUser.mLocation_Name.Trim()) == 0) { title.Click(); bLocationFound = true; break; } } // new SelectElement(driver.FindElement(By.Name("selectedEnrollmentCenter"))).SelectByText(pUser.mLocation_Name); // String strPath = "//*[@title='" + pUser.mLocation_Name + "']"; // IWebElement we = driver.FindElement(By.XPath(strPath)); // new SelectElement(we); if (bLocationFound) { driver.FindElement(By.Name("next")).Click(); } else { String strErrorMessage = "Can''t find your selected Enrollment Center. Usually means the site had an error."; if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, strErrorMessage); SendSupportEmail(strErrorMessage); } else { ShowMessage(strErrorMessage); } RaiseCrawlComplete(null); return; } } catch (Exception ex) { String strErrorMessage = "Can''t find your selected Enrollment Center. Usually means the site had an error."; if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, strErrorMessage, ex.Message); SendSupportEmail(strErrorMessage); } else { ShowMessage(strErrorMessage); } RaiseCrawlComplete(null); return; } // Find and parse the current next available date DateTime dateAvailable; try { String CurrentDate = driver.FindElement(By.ClassName("header")).Text; String[] stringDateParts = CurrentDate.Split('\r'); String stringModifiedDate = stringDateParts[0] + " " + stringDateParts[2].Substring(1); dateAvailable = Convert.ToDateTime(stringModifiedDate); } catch (Exception ex) { String strErrorMessage = "Cant find header with current interview date. Check the site for changes."; if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, strErrorMessage, ex.Message); SendSupportEmail(strErrorMessage); } else { ShowMessage(strErrorMessage); } RaiseCrawlComplete(null); return; } // Now compare the dates and book the new if earlier than current interview date if (DateTime.Compare(dateAvailable, dateInterview) < 0) { // This block schedules the new appointment driver.FindElement(By.ClassName("entry")).Click(); driver.FindElement(By.Id("comments")).Clear(); driver.FindElement(By.Id("comments")).SendKeys("Looking for an earlier interview"); driver.FindElement(By.Name("Confirm")).Click(); // Find the New Interview Time Int32 intTimePos = driver.PageSource.IndexOf("New Interview Time:"); String strNewTime = driver.PageSource.Substring(intTimePos + 20, 8); SendEmail(dateAvailable.ToShortDateString(), strNewTime, pUser.mEmail); if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, dateAvailable, "Congratulations! We found an earlier date. The process has stopped, please visit the site if you want to continue searching for an earlier date."); SetUserStatus(pUser.mUser_id, 3); } else { ShowMessage("Congratulations! We found an earlier date. The process has stopped, please visit the site if you want to continue searching for an earlier date."); } } else { if (pUser.mAppType == GoesUser.AppType.Server) { LogStatus(pUser.mUser_id, dateAvailable, "Searched the site. Earliest date is " + dateAvailable.ToShortDateString()); SetUserStatus(pUser.mUser_id, 1); } GoesEventArgs ge = new GoesEventArgs(); ge.GoesResult = dateAvailable.ToShortDateString(); RaiseCrawlComplete(ge); return; } return; } }