From df3ab81cd5795a47b3a07f22f94c9a9aef05ebef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Tamargo?= Date: Tue, 22 Oct 2024 16:15:47 +0200 Subject: [PATCH 1/3] MBS-13784: Support paid streaming for beatport Beatport now supports streaming (with a subscription) for what seems to be most, but possibly not all, of its content (there's a streaming flag in the API, suggesting some music is still available for download only). This keeps always selecting purchase for download, but also allows selecting streaming alongside it for releases and recordings. For now artists and labels are left as purchase only; since adding a separate relationship for Beatport is not an available solution at the moment, this seems like the least bad option. --- root/static/scripts/edit/URLCleanup.js | 40 ++++++++++++++++- .../scripts/tests/Control/URLCleanup.js | 44 +++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/root/static/scripts/edit/URLCleanup.js b/root/static/scripts/edit/URLCleanup.js index 2e7079c61eb..70e03e52c11 100644 --- a/root/static/scripts/edit/URLCleanup.js +++ b/root/static/scripts/edit/URLCleanup.js @@ -1368,7 +1368,43 @@ const CLEANUPS: CleanupEntries = { }, 'beatport': { match: [/^(https?:\/\/)?([^/]+\.)?beatport\.com/i], - restrict: [LINK_TYPES.downloadpurchase], + restrict: [ + LINK_TYPES.downloadpurchase, + { + recording: [ + LINK_TYPES.downloadpurchase.recording, + LINK_TYPES.streamingpaid.recording, + ], + }, + { + release: [ + LINK_TYPES.downloadpurchase.release, + LINK_TYPES.streamingpaid.release, + ], + }, + ], + select(url, sourceType) { + const m = /^https?:\/\/(?:sounds|www)\.beatport\.com\/([\w-]+)\/[\w!%-]+\/[1-9][0-9]*$/.exec(url); + if (m) { + const prefix = m[1]; + switch (prefix) { + case 'chart': + case 'release': + case 'stem-pack': + if (sourceType === 'release') { + return LINK_TYPES.downloadpurchase.release; + } + break; + case 'stem': + case 'track': + if (sourceType === 'recording') { + return LINK_TYPES.downloadpurchase.recording; + } + break; + } + } + return false; + }, clean(url) { url = url.replace(/^(?:https?:\/\/)?(?:(?:classic|pro|www)\.)?beatport\.com\//, 'https://www.beatport.com/'); const m = url.match(/^(https:\/\/www\.beatport\.com)\/[\w-]+\/html\/content\/([\w-]+)\/detail\/0*([0-9]+)\/([^/?&#]*).*$/); @@ -1405,11 +1441,13 @@ const CLEANUPS: CleanupEntries = { target: ERROR_TARGETS.ENTITY, }; case LINK_TYPES.downloadpurchase.recording: + case LINK_TYPES.streamingpaid.recording: return { result: prefix === 'track' || prefix === 'stem', target: ERROR_TARGETS.ENTITY, }; case LINK_TYPES.downloadpurchase.release: + case LINK_TYPES.streamingpaid.release: return { result: prefix === 'release' || prefix === 'chart' || diff --git a/root/static/scripts/tests/Control/URLCleanup.js b/root/static/scripts/tests/Control/URLCleanup.js index f906743535e..6a58d87e4e7 100644 --- a/root/static/scripts/tests/Control/URLCleanup.js +++ b/root/static/scripts/tests/Control/URLCleanup.js @@ -1067,6 +1067,10 @@ limited_link_type_combinations: [ input_url: 'https://www.beatport.com/release/pryda-10-vol-i/1563118', input_entity_type: 'release', expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], expected_clean_url: 'https://www.beatport.com/release/pryda-10-vol-i/1563118', only_valid_entity_types: ['release'], }, @@ -1074,6 +1078,10 @@ limited_link_type_combinations: [ input_url: 'http://classic.beatport.com/release/4/2361374', input_entity_type: 'release', expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], expected_clean_url: 'https://www.beatport.com/release/4/2361374', only_valid_entity_types: ['release'], }, @@ -1081,6 +1089,10 @@ limited_link_type_combinations: [ input_url: 'https://www.beatport.com/en-US/html/content/release/detail/161035/Back%20To%20The%20Future', input_entity_type: 'release', expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], expected_clean_url: 'https://www.beatport.com/release/back-to-the-future/161035', only_valid_entity_types: ['release'], }, @@ -1088,6 +1100,10 @@ limited_link_type_combinations: [ input_url: 'https://www.beatport.com/en-US/html/content/release/detail/06130/%40@%26%25%24$%23%22%21!-&tracks#', input_entity_type: 'release', expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], expected_clean_url: 'https://www.beatport.com/release/at-at-and-percent-money-money-pound-!!/6130', only_valid_entity_types: ['release'], }, @@ -1095,6 +1111,10 @@ limited_link_type_combinations: [ input_url: 'https://www.beatport.com/en-US/html/content/release/detail/287442/', input_entity_type: 'release', expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], expected_clean_url: 'https://www.beatport.com/release/---/287442', only_valid_entity_types: ['release'], }, @@ -1102,6 +1122,10 @@ limited_link_type_combinations: [ input_url: 'https://www.beatport.com/release//287442', input_entity_type: 'release', expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], expected_clean_url: 'https://www.beatport.com/release/---/287442', only_valid_entity_types: ['release'], }, @@ -1109,6 +1133,10 @@ limited_link_type_combinations: [ input_url: 'https://www.beatport.com/release/riva-starr-presents-square-pegs-round-holes-5-years-of-snatch%21-sampler/1520186', input_entity_type: 'release', expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], expected_clean_url: 'https://www.beatport.com/release/riva-starr-presents-square-pegs-round-holes-5-years-of-snatch%21-sampler/1520186', only_valid_entity_types: ['release'], }, @@ -1116,6 +1144,10 @@ limited_link_type_combinations: [ input_url: 'https://www.beatport.com/chart/eric-prydz-february-chart/32623', input_entity_type: 'release', expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], expected_clean_url: 'https://www.beatport.com/chart/eric-prydz-february-chart/32623', only_valid_entity_types: ['release'], }, @@ -1123,6 +1155,10 @@ limited_link_type_combinations: [ input_url: 'https://www.beatport.com/stem-pack/my-colors-ep/3030', input_entity_type: 'release', expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], expected_clean_url: 'https://www.beatport.com/stem-pack/my-colors-ep/3030', only_valid_entity_types: ['release'], }, @@ -1130,6 +1166,10 @@ limited_link_type_combinations: [ input_url: 'https://www.beatport.com/stem/celestial/7380', input_entity_type: 'recording', expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], expected_clean_url: 'https://www.beatport.com/stem/celestial/7380', only_valid_entity_types: ['recording'], }, @@ -1137,6 +1177,10 @@ limited_link_type_combinations: [ input_url: 'https://www.beatport.com/track/full-stop-original-mix/1682783', input_entity_type: 'recording', expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], expected_clean_url: 'https://www.beatport.com/track/full-stop-original-mix/1682783', only_valid_entity_types: ['recording'], }, From 10c36030cdd5a87e67e38b20b0ac329dd13d351d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Tamargo?= Date: Tue, 22 Oct 2024 16:46:57 +0200 Subject: [PATCH 2/3] Use - instead of --- as a slug fallback We have 58 --- URLs, but around 500 with just - (probably because of Harmony). There seems to be no reason to prefer --- so let's do - in the future. This will become more relevant as I need to clean up dj.beatport releases which have the same release ID but do not have a slug. --- root/static/scripts/edit/URLCleanup.js | 4 ++-- root/static/scripts/tests/Control/URLCleanup.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/root/static/scripts/edit/URLCleanup.js b/root/static/scripts/edit/URLCleanup.js index 70e03e52c11..ccda986c5a5 100644 --- a/root/static/scripts/edit/URLCleanup.js +++ b/root/static/scripts/edit/URLCleanup.js @@ -1423,11 +1423,11 @@ const CLEANUPS: CleanupEntries = { .replace(/[^a-z0-9!]/g, '-') .replace(/-+/g, '-') .replace(/^-|-$/g, '') - .replace(/^$/, '---'); + .replace(/^$/, '-'); url = [m[1], m[2], slug, m[3]].join('/'); } url = url.replace(/^(https:\/\/www\.beatport\.com)\/([\w-]+)\/([\w!-]+)\/0*([0-9]+).*$/, '$1/$2/$3/$4'); - url = url.replace(/^(https:\/\/www\.beatport\.com)\/([\w-]+)\/\/0*([0-9]+)(?![\w!-]|\/[0-9]).*$/, '$1/$2/---/$3'); + url = url.replace(/^(https:\/\/www\.beatport\.com)\/([\w-]+)\/\/0*([0-9]+)(?![\w!-]|\/[0-9]).*$/, '$1/$2/-/$3'); return url; }, validate(url, id) { diff --git a/root/static/scripts/tests/Control/URLCleanup.js b/root/static/scripts/tests/Control/URLCleanup.js index 6a58d87e4e7..bace17f4f96 100644 --- a/root/static/scripts/tests/Control/URLCleanup.js +++ b/root/static/scripts/tests/Control/URLCleanup.js @@ -1017,7 +1017,7 @@ limited_link_type_combinations: [ expected_clean_url: 'https://www.bbc.co.uk/music/artists/b52dd210-909c-461a-a75d-19e85a522042', }, // Beatport - { // Closed in Dec. 2017, replaced with www.beatport.com/chart + { // Old DJ page, closed in Dec. 2017, replaced with www.beatport.com/chart input_url: 'http://dj.beatport.com/thegoldenboyuk', input_entity_type: 'artist', expected_relationship_type: 'downloadpurchase', @@ -1115,7 +1115,7 @@ limited_link_type_combinations: [ ['downloadpurchase', 'streamingpaid'], 'downloadpurchase', ], - expected_clean_url: 'https://www.beatport.com/release/---/287442', + expected_clean_url: 'https://www.beatport.com/release/-/287442', only_valid_entity_types: ['release'], }, { // Nowadays erroneous redirect for legacy URL format missing slug (same example) @@ -1126,7 +1126,7 @@ limited_link_type_combinations: [ ['downloadpurchase', 'streamingpaid'], 'downloadpurchase', ], - expected_clean_url: 'https://www.beatport.com/release/---/287442', + expected_clean_url: 'https://www.beatport.com/release/-/287442', only_valid_entity_types: ['release'], }, { // Used to be rejected by validation (MBS-11263) From e9897c9ce94dfe673bbbd0e73872f9bda05ddb5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Tamargo?= Date: Tue, 22 Oct 2024 17:40:57 +0200 Subject: [PATCH 3/3] MBS-13784: Clean up dj.beatport links These are for a DJ-oriented UI for the beatport store, allowing live DJ use. The content seems to be the same as the main store though and with both allowing stream and purchase, there seems to be no reason not to consolidate them. Artists and labels have a slug on both versions of the site, so they can be converted trivially. Releases don't, so we need the false slug hack we already used for some older redirects. Track links are release id plus track id, but I chose to clean them to tracks rather than releases so that there is a way for users to get track links from the DJ site. Hopefully it won't be too confusing since the UI mostly highlights the release even from DJ track links. --- root/static/scripts/edit/URLCleanup.js | 6 +++- .../scripts/tests/Control/URLCleanup.js | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/root/static/scripts/edit/URLCleanup.js b/root/static/scripts/edit/URLCleanup.js index ccda986c5a5..124126a04d2 100644 --- a/root/static/scripts/edit/URLCleanup.js +++ b/root/static/scripts/edit/URLCleanup.js @@ -1406,7 +1406,11 @@ const CLEANUPS: CleanupEntries = { return false; }, clean(url) { - url = url.replace(/^(?:https?:\/\/)?(?:(?:classic|pro|www)\.)?beatport\.com\//, 'https://www.beatport.com/'); + url = url.replace(/^(?:https?:\/\/)?([^/]+\.)?beatport\.com\//, 'https://$1beatport.com/'); + url = url.replace(/^https:\/\/(?:(?:classic|pro|www)\.)?beatport\.com\//, 'https://www.beatport.com/'); + url = url.replace(/^https:\/\/dj\.beatport\.com\/(artist|label)s\/([\w-]+)\/([1-9][0-9]*)/, 'https://www.beatport.com/$1/$2/$3'); + url = url.replace(/^https:\/\/dj\.beatport\.com\/releases\/[1-9][0-9]*\/([1-9][0-9]*)/, 'https://www.beatport.com/track/-/$1'); + url = url.replace(/^https:\/\/dj\.beatport\.com\/releases\/([1-9][0-9]*)/, 'https://www.beatport.com/release/-/$1'); const m = url.match(/^(https:\/\/www\.beatport\.com)\/[\w-]+\/html\/content\/([\w-]+)\/detail\/0*([0-9]+)\/([^/?&#]*).*$/); if (m) { const slug = m[4].toLowerCase() diff --git a/root/static/scripts/tests/Control/URLCleanup.js b/root/static/scripts/tests/Control/URLCleanup.js index bace17f4f96..f49ef4412d4 100644 --- a/root/static/scripts/tests/Control/URLCleanup.js +++ b/root/static/scripts/tests/Control/URLCleanup.js @@ -1063,6 +1063,13 @@ limited_link_type_combinations: [ expected_clean_url: 'https://www.beatport.com/artist/4orcedj/208047', only_valid_entity_types: ['artist'], }, + { + input_url: 'https://dj.beatport.com/artists/4orce-dj/208047', + input_entity_type: 'artist', + expected_relationship_type: 'downloadpurchase', + expected_clean_url: 'https://www.beatport.com/artist/4orce-dj/208047', + only_valid_entity_types: ['artist'], + }, { input_url: 'https://www.beatport.com/release/pryda-10-vol-i/1563118', input_entity_type: 'release', @@ -1140,6 +1147,17 @@ limited_link_type_combinations: [ expected_clean_url: 'https://www.beatport.com/release/riva-starr-presents-square-pegs-round-holes-5-years-of-snatch%21-sampler/1520186', only_valid_entity_types: ['release'], }, + { // DJ page (no slug available) + input_url: 'https://dj.beatport.com/releases/3794236', + input_entity_type: 'release', + expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], + expected_clean_url: 'https://www.beatport.com/release/-/3794236', + only_valid_entity_types: ['release'], + }, { input_url: 'https://www.beatport.com/chart/eric-prydz-february-chart/32623', input_entity_type: 'release', @@ -1184,6 +1202,17 @@ limited_link_type_combinations: [ expected_clean_url: 'https://www.beatport.com/track/full-stop-original-mix/1682783', only_valid_entity_types: ['recording'], }, + { + input_url: 'https://dj.beatport.com/releases/4758665/19583630', + input_entity_type: 'recording', + expected_relationship_type: 'downloadpurchase', +limited_link_type_combinations: [ + ['downloadpurchase', 'streamingpaid'], + 'downloadpurchase', + ], + expected_clean_url: 'https://www.beatport.com/track/-/19583630', + only_valid_entity_types: ['recording'], + }, { input_url: 'https://www.beatport.com/label/mouseville/1421', input_entity_type: 'label', @@ -1191,6 +1220,13 @@ limited_link_type_combinations: [ expected_clean_url: 'https://www.beatport.com/label/mouseville/1421', only_valid_entity_types: ['label'], }, + { + input_url: 'https://dj.beatport.com/labels/justice-hardcore/30135', + input_entity_type: 'label', + expected_relationship_type: 'downloadpurchase', + expected_clean_url: 'https://www.beatport.com/label/justice-hardcore/30135', + only_valid_entity_types: ['label'], + }, // Behance { input_url: 'http://behance.net/tristan-gion/appreciated',