hfs 0.1.6 → 0.26.2

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 (91) hide show
  1. package/LICENSE.txt +674 -0
  2. package/README.md +102 -8
  3. package/admin/assets/index.dcc78777.css +1 -0
  4. package/admin/assets/index.f056db34.js +282 -0
  5. package/admin/assets/sha512.3c0e384c.js +8 -0
  6. package/admin/index.html +17 -0
  7. package/admin/logo.svg +36 -0
  8. package/frontend/assets/index.55c710c2.js +85 -0
  9. package/frontend/assets/index.ee805a6c.css +1 -0
  10. package/frontend/assets/sha512.634b743e.js +8 -0
  11. package/frontend/fontello.css +77 -0
  12. package/frontend/fontello.woff2 +0 -0
  13. package/frontend/index.html +18 -0
  14. package/package.json +93 -28
  15. package/plugins/antibrute/plugin.js +38 -0
  16. package/plugins/download-counter/plugin.js +47 -0
  17. package/plugins/download-counter/public/hits.js +5 -0
  18. package/plugins/updater-disabled/plugin.js +44 -0
  19. package/plugins/vhosting/plugin.js +42 -0
  20. package/src/QuickZipStream.js +285 -0
  21. package/src/ThrottledStream.js +93 -0
  22. package/src/adminApis.js +169 -0
  23. package/src/api.accounts.js +59 -0
  24. package/src/api.auth.js +130 -0
  25. package/src/api.file_list.js +103 -0
  26. package/src/api.helpers.js +32 -0
  27. package/src/api.monitor.js +102 -0
  28. package/src/api.plugins.js +125 -0
  29. package/src/api.vfs.js +164 -0
  30. package/src/apiMiddleware.js +136 -0
  31. package/src/block.js +33 -0
  32. package/src/commands.js +105 -0
  33. package/src/config.js +172 -0
  34. package/src/connections.js +57 -0
  35. package/src/const.js +83 -0
  36. package/src/crypt.js +21 -0
  37. package/src/debounceAsync.js +48 -0
  38. package/src/events.js +9 -0
  39. package/src/frontEndApis.js +38 -0
  40. package/src/github.js +102 -0
  41. package/src/index.js +53 -0
  42. package/src/listen.js +226 -0
  43. package/src/log.js +137 -0
  44. package/src/middlewares.js +154 -0
  45. package/src/misc.js +160 -0
  46. package/src/pbkdf2.js +74 -0
  47. package/src/perm.js +176 -0
  48. package/src/plugins.js +338 -0
  49. package/src/serveFile.js +104 -0
  50. package/src/serveGuiFiles.js +113 -0
  51. package/src/sse.js +29 -0
  52. package/src/throttler.js +91 -0
  53. package/src/update.js +69 -0
  54. package/src/util-files.js +141 -0
  55. package/src/util-generators.js +30 -0
  56. package/src/util-http.js +30 -0
  57. package/src/vfs.js +227 -0
  58. package/src/watchLoad.js +73 -0
  59. package/src/zip.js +69 -0
  60. package/.npmignore +0 -19
  61. package/admin-server.js +0 -212
  62. package/cli.js +0 -33
  63. package/file-server.js +0 -100
  64. package/lib/common.js +0 -10
  65. package/lib/extending.js +0 -158
  66. package/lib/mime.js +0 -19
  67. package/lib/misc.js +0 -75
  68. package/lib/serving.js +0 -81
  69. package/lib/vfs.js +0 -403
  70. package/main.js +0 -24
  71. package/note.txt +0 -104
  72. package/speedtest.js +0 -21
  73. package/static/backend.css +0 -14
  74. package/static/backend.html +0 -32
  75. package/static/backend.js +0 -694
  76. package/static/extending.js +0 -187
  77. package/static/frontend.css +0 -29
  78. package/static/frontend.html +0 -23
  79. package/static/frontend.js +0 -230
  80. package/static/icons/files/archive.png +0 -0
  81. package/static/icons/files/audio.png +0 -0
  82. package/static/icons/files/file.png +0 -0
  83. package/static/icons/files/folder.png +0 -0
  84. package/static/icons/files/image.png +0 -0
  85. package/static/icons/files/link.png +0 -0
  86. package/static/icons/files/video.png +0 -0
  87. package/static/jquery.js +0 -4
  88. package/static/jquery.rule-1.0.2.js +0 -273
  89. package/static/misc.js +0 -194
  90. package/static/tpl.js +0 -17
  91. package/todo.txt +0 -25
