背景
The Boring Flutter Development Show [Pilot Episode] で出てくる article.dart
は、Ep.1 の時点でデータがハードコードされています。
写経するにあたって適当なコードがほしかったので、Hacker News API を叩いて article.dart
ファイルを生成するコードを書きました。
せっかくなので共有します。
使い方
- 次節にあるコード
index.js
をローカルにコピー -
npm install
を実行 -
node index.js
を実行
node v10.14.2、windows 10 で動作確認しました。
別に最新である必要はないんだよという人は、結果を gist に貼っているのでコピーしてください。
https://gist.github.com/noobar/9ba5b41f6e02986e077809e18f7b09e7
コード
やっていることは次の通りです。
-
/v0/topstories.json
を叩いて Top Stories にある記事の記事IDを取得 - 1.で取得したIDで
/v0/item/[ID].json
を叩き、記事情報を取得 - 2.で取得した記事情報を適切にフォーマットする
-
article.dart
に文字列を書き込む
index.js
const fs = require('fs');
const os = require('os');
const url = require('url');
const moment = require('moment');
const request = require('request-promise-native');
const hackerNewsUrl = 'https://hacker-news.firebaseio.com';
const sleep = msec => new Promise(resolve => setTimeout(resolve, msec));
(async () => {
// 記事のIDリストを取得
const ids = await request({
uri: `${hackerNewsUrl}/v0/topstories.json`,
json: true
});
// 各IDに対して記事内容を取得し、パースしたものを articles に詰め込む
const articles = [];
for (let i=0; i<30; i++) {
const reqURI = `${hackerNewsUrl}/v0/item/${ids[i]}.json`
console.log(`Requesting ${i + 1}/30 ${reqURI}`);
const article = await request({
uri: reqURI,
json: true
});
articles.push({
text: article.title,
domain: url.parse(article.url).hostname,
by: article.by,
age: moment.unix(article.time).fromNow(), // "5 hours ago" のような形式に変換
score: article.score,
commentsCount: article.descendants
});
// リクエスト間隔を設ける
await sleep(500);
}
// なんとなくJSONファイルを保存
fs.writeFileSync('./articles.json', JSON.stringify(articles, null, ' '));
// articles.dart をつくる
let fileBody = [
'class Article {',
' final String text;',
' final String domain;',
' final String by;',
' final String age;',
' final int score;',
' final int commentsCount;',
' ',
' const Article({',
' this.text,',
' this.domain,',
' this.by,',
' this.age,',
' this.score,',
' this.commentsCount',
' });',
'}',
'',
'final articles = [',
''
].join(os.EOL);
fileBody += articles.map(a => {
return [
' new Article(',
` text: "${a.text}",`,
` domain: "${a.domain}",`,
` by: "${a.by}",`,
` age: "${a.age}",`,
` score: ${a.score},`,
` commentsCount: ${a.commentsCount},`,
' ),'
].join(os.EOL)
}).join(os.EOL);
fileBody += os.EOL + '];'
fs.writeFileSync('./article.dart', fileBody);
})();
作法として、リクエスト間隔を500msとっています。