Skip to content

Commit a7094ae

Browse files
authored
New Components - pexels (#16498)
* pexels init * [Components] pexels #16496 Sources - New Photo By Search - New Curated Photo Actions - Search Photos - Get Photo Details - Download Photo * pnpm update * update package.json * pnpm update * fix import path * fix props types
1 parent 6d66e61 commit a7094ae

File tree

12 files changed

+524
-7
lines changed

12 files changed

+524
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { axios } from "@pipedream/platform";
2+
import fs from "fs";
3+
import stream from "stream";
4+
import { promisify } from "util";
5+
import pexels from "../../pexels.app.mjs";
6+
7+
export default {
8+
key: "pexels-download-photo",
9+
name: "Download Photo",
10+
description: "Download a specific photo by providing its photo ID and optionally choosing the desired size. [See the documentation](https://www.pexels.com/api/documentation/)",
11+
version: "0.0.1",
12+
type: "action",
13+
props: {
14+
pexels,
15+
photoId: {
16+
propDefinition: [
17+
pexels,
18+
"photoId",
19+
],
20+
},
21+
filePath: {
22+
type: "string",
23+
label: "File Path",
24+
description: "The destination path in [`/tmp`](https://pipedream.com/docs/workflows/steps/code/nodejs/working-with-files/#the-tmp-directory) for the downloaded the file (e.g., `/tmp/myFile.jpg`). Make sure to include the file extension.",
25+
},
26+
},
27+
methods: {
28+
getFileStream({
29+
$, downloadUrl,
30+
}) {
31+
return axios($, {
32+
url: downloadUrl,
33+
responseType: "stream",
34+
});
35+
},
36+
},
37+
async run({ $ }) {
38+
const response = await this.pexels.getPhoto({
39+
$,
40+
photoId: this.photoId,
41+
});
42+
43+
const fileStream = await this.getFileStream({
44+
$,
45+
downloadUrl: response.src.original,
46+
});
47+
48+
const pipeline = promisify(stream.pipeline);
49+
const resp = await pipeline(
50+
fileStream,
51+
fs.createWriteStream(this.filePath.includes("/tmp")
52+
? this.filePath
53+
: `/tmp/${this.filePath}`),
54+
);
55+
56+
$.export("$summary", `Successfully downloaded photo with ID ${this.photoId} to ${this.filePath}`);
57+
return {
58+
resp,
59+
};
60+
},
61+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import pexels from "../../pexels.app.mjs";
2+
3+
export default {
4+
key: "pexels-get-photo-details",
5+
name: "Get Photo Details",
6+
description: "Retrieve detailed information about a specific photo by providing its photo ID. [See the documentation](https://www.pexels.com/api/documentation/#photos-show)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
pexels,
11+
photoId: {
12+
propDefinition: [
13+
pexels,
14+
"photoId",
15+
],
16+
},
17+
},
18+
async run({ $ }) {
19+
const response = await this.pexels.getPhoto({
20+
$,
21+
photoId: this.photoId,
22+
});
23+
$.export("$summary", `Successfully retrieved details for photo ID: ${this.photoId}`);
24+
return response;
25+
},
26+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import pexels from "../../pexels.app.mjs";
2+
3+
export default {
4+
key: "pexels-search-photos",
5+
name: "Search Photos",
6+
description: "Search for photos on Pexels using a keyword or phrase. [See the documentation](https://www.pexels.com/api/documentation/#photos-search)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
pexels,
11+
searchQuery: {
12+
propDefinition: [
13+
pexels,
14+
"searchQuery",
15+
],
16+
},
17+
orientation: {
18+
propDefinition: [
19+
pexels,
20+
"orientation",
21+
],
22+
},
23+
size: {
24+
propDefinition: [
25+
pexels,
26+
"size",
27+
],
28+
},
29+
color: {
30+
propDefinition: [
31+
pexels,
32+
"color",
33+
],
34+
},
35+
page: {
36+
type: "integer",
37+
label: "Page",
38+
description: "The page number you are requesting",
39+
optional: true,
40+
},
41+
perPage: {
42+
type: "integer",
43+
label: "Per Page",
44+
description: "The number of results you are requesting per page",
45+
max: 80,
46+
optional: true,
47+
},
48+
},
49+
async run({ $ }) {
50+
const response = await this.pexels.searchPhotos({
51+
$,
52+
params: {
53+
query: this.searchQuery,
54+
orientation: this.orientation,
55+
size: this.size,
56+
color: this.color,
57+
page: this.page || 1,
58+
per_page: this.perPage || 15,
59+
},
60+
});
61+
62+
$.export("$summary", `Successfully retrieved ${response.photos.length} photos for the query "${this.searchQuery}".`);
63+
return response;
64+
},
65+
};
+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
export const ORIENTATION_OPTIONS = [
2+
{
3+
label: "Landscape",
4+
value: "landscape",
5+
},
6+
{
7+
label: "Portrait",
8+
value: "portrait",
9+
},
10+
{
11+
label: "Square",
12+
value: "square",
13+
},
14+
];
15+
16+
export const SIZE_OPTIONS = [
17+
{
18+
label: "Large (24MP)",
19+
value: "large",
20+
},
21+
{
22+
label: "Medium (12MP)",
23+
value: "medium",
24+
},
25+
{
26+
label: "Small (4MP)",
27+
value: "small",
28+
},
29+
];
30+
31+
export const COLOR_OPTIONS = [
32+
{
33+
label: "Red",
34+
value: "red",
35+
},
36+
{
37+
label: "Orange",
38+
value: "orange",
39+
},
40+
{
41+
label: "Yellow",
42+
value: "yellow",
43+
},
44+
{
45+
label: "Green",
46+
value: "green",
47+
},
48+
{
49+
label: "Turquoise",
50+
value: "turquoise",
51+
},
52+
{
53+
label: "Blue",
54+
value: "blue",
55+
},
56+
{
57+
label: "Violet",
58+
value: "violet",
59+
},
60+
{
61+
label: "Pink",
62+
value: "pink",
63+
},
64+
{
65+
label: "Brown",
66+
value: "brown",
67+
},
68+
{
69+
label: "Black",
70+
value: "black",
71+
},
72+
{
73+
label: "Gray",
74+
value: "gray",
75+
},
76+
{
77+
label: "White",
78+
value: "white",
79+
},
80+
];

components/pexels/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/pexels",
3-
"version": "0.6.0",
3+
"version": "0.1.0",
44
"description": "Pipedream pexels Components",
55
"main": "pexels.app.mjs",
66
"keywords": [
@@ -13,6 +13,7 @@
1313
"access": "public"
1414
},
1515
"dependencies": {
16-
"@pipedream/platform": "^3.0.0"
16+
"@pipedream/platform": "^3.0.3",
17+
"stream": "^0.0.3"
1718
}
1819
}

