newLISPで Amazon を参照する、GUI編。。。または、V.10 対応

 “newLISPで Amazon を参照する。” を紹介した頃は、newLISPが V.9.X時代でした。
 あれから、newLISP は V.10 になり、そのままでは動かなくなっていたのです(汗)。
 そこで、newLISP V.10.0  以降対応版の紹介です。それだけでは、申し訳ないので、GUIしてみました(笑)。
 まずは、ISBN番号のチェックから
 (defun と remove は newlisp-utility.lsp に定義してあります。)

(context 'isbn)
(defun modulus11 (str)
  (let ((n 10) (sum 0))
    (when (apply 'and (map 'int (explode (0 9 str))))
      (dostring (c str (= n 1))
        (setq sum (+ sum (* n (- c 48))))
        (dec n))
      (setq n (- 11 (% sum 11)))
      ((if (= n 10) "X" (string n)))))
      (cond ((= n 10) "X")        ; 2009/ 9/ 9 corrected
            ((= n 11) "0")
            (true (string n)))))) 
(defun modulus10 (str)
  (let ((x (select str '(0 2 4 6 8 10)))
        (y (select str '(1 3 5 7 9 11)))
        (sum 0))
  (setq x (map 'int (explode x)))
  (setq y (map 'int (explode y)))
  (cond ((and (apply 'and x) (apply 'and y))
     (setq x (apply '+ x))
         (setq y (apply '+ y))
         (setq sum (+ x (* 3 y)))
         (string (- 10 (% sum 10))))
         ((string (- 10 (% sum 10))) -1)) ; 2009/ 9/ 2 corrected
    (true nil)))) 
(defun check (str)
  (let (jan (remove "-" (remove "ISBN" (upper-case str))))
    (let ((len (length jan)) (ck))
      (cond ((= len 13) (when (starts-with jan "978")
              (setq ck (modulus10 jan))
              (when (= ck (jan -1))
                (setq jan (3 9 jan))
                (setq ck (modulus11 jan))
                (if ck (setq jan (string jan ck)) nil))))
        ((= len 12) (starts-with jan "978")
         (setq jan (3 9 jan))
         (setq ck (modulus11 jan))
         (if ck (setq jan (string jan ck)) nil))
        ((= len 10) (setq ck (modulus11 jan))
         (if (= ck (jan -1)) jan nll))
        ((= len 9) (setq ck (modulus11 jan))
         (if ck (setq jan (string jan ck)) nil))
        (true nil))))) 
(context MAIN)

 “newLISPでAmazonを開く” からの変更箇所は、dec に ‘ (クォート)がいらなくなった点です。
 そして、Amazon から本の情報を切り出す関数群。(defun は newlisp-utility.lsp に定義してあります。)

(defun get-parts (str start-tag end-tag (addcount 0) (start 0))
  (let ((x (find start-tag str)))
    (let ((y (find end-tag (x str))))
      (x (+ y addcount) str)))) 
(defun get-jpg (str)
  (let (tmp (get-parts str "registerImage("original_image"" "<"))
    (chop ((find "http:" tmp) tmp) 4))) 
(defun get-TEXT (lst)
  (cond ((null lst) nil)
        ((atom? lst) nil)
        ((= "TEXT" (lst 0)) (lst 1))
        (t (dolist (l lst (get-TEXT l)))))) 
(defun get-titleList (str)
  (let ((tmp (get-parts str {<h1 class="parseasinTitle">} "<br />" 6)))
    (let ((xml (xml-parse  tmp (+ 1 2 4))) (result))
      (dolist (l xml)
    (let (s (get-TEXT l))
      (unless (null? s)
        (if (= (l 0) "ELEMENT") (push s result -1)
          (setf (result -1) (append $it " " (trim (trim (replace "n" s " ")) ",")))))))
      result))) 
(defun get-detailList (str)
  (let ((tmp ((find "productDetails" str) str)))
    (setq tmp (get-parts tmp "<li>"  {<li><b>おすすめ度:</b>}))
    (let (xml (xml-parse  tmp (+ 1 2 4)) (result))
      (dolist (l xml)
    (push (list (trim (trim (get-TEXT (l 2 0)) "n")) (trim (trim (get-TEXT (l 2 1)) "n"))) result -1))
      result))) 

 “newLISPで Amazon を参照する。” からの変更箇所は、nth-set を setf に変更した点です。
 ついでに、本の表示画像を取り出す関数get-jpg も用意しました(笑)。
 これらを使い、ISBN番号から、本の情報を取り出すスクリプトです。
 (with-open-file と remove は newlisp-utility.lsp に定義してあります。)

; initialization
(load (append (env "NEWLISPDIR") "/guiserver.lsp"))
; describe the GUI
(gs:init) 
(define FPosX 100)
(define FPosY 50)
(define FWidth 480)
(define FHeight 300)
(define LF 0x0A) 
; event handler
(define (null-handler))
(define (text-handler id c pos) 
  (when (= c LF)
    (when (> pos 1)
      (gs:set-text 'InputText (remove "n" (gs:get-text 'InputText)))
      (search-action))))
(define (search-action)
  (gs:set-text 'BookList "serching...")
  (let (str (gs:get-text 'InputText))
    (let (isbn-code (isbn:check str))
    (if isbn-code 
        (letn (book (get-url (append "http://www.amazon.co.jp/o/ASIN/" isbn-code))
              jpg (get-jpg book))
          (gs:clear-text 'BookList)
          ;(with-open-file (out (string isbn-code "." ((parse jpg ".") -1)) "write") 
          ;  (write-buffer out (get-url jpg)))
          ;(gs:set-text'BookList jpg) (gs:append-text'BookList "n")
          (dolist (lst (get-titleList book))
            (gs:append-text 'BookList lst) (gs:append-text'BookList "n"))
          (dolist (lst (get-detailList book))
            (map (curry gs:append-text 'BookList) lst) (gs:append-text'BookList "n")))
        (gs:set-text 'BookList (string str "is ISBN number?")))
    (gs:set-visible 'Frame true))))
; frame define
(gs:frame 'Frame FPosX FPosY FWidth FHeight "Book-Search from Amazon JAPAN")
; define panel
(gs:panel 'RegsPanel)
(gs:panel 'SavePanel)
; define button & area for panel
(gs:button 'SearchButton 'search-action "search")
(gs:text-area 'InputText 'text-handler 160 22)
(gs:text-area 'BookList 'null-handler)
; mount button & area on panel
(gs:add-to 'RegsPanel 'SearchButton 'InputText)
; set layout for frame & panel
(gs:set-border-layout 'Frame)
(gs:set-flow-layout 'RegsPanel "left")
; mount all on frame
(gs:add-to 'Frame 'RegsPanel "north" 'BookList "center" )
(gs:set-visible 'Frame true) 
; start
(gs:listen)
(exit) 

 bookserch01後は、先頭に、

(load "newlisp-utility.lsp")

 を追加して、これらを “book-search.lsp” とでも名づけ、保存し、DOS窓(コマンド・プロンプト)で、

> newlisp book-search.lsp

 と、打ち込めば、右図のような Window が出るはずです。
 後は、searchボタンの横のテキスト・ボックスに ISBN番号を入力すれば、
booksearch03  下の図のように、その番号の本の情報が得られます。
 上記スクリプト中ほどでコメント・アウトしてある (with-open-file からスクリプトは、
 本の表紙画像を、ISBN番号名で保存するのと、取り込み先URL を表示する部分です。必要に応じてどうぞ。
 ちなみに、表示画像のないものだと、gif の拡張子で保存されますが、内容は、何故か jpeg です。

 さて今回のスクリプトは、GUI といっても、guisever のみの使用ですから、Linux でも、動きます。
 newLISP と JAVA が動いていれば。。。ただし、上記スクリプトのままでは動くだけです。
 Amazon サイトのコードは、Shift-JIS なので、UTF-8 や ECU-JP を使っている Linux では、確実に文字化けします。
 その辺の対応は、別に機会に。先に、V.10対応をやらなくては。。。(汗)

 以上、如何でしょうか?

カテゴリー: LISP パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中