Open9

FlutterでGitHub APIを操作する

Ryo24Ryo24

Fileの内容を取得する

import 'dart:convert';
import 'package:github/github.dart';


final github = GitHub(auth: Authentication.withToken(githubToken));

// リポジトリ&ファイル名を指定し、コンテンツを取得
RepositoryContents repositoryContents = await github.repositories.getContents(
  RepositorySlug('<ユーザー名>', '<リポジトリ名>'),
   '<ファイルのパス>',
);

// UTF-8形式でBase64をデコード
final String content = utf8.decode(base64.decode(repositoryContents.file?.content?.split('\n').join() ?? ''));

メモ

repositoryContentsの中にファイルに関する情報が入っており、contentプロパティにファイルの内容がある。Base64にエンコードされた状態のため、アプリで使うならデコードする必要がある。
また軽く調べた範囲だとリポジトリないのファイルを一括取得はできなさそうだから、GitHub Actionsでいい感じにCIを作った方がいいかな。

Ryo24Ryo24
RepositoryContents repositoryContents = await github.repositories.getContents(
  RepositorySlug('<ユーザー名>', '<リポジトリ名>'),
   '<ディレクトリ>',
);
repositoryContents.tree
lib/data
lib/exec
lib/main.dart
lib/work_space

<ディレクトリ>/<ファイルorディレクトリ>形式で返ってくるな

Ryo24Ryo24
Flutter Web Bootstrap: Programmatic
The Flutter DevTools debugger and profiler on Chrome is available at: http://127.0.0.1:9101?uri=http://127.0.0.1:52944/5KqHOIHeSB4=
Error: XMLHttpRequest error.
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 299:10  createErrorWithStack
dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 341:28            _throw
dart-sdk/lib/core/errors.dart 116:5                                           throwWithStackTrace
dart-sdk/lib/async/zone.dart 1378:11                                          callback
dart-sdk/lib/async/schedule_microtask.dart 40:11                              _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                               _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15           <fn>
rm bin/cache/flutter_tools.stamp

flutter/packages/flutter_tools/lib/src/web/chrome.dart を開く
207行目にある`--disable-extensions`を`--disable-web-security`に書き換える
Ryo24Ryo24
final List<String> args = <String>[
      chromeExecutable,
      // Using a tmp directory ensures that a new instance of chrome launches
      // allowing for the remote debug port to be enabled.
      '--user-data-dir=${userDataDir.path}',
      '--remote-debugging-port=$port',
      // When the DevTools has focus we don't want to slow down the application.
      '--disable-background-timer-throttling',
      // Since we are using a temp profile, disable features that slow the
      // Chrome launch.
      '--disable-web-security',
      '--disable-popup-blocking',
      '--bwsi',
      '--no-first-run',
      '--no-default-browser-check',
      '--disable-default-apps',
      '--disable-translate',
      if (headless) ...<String>[
        '--headless',
        '--disable-gpu',
        '--no-sandbox',
        '--window-size=2400,1800',
      ],
      ...webBrowserFlags,
      url,
    ];
Future<Process?> _spawnChromiumProcess(List<String> args, String chromeExecutable) async {
    if (_operatingSystemUtils.hostPlatform == HostPlatform.darwin_arm) {
      final ProcessResult result = _processManager.runSync(<String>['file', chromeExecutable]);
      // Check if ARM Chrome is installed.
      // Mach-O 64-bit executable arm64
      if ((result.stdout as String).contains('arm64')) {
        _logger.printTrace(
            'Found ARM Chrome installation at $chromeExecutable, forcing native launch.');
        // If so, force Chrome to launch natively.
        args.insertAll(0, <String>['/usr/bin/arch', '-arm64']);
      }
    }

    // Keep attempting to launch the browser until one of:
    // - Chrome launched successfully, in which case we just return from the loop.
    // - The tool reached the maximum retry count, in which case we throw ToolExit.
    const int kMaxRetries = 3;
    int retry = 0;
    while (true) {
      final Process process = await _processManager.start(args);

      process.stdout.transform(utf8.decoder).transform(const LineSplitter()).listen((String line) {
        _logger.printTrace('[CHROME]: $line');
      });

      // Wait until the DevTools are listening before trying to connect. This is
      // only required for flutter_test --platform=chrome and not flutter run.
      bool hitGlibcBug = false;
      bool shouldRetry = false;
      final List<String> errors = <String>[];
      await process.stderr
          .transform(utf8.decoder)
          .transform(const LineSplitter())
          .map((String line) {
        _logger.printTrace('[CHROME]: $line');
        errors.add('[CHROME]:$line');
        if (line.contains(_kGlibcError)) {
          hitGlibcBug = true;
          shouldRetry = true;
        }
        return line;
      }).firstWhere((String line) => line.startsWith('DevTools listening'), orElse: () {
        if (hitGlibcBug) {
          _logger.printTrace(
            'Encountered glibc bug https://sourceware.org/bugzilla/show_bug.cgi?id=19329. '
            'Will try launching browser again.',
          );
          // Return value unused.
          return '';
        }
        if (retry >= kMaxRetries) {
          errors.forEach(_logger.printError);
          _logger.printError(
              'Failed to launch browser after $kMaxRetries tries. Command used to launch it: ${args.join(' ')}');
          throw ToolExit(
            'Failed to launch browser. Make sure you are using an up-to-date '
            'Chrome or Edge. Otherwise, consider using -d web-server instead '
            'and filing an issue at https://github.com/flutter/flutter/issues.',
          );
        }
        shouldRetry = true;
        return '';
      });

      if (!hitGlibcBug && !shouldRetry) {
        return process;
      }
      retry += 1;

      // A precaution that avoids accumulating browser processes, in case the
      // glibc bug doesn't cause the browser to quit and we keep looping and
      // launching more processes.
      unawaited(process.exitCode.timeout(const Duration(seconds: 1), onTimeout: () {
        process.kill();
        // sigterm
        return 15;
      }));
    }
  }

恐らくChrome起動時、ウェブ関連のセキュリティ関連を無効にして実行することでブラウザないでリクエストなどができるようにしているのかな???

Ryo24Ryo24
Access to XMLHttpRequest at 'https://api.github.com/repos/r0227n/zenn-article' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field x-github-api-version is not allowed by Access-Control-Allow-Headers in preflight response.

うん、、、ビルドしたらやっぱりダメか、、、

Ryo24Ryo24

GitHub Pagesにデプロイしたから、やっぱりx-github-api-version headerがよくないのかな?