<commit_before>/**
 * Tab in the Bottom Navigation. Consists of Label + Icon.
 * Handles all the fancy animations.
 * @flow
 */

import React, { Component } from 'react'
import {
  View,
  Text,
  Easing,
  Animated,
  Platform,
  StyleSheet,
  TouchableWithoutFeedback
} from 'react-native'
import Badge from "./Badge"
import { easeInOut } from './utils/easing'

const useNativeDriver = Platform.OS === 'android'

type TabProps = {
  active: boolean,
  shifting: boolean,
  tabIndex: number,
  barBackgroundColor: string,
  icon: ReactElement<*>,
  activeIcon?: ReactElement<*>,
  label: string,
  labelColor: string,
  activeLabelColor?: string,
  onTabPress: () => void,
  onPress: () => void,
  badgeText: string,
  badgeSize: number,
  badgeStyle: any,
  isBadgeVisible: boolean,
}

type TabState = {
  fixed: {
    labelScale: Animated.Value,
    labelY: Animated.Value,
    iconY: Animated.Value,
    iconOpacity: Animated.Value
  },
  shifting: {
    labelOpacity: Animated.Value,
    labelScale: Animated.Value,
    iconY: Animated.Value,
    iconOpacity: Animated.Value
  }
}

export default class Tab extends Component {

  props: TabProps
  state: TabState
  didOnceBecameActive: boolean

  constructor(props: TabProps) {
    super(props)
    const { active } = props

    this.state = {
      fixed: {
        iconY: active ? new Animated.Value(-2) : new Animated.Value(0),
        labelScale: active ? new Animated.Value(1) : new Animated.Value(0.857),
        labelY: active ? new Animated.Value(0) : new Animated.Value(2),
        iconOpacity: active ? new Animated.Value(1) : new Animated.Value(0.8)
      },
      shifting: {
        labelOpacity: active ? new Animated.Value(1) : new Animated.Value(0),
        labelScale: active ? new Animated.Value(1) : new Animated.Value(0.857),
        iconY: active ? new Animated.Value(0) : new Animated.Value(8),
        iconOpacity: active ? new Animated.Value(1) : new Animated.Value(0.8)
      }
    }
  }

  // Animations will start as soon as new props are passed through
  componentWillReceiveProps(nextProps: TabProps) {
    const { props } = this

    const fixedMode = !props.shifting
    const shiftingMode = props.shifting
    const willBeActive = !props.active && nextProps.active
    const willBeInactive = props.active && !nextProps.active

    if (fixedMode && willBeActive) {
      this._animateFixedInactiveToActive()
    } else if (fixedMode && willBeInactive) {
      this._animateFixedActiveToInactive()
    } else if (shiftingMode && willBeActive) {
      this._animateShiftingInactiveToActive()
    } else if (shiftingMode && willBeInactive) {
      this._animateShiftingActiveToInactive()
    }
  }

  render() {
    const { icon, label, active } = this.props

    return (
      <TouchableWithoutFeedback onPress={this._handleTabPress}>
        <View
          style={[
            styles.container,
            (this._isShifting() && active) && styles.shiftingActiveContainer,
            (this._isShifting() && !active) && styles.shiftingInactiveContainer
          ]}
        >
          {this._renderIcon()}
          {this._renderBadge()}
          {this._renderLabel()}
        </View>
      </TouchableWithoutFeedback>
    )
  }

  _renderBadge = () => {
    const { badgeText, badgeSize, badgeStyle, isBadgeVisible } = this.props;
    const mode = this._getModeString();

    if (badgeText === undefined && !isBadgeVisible) {
      return null;
    }

    return (
        <Badge
          text={badgeText}
          size={badgeSize}
          style={badgeStyle}
          isVisible={isBadgeVisible}
          translateY={this.state[mode].iconY}
        />
    )
  }

  _renderIcon = () => {
    const mode = this._getModeString();
    const { active, icon, activeIcon } = this.props;

    return (
      <Animated.View
        style={[
          styles.icon,
          { transform: [{ translateY: this.state[mode].iconY }] },
          { opacity: this.state[mode].iconOpacity }
        ]}
      >

        <View ref="_bnic" collapsable={false}>
          {active && activeIcon ? activeIcon : icon}
        </View>
      </Animated.View>
    )
  }

  _renderLabel = () => {
    const { active, labelColor, activeLabelColor, label } = this.props

    return (
      <Animated.Text
        style={[
          { color: active && activeLabelColor ? activeLabelColor : labelColor },
          styles.label,
          this._isShifting() && { opacity: this.state.shifting.labelOpacity },
          this._isFixed() && {
            transform: [
              { scale: this.state.fixed.labelScale },
              { translateY: this.state.fixed.labelY }
            ]
          }
        ]}
        numberOfLines={1}
      >
        {label}
      </Animated.Text>
    )
  }

