2025/05/09 / CloudStrage

DropBox APIを使ってみた

GitLFSの無料ユーザーを救済します!

git api dropbox cloudstrage

こんにちは!パン君です

今回は自作 GameEngine のファイル管理関連です。

皆さん Git LFS は使っていますか?便利ですよね。ですが個人だと無料ユーザーも多いことでしょう。
因みに自作 GameEngine は C++ベースで作成されていて DirectX12, DirectX11 対応だったり、様々なモデルファイルを独自のモデルデータにコンバートしたり、、、

まぁ要するに色んな機能を乗っけたいわけなので、自作 GameEngine(BreadEditor)は ExternalLibrary なるディレクトリが存在しています。

静的ライブラリを導入するのですが、さあどうやってこのファイルを管理しようかと考えて真っ先に出てくるのがクラウドサービスの利用でした。

ここではそれの方法と気にしたポイント等を話していきたいと思います。


概要

大まかな流れは下記の通りです。

  • DropBox のアカウントを作成
  • DropBox でアプリを作成
  • 該当アプリのアクセストークを作成
  • node.js をベースに javascript で DropBox との送受信処理作成
  • バッチファイル、シェルスクリプト作成

BreadEditor の大まかなディレクトリ構造も記載しておきます。

Text
BreadEditor
├── .git
├── Bat
│   ├── js
│   ├── json
│   └── *.bat
├── BreadEditor
├── Data
├── Library
│   ├── BreadLibrary
│   └── ExternalLibrary
└── project.sln

準備

DropBox のアカウント作成

ここからできます。
特筆する事はないですが、普段使いしている人はアプリケーション専用アカウントとか作っておいた方が事故防止になるかなといった具合です。

DropBox でアプリ作成

ここのページからアプリを作成します。
こっちに作成ボタンの URL をはっておきます。一発で行きたい人はこちらで。

下記入力項目の説明です。

  1. Choose an API: 個人で使う場合は「Dropbox API」で問題ないかと思います。
  2. Choose the type of access you need: 作成するアプリが指定フォルダのみか全体かです。推奨は指定フォルダのみです。
  3. Name your app: お好みで。
  4. Create app を押下。

[! NOTE] 既にアプリ作成済みの場合、DropBox Developer ページの3点バーコードの「App console」から触れます。

アクセストークン作成

必要なパーミッションを設定して Generated access token ボタンを押下。
出力されたトークンをどっかにメモっておきます。(一時的な物のため作業を行うたびに出力する必要があります。感覚的に半日ぐらいが有効期限)

環境構築

作業を行うディレクトリ下で色々作成していきます。(今回は Bat ディレクトリ)

  • bat
    • data
      • Dropbox.json
    • js
      • DropboxDownload.js
      • DropboxUpload.js
    • Download.bat
    • Update.bat

js ディレクトリ下でターミナルを開き下記を実行します。(node.js npm インストール済み想定)

npm install --save dropbox
npm install --save isomorphic-fetch

アップロードスクリプト作成

とりあえずコードを添付しておきます。
まずは DropboxUpload.js から

Javascript
const fs = require("fs");
const path = require("path");
const Dropbox = require("dropbox");
const accessToken = "{取得したアクセストークン}";
const dbx = new Dropbox.Dropbox({ accessToken });

function DropboxUpload(dirPath, remotePath) {
  const files = fs.readdirSync(dirPath, {
    withFileTypes: true,
  });

  files.forEach((element) => {
    if (element.isDirectory()) {
      dbx.filesCreateFolderV2({
        path: remotePath + element.name + "/",
        autorename: false,
      });
      DropboxUpload(
        dirPath + "/" + element.name,
        remotePath + element.name + "/"
      );
    } else if (element.isFile()) {
      if (path.extname(element.name) == ".{アップしたい拡張子}") {
        const uploadFile = fs.readFileSync(dirPath + "/" + element.name, {
          encoding: "binary",
        });

        const response = dbx.filesUpload({
          path: remotePath + element.name,
          contents: uploadFile,
          mode: "overwrite",
        });
      }
    }
  });
}
DropboxUpload("{作業ディレクトリパス}", "/");

