berkshelf-store 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile +5 -0
  4. data/README.md +83 -0
  5. data/Rakefile +44 -0
  6. data/berkshelf-store.gemspec +26 -0
  7. data/bin/berkshelf-store +49 -0
  8. data/lib/berkshelf-store/backends/filesystem.rb +138 -0
  9. data/lib/berkshelf-store/backends.rb +5 -0
  10. data/lib/berkshelf-store/webservice.rb +100 -0
  11. data/lib/berkshelf-store.rb +5 -0
  12. data/test/data/arbo/cookbooks/apache2/1.10.4/data.json +1 -0
  13. data/test/data/arbo/cookbooks/couchbase/1.1.0/data.json +1 -0
  14. data/test/data/arbo/cookbooks/couchbase/1.2.0/data.json +1 -0
  15. data/test/data/catalog.json +69 -0
  16. data/test/data/tarballs/apache2-v1.10.4.tar.gz +0 -0
  17. data/test/data/tarballs/couchbase-v1.1.0.tar.gz +0 -0
  18. data/test/data/tarballs/couchbase-v1.2.0.tar.gz +0 -0
  19. data/test/data/tarballs/not_a_cookbook.tgz +0 -0
  20. data/test/test_berkshelf-store_backends_filesystem.rb +76 -0
  21. data/ui/static/bootstrap/css/bootstrap-theme.css +347 -0
  22. data/ui/static/bootstrap/css/bootstrap-theme.css.map +1 -0
  23. data/ui/static/bootstrap/css/bootstrap-theme.min.css +7 -0
  24. data/ui/static/bootstrap/css/bootstrap.css +5785 -0
  25. data/ui/static/bootstrap/css/bootstrap.css.map +1 -0
  26. data/ui/static/bootstrap/css/bootstrap.min.css +7 -0
  27. data/ui/static/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
  28. data/ui/static/bootstrap/fonts/glyphicons-halflings-regular.svg +229 -0
  29. data/ui/static/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  30. data/ui/static/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
  31. data/ui/static/bootstrap/js/bootstrap.js +1951 -0
  32. data/ui/static/bootstrap/js/bootstrap.min.js +6 -0
  33. data/ui/static/jquery/jquery.min.js +4 -0
  34. data/ui/static/jquery_file_upload/CONTRIBUTING.md +42 -0
  35. data/ui/static/jquery_file_upload/Gruntfile.js +37 -0
  36. data/ui/static/jquery_file_upload/README.md +123 -0
  37. data/ui/static/jquery_file_upload/angularjs.html +211 -0
  38. data/ui/static/jquery_file_upload/basic-plus.html +226 -0
  39. data/ui/static/jquery_file_upload/basic.html +136 -0
  40. data/ui/static/jquery_file_upload/blueimp-file-upload.jquery.json +50 -0
  41. data/ui/static/jquery_file_upload/bower.json +85 -0
  42. data/ui/static/jquery_file_upload/cors/postmessage.html +75 -0
  43. data/ui/static/jquery_file_upload/cors/result.html +24 -0
  44. data/ui/static/jquery_file_upload/css/demo-ie8.css +21 -0
  45. data/ui/static/jquery_file_upload/css/demo.css +67 -0
  46. data/ui/static/jquery_file_upload/css/jquery.fileupload-noscript.css +22 -0
  47. data/ui/static/jquery_file_upload/css/jquery.fileupload-ui-noscript.css +17 -0
  48. data/ui/static/jquery_file_upload/css/jquery.fileupload-ui.css +57 -0
  49. data/ui/static/jquery_file_upload/css/jquery.fileupload.css +36 -0
  50. data/ui/static/jquery_file_upload/css/style.css +15 -0
  51. data/ui/static/jquery_file_upload/img/loading.gif +0 -0
  52. data/ui/static/jquery_file_upload/img/progressbar.gif +0 -0
  53. data/ui/static/jquery_file_upload/index.html +255 -0
  54. data/ui/static/jquery_file_upload/jquery-ui.html +250 -0
  55. data/ui/static/jquery_file_upload/js/app.js +101 -0
  56. data/ui/static/jquery_file_upload/js/cors/jquery.postmessage-transport.js +117 -0
  57. data/ui/static/jquery_file_upload/js/cors/jquery.xdr-transport.js +86 -0
  58. data/ui/static/jquery_file_upload/js/jquery.fileupload-angular.js +429 -0
  59. data/ui/static/jquery_file_upload/js/jquery.fileupload-audio.js +106 -0
  60. data/ui/static/jquery_file_upload/js/jquery.fileupload-image.js +315 -0
  61. data/ui/static/jquery_file_upload/js/jquery.fileupload-jquery-ui.js +152 -0
  62. data/ui/static/jquery_file_upload/js/jquery.fileupload-process.js +172 -0
  63. data/ui/static/jquery_file_upload/js/jquery.fileupload-ui.js +699 -0
  64. data/ui/static/jquery_file_upload/js/jquery.fileupload-validate.js +119 -0
  65. data/ui/static/jquery_file_upload/js/jquery.fileupload-video.js +106 -0
  66. data/ui/static/jquery_file_upload/js/jquery.fileupload.js +1426 -0
  67. data/ui/static/jquery_file_upload/js/jquery.iframe-transport.js +214 -0
  68. data/ui/static/jquery_file_upload/js/main.js +75 -0
  69. data/ui/static/jquery_file_upload/js/vendor/jquery.ui.widget.js +530 -0
  70. data/ui/static/jquery_file_upload/package.json +54 -0
  71. data/ui/static/jquery_file_upload/server/gae-go/app/main.go +296 -0
  72. data/ui/static/jquery_file_upload/server/gae-go/app.yaml +12 -0
  73. data/ui/static/jquery_file_upload/server/gae-go/static/favicon.ico +0 -0
  74. data/ui/static/jquery_file_upload/server/gae-go/static/robots.txt +2 -0
  75. data/ui/static/jquery_file_upload/server/gae-python/app.yaml +16 -0
  76. data/ui/static/jquery_file_upload/server/gae-python/main.py +170 -0
  77. data/ui/static/jquery_file_upload/server/gae-python/static/favicon.ico +0 -0
  78. data/ui/static/jquery_file_upload/server/gae-python/static/robots.txt +2 -0
  79. data/ui/static/jquery_file_upload/server/node/package.json +41 -0
  80. data/ui/static/jquery_file_upload/server/node/server.js +292 -0
  81. data/ui/static/jquery_file_upload/server/php/UploadHandler.php +1330 -0
  82. data/ui/static/jquery_file_upload/server/php/index.php +15 -0
  83. data/ui/static/jquery_file_upload/test/index.html +166 -0
  84. data/ui/static/jquery_file_upload/test/test.js +1288 -0
  85. data/ui/views/catalog.erb +20 -0
  86. data/ui/views/doc.erb +23 -0
  87. data/ui/views/layout.erb +47 -0
  88. data/ui/views/upload.erb +46 -0
  89. metadata +210 -0