components/pexels/pexels.app.mjs

+101-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,108 @@
1+
import { axios } from "@pipedream/platform";
2+
import {
3+
COLOR_OPTIONS,
4+
ORIENTATION_OPTIONS,
5+
SIZE_OPTIONS,
6+
} from "./common/constants.mjs";
7+
18
export default {
29
type: "app",
310
app: "pexels",
4-
propDefinitions: {},
11+
propDefinitions: {
12+
searchQuery: {
13+
type: "string",
14+
label: "Search Query",
15+
description: "The search query. **Ocean**, **Tigers**, **Pears**, etc.",
16+
},
17+
orientation: {
18+
type: "string",
19+
label: "Orientation",
20+
description: "Desired photo orientation.",
21+
optional: true,
22+
options: ORIENTATION_OPTIONS,
23+
},
24+
size: {
25+
type: "string",
26+
label: "Size",
27+
description: "Minimum photo size.",
28+
optional: true,
29+
options: SIZE_OPTIONS,
30+
},
31+
color: {
32+
type: "string",
33+
label: "Color",
34+
description: "Desired photo color. You can set any color listed or any hexidecimal color code (eg. #ffffff)",
35+
optional: true,
36+
options: COLOR_OPTIONS,
37+
},
38+
photoId: {
39+
type: "string",
40+
label: "Photo ID",
41+
description: "The ID of the photo to retrieve or download.",
42+
},
43+
},
544
methods: {
6-
// this.$auth contains connected account data
7-
authKeys() {
8-
console.log(Object.keys(this.$auth));
45+
_baseUrl() {
46+
return "https://api.pexels.com/v1";
47+
},
48+
_headers() {
49+
return {
50+
"Authorization": `${this.$auth.api_key}`,
51+
};
52+
},
53+
_makeRequest({
54+
$ = this, path, ...opts
55+
}) {
56+
return axios($, {
57+
url: this._baseUrl() + path,
58+
headers: this._headers(),
59+
...opts,
60+
});
61+
},
62+
searchPhotos(opts = {}) {
63+
return this._makeRequest({
64+
path: "/search",
65+
...opts,
66+
});
67+
},
68+
getPhoto({
69+
photoId, ...opts
70+
} = {}) {
71+
return this._makeRequest({
72+
path: `/photos/${photoId}`,
73+
...opts,
74+
});
75+
},
76+
getCuratedPhotos(opts = {}) {
77+
return this._makeRequest({
78+
path: "/curated",
79+
...opts,
80+
});
81+
},
82+
async *paginate({
83+
fn, params = {}, maxResults = null, ...opts
84+
}) {
85+
let hasMore = false;
86+
let count = 0;
87+
let page = 0;
88+
89+
do {
90+
params.page = ++page;
91+
const { photos } = await fn({
92+
params,
93+
...opts,
94+
});
95+
for (const d of photos) {
96+
yield d;
97+
98+
if (maxResults && ++count === maxResults) {
99+
return count;
100+
}
101+
}
102+
103+
hasMore = photos.length;
104+
105+
} while (hasMore);
9106
},
10107
},
11108
};

0 commit comments

Comments
 (0)