Ghost/core/server/utils/cached-image-size-from-url.js

50 lines
1.6 KiB
JavaScript
Raw Normal View History

var debug = require('ghost-ignition').debug('utils:image-size-cache'),
imageSize = require('./image-size'),
logging = require('../lib/common/logging'),
errors = require('../lib/common/errors'),
imageSizeCache = {};
✨ [FEATURE] AMP⚡ (#7229) closes #6588, #7095 * `ImageObject` with image dimensions (#7152, #7151, #7153) - Returns meta data as promise - returns a new Promise from meta data - uses `Promise.props()` to resolve `getClient()` and `getMetaData()` - Adds 'image-size' util The util returns an object like this ``` { height: 50, url: 'http://myblog.com/images/cat.jpg', width: 50 }; ``` if the dimensions can be fetched and rejects with error, if not. In case we get a locally stored image or a not complete url (like `//www.gravatar.com/andsoon`), we add the protocol to the incomplete one and use `urlFor()` to get the absolute URL. If the request fails or `image-size` is not able to read the file, we reject with error. - adds 'image-size' module to dependencies - adds `getImageSizeFromUrl` function that returns image dimensions - In preparation of AMP support and to improve our schema.org JSON-LD and structured data, I made the following changes: - Changes the following properties to be `Objects`, which have a `url` property by default and a `dimensions` property, if `width` and `height` are available: - `metaData.coverImage` - `metaData.authorImage` - `metaData.blog.logo` - Checks cache by calling `getCachedImageSizeFromUrl`. If image dimensions were fetched already, returns them from cache instead of fetching them again. - If we have image dimensions on hand, the output in our JSON-LD changes from normal urls to be full `ImageObjects`. Applies to all images and logos. - Special case for `publisher.logo` as it has size restrictions: if the image doesn't fulfil the restrictions (<=600 width and <=60 height), we simply output the url instead, so like before. - Adds new property for schema.org JSON-LD: `mainEntityOfPage` as an Object. - Adds additional Open Graph data (if we have the image size): `og:image:width` and `og:image:height` - Adds/updates tests * AMP router and controller (#7171, #7157) Implements AMP in `/apps/`: - renders `amp.hbs` if route is `/:slug/amp/` - updates `setResponseContext` to set context to `['amp', 'post']` for a amp post and `['amp', 'page']` for a page, but will not render amp template for a page - updates `context_spec` - registers 'amp' as new internal app - adds the `amp.hbs` template to `core/server/apps/amp` which will be the default template for AMP posts. - adds `isAmpURL` to `post-lookup` * 🎨 Use `context` in meta as array (#7205) Instead of reading the first value of the context array, we're checking if it includes certain context values. This is a preparation change for AMP, where the context will be delivered as `['amp', 'post']`. * ✨ AMP helpers (#7174, #7216, #7215, #7223) - Adds AMP helpers `{{amp_content}}`, `{{amp_component}}` and `{{amp_ghost_head}}` to support AMP: - `{{amp_content}}`: - Adds `Amperize` as dependency - AMP app uses new helper `{{amp_content}}` to render AMP HTML - `Amperize` transforms regular HTML into AMP HTML - Adds test for `{{amp_content}}` helper - Adds 'Sanitize-HTML` as dependendy - After the HTML get 'amperized' we still might have some HTML tags, which are prohibited in AMP HTML, so we use `sanitize-html` to remove those. With every update, `Amperize` gets and it is able to transform more HTML tags, they valid AMP HTML tags (e. g. `video` and `amp-video`) and will therefore not be removed. - `{{amp_ghost_head}}`: - registers `{{amp_ghost_head}}` helper, but uses `{{ghost_head}}` code - uses `{{amp_ghost_head}}` in `amp.hbs` instead of `{{ghost_head}}` - `{{ghost_head}}`: - Render `amphtml` link in metadata for post, which links to the amp post (`getAmpUrl`) - Updates all test in metadata to support `amp` context - Changes context conditionals to work with full array instead of first array value - Adds conditionals, so no additional javascript gets rendered in `{{ghost_head}}` - Removes trailing `/amp/` in URLs, so only `amphtml` link on regular post renders it - Adds a conditional, so no code injection will be included, for an `amp` context. - `{{amp_components}}`: - AMP app uses new helper `{{amp_components}}` to render necessary script tags for AMP extended components as `amp-iframe`, `amp-anime` and `amp-form` - Adds test for `{{amp_components}}`
2016-08-22 19:49:27 +03:00
/**
* Get cached image size from URL
* Always returns {object} imageSizeCache
* @param {string} url
* @returns {Promise<Object>} imageSizeCache
* @description Takes a url and returns image width and height from cache if available.
* If not in cache, `getImageSizeFromUrl` is called and returns the dimensions in a Promise.
*/
function getCachedImageSizeFromUrl(url) {
if (!url || url === undefined || url === null) {
return;
}
// image size is not in cache
if (!imageSizeCache[url]) {
return imageSize.getImageSizeFromUrl(url).then(function (res) {
✨ [FEATURE] AMP⚡ (#7229) closes #6588, #7095 * `ImageObject` with image dimensions (#7152, #7151, #7153) - Returns meta data as promise - returns a new Promise from meta data - uses `Promise.props()` to resolve `getClient()` and `getMetaData()` - Adds 'image-size' util The util returns an object like this ``` { height: 50, url: 'http://myblog.com/images/cat.jpg', width: 50 }; ``` if the dimensions can be fetched and rejects with error, if not. In case we get a locally stored image or a not complete url (like `//www.gravatar.com/andsoon`), we add the protocol to the incomplete one and use `urlFor()` to get the absolute URL. If the request fails or `image-size` is not able to read the file, we reject with error. - adds 'image-size' module to dependencies - adds `getImageSizeFromUrl` function that returns image dimensions - In preparation of AMP support and to improve our schema.org JSON-LD and structured data, I made the following changes: - Changes the following properties to be `Objects`, which have a `url` property by default and a `dimensions` property, if `width` and `height` are available: - `metaData.coverImage` - `metaData.authorImage` - `metaData.blog.logo` - Checks cache by calling `getCachedImageSizeFromUrl`. If image dimensions were fetched already, returns them from cache instead of fetching them again. - If we have image dimensions on hand, the output in our JSON-LD changes from normal urls to be full `ImageObjects`. Applies to all images and logos. - Special case for `publisher.logo` as it has size restrictions: if the image doesn't fulfil the restrictions (<=600 width and <=60 height), we simply output the url instead, so like before. - Adds new property for schema.org JSON-LD: `mainEntityOfPage` as an Object. - Adds additional Open Graph data (if we have the image size): `og:image:width` and `og:image:height` - Adds/updates tests * AMP router and controller (#7171, #7157) Implements AMP in `/apps/`: - renders `amp.hbs` if route is `/:slug/amp/` - updates `setResponseContext` to set context to `['amp', 'post']` for a amp post and `['amp', 'page']` for a page, but will not render amp template for a page - updates `context_spec` - registers 'amp' as new internal app - adds the `amp.hbs` template to `core/server/apps/amp` which will be the default template for AMP posts. - adds `isAmpURL` to `post-lookup` * 🎨 Use `context` in meta as array (#7205) Instead of reading the first value of the context array, we're checking if it includes certain context values. This is a preparation change for AMP, where the context will be delivered as `['amp', 'post']`. * ✨ AMP helpers (#7174, #7216, #7215, #7223) - Adds AMP helpers `{{amp_content}}`, `{{amp_component}}` and `{{amp_ghost_head}}` to support AMP: - `{{amp_content}}`: - Adds `Amperize` as dependency - AMP app uses new helper `{{amp_content}}` to render AMP HTML - `Amperize` transforms regular HTML into AMP HTML - Adds test for `{{amp_content}}` helper - Adds 'Sanitize-HTML` as dependendy - After the HTML get 'amperized' we still might have some HTML tags, which are prohibited in AMP HTML, so we use `sanitize-html` to remove those. With every update, `Amperize` gets and it is able to transform more HTML tags, they valid AMP HTML tags (e. g. `video` and `amp-video`) and will therefore not be removed. - `{{amp_ghost_head}}`: - registers `{{amp_ghost_head}}` helper, but uses `{{ghost_head}}` code - uses `{{amp_ghost_head}}` in `amp.hbs` instead of `{{ghost_head}}` - `{{ghost_head}}`: - Render `amphtml` link in metadata for post, which links to the amp post (`getAmpUrl`) - Updates all test in metadata to support `amp` context - Changes context conditionals to work with full array instead of first array value - Adds conditionals, so no additional javascript gets rendered in `{{ghost_head}}` - Removes trailing `/amp/` in URLs, so only `amphtml` link on regular post renders it - Adds a conditional, so no code injection will be included, for an `amp` context. - `{{amp_components}}`: - AMP app uses new helper `{{amp_components}}` to render necessary script tags for AMP extended components as `amp-iframe`, `amp-anime` and `amp-form` - Adds test for `{{amp_components}}`
2016-08-22 19:49:27 +03:00
imageSizeCache[url] = res;
debug('Cached image:', url);
🐛 Fix invalid image URLs not being cached and causing timeouts (#8986) refs #8868 * 📐 Use request util in image-size - swapped the usage of `got` for requests with the request util * 💄 Use catch predicates - Uses catch predicates instead of conditionals in `getImageSizeFromUrl` - Return `NotFoundError` if applicable in `getImageSizeFromFilePath` as the caller function `cachedImageSizeFromUrl` is differentiating those between this error and others. * 🐛 Fixed ImageObject URL & simplify no protocol URL logic - Using `ImageObject` as a global var resulted in having the `url` property being the same for all requests coming in. - The logic that checked for an existing protocol (e. g. gravatar URLs) was overly complicated. Refactored it to be more simple. - Passing the correct value to `fetchDimensionsFromBuffer` as the population of `imageObject.url` happens there. These are used in our structured data and need to be full URLs (in case of locally stored files) or the original URL (in case of URLs missing the protocol) - Added two more debug logs in `getCachedImageSizeFromUrl` so it's logged when an image is added to the cache even tho it was returned as error. * 👀 Differentiate error codes between request and storage * 🔥 Remove not needed `Promise.resolve()` We're always resolving the result in `getCachedImageSizeFromUrl`, so there's no need to return the values with a `Promise.resolve()`. The caller fn uses waits for the Promises to be fulfilled. * ☂️ Wrap already rejected predicate errors in catch all * Use errorDetails instead of context * ☂️ Support /assets/ image paths - adds a guard that checks the image URL for `/assets/` in the beginning and passes a completed URL to the request util to try and fetch the image size - adds tests
2017-09-12 14:53:18 +03:00
return imageSizeCache[url];
}).catch(errors.NotFoundError, function () {
🐛 Fix invalid image URLs not being cached and causing timeouts (#8986) refs #8868 * 📐 Use request util in image-size - swapped the usage of `got` for requests with the request util * 💄 Use catch predicates - Uses catch predicates instead of conditionals in `getImageSizeFromUrl` - Return `NotFoundError` if applicable in `getImageSizeFromFilePath` as the caller function `cachedImageSizeFromUrl` is differentiating those between this error and others. * 🐛 Fixed ImageObject URL & simplify no protocol URL logic - Using `ImageObject` as a global var resulted in having the `url` property being the same for all requests coming in. - The logic that checked for an existing protocol (e. g. gravatar URLs) was overly complicated. Refactored it to be more simple. - Passing the correct value to `fetchDimensionsFromBuffer` as the population of `imageObject.url` happens there. These are used in our structured data and need to be full URLs (in case of locally stored files) or the original URL (in case of URLs missing the protocol) - Added two more debug logs in `getCachedImageSizeFromUrl` so it's logged when an image is added to the cache even tho it was returned as error. * 👀 Differentiate error codes between request and storage * 🔥 Remove not needed `Promise.resolve()` We're always resolving the result in `getCachedImageSizeFromUrl`, so there's no need to return the values with a `Promise.resolve()`. The caller fn uses waits for the Promises to be fulfilled. * ☂️ Wrap already rejected predicate errors in catch all * Use errorDetails instead of context * ☂️ Support /assets/ image paths - adds a guard that checks the image URL for `/assets/` in the beginning and passes a completed URL to the request util to try and fetch the image size - adds tests
2017-09-12 14:53:18 +03:00
debug('Cached image (not found):', url);
// in case of error we just attach the url
🐛 Fix invalid image URLs not being cached and causing timeouts (#8986) refs #8868 * 📐 Use request util in image-size - swapped the usage of `got` for requests with the request util * 💄 Use catch predicates - Uses catch predicates instead of conditionals in `getImageSizeFromUrl` - Return `NotFoundError` if applicable in `getImageSizeFromFilePath` as the caller function `cachedImageSizeFromUrl` is differentiating those between this error and others. * 🐛 Fixed ImageObject URL & simplify no protocol URL logic - Using `ImageObject` as a global var resulted in having the `url` property being the same for all requests coming in. - The logic that checked for an existing protocol (e. g. gravatar URLs) was overly complicated. Refactored it to be more simple. - Passing the correct value to `fetchDimensionsFromBuffer` as the population of `imageObject.url` happens there. These are used in our structured data and need to be full URLs (in case of locally stored files) or the original URL (in case of URLs missing the protocol) - Added two more debug logs in `getCachedImageSizeFromUrl` so it's logged when an image is added to the cache even tho it was returned as error. * 👀 Differentiate error codes between request and storage * 🔥 Remove not needed `Promise.resolve()` We're always resolving the result in `getCachedImageSizeFromUrl`, so there's no need to return the values with a `Promise.resolve()`. The caller fn uses waits for the Promises to be fulfilled. * ☂️ Wrap already rejected predicate errors in catch all * Use errorDetails instead of context * ☂️ Support /assets/ image paths - adds a guard that checks the image URL for `/assets/` in the beginning and passes a completed URL to the request util to try and fetch the image size - adds tests
2017-09-12 14:53:18 +03:00
imageSizeCache[url] = url;
return imageSizeCache[url];
}).catch(function (err) {
🐛 Fix invalid image URLs not being cached and causing timeouts (#8986) refs #8868 * 📐 Use request util in image-size - swapped the usage of `got` for requests with the request util * 💄 Use catch predicates - Uses catch predicates instead of conditionals in `getImageSizeFromUrl` - Return `NotFoundError` if applicable in `getImageSizeFromFilePath` as the caller function `cachedImageSizeFromUrl` is differentiating those between this error and others. * 🐛 Fixed ImageObject URL & simplify no protocol URL logic - Using `ImageObject` as a global var resulted in having the `url` property being the same for all requests coming in. - The logic that checked for an existing protocol (e. g. gravatar URLs) was overly complicated. Refactored it to be more simple. - Passing the correct value to `fetchDimensionsFromBuffer` as the population of `imageObject.url` happens there. These are used in our structured data and need to be full URLs (in case of locally stored files) or the original URL (in case of URLs missing the protocol) - Added two more debug logs in `getCachedImageSizeFromUrl` so it's logged when an image is added to the cache even tho it was returned as error. * 👀 Differentiate error codes between request and storage * 🔥 Remove not needed `Promise.resolve()` We're always resolving the result in `getCachedImageSizeFromUrl`, so there's no need to return the values with a `Promise.resolve()`. The caller fn uses waits for the Promises to be fulfilled. * ☂️ Wrap already rejected predicate errors in catch all * Use errorDetails instead of context * ☂️ Support /assets/ image paths - adds a guard that checks the image URL for `/assets/` in the beginning and passes a completed URL to the request util to try and fetch the image size - adds tests
2017-09-12 14:53:18 +03:00
debug('Cached image (error):', url);
logging.error(err);
✨ [FEATURE] AMP⚡ (#7229) closes #6588, #7095 * `ImageObject` with image dimensions (#7152, #7151, #7153) - Returns meta data as promise - returns a new Promise from meta data - uses `Promise.props()` to resolve `getClient()` and `getMetaData()` - Adds 'image-size' util The util returns an object like this ``` { height: 50, url: 'http://myblog.com/images/cat.jpg', width: 50 }; ``` if the dimensions can be fetched and rejects with error, if not. In case we get a locally stored image or a not complete url (like `//www.gravatar.com/andsoon`), we add the protocol to the incomplete one and use `urlFor()` to get the absolute URL. If the request fails or `image-size` is not able to read the file, we reject with error. - adds 'image-size' module to dependencies - adds `getImageSizeFromUrl` function that returns image dimensions - In preparation of AMP support and to improve our schema.org JSON-LD and structured data, I made the following changes: - Changes the following properties to be `Objects`, which have a `url` property by default and a `dimensions` property, if `width` and `height` are available: - `metaData.coverImage` - `metaData.authorImage` - `metaData.blog.logo` - Checks cache by calling `getCachedImageSizeFromUrl`. If image dimensions were fetched already, returns them from cache instead of fetching them again. - If we have image dimensions on hand, the output in our JSON-LD changes from normal urls to be full `ImageObjects`. Applies to all images and logos. - Special case for `publisher.logo` as it has size restrictions: if the image doesn't fulfil the restrictions (<=600 width and <=60 height), we simply output the url instead, so like before. - Adds new property for schema.org JSON-LD: `mainEntityOfPage` as an Object. - Adds additional Open Graph data (if we have the image size): `og:image:width` and `og:image:height` - Adds/updates tests * AMP router and controller (#7171, #7157) Implements AMP in `/apps/`: - renders `amp.hbs` if route is `/:slug/amp/` - updates `setResponseContext` to set context to `['amp', 'post']` for a amp post and `['amp', 'page']` for a page, but will not render amp template for a page - updates `context_spec` - registers 'amp' as new internal app - adds the `amp.hbs` template to `core/server/apps/amp` which will be the default template for AMP posts. - adds `isAmpURL` to `post-lookup` * 🎨 Use `context` in meta as array (#7205) Instead of reading the first value of the context array, we're checking if it includes certain context values. This is a preparation change for AMP, where the context will be delivered as `['amp', 'post']`. * ✨ AMP helpers (#7174, #7216, #7215, #7223) - Adds AMP helpers `{{amp_content}}`, `{{amp_component}}` and `{{amp_ghost_head}}` to support AMP: - `{{amp_content}}`: - Adds `Amperize` as dependency - AMP app uses new helper `{{amp_content}}` to render AMP HTML - `Amperize` transforms regular HTML into AMP HTML - Adds test for `{{amp_content}}` helper - Adds 'Sanitize-HTML` as dependendy - After the HTML get 'amperized' we still might have some HTML tags, which are prohibited in AMP HTML, so we use `sanitize-html` to remove those. With every update, `Amperize` gets and it is able to transform more HTML tags, they valid AMP HTML tags (e. g. `video` and `amp-video`) and will therefore not be removed. - `{{amp_ghost_head}}`: - registers `{{amp_ghost_head}}` helper, but uses `{{ghost_head}}` code - uses `{{amp_ghost_head}}` in `amp.hbs` instead of `{{ghost_head}}` - `{{ghost_head}}`: - Render `amphtml` link in metadata for post, which links to the amp post (`getAmpUrl`) - Updates all test in metadata to support `amp` context - Changes context conditionals to work with full array instead of first array value - Adds conditionals, so no additional javascript gets rendered in `{{ghost_head}}` - Removes trailing `/amp/` in URLs, so only `amphtml` link on regular post renders it - Adds a conditional, so no code injection will be included, for an `amp` context. - `{{amp_components}}`: - AMP app uses new helper `{{amp_components}}` to render necessary script tags for AMP extended components as `amp-iframe`, `amp-anime` and `amp-form` - Adds test for `{{amp_components}}`
2016-08-22 19:49:27 +03:00
// in case of error we just attach the url
🐛 Fix invalid image URLs not being cached and causing timeouts (#8986) refs #8868 * 📐 Use request util in image-size - swapped the usage of `got` for requests with the request util * 💄 Use catch predicates - Uses catch predicates instead of conditionals in `getImageSizeFromUrl` - Return `NotFoundError` if applicable in `getImageSizeFromFilePath` as the caller function `cachedImageSizeFromUrl` is differentiating those between this error and others. * 🐛 Fixed ImageObject URL & simplify no protocol URL logic - Using `ImageObject` as a global var resulted in having the `url` property being the same for all requests coming in. - The logic that checked for an existing protocol (e. g. gravatar URLs) was overly complicated. Refactored it to be more simple. - Passing the correct value to `fetchDimensionsFromBuffer` as the population of `imageObject.url` happens there. These are used in our structured data and need to be full URLs (in case of locally stored files) or the original URL (in case of URLs missing the protocol) - Added two more debug logs in `getCachedImageSizeFromUrl` so it's logged when an image is added to the cache even tho it was returned as error. * 👀 Differentiate error codes between request and storage * 🔥 Remove not needed `Promise.resolve()` We're always resolving the result in `getCachedImageSizeFromUrl`, so there's no need to return the values with a `Promise.resolve()`. The caller fn uses waits for the Promises to be fulfilled. * ☂️ Wrap already rejected predicate errors in catch all * Use errorDetails instead of context * ☂️ Support /assets/ image paths - adds a guard that checks the image URL for `/assets/` in the beginning and passes a completed URL to the request util to try and fetch the image size - adds tests
2017-09-12 14:53:18 +03:00
imageSizeCache[url] = url;
return imageSizeCache[url];
✨ [FEATURE] AMP⚡ (#7229) closes #6588, #7095 * `ImageObject` with image dimensions (#7152, #7151, #7153) - Returns meta data as promise - returns a new Promise from meta data - uses `Promise.props()` to resolve `getClient()` and `getMetaData()` - Adds 'image-size' util The util returns an object like this ``` { height: 50, url: 'http://myblog.com/images/cat.jpg', width: 50 }; ``` if the dimensions can be fetched and rejects with error, if not. In case we get a locally stored image or a not complete url (like `//www.gravatar.com/andsoon`), we add the protocol to the incomplete one and use `urlFor()` to get the absolute URL. If the request fails or `image-size` is not able to read the file, we reject with error. - adds 'image-size' module to dependencies - adds `getImageSizeFromUrl` function that returns image dimensions - In preparation of AMP support and to improve our schema.org JSON-LD and structured data, I made the following changes: - Changes the following properties to be `Objects`, which have a `url` property by default and a `dimensions` property, if `width` and `height` are available: - `metaData.coverImage` - `metaData.authorImage` - `metaData.blog.logo` - Checks cache by calling `getCachedImageSizeFromUrl`. If image dimensions were fetched already, returns them from cache instead of fetching them again. - If we have image dimensions on hand, the output in our JSON-LD changes from normal urls to be full `ImageObjects`. Applies to all images and logos. - Special case for `publisher.logo` as it has size restrictions: if the image doesn't fulfil the restrictions (<=600 width and <=60 height), we simply output the url instead, so like before. - Adds new property for schema.org JSON-LD: `mainEntityOfPage` as an Object. - Adds additional Open Graph data (if we have the image size): `og:image:width` and `og:image:height` - Adds/updates tests * AMP router and controller (#7171, #7157) Implements AMP in `/apps/`: - renders `amp.hbs` if route is `/:slug/amp/` - updates `setResponseContext` to set context to `['amp', 'post']` for a amp post and `['amp', 'page']` for a page, but will not render amp template for a page - updates `context_spec` - registers 'amp' as new internal app - adds the `amp.hbs` template to `core/server/apps/amp` which will be the default template for AMP posts. - adds `isAmpURL` to `post-lookup` * 🎨 Use `context` in meta as array (#7205) Instead of reading the first value of the context array, we're checking if it includes certain context values. This is a preparation change for AMP, where the context will be delivered as `['amp', 'post']`. * ✨ AMP helpers (#7174, #7216, #7215, #7223) - Adds AMP helpers `{{amp_content}}`, `{{amp_component}}` and `{{amp_ghost_head}}` to support AMP: - `{{amp_content}}`: - Adds `Amperize` as dependency - AMP app uses new helper `{{amp_content}}` to render AMP HTML - `Amperize` transforms regular HTML into AMP HTML - Adds test for `{{amp_content}}` helper - Adds 'Sanitize-HTML` as dependendy - After the HTML get 'amperized' we still might have some HTML tags, which are prohibited in AMP HTML, so we use `sanitize-html` to remove those. With every update, `Amperize` gets and it is able to transform more HTML tags, they valid AMP HTML tags (e. g. `video` and `amp-video`) and will therefore not be removed. - `{{amp_ghost_head}}`: - registers `{{amp_ghost_head}}` helper, but uses `{{ghost_head}}` code - uses `{{amp_ghost_head}}` in `amp.hbs` instead of `{{ghost_head}}` - `{{ghost_head}}`: - Render `amphtml` link in metadata for post, which links to the amp post (`getAmpUrl`) - Updates all test in metadata to support `amp` context - Changes context conditionals to work with full array instead of first array value - Adds conditionals, so no additional javascript gets rendered in `{{ghost_head}}` - Removes trailing `/amp/` in URLs, so only `amphtml` link on regular post renders it - Adds a conditional, so no code injection will be included, for an `amp` context. - `{{amp_components}}`: - AMP app uses new helper `{{amp_components}}` to render necessary script tags for AMP extended components as `amp-iframe`, `amp-anime` and `amp-form` - Adds test for `{{amp_components}}`
2016-08-22 19:49:27 +03:00
});
}
debug('Read image from cache:', url);
✨ [FEATURE] AMP⚡ (#7229) closes #6588, #7095 * `ImageObject` with image dimensions (#7152, #7151, #7153) - Returns meta data as promise - returns a new Promise from meta data - uses `Promise.props()` to resolve `getClient()` and `getMetaData()` - Adds 'image-size' util The util returns an object like this ``` { height: 50, url: 'http://myblog.com/images/cat.jpg', width: 50 }; ``` if the dimensions can be fetched and rejects with error, if not. In case we get a locally stored image or a not complete url (like `//www.gravatar.com/andsoon`), we add the protocol to the incomplete one and use `urlFor()` to get the absolute URL. If the request fails or `image-size` is not able to read the file, we reject with error. - adds 'image-size' module to dependencies - adds `getImageSizeFromUrl` function that returns image dimensions - In preparation of AMP support and to improve our schema.org JSON-LD and structured data, I made the following changes: - Changes the following properties to be `Objects`, which have a `url` property by default and a `dimensions` property, if `width` and `height` are available: - `metaData.coverImage` - `metaData.authorImage` - `metaData.blog.logo` - Checks cache by calling `getCachedImageSizeFromUrl`. If image dimensions were fetched already, returns them from cache instead of fetching them again. - If we have image dimensions on hand, the output in our JSON-LD changes from normal urls to be full `ImageObjects`. Applies to all images and logos. - Special case for `publisher.logo` as it has size restrictions: if the image doesn't fulfil the restrictions (<=600 width and <=60 height), we simply output the url instead, so like before. - Adds new property for schema.org JSON-LD: `mainEntityOfPage` as an Object. - Adds additional Open Graph data (if we have the image size): `og:image:width` and `og:image:height` - Adds/updates tests * AMP router and controller (#7171, #7157) Implements AMP in `/apps/`: - renders `amp.hbs` if route is `/:slug/amp/` - updates `setResponseContext` to set context to `['amp', 'post']` for a amp post and `['amp', 'page']` for a page, but will not render amp template for a page - updates `context_spec` - registers 'amp' as new internal app - adds the `amp.hbs` template to `core/server/apps/amp` which will be the default template for AMP posts. - adds `isAmpURL` to `post-lookup` * 🎨 Use `context` in meta as array (#7205) Instead of reading the first value of the context array, we're checking if it includes certain context values. This is a preparation change for AMP, where the context will be delivered as `['amp', 'post']`. * ✨ AMP helpers (#7174, #7216, #7215, #7223) - Adds AMP helpers `{{amp_content}}`, `{{amp_component}}` and `{{amp_ghost_head}}` to support AMP: - `{{amp_content}}`: - Adds `Amperize` as dependency - AMP app uses new helper `{{amp_content}}` to render AMP HTML - `Amperize` transforms regular HTML into AMP HTML - Adds test for `{{amp_content}}` helper - Adds 'Sanitize-HTML` as dependendy - After the HTML get 'amperized' we still might have some HTML tags, which are prohibited in AMP HTML, so we use `sanitize-html` to remove those. With every update, `Amperize` gets and it is able to transform more HTML tags, they valid AMP HTML tags (e. g. `video` and `amp-video`) and will therefore not be removed. - `{{amp_ghost_head}}`: - registers `{{amp_ghost_head}}` helper, but uses `{{ghost_head}}` code - uses `{{amp_ghost_head}}` in `amp.hbs` instead of `{{ghost_head}}` - `{{ghost_head}}`: - Render `amphtml` link in metadata for post, which links to the amp post (`getAmpUrl`) - Updates all test in metadata to support `amp` context - Changes context conditionals to work with full array instead of first array value - Adds conditionals, so no additional javascript gets rendered in `{{ghost_head}}` - Removes trailing `/amp/` in URLs, so only `amphtml` link on regular post renders it - Adds a conditional, so no code injection will be included, for an `amp` context. - `{{amp_components}}`: - AMP app uses new helper `{{amp_components}}` to render necessary script tags for AMP extended components as `amp-iframe`, `amp-anime` and `amp-form` - Adds test for `{{amp_components}}`
2016-08-22 19:49:27 +03:00
// returns image size from cache
🐛 Fix invalid image URLs not being cached and causing timeouts (#8986) refs #8868 * 📐 Use request util in image-size - swapped the usage of `got` for requests with the request util * 💄 Use catch predicates - Uses catch predicates instead of conditionals in `getImageSizeFromUrl` - Return `NotFoundError` if applicable in `getImageSizeFromFilePath` as the caller function `cachedImageSizeFromUrl` is differentiating those between this error and others. * 🐛 Fixed ImageObject URL & simplify no protocol URL logic - Using `ImageObject` as a global var resulted in having the `url` property being the same for all requests coming in. - The logic that checked for an existing protocol (e. g. gravatar URLs) was overly complicated. Refactored it to be more simple. - Passing the correct value to `fetchDimensionsFromBuffer` as the population of `imageObject.url` happens there. These are used in our structured data and need to be full URLs (in case of locally stored files) or the original URL (in case of URLs missing the protocol) - Added two more debug logs in `getCachedImageSizeFromUrl` so it's logged when an image is added to the cache even tho it was returned as error. * 👀 Differentiate error codes between request and storage * 🔥 Remove not needed `Promise.resolve()` We're always resolving the result in `getCachedImageSizeFromUrl`, so there's no need to return the values with a `Promise.resolve()`. The caller fn uses waits for the Promises to be fulfilled. * ☂️ Wrap already rejected predicate errors in catch all * Use errorDetails instead of context * ☂️ Support /assets/ image paths - adds a guard that checks the image URL for `/assets/` in the beginning and passes a completed URL to the request util to try and fetch the image size - adds tests
2017-09-12 14:53:18 +03:00
return imageSizeCache[url];
✨ [FEATURE] AMP⚡ (#7229) closes #6588, #7095 * `ImageObject` with image dimensions (#7152, #7151, #7153) - Returns meta data as promise - returns a new Promise from meta data - uses `Promise.props()` to resolve `getClient()` and `getMetaData()` - Adds 'image-size' util The util returns an object like this ``` { height: 50, url: 'http://myblog.com/images/cat.jpg', width: 50 }; ``` if the dimensions can be fetched and rejects with error, if not. In case we get a locally stored image or a not complete url (like `//www.gravatar.com/andsoon`), we add the protocol to the incomplete one and use `urlFor()` to get the absolute URL. If the request fails or `image-size` is not able to read the file, we reject with error. - adds 'image-size' module to dependencies - adds `getImageSizeFromUrl` function that returns image dimensions - In preparation of AMP support and to improve our schema.org JSON-LD and structured data, I made the following changes: - Changes the following properties to be `Objects`, which have a `url` property by default and a `dimensions` property, if `width` and `height` are available: - `metaData.coverImage` - `metaData.authorImage` - `metaData.blog.logo` - Checks cache by calling `getCachedImageSizeFromUrl`. If image dimensions were fetched already, returns them from cache instead of fetching them again. - If we have image dimensions on hand, the output in our JSON-LD changes from normal urls to be full `ImageObjects`. Applies to all images and logos. - Special case for `publisher.logo` as it has size restrictions: if the image doesn't fulfil the restrictions (<=600 width and <=60 height), we simply output the url instead, so like before. - Adds new property for schema.org JSON-LD: `mainEntityOfPage` as an Object. - Adds additional Open Graph data (if we have the image size): `og:image:width` and `og:image:height` - Adds/updates tests * AMP router and controller (#7171, #7157) Implements AMP in `/apps/`: - renders `amp.hbs` if route is `/:slug/amp/` - updates `setResponseContext` to set context to `['amp', 'post']` for a amp post and `['amp', 'page']` for a page, but will not render amp template for a page - updates `context_spec` - registers 'amp' as new internal app - adds the `amp.hbs` template to `core/server/apps/amp` which will be the default template for AMP posts. - adds `isAmpURL` to `post-lookup` * 🎨 Use `context` in meta as array (#7205) Instead of reading the first value of the context array, we're checking if it includes certain context values. This is a preparation change for AMP, where the context will be delivered as `['amp', 'post']`. * ✨ AMP helpers (#7174, #7216, #7215, #7223) - Adds AMP helpers `{{amp_content}}`, `{{amp_component}}` and `{{amp_ghost_head}}` to support AMP: - `{{amp_content}}`: - Adds `Amperize` as dependency - AMP app uses new helper `{{amp_content}}` to render AMP HTML - `Amperize` transforms regular HTML into AMP HTML - Adds test for `{{amp_content}}` helper - Adds 'Sanitize-HTML` as dependendy - After the HTML get 'amperized' we still might have some HTML tags, which are prohibited in AMP HTML, so we use `sanitize-html` to remove those. With every update, `Amperize` gets and it is able to transform more HTML tags, they valid AMP HTML tags (e. g. `video` and `amp-video`) and will therefore not be removed. - `{{amp_ghost_head}}`: - registers `{{amp_ghost_head}}` helper, but uses `{{ghost_head}}` code - uses `{{amp_ghost_head}}` in `amp.hbs` instead of `{{ghost_head}}` - `{{ghost_head}}`: - Render `amphtml` link in metadata for post, which links to the amp post (`getAmpUrl`) - Updates all test in metadata to support `amp` context - Changes context conditionals to work with full array instead of first array value - Adds conditionals, so no additional javascript gets rendered in `{{ghost_head}}` - Removes trailing `/amp/` in URLs, so only `amphtml` link on regular post renders it - Adds a conditional, so no code injection will be included, for an `amp` context. - `{{amp_components}}`: - AMP app uses new helper `{{amp_components}}` to render necessary script tags for AMP extended components as `amp-iframe`, `amp-anime` and `amp-form` - Adds test for `{{amp_components}}`
2016-08-22 19:49:27 +03:00
}
module.exports = getCachedImageSizeFromUrl;