  _animateFixedInactiveToActive = () => {
    const duration = 266
    const easing = easeInOut

    Animated.parallel([
      Animated.timing(this.state.fixed.iconY,
        { toValue: -2, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.labelScale,
        { toValue: 1, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.labelY,
        { toValue: 0, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.iconOpacity,
        { toValue: 1, duration, easing, useNativeDriver })
    ]).start()
  }

  _animateFixedActiveToInactive = () => {
    const duration = 266
    const easing = easeInOut

    Animated.parallel([
      Animated.timing(this.state.fixed.iconY,
        { toValue: 0, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.labelScale,
        { toValue: 0.857, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.labelY,
        { toValue: 2, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.iconOpacity,
        { toValue: 0.8, duration, easing, useNativeDriver })
    ]).start()
  }

  _animateShiftingInactiveToActive = () => {
    const easing = easeInOut

    Animated.parallel([
      Animated.timing(this.state.shifting.iconY,
        { toValue: 0, duration: 266, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.iconOpacity,
        { toValue: 1, duration: 266, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.labelOpacity,
        { toValue: 1, duration: 183, delay: 83, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.labelScale,
        { toValue: 1, duration: 183, delay: 83, easing, useNativeDriver })
    ]).start()
  }

  _animateShiftingActiveToInactive = () => {
    const easing = easeInOut

    Animated.parallel([
      Animated.timing(this.state.shifting.iconY,
        { toValue: 8, duration: 266, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.labelOpacity,
        { toValue: 0, duration: 83, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.labelScale,
        { toValue: 0.857, duration: 83, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.iconOpacity,
        { toValue: 0.8, duration: 266, easing, useNativeDriver })
    ]).start()
  }

  _handleTabPress = () => {
    this.props.onPress && this.props.onPress(this.props.tabIndex)

    // if onPress is set, only run the (ripple) animation, don't set it active
    this.setTabActive({ updateActiveTab: !this.props.onPress })
  }

  setTabActive = ({ updateActiveTab = true, forceAnimation = false }) => {
    // Setting the tab active is job of the BottomNavigation Component,
    // so call it's function to handle that.
    this.props.onTabPress({
      tabIndex: this.props.tabIndex,
      barBackgroundColor: this.props.barBackgroundColor,
      iconRef: this.refs._bnic
    }, { updateActiveTab, forceAnimation })
  }

  _getModeString = () => {
    if (this.props.shifting) return 'shifting'
    return 'fixed'
  }

  _isShifting = () => {
    return !!this.props.shifting
  }

  _isFixed = () => {
    return !this.props.shifting
  }

  getIconRef = () => {
    return this.refs._bnic
  }
}

const styles = StyleSheet.create({
  container: {
    height: 56,
    flex: 1,
    alignItems: 'center',
    paddingTop: 8,
    paddingBottom: (Platform.OS !== 'web' ? 10 : 0),
    paddingLeft: 12,
    paddingRight: 12,
    backgroundColor: 'transparent',
    position: "relative",
    ...(Platform.OS !== 'web' ? {} : { transition: '0.5s all' }),
  },
  shiftingInactiveContainer: {
    maxWidth: 96,
    flex: 1
  },
  shiftingActiveContainer: {
    maxWidth: 168,
    flex: 1.75
  },
  icon: {
    width: 24,
    height: 24,
    backgroundColor: 'transparent'
  },
  label: {
    fontSize: 14,
    width: 168,
    textAlign: 'center',
    ...(Platform.OS !== 'web' ? { includeFontPadding: false } : {}),
    textAlignVertical: 'center',
    justifyContent: 'flex-end',
    backgroundColor: 'transparent',
    zIndex: 0
  }
})
<commit_msg>Fix warnings in react-native-web<commit_after>/**
 * Tab in the Bottom Navigation. Consists of Label + Icon.
 * Handles all the fancy animations.
 * @flow
 */

import React, { Component } from 'react'
import {
  View,
  Text,
  Easing,
  Animated,
  Platform,
  StyleSheet,
  TouchableWithoutFeedback
} from 'react-native'
import Badge from "./Badge"
import { easeInOut } from './utils/easing'

const useNativeDriver = Platform.OS === 'android'

type TabProps = {
  active: boolean,
  shifting: boolean,
  tabIndex: number,
  barBackgroundColor: string,
  icon: ReactElement<*>,
  activeIcon?: ReactElement<*>,
  label: string,
  labelColor: string,
  activeLabelColor?: string,
  onTabPress: () => void,
  onPress: () => void,
  badgeText: string,
  badgeSize: number,
  badgeStyle: any,
  isBadgeVisible: boolean,
}

type TabState = {
  fixed: {
    labelScale: Animated.Value,
    labelY: Animated.Value,
    iconY: Animated.Value,
    iconOpacity: Animated.Value
  },
  shifting: {
    labelOpacity: Animated.Value,
    labelScale: Animated.Value,
    iconY: Animated.Value,
    iconOpacity: Animated.Value
  }
}

export default class Tab extends Component {

  props: TabProps
  state: TabState
  didOnceBecameActive: boolean

  constructor(props: TabProps) {
    super(props)
    const { active } = props

    this.state = {
      fixed: {
        iconY: active ? new Animated.Value(-2) : new Animated.Value(0),
        labelScale: active ? new Animated.Value(1) : new Animated.Value(0.857),
        labelY: active ? new Animated.Value(0) : new Animated.Value(2),
        iconOpacity: active ? new Animated.Value(1) : new Animated.Value(0.8)
      },
      shifting: {
        labelOpacity: active ? new Animated.Value(1) : new Animated.Value(0),
        labelScale: active ? new Animated.Value(1) : new Animated.Value(0.857),
        iconY: active ? new Animated.Value(0) : new Animated.Value(8),
        iconOpacity: active ? new Animated.Value(1) : new Animated.Value(0.8)
      }
    }
  }

  // Animations will start as soon as new props are passed through
  componentWillReceiveProps(nextProps: TabProps) {
    const { props } = this

    const fixedMode = !props.shifting
    const shiftingMode = props.shifting
    const willBeActive = !props.active && nextProps.active
    const willBeInactive = props.active && !nextProps.active

    if (fixedMode && willBeActive) {
      this._animateFixedInactiveToActive()
    } else if (fixedMode && willBeInactive) {
      this._animateFixedActiveToInactive()
    } else if (shiftingMode && willBeActive) {
      this._animateShiftingInactiveToActive()
    } else if (shiftingMode && willBeInactive) {
      this._animateShiftingActiveToInactive()
    }
  }

  render() {
    const { icon, label, active } = this.props

    return (
      <TouchableWithoutFeedback onPress={this._handleTabPress}>
        <View
          style={[
            styles.container,
            (this._isShifting() && active) && styles.shiftingActiveContainer,
            (this._isShifting() && !active) && styles.shiftingInactiveContainer
          ]}
        >
          {this._renderIcon()}
          {this._renderBadge()}
          {this._renderLabel()}
        </View>
      </TouchableWithoutFeedback>
    )
  }

  _renderBadge = () => {
    const { badgeText, badgeSize, badgeStyle, isBadgeVisible } = this.props;
    const mode = this._getModeString();

    if (badgeText === undefined && !isBadgeVisible) {
      return null;
    }

    return (
        <Badge
          text={badgeText}
          size={badgeSize}
          style={badgeStyle}
          isVisible={isBadgeVisible}
          translateY={this.state[mode].iconY}
        />
    )
  }

  _renderIcon = () => {
    const mode = this._getModeString();
    const { active, icon, activeIcon } = this.props;

    return (
      <Animated.View
        style={[
          styles.icon,
          { transform: [{ translateY: this.state[mode].iconY }] },
          { opacity: this.state[mode].iconOpacity }
        ]}
      >

        <View ref="_bnic" collapsable={false}>
          {active && activeIcon ? activeIcon : icon}
        </View>
      </Animated.View>
    )
  }

  _renderLabel = () => {
    const { active, labelColor, activeLabelColor, label } = this.props

    return (
      <Animated.Text
        style={[
          { color: active && activeLabelColor ? activeLabelColor : labelColor },
          styles.label,
          this._isShifting() && { opacity: this.state.shifting.labelOpacity },
          this._isFixed() && {
            transform: [
              { scale: this.state.fixed.labelScale },
              { translateY: this.state.fixed.labelY }
            ]
          }
        ]}
        numberOfLines={1}
      >
        {label}
      </Animated.Text>
    )
  }

  _animateFixedInactiveToActive = () => {
    const duration = 266
    const easing = easeInOut

    Animated.parallel([
      Animated.timing(this.state.fixed.iconY,
        { toValue: -2, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.labelScale,
        { toValue: 1, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.labelY,
        { toValue: 0, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.iconOpacity,
        { toValue: 1, duration, easing, useNativeDriver })
    ]).start()
  }

  _animateFixedActiveToInactive = () => {
    const duration = 266
    const easing = easeInOut

    Animated.parallel([
      Animated.timing(this.state.fixed.iconY,
        { toValue: 0, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.labelScale,
        { toValue: 0.857, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.labelY,
        { toValue: 2, duration, easing, useNativeDriver }),
      Animated.timing(this.state.fixed.iconOpacity,
        { toValue: 0.8, duration, easing, useNativeDriver })
    ]).start()
  }

  _animateShiftingInactiveToActive = () => {
    const easing = easeInOut

    Animated.parallel([
      Animated.timing(this.state.shifting.iconY,
        { toValue: 0, duration: 266, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.iconOpacity,
        { toValue: 1, duration: 266, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.labelOpacity,
        { toValue: 1, duration: 183, delay: 83, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.labelScale,
        { toValue: 1, duration: 183, delay: 83, easing, useNativeDriver })
    ]).start()
  }

  _animateShiftingActiveToInactive = () => {
    const easing = easeInOut

    Animated.parallel([
      Animated.timing(this.state.shifting.iconY,
        { toValue: 8, duration: 266, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.labelOpacity,
        { toValue: 0, duration: 83, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.labelScale,
        { toValue: 0.857, duration: 83, easing, useNativeDriver }),
      Animated.timing(this.state.shifting.iconOpacity,
        { toValue: 0.8, duration: 266, easing, useNativeDriver })
    ]).start()
  }

  _handleTabPress = () => {
    this.props.onPress && this.props.onPress(this.props.tabIndex)

    // if onPress is set, only run the (ripple) animation, don't set it active
    this.setTabActive({ updateActiveTab: !this.props.onPress })
  }

  setTabActive = ({ updateActiveTab = true, forceAnimation = false }) => {
    // Setting the tab active is job of the BottomNavigation Component,
    // so call it's function to handle that.
    this.props.onTabPress({
      tabIndex: this.props.tabIndex,
      barBackgroundColor: this.props.barBackgroundColor,
      iconRef: this.refs._bnic
    }, { updateActiveTab, forceAnimation })
  }

  _getModeString = () => {
    if (this.props.shifting) return 'shifting'
    return 'fixed'
  }

  _isShifting = () => {
    return !!this.props.shifting
  }

  _isFixed = () => {
    return !this.props.shifting
  }

  getIconRef = () => {
    return this.refs._bnic
  }
}

const styles = StyleSheet.create({
  container: {
    height: 56,
    flex: 1,
    alignItems: 'center',
    paddingTop: 8,
    paddingBottom: (Platform.OS !== 'web' ? 10 : 0),
    paddingLeft: 12,
    paddingRight: 12,
    backgroundColor: 'transparent',
    position: "relative",
    ...(Platform.OS !== 'web' ? {} : {
      transitionDuration: '0.5s',
      transitionProperty: 'all'
    }),
  },
  shiftingInactiveContainer: {
    maxWidth: 96,
    flex: 1
  },
  shiftingActiveContainer: {
    maxWidth: 168,
    flex: 1.75
  },
  icon: {
    width: 24,
    height: 24,
    backgroundColor: 'transparent'
  },
  label: {
    fontSize: 14,
    width: 168,
    textAlign: 'center',
    ...(Platform.OS !== 'web' ? { includeFontPadding: false } : {}),
    textAlignVertical: 'center',
    justifyContent: 'flex-end',
    backgroundColor: 'transparent',
    zIndex: 0
  }
})
<|endoftext|>


<commit_before>var CommandUtil = require('../src/command_util').CommandUtil;
var util = require('util');
var l10n_file = __dirname + '/../l10n/commands/appraise.yml';
var l10n = require('../src/l10n')(l10n_file);
exports.command = function(rooms, items, players, npcs, Commands) {

  return function(args, player) {

    var room = rooms.getAt(player.getLocation());
    var target = CommandUtil.findNpcInRoom(npcs, args, room, player, true);

    if (!target) {
      player.sayL10n(l10n, 'TARGET_NOT_FOUND');
      return;
    }

    var targetLevel = target.getAttribute('level') || null;
    var playerLevel = player.getAttribute('level') || null;
    var targetName = target.getShortDesc() || null;

    if (targetLevel && playerLevel && targetName) {
      player.sayL10n(l10n, getRelativeLevel(playerLevel, targetLevel), targetName);
      return;
    }

    player.sayL10n(l10n, 'MISSING_INFORMATION');
    return;

  }

    function getRelativeLevel(player, target) {
      var difference = player - target;
      if (difference < -3) {
        return 'TARGET_MUCH_STRONGER';
      } else if (difference < -1) {
        return 'TARGET_STRONGER';
      } else if (difference > 3) {
        return 'TARGET_MUCH_WEAKER';
      } else if (difference > 1) {
        return 'TARGET_WEAKER';
      } else if (difference < 1) {
        return 'TARGET_SAME_LEVEL';
      } else return 'MISSING_INFORMATION';
    }

};
<commit_msg>Refactor appraise command :sunny: to use ES6 syntax.<commit_after>'use strict';
const CommandUtil = require('../src/command_util').CommandUtil;
const util = require('util');
const l10n_file = __dirname + '/../l10n/commands/appraise.yml';
const l10n = require('../src/l10n')(l10n_file);

exports.command = (rooms, items, players, npcs, Commands) => {

  return (args, player) => {

    const room = rooms.getAt(player.getLocation());
    const target = CommandUtil.findNpcInRoom(npcs, args, room, player, true);

    if (!target) {
      player.sayL10n(l10n, 'TARGET_NOT_FOUND');
      return;
    }

    const targetLevel = target.getAttribute('level') || null;
    const playerLevel = player.getAttribute('level') || null;
    const targetName = target.getShortDesc() || null;

    if (targetLevel && playerLevel && targetName) {
      player.sayL10n(l10n, getRelativeLevel(playerLevel, targetLevel), targetName);
      return;
    }

    player.sayL10n(l10n, 'MISSING_INFORMATION');
    return;

  }

  function getRelativeLevel(playerLevel, targetLevel) {
    const difference = playerLevel - targetLevel;
    if (difference < -3) {
      return 'TARGET_MUCH_STRONGER';
    } else if (difference < -1) {
      return 'TARGET_STRONGER';
    } else if (difference > 3) {
      return 'TARGET_MUCH_WEAKER';
    } else if (difference > 1) {
      return 'TARGET_WEAKER';
    } else if (difference < 1) {
      return 'TARGET_SAME_LEVEL';
    } else return 'MISSING_INFORMATION';
  }

};
<|endoftext|>


<commit_before>'use strict';

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.computeCrimePercentages = functions.database.ref('crimedata/{pushId}/offense_code_group')
  .onWrite(event => {
    console.log('Recalculating crime percentages for new message', event.params.pushId);
    // Only edit data when it is first created.
    if (!event.data.changed()) {
      console.log('Skipping update to same value');
      return;
    }

    var ocgRef = admin.database().ref('analytics/offense_code_group/');
    return ocgRef.transaction(current_value => {
      if (current_value[event.data.val()]) {
        console.log("Incrementing", event.data.val());
        current_value[event.data.val()]+= 1;
      } else {
        console.log("Incrementing", event.data.val());
        current_value[event.data.val()] = 1;
      }

      if (even.data.previous.exists()) {
        if (current_value[event.data.previous.val()] {
          console.log("Decrementing", event.data.previous.val());
          current_value[event.data.previous.val()]-= 1;
          if (current_value[event.data.previous.val()] <= 0) {
            delete current_value[event.data.previous.val()];
          }
        }
      }

      return current_value;
    }).then(() => console.log("Transaction committed"));
  });

exports.computeSeverityLevel = functions.database.ref('crimedata/{pushId}/offense_code_group')
  .onWrite(event => {
    console.log('Calculating severity level for', event.params.pushId);

    return event.data.ref.parent.child('severity').set("Something");
  });

<commit_msg>fix typo<commit_after>'use strict';

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.computeCrimePercentages = functions.database.ref('crimedata/{pushId}/offense_code_group')
  .onWrite(event => {
    console.log('Recalculating crime percentages for new message', event.params.pushId);
    // Only edit data when it is first created.
    if (!event.data.changed()) {
      console.log('Skipping update to same value');
      return;
    }

    var ocgRef = admin.database().ref('analytics/offense_code_group/');
    return ocgRef.transaction(current_value => {
      if (current_value[event.data.val()]) {
        console.log("Incrementing", event.data.val());
        current_value[event.data.val()]+= 1;
      } else {
        console.log("Incrementing", event.data.val());
        current_value[event.data.val()] = 1;
      }

      if (even.data.previous.exists()) {
        if (current_value[event.data.previous.val()]) {
          console.log("Decrementing", event.data.previous.val());
          current_value[event.data.previous.val()]-= 1;
          if (current_value[event.data.previous.val()] <= 0) {
            delete current_value[event.data.previous.val()];
          }
        }
      }

      return current_value;
    }).then(() => console.log("Transaction committed"));
  });

exports.computeSeverityLevel = functions.database.ref('crimedata/{pushId}/offense_code_group')
  .onWrite(event => {
    console.log('Calculating severity level for', event.params.pushId);

    return event.data.ref.parent.child('severity').set("Something");
  });

<|endoftext|>


<commit_before>'use strict';

let _ = require('underscore');
let cli = require('heroku-cli-util');

let VERSION = "v0";
let DEFAULT_HOST = "kafka-api.heroku.com";

function HerokuKafkaClusters(heroku, env, context) {
  this.heroku = heroku;
  this.env = env;
  this.context = context;
  this.app = context.app;
}

HerokuKafkaClusters.prototype.info = function* (cluster) {
  var that = this;
  var addons = yield this.addonsForManyClusterCommand(cluster);
  var responses = yield _.map(addons, function(addon) {
    return that.request({
      path: `/client/kafka/${VERSION}/clusters/${addon.name}`
    });
  });
  return responses;
};

HerokuKafkaClusters.prototype.topic = function* (cluster, topic) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    return yield this.request({
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/topics/${topic}`
    });
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.topics = function* (cluster) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    return yield this.request({
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/topics`
    });
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.fail = function* (cluster, catastrophic, zk) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    var response = yield this.request({
      method: 'POST',
      body: { catastrophic: catastrophic, zookeeper: zk },
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/induce-failure`
    });
    return response;
  } else {
    cli.error(`kafka addon not found, but found these addons: ${addon.available.map(function (addon) { return addon.addon_service.name; }).join(',')}`);
    return null;
  }
};

HerokuKafkaClusters.prototype.waitStatus = function* (addon) {
  if (addon) {
    var response = yield this.request({
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/wait_status`
    });
    return response;
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.createTopic = function* (cluster, topicName, flags) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    var response = yield this.request({
      method: 'POST',
      body: {
        topic:
          {
            name: topicName,
            retention_time_ms: flags['retention-time'],
            replication_factor: flags['replication-factor'],
            partition_count: flags['partitions'],
            compaction: flags['compaction'] || false
          }
      },
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/topics`
    }).catch(function (err) { return err; });
    return this.handleResponse(response);
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.configureTopic = function* (cluster, topicName, flags) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    var response = yield this.request({
      method: 'PUT',
      body: {
        topic:
          _.extend({
            name: topicName,
            retention_time_ms: flags['retention-time']
          }, this.compactionSettingFromFlags(flags))
      },
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/topics/${topicName}`
    }).catch(function (err) { return err; });
    return this.handleResponse(response);
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.compactionSettingFromFlags = function* (flags) {
  if (flags['no-compaction']) {
    return { compaction: false };
  } else if (flags['compaction']) {
    return { compaction: true };
  } else {
    return {};
  }
};

HerokuKafkaClusters.prototype.deleteTopic = function* (cluster, topicName) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    var response = yield this.request({
      method: 'DELETE',
      body: {
        topic: { name: topicName }
      },
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/topics/${topicName}`
    }).catch(function (err) { return err; });
    return this.handleResponse(response);
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.request = function (params) {
  cli.hush(`picked shogun host: ${this.host()}`);
  var defaultParams = {
    host: this.host(),
    auth: `${this.context.auth.username}:${this.context.auth.password}`,
    accept: 'application/json'
  };
  return this.heroku.request(_.extend(defaultParams, params));
};

HerokuKafkaClusters.prototype.handleResponse = function (response) {
  if (response.statusCode >= 400 || response.statusCode <= 499) {
    return response.body.message;
  } else if (response.statusCode == undefined || (response.statusCode < 300 && response.statusCode >= 200)) {
    return null;
  } else {
    cli.hush("Error connecting to backend API");
    return "Error, please try again later.";
  }
};

HerokuKafkaClusters.prototype.host = function () {
  if (this.env.SHOGUN) {
    return `shogun-${this.env.SHOGUN}.herokuapp.com`;
  } else if (this.env.DEPLOY) {
    return `shogun-${this.env.DEPLOY}.herokuapp.com`;
  } else {
    return DEFAULT_HOST;
  }
};

HerokuKafkaClusters.prototype.addonsForManyClusterCommand = function* (cluster) {
  var addons = yield this.addons();
  var filteredAddons;
  if (cluster === undefined) {
    filteredAddons = addons.kafkas;
  } else {
    filteredAddons = this.findByClusterName(addons, cluster);
  }
  if (filteredAddons.length !== 0) {
    return filteredAddons;
  } else if (cluster !== undefined) {
    cli.error(`couldn't find the kafka cluster ${cluster}, but found these addons instead: ${addons.allAddons.map(function (addon) { return addon.name; }).join(',')}`);
    return null;
  } else {
    cli.error(`kafka addon not found, but found these addons: ${addons.allAddons.map(function (addon) { return addon.name; }).join(',')}`);
    return null;
  }
};

HerokuKafkaClusters.prototype.addonForSingleClusterCommand = function* (cluster) {
  var addons = yield this.addons();
  var addon;
  if (addons.kafkas.length === 1 && cluster === undefined) {
    addon = addons.kafkas[0];
  } else {
    addon = this.findByClusterName(addons, cluster)[0];
  }
  if (addon) {
    return addon;
  } else if (cluster !== undefined) {
    cli.error(`couldn't find the kafka cluster ${cluster}, but found these addons instead: ${addons.allAddons.map(function (addon) { return addon.name; }).join(',')}`);
    return null;
  } else if (addons.kafkas.length !== 1) {
    cli.error(`please specify a kafka cluster. Possible clusters: ${addons.kafkas.map(function (addon) { return addon.name; }).join(',')}`);
    return null;
  } else {
    cli.error(`kafka addon not found, but found these addons: ${addons.allAddons.map(function (addon) { return addon.name; }).join(',')}`);
    return null;
  }
};

HerokuKafkaClusters.prototype.findByClusterName = function (addons, cluster) {
  return addons.kafkas.filter(function (addon) { return _.contains(addon.config_vars, cluster) || addon.name == cluster; });
};

HerokuKafkaClusters.prototype.addons = function* () {
  let allAddons = yield this.heroku.apps(this.app).addons().listByApp();
  let kafkaAddons = allAddons.filter(function (addon) { return addon.addon_service.name.startsWith('heroku-kafka'); });
  return {
    kafkas: kafkaAddons,
    allAddons: allAddons
  };
};

module.exports = {
  HerokuKafkaClusters: HerokuKafkaClusters
};
<commit_msg>Fix compaction flags for kafka:configure<commit_after>'use strict';

let _ = require('underscore');
let cli = require('heroku-cli-util');

let VERSION = "v0";
let DEFAULT_HOST = "kafka-api.heroku.com";

function HerokuKafkaClusters(heroku, env, context) {
  this.heroku = heroku;
  this.env = env;
  this.context = context;
  this.app = context.app;
}

HerokuKafkaClusters.prototype.info = function* (cluster) {
  var that = this;
  var addons = yield this.addonsForManyClusterCommand(cluster);
  var responses = yield _.map(addons, function(addon) {
    return that.request({
      path: `/client/kafka/${VERSION}/clusters/${addon.name}`
    });
  });
  return responses;
};

HerokuKafkaClusters.prototype.topic = function* (cluster, topic) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    return yield this.request({
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/topics/${topic}`
    });
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.topics = function* (cluster) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    return yield this.request({
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/topics`
    });
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.fail = function* (cluster, catastrophic, zk) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    var response = yield this.request({
      method: 'POST',
      body: { catastrophic: catastrophic, zookeeper: zk },
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/induce-failure`
    });
    return response;
  } else {
    cli.error(`kafka addon not found, but found these addons: ${addon.available.map(function (addon) { return addon.addon_service.name; }).join(',')}`);
    return null;
  }
};

HerokuKafkaClusters.prototype.waitStatus = function* (addon) {
  if (addon) {
    var response = yield this.request({
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/wait_status`
    });
    return response;
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.createTopic = function* (cluster, topicName, flags) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    var response = yield this.request({
      method: 'POST',
      body: {
        topic:
          {
            name: topicName,
            retention_time_ms: flags['retention-time'],
            replication_factor: flags['replication-factor'],
            partition_count: flags['partitions'],
            compaction: flags['compaction'] || false
          }
      },
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/topics`
    }).catch(function (err) { return err; });
    return this.handleResponse(response);
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.configureTopic = function* (cluster, topicName, flags) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    var response = yield this.request({
      method: 'PUT',
      body: {
        topic:
          _.extend({
            name: topicName,
            retention_time_ms: flags['retention-time']
          }, this.compactionSettingFromFlags(flags))
      },
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/topics/${topicName}`
    }).catch(function (err) { return err; });
    return this.handleResponse(response);
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.compactionSettingFromFlags = function (flags) {
  if (flags['no-compaction']) {
    return { compaction: false };
  } else if (flags['compaction']) {
    return { compaction: true };
  } else {
    return {};
  }
};

HerokuKafkaClusters.prototype.deleteTopic = function* (cluster, topicName) {
  var addon = yield this.addonForSingleClusterCommand(cluster);
  if (addon) {
    var response = yield this.request({
      method: 'DELETE',
      body: {
        topic: { name: topicName }
      },
      path: `/client/kafka/${VERSION}/clusters/${addon.name}/topics/${topicName}`
    }).catch(function (err) { return err; });
    return this.handleResponse(response);
  } else {
    return null;
  }
};

HerokuKafkaClusters.prototype.request = function (params) {
  cli.hush(`picked shogun host: ${this.host()}`);
  var defaultParams = {
    host: this.host(),
    auth: `${this.context.auth.username}:${this.context.auth.password}`,
    accept: 'application/json'
  };
  return this.heroku.request(_.extend(defaultParams, params));
};

HerokuKafkaClusters.prototype.handleResponse = function (response) {
  if (response.statusCode >= 400 || response.statusCode <= 499) {
    return response.body.message;
  } else if (response.statusCode == undefined || (response.statusCode < 300 && response.statusCode >= 200)) {
    return null;
  } else {
    cli.hush("Error connecting to backend API");
    return "Error, please try again later.";
  }
};

HerokuKafkaClusters.prototype.host = function () {
  if (this.env.SHOGUN) {
    return `shogun-${this.env.SHOGUN}.herokuapp.com`;
  } else if (this.env.DEPLOY) {
    return `shogun-${this.env.DEPLOY}.herokuapp.com`;
  } else {
    return DEFAULT_HOST;
  }
};

HerokuKafkaClusters.prototype.addonsForManyClusterCommand = function* (cluster) {
  var addons = yield this.addons();
  var filteredAddons;
  if (cluster === undefined) {
    filteredAddons = addons.kafkas;
  } else {
    filteredAddons = this.findByClusterName(addons, cluster);
  }
  if (filteredAddons.length !== 0) {
    return filteredAddons;
  } else if (cluster !== undefined) {
    cli.error(`couldn't find the kafka cluster ${cluster}, but found these addons instead: ${addons.allAddons.map(function (addon) { return addon.name; }).join(',')}`);
    return null;
  } else {
    cli.error(`kafka addon not found, but found these addons: ${addons.allAddons.map(function (addon) { return addon.name; }).join(',')}`);
    return null;
  }
};

HerokuKafkaClusters.prototype.addonForSingleClusterCommand = function* (cluster) {
  var addons = yield this.addons();
  var addon;
  if (addons.kafkas.length === 1 && cluster === undefined) {
    addon = addons.kafkas[0];
  } else {
    addon = this.findByClusterName(addons, cluster)[0];
  }
  if (addon) {
    return addon;
  } else if (cluster !== undefined) {
    cli.error(`couldn't find the kafka cluster ${cluster}, but found these addons instead: ${addons.allAddons.map(function (addon) { return addon.name; }).join(',')}`);
    return null;
  } else if (addons.kafkas.length !== 1) {
    cli.error(`please specify a kafka cluster. Possible clusters: ${addons.kafkas.map(function (addon) { return addon.name; }).join(',')}`);
    return null;
  } else {
    cli.error(`kafka addon not found, but found these addons: ${addons.allAddons.map(function (addon) { return addon.name; }).join(',')}`);
    return null;
  }
};

HerokuKafkaClusters.prototype.findByClusterName = function (addons, cluster) {
  return addons.kafkas.filter(function (addon) { return _.contains(addon.config_vars, cluster) || addon.name == cluster; });
};

HerokuKafkaClusters.prototype.addons = function* () {
  let allAddons = yield this.heroku.apps(this.app).addons().listByApp();
  let kafkaAddons = allAddons.filter(function (addon) { return addon.addon_service.name.startsWith('heroku-kafka'); });
  return {
    kafkas: kafkaAddons,
    allAddons: allAddons
  };
};

module.exports = {
  HerokuKafkaClusters: HerokuKafkaClusters
};
<|endoftext|>


<commit_before>'use strict';

module.exports = '_ ee v0.2 _';
<commit_msg>Simplified id as it affected performance<commit_after>'use strict';

module.exports = '_ee2_';
<|endoftext|>


<commit_before>const functions = require("firebase-functions")
const { Nuxt } = require("nuxt")
const express = require("express")
const sm = require("sitemap")
const app = express()

const urls = ["shiren", "shiren2", "shiren3", "shiren4", "shiren5"]
  .map((name) => `/${name}/`)
  .concat(["/"])
const sitemap = sm.createSitemap({
  hostname: "https://shikibetsuhyo.yysaki.com",
  cacheTime: 1000 * 60 * 15,
  urls: urls.map((url) => ({ url: url })),
})

app.get("/sitemap.xml", (req, res) => {
  sitemap.toXML((err, xml) => {
    if (err) {
      return res.status(500).end()
    }
    res.header("Content-Type", "application/xml")
    res.send(xml)
    return true
  })
})

const nuxt = new Nuxt({ buildDir: "nuxt", dev: false })

function handleRequest(req, res) {
  res.set("Cache-Control", "public, max-age=300, s-maxage=600")
  return new Promise((resolve, reject) => {
    nuxt.render(req, res, (promise) => {
      promise.then(resolve).catch(reject)
    })
  })
}

app.use(handleRequest)
exports.ssr = functions.https.onRequest(app)
<commit_msg>Update to treat promise in functions/index.js<commit_after>const functions = require("firebase-functions")
const { Nuxt } = require("nuxt")
const express = require("express")
const sm = require("sitemap")
const app = express()

const urls = ["shiren", "shiren2", "shiren3", "shiren4", "shiren5"]
  .map((name) => `/${name}/`)
  .concat(["/"])
const sitemap = sm.createSitemap({
  hostname: "https://shikibetsuhyo.yysaki.com",
  cacheTime: 1000 * 60 * 15,
  urls: urls.map((url) => ({ url: url })),
})

app.get("/sitemap.xml", (req, res) => {
  sitemap.toXML((err, xml) => {
    if (err) {
      return res.status(500).end()
    }
    res.header("Content-Type", "application/xml")
    res.send(xml)
    return true
  })
})

const nuxt = new Nuxt({ buildDir: "nuxt", dev: false })

function handleRequest(req, res) {
  res.set("Cache-Control", "public, max-age=300, s-maxage=600")
  return nuxt.render(req, res)
}

app.use(handleRequest)
exports.ssr = functions.https.onRequest(app)
<|endoftext|>


<commit_before>'use strict';

module.exports = '- ee v0.2 -';
<commit_msg>Start id with underscore (hint it's private)<commit_after>'use strict';

module.exports = '_ ee v0.2 _';
<|endoftext|>


<commit_before>var functions = require('firebase-functions');

// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
//  response.send("Hello from Firebase!");
// });
<commit_msg>Implement temporary version of `closeSlot` HTTP function<commit_after>const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

class HTTPError extends Error {
  constructor(code, message) {
    super(message);
    this.code = code;
  }
}

// TODO: Implement the real matching algorithm.
// This version always creates a single 'Firebase' topic and assigns everyone to it.
exports.closeSlot = functions.https.onRequest((req, res) => {
  const slotId = req.body.id;
  if (!slotId) {
    res.sendStatus(400);
    return;
  }

  // Get a few refs for convenience
  const db = admin.database();
  const rootRef = db.ref();
  const slotRef = db.ref(`/slots/${slotId}`);
  const reqsRef = db.ref(`/requests/${slotId}`);

  return slotRef.once('value')
    .then(snapshot => {
      // Does the slot exist?
      const slot = snapshot.val();
      if (!slot) {
        throw new HTTPError(404, 'slot not found');
      }

      // Mark the slot as closed
      return slotRef.update({state: 'closed'});
    })
    .then(() => {
      // Fetch all of the requests
      return reqsRef.once('value');
    })
    .then(snapshot => {
      // Build a multi-key database update
      const updates = {};

      // Create a new topic
      const topicId = 'firebase-001';
      const topic = {
        name: 'Firebase',
        members: {},
      };
      updates[`/topics/${slotId}/${topicId}`] = topic;

      // Add every user to the topic
      const uids = Object.keys(snapshot.val())
      uids.forEach(uid => {
        topic.members[uid] = true;
        updates[`/account/${uid}/slots/${slotId}/topicId`] = topicId;
      });

      // Apply all updates atomically
      return rootRef.update(updates);
    })
    .then(() => {
      res.sendStatus(200);
    })
    .catch(err => {
      console.error(err);
      if (err instanceof HTTPError) {
        res.sendStatus(err.code);
      } else {
        res.sendStatus(500);
      }
    });
});
<|endoftext|>


<commit_before>/**
 * Graph ACL.
 */

var async = require('async');

/**
 * Creates an instance of ACL.
 *
 * @constructor
 * @this {ACL}
 * @param {Connector|Neo4jConnector} connector - A connector to a graph database of your choice
 */
var ACL = function(connector) {
  this.connector = connector;
};

/**
  addUserRoles( userId, roles, function(err) )

  Adds roles to a given user id.

  @param {String|Number} User id.
  @param {String|Array} Role(s) to add to the user id.
  @param {Function} Callback called when finished.
  @return {Boolean}
*/
ACL.prototype.addUserRoles = function(userId, roles, callback){
  var _this = this;

  if (typeof userId === 'undefined') {
    callback(new Error('User ID is empty'));
    return;
  }
  if (typeof roles === 'undefined') {
    callback(new Error('Roles are empty'));
    return;
  }

  // When only one role in format string, transform it to array
  if (!(roles instanceof Array)) {
    roles = [roles];
  }

  // @todo: must search for user with that id. If already exists, we can't create
  _this.connector.createNode({uid: userId}, ['User'], function (err, user) {
    async.map(
      roles, // Array
      function(item, callback){
        // @todo: verify if role exists
        _this.connector.createNode({rid: item}, ['Role'], function(err, role) {
          // @todo: verify if relationship exists
          _this.connector.addRelationship(user._id, role._id, 'BELONGS_TO', undefined, callback);
        });
      },
      function(err, results){
        callback(err, results);
      }
    );
  });

};

/**
  removeUserRoles( userId, roles, function(err) )

  Remove roles from a given user.

  @param {String|Number} User id.
  @param {String|Array} Role(s) to remove to the user id.
  @param {Function} Callback called when finished.
  @return {Promise} Promise resolved when finished
*/
ACL.prototype.removeUserRoles = function(userId, roles, callback){
  return true;
};

/**
  userRoles( userId, function(err, roles) )

  Return all the roles from a given user.

  @param {String|Number} User id.
  @param {Function} Callback called when finished.
  @return {Promise} Promise resolved with an array of user roles
*/
ACL.prototype.userRoles = function(userId, callback){
  return true;
};

/**
  addRoleParents( role, parents, function(err) )

  Adds a parent or parent list to role.

  @param {String|Number} User id.
  @param {String|Array} Role(s) to remove to the user id.
  @param {Function} Callback called when finished.
  @return {Promise} Promise resolved when finished
*/
ACL.prototype.addRoleParents = function(role, parents, callback){
  return true;
};

/**
  removeRole( role, function(err) )

  Removes a role from the system.

  @param {String} Role to be removed
  @param {Function} Callback called when finished.
*/
ACL.prototype.removeRole = function(role, callback){
  return true;
};

/**
  removeResource( resource, function(err) )

  Removes a resource from the system

  @param {String} Resource to be removed
  @param {Function} Callback called when finished.
  @return {Promise} Promise resolved when finished
*/
ACL.prototype.removeResource = function(resource, callback){
  return true;
};

/**
  allow( roles, resources, permissions, function(err) )

  Adds the given permissions to the given roles over the given resources.

  @param {String|Array} role(s) to add permissions to.
  @param {String|Array} resource(s) to add permisisons to.
  @param {String|Array} permission(s) to add to the roles over the resources.
  @param {Function} Callback called when finished.

  allow( permissionsArray, function(err) )

  @param {Array} Array with objects expressing what permissions to give.

  [{roles:{String|Array}, allows:[{resources:{String|Array}, permissions:{String|Array}]]

  @param {Function} Callback called when finished.
  @return {Promise} Promise resolved when finished
*/
ACL.prototype.allow = function(roles, resources, permissions, callback){
  return true;
};

ACL.prototype.removeAllow = function(role, resources, permissions, callback){
  return true;
};

/**
  removePermissions( role, resources, permissions)

  Remove permissions from the given roles owned by the given role.

  Note: we loose atomicity when removing empty role_resources.

  @param {String}
  @param {String|Array}
  @param {String|Array}
*/
ACL.prototype.removePermissions = function(role, resources, permissions, callback){
  return true;
};

/**
  allowedPermissions( userId, resources, function(err, obj) )

  Returns all the allowable permissions a given user have to
  access the given resources.

  It returns an array of objects where every object maps a
  resource name to a list of permissions for that resource.

  @param {String|Number} User id.
  @param {String|Array} resource(s) to ask permissions for.
  @param {Function} Callback called when finished.
*/
ACL.prototype.allowedPermissions = function(userId, resources, callback){
  return true;
};

/**
  isAllowed( userId, resource, permissions, function(err, allowed) )

  Checks if the given user is allowed to access the resource for the given
  permissions (note: it must fulfill all the permissions).

  @param {String|Number} User id.
  @param {String|Array} resource(s) to ask permissions for.
  @param {String|Array} asked permissions.
  @param {Function} Callback called wish the result.
*/
ACL.prototype.isAllowed = function(userId, resource, permissions, callback){
  return true;
};

/**
  areAnyRolesAllowed( roles, resource, permissions, function(err, allowed) )

  Returns true if any of the given roles have the right permissions.

  @param {String|Array} Role(s) to check the permissions for.
  @param {String} resource(s) to ask permissions for.
  @param {String|Array} asked permissions.
  @param {Function} Callback called with the result.
*/
ACL.prototype.areAnyRolesAllowed = function(roles, resource, permissions, callback){
  return true;
};

/**
  whatResources(role, function(err, {resourceName: [permissions]})

  Returns what resources a given role or roles have permissions over.

  whatResources(role, permissions, function(err, resources) )

  Returns what resources a role has the given permissions over.

  @param {String|Array} Roles
  @param {String|Array} Permissions
  @param {Function} Callback called wish the result.
*/
ACL.prototype.whatResources = function(roles, permissions, callback){
  return true;
};

/*ACL.prototype.permittedResources = function(roles, permissions, callback){
  return true;
};*/

module.exports = ACL;
<commit_msg>added createUser and createRole<commit_after>/**
 * Graph ACL.
 */

var async = require('async');

/**
 * Creates an instance of ACL.
 *
 * @constructor
 * @this {ACL}
 * @param {Connector|Neo4jConnector} connector - A connector to a graph database of your choice
 */
var ACL = function(connector) {
  this.connector = connector;
};

/**
  addUserRoles( userId, roles, function(err) )

  Adds roles to a given user id.

  @param {String|Number} User id.
  @param {String|Array} Role(s) to add to the user id.
  @param {Function} Callback called when finished.
  @return {Boolean}
*/
ACL.prototype.addUserRoles = function(userId, roles, callback){
  var _this = this;

  if (typeof userId === 'undefined') {
    callback(new Error('User ID is empty'));
    return;
  }
  if (typeof roles === 'undefined') {
    callback(new Error('Roles are empty'));
    return;
  }

  // When only one role in format string, transform it to array
  if (!(roles instanceof Array)) {
    roles = [roles];
  }

  // @todo: verify if user exists
  _this.connector.createNode({uid: userId}, ['User'], function (err, user) {
    async.map(
      roles, // Array
      function(item, callback){
        // @todo: verify if role exists
        _this.connector.createNode({rid: item}, ['Role'], function(err, role) {
          // @todo: verify if relationship exists
          _this.connector.addRelationship(user._id, role._id, 'BELONGS_TO', undefined, callback);
        });
      },
      function(err, results){
        callback(err, results);
      }
    );
  });
};

ACL.prototype.createUser = function (userId, callback) {
  this.connector.existsNodeWithLabelsAndProperties(['User'], {uid: userId}, function(err, exists) {
    if (exists) {
      this.connector.getNodesWithLabelsAndProperties(['User'], {uid: userId}, function(err, userRetrieved) {
        callback(null, userRetrieved[0]);
      });
    } else {
      this.connector.createNode({uid: userId}, ['User'], function (err, userCreated) {
        callback(null, userCreated);
      });
    }
  });
};

ACL.prototype.createRole = function (roleId, callback) {
  this.connector.existsNodeWithLabelsAndProperties(['Role'], {rid: roleId}, function(err, exists) {
    if (exists) {
      this.connector.getNodesWithLabelsAndProperties(['Role'], {rid: roleId}, function(err, roleRetrieved) {
        callback(null, roleRetrieved[0]);
      });
    } else {
      this.connector.createNode({rid: roleId}, ['Role'], function (err, roleCreated) {
        callback(null, roleCreated);
      });
    }
  });
};

/**
  removeUserRoles( userId, roles, function(err) )

  Remove roles from a given user.

  @param {String|Number} User id.
  @param {String|Array} Role(s) to remove to the user id.
  @param {Function} Callback called when finished.
  @return {Promise} Promise resolved when finished
*/
ACL.prototype.removeUserRoles = function(userId, roles, callback){
  return true;
};

/**
  userRoles( userId, function(err, roles) )

  Return all the roles from a given user.

  @param {String|Number} User id.
  @param {Function} Callback called when finished.
  @return {Promise} Promise resolved with an array of user roles
*/
ACL.prototype.userRoles = function(userId, callback){
  return true;
};

/**
  addRoleParents( role, parents, function(err) )

  Adds a parent or parent list to role.

  @param {String|Number} User id.
  @param {String|Array} Role(s) to remove to the user id.
  @param {Function} Callback called when finished.
  @return {Promise} Promise resolved when finished
*/
ACL.prototype.addRoleParents = function(role, parents, callback){
  return true;
};

/**
  removeRole( role, function(err) )

  Removes a role from the system.

  @param {String} Role to be removed
  @param {Function} Callback called when finished.
*/
ACL.prototype.removeRole = function(role, callback){
  return true;
};

/**
  removeResource( resource, function(err) )

  Removes a resource from the system

  @param {String} Resource to be removed
  @param {Function} Callback called when finished.
  @return {Promise} Promise resolved when finished
*/
ACL.prototype.removeResource = function(resource, callback){
  return true;
};

/**
  allow( roles, resources, permissions, function(err) )

  Adds the given permissions to the given roles over the given resources.

  @param {String|Array} role(s) to add permissions to.
  @param {String|Array} resource(s) to add permisisons to.
  @param {String|Array} permission(s) to add to the roles over the resources.
  @param {Function} Callback called when finished.

  allow( permissionsArray, function(err) )

  @param {Array} Array with objects expressing what permissions to give.

  [{roles:{String|Array}, allows:[{resources:{String|Array}, permissions:{String|Array}]]

  @param {Function} Callback called when finished.
  @return {Promise} Promise resolved when finished
*/
ACL.prototype.allow = function(roles, resources, permissions, callback){
  return true;
};

ACL.prototype.removeAllow = function(role, resources, permissions, callback){
  return true;
};

/**
  removePermissions( role, resources, permissions)

  Remove permissions from the given roles owned by the given role.

  Note: we loose atomicity when removing empty role_resources.

  @param {String}
  @param {String|Array}
  @param {String|Array}
*/
ACL.prototype.removePermissions = function(role, resources, permissions, callback){
  return true;
};

/**
  allowedPermissions( userId, resources, function(err, obj) )

  Returns all the allowable permissions a given user have to
  access the given resources.

  It returns an array of objects where every object maps a
  resource name to a list of permissions for that resource.

  @param {String|Number} User id.
  @param {String|Array} resource(s) to ask permissions for.
  @param {Function} Callback called when finished.
*/
ACL.prototype.allowedPermissions = function(userId, resources, callback){
  return true;
};

/**
  isAllowed( userId, resource, permissions, function(err, allowed) )

  Checks if the given user is allowed to access the resource for the given
  permissions (note: it must fulfill all the permissions).

  @param {String|Number} User id.
  @param {String|Array} resource(s) to ask permissions for.
  @param {String|Array} asked permissions.
  @param {Function} Callback called wish the result.
*/
ACL.prototype.isAllowed = function(userId, resource, permissions, callback){
  return true;
};

/**
  areAnyRolesAllowed( roles, resource, permissions, function(err, allowed) )

  Returns true if any of the given roles have the right permissions.

  @param {String|Array} Role(s) to check the permissions for.
  @param {String} resource(s) to ask permissions for.
  @param {String|Array} asked permissions.
  @param {Function} Callback called with the result.
*/
ACL.prototype.areAnyRolesAllowed = function(roles, resource, permissions, callback){
  return true;
};

/**
  whatResources(role, function(err, {resourceName: [permissions]})

  Returns what resources a given role or roles have permissions over.

  whatResources(role, permissions, function(err, resources) )

  Returns what resources a role has the given permissions over.

  @param {String|Array} Roles
  @param {String|Array} Permissions
  @param {Function} Callback called wish the result.
*/
ACL.prototype.whatResources = function(roles, permissions, callback){
  return true;
};

/*ACL.prototype.permittedResources = function(roles, permissions, callback){
  return true;
};*/

module.exports = ACL;
<|endoftext|>


<commit_before>exports.names = ['moveback'];
exports.hidden = true;
exports.enabled = true;
exports.matchStart = true;
exports.cd_all = 20;
exports.cd_user = 3600;
exports.cd_manager = 0;
exports.min_role = PERMISSIONS.NONE;
exports.handler = function (data) {
				var position = bot.getWaitListPosition(data.from.id);
					if(position !== -1) {
						 move_user(data.from.id, 50);
            	 		 chatMessage('/me Moving ' + data.from.username + ' back to 50.');
            	 		 }
            	 	};<commit_msg>Slightly modified the .moveback command<commit_after>exports.names = ['moveback'];
exports.hidden = true;
exports.enabled = true;
exports.matchStart = true;
exports.cd_all = 20;
exports.cd_user = 3600;
exports.cd_manager = 0;
exports.min_role = PERMISSIONS.NONE;
exports.handler = function (data) {
    var position = bot.getWaitListPosition(data.from.id);
    if (position !== -1 && position !== 0) {
        move_user(data.from.id, 50);
        chatMessage('/me Moving ' + data.from.username + ' back to 50.');
    }
};
<|endoftext|>


<commit_before>const getRole = require('./util/getRole.js')
const printFeeds = require('./util/printFeeds.js')
const fileOps = require('../util/updateJSON.js')
const addFilter = require('./filterAdd.js')
const removeFilter = require('./filterRemove.js')
const rssConfig = require('../config.json')

module.exports = function(bot, message, command) {
  const collectorFilter = m => m.author.id == message.author.id;

  try {var guildRss = require(`../sources/${message.guild.id}.json`)}
  catch (e) {return message.channel.sendMessage("Cannot add role customizations without any active feeds.")}

  var rssList = guildRss.sources
  var role

  function isEmptyObject(obj) {
      for(var prop in obj) {
          if(obj.hasOwnProperty(prop))
              return false;
      }
      return JSON.stringify(obj) === JSON.stringify({});
  }

  function addGlobalSub (rssIndex, role) {
    let source = rssList[rssIndex]
    //remove any filtered subscriptions when adding global subscription
    if (source.filters != null && source.filters.roleSubscriptions != null && source.filters.roleSubscriptions[role.id] != null) delete source.filters.roleSubscriptions[role.id];
    if (source.filters != null && source.filters.roleSubscriptions != null && isEmptyObject(source.filters.roleSubscriptions)) delete source.filters.roleSubscriptions;
    if (source.filters != null && isEmptyObject(source.filters)) delete source.filters;
    if (source.roleSubscriptions == null) source.roleSubscriptions = [];
    source.roleSubscriptions.push({
      roleID: role.id,
      roleName: role.name
    })
    message.channel.sendMessage(`Global subscription successfully added for \`${message.guild.roles.get(role.id).name}\` to feed \`${rssList[rssIndex].title}\`.`);
    console.log(`RSS Role Customization: (${message.guild.id}, ${message.guild.name}) => (${message.guild.roles.get(role.id).id}, ${message.guild.roles.get(role.id).name}) => Global subscription added to feed \`${rssList[rssIndex].title}\`.`);
    return fileOps.updateFile(`./sources/${message.guild.id}.json`, guildRss, `../sources/${message.guild.id}.json`);
  }

  function removeGlobalSub (rssIndex, role) {
    let source = rssList[rssIndex]
    var found = false
    if (source.roleSubscriptions.length == 0) delete source.roleSubscriptions;
    if (source.roleSubscriptions == null) return message.channel.sendMessage("This role is not globally subscribed to this feed.");

    for (let globalSubber in source.roleSubscriptions) {
      if (source.roleSubscriptions[globalSubber].roleID == role.id) {source.roleSubscriptions.splice(subbedRole, 1); found = true;}
    }
    if (source.roleSubscriptions.length == 0) delete source.roleSubscriptions;
    if (found == false) return message.channel.sendMessage(`The role \`${role.name} does not have a global subscription to this feed.`);
    else message.channel.sendMessage(`Successfully removed the global subscription of the role \`${role.name}\` from the feed \`${rssList[rssIndex].title}\``);
    console.log(`RSS Role Customization: (${message.guild.id}, ${message.guild.name}) => (${role.id}, ${role.name}) => Removed global subscription for feed \`${rssList[rssIndex].title}\``);
    return fileOps.updateFile(`./sources/${message.guild.id}.json`, guildRss, `../sources/${message.guild.id}.json`);
  }

  function openSubMenu (rssIndex, role, isGlobalSub) {
    var subMenu = {embed: {
      color: rssConfig.menuColor,
      author: {},
      description: `**Selected Role**: ${role.name}\n**Feed Title:** ${rssList[rssIndex].title}\n**Feed Link:** ${rssList[rssIndex].link}\nSelect an option by typing its number, or type *exit* to cancel.\n_____`,
      footer: {}
    }}
    if (!isGlobalSub) {
      subMenu.embed.fields = [{name: `1) Add filter to filtered subscription`, value: `Add a filtered subscription so that this role will get mentioned everytime an article from a feed passes its filter tests.`},
                              {name: `2) Remove filtered subscription`, value: `Remove a word/phrase from this role's subscription to a feed.`}];
      subMenu.embed.author.name = `Role Customization - Add/Remove Filtered Subscription`;
    }
    else {
      subMenu.embed.fields = [{name: `1) Add global subscription`, value: `Have the role get mentioned every time a new article is posted from this feed.`},
                              {name: `2) Remove global subscription`, value: `Remove the role's subscription to this feed.`}];
      subMenu.embed.author.name = `Role Cusotmization: Add/Remove Global Subscription`;
    }

    message.channel.sendMessage("",subMenu)

    const filterOptionCollector = message.channel.createCollector(collectorFilter,{time:240000});
    filterOptionCollector.on('message', function (m) {
      let optionSelected = m.content
      if (optionSelected.toLowerCase() == "exit") return filterOptionCollector.stop("RSS Role Customization menu closed.");
      if (optionSelected == 1) {
        filterOptionCollector.stop();
        if (!isGlobalSub) addFilter(message, rssIndex, role);
        else addGlobalSub(rssIndex, role);
      }
      else if (optionSelected == 2) {
        filterOptionCollector.stop();
        if (!isGlobalSub) removeFilter(message, rssIndex, role);
        else removeGlobalSub(rssIndex, role);
      }
      else message.channel.sendMessage("That is not a valid option. Try again.")
    })

    filterOptionCollector.on('end', (collected, reason) => {
      if (reason == "time") {
        return message.channel.sendMessage(`I have closed the menu due to inactivity.`);
      }
      else if (reason !== "user") {
        return message.channel.sendMessage(reason);
      }
    });
  }

  function printSubscriptions () {
    let guild = message.guild
    var subList = {}
    var msg = {embed: {
      color: rssConfig.menuColor,
      description: `\nBelow are the feed titles with any roles subscribed to that feed under it.\n_____`,
      author: {name: `Subscribed Roles List`},
      fields: [],
      footer: {}
    }}

    for (let rssIndex in rssList) {
      let source = rssList[rssIndex];
      //global sub list is an array
      if (source.roleSubscriptions != null) {
        for (let globalSubber in source.roleSubscriptions) {
          if (subList[source.title] == null) subList[source.title] = {};
          if (subList[source.title].globalSubs == null) subList[source.title].globalSubs = [];

          let globalSubbedRole = guild.roles.get(source.roleSubscriptions[globalSubber].roleID).name;
          subList[source.title].globalSubs.push(globalSubbedRole);
        }
      }
      //filtered sub list is an object
      if (source.filters != null && source.filters.roleSubscriptions != null) {
        for (let filteredSubber in source.filters.roleSubscriptions) {
          if (subList[source.title] == null) subList[source.title] = {};
          if (subList[source.title].filteredSubs == null) subList[source.title].filteredSubs = [];

          let filteredSubbedRole = guild.roles.get(filteredSubber).name;
          subList[source.title].filteredSubs.push(filteredSubbedRole);
        }
      }
    }

    if (isEmptyObject(subList)) return message.channel.sendMessage("There are no roles with subscriptions.");
    else {
      for (let feed in subList) {
        var list = "";

        var globalSubList = "**Global Subscriptions:**\n";
        for (let globalSubber in subList[feed].globalSubs) {
           globalSubList += `${subList[feed].globalSubs[globalSubber]}\n`;
        }
        if (globalSubList !== "**Global Subscriptions:**\n") list+= globalSubList;

        var filteredSubList = "\n**Filtered Subscriptions:**\n";
        for (let filteredSubber in subList[feed].filteredSubs) {
          list += `${subList[feed].filteredSubs[filteredSubber]}\n`;
        }
        if (filteredSubList !== "\n**Filtered Subscriptions:**\n") list += filteredSubList;
        msg.embed.fields.push({name: `${feed}`, value: list, inline: true});
      }
      return message.channel.sendMessage("",msg);
    }
  }

  function deleteSubscription (roleID) {
    var found = false
    for (var index in rssList) {
      var source = rssList[index];
      //global sub list is an array
      if (source.roleSubscriptions != null) {
        for (let globalSubber in source.roleSubscriptions) {
          if (source.roleSubscriptions[globalSubber].roleID == roleID) {source.roleSubscriptions.splice(globalSubber, 1); found = true;}
        }
      }
      //filtered sub list is an object
      if (source.filters != null && source.filters.roleSubscriptions != null) {
        for (let filteredSubber in source.filters.roleSubscriptions) {
          if (filteredSubber == roleID) {delete source.filters.roleSubscriptions[filteredSubber]; found = true;}
        }
      }
    }
    if (found == false) return message.channel.sendMessage("This role has no subscriptions to remove.");
    if (source.roleSubscriptions != null && source.roleSubscriptions.length == 0) delete source.roleSubscriptions;
    if (source.filters != null && isEmptyObject(source.filters.roleSubscriptions)) delete source.filters.roleSubscriptions;
    if (source.filters != null && isEmptyObject(source.filters)) delete source.filters;
    fileOps.updateFile(`./sources/${message.guild.id}.json`, guildRss, `../sources/${message.guild.id}.json`)
    console.log(`RSS Role Customization: (${message.guild.id}, ${message.guild.name}) => (${message.guild.roles.get(roleID).id}, ${message.guild.roles.get(roleID).name}) => All subscriptions deleted.`);
    return message.channel.sendMessage(`All subscriptions successfully deleted for role \`${message.guild.roles.get(roleID).name}\`.`)
  }

  var menu = {embed: {
    color: rssConfig.menuColor,
    description: `Select an option by typing its number, or type *exit* to cancel.\n_____`,
    author: {name: `Role Customization - Role Subscription Options`},
    fields: [{name: `1) Add/Remove Global Subscriptions for a Role`, value: `Enable mentions for a role for all delivered articles of this feed.\n*Using global subscriptions will disable filtered subscriptions if enabled for that role.*`},
            {name: `2) Add/Remove Filtered Subscriptions for a Role`, value: `Create role-specific filters where only selected articles will mention a role.\n*Using filtered subscriptions will disable global subscriptions if enabled for that role.*`},
            {name: `3) Disable All Subscriptions for a Role`, value: `Disable all subscriptions for a role.`},
            {name: `4) List Roles with Subscriptions`, value: `List all roles with all types of subscriptions.`}],
    footer: {}
  }}

  message.channel.sendMessage("", menu)

  const collector = message.channel.createCollector(collectorFilter,{time:240000});

  collector.on('message', function (m) {
    let optionSelected = m.content
    if (optionSelected.toLowerCase() == "exit") return collector.stop("RSS Role Customization menu closed.");
    else if (optionSelected == 4){
      collector.stop()
      return printSubscriptions(collector);
    }
    else if (optionSelected == 3 || optionSelected == 2 || optionSelected == 1) {
      collector.stop()
      getRole(message, function(role) {
        if (!role) return;
        else if (optionSelected == 3) {
          return deleteSubscription(role.id);
        }
        else printFeeds(bot, message, true, command, function(rssIndex) {
          if (optionSelected == 2) {
            return openSubMenu(rssIndex, role, false);
          }
          else if (optionSelected == 1) {
            return openSubMenu(rssIndex, role, true);
          }
        })
      })
    }
    else message.channel.sendMessage("That is not a valid option. Try again.");
  })

  collector.on('end', (collected, reason) => {
    if (reason == "time") return message.channel.sendMessage(`I have closed the menu due to inactivity.`);
    else if (reason !== "user") return message.channel.sendMessage(reason);
  });

}
<commit_msg>better logging and clearer menu descrips<commit_after>const getRole = require('./util/getRole.js')
const printFeeds = require('./util/printFeeds.js')
const fileOps = require('../util/updateJSON.js')
const addFilter = require('./filterAdd.js')
const removeFilter = require('./filterRemove.js')
const rssConfig = require('../config.json')

module.exports = function(bot, message, command) {
  const collectorFilter = m => m.author.id == message.author.id;

  try {var guildRss = require(`../sources/${message.guild.id}.json`)}
  catch (e) {return message.channel.sendMessage("Cannot add role customizations without any active feeds.")}

  var rssList = guildRss.sources
  var role

  function isEmptyObject(obj) {
      for(var prop in obj) {
          if(obj.hasOwnProperty(prop))
              return false;
      }
      return JSON.stringify(obj) === JSON.stringify({});
  }

  function addGlobalSub (rssIndex, role) {
    let source = rssList[rssIndex]
    //remove any filtered subscriptions when adding global subscription
    if (source.filters != null && source.filters.roleSubscriptions != null && source.filters.roleSubscriptions[role.id] != null) delete source.filters.roleSubscriptions[role.id];
    if (source.filters != null && source.filters.roleSubscriptions != null && isEmptyObject(source.filters.roleSubscriptions)) delete source.filters.roleSubscriptions;
    if (source.filters != null && isEmptyObject(source.filters)) delete source.filters;
    if (source.roleSubscriptions == null) source.roleSubscriptions = [];
    source.roleSubscriptions.push({
      roleID: role.id,
      roleName: role.name
    })
    message.channel.sendMessage(`Global subscription successfully added for \`${message.guild.roles.get(role.id).name}\` to feed \`${rssList[rssIndex].title}\`.`);
    console.log(`Guild Roles: (${message.guild.id}, ${message.guild.name}) => (${message.guild.roles.get(role.id).id}, ${message.guild.roles.get(role.id).name}) => Global subscription added to feed \`${rssList[rssIndex].title}\`.`);
    return fileOps.updateFile(`./sources/${message.guild.id}.json`, guildRss, `../sources/${message.guild.id}.json`);
  }

  function removeGlobalSub (rssIndex, role) {
    let source = rssList[rssIndex]
    var found = false
    if (source.roleSubscriptions.length == 0) delete source.roleSubscriptions;
    if (source.roleSubscriptions == null) return message.channel.sendMessage("This role is not globally subscribed to this feed.");

    for (let globalSubber in source.roleSubscriptions) {
      if (source.roleSubscriptions[globalSubber].roleID == role.id) {source.roleSubscriptions.splice(subbedRole, 1); found = true;}
    }
    if (source.roleSubscriptions.length == 0) delete source.roleSubscriptions;
    if (found == false) return message.channel.sendMessage(`The role \`${role.name} does not have a global subscription to this feed.`);
    else message.channel.sendMessage(`Successfully removed the global subscription of the role \`${role.name}\` from the feed \`${rssList[rssIndex].title}\``);
    console.log(`Guild Roles: (${message.guild.id}, ${message.guild.name}) => (${role.id}, ${role.name}) => Removed global subscription for feed \`${rssList[rssIndex].title}\``);
    return fileOps.updateFile(`./sources/${message.guild.id}.json`, guildRss, `../sources/${message.guild.id}.json`);
  }

  function openSubMenu (rssIndex, role, isGlobalSub) {
    var subMenu = {embed: {
      color: rssConfig.menuColor,
      author: {},
      description: `**Selected Role**: ${role.name}\n**Feed Title:** ${rssList[rssIndex].title}\n**Feed Link:** ${rssList[rssIndex].link}\n\nSelect an option by typing its number, or type *exit* to cancel.\n_____`,
      footer: {}
    }}
    if (!isGlobalSub) {
      subMenu.embed.fields = [{name: `1) Add filter to filtered subscription`, value: `Add a filtered subscription so that this role will get mentioned everytime an article from a feed passes its filter tests.`},
                              {name: `2) Remove filtered subscription`, value: `Remove a word/phrase from this role's subscription to a feed.`}];
      subMenu.embed.author.name = `Role Customization - Add/Remove Filtered Subscription`;
    }
    else {
      subMenu.embed.fields = [{name: `1) Add global subscription`, value: `Have the role get mentioned every time a new article is posted from this feed.`},
                              {name: `2) Remove global subscription`, value: `Remove the role's subscription to this feed.`}];
      subMenu.embed.author.name = `Role Cusotmization: Add/Remove Global Subscription`;
    }

    message.channel.sendMessage("",subMenu)

    const filterOptionCollector = message.channel.createCollector(collectorFilter,{time:240000});
    filterOptionCollector.on('message', function (m) {
      let optionSelected = m.content
      if (optionSelected.toLowerCase() == "exit") return filterOptionCollector.stop("RSS Role Customization menu closed.");
      if (optionSelected == 1) {
        filterOptionCollector.stop();
        if (!isGlobalSub) addFilter(message, rssIndex, role);
        else addGlobalSub(rssIndex, role);
      }
      else if (optionSelected == 2) {
        filterOptionCollector.stop();
        if (!isGlobalSub) removeFilter(message, rssIndex, role);
        else removeGlobalSub(rssIndex, role);
      }
      else message.channel.sendMessage("That is not a valid option. Try again.")
    })

    filterOptionCollector.on('end', (collected, reason) => {
      if (reason == "time") {
        return message.channel.sendMessage(`I have closed the menu due to inactivity.`);
      }
      else if (reason !== "user") {
        return message.channel.sendMessage(reason);
      }
    });
  }

  function printSubscriptions () {
    let guild = message.guild
    var subList = {}
    var msg = {embed: {
      color: rssConfig.menuColor,
      description: `\nBelow are the feed titles with any roles subscribed to that feed under it.\n_____`,
      author: {name: `Subscribed Roles List`},
      fields: [],
      footer: {}
    }}

    for (let rssIndex in rssList) {
      let source = rssList[rssIndex];
      //global sub list is an array
      if (source.roleSubscriptions != null) {
        for (let globalSubber in source.roleSubscriptions) {
          if (subList[source.title] == null) subList[source.title] = {};
          if (subList[source.title].globalSubs == null) subList[source.title].globalSubs = [];

          let globalSubbedRole = guild.roles.get(source.roleSubscriptions[globalSubber].roleID).name;
          subList[source.title].globalSubs.push(globalSubbedRole);
        }
      }
      //filtered sub list is an object
      if (source.filters != null && source.filters.roleSubscriptions != null) {
        for (let filteredSubber in source.filters.roleSubscriptions) {
          if (subList[source.title] == null) subList[source.title] = {};
          if (subList[source.title].filteredSubs == null) subList[source.title].filteredSubs = [];

          let filteredSubbedRole = guild.roles.get(filteredSubber).name;
          subList[source.title].filteredSubs.push(filteredSubbedRole);
        }
      }
    }

    if (isEmptyObject(subList)) return message.channel.sendMessage("There are no roles with subscriptions.");
    else {
      for (let feed in subList) {
        var list = "";

        var globalSubList = "**Global Subscriptions:**\n";
        for (let globalSubber in subList[feed].globalSubs) {
           globalSubList += `${subList[feed].globalSubs[globalSubber]}\n`;
        }
        if (globalSubList !== "**Global Subscriptions:**\n") list+= globalSubList;

        var filteredSubList = "\n**Filtered Subscriptions:**\n";
        for (let filteredSubber in subList[feed].filteredSubs) {
          list += `${subList[feed].filteredSubs[filteredSubber]}\n`;
        }
        if (filteredSubList !== "\n**Filtered Subscriptions:**\n") list += filteredSubList;
        msg.embed.fields.push({name: `${feed}`, value: list, inline: true});
      }
      return message.channel.sendMessage("",msg);
    }
  }

  function deleteSubscription (roleID) {
    var found = false
    for (var index in rssList) {
      var source = rssList[index];
      //global sub list is an array
      if (source.roleSubscriptions != null) {
        for (let globalSubber in source.roleSubscriptions) {
          if (source.roleSubscriptions[globalSubber].roleID == roleID) {source.roleSubscriptions.splice(globalSubber, 1); found = true;}
        }
      }
      //filtered sub list is an object
      if (source.filters != null && source.filters.roleSubscriptions != null) {
        for (let filteredSubber in source.filters.roleSubscriptions) {
          if (filteredSubber == roleID) {delete source.filters.roleSubscriptions[filteredSubber]; found = true;}
        }
      }
    }
    if (found == false) return message.channel.sendMessage("This role has no subscriptions to remove.");
    if (source.roleSubscriptions != null && source.roleSubscriptions.length == 0) delete source.roleSubscriptions;
    if (source.filters != null && isEmptyObject(source.filters.roleSubscriptions)) delete source.filters.roleSubscriptions;
    if (source.filters != null && isEmptyObject(source.filters)) delete source.filters;
    fileOps.updateFile(`./sources/${message.guild.id}.json`, guildRss, `../sources/${message.guild.id}.json`)
    console.log(`Guild Roles: (${message.guild.id}, ${message.guild.name}) => (${message.guild.roles.get(roleID).id}, ${message.guild.roles.get(roleID).name}) => All subscriptions deleted.`);
    return message.channel.sendMessage(`All subscriptions successfully deleted for role \`${message.guild.roles.get(roleID).name}\`.`)
  }

  var menu = {embed: {
    color: rssConfig.menuColor,
    description: `\nCurrent Channel: ${message.channel}\n\nSelect an option by typing its number, or type *exit* to cancel.\n_____`,
    author: {name: `Role Subscription Options`},
    fields: [{name: `1) Add/Remove Global Subscriptions for a Role`, value: `Enable mentions for a role for all delivered articles of this feed.\n*Using global subscriptions will disable filtered subscriptions if enabled for that role.*`},
            {name: `2) Add/Remove Filtered Subscriptions for a Role`, value: `Create role-specific filters where only selected articles will mention a role.\n*Using filtered subscriptions will disable global subscriptions if enabled for that role.*`},
            {name: `3) Disable All Subscriptions for a Role`, value: `Disable all subscriptions for a role.`},
            {name: `4) List Roles with Subscriptions`, value: `List all roles with all types of subscriptions.`}],
    footer: {}
  }}

  message.channel.sendMessage("", menu)

  const collector = message.channel.createCollector(collectorFilter,{time:240000});

  collector.on('message', function (m) {
    let optionSelected = m.content
    if (optionSelected.toLowerCase() == "exit") return collector.stop("RSS Role Customization menu closed.");
    else if (optionSelected == 4){
      collector.stop()
      return printSubscriptions(collector);
    }
    else if (optionSelected == 3 || optionSelected == 2 || optionSelected == 1) {
      collector.stop()
      getRole(message, function(role) {
        if (!role) return;
        else if (optionSelected == 3) {
          return deleteSubscription(role.id);
        }
        else printFeeds(bot, message, true, command, function(rssIndex) {
          if (optionSelected == 2) {
            return openSubMenu(rssIndex, role, false);
          }
          else if (optionSelected == 1) {
            return openSubMenu(rssIndex, role, true);
          }
        })
      })
    }
    else message.channel.sendMessage("That is not a valid option. Try again.");
  })

  collector.on('end', (collected, reason) => {
    if (reason == "time") return message.channel.sendMessage(`I have closed the menu due to inactivity.`);
    else if (reason !== "user") return message.channel.sendMessage(reason);
  });

}
<|endoftext|>


<commit_before>'use strict';

var getAccount = require('../api/team/getS.js');

module.exports.pattern = /^show team$/i;
module.exports.command  = 'show team';
module.exports.run = run;

function run(commandText,callback){

  _getTeam(function(err,users){
    if(err)
      var replyMessageText = 'Error while getting team members: ' + err;
    else
      var replyMessageText = 'Your team members are (of monitored Repos) \n>>>' + users;
    callback(replyMessageText);
  });
}

function _getTeam(callback){
  getAccount(function(err, team) {
    if (err)
      callback(err);
    else{
      var users = '';
      team.forEach(function(user){
        users += '\n*' + user.name + '* `' + user.username + '`';
      });
      callback(null,users);
    }
  });
}<commit_msg>add user link in show team command<commit_after>'use strict';

var getAccount = require('../api/team/getS.js');

module.exports.pattern = /^show team$/i;
module.exports.command  = 'show team';
module.exports.run = run;

function run(commandText,callback){

  _getTeam(function(err,users){
    if(err)
      var replyMessageText = 'Error while getting team members: ' + err;
    else
      var replyMessageText = 'Your team members are (of monitored Repos) \n>>>' + users;
    callback(replyMessageText);
  });
}

function _getTeam(callback){
  getAccount(function(err, team) {
    if (err)
      callback(err);
    else{
      var users = '';
      team.forEach(function(user){
        // *Name* <https://github.com/username|username>
        users += '\n*' + user.name + '* <' +
        "https://github.com/" + user.username + '|' + user.username + '>';
      });
      callback(null,users);
    }
  });
}<|endoftext|>


<commit_before>var request = require('request');
var q = require('q');
var _ = require('underscore');

var api = exports = module.exports = {};
var tokenPromise = null;

api.init = function() {
  this.settings = {};
  this.defaultConfiguration();
};

api.defaultConfiguration = function() {
  this.set('tokenEndpoint', 'token');
  this.set('maxLimit', 500);
};

api.urlFor = function(resource, id) {
  var url = this.settings.url + '/' + resource;
  if (id) {
    url = url + '/' + id;
  }

  return url;
};

api.getToken = function() {
  if (!tokenPromise) {
    var deferred = q.defer();
    tokenPromise = deferred.promise;

    request.post(
      this.urlFor(this.settings.tokenEndpoint),
      {form: {grant_type: 'client_credentials', client_id: this.settings.clientId, client_secret: this.settings.clientSecret}, json: true},
      function(error, res, body) {
        if (error) {
          deferred.reject(error);
        } else if (res.statusCode != 200) {
          deferred.reject(body);
        } else {
          deferred.resolve(body.access_token);
        }
      }
    );
  }

  return tokenPromise;
};

api.get = function(resource, id, parameters) {
  return this.getToken().then(_.bind(function(token) {
    var deferred = q.defer();

    request.get(
      this.urlFor(resource, id),
      {qs: parameters, headers: {'Authorization': 'Bearer ' + token}, json: true},
      function(error, res, body) {
        if (error) {
          deferred.reject(error);
        } else if (res.statusCode != 200) {
          deferred.reject(body);
        } else {
          deferred.resolve(body);
        }
      }
    );

    return deferred.promise;
  }, this));
};

api.getResult = function(resource, id, parameters) {
  return this.get(resource, id, parameters).get('result');
};

api.index = function(resource, parameters) {
  return this.getToken().then(_.bind(function(token) {
    var deferred = q.defer();

    request.get(this.urlFor(resource), {qs: parameters, headers: {'Authorization': 'Bearer ' + token}, json: true}, function(error, res, body) {
      if (error) {
        deferred.reject(error);
      } else if (res.statusCode != 200) {
        deferred.reject(body);
      } else {
        deferred.resolve(body);
      }
    });

    return deferred.promise;
  }, this));
};

api.indexAll = function(resource, parameters) {
  var promises = [];
  promises.push(this.index(resource, _.extend({}, parameters, {offset: 0, limit: this.settings.maxLimit})));
  return promises[0].then(_.bind(function(firstPage) {
    for (var offset = this.settings.maxLimit; offset < firstPage.pagination.total; offset += this.settings.maxLimit) {
      promises.push(this.index(resource, _.extend({}, parameters, {offset: offset, limit: this.settings.maxLimit})));
    }

    return q.all(promises).then(function(pages) {
      return _.flatten(_.pluck(pages, 'result'), true);
    });
  }, this));
};

api.set = function(setting, value) {
  if (arguments.length == 1) {
    return this.settings[setting];
  }

  this.settings[setting] = value;
  return this;
};
<commit_msg>Add a helper to consolidate response resolution.<commit_after>var request = require('request');
var q = require('q');
var _ = require('underscore');

var api = exports = module.exports = {};
var tokenPromise = null;

api.init = function() {
  this.settings = {};
  this.defaultConfiguration();
};

api.defaultConfiguration = function() {
  this.set('tokenEndpoint', 'token');
  this.set('maxLimit', 500);
};

api.urlFor = function(resource, id) {
  var url = this.settings.url + '/' + resource;
  if (id) {
    url = url + '/' + id;
  }

  return url;
};

api.getToken = function() {
  if (!tokenPromise) {
    var deferred = q.defer();
    tokenPromise = deferred.promise;

    request.post(
      this.urlFor(this.settings.tokenEndpoint),
      {form: {grant_type: 'client_credentials', client_id: this.settings.clientId, client_secret: this.settings.clientSecret}, json: true},
      resolveResponse(deferred)
    );
  }

  return tokenPromise.get('access_token');
};

api.get = function(resource, id, parameters) {
  return this.getToken().then(_.bind(function(token) {
    var deferred = q.defer();

    request.get(
      this.urlFor(resource, id),
      {qs: parameters, headers: {'Authorization': 'Bearer ' + token}, json: true},
      resolveResponse(deferred)
    );

    return deferred.promise;
  }, this));
};

api.getResult = function(resource, id, parameters) {
  return this.get(resource, id, parameters).get('result');
};

api.index = function(resource, parameters) {
  return this.getToken().then(_.bind(function(token) {
    var deferred = q.defer();

    request.get(this.urlFor(resource), {qs: parameters, headers: {'Authorization': 'Bearer ' + token}, json: true}, resolveResponse(deferred));

    return deferred.promise;
  }, this));
};

api.indexAll = function(resource, parameters) {
  var promises = [];
  promises.push(this.index(resource, _.extend({}, parameters, {offset: 0, limit: this.settings.maxLimit})));
  return promises[0].then(_.bind(function(firstPage) {
    for (var offset = this.settings.maxLimit; offset < firstPage.pagination.total; offset += this.settings.maxLimit) {
      promises.push(this.index(resource, _.extend({}, parameters, {offset: offset, limit: this.settings.maxLimit})));
    }

    return q.all(promises).then(function(pages) {
      return _.flatten(_.pluck(pages, 'result'), true);
    });
  }, this));
};

api.set = function(setting, value) {
  if (arguments.length == 1) {
    return this.settings[setting];
  }

  this.settings[setting] = value;
  return this;
};

function resolveResponse(deferred) {
  return function(error, res, body) {
    if (error) {
      deferred.reject(error);
    } else if (res.statusCode != 200) {
      deferred.reject(body);
    } else {
      deferred.resolve(body);
    }
  };
}
<|endoftext|>