Skip to content

Commit

Permalink
Merge pull request #26 from isomerpages/blob
Browse files Browse the repository at this point in the history
Blob
  • Loading branch information
kwajiehao authored Nov 15, 2019
2 parents b79b885 + 748f4b7 commit abdbd9a
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 7 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.env
node_modules/
node_modules/
.vscode/
172 changes: 172 additions & 0 deletions classes/ImageFile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
const axios = require('axios');
const _ = require('lodash')

const GITHUB_ORG_NAME = 'isomerpages'

// validateStatus allows axios to handle a 404 HTTP status without rejecting the promise.
// This is necessary because GitHub returns a 404 status when the file does not exist.
const validateStatus = (status) => {
return (status >= 200 && status < 300) || status === 404
}

class ImageFile {
constructor(accessToken, siteName) {
this.accessToken = accessToken
this.siteName = siteName
this.baseEndpoint = null
this.blobEndpoint = null
this.fileType = null
}

setFileTypeToImage() {
this.fileType = new ImageType()
this.baseEndpoint = `https://api.github.com/repos/${GITHUB_ORG_NAME}/${this.siteName}/contents/${this.fileType.getFolderName()}`
// Endpoint to retrieve files greater than 1MB
this.baseBlobEndpoint = `https://api.github.com/repos/${GITHUB_ORG_NAME}/${this.siteName}/git/blobs`
}



async list() {
try {
const endpoint = `${this.baseEndpoint}`

const resp = await axios.get(endpoint, {
validateStatus: validateStatus,
headers: {
Authorization: `token ${this.accessToken}`,
"Content-Type": "application/json"
}
})

if (resp.status !== 200) return {}

const files = resp.data.map(object => {
const pathNameSplit = object.path.split("/")
const fileName = pathNameSplit[pathNameSplit.length - 1]
if (object.type === 'file') {
return {
path: encodeURIComponent(object.path),
fileName,
sha: object.sha
}
}
})

return _.compact(files)
} catch (err) {
throw err
}
}

async create(fileName, content) {
try {
const endpoint = `${this.baseEndpoint}/${fileName}`

let params = {
"message": `Create file: ${fileName}`,
"content": content,
"branch": "staging",
}

const resp = await axios.put(endpoint, params, {
headers: {
Authorization: `token ${this.accessToken}`,
"Content-Type": "application/json"
}
})

return { sha: resp.data.content.sha }
} catch (err) {
throw err
}
}

async read(fileName) {
try {
/**
* Images that are bigger than 1 MB needs to be retrieved
* via Github Blob API. The content can only be retrieved through
* the `sha` of the file.
* The code below takes the `fileName`,
* lists all the files in the image directory
* and filters it down to get the sha of the file
*/
const images = await this.list()
const imageSha = images.filter(image => image.fileName === fileName)[0].sha

const blobEndpoint = `${this.baseBlobEndpoint}/${imageSha}`

const resp = await axios.get(blobEndpoint, {
validateStatus: validateStatus,
headers: {
Authorization: `token ${this.accessToken}`,
}
})

if (resp.status === 404) throw new Error ('Page does not exist')

const { content, sha } = resp.data

return { content, sha }
} catch (err) {
throw err
}
}

async update(fileName, content, sha) {
try {
const endpoint = `${this.baseEndpoint}/${fileName}`

let params = {
"message": `Update file: ${fileName}`,
"content": content,
"branch": "staging",
"sha": sha
}

const resp = await axios.put(endpoint, params, {
headers: {
Authorization: `token ${this.accessToken}`,
"Content-Type": "application/json"
}
})

return { newSha: resp.data.commit.sha }
} catch (err) {
throw err
}
}

async delete (fileName, sha) {
try {
const endpoint = `${this.baseEndpoint}/${fileName}`

let params = {
"message": `Delete file: ${fileName}`,
"branch": "staging",
"sha": sha
}

await axios.delete(endpoint, {
data: params,
headers: {
Authorization: `token ${this.accessToken}`,
"Content-Type": "application/json"
}
})
} catch (err) {
throw err
}
}
}

class ImageType {
constructor() {
this.folderName = 'images'
}
getFolderName() {
return this.folderName
}
}
module.exports = { ImageFile }
8 changes: 4 additions & 4 deletions routes/images.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const jwtUtils = require('../utils/jwt-utils')

// Import classes
const { File, ImageType } = require('../classes/File.js')
const { ImageFile } = require('../classes/ImageFile.js')

// List images
router.get('/:siteName/images', async function(req, res, next) {
Expand Down Expand Up @@ -54,10 +55,9 @@ router.get('/:siteName/images/:imageName', async function(req, res, next) {

const { siteName, imageName } = req.params

const IsomerFile = new File(access_token, siteName)
const imageType = new ImageType()
IsomerFile.setFileType(imageType)
const { sha, content } = await IsomerFile.read(imageName)
const IsomerImageFile = new ImageFile(access_token, siteName)
IsomerImageFile.setFileTypeToImage()
const { sha, content } = await IsomerImageFile.read(imageName)

// TO-DO:
// Validate content
Expand Down
4 changes: 2 additions & 2 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const homepageRouter = require('./routes/homepage')
const app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.json({ limit: '5mb'}));
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
Expand Down Expand Up @@ -64,7 +64,7 @@ app.use(function(err, req, res, next) {

// render the error page
res.status(err.status || 500);
res.render('error');
res.json({ error: err });
});

module.exports = app;

0 comments on commit abdbd9a

Please sign in to comment.