この投稿では、無料のソリューションのみを使用してファイルを保存するWebサービスを整理する方法を簡単に説明します。
すべての興味-猫の下でお願いします。
足場を準備する
必要なのは:
- ローカルマシンにインストールされたNode.js
- Dropboxアカウント
- アプリケーションNode.jsサーバー(ローカルだけでなくサービスを開始する場合)
最初の2つのポイントですべてが明確になったら、3番目のポイントについてもう少し詳しく説明します。 私はすでにすべてが無料で判明するはずであると述べました、そして、私は私の言葉を後戻りさせません。
Node.jsの世界での「むかつき」の過程で、Node.jsサーバーを無料で使用できるようにする準備ができている多くのプラットフォームに出会いました。 個人的には、HerokuとNodesterの2つを経験しました。 その結果、率直に言って、この決定は何によっても実証されていないものの、私はそれでも2番目に落ち着きました。
Nodesterに登録するにはクーポンが必要です。 これは、彼らのWebサイトまたはコマンドラインでnodester-cliを使用して実行できます。 リクエストを送信した翌日にクーポンを受け取りました。 それは非常に速いですが、私はただ幸運だったことを除外しません。
プロジェクトを作成する
局所的に
結局のところ、あなたは何かから始めなければなりません。 これを行うには、都合の良い場所にフォルダー(私の名前はhabr-nodebox)とpackage.jsonファイルを作成します。
{ "name": "habr-nodebox", "version": "0.0.1", "node": "0.6.17", "author": "andbas", "dependencies": { "express": "2.5.x", "jade": "0.26.x", "dbox": "0.4.x" } }
フィールド名、バージョン、作成者-プロジェクトに関する情報を入力するだけで、問題なく変更できます。 node-プロジェクトで使用されるNode.jsのバージョン。 依存関係セクションには、使用されているすべてのサードパーティモジュールが一覧表示されます。 前述したように、プロジェクトではエクスプレスとジェイドを使用します。 dboxプラグインは、その名前が示すとおり、Dropboxでの作業に使用されます。 dropboxと呼ばれる別のプラグインを試しましたが、残念ながら、/トークンを使用した古いDropbox APIを実装していたため、アプリケーションの承認を許可しませんでした。 Dropboxは現在、認証にoauth標準を使用しています。
コマンドラインでこのファイルを保存した後、呼び出します:
npm install
すべてが正しく書き込まれていれば、npmは依存関係に記載されているすべてのモジュールをダウンロードし、現在のディレクトリにインストールします。
さらに、パブリックとビューの2つのフォルダーを作成します。 最初は静的ファイル(CSS、JSなど)に使用され、ビューはJadeテンプレートに使用されます。
一方、Dropboxで
Dropboxにいくつかのファイルを保存できるようにするには、いくつかのアクションを実行する必要があります。最初のアクションは、アプリケーションのキーとシークレット行を取得することです。 これを行うには、ブラウザからDropboxアカウントのアプリケーションページに移動し、そこで新しいアプリケーションを作成します。 [アクセスの種類]フィールドで、値をAppフォルダーに設定します(アプリケーションは、Dropbox内の独自のフォルダーのみにアクセスを制限します)。
アプリケーションページで、どこかにAppキーとApp Secretを書き込みます。 これは実際に、最初のステップがすでに完了しています。
承認の次の手順を自動化するには、同じnode.jsで小さなスクリプトを作成することをお勧めします。 スクリプトは次のとおりです(アプリケーションフォルダーのdbox-init.js):
var dbox = require("dbox"), stdin = process.stdin, stdout = process.stdout; ask('App key', /^\S+$/, function(app_key) { ask('App secret', /^\S+$/, function(app_secret) { var app = dbox.app({ 'app_key': app_key, 'app_secret': app_secret }); app.request_token(function(status, request_token){ if(request_token){ console.log('Please visit ', request_token.authorize_url, ' to authorize your app.'); ask('Is this done? (yes)', /^yes$/, function(answer) { app.access_token(request_token, function(status, access_token){ console.log('app_key: ' + app_key); console.log('app_secret: ' + app_secret); console.log('oauth_token: ' + access_token.oauth_token); console.log('oauth_token_secret: ' + access_token.oauth_token_secret); console.log('uid: ' + access_token.uid); process.exit(); }); }); } }); }); }); function ask(question, format, callback) { stdin.resume(); stdout.write(question + ": "); stdin.once('data', function(data) { data = data.toString().trim(); if (format.test(data)) { callback(data); } else { stdout.write("It should match: "+ format +"\n"); ask(question, format, callback); } }); }
スクリプトを実行するには、コマンドラインに入力するだけです。
node dbox-init
このスクリプトは、Dropboxでのoauth認証のすべての段階を通過し、必要なすべてのキーを取得するのに役立ちます。 手順は次のとおりです。
- スクリプトはアプリキーとアプリシークレット(以前に取得したもの)を要求し、それらに基づいてリンクを生成します
- ブラウザへのリンクをコピーし、アプリケーションがDropboxアカウントで動作することを承認すると、アプリケーションが承認されたという通知を受け取ります
- 承認を経たかどうかについてのスクリプトの質問に、「はい」と大胆に書きます
- 承認に必要なデータ、つまりapp_key、app_secret、oauth_token、oauth_token_secretおよびuidを取得して、人里離れた場所に書き込みます
この準備作業が完了したら、アプリケーション自体の作成に進むことができます。
戦闘中:コントローラーを投げる
私の意見では、私たちは最も興味深いこと、つまりコントローラーの作成に目を向けています。 主なアクションは、すべてのファイルの表示、新しいファイルの追加、既存のファイルの取得です。 コード(web.js)を苦しめず、すぐに提供します。
var express = require('express'), app = express.createServer(express.logger()), fs = require('fs'), dropbox = require("dbox").app({"app_key": process.env['dbox_app_key'], "app_secret": process.env['dbox_app_secret'] }), client = dropbox.createClient({oauth_token_secret: process.env['dbox_oauth_token_secret'], oauth_token: process.env['dbox_oauth_token'], uid: process.env['dbox_uid']}); app.use(express.static(__dirname+'/public')); app.set('views', __dirname + '/views'); app.set('view engine', 'jade'); app.set('view options', { layout: false }); app.use(express.bodyParser()); app.get('/', function(req, res) { client.metadata(".", function(status, reply) { res.render('index', { content : reply }); }); }); app.get('/:path', function(req, res) { var path = req.params.path; client.get(path, function(status, reply, metadata){ res.send(reply); }); }); app.post('/', function(req, res) { var fileMeta = req.files['file-input']; if (fileMeta) { fs.readFile(fileMeta.path, function(err, data) { if (err) throw err; client.put(fileMeta.name, data, function(status, reply) { res.redirect('/'); }); }); } else { res.redirect('/'); } }); var port = process.env['app_port'] || 5000; app.listen(port, function() { console.log("Listening on " + port); });
ここで何が起こっているのかを少し説明しても害はないと思います。
var express = require('express'), app = express.createServer(express.logger()), fs = require('fs'), dropbox = require("dbox").app({"app_key": process.env['dbox_app_key'], "app_secret": process.env['dbox_app_secret'] }), client = dropbox.createClient({oauth_token_secret: process.env['dbox_oauth_token_secret'], oauth_token: process.env['dbox_oauth_token'], uid: process.env['dbox_uid']});
アプリケーションの主要なブリックの発表:
- エクスプレス-前述のように、Webフレームワーク
- appは実際にはWebアプリケーションそのものです
- fs-ファイルシステムインターフェイス
- dropbox-Dropboxクライアントを作成するためのファクトリー
- client-DropboxクライアントはAPIの操作を簡素化します
app.use(express.static(__dirname+'/public')); app.set('views', __dirname + '/views'); app.set('view engine', 'jade'); app.set('view options', { layout: false }); app.use(express.bodyParser());
Webアプリケーションを初期化します。 ここで主なパラメーターを設定します:静的ファイルへのパス(パブリック)、テンプレートのディレクトリ(ビュー)、これらの同じテンプレートのエンジン(ヒスイ)、メインレイアウトをオフにしてスペルを少し簡略化し、1つのテンプレートで処理し、最後にアプリケーションに渡しますbodyParser。着信リクエストの本文を解析します。
それでは、メインの魔法に移りましょう。 サービスの3つの主なハンドラーが続きます。
app.get('/', function(req, res) { client.metadata(".", function(status, reply) { res.render('index', { content : reply }); }); });
このコードはメインページを担当します。 その上に、Dropboxフォルダー内のファイルのリストを表示します。そのため、クライアントを介して要求を行い、メタ情報を取得します。 これには、アプリケーション内のすべてのファイルに関する情報が含まれています。 この情報をテンプレートエンジンに渡し、ページレンダリングが行われます。
app.get('/:path', function(req, res) { var path = req.params.path; client.get(path, function(status, reply, metadata){ res.send(reply); }); });
上記のメソッドはファイル要求を処理します。 すべてが非常に簡単です-ファイル名を取得し、Dropboxにリクエストを送信します。 受信した応答はユーザーにリダイレクトされます。
app.post('/', function(req, res) { var fileMeta = req.files['file-input']; if (fileMeta) { fs.readFile(fileMeta.path, function(err, data) { if (err) throw err; client.put(fileMeta.name, data, function(status, reply) { res.redirect('/'); }); }); } else { res.redirect('/'); } });
私たちのためのほとんどすべての仕事は速達で行われました。 ポストリクエストの本文でサーバーに送信されたファイルは、一時的にファイルシステムに保存されました。 req.files ['file-input']オブジェクトで必要なすべての情報が提示されました。file -inputは、htmlのフォームの入力要素の名前属性です。 ファイルシステムからファイルを取得してDropboxに送信するだけです。 その後、メインページにリダイレクトされます。
var port = process.env['app_port'] || 5000; app.listen(port, function() { console.log("Listening on " + port); });
最後に、アプリケーションのポートを設定します。デフォルト値は5000です。jadeテンプレートを使用して単純なページを1つ書くだけで、これを行います。
adeテンプレート-インデントがすべて
ジェイドとの最初の出会いは個人的に苦痛でした。 通常のhtmlの方が少し近いです。
しかし、不快感はすぐに過ぎました。 2ページ目は敵意なく書かれました。 一般的に、すぐに慣れます。 試すことをお勧めします。
ヒスイの便利さを議論するのは素晴らしいことですが、今度はコードを紹介します。 これを行うには、viewsフォルダーにindex.jadeファイルを作成して書き込みます。
!!! 5 html(lang="en") head title habr-nodebox body each item, i in content.contents div a(href="#{item.path}") #{item.path} - #{item.size} div form#upload-form(action="/", method="POST", enctype="multipart/form-data") input#file-input(name="file-input", type="file") input#submit(value="Upload file", type="submit")
テンプレートを最も透明で理解しやすいものにしようとしました。 もちろん、際立ったスタイルの結果を達成することはできませんが、明確にするために何かを犠牲にすることはありません。
フォルダー内のファイルのリストを含む最も単純なHTMLページを作成しました。 これを行うために、すべてのファイルエントリに対して各ループを実行しました。 コンテンツメタデータは、コントローラーのテンプレート用に慎重に受信されたことを思い出させてください。 各リスト項目は、「/:パス」形式のクエリのコントローラーメソッドにつながるリンクです。 リストは、新しいファイルをアップロードするためのフォームです。 ファイル用とフォーム送信用の2つの入力要素で構成されます。
打ち上げ
それが実際に私たちのアプリケーションであり、準備ができており、それを起動するだけです。 おそらく、Dropboxのすべてのキーがprocess.env []配列の変数として書き込まれていることに気づいた人がいたでしょう。 これは、コードにそれらを残さず、侵害されることを恐れずにアプリケーションを公開できるようにするために行われます。 値をprocess.env配列に渡すには、nodeを呼び出す前にkey = valueの形式で値を書き込むだけで十分です。 コマンドラインで、次のようなものが得られるはずです。
$ dbox_app_key=abc1qwe2rty3asd dbox_app_secret=123asd123asd123 dbox_oauth_token_secret=aaabbbccc111222 dbox_oauth_token=123asd123asd123 dbox_uid=12345678 node web
Nodesterなどのサービスでは、process.envをインストールすることができるため、これが私の頭に浮かぶ問題のない唯一の方法でした。
結果は、いくつかのファイルを追加した後、次のようになります。
誰かがそのようなコードをオンラインで実行したい場合は、これで終わりです-Node.jsサーバーにアップロードするだけです。 Nodesterでテストしました-すべてが機能し、残りの部分に問題はないと思います。
コードはここにあります。