private static void RaiseCrawlComplete(GoesEventArgs e) { if (CrawlComplete != null) { CrawlComplete(null, e); } }
// This function is called when a crawl is complete public void HandleCrawlCompleted(Object sender, GoesEventArgs e) { mThreadCount--; mCrawlCount++; MethodInvoker inv = delegate { GoesEventArgs g = (GoesEventArgs)e; lblThreadCount.Text = mThreadCount.ToString(); lblCrawlCount.Text = mCrawlCount.ToString(); lblLastCrawlTime.Text = DateTime.Now.ToLongTimeString(); }; this.Invoke(inv); }
// This function is called when a crawl is complete public void HandleCrawlCompleted(Object sender, GoesEventArgs e) { MethodInvoker inv = delegate { mCrawlCount++; lblCrawlCount.Text = mCrawlCount.ToString(); lblLastCrawlTime.Text = DateTime.Now.ToLongTimeString(); if (e != null) { lblLastDateFound.Text = e.GoesResult; } lblStatus.Text = "Waiting for timer"; barTime.Minimum = 0; barTime.Maximum = timerCrawl.Interval; barTime.Value = barTime.Maximum; timerVisuals.Enabled = true; }; this.Invoke(inv); }
// 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; } }