Skip to content

Commit

Permalink
get photo metadata in batch
Browse files Browse the repository at this point in the history
  • Loading branch information
mathieudutour committed Feb 26, 2019
1 parent 9b0cc8c commit 2d89f03
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 61 deletions.
71 changes: 10 additions & 61 deletions src/DataProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,7 @@ const path = require('path')
const util = require('util')
const fs = require('@skpm/fs')
const sketch = require('sketch')

const API_KEY = 'bfd993ac8c14516588069b3fc664b216d0e20fb9b9fa35aa06fcc3ba6e0bc703'
const API_ENDPOINT = 'https://api.unsplash.com'
const collectionId = 317099 // Unsplash's curated collection
const apiOptions = {
'headers': {
'app-pragma': 'no-cache'
}
}
const { getImagesURLsForItems } = require('./unsplash')

const { DataSupplier, UI, Settings } = sketch

Expand Down Expand Up @@ -102,60 +94,20 @@ export default function onImageDetails () {
}
}

function setImageForContext (context, ...params) {
function setImageForContext (context, searchTerm, photoId) {
const dataKey = context.data.key
const items = util.toArray(context.data.items).map(sketch.fromNative)
items.forEach((item, index) => setImageFor(item, index, dataKey, ...params))
}

function setImageFor (item, index, dataKey, searchTerm, photoId) {
let layer
if (!item.type) {
// if we get an unknown item, it means that we have a layer that is not yet
// recognized by the API (probably an MSOvalShape or something)
// force cast it to a Shape
item = sketch.Shape.fromNative(item.sketchObject)
}
if (item.type === 'DataOverride') {
layer = item.symbolInstance // or item.override.affectedLayer, but both of them are not really what we need… Check `MSOverrideRepresentation` to get the true size of the affected layer after being resized on the Symbol instance
} else {
layer = item
}

let orientation
if (layer.frame.width > layer.frame.height) {
orientation = 'landscape'
}
if (layer.frame.width < layer.frame.height) {
orientation = 'portrait'
}
if (layer.frame.width === layer.frame.height) {
orientation = 'squarish'
}

let action = photoId ? `/photos/${photoId}` : '/photos/random'
let url = API_ENDPOINT + action + '?client_id=' + API_KEY + '&count=1&orientation=' + orientation
if (!photoId) {
if (searchTerm) {
url += '&query=' + searchTerm
} else {
url += '&collections=' + collectionId
}
}

UI.message('🕑 Downloading…')
fetch(url, apiOptions)
.then(response => response.json())
.then(json => {
if (json.errors) {
return Promise.reject(json.errors[0])
} else if (typeof json.id !== 'undefined') {
return json
getImagesURLsForItems(items, { searchTerm, photoId })
.then(res => Promise.all(res.map(({ data, item, index, error }) => {
if (error) {
UI.message(error)
console.error(error)
} else {
return json[0]
process(data, dataKey, index, item)
}
})
.then(json => process(json, dataKey, index, item))
})))
.catch(e => {
UI.message(e)
console.error(e)
Expand All @@ -176,10 +128,7 @@ function process (data, dataKey, index, item) {
Settings.setLayerSettingForKey(item, SETTING_KEY, data.id)
}

// show the name of the photographer
let downloadLocation = data.links.download_location + '?client_id=' + API_KEY
return fetch(downloadLocation, apiOptions)
.then(UI.message('📷 by ' + data.user.name + ' on Unsplash'))
UI.message('📷 by ' + data.user.name + ' on Unsplash')
})
}

Expand Down
85 changes: 85 additions & 0 deletions src/unsplash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const sketch = require('sketch')

const API_KEY = 'bfd993ac8c14516588069b3fc664b216d0e20fb9b9fa35aa06fcc3ba6e0bc703'
const API_ENDPOINT = 'https://api.unsplash.com'
const collectionId = 317099 // Unsplash's curated collection
const apiOptions = {
'headers': {
'app-pragma': 'no-cache'
}
}

function flatten (arrays) {
return arrays.reduce((prev, array) => prev.concat(array), [])
}

export function getImagesURLsForItems (items, { searchTerm, photoId }) {
const orientations = items.reduce((prev, item, index) => {
if (!item.type) {
// if we get an unknown item, it means that we have a layer that is not yet
// recognized by the API (probably an MSOvalShape or something)
// force cast it to a Shape
item = sketch.Shape.fromNative(item.sketchObject)
}
let layer
if (item.type === 'DataOverride') {
layer = item.symbolInstance // or item.override.affectedLayer, but both of them are not really what we need… Check `MSOverrideRepresentation` to get the true size of the affected layer after being resized on the Symbol instance
} else {
layer = item
}

if (layer.frame.width > layer.frame.height) {
prev.landscape.push({ item, index })
} else if (layer.frame.width < layer.frame.height) {
prev.portrait.push({ item, index })
} else if (layer.frame.width === layer.frame.height) {
prev.squarish.push({ item, index })
}
return prev
}, {
landscape: [],
portrait: [],
squarish: []
})

let action = photoId ? `/photos/${photoId}` : '/photos/random'
let url = API_ENDPOINT + action + '?client_id=' + API_KEY
if (!photoId) {
if (searchTerm) {
url += '&query=' + searchTerm
} else {
url += '&collections=' + collectionId
}
}

return Promise.all(Object.keys(orientations).map(orientation => {
const itemsForOrientation = orientations[orientation]
if (!itemsForOrientation || !itemsForOrientation.length) {
return Promise.resolve([])
}

// we can only request 30 photos max at a time
const numberOfRequests = Math.ceil(itemsForOrientation.length / 30)

return Promise.all(Array(numberOfRequests).fill().map((_, i) => {
// we only itemsForOrientation % 30 photos on the last request
const count = i === numberOfRequests - 1 ? (itemsForOrientation.length % 30) : 30

return fetch(`${url}&count=${count}&orientation=${orientation}`, apiOptions)
.then(response => response.json())
.then(json => {
if (json.errors) {
return Promise.reject(json.errors[0])
}
return json.map((data, j) => ({
data,
...itemsForOrientation[30 * i + j]
}))
}).catch(error => {
// don't reject the promise here so that we can
// at least can provide data for the others
return [{ error }]
})
})).then(flatten)
})).then(flatten)
}

0 comments on commit 2d89f03

Please sign in to comment.