Androidで動くBASICでGoogle Feed APIの自前代替機能をテストする（ BASIC プログラミング ）

【注意事項】

> * この記事はとてもニッチでマニアックです。BASIC!を使う場合以外の利用方法はないと思います。
> * 記事中にHTMLやJavascriptの内容がありますが投稿者の知識レベルは低いです。正直よくわかんないけどやったら動きました♪…レベルです。 

BASIC!は、Androidで動くBASIC インタープリタです。詳しくは以下をどうぞ。

* [AndroidでBASICを使う](http://qiita.com/basictomonokai/items/25bcb21ec69c00e9ad23)

2015年12月に突然死し復活したGoogle Feed APIのBASIC!での後継機能を検討、テストしました。Google Feed APIについては以下をどうぞ。

* [Google AJAX Feed APIとは- Google AJAX Feed API入門](http://www.ajaxtower.jp/googleajaxfeed/before/index2.html)

BASIC!のHTMLモードを使い、RSS1.0、2.0の取得・整形ができたのでまとめます。HTMLモードについては以下をどうぞ。

* [Androidで動くBASICでHTMLをUIやWEBAPIで利用する](http://qiita.com/basictomonokai/items/14c9d3044294253a3)

外部機能の利用はJQueryのみのBASIC!完全自前版になります。本稿中のHTML、JavascriptはBASIC!のHTMLモードで動作するものです。


## 1.処理の概要

処理の考え方は以下の通りです。


* クロスドメイン制約が無いBASIC!ネイティブで外部RSSを取得
* 取得したRSSを含んだHTMLデータをBASIC!ネイティブで生成
* RSSから必要な項目（タイトル、リンク、説明、日付）を抽出・整形するためにHTMLモード上のJavascriptで処理
* HTMLモードでの処理結果をBASIC!ネイティブへの連携機能（Android.dataLink）で受渡
* BASIC!ネイティブで編集処理


BASIC!自身にHTTPサーバー機能がないので先にネィティブで取得したRSSを強引にHTMLに挿入し処理を実行する仕様になります。


## 2.コード

BASIC!のプログラムコードは以下です。


```rsstest.bas
console.title "RSS完全自前版　test"
! rss get
graburl aaa$,"http://rss.rssad.jp/rss/itmnews/1.0/news_bursts.xml"

! template html read
grabfile outhtml$,"rssx0y1.html",1

! replace html particaly
outhtml$=replace$(outhtml$,"@@@1@@@",aaa$)

nxttest:

HTML.OPEN

HTML.LOAD.string outhtml$

xnextUserAction:

! loop until data$ is not ""

DO
 HTML.GET.DATALINK data$
UNTIL data$ <> ""

type$ = LEFT$(data$, 4)

data$ = MID$(data$,5)

! Act on the data type
! Shown are all the current data types

SW.BEGIN type$

 ! Back Key hit.
 ! if we can go back then do it
 SW.CASE "BAK:"
  PRINT "BACK key: " + data$
  popup "終了します",0,0,0
  pause 2000
  end
  SW.BREAK

 ! A hyperlink was clicked on
 SW.CASE "LNK:"
  PRINT "Hyperlink selected: "+ data$
  popup "リンク先をロード中",0,0,1
!  HTML.LOAD.URL data$
  browse data$


  SW.BREAK

 ! An error occured
 SW.CASE "ERR:"
  PRINT "Error: " + data$
  popup "エラーが発生しました 終了します",0,0,0
  pause 2000
  exit
  SW.BREAK

 ! User data returned
 SW.CASE "DAT:"
  PRINT "【HTMLからの受信データ】\n" + data$
  
  ! Check for Exit
  IF data$ = "Exit"
   PRINT "User ended demo."
   HTML.CLOSE
   popup "終了します",0,0,0
   pause 5000
   end
  else
   msx$=data$+"←データの内容"
   popup msx$,0,0,0
   pause 5000
   html.close
   pause 2000
!   goto nxttest
   end
  ENDIF
  SW.BREAK

 ! Form data returned.
 ! Note: Form data returning
 ! always exits the html.

 SW.CASE "FOR:"
  PRINT "Form data: "+data$
  popup "終了します",0,0,0
  pause 2000
  exit
  SW.BREAK



 SW.DEFAULT
  PRINT "Unexpected data type:", type$ + data$
  popup "終了します",0,0,0
  pause 2000
  exit

SW.END

GOTO xnextUserAction


end
```


RSSからのデータ取得はgraburl命令一発で取れます。

これをHTMLに強引に挿入するためにテンプレート用HTMLファイルをgrabfile命令で変数に読込しreplace$関数でHTMLの特定の場所(@@@1@@@)を置換しています。

あとは通常のHTMLモードに従う形になります。このプログラムではHTMLモード側で処理したデータをコンソール画面で表示してるだけです。

続いてテンプレート用HTMLファイルは以下になります。


```rssx0y1.html
﻿<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>RSSのテスト</title>
    <script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>
</head>
  <body>
<h1>RSSフィード表示サンプル</h1>
<textarea id='zzz'>
@@@1@@@
</textarea>

<div id="rss"></div>


    <script>
      
      // ロード完了イベント
      $(document).ready(function(){
			var row = 0;
			var data = [];
			var nodeName;
			var output = $('#rss');
                        var xml = document.getElementById("zzz").value
// start item 成形
			$(xml).find('item').each(function() {
				data[row] = {};
				$(this).children().each(function() {
				    nodeName = $(this)[0].nodeName;
				    data[row][nodeName] = {};
				    attributes = $(this)[0].attributes;
				    for (var i in attributes) {
						data[row][nodeName][attributes[i].name] = attributes[i].value;
				    }
					data[row][nodeName]['text'] = $(this).text();

                                        if (nodeName == 'LINK'){
					    data[row][nodeName]['text'] = this.nextSibling.data;
                                        };

                                        if (nodeName == 'DESCRIPTION'){
					    data[row][nodeName]['text'] = $(this).text().replace("]]>","");
                                        };


				});
				row++;
			});
// end item 成形
                        var outrss
                        outrss = '';
			for (i in data) {
                            if (data[i].DESCRIPTION == null) {
                              if (data[i].PUBDATE == null) {
                                output.append('<li><a href="' + data[i].LINK.text + '">' + data[i].TITLE.text + '</a>' + data[i]['DC:DATE']['text'] + '</li><br>');
                                outrss = outrss + data[i].TITLE.text + '@x@' + '※説明なし' + '@x@' + data[i].LINK.text + '@x@' + data[i]['DC:DATE']['text'] + "@y@";
                              } else {
                                output.append('<li><a href="' + data[i].LINK.text + '">' + data[i].TITLE.text + '</a>' + data[i].PUBDATE.text + '</li><br>');
                                outrss = outrss + data[i].TITLE.text + '@x@' + '※説明なし' + '@x@' + data[i].LINK.text + '@x@' + data[i].PUBDATE.text + "@y@";
                              }
                            } else {
                              if (data[i].PUBDATE == null) {
                                output.append('<li><a href="' + data[i].LINK.text + '">' + data[i].TITLE.text + '</a>' + data[i].DESCRIPTION.text + data[i]['DC:DATE']['text'] + '</li><br>');
                                outrss = outrss + data[i].TITLE.text + '@x@' + data[i].DESCRIPTION.text + '@x@' + data[i].LINK.text + '@x@' + data[i]['DC:DATE']['text'] + "@y@";
                              } else {
                                output.append('<li><a href="' + data[i].LINK.text + '">' + data[i].TITLE.text + '</a>' + data[i].DESCRIPTION.text + data[i].PUBDATE.text + '</li><br>');
                                outrss = outrss + data[i].TITLE.text + '@x@' + data[i].DESCRIPTION.text + '@x@' + data[i].LINK.text + '@x@' + data[i].PUBDATE.text + "@y@";
                              }
                            };
			}
                        alert(outrss);
                        Android.dataLink(outrss);
    });


    </script>
  </body>
</html>
```


textareaタグ内にRSSが挿入されるのでそれを受けてJavascriptが実行されます。

タイトルやリンクは必ずあるのですが、説明(DESCRIPTION)は無いRSSもあるようです。日付もPUBDATEやDC:DATEでマチマチなのでそこは考慮しています。

Android.dataLinkで整形した内容をBASIC!ネイティブに受渡します。

## 3.実行結果

実行結果は写真の通りです。外部RSSの取得が出来ています。

![1456372023.jpg](https://qiita-image-store.s3.amazonaws.com/0/35574/c0baef6c-06ef-11c7-d23b-d1694e619ea2.jpeg)

## 4.まとめ

このようにBASIC!完全自前版でRSS外部受信は可能です。ただベストな方法ではないかもしれません。こんなこと何で自前でやらなきゃいけないのかという根本的な疑問はありますが…

「Yahoo! Pipes」はすでにこの世に無く、最近有名なWebスクレイパーサービス「Kimono」も2015年２月サービス終了だそうです。

個人的にはGoogle Feed APIやYQLもいつまで続くかわからないとの不安を感じています。少しでも予防策を講じる必要はあるかなと思っています。