[PR] 不動産担保ローン
Apache James + Groovy でメール連携アプリケーション その4
今回はGroovyのスクリプトを考えてみます。
ISBN -> 書籍名に変換するよいwebapiが見当たらなかったので
自力で取得し、一度取得したものはDBにキャッシュするようにしました。
ちなみに、Groovy書くのは初めてです。
以下のスクリプトをappend.groovyとし、
/var/local/james/に保存します。
■append.groovy
import jp.dip.dkdc.james.*;
import java.sql.*;
import groovy.sql.Sql
//書籍情報クラス
class BookData {
String bookTitle
String author
String publisher
int count = 0
}
//全角・半角数値をとりあえずintへ変換
def toNumber(value){
temp = 0
for (int i = 0; i < value.length(); i++) {
switch (value[i]) {
case '1':
case '1':
temp = temp * 10 + 1
break
case '2':
case '2':
temp = temp * 10 + 2
break
case '3':
case '3':
temp = temp * 10 + 3
break
case '4':
case '4':
temp = temp * 10 + 4
break
case '5':
case '5':
temp = temp * 10 + 5
break
case '6':
case '6':
temp = temp * 10 + 6
break
case '7':
case '7':
temp = temp * 10 + 7
break
case '8':
case '8':
temp = temp * 10 + 8
break
case '9':
case '9':
temp = temp * 10 + 9
break
case '0':
case '0':
temp = temp * 10 + 0
break
}
}
return temp
}
//メールアドレスからユーザIDを取得
def getUserId(sql, user_address) {
def user_count = sql.firstRow(
"select count(*) as user_count from user_address where mail = '" + user_address + "'").user_count
def user_id = 0
if (user_count == 0) {
user_id = sql.firstRow("select coalesce(max(id) + 1,1) as user_id from user_address").user_id
def usert = sql.dataSet("user_address")
usert.add(mail:user_address, id:user_id)
} else {
user_id = sql.firstRow("select id from user_address where mail = '" + user_address + "'").id
}
return user_id
}
//ISBNから書籍データ取得
def getBookData(isbn, sql) {
//一旦DBを検索
BookData book = getBookData4DB(isbn, sql)
if (book == null) {
//DBにデータがなければweb検索
url_str = "http://bookweb.kinokuniya.co.jp/guest/cgi-bin/wshosea.cgi?W-ISBN=${isbn}"
book = getBookData4URL(url_str)
if (book.bookTitle != null) {
//キャッシュにデータを追加
def bookt = sql.dataSet("book_data")
bookt.add(isbn:isbn, title:book.bookTitle ,count:book.count, author:book.author, publisher:book.publisher)
} else {
book = null
}
}
return book
}
//DBのキャッシュを検索
def getBookData4DB(isbn, sql){
def book_count = sql.firstRow("select count(*) as book_count from book_data where isbn = " + isbn).book_count
if (book_count == 0) {
return null
}
row = sql.firstRow("select * from book_data where isbn = " + isbn)
BookData book = new BookData()
book.bookTitle = row.title
book.author = row.author
book.publisher = row.publisher
book.count = row.count
return book
}
//webページから書籍名を取得
def getBookData4URL(url_str) {
isHit = false
hitAfter = 0
BookData data = new BookData()
def url = new URL(url_str)
input=new BufferedReader(new InputStreamReader(url.openStream(), 'Shift_JIS'));
while((s=input.readLine()) != null){
if (s.contains('<span class="font16"><strong>')) {
isHit = true
//本の名前
s = s - '<span class="font16"><strong>' - '</strong></span><br />'
sp = s.tokenize('〈〉')
data.bookTitle = sp[0]
if (sp.size > 2) {
data.count = toNumber(sp[1])
}
}
if (s.contains('<h3 class="pro-bname">')) {
return getBookData4URL('http://bookweb.kinokuniya.co.jp' + s.tokenize('"')[3])
}
if (isHit) {
hitAfter++
}
if (hitAfter == 4) {
//作者
data.author = s.tokenize('<')[0].tokenize('>')[1]
} else if (hitAfter == 5) {
//出版社
data.publisher = s.tokenize('<')[0].tokenize('>')[1]
break
}
}
return data
}
//返信内容取得
def bookComment(isbn, sql, user_id) {
def comment = ""
def book_count = sql.firstRow(
"select count(*) as book_count from user_books where (isbn = " + isbn + ") and (id = " + user_id + ")"
).book_count
if (book_count == 0) {
def ubt = sql.dataSet("user_books")
ubt.add(isbn:isbn, id:user_id)
comment = "この本は持っていません。追加しました。\n"
} else {
comment = "この本は所持しています。\n"
}
return comment
}
//ISBNとしての妥当性検証
//といても、10もしくは13桁かのチェックのみ
def isISBN(value) {
if (value == null) {
return false
}
return ((value.length() == 10) || (value.length() == 13))
}
//ISBNから書籍名を解析
//また、このユーザがこの書籍を保持しているのか確認
def analize(isbn, sql, user_id) {
result = ""
if (isbn == null) {
return result
}
if (isISBN(isbn)) {
book = getBookData(isbn, sql)
if (book == null) {
result += isbn + ":書籍が特定できません。\n"
} else {
result += isbn + ":" + book.bookTitle
if (book.count > 0) {
result += "(" + book.count + ")"
}
result += "\n"
//この本に対するコメントを付加
result += bookComment(isbn, sql, user_id)
}
} else {
result += isbn + ":ISBNの桁数が不正です\n"
}
return result
}
//Jamesから渡されたメールデータ
MailData data = (MailData)mail
//Jamesから渡されたコネクション
Connection con = (Connection)db
//groovy.sqlを生成
def sql = new Sql(con)
//メールアドレスからユーザID取得
def user_id = getUserId(sql, data.getSender())
BookData book = null;
resultBody = ""
//タイトル解析
resultBody += analize(data.getSubject(), sql, user_id)
//本体解析
if (data.getBody() != null) {
line = data.getBody().replaceAll("\r", "")
lines = line.tokenize("\n")
for (int i = 0; i < lines.size; i++) {
resultBody += analize(lines[i], sql, user_id)
}
}
MailData result = new MailData()
result.setSubject("解析結果")
result.setBody(resultBody)
result.setSender(data.getSender())
return result
【参考URL】
http://kakutani.com/trans/ociweb/
http://www.jdocs.com/groovy/1.0.jsr06/groovy/sql/DataSet.html
http://groovy.codehaus.org/Database+features
もどる