首页 > 解决方案 > ostrio:在 Meteor 上使用 Dropbox 的文件

问题描述

我正在尝试设置 ostrio:files 以使用 Dropbox。有人可以解释一下我该怎么做吗?我已经在保管箱上注册并使用 ostrio:files 手册生成了令牌,但我不知道如何将文件上传到保管箱。上传后,当我检查本地图像数据库时,有所有图像信息,但我不知道如何将其发送到 Dropbox。

选择文件后,显示“上传成功”,但 Dropbox 上没有上传文件。

dropbox.js

import { Meteor } from 'meteor/meteor';
import { FilesCollection } from 'meteor/ostrio:files';

var Dropbox,
  Request,
  bound,
  client,
  fs,
  Images = {};

if (Meteor.isServer) {
  Dropbox = require("dropbox").Dropbox;
  const fetch = require("node-fetch");
  bound = Meteor.bindEnvironment(function (callback) {
    return callback();
  });
  client = new Dropbox({
    accessToken: "mytoken", // Use your token here
    fetch: fetch,
  });
}

Request = require("request");
fs = require("fs");

Images.files = new FilesCollection({
  debug: false, // Change to `true` for debugging
  storagePath: "assets/app/uploads/uploadedFiles",
  collectionName: "uploadedFiles",
  allowClientCode: false,
  onAfterUpload: function (fileRef) {
    // In onAfterUpload callback we will move file to DropBox
    try {
      var self = this;
      var makeUrl = function (path, fileRef, version) {
        client
          .sharingCreateSharedLink({ path: path, short_url: false })
          .then(function (response) {
            bound(function () {
              const url = response.url.replace("dl=0", "raw=1");
              var upd = {
                $set: {},
              };
              upd["$set"]["versions." + version + ".meta.pipeFrom"] = url;
              upd["$set"]["versions." + version + ".meta.pipePath"] = path;
              self.collection.update(
                {
                  _id: fileRef._id,
                },
                upd,
                function (error) {
                  if (error) {
                    return console.error(error);
                  }
                  // Unlink original files from FS after successful upload to DropBox
                  self.unlink(self.collection.findOne(fileRef._id), version);
                }
              );
            });
          })
          .catch(function (error) {
            console.error(error);
          });
      };

      var writeToDB = function (fileRef, version, data) {
        // DropBox already uses random URLs
        // No need to use random file names
        client
          .filesUpload({
            path: "/" + fileRef._id + "-" + version + "." + fileRef.extension,
            contents: data,
            autorename: false,
          })
          .then(function (response) {
            bound(function () {
              // The file was successfully uploaded, generating a downloadable link
              makeUrl(response.path_display, fileRef, version);
            });
          })
          .catch(function (error) {
            bound(function () {
              console.error(error);
            });
          });
      };

      var readFile = function (fileRef, vRef, version) {
        fs.readFile(vRef.path, function (error, data) {
          bound(function () {
            if (error) {
              return console.error(error);
            }
            writeToDB(fileRef, version, data);
          });
        });
      };

      var sendToStorage = function (fileRef) {
        _.each(fileRef.versions, function (vRef, version) {
          readFile(fileRef, vRef, version);
        });
      };

      sendToStorage(fileRef);
    } catch (error) {
      // There was an error while uploading the file to Dropbox, displaying the concerned file
      console.log(
        "The following error occurred while removing " + fileRef.path
      );
      // Removing the file from the file system
      fs.unlink(fileRef.path, function (error) {
        if (error) {
          console.error(error);
        }
      });
      // Removing the file from the collection
      Images.files.remove(
        {
          _id: fileRef._id,
        },
        function (error) {
          if (error) {
            console.error(error);
          }
        }
      );
    }
  },
  onBeforeRemove: function (cursor) {
    return false;
  },
  interceptDownload: function (http, fileRef, version) {
    // Files are stored in Dropbox, intercepting the download to serve the file from Dropbox
    var path, ref, ref1, ref2;
    path =
      (ref = fileRef.versions) != null
        ? (ref1 = ref[version]) != null
          ? (ref2 = ref1.meta) != null
            ? ref2.pipeFrom
            : void 0
          : void 0
        : void 0;
    if (path) {
      // If file is moved to DropBox
      // We will pipe request to DropBox
      // So, original link will stay always secure
      Request({
        url: path,
        headers: _.pick(
          http.request.headers,
          "range",
          "accept-language",
          "accept",
          "cache-control",
          "pragma",
          "connection",
          "upgrade-insecure-requests",
          "user-agent"
        ),
      })
        .on("response", function (response) {
          if (response.statusCode == 200) {
            response.headers = _.pick(
              response.headers,
              "accept-ranges",
              "cache-control",
              "connection",
              "content-disposition",
              "content-length",
              "content-type",
              "date",
              "etag"
            );
            response.headers["Cache-control"] =
              "only-if-cached, public, max-age=2592000";
          }
        })
        .pipe(http.response);
      return true;
    } else {
      // While file is not yet uploaded to DropBox
      // We will serve file from FS
      return false;
    }
  },
});

