Help us understand the problem. What is going on with this article?

The Boring Flutter Development Show Ep.1 で使われた article.dart 相当のものをつくる

背景

The Boring Flutter Development Show [Pilot Episode] で出てくる article.dart は、Ep.1 の時点でデータがハードコードされています。
写経するにあたって適当なコードがほしかったので、Hacker News API を叩いて article.dart ファイルを生成するコードを書きました。
せっかくなので共有します。

使い方

  1. 次節にあるコード index.js をローカルにコピー
  2. npm install を実行
  3. node index.js を実行

node v10.14.2、windows 10 で動作確認しました。

別に最新である必要はないんだよという人は、結果を gist に貼っているのでコピーしてください。
https://gist.github.com/noobar/9ba5b41f6e02986e077809e18f7b09e7

コード

やっていることは次の通りです。

  1. /v0/topstories.json を叩いて Top Stories にある記事の記事IDを取得
  2. 1.で取得したIDで /v0/item/[ID].json を叩き、記事情報を取得
  3. 2.で取得した記事情報を適切にフォーマットする
  4. 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とっています。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away