@@ -0,0 +1,292 @@
1
+ #!/usr/bin/env node
2
+ /*
3
+ * jQuery File Upload Plugin Node.js Example 2.1.1
4
+ * https://github.com/blueimp/jQuery-File-Upload
5
+ *
6
+ * Copyright 2012, Sebastian Tschan
7
+ * https://blueimp.net
8
+ *
9
+ * Licensed under the MIT license:
10
+ * http://www.opensource.org/licenses/MIT
11
+ */
12
+
13
+ /* jshint nomen:false */
14
+ /* global require, __dirname, unescape, console */
15
+
16
+ (function (port) {
17
+ 'use strict';
18
+ var path = require('path'),
19
+ fs = require('fs'),
20
+ // Since Node 0.8, .existsSync() moved from path to fs:
21
+ _existsSync = fs.existsSync || path.existsSync,
22
+ formidable = require('formidable'),
23
+ nodeStatic = require('node-static'),
24
+ imageMagick = require('imagemagick'),
25
+ options = {
26
+ tmpDir: __dirname + '/tmp',
27
+ publicDir: __dirname + '/public',
28
+ uploadDir: __dirname + '/public/files',
29
+ uploadUrl: '/files/',
30
+ maxPostSize: 11000000000, // 11 GB
31
+ minFileSize: 1,
32
+ maxFileSize: 10000000000, // 10 GB
33
+ acceptFileTypes: /.+/i,
34
+ // Files not matched by this regular expression force a download dialog,
35
+ // to prevent executing any scripts in the context of the service domain:
36
+ inlineFileTypes: /\.(gif|jpe?g|png)$/i,
37
+ imageTypes: /\.(gif|jpe?g|png)$/i,
38
+ imageVersions: {
39
+ 'thumbnail': {
40
+ width: 80,
41
+ height: 80
42
+ }
43
+ },
44
+ accessControl: {
45
+ allowOrigin: '*',
46
+ allowMethods: 'OPTIONS, HEAD, GET, POST, PUT, DELETE',
47
+ allowHeaders: 'Content-Type, Content-Range, Content-Disposition'
48
+ },
49
+ /* Uncomment and edit this section to provide the service via HTTPS:
50
+ ssl: {
51
+ key: fs.readFileSync('/Applications/XAMPP/etc/ssl.key/server.key'),
52
+ cert: fs.readFileSync('/Applications/XAMPP/etc/ssl.crt/server.crt')
53
+ },
54
+ */
55
+ nodeStatic: {
56
+ cache: 3600 // seconds to cache served files
57
+ }
58
+ },
59
+ utf8encode = function (str) {
60
+ return unescape(encodeURIComponent(str));
61
+ },
62
+ fileServer = new nodeStatic.Server(options.publicDir, options.nodeStatic),
63
+ nameCountRegexp = /(?:(?: \(([\d]+)\))?(\.[^.]+))?$/,
64
+ nameCountFunc = function (s, index, ext) {
65
+ return ' (' + ((parseInt(index, 10) || 0) + 1) + ')' + (ext || '');
66
+ },
67
+ FileInfo = function (file) {
68
+ this.name = file.name;
69
+ this.size = file.size;
70
+ this.type = file.type;
71
+ this.deleteType = 'DELETE';
72
+ },
73
+ UploadHandler = function (req, res, callback) {
74
+ this.req = req;
75
+ this.res = res;
76
+ this.callback = callback;
77
+ },
78
+ serve = function (req, res) {
79
+ res.setHeader(
80
+ 'Access-Control-Allow-Origin',
81
+ options.accessControl.allowOrigin
82
+ );
83
+ res.setHeader(
84
+ 'Access-Control-Allow-Methods',
85
+ options.accessControl.allowMethods
86
+ );
87
+ res.setHeader(
88
+ 'Access-Control-Allow-Headers',
89
+ options.accessControl.allowHeaders
90
+ );
91
+ var handleResult = function (result, redirect) {
92
+ if (redirect) {
93
+ res.writeHead(302, {
94
+ 'Location': redirect.replace(
95
+ /%s/,
96
+ encodeURIComponent(JSON.stringify(result))
97
+ )
98
+ });
99
+ res.end();
100
+ } else {
101
+ res.writeHead(200, {
102
+ 'Content-Type': req.headers.accept
103
+ .indexOf('application/json') !== -1 ?
104
+ 'application/json' : 'text/plain'
105
+ });
106
+ res.end(JSON.stringify(result));
107
+ }
108
+ },
109
+ setNoCacheHeaders = function () {
110
+ res.setHeader('Pragma', 'no-cache');
111
+ res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
112
+ res.setHeader('Content-Disposition', 'inline; filename="files.json"');
113
+ },
114
+ handler = new UploadHandler(req, res, handleResult);
115
+ switch (req.method) {
116
+ case 'OPTIONS':
117
+ res.end();
118
+ break;
119
+ case 'HEAD':
120
+ case 'GET':
121
+ if (req.url === '/') {
122
+ setNoCacheHeaders();
123
+ if (req.method === 'GET') {
124
+ handler.get();
125
+ } else {
126
+ res.end();
127
+ }
128
+ } else {
129
+ fileServer.serve(req, res);
130
+ }
131
+ break;
132
+ case 'POST':
133
+ setNoCacheHeaders();
134
+ handler.post();
135
+ break;
136
+ case 'DELETE':
137
+ handler.destroy();
138
+ break;
139
+ default:
140
+ res.statusCode = 405;
141
+ res.end();
142
+ }
143
+ };
144
+ fileServer.respond = function (pathname, status, _headers, files, stat, req, res, finish) {
145
+ // Prevent browsers from MIME-sniffing the content-type:
146
+ _headers['X-Content-Type-Options'] = 'nosniff';
147
+ if (!options.inlineFileTypes.test(files[0])) {
148
+ // Force a download dialog for unsafe file extensions:
149
+ _headers['Content-Type'] = 'application/octet-stream';
150
+ _headers['Content-Disposition'] = 'attachment; filename="' +
151
+ utf8encode(path.basename(files[0])) + '"';
152
+ }
153
+ nodeStatic.Server.prototype.respond
154
+ .call(this, pathname, status, _headers, files, stat, req, res, finish);
155
+ };
156
+ FileInfo.prototype.validate = function () {
157
+ if (options.minFileSize && options.minFileSize > this.size) {
158
+ this.error = 'File is too small';
159
+ } else if (options.maxFileSize && options.maxFileSize < this.size) {
160
+ this.error = 'File is too big';
161
+ } else if (!options.acceptFileTypes.test(this.name)) {
162
+ this.error = 'Filetype not allowed';
163
+ }
164
+ return !this.error;
165
+ };
166
+ FileInfo.prototype.safeName = function () {
167
+ // Prevent directory traversal and creating hidden system files:
168
+ this.name = path.basename(this.name).replace(/^\.+/, '');
169
+ // Prevent overwriting existing files:
170
+ while (_existsSync(options.uploadDir + '/' + this.name)) {
171
+ this.name = this.name.replace(nameCountRegexp, nameCountFunc);
172
+ }
173
+ };
174
+ FileInfo.prototype.initUrls = function (req) {
175
+ if (!this.error) {
176
+ var that = this,
177
+ baseUrl = (options.ssl ? 'https:' : 'http:') +
178
+ '//' + req.headers.host + options.uploadUrl;
179
+ this.url = this.deleteUrl = baseUrl + encodeURIComponent(this.name);
180
+ Object.keys(options.imageVersions).forEach(function (version) {
181
+ if (_existsSync(
182
+ options.uploadDir + '/' + version + '/' + that.name
183
+ )) {
184
+ that[version + 'Url'] = baseUrl + version + '/' +
185
+ encodeURIComponent(that.name);
186
+ }
187
+ });
188
+ }
189
+ };
190
+ UploadHandler.prototype.get = function () {
191
+ var handler = this,
192
+ files = [];
193
+ fs.readdir(options.uploadDir, function (err, list) {
194
+ list.forEach(function (name) {
195
+ var stats = fs.statSync(options.uploadDir + '/' + name),
196
+ fileInfo;
197
+ if (stats.isFile() && name[0] !== '.') {
198
+ fileInfo = new FileInfo({
199
+ name: name,
200
+ size: stats.size
201
+ });
202
+ fileInfo.initUrls(handler.req);
203
+ files.push(fileInfo);
204
+ }
205
+ });
206
+ handler.callback({files: files});
207
+ });
208
+ };
209
+ UploadHandler.prototype.post = function () {
210
+ var handler = this,
211
+ form = new formidable.IncomingForm(),
212
+ tmpFiles = [],
213
+ files = [],
214
+ map = {},
215
+ counter = 1,
216
+ redirect,
217
+ finish = function () {
218
+ counter -= 1;
219
+ if (!counter) {
220
+ files.forEach(function (fileInfo) {
221
+ fileInfo.initUrls(handler.req);
222
+ });
223
+ handler.callback({files: files}, redirect);
224
+ }
225
+ };
226
+ form.uploadDir = options.tmpDir;
227
+ form.on('fileBegin', function (name, file) {
228
+ tmpFiles.push(file.path);
229
+ var fileInfo = new FileInfo(file, handler.req, true);
230
+ fileInfo.safeName();
231
+ map[path.basename(file.path)] = fileInfo;
232
+ files.push(fileInfo);
233
+ }).on('field', function (name, value) {
234
+ if (name === 'redirect') {
235
+ redirect = value;
236
+ }
237
+ }).on('file', function (name, file) {
238
+ var fileInfo = map[path.basename(file.path)];
239
+ fileInfo.size = file.size;
240
+ if (!fileInfo.validate()) {
241
+ fs.unlink(file.path);
242
+ return;
243
+ }
244
+ fs.renameSync(file.path, options.uploadDir + '/' + fileInfo.name);
245
+ if (options.imageTypes.test(fileInfo.name)) {
246
+ Object.keys(options.imageVersions).forEach(function (version) {
247
+ counter += 1;
248
+ var opts = options.imageVersions[version];
249
+ imageMagick.resize({
250
+ width: opts.width,
251
+ height: opts.height,
252
+ srcPath: options.uploadDir + '/' + fileInfo.name,
253
+ dstPath: options.uploadDir + '/' + version + '/' +
254
+ fileInfo.name
255
+ }, finish);
256
+ });
257
+ }
258
+ }).on('aborted', function () {
259
+ tmpFiles.forEach(function (file) {
260
+ fs.unlink(file);
261
+ });
262
+ }).on('error', function (e) {
263
+ console.log(e);
264
+ }).on('progress', function (bytesReceived) {
265
+ if (bytesReceived > options.maxPostSize) {
266
+ handler.req.connection.destroy();
267
+ }
268
+ }).on('end', finish).parse(handler.req);
269
+ };
270
+ UploadHandler.prototype.destroy = function () {
271
+ var handler = this,
272
+ fileName;
273
+ if (handler.req.url.slice(0, options.uploadUrl.length) === options.uploadUrl) {
274
+ fileName = path.basename(decodeURIComponent(handler.req.url));
275
+ if (fileName[0] !== '.') {
276
+ fs.unlink(options.uploadDir + '/' + fileName, function (ex) {
277
+ Object.keys(options.imageVersions).forEach(function (version) {
278
+ fs.unlink(options.uploadDir + '/' + version + '/' + fileName);
279
+ });
280
+ handler.callback({success: !ex});
281
+ });
282
+ return;
283
+ }
284
+ }
285
+ handler.callback({success: false});
286
+ };
287
+ if (options.ssl) {
288
+ require('https').createServer(options.ssl, serve).listen(port);
289
+ } else {
290
+ require('http').createServer(serve).listen(port);
291
+ }
292
+ }(8888));