Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
An express app that redirects to largest SoundCloud artwork URL that doesn't 404.
'use strict';
var express = require('express'),
app = express();
require('./config/development')(app, express);
require('./config/production')(app, express);
var redis = require('redis'),
request = require('request'),
Promise = require('bluebird');
Promise.promisifyAll(redis.RedisClient.prototype);
var redisSettings = app.set('redis'),
redisClient = redis.createClient(redisSettings.port, redisSettings.host, redisSettings.options);
app.configure(function () {
app.use(express.bodyParser());
app.use(app.router);
});
function sendError(res, status, error) {
if (!(error instanceof Error)) {
error = new Error(JSON.stringify(error));
}
return res
.status(status || 500)
.end(error && error.message || 'Internal Server Error');
}
function generateCacheHeaders() {
var maxAge = 3600 * 24 * 365;
return {
'Cache-Control': 'public,max-age=' + maxAge,
'Expires': new Date(Date.now() + (maxAge * 1000)).toUTCString()
};
}
function getCacheKey(url) {
return 'soundcloud-thumbnail-proxy:' + url;
}
app.get('/*', function (req, res) {
var originalUrl = req.params[0],
cacheKey = getCacheKey(originalUrl),
urls;
// https://developers.soundcloud.com/docs/api/reference#artwork_url
// This is a ridiculous naming scheme, by the way.
urls = [
originalUrl,
originalUrl.replace('-large', '-t500x500'),
originalUrl.replace('-large', '-crop'), // 400x400
originalUrl.replace('-large', '-t300x300'),
originalUrl.replace('-large', '-large') // 100x100
];
return redisClient.getAsync(cacheKey).then(function (cachedUrl) {
if (cachedUrl) {
return cachedUrl;
}
return Promise.reduce(urls, function (resolvedUrl, url) {
if (resolvedUrl) {
return resolvedUrl;
}
return new Promise(function (resolve) {
request.head(url, function (err, response) {
if (!err && response.statusCode === 200) {
resolve(url);
} else {
resolve(null);
}
});
});
}, null);
}).then(function (url) {
if (!url) {
throw new Error('File not found');
}
var headers = generateCacheHeaders();
for (var key in headers) {
if (headers.hasOwnProperty(key)) {
res.setHeader(key, headers[key]);
}
}
res.redirect(url);
redisClient.set(cacheKey, url);
redisClient.expire(cacheKey, 60 * 60 * 24 * 30);
}).catch(function (err) {
sendError(res, 404, err);
});
});
app.get('/crossdomain.xml', function (req, res) {
req.setEncoding('utf8');
res.writeHead(200, { 'Content-Type': 'text/xml' });
res.end('<?xml version="1.0" ?><cross-domain-policy><allow-access-from domain="*" /></cross-domain-policy>');
});
redisClient.on('ready', function () {
app.listen(app.set('port'));
});
redisClient.on('error', function () {
throw new Error('Could not connect to Redis');
});
module.exports = app;
@alexkuz

This comment has been minimized.

Copy link

@alexkuz alexkuz commented Nov 8, 2014

https://gist.github.com/gaearon/717ed6d6c7771f95d50d#file-fixsoundcloudartworkurl-js-L52

It's a widespread convention known as "так исторически сложилось"

@chanocg

This comment has been minimized.

Copy link

@chanocg chanocg commented Jan 15, 2021

Heya,

Silly question - Where do i add the url for the soundcloud link?

Also is it possible for the output to be the a string which is the url of the artwork image.

example url:

url: https://soundcloud.com/jens-records/jens012-a1-funkig/s-ueATsI77OHU?in=jens-records/sets/jens112-the-ristorante-ep//s-9lt1WDfSCtf

url for artwork:

https://i1.sndcdn.com/artworks-1TKywvsYSljt2vXR-KSOtfQ-t500x500.jpg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment