Files
angular.js/gdocs.js
T
Michał Gołębiowski 9360aa2d27 chore(eslint): enable quotes: ["error", "single"]
The quotes rule had to be disabled for e2e tests generated from ngdoc
because dgeni templates use double quotes as string delimiters.

Since we can't have guarantees that dgeni template wrappers will follow
the same JS code style the Angular 1 repo uses, we should find a way
to enforce our ESLint setup only for the parts in this repo, perhaps
via prepending a generated `/* eslint-enable OUR_RULES */` pragma.

Closes #15011
2016-08-10 21:52:38 +02:00

259 lines
7.0 KiB
JavaScript
Executable File

#!/usr/bin/env node
'use strict';
var http = require('http');
var https = require('https');
var fs = require('fs');
var collections = {
'guide': 'https://docs.google.com/feeds/default/private/full/folder%3A0B9PsajIPqzmANGUwMGVhZmYtMTk1ZC00NTdmLWIxMDAtZGI5YWNlZjQ2YjZl/contents',
'api': 'https://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDYjMwYTc2YWUtZTgzYy00YjIxLThlZDYtYWJlOTFlNzE2NzEw/contents',
'tutorial': 'https://docs.google.com/feeds/default/private/full/folder%3A0B9PsajIPqzmAYWMxYWE3MzYtYzdjYS00OGQxLWJhZjItYzZkMzJiZTRhZjFl/contents',
'cookbook': 'https://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDNzkxZWM5ZTItN2M5NC00NWIxLTg2ZDMtMmYwNDY1NWM1MGU4/contents',
'misc': 'https://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDZjVlNmZkYzQtMjZlOC00NmZhLWI5MjAtMGRjZjlkOGJkMDBi/contents'
};
console.log('Google Docs...');
var flag = process && process.argv[2];
if (flag === '--login') {
var username = process.argv[3];
if (username) {
askPassword(function(password) {
login(username, password);
});
} else {
console.log('Missing username!');
}
} else if (flag === '--fetch') {
var collection = process.argv[3];
if (collection) {
fetch(collection, collections[collection]);
} else {
for (collection in collections)
fetch(collection, collections[collection]);
}
} else {
help();
}
function help() {
console.log('Synopsys');
console.log('gdocs.js --login <username>');
console.log('gdocs.js --fetch [<docs collection>]');
process.exit(-1);
}
function fetch(collection, url) {
console.log('fetching a list of docs in collection ' + collection + '...');
request('GET', url, {
headers: {
'Gdata-Version': '3.0',
'Authorization': 'GoogleLogin auth=' + getAuthToken()
}
},
function(chunk) {
var entries = chunk.split('<entry');
entries.shift();
entries.forEach(function(entry) {
var title = entry.match(/<title>(.*?)<\/title>/)[1];
if (title.match(/\.ngdoc$/)) {
var exportUrl = entry.match(/<content type='text\/html' src='(.*?)'\/>/)[1];
download(collection, title, exportUrl);
}
});
}
);
}
function download(collection, name, url) {
console.log('Downloading:', name, '...');
request('GET', url + '&exportFormat=txt',
{
headers: {
'Gdata-Version': '3.0',
'Authorization': 'GoogleLogin auth=' + getAuthToken()
}
},
function(data) {
data = data.replace('\ufeff', '');
data = data.replace(/\r\n/mg, '\n');
// strip out all text annotations
data = data.replace(/\[[a-zA-Z]{1,2}\]/mg, '');
// strip out all docos comments
data = data.replace(/^[^\s_]+:\n\S+[\S\s]*$/m, '');
// fix smart-quotes
data = data.replace(/[“”]/g, '"');
data = data.replace(/[‘’]/g, '\'');
data = data + '\n';
//this should be a bug in Google Doc API, hence need to remove this once the bug is fixed
data = data.replace(/\n\n/g, '\n');
fs.writeFileSync('docs/content/' + collection + '/' + name, reflow(data, 100));
}
);
}
/**
* token=$(curl
* -s https://www.google.com/accounts/ClientLogin
* -d Email=...username...
* -d Passwd=...password...
* -d accountType=GOOGLE
* -d service=writely
* -d Gdata-version=3.0 | cut -d "=" -f 2)
*/
function login(username, password) {
request('POST', 'https://www.google.com/accounts/ClientLogin',
{
data: {
Email: username,
Passwd: password,
accountType: 'GOOGLE',
service: 'writely',
'Gdata-version': '3.0'
},
headers: {
'Content-type': 'application/x-www-form-urlencoded'
}
},
function(chunk) {
var token;
chunk.split('\n').forEach(function(line) {
var parts = line.split('=');
if (parts[0] === 'Auth') {
token = parts[1];
}
});
if (token) {
fs.writeFileSync('tmp/gdocs.auth', token);
console.log('logged in, token saved in \'tmp/gdocs.auth\'');
} else {
console.log('failed to log in');
}
}
);
}
function getAuthToken() {
var pwdFile = 'tmp/gdocs.auth';
try {
fs.statSync(pwdFile);
return fs.readFileSync(pwdFile);
} catch (e) {
console.log('Please log in first...');
}
}
function request(method, url, options, response) {
url = url.match(/http(s?):\/\/(.+?)(\/.*)/);
var isHttps = url[1];
var req = (isHttps ? https : http).request({
host: url[2],
port: (url[1] ? 443 : 80),
path: url[3],
method: method
}, function(res) {
var data;
switch (res.statusCode) {
case 200:
data = [];
res.setEncoding('utf8');
res.on('end', function() { response(data.join('')); });
res.on('close', function() { response(data.join('')); }); // https
res.on('data', function(chunk) { data.push(chunk); });
res.on('error', function(e) { console.log(e); });
break;
case 401:
console.log('Error: Login credentials expired! Please login.');
break;
default:
data = [];
console.log('ERROR: ', res.statusCode);
console.log('REQUEST URL: ', url[0]);
console.log('REQUEST POST: ', options.data);
console.log('REQUEST HEADERS: ', options.headers);
console.log('RESPONSE HEADERS: ', res.headers);
res.on('end', function() { console.log('BODY: ', data.join('')); });
res.on('close', function() { console.log('BODY: ', data.join('')); }); // https
res.on('data', function(chunk) { data.push(chunk); });
res.on('error', function(e) { console.log(e); });
}
});
for (var header in options.headers) {
req.setHeader(header, options.headers[header]);
}
if (options.data)
req.write(encodeData(options.data));
req.on('end', function() {
console.log('end');
});
req.end();
}
function encodeData(obj) {
var pairs = [];
for (var key in obj) {
pairs.push(key + '=' + obj[key]);
}
return pairs.join('&') + '\n';
}
function askPassword(callback) {
var stdin = process.openStdin(),
stdio = process.binding('stdio');
stdio.setRawMode();
console.log('Enter your password:');
var password = '';
stdin.on('data', function(c) {
c = c + '';
switch (c) {
case '\n':
case '\r':
case '\u0004':
stdio.setRawMode(false);
stdin.pause();
callback(password);
break;
case '\u0003':
process.exit();
break;
default:
password += c;
break;
}
});
}
function reflow(text, margin) {
var lines = [];
text.split(/\n/).forEach(function(line) {
var col = 0;
var reflowLine = '';
function flush() {
reflowLine = reflowLine.replace(/\s*$/, '');
lines.push(reflowLine);
reflowLine = '';
col = 0;
}
line.replace(/\s*\S*\s*/g, function(chunk) {
if (col + chunk.length > margin) flush();
reflowLine += chunk;
col += chunk.length;
});
flush();
});
return lines.join('\n');
}