下記簡単なコードの説明です。
DropBoxUpload は再帰的に処理されます。
第一引数「dirPath : string」はローカルのクラウドストレージと同期したいディレクトリパスです。
第二引数「remotePath : string」はリモート(クラウドストレージのパスです。)

DropBox の参照パスは「/」始まりです。
これは作成したアプリの管理しているディレクトリ直下を差します。

readdirSync は今回recursive: falseで行っています。
理由は DropBox はディレクトリを随時作成してあげる必要があるためです。
自分で再帰的に処理している理由でもあります。

readdirSync で取得したパスがディレクトリだった場合、階層を下げて同様の処理。
ファイルだった場合アップロードを行います。

ダウンロードスクリプト作成

続いて DropboxDownload.js

Javascript
const fs = require("fs");
const Dropbox = require("dropbox");
const fetch = require("isomorphic-fetch");
const accessToken = "{取得したアクセストークン}";
const dbx = new Dropbox.Dropbox({ accessToken: accessToken, fetch: fetch });
const targetDir = "{ダウンロード先ローカルパス}";

function DropboxDownload(originPath) {
  dbx.filesListFolder({ path: originPath }).then(function (response) {
    response.result.entries.forEach((element) => {
      if (element[".tag"] == "folder") {
        if (!fs.existsSync(targetdir + element.path_display)) {
          fs.mkdirSync(targetdir + element.path_display);
        }

        DropboxDownload(element.path_display);
      } else if (element[".tag"] == "file") {
        dbx
          .filesDownload({ path: element.path_display })
          .then(function (response) {
            fs.writeFile(
              targetdir + response.result.path_display,
              response.result.fileBinary,
              "binary",
              function (err) {
                console.error({ err });
              }
            );
          });
      }
    });
  });
}
DropboxDownload("");

下記簡単なコードの説明です。
落としてくるだけなのでアップより考慮することは少ないですね。

こちらも基本的な考え方はアップと一緒です。
fileListFolder から帰ってくる要素を総なめしてディレクトリだったら再帰する。ファイルだったらダウンロードするのがベース。


バッチファイル作成

Bat ディレクトリ直下に作成 Download.bat, Upload.bat にそれぞれの javascript を実行するコマンドを入力します。

この時ディレクトリを変えたい、拡張子を変えたい、トークンが変わるのにも対応したいという場合は引数に入れるようにして、対応する javascript の方もそれに対応してください。

node.js の引数の取得はprocess.argv[]です。
先頭のコマンドから格納されているため第一要素はnode第二要素は実行javascriptファイル名 となっているはずです。
ですので引数をとってこれるのはprocess.argv[2]からです。


詰まった箇所

結論を話します。
公式しか勝たん。
途中からサードパーティの記事を見て端折るのは諦めて公式を見るようにしました。

理由は NDK が更新されているからか何でかわからないですが、コピペで使えるコードを添付している記事が一つもない。

例で言うと DropboxDownload.js のdbx.filesListFolder().then(function(response))responseですが、後の filesDownload で使用することになりますが、response.fileBinary と記載されていました。(んなもん存在しない。)

その他色々ありますが、言いたいのはこの記事も例外に漏れずサードパーティは参考程度にとどめて公式をしっかり読みましょう。


最後に

今回はクラウドストレージサービスを利用したプロジェクト内の一部ファイルの同期についてでした。
これで無料でファイル管理ができるね!!

gitLFS との使い分けとしては下記2点を基準に判断すればいいかと思います。

  • バージョン管理したいか
  • 保持する必要があるか(無くてもコンパイル時に生成される等)

筆者としてはバージョン管理したくないけど複数の作業環境を使うために使用しています。
まぁ GitLFS にお金突っ込んでいるなら不要ではありますが。

ご自宅に専用サーバーを置いているならこういうのも必要ないので、金銭面ジリ貧の人がとる手法な気がします。


参考資料

https://qiita.com/Ella_Engelhardt/items/c33f08b6b427eab8b310

← Modoium Remot…← ブログ一覧へ戻るUE5プラグイン開発 →