Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 221 lines (198 sloc) 5.991 kb
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
1 #!/usr/bin/env node
887da56 Igor Minar enhancing gdocs.js to work with nested collections
IgorMinar authored
2
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
3 var http = require('http');
4 var https = require('https');
5 var fs = require('fs');
6
887da56 Igor Minar enhancing gdocs.js to work with nested collections
IgorMinar authored
7 var collections = {
10a7521 Igor Minar rename devguide collection in gdocs.js to guide
IgorMinar authored
8 'guide': 'http://docs.google.com/feeds/default/private/full/folder%3A0B9PsajIPqzmANGUwMGVhZmYtMTk1ZC00NTdmLWIxMDAtZGI5YWNlZjQ2YjZl/contents',
887da56 Igor Minar enhancing gdocs.js to work with nested collections
IgorMinar authored
9 'api': 'http://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDYjMwYTc2YWUtZTgzYy00YjIxLThlZDYtYWJlOTFlNzE2NzEw/contents',
9701f07 Igor Minar add the tutorial collection to gdocs.js
IgorMinar authored
10 'tutorial': 'http://docs.google.com/feeds/default/private/full/folder%3A0B9PsajIPqzmAYWMxYWE3MzYtYzdjYS00OGQxLWJhZjItYzZkMzJiZTRhZjFl/contents',
887da56 Igor Minar enhancing gdocs.js to work with nested collections
IgorMinar authored
11 'cookbook': 'http://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDNzkxZWM5ZTItN2M5NC00NWIxLTg2ZDMtMmYwNDY1NWM1MGU4/contents',
12 'misc': 'http://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDZjVlNmZkYzQtMjZlOC00NmZhLWI5MjAtMGRjZjlkOGJkMDBi/contents'
d6e4636 Vojta Jina Couple of missing semi-colons
vojtajina authored
13 };
887da56 Igor Minar enhancing gdocs.js to work with nested collections
IgorMinar authored
14
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
15 console.log('Google Docs...');
16
17 var flag = process && process.argv[2];
18 if (flag == '--login')
19 askPassword(function(password){
20 login(process.argv[3], password);
21 });
887da56 Igor Minar enhancing gdocs.js to work with nested collections
IgorMinar authored
22 else if (flag == '--fetch') {
23 var collection = process.argv[3];
24 if (collection) {
25 fetch(collection, collections[collection]);
26 } else {
27 for (collection in collections)
28 fetch(collection, collections[collection]);
29 }
30 } else
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
31 help();
32
33 function help(){
34 console.log('Synopsys');
887da56 Igor Minar enhancing gdocs.js to work with nested collections
IgorMinar authored
35 console.log('gdocs.js --login <username>');
36 console.log('gdocs.js --fetch [<docs collection>]');
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
37 process.exit(-1);
38 };
39
40
91f9efe Igor Minar gdocs.js should store files under docs/content/[collection]/
IgorMinar authored
41 function fetch(collection, url){
42 console.log('fetching a list of docs in collection ' + collection + '...');
887da56 Igor Minar enhancing gdocs.js to work with nested collections
IgorMinar authored
43 request('GET', url, {
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
44 headers: {
45 'Gdata-Version': '3.0',
46 'Authorization': 'GoogleLogin auth=' + getAuthToken()
47 }
48 },
49 function(chunk){
50 var entries = chunk.split('<entry');
51 entries.shift();
52 entries.forEach(function(entry){
53 var title = entry.match(/<title>(.*?)<\/title>/)[1];
54 if (title.match(/\.ngdoc$/)) {
55 var exportUrl = entry.match(/<content type='text\/html' src='(.*?)'\/>/)[1];
91f9efe Igor Minar gdocs.js should store files under docs/content/[collection]/
IgorMinar authored
56 download(collection, title, exportUrl);
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
57 }
58 });
59 }
60 );
61 }
62
91f9efe Igor Minar gdocs.js should store files under docs/content/[collection]/
IgorMinar authored
63 function download(collection, name, url) {
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
64 console.log('Downloading:', name, '...');
65 request('GET', url + '&exportFormat=txt',
66 {
67 headers: {
68 'Gdata-Version': '3.0',
69 'Authorization': 'GoogleLogin auth=' + getAuthToken()
70 }
71 },
72 function(data){
73 data = data.replace('\ufeff', '');
74 data = data.replace(/\r\n/mg, '\n');
75
a4dd9ca Igor Minar fix comment stripping
IgorMinar authored
76 // strip out all text annotations
77 data = data.replace(/\[[a-zA-Z]{1,2}\]/mg, '');
78
22dee3e Igor Minar gdocs.js - add docos style comment stripping
IgorMinar authored
79 // strip out all docos comments
d6e4636 Vojta Jina Couple of missing semi-colons
vojtajina authored
80 data = data.replace(/^[^\s_]+:\n\S+[\S\s]*$/m, '');
22dee3e Igor Minar gdocs.js - add docos style comment stripping
IgorMinar authored
81
fd6e5e3 Miško Hevery replace smart-quotes with regular quotes
mhevery authored
82 // fix smart-quotes
83 data = data.replace(/[“”]/g, '"');
84 data = data.replace(/[‘’]/g, "'");
85
86
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
87 data = data + '\n';
91f9efe Igor Minar gdocs.js should store files under docs/content/[collection]/
IgorMinar authored
88 fs.writeFileSync('docs/content/' + collection + '/' + name, reflow(data, 100));
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
89 }
90 );
91 }
92
93 /**
94 * token=$(curl
95 * -s https://www.google.com/accounts/ClientLogin
96 * -d Email=...username...
97 * -d Passwd=...password...
98 * -d accountType=GOOGLE
99 * -d service=writely
100 * -d Gdata-version=3.0 | cut -d "=" -f 2)
101 */
102 function login(username, password){
103 request('POST', 'https://www.google.com/accounts/ClientLogin',
104 {
105 data: {
106 Email: username,
107 Passwd: password,
108 accountType: 'GOOGLE',
109 service: 'writely',
110 'Gdata-version': '3.0'
111 },
112 headers: {
113 'Content-type': 'application/x-www-form-urlencoded'
114 }
115 },
116 function(chunk){
117 var token;
118 chunk.split('\n').forEach(function(line){
119 var parts = line.split('=');
120 if (parts[0] == 'Auth') {
121 token = parts[1];
122 }
123 });
124 if (token) {
125 fs.writeFileSync('tmp/gdocs.auth', token);
126 console.log("logged in, token saved in 'tmp/gdocs.auth'");
127 } else {
128 console.log('failed to log in');
129 }
130 }
131 );
132 }
133
134 function getAuthToken(){
135 return fs.readFileSync('tmp/gdocs.auth');
136 }
137
138 function request(method, url, options, response) {
139 var url = url.match(/http(s?):\/\/(.+?)(\/.*)/);
140 var request = (url[1] ? https : http).request({
141 host: url[2],
142 port: (url[1] ? 443 : 80),
143 path: url[3],
144 method: method
145 }, function(res){
146 var data = [];
147 res.setEncoding('utf8');
148 res.on('end', function(){
149 response(data.join(''));
150 });
151 res.on('data', function (chunk) {
152 data.push(chunk);
153 });
154 });
155 for(var header in options.headers) {
156 request.setHeader(header, options.headers[header]);
157 }
158 if (options.data)
159 request.write(encodeData(options.data));
160 request.on('end', function(){
161 console.log('end');
162 });
163 request.end();
164 }
165
166 function encodeData(obj) {
167 var pairs = [];
168 for(var key in obj) {
169 pairs.push(key + '=' + obj[key]);
170 }
171 return pairs.join('&') + '\n';
172 }
173
174 function askPassword(callback) {
175 var stdin = process.openStdin(),
176 stdio = process.binding("stdio");
177
178 stdio.setRawMode();
179
180 console.log('Enter your password:');
d6e4636 Vojta Jina Couple of missing semi-colons
vojtajina authored
181 var password = "";
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
182 stdin.on("data", function (c) {
183 c = c + "";
184 switch (c) {
185 case "\n": case "\r": case "\u0004":
186 stdio.setRawMode(false);
187 stdin.pause();
188 callback(password);
189 break;
190 case "\u0003":
191 process.exit();
192 break;
193 default:
194 password += c;
195 break;
196 }
197 })
198
199 }
200
201 function reflow(text, margin) {
202 var lines = [];
203 text.split(/\n/).forEach(function(line) {
204 var col = 0;
205 var reflowLine = '';
206 function flush(){
08e3b1e Igor Minar gdocs.js should strip trailing whitespace in imported docs
IgorMinar authored
207 reflowLine = reflowLine.replace(/\s*$/, '');
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
208 lines.push(reflowLine);
209 reflowLine = '';
210 col = 0;
211 }
212 line.replace(/\s*\S*\s*/g, function(chunk){
213 if (col + chunk.length > margin) flush();
214 reflowLine += chunk;
215 col += chunk.length;
216 });
217 flush();
218 });
219 return lines.join('\n');
220 }
Something went wrong with that request. Please try again.