<commit_before>'use strict';

const EventEmitter = require('events');
const { fork } = require('child_process');
const path = require('path');
const fs = require('fs');

class MotionDetectionModule extends EventEmitter {
  constructor(options) {
    super();
    this.config = Object.assign({
      captureDirectory: null, // Directory to store tmp photos and video captures
      continueAfterMotion: false, // Flag to control if motion detection will continue after detection
      captureVideoOnMotion: false, // Flag to control video capture on motion detection
      continueToCapture: true, // Flag to control internal state of photo capture
    }, options);

    // Verify and create (if needed) capture directories
    captureDirsCheck(this.config.captureDirectory);
  }

  watch() {
    const self = this;
    const imageCaptureChild = fork(path.resolve(__dirname, 'lib', 'ImageCapture.js'), [ path.resolve(self.config.captureDirectory, 'images', '%d.jpg') ]);
    const imageCompareChild = fork(path.resolve(__dirname, 'lib', 'ImageCompare.js'), [ path.resolve(self.config.captureDirectory, 'images') ]);
    const videoCaptureChild = fork(path.resolve(__dirname, 'lib', 'VideoCapture.js'), [ path.resolve(self.config.captureDirectory, 'videos', 'video.h264') ]);
    const videoRenameChild = fork(path.resolve(__dirname, 'lib', 'VideoRename.js'), [ path.resolve(self.config.captureDirectory, 'videos') ]);

    imageCaptureChild.on('message', (message) => {
      if (message.error) {
        self.emit('error', message.error);
      }
      else if (message.response === 'success' && self.config.continueToCapture) {
        imageCaptureChild.send({ cmd: 'capture' });
      }
    });

    imageCompareChild.on('message', (message) => {
      if (message.error) {
        self.emit('error', message.error);
      }
      else if (message.response === 'motion') {
        self.config.continueToCapture = false;
        self.emit('motion');

        if (self.config.captureVideoOnMotion) {
          videoCaptureChild.send({
            cmd: 'capture',
          });
        }
        else {
          self.config.continueToCapture = true;
          imageCaptureChild.send({ cmd: 'capture' });
        }
      }
    });

    videoCaptureChild.on('message', (message) => {
      if (message.error) {
        self.emit('error', message.error);
      }
      else if (message.response === 'success') {
        self.config.continueToCapture = true;
        imageCaptureChild.send({ cmd: 'capture' });
      }
    });

    videoRenameChild.on('message', (message) => {
      if (message.error) {
        self.emit('error', message.error);
      }
    });

    // Start the magic
    imageCaptureChild.send({ cmd: 'capture' });
  }
}

function captureDirsCheck(base) {
  if (!base) {
    throw new Error(`'captureDirectory' can't be null`);
  }

  const dirsToCheck = [ base, path.resolve(base, 'images'), path.resolve(base, 'videos') ];

  dirsToCheck.forEach((dir) => {
    try {
      fs.accessSync(dir);
    }
    catch (e) {
      // Doesn't exist, create it
      fs.mkdirSync(dir);
    }
  });
}

module.exports = MotionDetectionModule;
<commit_msg>Add emptying of captures/images on startup<commit_after>'use strict';

const EventEmitter = require('events');
const { fork } = require('child_process');
const path = require('path');
const fs = require('fs');

class MotionDetectionModule extends EventEmitter {
  constructor(options) {
    super();
    this.config = Object.assign({
      captureDirectory: null, // Directory to store tmp photos and video captures
      continueAfterMotion: false, // Flag to control if motion detection will continue after detection
      captureVideoOnMotion: false, // Flag to control video capture on motion detection
      continueToCapture: true, // Flag to control internal state of photo capture
    }, options);

    // Verify and create (if needed) capture directories
    captureDirsCheck(this.config.captureDirectory);
    emptyImagesDir(path.resolve(this.config.captureDirectory, 'images'));
  }

  watch() {
    const self = this;
    const imageCaptureChild = fork(path.resolve(__dirname, 'lib', 'ImageCapture.js'), [ path.resolve(self.config.captureDirectory, 'images', '%d.jpg') ]);
    const imageCompareChild = fork(path.resolve(__dirname, 'lib', 'ImageCompare.js'), [ path.resolve(self.config.captureDirectory, 'images') ]);
    const videoCaptureChild = fork(path.resolve(__dirname, 'lib', 'VideoCapture.js'), [ path.resolve(self.config.captureDirectory, 'videos', 'video.h264') ]);
    const videoRenameChild = fork(path.resolve(__dirname, 'lib', 'VideoRename.js'), [ path.resolve(self.config.captureDirectory, 'videos') ]);

    imageCaptureChild.on('message', (message) => {
      if (message.error) {
        self.emit('error', message.error);
      }
      else if (message.response === 'success' && self.config.continueToCapture) {
        imageCaptureChild.send({ cmd: 'capture' });
      }
    });

    imageCompareChild.on('message', (message) => {
      if (message.error) {
        self.emit('error', message.error);
      }
      else if (message.response === 'motion') {
        self.config.continueToCapture = false;
        self.emit('motion');

        if (self.config.captureVideoOnMotion) {
          videoCaptureChild.send({
            cmd: 'capture',
          });
        }
        else {
          self.config.continueToCapture = true;
          imageCaptureChild.send({ cmd: 'capture' });
        }
      }
    });

    videoCaptureChild.on('message', (message) => {
      if (message.error) {
        self.emit('error', message.error);
      }
      else if (message.response === 'success') {
        self.config.continueToCapture = true;
        imageCaptureChild.send({ cmd: 'capture' });
      }
    });

    videoRenameChild.on('message', (message) => {
      if (message.error) {
        self.emit('error', message.error);
      }
    });

    // Start the magic
    imageCaptureChild.send({ cmd: 'capture' });
  }
}

function captureDirsCheck(base) {
  if (!base) {
    throw new Error(`'captureDirectory' can't be null`);
  }

  const dirsToCheck = [ base, path.resolve(base, 'images'), path.resolve(base, 'videos') ];

  dirsToCheck.forEach((dir) => {
    try {
      fs.accessSync(dir);
    }
    catch (e) {
      // Doesn't exist, create it
      fs.mkdirSync(dir);
    }
  });
}

function emptyImagesDir(imagesDir) {
  const files = fs.readdirSync(imagesDir);

  files.forEach((file) => {
    fs.unlink(path.resolve(imagesDir, file), (error) => {
      if (error) {
        throw error;
      }
    });
  });
}

module.exports = MotionDetectionModule;

{'fraction_non_alphanumeric': 0.14830954169797145, 'fraction_numerical': 0.0009015777610818933, 'mean_word_length': 3.0241837968561063, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '386627', 'n_tokens_mistral': 1960, 'n_tokens_neox': 1907, 'n_words': 422}