1 | //- JavaScript source code
|
2 |
|
3 | //- katamari.js ~~
|
4 | //
|
5 | // This is adapted from a previously unpublished NPM module I wrote.
|
6 | //
|
7 | // ~~ (c) SRW, 11 Dec 2012
|
8 | // ~~ last updated 07 Aug 2014
|
9 |
|
10 | (function () {
|
11 | ;
|
12 |
|
13 | // Pragmas
|
14 |
|
15 | /*jshint maxparams: 2, quotmark: single, strict: true */
|
16 |
|
17 | /*jslint indent: 4, maxlen: 80, node: true */
|
18 |
|
19 | /*properties
|
20 | avar, base64, buffer, error, exit, extname, fail, forEach,
|
21 | hasOwnProperty, isDirectory, isFile, join, last_mod_date,
|
22 | last_modified, length, log, lstat, mime_type, normalize, on, Q,
|
23 | readdir, readFile, roll_up, stringify, test, toGMTString, toString,
|
24 | unroll, val, writeFile, '', '.appcache', '.css', '.html', '.ico',
|
25 | '.jpg', '.js', '.json', '.manifest', '.png', '.txt', '.webapp', '.xml'
|
26 | */
|
27 |
|
28 | // Declarations
|
29 |
|
30 | var avar, fs, ignore_patterns, mime_types, path, roll_up, unroll;
|
31 |
|
32 | // Definitions
|
33 |
|
34 | avar = require('quanah').avar;
|
35 |
|
36 | fs = require('fs');
|
37 |
|
38 | ignore_patterns = [
|
39 | /^[.]/
|
40 | ];
|
41 |
|
42 | mime_types = {
|
43 | '': 'text/plain',
|
44 | '.appcache': 'text/cache-manifest',
|
45 | '.css': 'text/css',
|
46 | '.html': 'text/html; charset=utf-8',
|
47 | '.ico': 'image/x-icon',
|
48 | '.jpg': 'image/jpeg',
|
49 | '.js': 'text/javascript',
|
50 | '.json': 'application/json',
|
51 | '.manifest': 'text/cache-manifest',
|
52 | '.png': 'image/png',
|
53 | '.txt': 'text/plain',
|
54 | '.webapp': 'application/x-web-app-manifest+json',
|
55 | '.xml': 'application/xml'
|
56 | };
|
57 |
|
58 | path = require('path');
|
59 |
|
60 | roll_up = function (public_html, json_file) {
|
61 | // This function needs documentation.
|
62 | var dirpath, y;
|
63 | dirpath = path.normalize(public_html);
|
64 | y = avar({val: {}});
|
65 | y.Q(function (evt) {
|
66 | // This function checks to see that the input argument is actually a
|
67 | // directory.
|
68 | fs.lstat(dirpath, function (err, stats) {
|
69 | // This function needs documentation.
|
70 | if (err !== null) {
|
71 | return evt.fail(err);
|
72 | }
|
73 | if (stats.isDirectory() === false) {
|
74 | return evt.fail('"' + dirpath + '" is not a directory.');
|
75 | }
|
76 | return evt.exit();
|
77 | });
|
78 | return;
|
79 | }).Q(function (evt) {
|
80 | // This function reads all files located in the top level of `dirpath`
|
81 | // into memory as the properties of an object.
|
82 | fs.readdir(dirpath, function (err, files) {
|
83 | // This function needs documentation.
|
84 | if (err !== null) {
|
85 | return evt.fail(err);
|
86 | }
|
87 | var count, remaining;
|
88 | count = function () {
|
89 | // This function needs documentation.
|
90 | remaining -= 1;
|
91 | if (remaining === 0) {
|
92 | return evt.exit();
|
93 | }
|
94 | return;
|
95 | };
|
96 | remaining = files.length;
|
97 | files.forEach(function (name) {
|
98 | // This function needs documentation.
|
99 | var flag, filepath, i, n;
|
100 | flag = (name === json_file);
|
101 | n = ignore_patterns.length;
|
102 | for (i = 0; (flag === false) && (i < n); i += 1) {
|
103 | flag = ignore_patterns[i].test(name);
|
104 | }
|
105 | if (flag === true) {
|
106 | return count();
|
107 | }
|
108 | filepath = path.join(dirpath, name);
|
109 | fs.lstat(filepath, function (err, stats) {
|
110 | // This function needs documentation.
|
111 | if (err !== null) {
|
112 | return evt.fail(err);
|
113 | }
|
114 | /*
|
115 | if (stats.isDirectory()) {
|
116 | // Recurse ...
|
117 | roll_up(filepath).Q(function (evt) {
|
118 | // This function isn't working correctly yet ...
|
119 | var key, temp, x;
|
120 | x = this.val;
|
121 | for (key in x) {
|
122 | if (x.hasOwnProperty(key)) {
|
123 | console.log(filepath, '-->', key);
|
124 | temp = path.resolve(filepath, key);
|
125 | y.val[temp] = x[key];
|
126 | }
|
127 | }
|
128 | count();
|
129 | return evt.exit();
|
130 | }).on('error', function (message) {
|
131 | // This function needs documentation.
|
132 | return evt.fail(message);
|
133 | });
|
134 | return;
|
135 | }
|
136 | */
|
137 | if (stats.isFile() === false) {
|
138 | return count();
|
139 | }
|
140 | fs.readFile(filepath, function (err, file) {
|
141 | // This function needs documentation.
|
142 | if (err !== null) {
|
143 | return evt.fail(err);
|
144 | }
|
145 | var temp = {
|
146 | buffer: file,
|
147 | last_modified: (new Date()).toGMTString(),
|
148 | mime_type: mime_types[path.extname(name)]
|
149 | };
|
150 | if (temp.mime_type === undefined) {
|
151 | temp.mime_type = 'application/octet-stream';
|
152 | }
|
153 | y.val['/' + name] = temp;
|
154 | return count();
|
155 | });
|
156 | return;
|
157 | });
|
158 | return;
|
159 | });
|
160 | return;
|
161 | });
|
162 | return;
|
163 | }).Q(function (evt) {
|
164 | // This function writes `y.val` as JSON to `json_file` if the second
|
165 | // input argument was a string.
|
166 | if (typeof json_file !== 'string') {
|
167 | console.log('Not a string.');
|
168 | return evt.exit();
|
169 | }
|
170 | var filepath, key, obj;
|
171 | filepath = path.normalize(json_file);
|
172 | obj = y.val;
|
173 | for (key in obj) {
|
174 | // This function needs documentation.
|
175 | if (obj.hasOwnProperty(key)) {
|
176 | try {
|
177 | obj[key].base64 = obj[key].buffer.toString('base64');
|
178 | delete obj[key].buffer;
|
179 | } catch (err) {
|
180 | console.error(err, key);
|
181 | }
|
182 | }
|
183 | }
|
184 | fs.writeFile(filepath, JSON.stringify(obj), function (err) {
|
185 | // This function needs documentation.
|
186 | if (err !== null) {
|
187 | return evt.fail(err);
|
188 | }
|
189 | console.log('Saved to "' + filepath + '".');
|
190 | return evt.exit();
|
191 | });
|
192 | return;
|
193 | }).on('error', function (message) {
|
194 | // This is a default error handler that can be overwritten.
|
195 | console.error('Error:', message);
|
196 | return;
|
197 | });
|
198 | return y;
|
199 | };
|
200 |
|
201 | unroll = function (filename) {
|
202 | // This function needs documentation.
|
203 | var key, x, y;
|
204 | x = require(filename);
|
205 | y = {};
|
206 | for (key in x) {
|
207 | if (x.hasOwnProperty(key)) {
|
208 | y[key] = {
|
209 | buffer: new Buffer(x[key].base64, 'base64'),
|
210 | last_modified: x[key].last_modified,
|
211 | last_mod_date: new Date(x[key].last_modified),
|
212 | mime_type: x[key].mime_type
|
213 | };
|
214 | }
|
215 | }
|
216 | return y;
|
217 | };
|
218 |
|
219 | // Out-of-scope definitions
|
220 |
|
221 | exports.roll_up = roll_up;
|
222 |
|
223 | exports.unroll = unroll;
|
224 |
|
225 | // That's all, folks!
|
226 |
|
227 | return;
|
228 |
|
229 | }());
|
230 |
|
231 | //- vim:set syntax=javascript:
|