Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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