Skip to content

Commit

Permalink
Merge pull request #699 from VeliovGroup/dev
Browse files Browse the repository at this point in the history
v1.11.2
 - πŸ“¦ Update `fs-extra` to `v8.1.0` *was `8.0.1`*
 - πŸ“¦ Update `eventemitter3 ` to `v4.0.0` *was `3.1.2`*
 - πŸ“‹ Update Google Cloud Storage tutorial, β€” #698 closing #684, #571 and #664, thanks to @salmanhasni for contribution πŸ₯³
  • Loading branch information
dr-dimitru authored Jun 29, 2019
2 parents 287d5d7 + d4ff3ea commit 6a9a0d2
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 73 deletions.
4 changes: 0 additions & 4 deletions .github/FUNDING.yml

This file was deleted.

30 changes: 15 additions & 15 deletions .npm/package/npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions .versions
106 changes: 57 additions & 49 deletions docs/google-cloud-storage-integration.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,57 @@
#### Using Google Cloud Storage as your storage provider
# Using Google Cloud Storage as your storage provider

This example shows how to add and retrieve files using Google Cloud Storage.
Additionally, this example will also show you how to list uploaded files and remove any of them.

*See production-ready code below.*

##### Step 1: install [google-cloud-node](https://github.com/GoogleCloudPlatform/google-cloud-node)
## Prerequisite

We will use next packages: *Request* (NPM), *Random* (meteor), *Underscore* (meteor)

```shell
npm install --save google-cloud
meteor add underscore
meteor add random
meteor npm install request
```
Or

### Step 1: install [google-cloud-storage](https://github.com/googleapis/nodejs-storage)