@@ -1,187 +0,0 @@
1
- ///////// EXTENDING FUNCTION
2
-
3
- /** as function.bind(), but additional parameters are prepended instead of appended
4
- * @return {function} proxied function
5
- */
6
- Function.prototype.prebind = function(){
7
- var args = Array.prototype.slice.call(arguments);
8
- var scope = args.shift();
9
- var fun = this;
10
- return function(){
11
- var moreArgs = Array.prototype.slice.call(arguments);
12
- fun.apply(scope, moreArgs.concat(args));
13
- };
14
- };
15
-
16
- if (!Function.prototype.bind)
17
- Function.prototype.bind = function(){
18
- var args = Array.prototype.slice.call(arguments);
19
- var scope = args.shift();
20
- var fun = this;
21
- return function(){
22
- var moreArgs = Array.prototype.slice.call(arguments);
23
- fun.apply(scope, args.concat(moreArgs));
24
- };
25
- };
26
-
27
- ///////// EXTENDING STRING
28
-
29
- /* return a new string filling "this" with arguments' values.
30
- The filling is done in place of strings in this form {key} or this other form {key|parameter}.
31
- If first argument is an object, then "key" is used as field name (i.e. property) of the object.
32
- Otherwise "key" should be a number, and it's the argument's index (zero-based).
33
- As stated before, keys can have a parameter. If such parameter is in the form \d*-\d* then these numbers
34
- denote a range of characters to extract (i.e. a substring). Otherwise the parameter is a property name for
35
- the value (that must be an object or an array in this case).
36
- */
37
- String.prototype.format = function() {
38
- var args = arguments;
39
- if (typeof args[0] == 'object')
40
- args = args[0];
41
- return this.replace(/\{([-_ a-z0-9]+)(\|([^}]+))?\}/gi, function(){
42
- var ret = args[arguments[1]];
43
- var par = arguments[3];
44
- if (par) {
45
- var v = /(\d*)-(\d*)/.exec(par); // is it in the "range" form?
46
- if (v) ret = ret.substring(v[1]-1 || 0, v[2] || ret.length); // extract the substring in range
47
- else ret = ret[par]; // get property
48
- }
49
- return ret;
50
- });
51
- };
52
-
53
- String.prototype.repeat = function(n) {
54
- var r = '';
55
- for (var i=0; i<n; i++) r += this;
56
- return r;
57
- };
58
-
59
- String.prototype.count = function(sub) {
60
- return this.split(sub).length-1;
61
- };
62
-
63
- String.prototype.ss = function(from, to) {
64
- return this.substring(from<0 ? this.length-from : from, to<0 ? this.length+to : to);
65
- };
66
-
67
- String.prototype.pad = function(lngt, filler) {
68
- return (filler || ' ').repeat(Math.max(0,lngt - this.length)) + this;
69
- };
70
-
71
- String.prototype.escapeRegExp = function() {
72
- return this.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
73
- };
74
-
75
- String.prototype.startsBy = function(sub, caseInsensitive) {
76
- return 0 <= this.search(new RegExp('^'+sub.escapeRegExp(), caseInsensitive ? 'i' : ''));
77
- };
78
-
79
- String.prototype.endsBy = function(sub, caseInsensitive) {
80
- return 0 <= this.search(new RegExp(sub.escapeRegExp()+'$', caseInsensitive ? 'i' : ''));
81
- };
82
-
83
- String.prototype.includeLeading = function(sub) { return this.startsBy(sub) ? this : sub+this };
84
- String.prototype.includeTrailing = function(sub) { return this.endsBy(sub) ? this : this+sub };
85
- // if in the following function the casting to string is not made, the resulting typeof is 'object' instead of 'string' (causing problems in some cases, e.g. using path.join)
86
- String.prototype.excludeLeading = function(sub) { return this.startsBy(sub) ? this.slice(sub.length) : ''+this };
87
- String.prototype.excludeTrailing = function(sub) { return this.endsBy(sub) ? this.slice(0,-sub.length) : ''+this };
88
-
89
- // handy shortcuts
90
- String.prototype.low = String.prototype.toLowerCase;
91
- String.prototype.up = String.prototype.toUpperCase;
92
-
93
- // case insensitive test
94
- String.prototype.same = function(s){
95
- var threshold = 10;
96
- return typeof s === 'string'
97
- && this.length === s.length
98
- && this.substr(0,threshold).low() === s.substr(0,threshold).low()
99
- && this.substr(threshold).low() === s.substr(threshold).low()
100
- }; // String.same
101
-
102
- String.prototype.in = function(s) {
103
- switch (typeof s) {
104
- case 'array':
105
- case 'string': return s.indexOf(this) >= 0;
106
- default: return false;
107
- }
108
- }; // String.in
109
-
110
- ///////// EXTENDING ARRAY
111
-
112
- if (!Array.prototype.forEach)
113
- Array.prototype.forEach = function(fun) {
114
- if (typeof fun != "function")
115
- throw new TypeError();
116
- for (var i=0, l=this.length; i<l; ++i) {
117
- fun.call(this[i], this[i], i, this);
118
- }
119
- }; // Array.forEach
120
-
121
- if (!Array.prototype.some)
122
- Array.prototype.some = function(cb) {
123
- for (var i=0, l=this.length; i<l; ++i) {
124
- if (cb ? cb(this[i]) : this[i]) {
125
- return true;
126
- }
127
- }
128
- return false;
129
- }; // Array.some
130
-
131
- ///////// EXTENDING OBJECT
132
-
133
- function extendObject(key, value) {
134
- Object.defineProperty(Object.prototype, key, {
135
- enumerable: false,
136
- value: value
137
- });
138
- } // extendObject
139
-
140
- extendObject('getKeyOf', function(value) {
141
- for (var i in this)
142
- if (this.hasOwnProperty(i)
143
- && this[i] === value)
144
- return i;
145
- return null;
146
- }); // Object.getKeyOf
147
-
148
- extendObject('forEach', function(cb) {
149
- for (var i in this)
150
- if (this.hasOwnProperty(i))
151
- cb(this[i], i);
152
- }); // Object.forEach
153
-
154
- extendObject('isIn', function(vals) {
155
- if (arguments.length == 1) {
156
- return Array.isArray(vals)
157
- ? vals.indexOf(this) >= 0
158
- : vals.keyOf(this) !== null;
159
- }
160
- for (var i in arguments)
161
- if (arguments[i] == this)
162
- return true;
163
- return false;
164
- }); // Object.isIn
165
-
166
- extendObject('extend', function(from) {
167
- var props = Object.getOwnPropertyNames(from);
168
- var dest = this;
169
- props.forEach(function(name) {
170
- if (name in dest) {
171
- var destination = Object.getOwnPropertyDescriptor(from, name);
172
- Object.defineProperty(dest, name, destination);
173
- }
174
- else {
175
- dest[name] = from[name];
176
- }
177
- });
178
- return this;
179
- }); // Object.extend
180
-
181
- extendObject('getProperties', function(){
182
- var res = [];
183
- for (var i in this)
184
- if (this.hasOwnProperty(i))
185
- res.push(this[i]);
186
- return res;
187
- }); // Object.getProperties
@@ -1,29 +0,0 @@
1
- body { font:10pt verdana, arial, sans-serif; }
2
- a img { border:0; } /* conform IE */
3
- #items { list-style:none; padding:0; }
4
- .full-label { position:absolute; padding-right:1em; text-align:left; }
5
-
6
- /* tiles */
7
- [mode=tiles] .item-link { float:left; width:9em; height:9em; overflow:hidden;
8
- text-align:center; text-decoration:none;
9
- margin:1px; /* reserve space for the border on hover */
10
- }
11
- [mode=tiles] .item-link:hover { background:#eee;
12
- border:1px solid #ccc; margin:0; /* replace margin with border */
13
- }
14
- [mode=tiles] .item-label { display:block; padding:0 0.5em; margin:3px; word-wrap:break-word; }
15
- [mode=tiles] .item-details { display:none; }
16
- [mode=tiles] .item-link:hover + .item-details { display:block; float:left; }
17
- [mode=tiles] .item-details-wrapper { position:absolute; background:#ffe; border:1px solid #eec; padding:0.2em 0.4em; }
18
- [mode=tiles] .full-label { max-width:17em; }
19
-
20
- /* list */
21
- [mode=list] li { border-bottom:1px solid #eee; height:1.5em; }
22
- [mode=list] li:nth-of-type(odd) { background:#fafafa; } /* stripes */
23
- [mode=list] .item-link { clear:left; float:left; text-decoration:none;
24
- width:20em; height:1.5em; overflow:hidden; margin-right:1em;
25
- }
26
- [mode=list] .item-link img { height:1.5em; vertical-align:middle; float:left; }
27
- [mode=list] .item-label { margin-left:0.5em; margin-right:1em; white-space:nowrap; }
28
- [mode=list] .item-type { display:none; }
29
- [mode=list] .item-size { display:inline; }
@@ -1,23 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>HFS 3 front end</title>
6
- <link rel="stylesheet" type="text/css" href="/~/frontend.css" />
7
-
8
- <!--[if lt IE 9 ]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]-->
9
- <script src='/socket.io/socket.io.js'></script>
10
- <script src='/~/jquery.js'></script>
11
- <script src='/~/extending.js'></script>
12
- <script src='/~/misc.js'></script>
13
- <script src='/~/frontend.js'></script>
14
- <script src='/~/tpl.js'></script>
15
- </head>
16
- <body>
17
- <h2>Folder <span id='folder'></span></h2>
18
- <div id='folder-info'></div>
19
- View mode <select id='mode'><option>tiles<option>list</select>
20
- <p>Order <select id='order'><option value='' selected>none<option value='label'>name<option>type<option>size</select>
21
- <ul id='items'></ul>
22
- </body>
23
- </html>
@@ -1,230 +0,0 @@
1
- var socket = io.connect(window.location.origin);
2
- var currentFolder, listFromServer, foldersBefore=1;
3
-
4
- // this object will hold all the customizable stuff, that is added in file "tpl.js"
5
- var TPL = function(event) {
6
- var fun = TPL[currentMode+'_'+event] || TPL[event];
7
- if (!fun) return;
8
- var newArgs = [];
9
- for (var i=1,a=arguments,l=a.length; i<l; ++i)
10
- newArgs.push(a[i]);
11
- fun.apply(this, newArgs);
12
- };
13
-
14
- // understand the requested folder from the URL
15
- function getURLfolder() {
16
- var sub = location.hash.substr(1);
17
- return sub.startsBy('/') ? sub : location.pathname+sub;
18
- } // getURLfolder
19
-
20
- $(function onJQ(){ // dom ready
21
- socket.on('connect', function onIO(){ // socket ready
22
- // try to restore last options
23
- updateOrder(getCookie('order'));
24
- updateMode(getCookie('mode'));
25
- // change things at user will
26
- $('#order').change(function(){ updateOrder(); redrawItems(); });
27
- $('#mode').change(function(){ updateMode(); redrawItems(); });
28
-
29
- loadFolder(getURLfolder(), function onFolder(){ // folder ready
30
-
31
- /* support for the BACK button: when the user clicks the BACK button, the address bar changes going out of
32
- sync with the view. We fix it ASAP. I don't know an event for the address bar, so i'm using an setInterval. */
33
- setInterval(function onBackSupport(){
34
- var shouldBe = getURLfolder();
35
- if (currentFolder != shouldBe) {
36
- loadFolder(shouldBe);
37
- }
38
- }, 300);
39
-
40
- }); // don't redraw
41
- });//socket connect
42
-
43
- socket.on('vfs.changed', function(data){
44
- log(data);
45
- // it would be nicer to update only the changed item, but for now easily reload the whole dir
46
- var folder = data.uri.substr(0, data.uri.lastIndexOf('/', data.uri.length-2)+1);
47
- if (folder === currentFolder) {
48
- loadFolder();
49
- }
50
- });
51
-
52
- // item hovering
53
- $('.item-link').live({
54
- mouseenter: function(){
55
- if (!$(this).isOverflowed()) return; // fine!
56
- // our label is clipped
57
- var lbl = $(this).find('.item-label');
58
- // make some changes so it's hopefully fully visible
59
- lbl.addClass('full-label');
60
- // if no bg was assigned, the enlarged label may overlap other elements, and its transparency may cause very bad readability
61
- if (isTransparent(lbl.css('background-color'))) {
62
- lbl.css('background-color', lbl.getClosestBackgroundColor() || '#fff')
63
- .data('remove bg', true);
64
- }
65
- },
66
- mouseleave: function(){
67
- // undo changes made few lines above
68
- var lbl = $(this).find('.full-label');
69
- lbl.removeClass('full-label');
70
- if (lbl.data('remove bg')) {
71
- lbl.css('background-color','');
72
- lbl.removeData('remove bg',null);
73
- }
74
- },
75
- });//live
76
-
77
- });//dom ready
78
-
79
- // ask the server for the items list of the specified folder, then sort and display
80
- function loadFolder(path /** optional */, cb /** optional */) {
81
- if (path) currentFolder = path;
82
- $('#folder').text(currentFolder);
83
- socket.emit('get list', { path:currentFolder }, function onGetList(reply){
84
- listFromServer = reply; // hold it in a global variable, to not loose it
85
- convertList(reply);
86
- $('#folder-info').html("number of items: "+reply.items.length);
87
- sortItems();
88
- redrawItems();
89
- if (typeof cb == 'function') {
90
- cb();
91
- }
92
- });
93
- } // loadFolder
94
-
95
- // convert the data: from object to array, so it can be sorted, and expands some field-names
96
- function convertList(serverReply) {
97
- var a = serverReply.items;
98
- var clientFormat = [];
99
- for (var k in a) {
100
- var o = a[k];
101
- renameProperties(o, {t:'type', s:'size'});
102
- o.label = k;
103
- switch (o.type) {
104
- case undefined: // no type is default type: file
105
- o.type = 'file';
106
- case 'file': // for files, calculate specific type
107
- o.type = nameToType(k) || o.type;
108
- break;
109
- case 'link':
110
- o.url = o.resource;
111
- break;
112
- }
113
- o.url = o.url || encodeURI(currentFolder)+encodeURI(k)+(o.type == 'folder' ? '/' : '');
114
-
115
- clientFormat.push(o);
116
- }
117
- serverReply.items = clientFormat;
118
- } // convertList
119
-
120
- // takes an object and renames some of its properties to the mapped names
121
- function renameProperties(o, map) {
122
- for (var from in map) {
123
- var to = map[from];
124
- if (!(from in o)) continue;
125
- o[to] = o[from];
126
- delete o[from];
127
- }
128
- } // renameProperties
129
-
130
- // rebuild the DOM of items
131
- function redrawItems() {
132
- var x = $('#items').empty();
133
-
134
- if (!listFromServer) return;
135
-
136
- // add a link to the parent folder
137
- var cf = currentFolder; // shortcut
138
- if (cf > '/') {
139
- addItem({
140
- label: '&uarr;&uarr;',
141
- url: cf.substr(0, 1+cf.lastIndexOf('/',cf.length-2)),
142
- type: 'folder',
143
- icon: 'folder'
144
- });
145
- }
146
-
147
- // put all the items. We don't support pagination yet
148
- for (var i=0, a=listFromServer.items, l=a.length; i<l; ++i) {
149
- var o = $.extend({}, a[i]); // clone. The item will be manipulated (also inside addItem), and we don't want to make this changes persistant over changes of the view mode
150
- o.icon = o.type;
151
- addItem(o);
152
- }
153
- } // redrawItems
154
-
155
- // build the DOM for the single item, applying possible filtering functions
156
- function addItem(it) {
157
- it.extend({'icon-file':getIconURI(it.icon)}); // make this additions before the hook, so it can change these too
158
- TPL('onObjectItem', it); // custom treatment, especially mode-based
159
- $('<li>').append(TPL.item.format(it))
160
- .appendTo('#items')
161
- .find('a.item-link').click(itemClickHandler);
162
- } // addItem
163
-
164
- // called when an item is clicked
165
- function itemClickHandler() {
166
- var x = $(this);
167
- var h = x.attr('href');
168
- if (h.substr(-1) == '/') {
169
- if (location.pathname != '/') { // reloads the page to have a neater URL
170
- location = '/#'+h.substr(1);
171
- return false;
172
- }
173
-
174
- location.hash = (h.startsBy(location.pathname)) ? h.substr(location.pathname.length) : h;
175
- loadFolder(h);
176
- return false;
177
- }
178
- if (!x.attr('target')) {
179
- x.attr('target', 'preview'); // open the file in a new window so the app doesn't stop
180
- }
181
- return true;
182
- } // itemClickHandler
183
-
184
- function updateMode(v){
185
- // if no value is passed, then read it from the DOM, otherwise write it in the DOM
186
- if (!v || !v.length) v = $('#mode').val();
187
- else $('#mode').val(v);
188
-
189
- currentMode = v; // global
190
- setCookie('mode', v); // remember
191
- $('body').attr('mode', v);
192
- } // updateMode
193
-
194
- function updateOrder(v) {
195
- // if no value is passed, then read it from the DOM, otherwise write it in the DOM
196
- if (!v || !v.length) v = $('#order').val();
197
- else $('#order').val(v);
198
-
199
- currentOrder = v; // global
200
- setCookie('order', v); // remember
201
- if (v) {
202
- $('#order option[value=]').remove(); // after we have sorted the items there's no way to return to the original order, so let's hide this option
203
- }
204
- sortItems();
205
- } // updateOrder
206
-
207
- function sortItems() {
208
- if (!currentOrder || !listFromServer) return; // no job
209
-
210
- listFromServer.items.sort(function cb(a,b,field){
211
- field = field || currentOrder;
212
- if (field != 'type' && foldersBefore) { // if field is 'type', then the folders are always put at the top
213
- var res = -cmp(a['type'] == 'folder', b['type'] == 'folder');
214
- if (res) return res;
215
- }
216
- var va = a[field];
217
- var vb = b[field];
218
- switch (field) {
219
- case 'label':
220
- va=va.low(), vb=vb.low();
221
- break;
222
- case 'type':
223
- if (va == 'folder') va=''; // trick to get folders at the top
224
- if (vb == 'folder') vb='';
225
- break;
226
- }
227
- return cmp(va,vb) || (field=='label' ? 0 : cb(a,b,'label'));
228
- });
229
- } // sortItems
230
-
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file