1. 記事一覧 >
  2. ブログ記事
category logo

GitLabから直接ダウンロードをNative Messagingのexeで実現(Chrome,FireFox,Edge拡張機能)

(更新) (公開)

はじめに

Native Messaging、拡張機能、GitLab の API を利用して、GitLab のリポジトリからファイルを直接ダウンロードするアプリを作成しました。今回、その仕組みをご紹介していきます。

ちなみに、同様のことができるDeveloper's Download Helperという拡張機能がありますが、こちらは、複数ファイルをダウンロードすると、zip でダウンロードされます。(bestzipという npm を使っているようです。)※他にも同様の拡張機能が有ると思いますが、複数ファイルをダウンロードする場合の解決策は、全て zip だと思います。


仕組みと動作内容
インストール
Chrome 動作確認
Firefox 動作確認


今回の検証環境は、

Windows 10 Pro(x64)

Chrome: 91.0.4472.114(Official Build) (64 ビット)

Microsoft Edge: 91.0.864.59 (公式ビルド) (64 ビット)

Firefox Developer: 90.0b12 (64 ビット)

になります。


仕組みと動作内容

動作内容

拡張機能のみの場合

・複数ファイルまとめてダウンロードすると、zip でダウンロードされます。

Native Messaging を利用した場合

・独自実装のダウンロード先選択画面が表示できます。

・複数ファイルまとめてダウンロードできます。


仕組み

「GitLab DL」をクリック

JavaScript で nativemesssampleLaunchApp イベントを発火

nativemesssampleLaunchApp イベントを拡張機能が検知

var port = chrome.runtime.connectNative( 'nativemesssample' );でアプリに接続
※nativemesssample はアプリの名前(アプリ側 manifest.json に名前が登録されている)

port.postMessage( request.message );
で GitLab API URL 等のパラメータをアプリに渡す

アプリが保存先ダイアログを表示

ユーザーが保存先を選んだらダウンロード
(GET /GitLab API)

ダウンロードし終わったら、アプリから拡張機能にメッセージを送信

アプリ - 拡張機能の接続を切断



GitLab API

ネイティブアプリには、以下のようなパラメータが渡されます。

{
  "command": "download",
  "files": [
    {
      "url": "http://gitlab.itccorporation.jp/api/v4/projects/root%2fwiringpi-python-bme280/repository/blobs/e07f1ee1076a78880ebc5baecf15120cc104c280/raw",
      "name": "root/wiringpi-python-bme280/opt/bme280.py"
    },
    {
      "url": "http://gitlab.itccorporation.jp/api/v4/projects/root%2fwiringpi-python-bme280/repository/blobs/cd4a885ad6fc4c5739ce345d902adb76c096f4c3/raw",
      "name": "root/wiringpi-python-bme280/opt/bme280_inc.py"
    },
    {
      "url": "http://gitlab.itccorporation.jp/api/v4/projects/root%2fwiringpi-python-bme280/repository/blobs/fe34e30c456f69b9818e1fd46299a1542f85606b/raw",
      "name": "root/wiringpi-python-bme280/opt/lcd1602_inc.py"
    }
  ],
  "write_mode": "",
  "rect": {
    "left": 132,
    "top": 150,
    "width": 1209,
    "height": 863
  },
  "cookies": [
    {
      "name": "experimentation_subject_id",
      "value": "eyJfcmFpbHMiOnsibWVzc2FnZSI6IkltWXlZV1JtT0RKa0xUSTFObU10TkdFek5pMDVNemxsTFdGaFlqSTJOR0ZsT0dGbE5DST0iLCJleHAiOm51bGwsInB1ciI6ImNvb2tpZS5leHBlcmltZW50YXRpb25fc3ViamVjdF9pZCJ9fQ%3D%3D--26ad9ed7dcf954aa7a479dd0d5e3dd291a770fe2"
    },
    {
      "name": "known_sign_in",
      "value": "b1RwNTJodElhMWw3RUtsa1BGZ2N2ZE1Cbnd2L0NMTWVUV0RacXJ5YmgzcUJmSEFma3B6Uk40c0RNRlBGckZtaTAyQjB6NUI2ZTMrNnBZMnAxSU9jUFRwTkFUczUrY0g4UzY3a2pETTZxa01DWUhTY1loR2dNU3JaeXUrclRCTkMtLTJMZmh5OHdtL2dQR1o5eHBtTEhkV2c9PQ%3D%3D--0ea06d5eff1f8fbcb7d211cb062c364367263174"
    },
    {
      "name": "_gitlab_session",
      "value": "f5e7efc7af5e2c22b74e7123aff2eb3d"
    },
    {
      "name": "event_filter",
      "value": "all"
    }
  ]
}

