Edited at

News API利用でBASIC!でニュースを検索( BASIC プログラミング )

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

ニュースのWEBAPIはなかなか良いのがありませんが日本語でも情報量がまぁまぁあって便利なAPIがあったのでBASIC!のHTMLモードでニュース検索するプログラムを作ってみました。


1.NEWS API

かなり有名なサイトらしいので特に説明は不要だと思います。ドキュメントもちゃんと整備されていてわかりやすいです。

News API

https://newsapi.org/


  • 非商用なら無料で利用可能らしい

  • 日本語のニュースソースもまぁまぁある

  • AND、OR、NOTなど条件検索もできる


2.作ったプログラム

複数の検索文字列をtextareaに入力して検索ボタンを押すと検索結果がアコーディオンで表示されます。

ほとんどHTML、CSS、JavaScriptでBASIC!は画面制御関連のみに使っています。


3.コード

さっそくコードです。HTMLファイルとBASファイルが1本づつです。ポイントは以下

(HTML)


  • 検索文字列はLocalStorageに保存

  • FetchでNEWS APIのエンドポイントを呼出し

  • アコーディオンで表示

(BASIC!)


  • HTMLのリンクをクリックするとブラウザーでリンク先を表示

  • 画面終了ボタンまたはバックキーでプログラムを終了


newsapixx2.html

<!DOCTYPE html>

<html lang="en" >

<head>
<meta charset="UTF-8">
<title>NEWS API-M</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">

<style>
body {
font-family: "Rounded Mplus 1c";
font-size: 100%;
color: #ecf0f1;
background: #27ae60;
}

#kkaf {
font-size: 1.5em;
margin: 10px;
}

</style>

<style>

#buttonx {
width:90px;
color:#ffffff;
background:#e67e22;
font-family: fantasy,sans-serif;
font-size:24px;
font-weight:bold;
text-shadow:0 1px 0px #143352,0 2px 0px #143352;
text-align:center;
display:inline-block;
text-decoration:none;
border:1px solid #225588;
padding:5px 0 2px 0;
border-radius:5px;
margin-bottom:20px;
margin-left:10px;
opacity: 0.7;
}

</style>

<style>

div#footer-fixed
{
position: fixed; /* フッターの固定 */
bottom: 0px; /* 位置(下0px) */
left: 0px; /* 位置(左0px) */
width: 100%; /* 横幅100% */
height: 70px; /* 縦幅70px */
}

div#body-bk{
padding: 0px 0 80px 0; /* 下に80pxを余白を取る */
}

.linknews{
display:block;
width: 90%;
height:35px;
line-height: 30px;
font-size: 1em;
color: #FFF;
text-decoration: none;
text-align: left;
background-color: #f39800; /*ボタン色*/
border-radius: 5px; /*角丸*/
-webkit-transition: all 0.5s;
transition: all 0.5s;
padding: 10px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.linknews:active{
background-color: #f9c500; /*ボタン色*/
}

#srch {
width: 80%;
font-size: 1.2em;
}

h3 {
background-color: #096c47;
padding: 5px;
}

.hide {
display: none;
}

</style>

<script type="text/javascript">
function doDataLink(data) {
// console.log(JSON.stringify(data));
Android.dataLink(data);
}
</script>

</head>

<body>

<h1>NEWS API</h1>

<textarea id="srch" rows="6"></textarea>

<div id="body-bk">

<div id="kkaf">

<div id="output"></div>

</div>

</div>

<div id="footer-fixed">

<a id="buttonx" onmouseover="this.style.background='#e67e22'" onmouseout="this.style.background='#d35400'" onclick="this.style.background='#e74c3c';getnews()">検索</a>

<a id="buttonx" onmouseover="this.style.background='#e67e22'" onmouseout="this.style.background='#d35400'" onclick="this.style.background='#e74c3c';doDataLink('//x//')">終了</a>

</div>

<script>

var srchs = localStorage.getItem('srchnewsapi20190103'); //Storageから読み込み
if ( srchs == null ) {
document.getElementById('srch').value = '';
localStorage.setItem('srchnewsapi20190103','');

} else {
if ( srchs == '' ) {
document.getElementById('srch').value = '';
localStorage.setItem('srchnewsapi20190103','');
} else {
document.getElementById('srch').value = srchs;
}
};

function getnews() {
var srchnew = document.getElementById('srch').value;
document.getElementById('output').innerHTML = '';
localStorage.setItem('srchnewsapi20190103',srchnew);
var arrsrch = srchnew.split('\n');
for (var i=0;i<arrsrch.length;i++) {
if (arrsrch[i] == '' ) {
} else {
kenone(encodeURIComponent(arrsrch[i]),arrsrch[i]);
};
};
};

function kenone(kenx,kend) {

var url = 'https://newsapi.org/v2/everything?' +
'q=' + kenx + '&' +
'pagesize=100&'+
'apiKey=(NEWS APIのAPIキー)';

var req = new Request(url);
var maehensyu = [];
var outhtml;
fetch(req).then(function(response) {
return response.json();
}).then(function(json) {
for (var i=0;i<json.articles.length;i++) {
outhtml = '';
outhtml += '【日付:' + json.articles[i].publishedAt + ' ';
outhtml += '情報元:' + json.articles[i].source.name + '】<br>\n';
outhtml += '<a class=\"linknews\" href=\"' + json.articles[i].url + '\">';
outhtml += json.articles[i].title + '</a><BR><BR>\n';
if (json.articles[i].description == null){
outhtml += '[説明なし]' + '<BR><BR>\n';
} else {
outhtml += json.articles[i].description + '<BR><BR>\n';
};
if (json.articles[i].urlToImage == null){
outhtml += '[写真なし]' + '<BR><BR>\n';
} else {
outhtml += '<img width=\"150\" src=\"' + json.articles[i].urlToImage + '\"><BR><BR>\n';
};
maehensyu.push(outhtml);
};
maehensyu.sort();
var atohensyu = '';
for (var j=0;j<maehensyu.length;j++) {
atohensyu = maehensyu[j] + atohensyu;
};
atohensyu = '<span class=\"hide\">\n'+atohensyu;
atohensyu = '<h3 class=\"group\">'+'検索結果('+j+'):'+kend+'</h3>\n'+atohensyu;
atohensyu = atohensyu+'</span>\n';

document.getElementById('output').innerHTML += atohensyu;

var menu = document.getElementsByClassName('group');

function show(){
console.log('aaa');
var hideContent = this.nextElementSibling;
hideContent.classList.toggle('hide');
};

for(var i = 0; i < menu.length; i++){
menu[i].addEventListener('click', show)
}

});

};

</script>

</body>

</html>



news.bas

console.title "NEW APIマルチ対応版v2"

nxttest:

HTML.OPEN

HTML.LOAD.URL "newsapixx2.html"

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
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 "User data: " + data$

! Check for Exit
IF data$ = "//x//" then
PRINT "User ended demo."
HTML.CLOSE
popup "終了します",0,0,0
pause 5000
end
else
msx$=data$+"←データの内容"
popup msx$,0,0,0
pause 1000
goto xnextUserAction
goto nxttest
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



4.テスト結果

テスト結果の動画は以下です。

https://www.youtube.com/watch?v=hBOOf_M6dPI

簡単に使えて便利だと思います。

以 上