-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ACTION] Unsplash - Search Photos, Get Photo (#11939)
* Tested components * pnpm-lock.yaml
- Loading branch information
Showing
7 changed files
with
345 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import app from "../../unsplash.app.mjs"; | ||
|
||
export default { | ||
key: "unsplash-get-photo", | ||
name: "Get Photo", | ||
description: "Get a specific photo from Unsplash. [See the documentation](https://unsplash.com/documentation#get-a-photo)", | ||
version: "0.0.1", | ||
type: "action", | ||
props: { | ||
app, | ||
photoId: { | ||
propDefinition: [ | ||
app, | ||
"photoId", | ||
], | ||
}, | ||
}, | ||
methods: { | ||
getPhoto({ | ||
photoId, ...args | ||
} = {}) { | ||
return this.app._makeRequest({ | ||
path: `/photos/${photoId}`, | ||
...args, | ||
}); | ||
}, | ||
}, | ||
async run({ $ }) { | ||
const { | ||
getPhoto, | ||
photoId, | ||
} = this; | ||
const response = await getPhoto({ | ||
$, | ||
photoId, | ||
}); | ||
|
||
$.export("$summary", `Successfully retrieved photo with ID \`${response.id}\``); | ||
return response; | ||
}, | ||
}; |
74 changes: 74 additions & 0 deletions
74
components/unsplash/actions/search-photos/search-photos.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import constants from "../../common/constants.mjs"; | ||
import app from "../../unsplash.app.mjs"; | ||
|
||
export default { | ||
key: "unsplash-search-photos", | ||
name: "Search Photos", | ||
description: "Get a single page of photo results for a query. [See the documentation](https://unsplash.com/documentation#search-photos)", | ||
version: "0.0.1", | ||
type: "action", | ||
props: { | ||
app, | ||
query: { | ||
type: "string", | ||
label: "Query", | ||
description: "Search terms.", | ||
}, | ||
contentFilter: { | ||
type: "string", | ||
label: "Content Filter", | ||
description: "Limit results by content safety. Valid values are `low` and `high`.", | ||
optional: true, | ||
options: constants.CONTENT_FILTERS, | ||
}, | ||
color: { | ||
type: "string", | ||
label: "Color", | ||
description: "Filter results by color. Valid values are: `black_and_white`, `black`, `white`, `yellow`, `orange`, `red`, `purple`, `magenta`, `green`, `teal`, and `blue`.", | ||
optional: true, | ||
options: constants.COLOR_OPTIONS, | ||
}, | ||
orientation: { | ||
type: "string", | ||
label: "Orientation", | ||
description: "Filter by photo orientation. Optional. (Valid values: `landscape`, `portrait`, `squarish`)", | ||
optional: true, | ||
options: constants.ORIENTATION_OPTIONS, | ||
}, | ||
}, | ||
methods: { | ||
searchPhotos(args = {}) { | ||
return this.app._makeRequest({ | ||
path: "/search/photos", | ||
...args, | ||
}); | ||
}, | ||
}, | ||
async run({ $ }) { | ||
const { | ||
app, | ||
searchPhotos, | ||
query, | ||
contentFilter, | ||
color, | ||
orientation, | ||
} = this; | ||
|
||
const photos = await app.paginate({ | ||
resourcesFn: searchPhotos, | ||
resourcesFnArgs: { | ||
$, | ||
params: { | ||
query, | ||
content_filter: contentFilter, | ||
color, | ||
orientation, | ||
}, | ||
}, | ||
resourceName: "results", | ||
}); | ||
|
||
$.export("$summary", `Successfully retrieved \`${photos.length}\` photo(s).`); | ||
return photos; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
const BASE_URL = "https://api.unsplash.com"; | ||
const API_VERSION = "v1"; | ||
const DEFAULT_MAX = 100; | ||
const DEFAULT_LIMIT = 100; | ||
|
||
const CONTENT_FILTERS = [ | ||
"low", | ||
"high", | ||
]; | ||
|
||
const COLOR_OPTIONS = [ | ||
{ | ||
label: "Black and White", | ||
value: "black_and_white", | ||
}, | ||
{ | ||
label: "Black", | ||
value: "black", | ||
}, | ||
{ | ||
label: "White", | ||
value: "white", | ||
}, | ||
{ | ||
label: "Yellow", | ||
value: "yellow", | ||
}, | ||
{ | ||
label: "Orange", | ||
value: "orange", | ||
}, | ||
{ | ||
label: "Red", | ||
value: "red", | ||
}, | ||
{ | ||
label: "Purple", | ||
value: "purple", | ||
}, | ||
{ | ||
label: "Magenta", | ||
value: "magenta", | ||
}, | ||
{ | ||
label: "Green", | ||
value: "green", | ||
}, | ||
{ | ||
label: "Teal", | ||
value: "teal", | ||
}, | ||
{ | ||
label: "Blue", | ||
value: "blue", | ||
}, | ||
]; | ||
|
||
const ORIENTATION_OPTIONS = [ | ||
{ | ||
label: "Landscape", | ||
value: "landscape", | ||
}, | ||
{ | ||
label: "Portrait", | ||
value: "portrait", | ||
}, | ||
{ | ||
label: "Squarish", | ||
value: "squarish", | ||
}, | ||
]; | ||
|
||
export default { | ||
BASE_URL, | ||
API_VERSION, | ||
DEFAULT_LIMIT, | ||
DEFAULT_MAX, | ||
CONTENT_FILTERS, | ||
COLOR_OPTIONS, | ||
ORIENTATION_OPTIONS, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
function parseLinkHeader(linkHeader) { | ||
return linkHeader?.split(",") | ||
.reduce((props, link) => { | ||
const [ | ||
url, | ||
rel, | ||
] = link.split(";"); | ||
const [ | ||
, value, | ||
] = url.split("<"); | ||
const [ | ||
, key, | ||
] = rel.split("="); | ||
const clearKey = key.replace(/"/g, ""); | ||
const clearValue = value.replace(/>/g, ""); | ||
return { | ||
...props, | ||
[clearKey]: clearValue, | ||
}; | ||
}, {}); | ||
} | ||
|
||
async function iterate(iterations) { | ||
const items = []; | ||
for await (const item of iterations) { | ||
items.push(item); | ||
} | ||
return items; | ||
} | ||
|
||
export default { | ||
iterate, | ||
parseLinkHeader, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"name": "@pipedream/unsplash", | ||
"version": "0.0.1", | ||
"description": "Pipedream Unsplash Components", | ||
"main": "unsplash.app.mjs", | ||
"keywords": [ | ||
"pipedream", | ||
"unsplash" | ||
], | ||
"homepage": "https://pipedream.com/apps/unsplash", | ||
"author": "Pipedream <[email protected]> (https://pipedream.com/)", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"dependencies": { | ||
"@pipedream/platform": "^1.6.5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,98 @@ | ||
import { axios } from "@pipedream/platform"; | ||
import utils from "./common/utils.mjs"; | ||
import constants from "./common/constants.mjs"; | ||
|
||
export default { | ||
type: "app", | ||
app: "unsplash", | ||
propDefinitions: {}, | ||
propDefinitions: { | ||
photoId: { | ||
type: "string", | ||
label: "Photo ID", | ||
description: "The ID of the photo to retrieve.", | ||
async options({ page }) { | ||
const photos = await this.listPhotos({ | ||
params: { | ||
page: page + 1, | ||
per_page: constants.DEFAULT_LIMIT, | ||
}, | ||
}); | ||
return photos.map(({ | ||
id: value, slug: label, | ||
}) => ({ | ||
label, | ||
value, | ||
})); | ||
}, | ||
}, | ||
}, | ||
methods: { | ||
// this.$auth contains connected account data | ||
authKeys() { | ||
console.log(Object.keys(this.$auth)); | ||
getUrl(path) { | ||
return `${constants.BASE_URL}${path}`; | ||
}, | ||
getHeaders(headers) { | ||
return { | ||
...headers, | ||
"Accept-Version": constants.API_VERSION, | ||
"Authorization": `Bearer ${this.$auth.oauth_access_token}`, | ||
}; | ||
}, | ||
_makeRequest({ | ||
$ = this, path, headers, ...args | ||
} = {}) { | ||
return axios($, { | ||
...args, | ||
debug: true, | ||
url: this.getUrl(path), | ||
headers: this.getHeaders(headers), | ||
}); | ||
}, | ||
listPhotos(args = {}) { | ||
return this._makeRequest({ | ||
path: "/photos", | ||
...args, | ||
}); | ||
}, | ||
async *getIterations({ | ||
resourcesFn, resourcesFnArgs, resourceName, | ||
max = constants.DEFAULT_MAX, | ||
}) { | ||
let page = 1; | ||
let resourcesCount = 0; | ||
|
||
while (true) { | ||
const response = | ||
await resourcesFn({ | ||
...resourcesFnArgs, | ||
params: { | ||
...resourcesFnArgs?.params, | ||
page, | ||
per_page: constants.DEFAULT_LIMIT, | ||
}, | ||
}); | ||
|
||
const nextResources = resourceName && response[resourceName] || response; | ||
|
||
if (!nextResources?.length) { | ||
console.log("No more resources found"); | ||
return; | ||
} | ||
|
||
for (const resource of nextResources) { | ||
yield resource; | ||
resourcesCount += 1; | ||
|
||
if (resourcesCount >= max) { | ||
console.log("Reached max resources"); | ||
return; | ||
} | ||
} | ||
|
||
page += 1; | ||
} | ||
}, | ||
paginate(args = {}) { | ||
return utils.iterate(this.getIterations(args)); | ||
}, | ||
}, | ||
}; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.