```shell
meteor npm install google-cloud
npm install @google-cloud/storage"
```
##### Step 2: Setup your Google Cloud Storage
- Sign into the Google Cloud Console site: https://console.developers.google.com
### Step 2: Setup your Google Cloud Storage
- Sign into the [Google Cloud Console site](https://console.developers.google.com)
- Go to your project and under Storage click on Create Bucket, and name your Bucket
* Don't forget the name of this bucket, you'll need it later
- Don't forget the name of this bucket, you'll need it later
- Under APIs & Auth click on Credentials
- Create an OAuth Service Account for your project (*if you don't already have one*)
- If you do not have a private key, click "*Generate new key*"
* This will download a JSON file to your computer
* Keep this JSON file, it is your key to the account, and you will need it later
* Also, __GUARD THIS JSON FILE AS YOUR LIFE__. IF ANYONE GETS AHOLD OF IT, THEY WILL HAVE FULL ACCESS TO YOUR ACCOUNT!
- This will download a JSON file to your computer
- Keep this JSON file, it is your key to the account, and you will need it later
- Also, __GUARD THIS JSON FILE AS YOUR LIFE__. IF ANYONE GETS AHOLD OF IT, THEY WILL HAVE FULL ACCESS TO YOUR ACCOUNT!
```javascript
var gcloud, gcs, bucket, bucketMetadata, Request, bound, Collections = {};
```js
let gcloud, gcs, bucket, bucketMetadata, Request, bound, Collections = {};
if (Meteor.isServer) {
gcloud = Npm.require('google-cloud')({
// use require() as "'import' and 'export' may only appear at the top level"
const Random = require('meteor/random');
const Storage = require('@google-cloud/storage');
gcs = new Storage('google-cloud')({
projectId: 'YOUR_PROJECT_ID', // <-- Replace this with your project ID
keyFilename: 'YOUR_KEY_JSON' // <-- Replace this with the path to your key.json
});
gcs = gcloud.storage();
bucket = gcs.bucket('YOUR_BUCKET_NAME'); // <-- Replace this with your bucket name
bucket.getMetadata(function(error, metadata, apiResponse){
bucket.getMetadata(function(error, metadata, apiResponse) {
if (error) {
console.error(error);
}
});
Request = Npm.require('request');
bound = Meteor.bindEnvironment(function(callback){
bound = Meteor.bindEnvironment(function(callback) {
return callback();
});
}
Expand All @@ -51,78 +61,76 @@ Collections.files = new FilesCollection({
storagePath: 'assets/app/uploads/uploadedFiles',
collectionName: 'uploadedFiles',
allowClientCode: false,
onAfterUpload: function(fileRef) {
onAfterUpload(fileRef) {
// In the onAfterUpload callback, we will move the file to Google Cloud Storage
var self = this;
_.each(fileRef.versions, function(vRef, version){
_.each(fileRef.versions, (vRef, version) => {
// We use Random.id() instead of real file's _id
// to secure files from reverse engineering
// As after viewing this code it will be easy
// to get access to unlisted and protected files
var filePath = "files/" + (Random.id()) + "-" + version + "." + fileRef.extension;
const filePath = 'files/' + (Random.id()) + '-' + version + '.' + fileRef.extension;
// Here we set the neccesary options to upload the file, for more options, see
// https://googlecloudplatform.github.io/gcloud-node/#/docs/v0.36.0/storage/bucket?method=upload
var options = {
const options = {
destination: filePath,
resumable: true
};
bucket.upload(fileRef.path, options, function(error, file){
bound(function(){
var upd;
bucket.upload(fileRef.path, options, (error, file) => {
bound(() => {
let upd;
if (error) {
console.error(error);
} else {
upd = {
$set: {}
};
upd['$set']["versions." + version + ".meta.pipePath"] = filePath;
self.collection.update({
upd['$set'][`versions.${version}.meta.pipePath`] = filePath;
this.collection.update({
_id: fileRef._id
}, upd, function (error) {
if (error) {
console.error(error);
}, upd, (updError) => {
if (updError) {
console.error(updError);
} else {
// Unlink original files from FS
// after successful upload to Google Cloud Storage
self.unlink(self.collection.findOne(fileRef._id), version);
this.unlink(this.collection.findOne(fileRef._id), version);
}
});
}
});
});
});
},
interceptDownload: function(http, fileRef, version) {
var path, ref, ref1, ref2;
path = (ref= fileRef.versions) != null ? (ref1 = ref[version]) != null ? (ref2 = ref1.meta) != null ? ref2.pipePath : void 0 : void 0 : void 0;
var vRef = ref1;
interceptDownload(http, fileRef, version) {
let ref, ref1, ref2;
const path = (ref= fileRef.versions) != null ? (ref1 = ref[version]) != null ? (ref2 = ref1.meta) != null ? ref2.pipePath : void 0 : void 0 : void 0;
const vRef = ref1;
if (path) {
// If file is moved to Google Cloud Storage
// We will pipe request to Google Cloud Storage
// So, original link will stay always secure
var remoteReadStream = getReadableStream(http, path, vRef);
const remoteReadStream = getReadableStream(http, path, vRef);
this.serve(http, fileRef, vRef, version, remoteReadStream);
return true;
} else {
// While the file has not been uploaded to Google Cloud Storage, we will serve it from the filesystem
return false;
}
// While the file has not been uploaded to Google Cloud Storage, we will serve it from the filesystem
return false;
}
});
if (Meteor.isServer) {
// Intercept file's collection remove method to remove file from Google Cloud Storage
var _origRemove = Collections.files.remove;
const _origRemove = Collections.files.remove;
Collections.files.remove = function(search) {
var cursor = this.collection.find(search);
cursor.forEach(function(fileRef) {
_.each(fileRef.versions, function(vRef) {
var ref;
const cursor = this.collection.find(search);
cursor.forEach((fileRef) => {
_.each(fileRef.versions, (vRef) => {
let ref;
if (vRef != null ? (ref = vRef.meta) != null ? ref.pipePath : void 0 : void 0) {
bucket.file(vRef.meta.pipePath).delete(function(error) {
bound(function() {
bucket.file(vRef.meta.pipePath).delete((error) => {
bound(() => {
if (error) {
console.error(error);
}
Expand All @@ -137,7 +145,7 @@ if (Meteor.isServer) {
}
function getReadableStream(http, path, vRef){
var array, end, partial, remoteReadStream, reqRange, responseType, start, take;
let array, end, partial, remoteReadStream, reqRange, responseType, start, take;
if (http.request.headers.range) {
partial = true;
Expand Down Expand Up @@ -179,12 +187,12 @@ function getReadableStream(http, path, vRef){
responseType = '200';
}
if (responseType === "206") {
if (responseType === '206') {
remoteReadStream = bucket.file(path).createReadStream({
start: reqRange.start,
end: reqRange.end
});
} else if (responseType === "200") {
} else if (responseType === '200') {
remoteReadStream = bucket.file(path).createReadStream();
}
Expand Down
6 changes: 3 additions & 3 deletions package.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
Package.describe({
name: 'ostrio:files',
version: '1.11.1',
version: '1.11.2',
summary: 'Upload files to Meteor application, with 3rd party storage support: AWS:S3, GridFS and other',
git: 'https://github.com/VeliovGroup/Meteor-Files',
documentation: 'README.md'
});

Npm.depends({
'fs-extra': '8.0.1',
'fs-extra': '8.1.0',
request: '2.88.0',
'file-type': '12.0.0',
eventemitter3: '3.1.2'
eventemitter3: '4.0.0'
});

Package.onUse(function(api) {
Expand Down

0 comments on commit 6a9a0d2

Please sign in to comment.