美国移民局签证状态扫描

This commit is contained in:
Yucheng Hu 2017-08-01 01:36:05 -04:00
parent 151daff0e9
commit b204889a78
9 changed files with 597 additions and 0 deletions

View File

@ -0,0 +1,89 @@
package com.usvisatrack.core.dao.model;
import java.util.Date;
import com.usvisatrack.core.common.DataObject;
import com.usvisatrack.core.dao.model.data.VisaEntry;
import com.usvisatrack.core.dao.model.data.VisaStatus;
/**
* Visa ORM
*
* @author YuCheng Hu
*
*/
public class UscisCase extends DataObject {
private User user;
private UscisForm uscisForm;
private UscisCaseStatus uscisCaseStatus;
private String uscisCaseNumber;
private Date dateUscisCaseReceived;
private Date dateVisaIssued;
private Date dateVisaCheckCompleted;
public UscisCase() {
Date date = new Date();
super.setCreateDate(date);
super.setModifyDate(date);
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public UscisForm getUscisForm() {
return uscisForm;
}
public void setUscisForm(UscisForm uscisForm) {
this.uscisForm = uscisForm;
}
public UscisCaseStatus getUscisCaseStatus() {
return uscisCaseStatus;
}
public void setUscisCaseStatus(UscisCaseStatus uscisCaseStatus) {
this.uscisCaseStatus = uscisCaseStatus;
}
public String getUscisCaseNumber() {
return uscisCaseNumber;
}
public void setUscisCaseNumber(String uscisCaseNumber) {
this.uscisCaseNumber = uscisCaseNumber;
}
public Date getDateUscisCaseReceived() {
return dateUscisCaseReceived;
}
public void setDateUscisCaseReceived(Date dateUscisCaseReceived) {
this.dateUscisCaseReceived = dateUscisCaseReceived;
}
public Date getDateVisaIssued() {
return dateVisaIssued;
}
public void setDateVisaIssued(Date dateVisaIssued) {
this.dateVisaIssued = dateVisaIssued;
}
public Date getDateVisaCheckCompleted() {
return dateVisaCheckCompleted;
}
public void setDateVisaCheckCompleted(Date dateVisaCheckCompleted) {
this.dateVisaCheckCompleted = dateVisaCheckCompleted;
}
}

View File

@ -0,0 +1,27 @@
package com.usvisatrack.core.dao.model;
import com.usvisatrack.core.common.DataObject;
/**
* UscisCaseStatus ORM
*
* @author YuCheng Hu
*
*/
public class UscisCaseStatus extends DataObject {
private String uscisCaseStatusName;
public UscisCaseStatus() {
}
public String getUscisCaseStatusName() {
return uscisCaseStatusName;
}
public void setUscisCaseStatusName(String uscisCaseStatusName) {
this.uscisCaseStatusName = uscisCaseStatusName;
}
}

View File

@ -0,0 +1,36 @@
package com.usvisatrack.core.dao.model;
import com.usvisatrack.core.common.DataObject;
/**
* UscisForm ORM
*
* @author YuCheng Hu
*
*/
public class UscisForm extends DataObject {
private String uscisFormCode;
private String uscisFormName;
public UscisForm() {
}
public String getUscisFormCode() {
return uscisFormCode;
}
public void setUscisFormCode(String uscisFormCode) {
this.uscisFormCode = uscisFormCode;
}
public String getUscisFormName() {
return uscisFormName;
}
public void setUscisFormName(String uscisFormName) {
this.uscisFormName = uscisFormName;
}
}

View File

@ -0,0 +1,120 @@
package com.usvisatrack.core.factories;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.usvisatrack.core.common.Factory;
import com.usvisatrack.core.dao.model.CheckeeVisa;
import com.usvisatrack.core.dao.model.USEmbassy;
import com.usvisatrack.core.dao.model.UscisCase;
import com.usvisatrack.core.dao.model.UscisCaseStatus;
import com.usvisatrack.core.dao.model.UscisForm;
import com.usvisatrack.core.dao.model.Visa;
import com.usvisatrack.core.dao.model.VisaClass;
/**
* Item Data Factory
*
* @author YuCheng Hu
*
*/
public class UscisCaseFactory extends Factory {
private static Logger logger = LoggerFactory.getLogger(UscisCaseFactory.class);
private static final int LISTING_PAGE_SIZE = 20;
public static final int DEFAULT_AUTH_EXPIRATION = 10;
/**
*
* @param uscisFormCode
* @return
*/
public static UscisCase getUscisCaseByCaseNumber(String uscisCaseNumber) {
logger.debug("Get UscisCase OBJ by form case number - [{}]", uscisCaseNumber);
try {
Factory.beginTransaction();
Criteria criteria = Factory.createCriteria(UscisCase.class);
criteria.add(Restrictions.eq("uscisCaseNumber", uscisCaseNumber));
criteria.setMaxResults(1);
return (UscisCase) criteria.uniqueResult();
} catch (Exception ex) {
logger.error("Search UscisCase data error", ex);
} finally {
Factory.commitTransaction();
}
return null;
}
/**
* Get Visa OBJ
*
* @param checkkeID
* @return
*/
public static UscisForm getUscisFormByCode(String uscisFormCode) {
logger.debug("Get UscisForm OBJ by form code - [{}]", uscisFormCode);
try {
Factory.beginTransaction();
Criteria criteria = Factory.createCriteria(UscisForm.class);
criteria.add(Restrictions.ilike("uscisFormCode", "%" + uscisFormCode + "%"));
criteria.setMaxResults(1);
return (UscisForm) criteria.uniqueResult();
} catch (Exception ex) {
logger.error("Search UscisForm data error", ex);
} finally {
Factory.commitTransaction();
}
return null;
}
/**
*
* @param uscisCaseStatusName
* @return
*/
public static UscisCaseStatus getUscisCaseStatusByCode(String uscisCaseStatusName) {
logger.debug("Get UscisForm OBJ by form code - [{}]", uscisCaseStatusName);
try {
Factory.beginTransaction();
Criteria criteria = Factory.createCriteria(UscisCaseStatus.class);
criteria.add(Restrictions.ilike("uscisCaseStatusName", "%" + uscisCaseStatusName + "%"));
criteria.setMaxResults(1);
return (UscisCaseStatus) criteria.uniqueResult();
} catch (Exception ex) {
logger.error("Search UscisForm data error", ex);
} finally {
Factory.commitTransaction();
}
return null;
}
/**
* Save UscisCase
*
* @param uscisCase
*/
public static void save(UscisCase uscisCase) {
try {
Factory.beginTransaction();
Factory.saveOrUpdate(uscisCase);
Factory.commitTransaction();
} catch (Exception ex) {
logger.error("Save UscisCase OBJ ERROR", ex);
Factory.rollbackTransaction();
}
}
}

View File

@ -0,0 +1,33 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.usvisatrack.core.dao.model">
<class name="UscisCase" table="uscis_case" catalog="northtecom_usvisatrack">
<id name="id" type="long">
<column name="uscis_case_id" />
<generator class="identity" />
</id>
<many-to-one class="com.usvisatrack.core.dao.model.UscisForm" name="uscisForm" column="uscis_form_fk" fetch="join" />
<many-to-one class="com.usvisatrack.core.dao.model.UscisCaseStatus" name="uscisCaseStatus" column="uscis_case_status_fk"
fetch="join" />
<property name="uscisCaseNumber" type="string">
<column name="uscis_case_number" length="24" />
</property>
<property name="dateUscisCaseReceived" type="date">
<column name="date_uscis_case_received" />
</property>
<property name="createDate" type="timestamp">
<column name="date_add" />
</property>
<property name="modifyDate" type="timestamp">
<column name="date_upd" />
</property>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.usvisatrack.core.dao.model">
<class name="UscisCaseStatus" table="uscis_case_status" catalog="northtecom_usvisatrack">
<id name="id" type="long">
<column name="uscis_case_status_id" />
<generator class="identity" />
</id>
<property name="uscisCaseStatusName" type="string">
<column name="uscis_case_status_name" length="128" />
</property>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.usvisatrack.core.dao.model">
<class name="UscisForm" table="uscis_form" catalog="northtecom_usvisatrack">
<id name="id" type="long">
<column name="uscis_form_id" />
<generator class="identity" />
</id>
<property name="uscisFormCode" type="string">
<column name="uscis_form_code" length="6" />
</property>
<property name="uscisFormName" type="string">
<column name="uscis_form_name" length="128" />
</property>
</class>
</hibernate-mapping>

View File

@ -29,6 +29,9 @@
<!-- HBMs -->
<mapping resource="hbm/CheckeeVisa.hbm.xml" />
<mapping resource="hbm/UscisCase.hbm.xml" />
<mapping resource="hbm/UscisCaseStatus.hbm.xml" />
<mapping resource="hbm/UscisForm.hbm.xml" />
<mapping resource="hbm/USEmbassy.hbm.xml" />
<mapping resource="hbm/User.hbm.xml" />
<mapping resource="hbm/Visa.hbm.xml" />

View File

@ -0,0 +1,254 @@
package com.usvisatrack.services;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.format.DateTimeFormat;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.usvisatrack.core.dao.model.data.UserStatus;
import com.usvisatrack.core.dao.model.data.VisaEntry;
import com.usvisatrack.core.dao.model.data.VisaStatus;
import com.usvisatrack.core.dao.model.CheckeeVisa;
import com.usvisatrack.core.dao.model.UscisCase;
import com.usvisatrack.core.dao.model.User;
import com.usvisatrack.core.dao.model.Visa;
import com.usvisatrack.core.dao.model.VisaClass;
import com.usvisatrack.core.factories.USFactory;
import com.usvisatrack.core.factories.UscisCaseFactory;
import com.usvisatrack.core.factories.UserFactory;
import com.usvisatrack.core.factories.VisaFactory;
import com.usvisatrack.services.common.DataCrawl;
/**
* MerchandiseDataImporter to read folder in disk and import to DB
*
* @author YuCheng Hu
*
*/
public class UscisCaseImporter extends DataCrawl {
private static final Logger logger = LoggerFactory.getLogger(UscisCaseImporter.class);
private final static String URL_USCIS_CASE = "https://egov.uscis.gov/casestatus/mycasestatus.do?appReceiptNum=";
private static List<String> caseNumberList = new ArrayList<>();
public static HashMap<String, VisaClass> visaClassMap = new HashMap<String, VisaClass>();
/**
* Command process function
*/
@Override
public void parseCommandLine(String[] args) {
options.addOption("l", true, "Clean all agents input information");
options.addOption("h", true, "Clean one agent by input email address");
CommandLineParser parser = new DefaultParser();
// parse command line
try {
CommandLine cmd = parser.parse(options, args);
if (cmd.hasOption("s")) {
// this.minId = Integer.parseInt(cmd.getOptionValue("l"));
// this.maxId = Integer.parseInt(cmd.getOptionValue("h"));
}
} catch (Exception e) {
logger.warn("CLI Parse failed, using default timestamp", e);
}
}
/**
* Run Function
*/
@Override
public void run() {
initData(); // Init data from database
for (String caseNumber : caseNumberList) {
crawlUscisCase(URL_USCIS_CASE + caseNumber);
}
}
/**
* crawlWebItem by parse web page
*/
private void crawlUscisCase(String cURL) {
logger.debug("Crawl USCIS Web Data to load Case info.");
Document doc = null;
try {
doc = Jsoup.connect(cURL).get();
// CASE NUMBER
String caseNumber = StringUtils.upperCase(StringUtils.substringAfterLast(cURL, "appReceiptNum="));
// CASE STATUS
String caseStatus = StringUtils.trimToNull(doc.select("h1").get(0).text());
// CASE DATE
String[] caseContentArray = StringUtils.split(doc.select("p").get(0).text(), ",");
String caseDate = StringUtils.trim(StringUtils.substringAfter(caseContentArray[0], "On"));
caseDate = caseDate + "," + StringUtils.trim(caseContentArray[1]);
DateTime dt = DateTimeFormat.forPattern("MMMMM dd,yyyy").parseDateTime(caseDate);
// CASE FORM
String uscisFormCode = StringUtils.trim(StringUtils.substringAfter(caseContentArray[2], "Form"));
logger.debug("Case Number / Form / Date - [{}]/[{}]/[{}]", caseNumber, uscisFormCode, dt);
UscisCase uscisCase = new UscisCase();
uscisCase.setUscisCaseNumber(caseNumber);
uscisCase.setUscisCaseStatus(UscisCaseFactory.getUscisCaseStatusByCode(StringUtils.capitalize(caseStatus)));
uscisCase.setUscisForm(UscisCaseFactory.getUscisFormByCode(uscisFormCode));
uscisCase.setDateUscisCaseReceived(dt.toDate());
UscisCaseFactory.save(uscisCase);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
*
*/
private void initData() {
logger.error("Init Data from Database");
String caseNumber = "SRC1790476518";
String preCaseNumber = StringUtils.left(caseNumber, 8);
long ascCaseNumberDigital = NumberUtils.createLong(StringUtils.right(caseNumber, 5));
long descCaseNumberDigital = NumberUtils.createLong(StringUtils.right(caseNumber, 5));
// ASC
int i = 0;
do {
ascCaseNumberDigital = ascCaseNumberDigital + 1;
String newCaseNumber = StringUtils.upperCase(preCaseNumber + Long.toString(ascCaseNumberDigital));
UscisCase uscisCase = UscisCaseFactory.getUscisCaseByCaseNumber(newCaseNumber);
if (uscisCase == null) {
caseNumberList.add(newCaseNumber);
i++;
} else {
if (Days.daysBetween(new DateTime(), new DateTime(uscisCase.getModifyDate())).getDays() > 3) {
caseNumberList.add(newCaseNumber);
i++;
}
}
} while (i <= 500);
// DESC
i = 0;
do {
descCaseNumberDigital = descCaseNumberDigital + 1;
String newCaseNumber = StringUtils.upperCase(preCaseNumber + Long.toString(descCaseNumberDigital));
UscisCase uscisCase = UscisCaseFactory.getUscisCaseByCaseNumber(newCaseNumber);
if (uscisCase == null) {
caseNumberList.add(newCaseNumber);
i++;
} else {
if (Days.daysBetween(new DateTime(), new DateTime(uscisCase.getModifyDate())).getDays() > 3) {
caseNumberList.add(newCaseNumber);
i++;
}
}
} while (i <= 500);
logger.debug("caseNumberList Size - [{}]", caseNumberList.size());
}
/**
* Get CheckeeCaseNumber from Checkee website
*
* @param element
* @return
*/
private String getCheckeeCaseNumber(Element element) {
String checkeeCaseNumber = null;
Element link = element.select("a").first();
checkeeCaseNumber = StringUtils.substringAfterLast(link.attr("href"), "casenum=");
return checkeeCaseNumber;
}
/**
*
* @param userName
* @return
*/
private User getUser(String checkeeCaseNumber) {
String userName = null;
String userEmail = null;
User user = null;
Document doc = null;
try {
doc = Jsoup.connect("https://www.checkee.info/update.php?casenum=" + checkeeCaseNumber).get();
Elements elements = doc.select("input[name=email_dis]");
userEmail = elements.first().val();
elements = doc.select("b");
userName = StringUtils.trim(StringUtils.substringAfter(elements.get(7).text(), "ID:"));
user = UserFactory.get(userName);
if (user == null) {
user = new User();
user.setUserName(userName);
user.setEmail(userEmail);
UserFactory.save(user);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return user;
}
private void updateVisaNote(Visa visa, String checkeeCaseNumber) {
Document doc = null;
try {
doc = Jsoup.connect("https://www.checkee.info/personal_detail.php?casenum=" + checkeeCaseNumber).get();
Elements newsHeadlines = doc.select("table");
Element table = newsHeadlines.get(2);
for (Element row : table.select("tr")) {
Elements tds = row.select("td");
String dataString = tds.get(0).text();
if (StringUtils.startsWithIgnoreCase(dataString, "Note:")) {
visa.setDescription(StringUtils.trimToEmpty(StringUtils.substringAfter(dataString, "Note:")));
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
logger.debug("Case Description - [{}]", visa.getDescription());
}
}