主な情報は、ダウンロードするための GitLab API URL とセッション情報("cookies":)です。
ダウンロードするための GitLab API URL を得るために、以下の事を行っています。


1.拡張機能でファイル一覧の取得
GitLab リポジトリのファイル一覧を取得する API URL のフォーマットは以下です。
http://gitlab.itccorporation.jp/api/v4/projects/{:id}/repository/tree?recursive=true&page={:page}&per_page=100&ref={:ref}&path={:path}


root/wiringpi-python-bme280/opt の場合の例

id:root%2fwiringpi-python-bme280
page:1
ref:master
path:opt
API URL:http://gitlab.itccorporation.jp/api/v4/projects/root%2fwiringpi-python-bme280/repository/tree?recursive=true&page=1&per_page=100&ref=master&path=opt

※この場合、1回で取得できるのが 100 件までですので、100 件を超える場合、page= を +1 して複数回実行する必要あり、空が返るまで繰り返しています。


リクエスト結果例

[
  {
    "id": "e07f1ee1076a78880ebc5baecf15120cc104c280",
    "name": "bme280.py",
    "type": "blob",
    "path": "opt/bme280.py",
    "mode": "100644"
  },
  {
    "id": "cd4a885ad6fc4c5739ce345d902adb76c096f4c3",
    "name": "bme280_inc.py",
    "type": "blob",
    "path": "opt/bme280_inc.py",
    "mode": "100644"
  },
  {
    "id": "fe34e30c456f69b9818e1fd46299a1542f85606b",
    "name": "lcd1602_inc.py",
    "type": "blob",
    "path": "opt/lcd1602_inc.py",
    "mode": "100644"
  }
]

2.ネイティブアプリでファイル取得
GitLab リポジトリのファイルを取得する API URL のフォーマットは以下です。
http://gitlab.itccorporation.jp/api/v4/projects/{:id}/repository/blobs/{:sha}/raw


root/wiringpi-python-bme280/opt/bme280.py の場合の例

id:root%2fwiringpi-python-bme280
sha:e07f1ee1076a78880ebc5baecf15120cc104c280
API URL:http://gitlab.itccorporation.jp/api/v4/projects/root%2fwiringpi-python-bme280/repository/blobs/e07f1ee1076a78880ebc5baecf15120cc104c280/raw


リクエスト結果例

※bme280.py の内容がそのまま返ってきます。

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
import os
import signal
from bme280_inc import Bme280
from lcd1602_inc import Lcd1602
・・・

コンテキストメニュー

コンテキストメニュー(右クリックメニュー)は、拡張機能のbackground.jsで以下のように実装しています。

try {
  chrome.contextMenus.create(
    {
      type: 'normal',
      id: 'gitdl',
      title: 'Native Message Example',
      targetUrlPatterns: urlFilter,
      documentUrlPatterns: ['<all_urls>'],
      contexts: ['link'],
    },
    function () {
      chrome.contextMenus.create(
        {
          type: 'normal',
          parentId: 'gitdl',
          id: 'download',
          title: 'GitLab DL',
          targetUrlPatterns: urlFilter,
          documentUrlPatterns: ['<all_urls>'],
          contexts: ['link'],
        },
        function () {
          console.dir('contextMenu created');
          chrome.contextMenus.onClicked.addListener(menuclick);
        }
      );
    }
  );
} catch (e) {
  console.log(e);
}


インストール

Native Messaging アプリ(exe)、Chrome,Firefox に拡張機能をインストールします。
Native Messaging の exe を試作してみた(Chrome,Firefox,Edge 拡張機能)」をご覧ください。
今回と動作内容が異なるだけで、インストール方法は同じです。
※Edge(Chromium)は、Chrome と同じような手順で Chrome の拡張機能がそのまま使えます。


・開発中の手順です。正規プロダクトの手順とは異なります。

・Firefoxについて、署名されていない拡張機能の場合、「Firefox Developer」「Firefox Nightly」どちらかが必要です。

・Edge(Chromium)もChromeと同じような手順でできましたので、Edge(Chromium)の説明は省略しています。


Chrome 動作確認

GitLab の任意のディレクトリへ行き、右クリックメニューから
「Native Message Example」→「GitLab DL」をクリックして発動します。


・ファイルが一つの場合


・ファイルが複数の場合


Firefox 動作確認

GitLab の任意のディレクトリへ行き、右クリックメニューから
「Native Message Example」→「GitLab DL」をクリックして発動します。


・ファイルが一つの場合


・ファイルが複数の場合


できました!


loading...