|
|
Google SiteSearch Box - KazMuzik Blog
2009-05-28 07:07
2009-05-28
長い間、このエントリをアップデートしてきましたが、ブログの移行に際して、今後はアップデートはアップデートしないことにしました。Tags: american_life, caltrain, computer_technology, español, français, game, health, immigration, internet, japanese, jobs_in_america, music, music_and_computer, music_gear, music_technology, programming, rebate, recycle_and_donation, second_life, tax, test, useful_link, walking
|
|
Fingerprint - Naturalization #11 - KazMuzik Blog
2009-03-12 20:02
3/10 に帰宅すると、USCIS から、Fingerprint Notification の I-797, Notice of Action が届いていました。Appointment は、3/19 1pm となっています。ただし、walk-in で、事前に行っても、だいたいは大丈夫なので、早めに済ませておこうと思い、今日の昼休みを利用して行ってきました。30分程度で終了して、1pm には Application Support Center の外に出ていました。
I-485 の時は、大幅な processing delay のために、何度も fingerprint をさせられましたが、今回の fingerprint が一生で最後の、少なくともアメリカ連邦政府に対しての、fingerprint になるはずです。Tags: immigration
|
|
I-797C, Notice of Action delivered #10 - KazMuzik Blog
2009-02-26 20:10
今朝、昨日(2/25)付けでチェックが換金されているのを確認しましたが、帰宅すると、USCIS から I-797C, Notice of Action が届いていました。Priority Date は USCIS が N-400 を受領した 2/18/2008 です。
なお、NoA (Notice of Action) には、application number があり、NBC*0000xxxxx となっていました。NBC から始まるので、USCIS National Benefits Center の扱いになるようです。ちなみに、I-485 の時は、WAC02124xxxxx という番号で、WAC は California Service Center (Western Application Center), 02 は 2002年度、124 は 2002年度の 124 日目(営業日), 以下 5桁は、WAC での他の application も含めての 50000 からの連番でした。今回は '*' がはいっていたり、かなり numbering scheme が変更になっているようです。なお、これで、USCIS の Case Status Online で status を確認できるようになりました。また、registration すると、status が変更されたときに、自動的にメールを受け取ることができます。
今後は、fingerprint, interview (and tests), oath という順で、晴れて U.S.Citizen になることができます。Tags: immigration
|
|
|
|
minor traffic ticket(s) - N-400 #8 - KazMuzik Blog
2009-02-19 08:08
N-400 は、すでに郵送しましたが、ImmigrationPortal Forum の US Citizenship に関する sub-forums を読んでいると、minor な traffic ticket の扱いに関しては、意見が分かれています。
N-400 Instructions の 5ページには、"Note that unless a traffic incident was alcohol or drug related, you do not need to submit documentation for traffic fines and incidents that did not involve an actual arrest if the only penalty was a fine of less than $500 or points on your driver's license." とあるので、このような軽い交通違反に関してはドキュメントを提出する必要はないのですが、N-400 の 9ページには、Part 10, D. Good Moral Character として、"16. Have you ever been arrested, cited, or detained by any law enforcement officer (including USCIS or former INS and military officers) for any reason ?" とあります。Instructions の記述を考慮して、私の場合は、No にチェックして出しましたが、質問だけを取り出して、厳密に答えると、minor な traffic ticket でも citation には違いないので、Yes となってしまいます。つまり、慎重な人は、16 の質問には Yes と答えるべきで、Instructions には、それに関する文書を提出する必要がない、という意味にとらえています。
また、interview や oath の時には、嘘をつくのはだめで、最悪、その事実に基づいて de-naturalization, deportation という risk があります。そこで、徹底的に USCIS を信用していない paranoia 的な人は、minor な traffic ticket でも、すべて報告するべきだと考えています。
一方、現実的に考えて、いくら悪名の高い USCIS (元 INS)とはいえ、minor な traffic ticket をひとつずつ調べて、それを根拠に de-naturalization, deportation という処置に出るとは、考えられません。また、Yes にチェックがある場合、USCIS の職員は、一応、それを考慮しなくてはならなくなるので、手間がかかりますし、実際、interview の時に、minor な traffic ticket に関しては、報告しないでほしい、と言われた例まであるようです。
また、極端な例としては、過去 5年間に、2回の軽微な speeding tickets があった、というだけで、deny された例もあるようです。これは、USCIS の担当者の方が異常で、運が悪かったとしか言えません。
私の場合は、すでに 16 に No にチェックして、提出してしまったので、interview のときに、"Have you ever arrested ?" と質問された場合は、"No" と答え、また "Have you ever arrested or CITED ?" と明確に質問された場合にだけ、"Yes" と答えて、ただし、minor な traffic ticket だったため、Instructions に従って、No にチェックした、と説明することになります。Tags: immigration
|
|
N-400 mailed to USCIS (#7) - KazMuzik Blog
2009-02-17 21:21
昨日、N-400 の準備が出来たので、今朝一番で、近所の郵便局へ行きましたが、すでに 10人以上の待ち行列ができていたために、あきらめて、昼前に、San Francisco の郵便局から発送しました。今年の 1月あたりから郵送先が変更になったようで、Phoenix, AZ の Lockbox 宛に Express Mail ($17.50) で出しました。特に、application で面倒な箇所はなかったので、郵送したのは、N-400 (10ページ), green card の表裏のコピー、2枚の写真($0.21), $675 のチェックと最低限のもので済みました。現在のところ、費用の合計は、$692.71 です。
2009-02-18 update Express Mail は、usps.com で tracking できますが、今日(2/18)の昼前に、無事に配達されたようで、"Notice Left" となっていました。次は、チェックが換金されるのを確認することです。これは、来週になりそうです。USCIS の処理は、どこで滞っているか、信用できないので、ひとつひとつ確実に tracking しておく必要があります。Tags: immigration
|
|
Adobe Reader 9 and GIMP - N-400 #6 - KazMuzik Blog
2009-02-16 21:04
今日は、Presidents Day で、私が約 8年前に U.S. へ来てからは、ずっと Bush が大統領でしたが、去年、めでたく、Obama が勝利して、先月、正式に大統領になりました。本当は、去年の選挙で vote したかったのですが、INS / USCIS の悪質な processing delay のため green card の取得が大幅に遅れ、今月、やっと N-400 をファイルできるところまで、きました。N-400 をファイルして、U.S.Citizen になるのが、Bush の時ではなく、Obama の時で、良かった、と思うことにしておきます。
N-400 は、まだ eFile できないので、記入して郵送することになりますが、PDF ファイルは form になっていて、自分のコンピュウータでタイプして、プリントできるようになっています。先週、保険関係の申請の PDF では、Mac OS X 付属の Preview でもできたのですが、N-400 は最新のバージョンを使っているようで、Adobe Reader 9 を使う必要がありました。
また、30日以内に撮影した photo も必要ですが、妻に digital camera で撮影してもらいました。iMaC#m7 で編集するので、USB ケーブルで接続しました。今回、初めてでしたが、自動的に iPhoto が立ち上がってきて、簡単に取り込むことができました。その後、2"x2" の正方形のイメージを作成するところまでは iPhoto で簡単に出来たのですが、それを、2x3 に並べて、4"x6" のイメージを作成することが出来ず、結局、GIMP を使うことにしました。ただし、今までは、Linux (Fedora) で使っていたので、install されているか、yum で簡単に install できたのですが、今回は Mac OS X なので、Mac OS X 用の GIMP を install しなければいけません。まずは、MacPorts を試してみようと思いましたが、先週、DarwinPorts をインストールしたので、それを使って port install gimp とやりましたが、すぐに止まってしまいます。ただし、CPU は消費しているようですが、ディスクやネットワークにアクセスしている気配もありません。そこで、GIMP on OS X をダウンロードして、インストールしました。こちらの方は X11 の上で、正常に立ち上がってきました。ただし、以前 Linux で使った時とは、若干、操作が異なるところがあり、戸惑うことが何度かありました。また、マウスの移動にカーソルの追従がかなり遅れる場合もありました。しかし、なんとか目的のイメージを作成することができ、Walgreens.com でオーダーしました。今日は、19¢+tax=21¢でした。Tags: computer_technology, immigration
|
|
|
|
|
|
|
|
|
|
|
|
uscis.gov crawled with Ntuch-0.9 - KazMuzik Blog
2008-07-05 22:49
uscis.gov のサイトを、Nutch で crawl してみました。Nutch は、4/12/2007 に 0.9 が release されてから、1年以上 update がありませんが、なれているので、使いました。基本的には、2/24/2007 に紹介した 0.81 のときの手順と同様です。
$ mkdir /KazMuzik/uscis.gov
$ cd /KazMuzik/uscis.gov
$ tar zxvpf .../nutch-0.9.tar.gz
$ cd nutch-0.9
$ vi conf/nutch-site.xml
$ mkdir seeds
$ vi seeds/seeds.txt
$ cat seeds/seeds.txt
http://www.uscis.gov/portal/site/uscis
$ vi conf/crawl-urlfilter.txt
$ cat conf/crawl-urlfilter.txt
-^(file|ftp|mailto):
-\.(gif|GIF|jpg|JPG|png|PNG|ico|ICO|css|sit|eps|wmf|zip|ppt|mpg|xls|gz|rpm|tgz|mov|MOV|exe|jpeg|JPEG|bmp|BMP)$
# -[?*!@=]
-.*(/.+?)/.*?\1/.*?\1/
+^http://([a-z0-9]*\.)*uscis.gov/
-.
$ export NUTCH_JAVA_HOME=/usr/java/jdk
$ nohup bin/nutch crawl seeds &
$ tail -f nohup.out
crawl started in: crawl-20080705105148
rootUrlDir = seeds
threads = 10
depth = 5
Injector: starting
...
merging indexes to: crawl-20080705105148/index
Adding crawl-20080705105148/indexes/part-00000
done merging
crawl finished: crawl-20080705105148
^C
$ bin/nutch readseg -list -dir crawl-20080705105148/segments | sort
20080705105152 1 2008-07-05T10:51:56 2008-07-05T10:51:56 1 1
20080705105202 33 2008-07-05T10:52:06 2008-07-05T10:52:42 39 24
20080705105254 248 2008-07-05T10:52:57 2008-07-05T10:58:28 287 184
20080705105910 1146 2008-07-05T10:59:22 2008-07-05T11:29:36 1191 903
20080705113222 2998 2008-07-05T11:32:29 2008-07-05T12:53:59 3046 2196
NAME GENERATED FETCHER START FETCHER END FETCHED PARSED
$ |
/usr/local に、Tomcat 6.0.16 がインストールされていたので、deploy してみます。
$ cp nutch-0.9.war /usr/loca/tomcat/webapps/uscis.war
$ /usr/local/tomcat/bin/shutdown.sh
$ vi /usr/local/tomcat/webapps/uscis/WEB-INF/classes/nutch-site.xml
$ cat /usr/local/tomcat/webapps/uscis/WEB-INF/classes/nutch-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>searcher.dir</name>
<value>/KazMuzik/uscis.gov/nutch-0.9/crawl-20080705105148</value>
</property>
</configuration>
$ /usr/local/tomcat/bin/startup.sh
$ |
 Tags: computer_technology, immigration
|
|
|
|
|
|
Spring Framework JdbcTemplate - USCIS Processing Times #7 - KazMuzik Blog
2007-12-18 21:14
前回、予告したように、今回からデータベースを用いることにします。12/12 に紹介した Spring Framework から、今回は、JdbcTemplate を用います。
前回の ProcessingTime オブジェクトに対応するテーブルを作成します。
package net.java.sampo.immigration.processingTime.db;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;
import org.apache.commons.chain.impl.ContextBase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class CreateTableCommand implements Command {
private static Log log = LogFactory.getLog(CreateTableCommand.class);
private static final String sql
= "create table PROCESSINGTIME ("
+ "FACILITY varchar(32),"
+ "POSTEDDATE timestamp,"
+ "LINENO integer,"
+ "FORM varchar(8),"
+ "TITLE varchar(128),"
+ "CLASSIFICATION varchar(128),"
+ "TIMEFRAME varchar(32),"
+ "PROCESSINGDATE timestamp,"
+ "DAYS integer,"
+ "primary key(FACILITY, POSTEDDATE, LINENO))";
private JdbcTemplate jdbcTemplate;
public CreateTableCommand() {
}
public void setDataSource(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
public void execute() {
execute(new ContextBase());
}
public boolean execute(Context context) {
try {
jdbcTemplate.execute(sql);
}
catch (DataAccessException e) {
log.error(e);
return true;
}
return false;
}
public static void main(String[] args) throws Exception {
Resource resource = new ClassPathResource("processingTime.xml");
XmlBeanFactory factory = new XmlBeanFactory(resource);
log.info("getting command bean ..");
CreateTableCommand command
= (CreateTableCommand)factory.getBean("createTableCommand");
log.info("executing ...");
command.execute();
}
} |
今までと同様、Command クラスとして、実装しています。Spring Framework の IoC により、Bean の property として、DataSource を与えて、execute() メソッドで、SQL を実行しています。
次は、Spring のリソースファイルです。
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
">
<bean id="createTableCommand"
class="net.java.sampo.immigration.processingTime.db.CreateTableCommand">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="url"
value="jdbc:derby:processingTime.db;create=true" />
</bean>
</beans>
|
DataSource では、Apache Commons DBCP (DataBase Connection Pool) を利用しました。データベースは、いつもの Apache Derby です。なお、commons-dbcp は、Commons Pool を使っているので、実行時には、commons-pool の JAR ファイルも必要になります。Tags: immigration, programming
|
|
USCIS Processing Times Tracking Project #6 - Processing Time & ParserUtils - KazMuzik Blog
2007-12-17 22:19
12/7 に、USCIS の Processing Times について書いてから、posted date は 11/14 のままで、更新はされていません。12/8 に、ProcessingTime クラスと、parser を紹介しましたが、今日は、今後の計画も含めて、アップデートしておきます。
まずは、ProcessingTime ですが、データベースのテーブルの 1行と対応させるため、Facility の名前、Posted Date, (そのページでの) 行番号を追加しておきます。また、元の timeframe は、せっかくデータベースに入れても扱いにくいので、Date 型の Processing Date と、int の timeframe (日数) を返す method も加えておきました。12/10 の snapshot の画像で、サンプルを見ることができます。
package net.java.sampo.immigration.processingTime;
import java.io.Serializable;
import java.util.Date;
import java.util.Formatter;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import static net.java.sampo.immigration.processingTime.ParserUtils.parseDate;
public class ProcessingTime implements Serializable {
private static final Log log = LogFactory.getLog(ProcessingTime.class);
private String facility;
private Date date;
private int lineNo;
private String form;
private String title; // name
private String classification; // basis
private String timeframe;
public ProcessingTime(String facility, Date date, int lineNo,
String form, String name, String timeframe) {
this(facility, date, lineNo, form, name, null, timeframe);
}
public ProcessingTime(String facility, Date date, int lineNo,
String form, String title, String classification, String timeframe) {
this.facility = facility;
this.date = date;
this.lineNo = lineNo;
this.form = form;
this.title = title;
this.classification = classification;
this.timeframe = timeframe;
}
public String getFacility() {
return facility;
}
public Date getDate() {
return date;
}
public int getLineNO() {
return lineNo;
}
public String getForm() {
return form;
}
public String getTitle() {
return title;
}
public String getName() {
return title;
}
public String getClassification() {
return classification;
}
public String getTimeframe() {
return timeframe;
}
public String toString() {
return toString(false);
}
public String toString(boolean additionalInfo) {
Formatter f = new Formatter();
f.format("[%s|%tF|%d|%s|%s|", facility, date, lineNo, form, title);
if (classification != null) {
f.format("%s|", classification);
}
f.format("%s", timeframe);
if (additionalInfo) {
f.format("|%tF|%d", getProcessingDate(), getTimeframeInDay());
}
f.format("]");
return f.toString();
}
public Date getProcessingDate() {
Date postedDate = date;
if (timeframe == null || timeframe.length() == 0) {
return null;
}
String s = timeframe.toLowerCase();
char c = s.charAt(0);
if (c >= 'a' && c <= 'z') {
return parseDate(s);
}
int i = s.indexOf(' ');
int n = 0 - Integer.parseInt(s.substring(0,i));
s = s.substring(i+1);
if (s.startsWith("day")) {
return DateUtils.addDays(postedDate, n);
}
else if (s.startsWith("week")) {
return DateUtils.addWeeks(postedDate, n);
}
else if (s.startsWith("month")) {
return DateUtils.addMonths(postedDate, n);
}
else if (s.startsWith("year")) {
return DateUtils.addYears(postedDate, n);
}
else if (s.startsWith("semana")) {
return DateUtils.addWeeks(postedDate, n);
}
else if (s.startsWith("mese")) {
return DateUtils.addMonths(postedDate, n);
}
else {
log.warn("invalid time frame \"" + timeframe + "\"");
return null;
}
}
public int getTimeframeInDay() {
Date postedDate = date;
Date processingDate = getProcessingDate();
if (processingDate == null) {
return -1;
}
return (int)((postedDate.getTime() - processingDate.getTime()) / 86400000L);
// 86400000 = 24 x 60 x 60 x 1000
}
} |
次は、ParserUtils ですが、parser 関係の method(s) を static として、まとめました。また、USCIS の Processing Times の web での公開は、4年前の 2003年11月から始まっていますが、当時のデータも保存してあったので、それを利用するために、昔のデータも parse できるよう、変更を加えてました。
package net.java.sampo.immigration.processingTime;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Formatter;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class ParserUtils {
private static Log log = LogFactory.getLog(ParserUtils.class);
public static String toTrimedString(Reader in) throws IOException {
StringBuilder sb = new StringBuilder();
for (String line : (List<String>)IOUtils.readLines(in)) {
sb.append(line.trim());
}
return sb.toString();
}
public static String cutContent(byte[] bytes) throws IOException {
Reader in = new InputStreamReader(new ByteArrayInputStream(bytes), "US-ASCII");
return cutContent( toTrimedString(in) );
}
public static String cutContent(File file) throws IOException {
Reader in = new InputStreamReader(new FileInputStream(file), "US-ASCII");
return cutContent(in);
}
public static String cutContent(Reader in) throws IOException {
return cutContent( toTrimedString(in) );
}
public static String cutContent(String html) {
String sl = html.toLowerCase();
int n = sl.indexOf("posted ");
n = sl.indexOf("posted ", n+7);
int m1 = sl.lastIndexOf("<b><big>", n);
if (m1 < 0) { // NBC 2003-11-14
m1 = n;
}
m1 = sl.lastIndexOf(">", m1);
int m2 = sl.indexOf("<", n);
StringBuilder sb = new StringBuilder();
sb.append("<p align=\"center\">");
sb.append(html.substring(m1+1,m2));
sb.append("</p>");
m1 = sl.indexOf("<table", m2);
m2 = sl.indexOf("</table>", m1);
sb.append(html.substring(m1,m2+8));
return sb.toString();
}
public static String parseFacilityName(String content) {
String s = content.toLowerCase();
int n = s.indexOf("<big>");
if (n < 0) {
if (log.isWarnEnabled()) {
log.warn("\"<big> \" tag not found.");
}
return "National Benefits Center"; // NBC 2003-11-14
}
int m = s.indexOf("</", n+5); // 2003-11-14
if (m < 0) {
if (log.isWarnEnabled()) {
log.warn("\"</big> \" tag not found.");
}
return null;
}
String name = content.substring(n+5, m).trim();
// 2003-11-14
if (s.substring(0,n).indexOf("service center") >= 0
&& name.toLowerCase().indexOf("service center") < 0) {
name = name + " Service Center";
}
return name;
}
public static Date parsePostedDate(String content) {
int n = content.toLowerCase().indexOf("posted ");
if (n < 0) {
if (log.isWarnEnabled()) {
log.warn("\"Posted \" not found.");
}
return null;
}
return parseDate(content.substring(n+7));
}
public static ProcessingTime[] parseProcessingTimes(String content) {
String facility = parseFacilityName(content);
Date date = parsePostedDate(content);
int lineNo = 0;
//
String s = content.toLowerCase();
int n = s.indexOf("form");
List<ProcessingTime> list = new ArrayList<ProcessingTime>();
while (true) {
n = s.indexOf("<tr", n);
if (n < 0) {
break;
}
int m = s.indexOf("<tr", n+4); // CSC 2003-11-14 </tr> missing !!
String line = null;
if (m < 0) {
line = content.substring(n);
}
else {
line = content.substring(n, m);
}
list.add( parseLine(facility, date, lineNo, line) );
lineNo ++;
if (m < 0) {
break;
}
n = m;
}
ProcessingTime[] array = new ProcessingTime[ list.size() ];
list.toArray(array);
return array;
}
private static ProcessingTime parseLine(String facility, Date date, int lineNo, String s) {
if (log.isDebugEnabled()) {
log.debug(s);
}
String sl = s.toLowerCase();
int m = sl.indexOf("<b>");
int n = sl.indexOf("<", m+3); // 2003-11-14
List<String> list = new ArrayList<String>(4);
list.add(s.substring(m+3, n).trim()); // form
if (log.isDebugEnabled()) {
log.debug(list);
}
while (true) {
n = sl.indexOf("</td", n+5); // 2005-10-19 District Office
if (n < 0) {
break;
}
m = sl.lastIndexOf(">", n);
list.add( s.substring(m+1, n).trim() );
if (log.isDebugEnabled()) {
log.debug(list);
}
}
ProcessingTime processingTime = null;
if (list.size() == 3) {
processingTime = new ProcessingTime(facility, date, lineNo,
list.get(0), list.get(1), list.get(2));
}
else if (list.size() >= 4) {
processingTime = new ProcessingTime(facility, date, lineNo,
list.get(0), list.get(1), list.get(2), list.get(3));
}
else {
if (log.isWarnEnabled()) {
log.warn("invalid field number = " + list.size() + " for " + s);
}
}
return processingTime;
}
public static Date parseDate(String s) {
int n = s.indexOf(' ');
int m = s.indexOf(',', n+1);
int dd = Integer.parseInt(s.substring(n+1,m));
int yyyy = Integer.parseInt(s.substring(m+2,m+6));
int mm = parseMonth(s.substring(0,n));
if (mm < 1 || mm > 12) {
return null;
}
Calendar cal = Calendar.getInstance();
cal.set(yyyy, mm-1, dd, 12, 0, 0);
return cal.getTime();
}
private static final String[] months = {
"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec"
};
private static int parseMonth(String s) {
s = s.toLowerCase();
for (int i = 0; i < months.length; i++) {
if (s.startsWith(months[i])) {
return i+1;
}
}
return -1;
}
} |
Tags: immigration, programming
|
|
Spring Framework and Apache Commons Chain #2 - USCIS Processing Times #7 - KazMuzik Blog
2007-12-16 07:16
12/12 に、Spring Framework の IoC を用いて、Command を使用する方法を紹介しましたが、これを Chain に拡張して、さらに便利にします。12/11 に、5つの Command(s) からなる Chain を紹介したので、これを例に使います。
まずは、XML のリソースです。
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
">
<bean id="chain" class="net.java.sampo.immigration.processingTime.command.spring.CommandChain">
<property name="commands">
<list>
<ref bean="fetchCommand" />
<ref bean="cutContentCommand" />
<ref bean="parseContentCommand" />
<ref bean="setFilenameCommand" />
<ref bean="writeBytesCommand" />
</list>
</property>
<property name="contextMap">
<map>
<entry key="url"
value="https://egov.uscis.gov/cris/jsps/officeProcesstimes.jsp?selectedOffice=70" />
<entry key="outPath" value="/tmp/pt" />
</map>
</property>
</bean>
<bean id="fetchCommand"
class="net.java.sampo.immigration.processingTime.command.FetchCommand" />
<bean id="cutContentCommand"
class="net.java.sampo.immigration.processingTime.command.CutContentCommand" />
<bean id="parseContentCommand"
class="net.java.sampo.immigration.processingTime.command.ParseContentCommand" />
<bean id="setFilenameCommand"
class="net.java.sampo.immigration.processingTime.command.SetFilenameCommand" />
<bean id="writeBytesCommand"
class="net.java.sampo.immigration.processingTime.command.WriteBytesCommand" />
</beans>
|
"chain" bean では、List で Command の bean(s) を、Map で Context の entry を定義してあります。
次に、"chain" bean の CommandChian クラスです。main() で、上記のリソースを読み込み、実行しています。
package net.java.sampo.immigration.processingTime.command.spring;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;
import org.apache.commons.chain.impl.ChainBase;
import org.apache.commons.chain.impl.ContextBase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class CommandChain extends ChainBase implements InitializingBean {
private static Log log = LogFactory.getLog(CommandChain.class);
private List<Command> commands;
private Map<String,String> contextMap;
private Context context;
public CommandChain() {
context = null;
}
public void setCommands(List<Command> commands) {
this.commands = commands;
}
public List<Command> getCommands() {
return commands;
}
public void setContextMap(Map<String,String> contextMap) {
this.contextMap = contextMap;
}
public Map<String,String> getContextMap() {
return contextMap;
}
public Context getContext() {
return context;
}
public void afterPropertiesSet() {
// adding commands
for (Command command : commands) {
addCommand(command);
}
// setting context
context = new ContextBase();
for (String key : contextMap.keySet()) {
String value = contextMap.get(key);
context.put(key, value);
}
}
public void execute() throws Exception {
super.execute(context);
}
public static void main(String[] args) throws Exception {
Resource resource = new ClassPathResource("chain.xml");
XmlBeanFactory factory = new XmlBeanFactory(resource);
log.info("getting chain ..");
CommandChain chain = (CommandChain)factory.getBean("chain");
Context context = chain.getContext();
log.info("context=" + context);
log.info("executing ...");
chain.execute();
//
context.remove("bytes");
context.remove("content");
context.remove("processingTimes");
log.info("context=" + context);
}
} |
InitializingBean で定義されている afterPropertiesSet() メソッドを実装して、properties がセットされた後に、必要な処理を自動的に行うようにしています。このため、main() では、"chain" bean を get した後は、execute() メソッドを呼ぶだけです。
$ cat log4j.properties
log4j.rootCategory=WARN,A1
log4j.category.net.java.sampo=INFO
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c{1} - %m%n
$ java -classpath .:lib/commons-logging-1.1.1.jar:lib/log4j-1.2.15.jar:lib/commons-chain-1.1.jar\
:lib/commons-io-1.3.2.jar:lib/spring-2.5.jar \
net.java.sampo.immigration.processingTime.command.spring.CommandChain
2007-12-16 07:39:34,508 [main] INFO CommandChain - getting chain ..
2007-12-16 07:39:34,569 [main] INFO CommandChain \
- context={outPath=/tmp/pt, url=https://egov.uscis.gov/cris/jsps/officeProcesstimes.jsp?selectedOffice=70}
2007-12-16 07:39:34,569 [main] INFO CommandChain - executing ...
2007-12-16 07:39:36,012 [main] INFO CommandChain \
- context={outPath=/tmp/pt, facility=San Jose CA, posted=Wed Nov 14 12:00:00 PST 2007,\
url=https://egov.uscis.gov/cris/jsps/officeProcesstimes.jsp?selectedOffice=70,\
outFile=/tmp/pt/San_Jose_CA-20071114.html}
$ |
CommandChain 自体は、今回の USCIS Processing Times の処理と独立しているので、リソースファイルで、Chain で実行する Command の List と、Context の Map を記述すれば、コンパイルせずに、任意の command chain と context を使って実行することができます。Tags: immigration, programming
|
|
USCIS Processing Times #4 - fetcher - KazMuzik Blog
2007-12-10 21:55
USCIS のサイトは、予定より早く、昨晩には立ち上がっていました。まずは、Processing Times のページをすべて fetch して、ローカルに保存しておくことにします。
まずは、特定の URL を fetch してきて、byte 配列に格納して返すクラスです。
package net.java.sampo.immigration.processingTime;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class EgovFetcher {
private static final long minimumFetchInterval = 1000; // 1 sec
private static Log log = LogFactory.getLog(EgovFetcher.class);
private static EgovFetcher fetcher = null;
public static EgovFetcher getInstance() {
if (fetcher == null) {
fetcher = new EgovFetcher();
}
return fetcher;
}
private long lastFetchedTime;
public EgovFetcher() {
lastFetchedTime = -1L;
}
synchronized public byte[] fetch(String url) throws IOException {
if (url == null) {
log.error("url is null.");
return null;
}
long now = System.currentTimeMillis();
long t = minimumFetchInterval - (now - lastFetchedTime);
if (t > 0L) {
if (log.isInfoEnabled()) {
log.info("sleeping " + t + "msecs ..");
}
try {
Thread.sleep(t);
}
catch (InterruptedException e) {
}
now = System.currentTimeMillis();
}
lastFetchedTime = now;
byte[] bytes = null;
InputStream in = new URL(url).openStream();
bytes = IOUtils.toByteArray(in);
return bytes;
}
} |
アクセスが集中しないように、fetch は、1秒間に 1回に制限してあります。また、このためと、使いやすさを考慮して、singleton になっています。
次は、Processing Times のトップページを parse して、facility (Field Office や Service Center)のリストと、それぞれの URL の Collection (List と Map) オブジェクトを準備するクラスです。
package net.java.sampo.immigration.processingTime;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class FacilityUrlMap extends HashMap<String, String> {
private static final String ptimesUrl = " https://egov.uscis.gov/cris/jsps/ptimes.jsp";
private static final String officeUrl
= "https://egov.uscis.gov/cris/jsps/officeProcesstimes.jsp?selectedOffice=";
private static final String centerUrl
= "https://egov.uscis.gov/cris/jsps/Processtimes.jsp?SeviceCenter=";
private static final String nbcUrl = "https://egov.uscis.gov/cris/jsps/NBCprocesstimes.jsp";
private static Log log = LogFactory.getLog(FacilityUrlMap.class);
private static FacilityUrlMap map;
public static FacilityUrlMap getInstance() {
if (map == null) {
map = new FacilityUrlMap();
}
return map;
}
private String[] facilityNames;
public FacilityUrlMap() {
super();
try {
init();
}
catch (IOException e) {
log.fatal(e);
}
}
public String getUrl(String facility) {
return get(facility);
}
public String[] getAllFacilityNames() {
return facilityNames;
}
private void init() throws IOException {
byte[] bytes = EgovFetcher.getInstance().fetch(ptimesUrl);
BufferedReader in
= new BufferedReader(new InputStreamReader(
new ByteArrayInputStream(bytes), "ISO-8859-1"));
parse(in);
}
private void parse(BufferedReader in) throws IOException {
List<String> list = new ArrayList<String>();
int mode = 0;
while (true) {
String line = in.readLine();
if (log.isDebugEnabled()) {
log.debug("" + mode + " : " + line);
}
if (line == null) {
break;
}
String s = line.toLowerCase();
if (mode == 0) {
if (s.indexOf("<select name=\"selectedoffice\">") >= 0) {
mode = 1;
}
else if (s.indexOf("<select name=\"sevicecenter\">") >= 0) { // Sevice : "r" missing !!
mode = 2;
}
continue;
}
if (s.indexOf("</select>") >= 0) {
if (mode == 2) {
break;
}
mode = 0;
continue;
}
//
int n = 0;
while (true) {
int m = s.indexOf("<option value=\"", n);
if (m < 0) {
break;
}
n = s.indexOf('"', m+15);
String id = line.substring(m+15,n).trim();
m = s.indexOf('<', n+2);
String name = line.substring(n+2, m).trim();
log.info(id + " : " + name);
if (mode == 1) {
int intId = Integer.parseInt(id);
put(name, officeUrl + intId);
list.add(name);
}
else if (mode == 2) {
put(name, centerUrl + id);
list.add(name);
}
n = m+8;
}
}
String name = "National Benefits Center";
put(name, nbcUrl);
list.add(name);
//
int n = list.size();
facilityNames = new String[n];
list.toArray(facilityNames);
}
} |
これも singleton です。
以上を利用して、すべての Processing Times のページを fetch して、ファイルに保存する Command クラスです。
package net.java.sampo.immigration.processingTime.command;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import org.apache.commons.chain.Chain;
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;
import org.apache.commons.chain.impl.ChainBase;
import org.apache.commons.chain.impl.ContextBase;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import net.java.sampo.immigration.processingTime.FacilityUrlMap;
public class FetchAllCommand implements Command {
private static Log log = LogFactory.getLog(FetchAllCommand.class);
public boolean execute(Context context) {
FacilityUrlMap urlMap = FacilityUrlMap.getInstance();
if (urlMap == null) {
log.fatal("facility to url map is null.");
return true;
}
String outPath = (String)context.get("outPath");
if (outPath == null) {
log.error("outPath not set in context.");
return true;
}
File outDir = new File(outPath);
if (! outDir.exists()) {
log.warn("outPath not exist. creating..");
if (! outDir.mkdir()) {
log.warn("outPath failed to create.");
return true;
}
}
Chain command = new ChainBase();
command.addCommand(new FetchCommand());
command.addCommand(new CutContentCommand());
command.addCommand(new ParseContentCommand());
command.addCommand(new SetFilenameCommand());
command.addCommand(new WriteBytesCommand());
for (String facility : urlMap.getAllFacilityNames()) {
String url = urlMap.getUrl(facility);
Context eachContext = new ContextBase();
eachContext.put("url", url);
eachContext.put("outPath", outPath);
if (log.isInfoEnabled()) {
log.info(facility + " : " + url + " to " + outPath);
}
try {
command.execute(eachContext);
}
catch (Exception e) {
log.error(e);
}
}
return false;
}
public static void main(String[] args) throws Exception {
String path = "orig";
if (args.length > 0) {
path = args[0];
}
Context context = new ContextBase();
context.put("outPath", path);
Chain command = new ChainBase();
command.addCommand(new FetchAllCommand());
command.execute(context);
}
} |
いくつかの簡単な Command オブジェクトを Chain で使っていますが、これは後に紹介します。(2007-12-11 -> USCIS Processing Times #5 - Command(s) and Chain)
実行して、保存したファイルを加工したページのサンプルを載せておきます。今日(12/10)の時点では、Posted Date は、まだ 11/14 のままでした。

 Tags: immigration, programming
|
|
USCIS Processing Times - Java parser - KazMuzik Blog
2007-12-09 00:58
USCIS の Processing Times ですが、San Jose だけではなく、参考のため、Los Angeles と San Francisco も載せておきます。
| District Office Processing Dates for Los Angeles CA Posted November 14, 2007 |
| Form | Form Name | Processing Timeframe: | | I-131 | Application for Travel Documents | 3 Months | | I-485 | Application to Register Permanent Residence or Adjust Status | 6 Months | | I-600 | Petition to Classify Orphan as an Immediate Relative | July 28, 2007 | | I-600A | Application for Advance Processing of Orphan Petition | July 28, 2007 | | I-765 | Application for Employment Authorization | 11 Weeks | | N-400 | Application for Naturalization | 7 Months | | N-600 | Application for Certification of Citizenship | May 24, 2007 |
| District Office Processing Dates for San Francisco CA Posted November 14, 2007 |
| Form | Form Name | Processing Timeframe: | | I-131 | Application for Travel Documents | 3 Months | | I-485 | Application to Register Permanent Residence or Adjust Status | 6 Months | | I-600 | Petition to Classify Orphan as an Immediate Relative | June 07, 2007 | | I-600A | Application for Advance Processing of Orphan Petition | June 07, 2007 | | I-765 | Application for Employment Authorization | 11 Weeks | | N-400 | Application for Naturalization | 7 Months | | N-600 | Application for Certification of Citizenship | July 06, 2007 |
N-400 に関しては、San Jose は、"March 08, 2007" と処理している日付になっていますが、Los Angeles と San Francisco は、"7 Months" と期間になっています。昔は、すべて、日付による表示でしたが、いつからか、期間による表示も混在するようになったようです。
今日、USCIS の Processing Times のページをアクセスすると、次にようなメッセージが表示されました。
The Case Status Online, Processing Times, Office Locator, and Change of Address Online Systems \
will be experiencing a scheduled outage from 9:30 PM EST
on Friday, December 7 to 8:00 AM EST on Monday, December 10 due to scheduled maintenance. |
週末に、maintenance のためとはいえ、このような mission critical (!?)) なサービスを、丸 2日半(58.5時間)にわたって out of service にするとは、さすが、USCIS です。
Processing Time(s) を parse するクラスを書きましたが、本格的な fetch は、週明け、maintenance が完了してからになります。なお、上記の table(s) は、昨日、保存しておいたものから、テストを兼ねて作成したものです。
package net.java.sampo.immigration.processingTime;
import java.io.Serializable;
public class ProcessingTime implements Serializable {
private String form;
private String title; // name
private String classification; // basis
private String timeframe;
public ProcessingTime(String form, String name, String timeframe) {
this(form, name, null, timeframe);
}
public ProcessingTime(String form, String title, String classification, String timeframe) {
this.form = form;
this.title = title;
this.classification = classification;
this.timeframe = timeframe;
}
public String getForm() {
return form;
}
public String getTitle() {
return title;
}
public String getName() {
return title;
}
public String getClassification() {
return title;
}
public String getTimeframe() {
return timeframe;
}
public String toString() {
return "PT[" + form + "|" + title + "|"
+ ((classification==null)?"":(classification+"|"))
+ timeframe + "]";
}
} |
package net.java.sampo.immigration.processingTime;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Formatter;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import static net.java.sampo.immigration.processingTime.ProcessingTimeUtils.parseDate;
public class ProcessingTimesPageParser extends BufferedReader {
private static Log log = LogFactory.getLog(ProcessingTimesPageParser.class);
private String facilityName;
private Date date;
private ProcessingTime[] processingTimes;
private String content;
public ProcessingTimesPageParser(Reader in) {
super(in);
}
public ProcessingTime[] getProcessingTimes() {
return processingTimes;
}
public String getFacilityName() {
return facilityName;
}
public Date getPostedDate() {
return date;
}
public String getContent() {
return content;
}
public void parseAll() throws IOException {
content = parseContent();
if (log.isDebugEnabled()) {
log.debug(content);
}
facilityName = parseFacility(content);
date = parsePostedDate(content);
processingTimes = parseTable(content);
}
private String parseContent() throws IOException {
int postedCount = 0;
int endTableCount = 0;
StringBuilder sb = new StringBuilder();
String tableTag = null;
while (true) {
String line = readLine();
if (line == null) {
break;
}
line = line.trim();
String lineLowerCase = line.toLowerCase();
if (lineLowerCase.indexOf("<table") >= 0 && postedCount < 2) {
tableTag = line;
}
if (lineLowerCase.indexOf("<tr") >= 0 && postedCount < 2) {
sb = new StringBuilder();
sb.append(tableTag);
if (line.indexOf("<tbody") < 0) {
sb.append("<tbody>");
}
}
sb.append(line);
if (lineLowerCase.indexOf("posted ") >= 0) {
postedCount ++;
}
if (lineLowerCase.indexOf("</table>") >= 0 && postedCount >= 2) {
endTableCount ++;
if (endTableCount >= 2) {
break;
}
}
}
return sb.toString();
}
private String parseFacility(String content) {
String contentLowerCase = content.toLowerCase();
int n = contentLowerCase.indexOf("<big>");
if (n < 0) {
if (log.isWarnEnabled()) {
log.warn("\"<big> \" tag not found.");
}
return null;
}
int m = contentLowerCase.indexOf("</big>", n+5);
if (m < 0) {
if (log.isWarnEnabled()) {
log.warn("\"</big> \" tag not found.");
}
return null;
}
return content.substring(n+5, m);
}
private Date parsePostedDate(String content) {
int n = content.toLowerCase().indexOf("posted ");
if (n < 0) {
if (log.isWarnEnabled()) {
log.warn("\"Posted \" not found.");
}
return null;
}
return parseDate(content.substring(n+7));
}
private ProcessingTime[] parseTable(String content) {
String contentLowerCase = content.toLowerCase();
int n = contentLowerCase.indexOf("processing timeframe");
List<ProcessingTime> list = new ArrayList<ProcessingTime>();
while (true) {
n = contentLowerCase.indexOf("<tr", n);
if (n < 0) {
break;
}
int m = contentLowerCase.indexOf("</tr>", n+4);
list.add( parseLine( content.substring(n, m+5) ) );
n = m;
}
ProcessingTime[] array = new ProcessingTime[ list.size() ];
list.toArray(array);
return array;
}
private ProcessingTime parseLine(String s) {
if (log.isDebugEnabled()) {
log.debug(s);
}
String sl = s.toLowerCase();
int m = sl.indexOf("<b>");
int n = sl.indexOf("</b>", m+3);
List<String> list = new ArrayList<String>(4);
list.add(s.substring(m+3, n).trim()); // form
if (log.isDebugEnabled()) {
log.debug(list);
}
while (true) {
n = sl.indexOf("</td>", n+5);
if (n < 0) {
break;
}
m = sl.lastIndexOf(">", n);
list.add( s.substring(m+1, n).trim() );
if (log.isDebugEnabled()) {
log.debug(list);
}
}
ProcessingTime processingTime = null;
if (list.size() == 3) {
processingTime = new ProcessingTime(list.get(0), list.get(1), list.get(2));
}
else if (list.size() == 4) {
processingTime = new ProcessingTime(list.get(0), list.get(1), list.get(2), list.get(3));
}
else {
if (log.isWarnEnabled()) {
log.warn("invalid field number = " + list.size());
}
}
return processingTime;
}
public static void main(String[] args) throws Exception {
ProcessingTimesPageParser parser
= new ProcessingTimesPageParser(new InputStreamReader(System.in, "ISO-8859-1"));
parser.parseAll();
System.out.printf("%s : %tF%n", parser.getFacilityName(), parser.getPostedDate());
for (ProcessingTime pt : parser.getProcessingTimes()) {
System.out.println(pt.toString());
}
System.out.println(parser.getContent());
}
} |
package net.java.sampo.immigration.processingTime;
import java.util.Calendar;
import java.util.Date;
import java.util.Formatter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class ProcessingTimeUtils {
private static Log log = LogFactory.getLog(ProcessingTimeUtils.class);
public static Date parseDate(String s) {
int n = s.indexOf(' ');
int m = s.indexOf(',', n+1);
int dd = Integer.parseInt(s.substring(n+1,m));
int yyyy = Integer.parseInt(s.substring(m+2,m+6));
int mm = parseMonth(s.substring(0,n));
if (mm < 1 || mm > 12) {
return null;
}
Calendar cal = Calendar.getInstance();
cal.set(yyyy, mm-1, dd);
return cal.getTime();
}
private static final String[] months = {
"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec"
};
private static int parseMonth(String s) {
s = s.toLowerCase();
for (int i = 0; i < months.length; i++) {
if (s.startsWith(months[i])) {
return i+1;
}
}
return -1;
}
} |
一部、不自然なコードもありますが、これは、Field Office (District Office) のページだけではなく、Service Center のページも parse できるようにしたためです。
2007-12-17 update -> USCIS Processing Times Tracking Project #6 - Processing Time & ParserUtils このエントリのコードは、12/17/2007 に、大幅にアップデートしました。Tags: immigration, programming
|
|
USCIS - Advisory on Processing Times - KazMuzik Blog
2007-12-07 22:06
今朝、久しぶりに、USCIS (U.S. Citizenship and Immigration Services) のホームページを見たところ、トップのニュースが、Advisory on Processing Times (*) で、次のような summary が載っています。
USCIS has received a significant increase in the number of applications filed; nearly double the number received in the same period last year. The agency is working to improve processes and focus increased resources, including hiring approximately 1,500 new employees, to address this workload.
As a result, average processing times for certain applications may grow longer. Naturalization applications filed after June 1, 2007 may take approximately 16-18 months to process.
|
リンクのページには、もう少し詳しい数字もあるので、引用しておきます。
... USCIS has received a significant increase in the number of applications filed. In July and August, nearly 2.5 million applications and petitions of all types were received. This compares to 1.2 million applications and petitions received in the same time period last year. This fiscal year, we received 1.4 million applications for naturalization; nearly double the volume we received the year before. The agency is working to improve processes and focus increased resources, including hiring approximately 1,500 new employees, to address this workload.
As a result, average processing times for certain application types may become longer. In particular, naturalization applications filed after June 1, 2007 may take approximately 16 - 18 months to process. ...
|
これは、この夏に申請料を大幅に値上げしましたが、たぶん、その影響だと思われます。特に、Naturalization (N-400) は、ある条件が整えば、いつでも申請できるので、値上げ前に、駆け込みで申請した人が多かったのでは、と予想されます。
せっかく、だいたいの application で、processing time が 6ヶ月~1年未満となってきたところでしたが、ここにきて、また面倒なことになってきました。来年中には、バックログが解消されればいいのですが、USCIS のことなので、ただ期待するだけでは、だめかもしれません。
一応、今日の時点での、San Jose District Office の Processing Time(s) を保存しておきます。
District Office Processing Dates for San Jose CA Posted November 14, 2007 |
| Form |
Form Name |
Processing Timeframe: |
| I-131 |
Application for Travel Documents |
3 Months |
| I-485 |
Application to Register Permanent Residence or Adjust Status |
6 Months |
| I-600 |
Petition to Classify Orphan as an Immediate Relative |
July 05, 2007 |
| I-600A |
Application for Advance Processing of Orphan Petition |
July 05, 2007 |
| I-765 |
Application for Employment Authorization |
11 Weeks |
| N-400 |
Application for Naturalization |
March 08, 2007 |
| N-600 |
Application for Certification of Citizenship |
October 12, 2006 |
Tags: immigration Current Mood: angry
|
|
DV-2009 #2 - Photo - KazMuzik Blog
2007-10-10 18:47
DV-2009 の申請には、デジタル写真を upload しなければいけません。DV-2009 の公式サイトには、Photo Validation のページがあり、事前にチェックすることができます。試しに、昨日、日本のパスポート申請のために準備した U.S. Passport 用の正方形の写真で確認しようとしたところ、62,500 bytes を超えているため、Your photo must be less than 62.5KB in size となりました。Instructions のドキュメントが PDF であるので、よく読むと、いろいろな条件が書いてあり、そのひとつにこのファイルサイズの制限があります。
その下には、解像度の指定があり、320 pixels high by 240 pixels wide とあります。これにけっこう苦労する人がいるみたいです。私は Linux で GIMP を使いますが、次のような手順がわかりやすいと思います。- 解像度は気にしないで、U.S. Passport の基準を満たすように、正方形のイメージを作成する。今回はすでに作成済みでした。
- 320x320 に縮小(あるいは拡大)する。ただし、拡大しなければいけないようだと、鮮明さに欠ける恐れがあり、元の解像度が小さ過ぎたということになります。
- 左右をカットして、320x240 にサイズ変更する。
これで試したところ、Your picture is valid となりました。私は DV-2009 には申請できないので、今回は写真のチェックだけです。
2007-10-10 update Instructions をよく読むと、300x300 の正方形でもいいみたいです。これならば、上記のステップ 2 で、300x300 にすればよく、ステップ 3 を省略できます。試しにやってみましたが、Your picture is valid と、無事にパスしました。
 320x240 |
 300x300 |
Tags: immigration
|
|
|
|
|
|
|
|