Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 225 lines (200 sloc) 6.135 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';
d428c99 Replaced double line break with single when text is fetched from Google ...
Di Peng authored
88
89 //this should be a bug in Google Doc API, hence need to remove this once the bug is fixed
90 data = data.replace(/\n\n/g, '\n');
91
91f9efe Igor Minar gdocs.js should store files under docs/content/[collection]/
IgorMinar authored
92 fs.writeFileSync('docs/content/' + collection + '/' + name, reflow(data, 100));
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
93 }
94 );
95 }
96
97 /**
98 * token=$(curl
99 * -s https://www.google.com/accounts/ClientLogin
100 * -d Email=...username...
101 * -d Passwd=...password...
102 * -d accountType=GOOGLE
103 * -d service=writely
104 * -d Gdata-version=3.0 | cut -d "=" -f 2)
105 */
106 function login(username, password){
107 request('POST', 'https://www.google.com/accounts/ClientLogin',
108 {
109 data: {
110 Email: username,
111 Passwd: password,
112 accountType: 'GOOGLE',
113 service: 'writely',
114 'Gdata-version': '3.0'
115 },
116 headers: {
117 'Content-type': 'application/x-www-form-urlencoded'
118 }
119 },
120 function(chunk){
121 var token;
122 chunk.split('\n').forEach(function(line){
123 var parts = line.split('=');
124 if (parts[0] == 'Auth') {
125 token = parts[1];
126 }
127 });
128 if (token) {
129 fs.writeFileSync('tmp/gdocs.auth', token);
130 console.log("logged in, token saved in 'tmp/gdocs.auth'");
131 } else {
132 console.log('failed to log in');
133 }
134 }
135 );
136 }
137
138 function getAuthToken(){
139 return fs.readFileSync('tmp/gdocs.auth');
140 }
141
142 function request(method, url, options, response) {
143 var url = url.match(/http(s?):\/\/(.+?)(\/.*)/);
144 var request = (url[1] ? https : http).request({
145 host: url[2],
146 port: (url[1] ? 443 : 80),
147 path: url[3],
148 method: method
149 }, function(res){
150 var data = [];
151 res.setEncoding('utf8');
152 res.on('end', function(){
153 response(data.join(''));
154 });
155 res.on('data', function (chunk) {
156 data.push(chunk);
157 });
158 });
159 for(var header in options.headers) {
160 request.setHeader(header, options.headers[header]);
161 }
162 if (options.data)
163 request.write(encodeData(options.data));
164 request.on('end', function(){
165 console.log('end');
166 });
167 request.end();
168 }
169
170 function encodeData(obj) {
171 var pairs = [];
172 for(var key in obj) {
173 pairs.push(key + '=' + obj[key]);
174 }
175 return pairs.join('&') + '\n';
176 }
177
178 function askPassword(callback) {
179 var stdin = process.openStdin(),
180 stdio = process.binding("stdio");
181
182 stdio.setRawMode();
183
184 console.log('Enter your password:');
d6e4636 Vojta Jina Couple of missing semi-colons
vojtajina authored
185 var password = "";
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
186 stdin.on("data", function (c) {
187 c = c + "";
188 switch (c) {
189 case "\n": case "\r": case "\u0004":
190 stdio.setRawMode(false);
191 stdin.pause();
192 callback(password);
193 break;
194 case "\u0003":
195 process.exit();
196 break;
197 default:
198 password += c;
199 break;
200 }
201 })
202
203 }
204
205 function reflow(text, margin) {
206 var lines = [];
207 text.split(/\n/).forEach(function(line) {
208 var col = 0;
209 var reflowLine = '';
210 function flush(){
08e3b1e Igor Minar gdocs.js should strip trailing whitespace in imported docs
IgorMinar authored
211 reflowLine = reflowLine.replace(/\s*$/, '');
7a54d27 Miško Hevery script for dowlnoading docs from google docs
mhevery authored
212 lines.push(reflowLine);
213 reflowLine = '';
214 col = 0;
215 }
216 line.replace(/\s*\S*\s*/g, function(chunk){
217 if (col + chunk.length > margin) flush();
218 reflowLine += chunk;
219 col += chunk.length;
220 });
221 flush();
222 });
223 return lines.join('\n');
224 }
Something went wrong with that request. Please try again.