add in support to filter what files can be synced to the cloud. (and will auto clean cloud files if filters later remove them)
| | |
| | | }, |
| | | // Getting list of entities |
| | | getLocalSet: function(mount, callback) { |
| | | var entries = {}; |
| | | |
| | | function isRealDir(p) { |
| | | return p !== '.' && p !== '..'; |
| | | }; |
| | | function toAbsolute(root) { |
| | | return function(p) { |
| | | return PATH.join2(root, p); |
| | | }; |
| | | }; |
| | | function checkPath(path) { |
| | | for (var i = 0, l = mount.opts.filters.length; i < l; ++i) { |
| | | var f = mount.opts.filters[i]; |
| | | if (typeof f == 'string') { |
| | | if (path.lastIndexOf(f, 0) == 0) { |
| | | return true; |
| | | } |
| | | } if (typeof f == 'function') { |
| | | if (f(path)) { |
| | | return true; |
| | | } |
| | | } if (f instanceof RegExp) { |
| | | if (f.test(path)) { |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | }; |
| | | |
| | | var check = FS.readdir(mount.mountpoint).filter(isRealDir); |
| | | var entries = {}, |
| | | shouldFilter = false, |
| | | check = FS.readdir(mount.mountpoint).filter(isRealDir); |
| | | |
| | | if (mount.opts.filters) { |
| | | shouldFilter = true; |
| | | } |
| | | |
| | | while (check.length) { |
| | | var path = check.pop(); |
| | | var stat; |
| | | var abs_path = PATH.join2(mount.mountpoint, path); |
| | | var path = check.pop(), |
| | | stat, |
| | | keep = true, |
| | | abs_path = PATH.join2(mount.mountpoint, path); |
| | | |
| | | try { |
| | | stat = FS.stat(abs_path); |
| | |
| | | |
| | | if (FS.isDir(stat.mode)) { |
| | | check.push.apply(check, FS.readdir(abs_path).filter(isRealDir).map(toAbsolute(path))); |
| | | } else if (shouldFilter) { |
| | | keep = checkPath(path); |
| | | } |
| | | |
| | | entries[abs_path] = { |
| | | timestamp: stat.mtime, |
| | | path: path |
| | | }; |
| | | if (keep) { |
| | | entries[abs_path] = { |
| | | timestamp: stat.mtime, |
| | | path: path |
| | | }; |
| | | } |
| | | } |
| | | |
| | | return callback(null, { type: 'local', entries: entries }); |
| | |
| | | var stat = FS.stat(path); |
| | | |
| | | if (FS.isDir(stat.mode)) { |
| | | FS.rmdir(path); |
| | | try { |
| | | FS.rmdir(path); |
| | | } catch(e) { |
| | | // it's ok if we can't remove the local folder.. it could be filtered files are in there |
| | | } |
| | | } else if (FS.isFile(stat.mode)) { |
| | | FS.unlink(path); |
| | | } |
| | |
| | | // If the provider isn't available then fallback to using IDBFS |
| | | if (CLOUDFS.validateProvider(provider_name)) { |
| | | FS.mount(CLOUDFS, { |
| | | // a list of regexes or string prefixes to synchronize |
| | | sync: [ |
| | | // a list of regexes, string prefixes, or functions for filtering what should be synced to the cloud |
| | | filters: [ |
| | | 'path/', // include paths that begin with this prefix |
| | | /\.sav/, // include files that end in sav |
| | | function(path) { // custom function to match |
| | | return path == 'config.ini'; |
| | | } |
| | | ], |
| | | // which provider engine to use.. Looks for a provider in the CLOUD_PROVIDERS object |
| | | provider: provider_name, |
| | |
| | | } |
| | | function populate_user_data() |
| | | { |
| | | FS.createPath('/user_data', 'test/two', true, true); |
| | | FS.writeFile('/user_data/test.txt', 'This is a test'); |
| | | FS.writeFile('/user_data/test/file2.txt', 'This is another test'); |
| | | FS.writeFile('/user_data/test/two/file3.txt', 'This is another test'); |
| | | FS.createPath('/user_data', 'path', true, true); |
| | | FS.writeFile('/user_data/path/myfile.ini', '[myfile]'); |
| | | FS.createPath('/user_data', 'ignored', true, true); |
| | | FS.writeFile('/user_data/ignored/test.txt', 'ignored text file'); |
| | | FS.writeFile('/user_data/ignored/test.sav', 'Test save file'); |
| | | FS.writeFile('/user_data/config.ini', '[config]'); |
| | | } |
| | | </script> |
| | | <script async type="text/javascript" src="TestApp.js"></script> |