From 346077171db5a7f0a2cb7501aac152585644c07a Mon Sep 17 00:00:00 2001 From: Tasso Evangelista Date: Thu, 10 Dec 2020 16:17:34 -0300 Subject: [PATCH] [FIX] Spotify oEmbed (#19825) --- app/oembed/client/baseWidget.js | 18 ++---- app/oembed/server/providers.js | 5 ++ app/spotify/client/index.js | 4 -- app/spotify/client/oembedSpotifyWidget.html | 16 ----- app/spotify/client/oembedSpotifyWidget.js | 16 ----- app/spotify/lib/spotify.js | 69 +++++---------------- app/spotify/server/index.js | 4 +- client/importPackages.js | 1 - client/startup/beforeSaveMessage/index.js | 1 - client/startup/beforeSaveMessage/spotify.js | 10 --- client/startup/index.js | 1 - client/startup/renderMessage/index.js | 1 - client/startup/renderMessage/spotify.js | 11 ---- 13 files changed, 28 insertions(+), 129 deletions(-) delete mode 100644 app/spotify/client/index.js delete mode 100644 app/spotify/client/oembedSpotifyWidget.html delete mode 100644 app/spotify/client/oembedSpotifyWidget.js delete mode 100644 client/startup/beforeSaveMessage/index.js delete mode 100644 client/startup/beforeSaveMessage/spotify.js delete mode 100644 client/startup/renderMessage/spotify.js diff --git a/app/oembed/client/baseWidget.js b/app/oembed/client/baseWidget.js index 3f97eabf5dbe..7db5c2388c29 100644 --- a/app/oembed/client/baseWidget.js +++ b/app/oembed/client/baseWidget.js @@ -7,27 +7,19 @@ createCollapseable(Template.oembedBaseWidget, (instance) => instance.data.settin Template.oembedBaseWidget.helpers({ template() { const { collapsedMedia } = Template.instance(); - this.collapsedMediaVar = function() { return collapsedMedia; }; + this.collapsedMediaVar = () => collapsedMedia; this.collapsed = collapsedMedia.get(); - let contentType; - if (this.headers) { - contentType = this.headers.contentType; - } - - if (this._overrideTemplate) { - return this._overrideTemplate; - } - if (this.headers && contentType && contentType.match(/image\/.*/)) { + if (this.headers?.contentType?.match(/image\/.*/)) { return 'oembedImageWidget'; } - if (this.headers && contentType && contentType.match(/audio\/.*/)) { + if (this.headers?.contentType?.match(/audio\/.*/)) { return 'oembedAudioWidget'; } - if ((this.headers && contentType && contentType.match(/video\/.*/)) || (this.meta && this.meta.twitterPlayerStreamContentType && this.meta.twitterPlayerStreamContentType.match(/video\/.*/))) { + if (this.headers?.contentType?.match(/video\/.*/) || this.meta?.twitterPlayerStreamContentType?.match(/video\/.*/)) { return 'oembedVideoWidget'; } - if (this.meta && this.meta.oembedHtml) { + if (this.meta?.oembedHtml) { return 'oembedFrameWidget'; } return 'oembedUrlWidget'; diff --git a/app/oembed/server/providers.js b/app/oembed/server/providers.js index b7049d9c8930..54bf583e1429 100644 --- a/app/oembed/server/providers.js +++ b/app/oembed/server/providers.js @@ -73,6 +73,11 @@ providers.registerProvider({ endPoint: 'https://publish.twitter.com/oembed', }); +providers.registerProvider({ + urls: [new RegExp('https?://(play|open)\\.spotify\\.com/(track|album|playlist|show)/\\S+')], + endPoint: 'https://open.spotify.com/oembed', +}); + export const oembed = {}; oembed.providers = providers; diff --git a/app/spotify/client/index.js b/app/spotify/client/index.js deleted file mode 100644 index 79c5b47e57fa..000000000000 --- a/app/spotify/client/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import './oembedSpotifyWidget'; -import './oembedSpotifyWidget.html'; - -export { createSpotifyMessageRenderer, createSpotifyBeforeSaveMessageHandler } from '../lib/spotify'; diff --git a/app/spotify/client/oembedSpotifyWidget.html b/app/spotify/client/oembedSpotifyWidget.html deleted file mode 100644 index 9da698d778f2..000000000000 --- a/app/spotify/client/oembedSpotifyWidget.html +++ /dev/null @@ -1,16 +0,0 @@ - diff --git a/app/spotify/client/oembedSpotifyWidget.js b/app/spotify/client/oembedSpotifyWidget.js deleted file mode 100644 index 275afdb287d8..000000000000 --- a/app/spotify/client/oembedSpotifyWidget.js +++ /dev/null @@ -1,16 +0,0 @@ -import { Template } from 'meteor/templating'; - -Template.registerHelper('replace', function(source, find, replace, option) { - if (option.hash.regex === true) { - find = new RegExp(find); - } - return source.replace(find, replace); -}); - -Template.registerHelper('match', (source, regex) => new RegExp(regex).test(source)); - -Template.oembedBaseWidget.onCreated(function() { - if (this.data && (this.data.meta && /^(music\.song|music\.album)$/.test(this.data.meta.ogType)) && this.data.parsedUrl && this.data.parsedUrl.host === 'open.spotify.com') { - this.data._overrideTemplate = 'oembedSpotifyWidget'; - } -}); diff --git a/app/spotify/lib/spotify.js b/app/spotify/lib/spotify.js index 9e4057854138..775f9a3ef47c 100644 --- a/app/spotify/lib/spotify.js +++ b/app/spotify/lib/spotify.js @@ -1,15 +1,8 @@ -/* - * Spotify a named function that will process Spotify links or syntaxes (ex: spotify:track:1q6IK1l4qpYykOaWaLJkWG) - * @param {Object} message - The message object - */ -import _ from 'underscore'; - const process = (message, source, callback) => { if (!source?.trim()) { return; } - // Separate text in code blocks and non code blocks const msgParts = source.split(/(```\w*[\n ]?[\s\S]*?```+?)|(`(?:[^`]+)`)/); for (let index = 0; index < msgParts.length; index++) { const part = msgParts[index]; @@ -19,55 +12,27 @@ const process = (message, source, callback) => { } }; -class Spotify { - static transform(message) { - let urls = []; - if (Array.isArray(message.urls)) { - urls = urls.concat(message.urls); - } - - let changed = false; +export const createSpotifyBeforeSaveMessageHandler = () => (message) => { + const urls = Array.isArray(message.urls) ? message.urls : []; - process(message, message.msg, function(message, msgParts, index, part) { - const re = /(?:^|\s)spotify:([^:\s]+):([^:\s]+)(?::([^:\s]+))?(?::(\S+))?(?:\s|$)/g; + let changed = false; - let match; - while ((match = re.exec(part)) != null) { - const data = _.filter(match.slice(1), (value) => value != null); - const path = _.map(data, (value) => _.escape(value)).join('/'); - const url = `https://open.spotify.com/${ path }`; - urls.push({ url, source: `spotify:${ data.join(':') }` }); - changed = true; - } - }); + process(message, message.msg, (message, msgParts, index, part) => { + const re = /(?:^|\s)spotify:([^:\s]+):([^:\s]+)(?::([^:\s]+))?(?::(\S+))?(?:\s|$)/g; - // Re-mount message - if (changed) { - message.urls = urls; + let match; + while ((match = re.exec(part)) != null) { + const data = match.slice(1).filter(Boolean); + const path = data.map((value) => encodeURI(value)).join('/'); + const url = `https://open.spotify.com/${ path }`; + urls.push({ url, source: `spotify:${ data.join(':') }` }); + changed = true; } + }); - return message; - } - - static render(message) { - process(message, message.html, function(message, msgParts, index, part) { - if (Array.isArray(message.urls)) { - for (const item of Array.from(message.urls)) { - if (item.source) { - const quotedSource = item.source.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&'); - const re = new RegExp(`(^|\\s)${ quotedSource }(\\s|$)`, 'g'); - msgParts[index] = part.replace(re, `$1${ item.source }$2`); - } - } - message.html = msgParts.join(''); - return message.html; - } - }); - - return message; + if (changed) { + message.urls = urls; } -} -export const createSpotifyMessageRenderer = () => Spotify.render; - -export const createSpotifyBeforeSaveMessageHandler = () => Spotify.transform; + return message; +}; diff --git a/app/spotify/server/index.js b/app/spotify/server/index.js index f25930176d05..8c612ddf614b 100644 --- a/app/spotify/server/index.js +++ b/app/spotify/server/index.js @@ -1,12 +1,10 @@ import { Meteor } from 'meteor/meteor'; import { callbacks } from '../../callbacks'; -import { createSpotifyBeforeSaveMessageHandler, createSpotifyMessageRenderer } from '../lib/spotify'; +import { createSpotifyBeforeSaveMessageHandler } from '../lib/spotify'; Meteor.startup(() => { const beforeSaveMessage = createSpotifyBeforeSaveMessageHandler(); - const renderMessage = createSpotifyMessageRenderer(); callbacks.add('beforeSaveMessage', beforeSaveMessage, callbacks.priority.LOW, 'spotify-save'); - callbacks.add('renderMessage', renderMessage, callbacks.priority.MEDIUM, 'spotify-render'); }); diff --git a/client/importPackages.js b/client/importPackages.js index af1359b46203..1fa0f34a0271 100644 --- a/client/importPackages.js +++ b/client/importPackages.js @@ -57,7 +57,6 @@ import '../app/slashcommands-kick/client'; import '../app/slashcommands-open'; import '../app/slashcommands-topic/client'; import '../app/slashcommands-unarchiveroom/client'; -import '../app/spotify/client'; import '../app/tokenpass/client'; import '../app/ui'; import '../app/ui-account'; diff --git a/client/startup/beforeSaveMessage/index.js b/client/startup/beforeSaveMessage/index.js deleted file mode 100644 index 1a5bea760f13..000000000000 --- a/client/startup/beforeSaveMessage/index.js +++ /dev/null @@ -1 +0,0 @@ -import './spotify'; diff --git a/client/startup/beforeSaveMessage/spotify.js b/client/startup/beforeSaveMessage/spotify.js deleted file mode 100644 index efd5c561a7c5..000000000000 --- a/client/startup/beforeSaveMessage/spotify.js +++ /dev/null @@ -1,10 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -import { callbacks } from '../../../app/callbacks'; - -Meteor.startup(() => { - import('../../../app/spotify/client').then(({ createSpotifyBeforeSaveMessageHandler }) => { - const beforeSaveMessage = createSpotifyBeforeSaveMessageHandler(); - callbacks.add('beforeSaveMessage', beforeSaveMessage, callbacks.priority.LOW, 'spotify-save'); - }); -}); diff --git a/client/startup/index.js b/client/startup/index.js index e27ed6535b36..9b0840470e40 100644 --- a/client/startup/index.js +++ b/client/startup/index.js @@ -1,4 +1,3 @@ -import './beforeSaveMessage'; import './contextualBar'; import './emailVerification'; import './i18n'; diff --git a/client/startup/renderMessage/index.js b/client/startup/renderMessage/index.js index 3b204e421e55..c4ac327c8cdf 100644 --- a/client/startup/renderMessage/index.js +++ b/client/startup/renderMessage/index.js @@ -8,4 +8,3 @@ import './issuelink'; import './katex'; import './markdown'; import './mentionsMessage'; -import './spotify'; diff --git a/client/startup/renderMessage/spotify.js b/client/startup/renderMessage/spotify.js deleted file mode 100644 index 7b1d7767e89f..000000000000 --- a/client/startup/renderMessage/spotify.js +++ /dev/null @@ -1,11 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -import { callbacks } from '../../../app/callbacks'; - -Meteor.startup(() => { - import('../../../app/spotify/client').then(({ createSpotifyMessageRenderer }) => { - const renderMessage = createSpotifyMessageRenderer(); - - callbacks.add('renderMessage', renderMessage, callbacks.priority.MEDIUM, 'spotify-render'); - }); -});