<commit_before>'use strict';

const _ = require('lodash');
const config = require('config');
const moment = require('moment');

const cron = require('../lib/cron');
const wechat = require('../lib/wechat');
const ssModel = require('../model/ss');
const ssService = require('../service/ss');

const UserModel = ssModel.User;
const TransferModel = ssModel.Transfer;

// 每月清空流量
let initUserTransfer = cron('0 0 0 1 * *', function* () {
  yield UserModel.update({
    flow_up: 0,
    flow_down: 0,
  }, {
    silent: true,
    where: {},
  });
});

// 清理过期日志
let cleanTransferLogs = cron('0 0 * * * *', function* () {
  let days = config.ss.transfer_log_save_days;
  let ms = days * 24 * 60 * 60 * 1000;
  yield TransferModel.destroy({
    where: {
      active_at: {
        $lt: new Date(new Date() - ms),
      },
    },
  });
});

// 节点监控
const MAX_TIME_DIFF = 180000;
let nodeMonitor = cron('*/3 * * * * *', function* () {
  let nodes = yield ssService.findNodeAsync({
    active_at: {
      $ne: null,
    },
  });

  for (let node of nodes) {
    let new_status = {ok: true, active_at: node.active_at};
    let old_status = (yield ssService.getNodeStatusAsync(node.node_id)) || new_status;

    let message;
    let time_diff = moment().diff(node.active_at);
    new_status.ok = time_diff <= MAX_TIME_DIFF;
    if (!new_status.ok && old_status.ok) {
      message = `【${node.name}】(ID:${node.node_id})科学上网服务异常，请及时检查`;
    } else if (new_status.ok && !old_status.ok) {
      let long = moment(old_status.active_at).fromNow(true);
      message = `【${node.name}】(ID:${node.node_id})科学上网服务已恢复，本次服务中断时长 ${long}`;
    }

    if (message) {
      let users = yield ssService.findUserAsync({is_admin: true});
      let send_to = _.map(users, 'user_id').join('|');
      yield wechat.sendAsync(send_to, {
        msgtype: 'text',
        text: {
          content: message,
        },
      });
    }

    yield ssService.setNodeStatusAsync(node.node_id, new_status);
  }
});

module.exports = {
  initUserTransfer,
  cleanTransferLogs,
  nodeMonitor,
};<commit_msg>fix: 修复消息发送Bug<commit_after>'use strict';

const _ = require('lodash');
const config = require('config');
const moment = require('moment');

const cron = require('../lib/cron');
const wechat = require('../lib/wechat');
const ssModel = require('../model/ss');
const ssService = require('../service/ss');

const UserModel = ssModel.User;
const TransferModel = ssModel.Transfer;

// 每月清空流量
let initUserTransfer = cron('0 0 0 1 * *', function* () {
  yield UserModel.update({
    flow_up: 0,
    flow_down: 0,
  }, {
    silent: true,
    where: {},
  });
});

// 清理过期日志
let cleanTransferLogs = cron('0 0 * * * *', function* () {
  let days = config.ss.transfer_log_save_days;
  let ms = days * 24 * 60 * 60 * 1000;
  yield TransferModel.destroy({
    where: {
      active_at: {
        $lt: new Date(new Date() - ms),
      },
    },
  });
});

// 节点监控
const MAX_TIME_DIFF = 180000;
let nodeMonitor = cron('0 * * * * *', function* () {
  let nodes = yield ssService.findNodeAsync({
    active_at: {
      $ne: null,
    },
  });

  for (let node of nodes) {
    let new_status = {ok: true, active_at: node.active_at};
    let old_status = (yield ssService.getNodeStatusAsync(node.node_id)) || new_status;

    let message;
    let time_diff = moment().diff(node.active_at);
    new_status.ok = time_diff <= MAX_TIME_DIFF;
    if (!new_status.ok && old_status.ok) {
      message = `【${node.name}】(ID:${node.node_id})科学上网服务异常，请及时检查`;
    } else if (new_status.ok && !old_status.ok) {
      let long = moment(old_status.active_at).fromNow(true);
      message = `【${node.name}】(ID:${node.node_id})科学上网服务已恢复，本次服务中断时长 ${long}`;
    }

    if (message) {
      let users = yield ssService.findUserAsync({is_admin: true});
      let touser = _.map(users, 'user_id').join('|');
      yield wechat.sendAsync({touser}, {
        msgtype: 'text',
        text: {
          content: message,
        },
      });
    }

    yield ssService.setNodeStatusAsync(node.node_id, new_status);
  }
});

module.exports = {
  initUserTransfer,
  cleanTransferLogs,
  nodeMonitor,
};
{'fraction_non_alphanumeric': 0.1701869385773246, 'fraction_numerical': 0.012138868657441126, 'mean_word_length': 3.083250743310208, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, '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': '1908713', 'n_tokens_mistral': 1559, 'n_tokens_neox': 1547, 'n_words': 299}