Skip to content

Instantly share code, notes, and snippets.

@callumlocke
Last active December 24, 2015 11:49
Show Gist options
  • Select an option

  • Save callumlocke/6793536 to your computer and use it in GitHub Desktop.

Select an option

Save callumlocke/6793536 to your computer and use it in GitHub Desktop.
Helper function to get the spreadsheet key from a URL in FT IG projects.
{
"directory": "bower_components",
"json": "bower.json"
}
bower_components
# Log files generated by Testem
testem.*.json
tests.tap
libpeerconnection.log

parseSpreadsheetKey

Simple function to parse out the key from whatever you throw at it (within reason) – any Google Spreadsheets URL or any Bertha URL.

Install

Front-end usage:

bower install --save git+https://gist.github.com/6793536.git
<script src="bower_components/parse-spreadsheet-key/index.js"></script>

You can then access the function at IG.parseSpreadsheetKey(str).

Node.js usage:

npm install git+https://gist.github.com/6793536.git
var parseSpreadsheetKey = require('parse-spreadsheet-key')

Functionality

parseSpreadsheetKey(str, [silent])

var key = parseSpreadsheetKey('https://docs.google.com/a/ft.com/spreadsheet/ccc?key=0Ajt08GcPGJRbdFJUZWZfZ3M1V0xDaTFBckJnNENCSGc');
  • It accepts any valid Bertha URL or Google Spreadsheets URL as input.
  • If you pass in a plain key on its own, it will pass it back untouched.
  • Throws an error if something invalid is found (unless you pass true as the 2nd argument, in which case it just returns null).
{
"name": "parse-spreadsheet-key",
"version": "0.0.0",
"main": "index.js",
"dependencies": {},
"devDependencies": {
"chai": "~1.5.0",
"mocha": "~1.9.0"
},
"ignore": [
".bowerrc",
".gitignore",
"bower.json",
"package.json",
"test.html",
"test.js",
"testem.json"
]
}
/*jshint node:true, browser:true, curly:false*/
(function (root) {
'use strict';
var spreadsheetKeyRegex = /^[a-zA-Z0-9\-_]{30,60}$/; // seems to always be 44 chars, but
// accepting range of 30-60 just in case.
var berthaHosts = [
'spottiswood-tupp.herokuapp.com',
'staging.bertha.ig.ft.com',
'spottiswood.herokuapp.com',
'bertha.ig.ft.com'
];
var parseSpreadsheetKey = function (str, silent) {
if (str.indexOf('http') === 0) {
// Attempt to parse as Google URL
if (str.indexOf('https://docs.google.com') === 0)
return (
str.split('key=')
.pop()
.split('&')[0]
.split('#')[0]
);
// Attempt to parse as Bertha URL
var afterProtocol = str.split('//')[1];
for (var i = berthaHosts.length - 1; i >= 0; i--) {
if (afterProtocol.indexOf(berthaHosts[i]) === 0)
return (
afterProtocol
.split('?')[0]
.split('/')[4]
);
}
}
if (!spreadsheetKeyRegex.test(str)) {
if (!silent)
throw new Error('Cannot parse spreadsheet key from value: ' + str);
else
return null;
}
// Must be a plain key
return str;
};
// Export for Node or attach to IG namespace
if (typeof module !== 'undefined' && module.exports)
module.exports = parseSpreadsheetKey;
else {
/*jshint sub:true*/
root['IG'] = root['IG'] || {};
root['IG'].parseSpreadsheetKey = parseSpreadsheetKey;
/*jshint sub:false*/
}
}(this));
{
"name": "parse-spreadsheet-key",
"private": "true",
"version": "0.0.1",
"description": "Helper function for FT IG projects",
"scripts": {
"test": "testem ci"
},
"repository": {
"type": "git",
"url": "https://gist.github.com/6793536.git"
},
"author": "Callum Locke"
}
<!doctype html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Mocha Spec Runner</title>
<link rel="stylesheet" href="bower_components/mocha/mocha.css">
</head>
<body>
<div id="mocha"></div>
<script src="bower_components/mocha/mocha.js"></script>
<script>mocha.setup('bdd')</script>
<script src="bower_components/chai/chai.js"></script>
<script>var expect = chai.expect</script>
<script src="/testem.js"></script>
<script src="index.js"></script>
<script src="test.js"></script>
<script>mocha.run()</script>
</body>
</html>
/*global describe, it, expect, IG */
/*jshint es5:true*/
(function () {
'use strict';
describe('parseSpreadsheetKey', function () {
// Prepare some values for testing
var key = '0Ajt08GcPGJRbdFJUZWZfZ3M1V0xDaTFBckJnNENCSGc';
var gsURLs = [
'https://docs.google.com/a/ft.com/spreadsheet/ccc?key=' + key,
'https://docs.google.com/a/ft.com/spreadsheet/ccc?key=' + key + '#hash',
'https://docs.google.com/a/ft.com/spreadsheet/ccc?key=' + key + '&foo=bar',
'https://docs.google.com/a/ft.com/spreadsheet/ccc?key=' + key + '&foo=bar#hash',
];
var berthaURLs = [];
([
'bertha.ig.ft.com',
'spottiswood.herokuapp.com',
'staging.bertha.ig.ft.com',
'spottiswood-tupp.herokuapp.com'
]).forEach(function (host) {
berthaURLs = berthaURLs.concat([
'http://' + host + '/view/publish/ig/' + key,
'http://' + host + '/republish/publish/ig/' + key + '/basic,foo',
'http://' + host + '/view/publish/ig/' + key + '?callback=hi'
]);
});
var invalidStrings = [
'ab==gsgsc....asdfasdf 891 sd', // invalid chars
'https://mops.google.com/a/ft.com/spreadsheet/ccc?key=' + key, // wrong hostname
'0Ajt08GcPGJRbdFJUZWZfZ3M1V0xDaTFBckJnNENCSGc/', // slash at end
'0Ajt08GcPGJRbdFJUZWZfZ', // too short
'0Ajt08GcPGJRbdFJUZWZfZ3M1V0xDaTFBckJnNENCSGc0Ajt08GcPGJRbdFJUZWZfZ3M1V0xDaTFBckJnNENCSGc' // too long
];
// Do tests
it('handles a plain key', function () {
expect(IG.parseSpreadsheetKey(key)).to.equal(key);
});
it('handles a Google Spreadsheets URL', function () {
gsURLs.forEach(function (url) {
expect(IG.parseSpreadsheetKey(url)).to.equal(key);
});
});
it('handles a Bertha URL at any of the known Bertha hosts', function () {
berthaURLs.forEach(function (url) {
expect(IG.parseSpreadsheetKey(url)).to.equal(key);
});
});
it('throws on invalid strings', function () {
invalidStrings.forEach(function (str) {
expect(function () {
IG.parseSpreadsheetKey(str);
}).to.throw(/Cannot parse spreadsheet key from value/);
});
});
it('returns null for invalid strings if "silent" flag is passed', function () {
invalidStrings.forEach(function (str) {
expect(function () {
expect(IG.parseSpreadsheetKey(str, true)).to.equal(null);
}).to.not.throw(Error);
});
});
});
})();
{
"framework": "mocha",
"test_page": "test.html",
"launch_in_dev": [
"Chrome",
"Firefox",
"Safari",
"Opera"
],
"launch_in_ci": [
"Chrome",
"Firefox",
"Safari",
"Opera"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment