! Обращение ко всем, кто умеет делать сетки!

Мы полностью проверили наш набор правил на ошибки/проблемы и… к сожалению, у нас довольно длинный список:

НЕПРАВЛЬНЫЕ СЕТКИ

НУЖДЕ ИХ УЛУЧШИТЬ

Для нас невозможно исправить такое количество сеток. Если кто-то из вас готов помочь с исправлением, мы (и сообщество в целом) будем очень благодарны. Добровольцы, понимающие regexp и js, очень приветствуются.

PS

Хотя этот список был тщательно проверен, гарантий, что все в нем правильно, нет. Если у вас есть уточнения, например, одна из сеток работает у вас, пожалуйста, оставьте комментарий в этой теме.

PPS

Учтите, что список постоянно меняется - исправленные правила удаляются, иногда что-то добавляется.

Shutterstock:

{"O_Shutterstock":{"link":"shutterstock.com/.*","res":":\nfunction a(a){const b=new XMLHttpRequest;return b.open(\"GET\",a,!1),b.timeout=3e3,b.send(),4==b.readyState?200==b.status?JSON.parse(b.responseText):void 0:void 0}function b(a){if(!a)return;let b={width:0};for(const c of Object.values(a))c.width>b.width&&(b=c);return b.src}function c(a){if(!a)return a;const b=a.indexOf(\"?\");return 0>b?a:a.substring(0,b)}function d(a){const b=a.split(\"-\");return 0===b.length?void 0:c(b[b.length-1])}const e=$[0];if(match=e.match(/shutterstock\\.com\\/(.*\\/)*g\\/(.*)/),match&&2<=match.length){console.log(match[match.length-1]);const d=c(match[match.length-1]);if(!d)return;console.log(d);const e=a(`https://www.shutterstock.com/_next/data/123/en/_shutterstock/g/${d}.json`),f=e.pageProps.assets;return f.map(a=>{const c=b(a.displays),d=a.title;return[c,d]})}if(match=e.match(/shutterstock\\.com\\/(.*\\/)*editorial\\/image-editorial\\/(.*)/),match&&2<=match.length){const c=match[match.length-1],e=d(c);if(!e)return;const f=a(`https://www.shutterstock.com/_next/data/123/en/_shutterstock/editorial/image-editorial/${e}.json`),g=b(f.pageProps.asset.displays),h=f.pageProps.asset.title;return[g,h]}if(match=e.match(/shutterstock\\.com\\/(.*\\/)*image-photo\\/(.*)/),match&&2<=match.length){const c=match[match.length-1],e=d(c);if(!e)return;const f=a(`https://www.shutterstock.com/studioapi/images/${e}`),g=b(f.data.attributes.displays),h=f.data.attributes.title;return[g,h]}if(match=e.match(/shutterstock\\.com\\/(.*\\/)*video\\/search\\/(.*)\\/*/),match&&2<=match.length){const b=c(match[match.length-1]),d=a(`https://www.shutterstock.com/_next/data/123/en/_shutterstock/video/search/${b}.json`);if(!d||!d.pageProps||!d.pageProps.videos)return;const e=d.pageProps.videos,f=d.pageProps.query&&d.pageProps.query.term||b;return e.map(a=>[a.previewVideoUrls.mp4,f])}if(match=e.match(/shutterstock\\.com\\/(.*\\/)*search\\/(.*)\\/*/),match&&2<=match.length){const d=c(match[match.length-1]),e=a(`https://www.shutterstock.com/_next/data/123/en/_shutterstock/search/${d}.json`);if(!e||!e.pageProps||!e.pageProps.assets)return;const f=e.pageProps.assets,g=e.pageProps.query&&e.pageProps.query.term||d;return f.map(a=>[b(a.displays),g])}","img":"shutterstock.com/.*"}}

Там много вариаций url для shutterstock. Я пытался покрыть все упомянутые на странице и немного больше.

Джаваскрипт сжат в сетке, вот его распакованная версия:

:
const url = $[0];

function syncFetch(u) {
  const x = new XMLHttpRequest();
  x.open('GET', u, false);
  x.timeout = 3000;
  x.send();
  if (x.readyState != 4) return;
  if (x.status != 200) return;
  return JSON.parse(x.responseText);
}

function findLargestImage(displays) {
  if (!displays) {
    return;
  }
  let largest = {
    width: 0,
  };
  for (const val of Object.values(displays)) {
    if (val.width > largest.width) {
      largest = val;
    }
  }
  // console.log(largest);
  return largest.src;
}

function removeQueryParams(string) {
  if (!string) {
    return string;
  }
  const index = string.indexOf('?');
  if (index < 0) {
    return string;
  }
  return string.substring(0, index);
}

function getIdFromSlug(slug) {
  const splits = slug.split('-');
  if (splits.length === 0) {
    return;
  }
  return removeQueryParams(splits[splits.length - 1]);
}

const profileGalleryRegex = /shutterstock\.com\/(.*\/)*g\/(.*)/;
match = url.match(profileGalleryRegex);
if (match && match.length >= 2) {
  console.log(match[match.length - 1]);
  const profile = removeQueryParams(match[match.length - 1]);
  if (!profile) {
    return;
  }
  console.log(profile);
  const json = syncFetch(`https://www.shutterstock.com/_next/data/123/en/_shutterstock/g/${profile}.json`);
  const assets = json.pageProps.assets;
  return assets.map(asset => {
    const imageUrl = findLargestImage(asset.displays);
    const caption = asset.title;
    return [imageUrl, caption];
  });
}
const imageEditorialRegex = /shutterstock\.com\/(.*\/)*editorial\/image-editorial\/(.*)/;
match = url.match(imageEditorialRegex);
if (match && match.length >= 2) {
  const slug = match[match.length - 1];
  const id = getIdFromSlug(slug);
  if (!id) {
    return;
  }
  // console.log(id);
  const json = syncFetch(`https://www.shutterstock.com/_next/data/123/en/_shutterstock/editorial/image-editorial/${id}.json`);
  const imageUrl = findLargestImage(json.pageProps.asset.displays);
  const caption = json.pageProps.asset.title;
  return [imageUrl, caption];
}
const imagePhotoRegex = /shutterstock\.com\/(.*\/)*image-photo\/(.*)/;
match = url.match(imagePhotoRegex);
if (match && match.length >= 2) {
  const slug = match[match.length - 1];
  const id = getIdFromSlug(slug);
  if (!id) {
    return;
  }
  // console.log(id);
  const json = syncFetch(`https://www.shutterstock.com/studioapi/images/${id}`);
  const imageUrl = findLargestImage(json.data.attributes.displays);
  const caption = json.data.attributes.title;
  return [imageUrl, caption];
}
const videoSearchRegex = /shutterstock\.com\/(.*\/)*video\/search\/(.*)\/*/;
match = url.match(videoSearchRegex);
if (match && match.length >= 2) {
  const term = removeQueryParams(match[match.length - 1]);
  const json = syncFetch(`https://www.shutterstock.com/_next/data/123/en/_shutterstock/video/search/${term}.json`)
  // console.log(json);
  if (!json || !json.pageProps || !json.pageProps.videos) {
    return;
  }
  const e=json.pageProps.videos,f=json.pageProps.query&&json.pageProps.query.term||b;return e.map(a=>[a.previewVideoUrls.mp4,f])}]}