Skip to content
This repository has been archived by the owner on Oct 11, 2022. It is now read-only.

Commit

Permalink
Merge pull request #2928 from johnnynotsolucky/local-image-storage
Browse files Browse the repository at this point in the history
Add local file storage for dev environments
  • Loading branch information
mxstbr authored Apr 23, 2018
2 parents 484dcec + 9c1b2e6 commit e220fef
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ api/.env
.expo
mobile/.expo
test-results.json
public/uploads
2 changes: 1 addition & 1 deletion api/models/community.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow
const { db } = require('./db');
import { parseRange } from './utils';
import { uploadImage } from '../utils/s3';
import { uploadImage } from '../utils/file-storage';
import getRandomDefaultPhoto from '../utils/get-random-default-photo';
import {
sendNewCommunityWelcomeEmailQueue,
Expand Down
2 changes: 1 addition & 1 deletion api/models/user.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow
const { db } = require('./db');
import { uploadImage } from '../utils/s3';
import { uploadImage } from '../utils/file-storage';
import { createNewUsersSettings } from './usersSettings';
import { sendNewUserWelcomeEmailQueue } from 'shared/bull/queues';
import type { PaginationOptions } from '../utils/paginate-arrays';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
getDirectMessageThread,
createDirectMessageThread,
} from '../../models/directMessageThread';
import { uploadImage } from '../../utils/s3';
import { uploadImage } from '../../utils/file-storage';
import { storeMessage } from '../../models/message';
import {
setUserLastSeenInDirectMessageThread,
Expand Down
2 changes: 1 addition & 1 deletion api/mutations/message/addMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { stateFromMarkdown } from 'draft-js-import-markdown';
import { EditorState } from 'draft-js';
import type { GraphQLContext } from '../../';
import UserError from '../../utils/UserError';
import { uploadImage } from '../../utils/s3';
import { uploadImage } from '../../utils/file-storage';
import { storeMessage } from '../../models/message';
import { setDirectMessageThreadLastActive } from '../../models/directMessageThread';
import { setUserLastSeenInDirectMessageThread } from '../../models/usersDirectMessageThreads';
Expand Down
2 changes: 1 addition & 1 deletion api/mutations/thread/editThread.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type { GraphQLContext } from '../../';
import type { EditThreadInput } from '../../models/thread';
import UserError from '../../utils/UserError';
import { uploadImage } from '../../utils/s3';
import { uploadImage } from '../../utils/file-storage';
import { getThreads, editThread } from '../../models/thread';
import { getUserPermissionsInCommunity } from '../../models/usersCommunities';
import { getUserPermissionsInChannel } from '../../models/usersChannels';
Expand Down
2 changes: 1 addition & 1 deletion api/mutations/thread/publishThread.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const debug = require('debug')('api:mutations:thread:publish-thread');
import stringSimilarity from 'string-similarity';
import type { GraphQLContext } from '../../';
import UserError from '../../utils/UserError';
import { uploadImage } from '../../utils/s3';
import { uploadImage } from '../../utils/file-storage';
import {
publishThread,
editThread,
Expand Down
27 changes: 27 additions & 0 deletions api/utils/file-storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// @flow
require('now-env');

import type { FileUpload, EntityTypes } from 'shared/types';

const { FILE_STORAGE } = process.env;

const getUploadImageFn = () => {
switch (FILE_STORAGE) {
case 'local':
return require('./file-system').uploadImage;
case 's3':
default:
return require('./s3').uploadImage;
}
};

const uploadImageFn = getUploadImageFn();

export const uploadImage = (
file: FileUpload,
entity: EntityTypes,
id: string
): Promise<string> =>
uploadImageFn(file, entity, id).catch(err => {
throw new Error(err);
});
40 changes: 40 additions & 0 deletions api/utils/file-system.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// @flow
import shortid from 'shortid';
import fs from 'fs';

import type { FileUpload, EntityTypes } from 'shared/types';

const STORAGE_DIR = 'public/uploads';
const READ_WRITE_MODE = 0o777;

const dirExists = (path: string): Promise<boolean> =>
new Promise(res => fs.access(path, fs.constants.F_OK, err => res(!!!err)));

const createUploadsDir = (path: string): Promise<void> =>
new Promise(res =>
fs.mkdir(path, READ_WRITE_MODE, err => {
if (err) throw new Error(err);
res();
})
);

export const uploadImage = async (
file: FileUpload,
entity: EntityTypes,
id: string
): Promise<string> => {
const result = await file;

if (!await dirExists(STORAGE_DIR)) {
await createUploadsDir(STORAGE_DIR);
}

return new Promise(res => {
const filePath = `${shortid.generate()}-${entity}-${id}`;
const { stream } = result;
stream.pipe(fs.createWriteStream(`${STORAGE_DIR}/${filePath}`));
stream.on('end', () => {
res(encodeURI(`/uploads/${filePath}`));
});
});
};
15 changes: 2 additions & 13 deletions api/utils/s3.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import AWS from 'aws-sdk';
import shortid from 'shortid';
const IS_PROD = process.env.NODE_ENV === 'production';

import type { FileUpload } from 'shared/types';
type EntityTypes = 'communities' | 'channels' | 'users' | 'threads';
import type { FileUpload, EntityTypes } from 'shared/types';

let S3_TOKEN = process.env.S3_TOKEN;
let S3_SECRET = process.env.S3_SECRET;
Expand Down Expand Up @@ -36,7 +35,7 @@ const generateImageUrl = path => {
return imgixBase + '/' + newPath;
};

const upload = async (
export const uploadImage = async (
file: FileUpload,
entity: EntityTypes,
id: string
Expand All @@ -62,13 +61,3 @@ const upload = async (
);
});
};

export const uploadImage = async (
file: FileUpload,
entity: EntityTypes,
id: string
): Promise<string> => {
return await upload(file, entity, id).catch(err => {
throw new Error(err);
});
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@
"start:pluto": "cross-env NODE_ENV=production node build-pluto/main.js",
"start:api": "cross-env NODE_ENV=production node build-api/main.js",
"dev:web": "cross-env NODE_PATH=./ react-app-rewired start",
"dev:api": "cross-env NODE_PATH=./ cross-env NODE_ENV=development cross-env DEBUG=build*,api*,shared:middlewares*,-api:resolvers cross-env DIR=api backpack",
"dev:api": "cross-env FILE_STORAGE=local cross-env NODE_PATH=./ cross-env NODE_ENV=development cross-env DEBUG=build*,api*,shared:middlewares*,-api:resolvers cross-env DIR=api backpack",
"dev:athena": "cross-env NODE_PATH=./ cross-env NODE_ENV=development cross-env DEBUG=build*,athena*,shared:middlewares*,-athena:resolvers cross-env DIR=athena backpack",
"dev:hermes": "cross-env NODE_PATH=./ cross-env NODE_ENV=development cross-env DEBUG=build*,hermes*,shared:middlewares*,-hermes:resolvers cross-env DIR=hermes backpack",
"dev:chronos": "cross-env NODE_PATH=./ cross-env NODE_ENV=development cross-env DEBUG=build*,chronos*,shared:middlewares*,-chronos:resolvers cross-env DIR=chronos backpack",
Expand Down
2 changes: 2 additions & 0 deletions shared/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,5 @@ export type FileUpload = {
encoding: string,
stream: any,
};

export type EntityTypes = 'communities' | 'channels' | 'users' | 'threads';

0 comments on commit e220fef

Please sign in to comment.