// if (Meteor.isServer) {
//   // Intercept File's collection remove method to remove file from DropBox

//   var _origRemove = Images.files.remove; // Catching the original remove method to call it after
//   Images.files.remove = function (search) {
//     var cursor = this.collection.find(search);
//     cursor.forEach(function (fileRef) {
//       _.each(fileRef.versions, function (vRef) {
//         var ref;
//         if (
//           vRef != null
//             ? (ref = vRef.meta) != null
//               ? ref.pipePath
//               : void 0
//             : void 0
//         ) {
//           client
//             .filesDeleteV2({ path: vRef.meta.pipePath })
//             .catch(function (error) {
//               bound(function () {
//                 console.error(error);
//               });
//             });
//         }
//       });
//     });
//     // Call original method
//     _origRemove.call(this, search);
//   };
// }

export default Images; // import in other files

上传表单.js

import { Template }    from 'meteor/templating';

import { ReactiveVar } from 'meteor/reactive-var';

import Images from '/lib/dropbox.js';

Template.uploadForm.onCreated(function () {

  this.currentUpload = new ReactiveVar(false);

});

Template.uploadForm.helpers({

  currentUpload() {

    return Template.instance().currentUpload.get();

  }

});

Template.uploadForm.events({

  'change #fileInput'(e, template) {

      console.log("file opened");

    if (e.currentTarget.files && e.currentTarget.files[0]) {

      // We upload only one file, in case

      // multiple files were selected

      const upload = Images.files.insert({

        file: e.currentTarget.files[0],

        streams: 'dynamic',

        chunkSize: 'dynamic'

      }, false);

      upload.on('start', function () {

        template.currentUpload.set(this);

        console.log("start upload");

      });

      upload.on('end', function (error, fileObj) {

        if (error) {

          alert(`Error during upload: ${error}`);

        } else {

          alert(`File "${fileObj.name}" successfully uploaded`);

        }

        template.currentUpload.set(false);

      });

      upload.start();

    }

  }

});

上传表单.html

<template name="uploadForm">
    {{#with currentUpload}}
      Uploading <b>{{file.name}}</b>:
      <span id="progress">{{progress.get}}%</span>
    {{else}}
      <input id="fileInput" type="file" />
    {{/with}}
</template>

当我尝试上传时,我在服务器控制台中得到了这个

[FilesCollection] [File Start Method] img.png - ms75Ah76svrFEGh2f
[FilesCollection] [Upload] [DDP Start Method] Got #-1/1 chunks, dst: img.png
[FilesCollection] [Upload] [DDP] Got #1/1 chunks, dst: img.png
[FilesCollection] [Upload] [DDP] Got #-1/1 chunks, dst: img.png     
[FilesCollection] [Upload] [finish(ing)Upload] -> tmp\ms75Ah76svrFEGh2f.png
[FilesCollection] [Upload] [finish(ed)Upload] -> tmp\ms75Ah76svrFEGh2f.png 
The following error occurred while removing tmp\ms75Ah76svrFEGh2f.png      
[FilesCollection] [remove({"_id":"ms75Ah76svrFEGh2f"})]
[FilesCollection] [unlink(ms75Ah76svrFEGh2f, undefined)]
[FilesCollection] [_preCollectionCursor.observe] [changed]: ms75Ah76svrFEGh2f
[FilesCollection] [_preCollectionCursor.observe] [removed]: ms75Ah76svrFEGh2f

标签: meteorfile-uploaddropboxmeteor-blaze

解决方案


推荐阅读