pixl-server-storage 3.2.0 → 3.2.1

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 (2) hide show
  1. package/engines/S3.js +88 -0
  2. package/package.json +1 -1
package/engines/S3.js CHANGED
@@ -2,6 +2,7 @@
2
2
  // Copyright (c) 2015 - 2022 Joseph Huckaby
3
3
  // Released under the MIT License
4
4
 
5
+ var Path = require('path');
5
6
  var Class = require("pixl-class");
6
7
  var Component = require("pixl-server/component");
7
8
  var Tools = require("pixl-tools");
@@ -596,6 +597,93 @@ module.exports = Class.create({
596
597
  } );
597
598
  },
598
599
 
600
+ list: function(opts, callback) {
601
+ // generate list of objects in S3 given prefix
602
+ // this repeatedly calls ListObjectsV2 for lists > 1000
603
+ // opts: { remotePath, filespec, filter }
604
+ // result: { files([{ key, size, mtime }, ...]), total_bytes }
605
+ let self = this;
606
+ let done = false;
607
+ let files = [];
608
+ let total_bytes = 0;
609
+ let num_calls = 0;
610
+ let now = Tools.timeNow(true);
611
+
612
+ if (typeof(opts) == 'string') opts = { remotePath: opts };
613
+ if (!opts.remotePath) opts.remotePath = '';
614
+ if (!opts.filespec) opts.filespec = /.*/;
615
+ if (!opts.filter) opts.filter = function() { return true; };
616
+
617
+ if (opts.older) {
618
+ // convert older to filter func with mtime
619
+ if (typeof(opts.older) == 'string') opts.older = Tools.getSecondsFromText( opts.older );
620
+ opts.filter = function(file) { return file.mtime <= now - opts.older; };
621
+ }
622
+
623
+ let params = Tools.mergeHashes( this.s3Params || {}, opts.params || {} );
624
+ params.Prefix = this.keyPrefix + opts.remotePath;
625
+ params.MaxKeys = 1000;
626
+
627
+ let PREFIX_RE = new RegExp('^' + Tools.escapeRegExp(this.keyPrefix));
628
+
629
+ this.logDebug(8, "Listing S3 files with prefix: " + params.Prefix, opts);
630
+ let tracker = this.perf ? this.perf.begin('s3_list') : null;
631
+
632
+ Tools.async.whilst(
633
+ function() {
634
+ return !done;
635
+ },
636
+ function(callback) {
637
+ self.logDebug(9, "Listing chunk", params);
638
+
639
+ self.s3.send( new S3.ListObjectsV2Command(params) )
640
+ .then( function(data) {
641
+ let items = data.Contents || [];
642
+ for (let idx = 0, len = items.length; idx < len; idx++) {
643
+ let item = items[idx];
644
+ let key = item.Key.replace(PREFIX_RE, '');
645
+ let bytes = item.Size;
646
+ let mtime = item.LastModified.getTime() / 1000;
647
+ let file = { key: key, size: bytes, mtime: mtime };
648
+
649
+ // optional filter and filespec
650
+ if (opts.filter(file) && Path.basename(key).match(opts.filespec)) {
651
+ total_bytes += bytes;
652
+ files.push(file);
653
+ }
654
+ }
655
+
656
+ // check for end of key list
657
+ if (!data.IsTruncated || !items.length) done = true;
658
+ else {
659
+ // advance to next chunk
660
+ params.StartAfter = items[ items.length - 1 ].Key;
661
+ }
662
+
663
+ num_calls++;
664
+ callback();
665
+ } )
666
+ .catch( function(err) {
667
+ callback( err );
668
+ } );
669
+ },
670
+ function(err) {
671
+ if (tracker) tracker.end();
672
+ if (err) return process.nextTick( function() { callback(err, null, null); });
673
+
674
+ self.logDebug(9, "S3 listing complete (" + Tools.commify(files.length) + " objects, " + Tools.getTextFromBytes(total_bytes) + ")", {
675
+ prefix: params.Prefix,
676
+ count: files.length,
677
+ bytes: total_bytes,
678
+ calls: num_calls
679
+ });
680
+
681
+ // break out of promise context
682
+ process.nextTick( function() { callback( null, files, total_bytes ); } );
683
+ }
684
+ ); // whilst
685
+ },
686
+
599
687
  runMaintenance: function(callback) {
600
688
  // run daily maintenance
601
689
  callback();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixl-server-storage",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "A key/value/list storage component for the pixl-server framework.",
5
5
  "author": "Joseph Huckaby <jhuckaby@gmail.com>",
6
6
  "homepage": "https://github.com/jhuckaby/pixl-server-storage",