Skip to content
This repository has been archived by the owner on Aug 18, 2021. It is now read-only.

Commit

Permalink
Merge pull request #27 from artsy/staging
Browse files Browse the repository at this point in the history
Deploy
  • Loading branch information
zephraph authored Oct 4, 2020
2 parents 6a2e948 + c73862f commit eee0439
Show file tree
Hide file tree
Showing 10 changed files with 300 additions and 42 deletions.
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ tmp
node_modules
npm-debug.log
.vscode
redis.conf
redis.conf
.google-api-creds.json
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ node_modules
.env
vars.yml
.hokusai-tmp
.google-api-creds.json
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ FROM node:12.14-alpine

# Build environment variables
ARG SHEETS_URL
ARG G_CREDS
ARG ACCESS_KEY_ID
ARG SECRET_ACCESS_KEY
ARG REGION
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,21 @@ Team Nav started off as a hackathon project way back in 2015. It's evolved a lot
_For Artsy Employees_

1. Copy down the `.env` file from citadel (You'll need proper access)

```
aws s3 cp s3://artsy-citadel/dev/.env.team .env
```

2. Install dependencies and start the service in dev mode

```
yarn && yarn dev
```

## Deploying

Merged PRs to `artsy/team#master` are automatically deployed to staging; PRs from `staging` to `release` are automatically deployed to production. [Start a deploy...](https://github.com/artsy/team/compare/release...staging?expand=1)

## About Artsy

<a href="https://www.artsy.net/">
Expand Down
1 change: 1 addition & 0 deletions hokusai/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ services:
context: ../
args:
SHEETS_URL: "{{ SHEETS_URL }}"
G_CREDS: "{{ G_CREDS }}"
ACCESS_KEY_ID: "{{ ACCESS_KEY_ID }}"
SECRET_ACCESS_KEY: "{{ SECRET_ACCESS_KEY }}"
REGION: "{{ REGION }}"
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
"private": true,
"description": "",
"scripts": {
"write-creds": "node ./scripts/write-credentials",
"start": "next start",
"predev": "dotenv yarn write-creds",
"dev": "next dev",
"prebuild": "dotenv yarn write-creds",
"build": "next build",
"type-check": "tsc",
"logs:staging": "hokusai staging logs | grep '^{' | npx miami-vice",
Expand All @@ -18,6 +21,7 @@
"aws-sdk": "^2.668.0",
"csvtojson": "^2.0.10",
"date-fns": "^2.12.0",
"googleapis": "^59.0.0",
"isomorphic-unfetch": "^3.0.0",
"isotopes": "^0.6.0",
"jwt-decode": "^2.2.0",
Expand Down Expand Up @@ -48,6 +52,7 @@
"@types/sharp": "^0.25.0",
"@types/styled-components": "^4",
"@types/styled-system": "^5.1.10",
"dotenv-cli": "^4.0.0",
"next-transpile-modules": "^4.1.0",
"typescript": "^3.8.3",
"typescript-styled-plugin": "^0.15.0"
Expand Down
9 changes: 9 additions & 0 deletions scripts/write-credentials.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* This file writes out the google credentials required to access the google drive api to read our team images.
*/
const fs = require("fs");

fs.writeFileSync(
".google-api-creds.json",
Buffer.from(process.env.G_CREDS, "base64").toString("ascii")
);
82 changes: 48 additions & 34 deletions src/data/image.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
import sharp from "sharp";
import S3 from "aws-sdk/clients/s3";
import stream from "stream";
import { hash } from "utils";
import { google } from "googleapis";

const drive = google.drive({
version: "v3",
auth: new google.auth.GoogleAuth({
keyFile: "./.google-api-creds.json",
scopes: [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/drive.appdata",
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive.metadata",
"https://www.googleapis.com/auth/drive.metadata.readonly",
"https://www.googleapis.com/auth/drive.photos.readonly",
"https://www.googleapis.com/auth/drive.readonly",
],
}),
});

const streamToS3 = (
s3: S3,
Expand All @@ -28,42 +44,40 @@ export async function resizeImage(
secretAccessKey: process.env.SECRET_ACCESS_KEY,
region: process.env.REGION,
});
if (imageUrl.href.includes("dropbox")) {
imageUrl.search = "?raw=1";
} else if (imageUrl.href.includes("drive.google.com")) {
const imageId = imageUrl.href.split("/file/d/")[1]?.split("/")[0];
if (!imageId) {
throw new Error(
`Invalid formatted google drive image url: ${imageUrl.href}`
);
}
imageUrl.href = "https://drive.google.com/a/artsymail.com/uc";
imageUrl.search = `?id=${imageId}`;

if (!imageUrl.href.startsWith("https://drive.google.com")) {
throw new Error(`Error processing ${imageUrl.href}, not a drive url`);
}

const imageId = imageUrl.href.split("/file/d/")[1]?.split("/")[0];

if (!imageId) {
throw new Error(
`Invalid formatted google drive image url: ${imageUrl.href}`
);
}

const resizer = sharp().rotate().resize(size, size);

return fetch(imageUrl.toString(), { redirect: "follow" }).then((imgRes) => {
return new Promise((resolve, reject) => {
if (!imgRes.headers.get("content-type")?.includes("image")) {
reject(`${imageUrl} resulted in invalid content type`);
return;
}
if (imgRes.status >= 400) {
reject(`${imageUrl} was not found`);
return;
}
(imgRes.body as any).pipe(resizer).pipe(
streamToS3(
s3,
`team/${hash(
imageUrl.href + "?size=" + size
)}.${imageUrl.pathname.split(".").pop()}`,
(err, data) => {
err ? reject(err) : resolve(data.Location);
}
)
);
});
const file = await drive.files.get(
{
fileId: imageId,
alt: "media",
},
{ responseType: "stream" }
);

const contentType = file.headers["content-type"];
const extension =
contentType.includes("image") && contentType.split("image/")[1];

if (!extension) throw new Error(`No valid extension for ${imageUrl.href}`);

return new Promise((resolve, reject) => {
file.data.pipe(resizer).pipe(
streamToS3(s3, `team/${imageId}-${size}.${extension}`, (err, data) => {
err ? reject(err) : resolve(data.Location);
})
);
});
}
4 changes: 3 additions & 1 deletion src/data/team.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const getResizedImageUrl = async (
return limit(() => resizeImage(new URL(imageUrl), size)).then(
async function afterResizingImage(resizedImageUrl) {
if (!resizedImageUrl) {
log.error(`No image URL provided`);
return;
}
log.info(`resized ${imageUrl} to ${size}`);
Expand Down Expand Up @@ -63,7 +64,8 @@ export const getMembers = memoize(async () => {
try {
member.profileImage = await getResizedImageUrl(member.headshot, 500);
member.avatar = await getResizedImageUrl(member.headshot, 200);
} catch {
} catch (error) {
log.error(error);
member.profileImage = "";
member.avatar = "";
}
Expand Down
Loading

0 comments on commit eee0439

Please sign in to comment.