Skip to content

Commit 2a31034

Browse files
committed
Initial version
0 parents  commit 2a31034

9 files changed

+2426
-0
lines changed

.babelrc

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"presets": [
3+
[
4+
"@babel/preset-env",
5+
{
6+
"useBuiltIns": "entry",
7+
"shippedProposals": true,
8+
"modules": "commonjs",
9+
"targets": {
10+
"node": 4
11+
}
12+
}
13+
]
14+
]
15+
}

.editorconfig

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# editorconfig.org
2+
root = true
3+
4+
[*]
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true
11+
12+
[{*.json, *.svg}]
13+
indent_style = space
14+
indent_size = 4
15+
16+
# Matches the exact package.json, or *rc
17+
[{package.json,*.yml,*rc}]
18+
indent_style = space
19+
indent_size = 2

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
/gatsby-node.js

.npmignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
src
2+
.babelrc
3+
.editorconfig

README.md

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# gatsby-source-pixabay
2+
3+
This source plugin for Gatsby will make images from [Flickr](https://flickr.com/) available in GraphQL queries.
4+
5+
## Derivation
6+
7+
This source plugin is **heavily** based on [Jason Lengstorf's](https://github.com/jlengstorf) [gatsby-source-pixabay](https://github.com/jlengstorf/gatsby-source-pixabay)
8+
9+
## Installation
10+
11+
```sh
12+
# Install the plugin
13+
yarn add gatsby-source-flickr
14+
```
15+
16+
In `gatsby-config.js`:
17+
18+
```js
19+
module.exports = {
20+
plugins: [
21+
{
22+
resolve: "gatsby-source-flickr",
23+
options: {
24+
api_key: "YOUR_FLICKR_API_KEY"
25+
}
26+
}
27+
]
28+
};
29+
```
30+
31+
**NOTE:** To get a Flickr API key, [register for a Flickr account](https://www.flickr.com/signup). You will then need to create a [Flickr API app](https://www.flickr.com/services/apps/create/).
32+
33+
## Configuration Options
34+
35+
The configuration options for this plugin mirror the [Flickr photo search API call options](https://www.flickr.com/services/api/flickr.photos.search.html). The only **required** option is the `api_key`.
36+
37+
The plugin will add defaults for certain other fields:
38+
39+
| key | default value | comment |
40+
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
41+
| method | flickr.photos.search | the plugin expects the call to use the photo search api |
42+
| extras | description, license, date_upload, date_taken, owner_name, icon_server, original_format, last_update, geo, tags, machine_tags, o_dims, views, media, path_alias, url_sq, url_t, url_s, url_q, url_m, url_n, url_z, url_c, url_l, url_o | these are the fields (all the available ones as of the time of writing) |
43+
| per_page | 500 | the number of photos per page (API call pagination) - 500 is the current maximum) |
44+
| format | json | the plugin expects json |
45+
| nojsoncallback | 1 | the plugin expects json - if this is not set then flickr returns jsonp |
46+
47+
### Example Configuration
48+
49+
This would retrieve all photos for a given user id.
50+
51+
```js
52+
module.exports = {
53+
plugins: [
54+
{
55+
resolve: "gatsby-source-flickr",
56+
options: {
57+
key: process.env.FLICKR_API_KEY,
58+
user_id: process.env.FLICKR_USER_ID
59+
}
60+
}
61+
]
62+
};
63+
```
64+
65+
## Querying Flickr Images
66+
67+
Once the plugin is configured, two new queries are available in GraphQL: `allFlickrPhoto` and `flickrPhoto`.
68+
69+
Here’s an example query to load 10 images:
70+
71+
```gql
72+
query PhotoQuery {
73+
allFlickrPhoto(limit: 10) {
74+
edges {
75+
node {
76+
id
77+
title
78+
description
79+
tags
80+
url_c
81+
width_c
82+
height_c
83+
}
84+
}
85+
}
86+
}
87+
```
88+
89+
## Limitations
90+
91+
The plugin does not handle the Flickr API pagination. It assumes that all the images required will be in the first page (and sets that first page to the maximum size).
92+
93+
The plugin was written to simply allow me to provide a source to my own flickr stream for my own site. It may or may not suit anyone else's needs :)

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// noop

package.json

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "gatsby-source-flickr",
3+
"description": "A Gatsby source plugin to load resources from the Flickr photo search API.",
4+
"author": "Chris Searle <[email protected]>",
5+
"repository": "https://github.com/chrissearle/gatsby-source-flickr.git",
6+
"keywords": [
7+
"gatsby",
8+
"gatsby-plugin",
9+
"flickr",
10+
"photos"
11+
],
12+
"license": "MIT",
13+
"scripts": {
14+
"build": "babel src --out-dir . --ignore __tests__",
15+
"prepublish": "yarn build",
16+
"format": "prettier --write \"src/**/*.js\""
17+
},
18+
"dependencies": {
19+
"@babel/polyfill": "^7.2.5",
20+
"node-fetch": "^2.3.0",
21+
"query-string": "^6.2.0"
22+
},
23+
"devDependencies": {
24+
"@babel/cli": "^7.2.3",
25+
"@babel/core": "^7.2.2",
26+
"@babel/preset-env": "^7.2.3",
27+
"cross-env": "^5.2.0",
28+
"prettier": "^1.15.2"
29+
},
30+
"version": "0.0.1"
31+
}

src/gatsby-node.js

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
require("@babel/polyfill");
2+
const fetch = require("node-fetch");
3+
const queryString = require("query-string");
4+
5+
exports.sourceNodes = async (
6+
{ boundActionCreators: { createNode }, createNodeId, createContentDigest },
7+
{ plugins, ...options }
8+
) => {
9+
const sizes = ["sq", "t", "s", "q", "m", "n", "z,", "c", "l", "z"];
10+
11+
// The flickr API has some issues when put into GraphQL - create a suitable version
12+
const fixPhoto = photo => {
13+
const fixed = photo;
14+
15+
// Don't name crash with node.id
16+
fixed.photo_id = fixed.id;
17+
delete fixed.id;
18+
19+
// Some fields can come down as either string or number. GraphQL doesn't like that. Force everything to number
20+
21+
sizes.forEach(suffix => {
22+
if (fixed.hasOwnProperty(`height_${suffix}`)) {
23+
fixed[`height_${suffix}`] = parseInt(fixed[`height_${suffix}`]);
24+
}
25+
if (fixed.hasOwnProperty(`width_${suffix}`)) {
26+
fixed[`width_${suffix}`] = parseInt(fixed[`width_${suffix}`]);
27+
}
28+
});
29+
30+
if (fixed.hasOwnProperty("accuracy")) {
31+
fixed.accuracy = parseInt(fixed.accuracy);
32+
}
33+
34+
// A missing latitude or longitude can come down as either 0 or "0" - force to string
35+
36+
if (fixed.hasOwnProperty("latitude")) {
37+
fixed.latitude = "" + fixed.latitude;
38+
}
39+
if (fixed.hasOwnProperty("longitude")) {
40+
fixed.longitude = "" + fixed.longitude;
41+
}
42+
43+
// These can come down as either string or number. Have only ever seen "0" and 0 here - and documentation is sparse - remove them
44+
45+
if (fixed.hasOwnProperty("datetakengranularity")) {
46+
delete fixed.datetakengranularity;
47+
}
48+
if (fixed.hasOwnProperty("datetakenunknown")) {
49+
delete fixed.datetakenunknown;
50+
}
51+
52+
// Convert Date versions of dateupload and lastupdate
53+
54+
if (fixed.hasOwnProperty("dateupload")) {
55+
fixed.dateupload_date = new Date(fixed.dateupload * 1000);
56+
}
57+
if (fixed.hasOwnProperty("lastupdate")) {
58+
fixed.lastupdate_date = new Date(fixed.lastupdate * 1000);
59+
}
60+
61+
// Simplify the structure of the description to just a string
62+
63+
if (fixed.hasOwnProperty("description")) {
64+
if (fixed.description.hasOwnProperty("_content")) {
65+
fixed.description = fixed.description._content;
66+
}
67+
}
68+
69+
return fixed;
70+
};
71+
72+
const url = `https://api.flickr.com/services/rest/?${queryString.stringify({
73+
method: "flickr.photos.search",
74+
extras:
75+
"description, license, date_upload, date_taken, owner_name, icon_server, original_format, last_update, geo, tags, machine_tags, o_dims, views, media, path_alias, url_sq, url_t, url_s, url_q, url_m, url_n, url_z, url_c, url_l, url_o",
76+
per_page: 500,
77+
format: "json",
78+
nojsoncallback: 1,
79+
...options
80+
})}`;
81+
82+
const response = await fetch(url);
83+
const data = await response.json();
84+
85+
data.photos.photo.forEach(raw => {
86+
const photo = fixPhoto(raw);
87+
88+
createNode({
89+
...photo,
90+
id: createNodeId(`flickr-photo-${photo.photo_id}`),
91+
parent: null,
92+
children: [],
93+
internal: {
94+
type: "FlickrPhoto",
95+
content: JSON.stringify(photo),
96+
contentDigest: createContentDigest(photo)
97+
}
98+
});
99+
});
100+
};

0 commit comments

Comments
 (0)