<commit_before>'use strict';

var five = require('johnny-five'),
    Raspi = require('raspi-io'),
    board,
    motors = {},
    on = true;
var sys = require('sys')
var exec = require('child_process').exec;
var rBoard = new five.Board({
	io: new Raspi()
});

rBoard.on("ready", function(){
	setInterval(function(){
		exec('sudo sh -c "echo ' + (on ? 1 : 0) + ' >/sys/class/leds/led0/brightness"',
			function(error, stdout, stderr) {
				sys.print('stdout: ' + stdout);
  			sys.print('stderr: ' + stderr);
  			if (error !== null) {
    			console.log('exec error: ' + error);
			  }
		});
		on = !on;
	}, 1000);
});

board = new five.Board({
  //port: ""
});

board.on('ready', function() {
  var configs = five.Motor.SHIELD_CONFIGS.ADAFRUIT_V1;
  motors.motor1 = new five.Motor(configs.M1);
  motors.motor2 = new five.Motor(configs.M2);
  motors.motor3 = new five.Motor(configs.M3);
  motors.motor4 = new five.Motor(configs.M4);
  console.log('board ready, created motors');
});

module.exports = function(socket) {
  console.log('setting up board socket listeners');
  socket.on('forward', function(data){
    motors.motor1.forward(255);
    motors.motor2.forward(255);
    motors.motor3.forward(255);
    motors.motor4.forward(255);
  });
  socket.on('backward', function(data){
    motors.motor1.reverse(125);
    motors.motor2.reverse(125);
    motors.motor3.reverse(125);
    motors.motor4.reverse(125);
  });
  socket.on('stop', function(data){
    motors.motor1.stop();
    motors.motor2.stop();
    motors.motor3.stop();
    motors.motor4.stop();
  });
  socket.on('left', function(data){
    motors.motor1.reverse(125);
    motors.motor2.reverse(125);
    motors.motor3.forward(125);
    motors.motor4.forward(125);
  });
  socket.on('right', function(data){
    motors.motor1.forward(125);
    motors.motor2.forward(125);
    motors.motor3.reverse(125);
    motors.motor4.reverse(125);
  });
}
<commit_msg>trying to get ardunio and pi happy<commit_after>'use strict';

var five = require('johnny-five'),
    Raspi = require('raspi-io'),
    board,
    motors = {},
    on = true;
var sys = require('sys')
var exec = require('child_process').exec;
board = new five.Board({
  //port: ""
});

board.on('ready', function() {
  setInterval(function(){
		exec('sudo sh -c "echo ' + (on ? 1 : 0) + ' >/sys/class/leds/led0/brightness"',
			function(error, stdout, stderr) {
  			if (error !== null) {
    			console.log('exec error: ' + error);
			  }
		});
		on = !on;
	}, 1000);
  var configs = five.Motor.SHIELD_CONFIGS.ADAFRUIT_V1;
  motors.motor1 = new five.Motor(configs.M1);
  motors.motor2 = new five.Motor(configs.M2);
  motors.motor3 = new five.Motor(configs.M3);
  motors.motor4 = new five.Motor(configs.M4);
  console.log('board ready, created motors');
});

var rBoard = new five.Board({
	io: new Raspi()
});
rBoard.on("ready", function(){
	console.log('raspi board ready, created motors');
});

module.exports = function(socket) {
  console.log('setting up board socket listeners');
  socket.on('forward', function(data){
    motors.motor1.forward(255);
    motors.motor2.forward(255);
    motors.motor3.forward(255);
    motors.motor4.forward(255);
  });
  socket.on('backward', function(data){
    motors.motor1.reverse(125);
    motors.motor2.reverse(125);
    motors.motor3.reverse(125);
    motors.motor4.reverse(125);
  });
  socket.on('stop', function(data){
    motors.motor1.stop();
    motors.motor2.stop();
    motors.motor3.stop();
    motors.motor4.stop();
  });
  socket.on('left', function(data){
    motors.motor1.reverse(125);
    motors.motor2.reverse(125);
    motors.motor3.forward(125);
    motors.motor4.forward(125);
  });
  socket.on('right', function(data){
    motors.motor1.forward(125);
    motors.motor2.forward(125);
    motors.motor3.reverse(125);
    motors.motor4.reverse(125);
  });
}
<|endoftext|>


<commit_before>var $ = require('../')

// import the "Foundation" framework and its dependencies
$.import('Foundation')

// create the mandatory NSAutoreleasePool instance
var pool = $.NSAutoreleasePool('alloc')('init')

// create an NSString of the applescript command that will be run
var command = $('tell (system info) to return system version')

// create an NSAppleScript instance with the `command` NSString
var appleScript = $.NSAppleScript('alloc')('initWithSource', command)

// finally execute the NSAppleScript instance synchronously
var resultObj = appleScript('executeAndReturnError', null)

// resultObj may be null` or an NSAppleEventDescriptor instance , so check first
if (resultObj) {
  console.dir(resultObj('stringValue').toString())
}
<commit_msg>example comment<commit_after>var $ = require('../')

// import the "Foundation" framework and its dependencies
$.import('Foundation')

// create the mandatory NSAutoreleasePool instance
var pool = $.NSAutoreleasePool('alloc')('init')

// create an NSString of the applescript command that will be run
var command = $('tell (system info) to return system version')

// create an NSAppleScript instance with the `command` NSString
var appleScript = $.NSAppleScript('alloc')('initWithSource', command)

// finally execute the NSAppleScript instance synchronously
var resultObj = appleScript('executeAndReturnError', null)

// resultObj may be null` or an NSAppleEventDescriptor instance , so check first
if (resultObj) {
  // print out the value
  console.dir(resultObj('stringValue').toString())
}
<|endoftext|>


<commit_before>'use strict';

import React, {
  AsyncStorage,
  Component,
  Dimensions,
  Image,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';

import Firebase from 'firebase';
import Icon from 'react-native-vector-icons/FontAwesome';
import Share from 'react-native-share';

import EventDetails from './event-details';
import PostDetails from './post-details';
import Profile from './profile';
import GridView from '../components/grid-view';
import Button from '../components/button';
import TextStyles from '../styles/text-styles';
import TitleBar from '../components/title-bar';

let database = new Firebase("poopapp1.firebaseio.com/");

class Notification extends Component {
  constructor(props) {
    super(props);
    /*new ListView.DataSource({
      rowHasChanged: (row1, row2) => row1 !== row2,
    })*/
    this.state = {
      dataSource: []
    };
  }

  componentDidMount() {
    var self = this;
    var loggedUserId;
    AsyncStorage.getItem('user_data', (error, result) => {
      loggedUserId = JSON.parse(result).uid;

      self.setState({
        userId: loggedUserId,
      });

      var notifications = database.child("users/" + loggedUserId + "/notifications");
      notifications.on("child_added", function(notificationSnapshot){
        let item = {
          who: notificationSnapshot.val().userID,
          type: notificationSnapshot.val().type,
          object: notificationSnapshot.val().objectID,
          action: notificationSnapshot.val().action,
          details: notificationSnapshot.val().textDetails,
          date: notificationSnapshot.val().date,
        };
        self.state.dataSource.unshift(item);
        self.forceUpdate();
      });
    });
  }

  renderRow(rowData){
      if (rowData.type == "events") //If the notification is for an event
      {
        if (rowData.action == "comment") //This is when someone comments on your event
        {
          var nameText;
          var profilePicture;
          var commentText;
          database.child("users/" + rowData.who).once("value", function(snapshot){
            nameText = snapshot.val().firstName + " " + snapshot.val().lastName;
            profilePicture = snapshot.val().profilePic.uri;
          });
          commentText = rowData.details;
          return (
            <View style = {styles.container}>
              <TouchableOpacity
                style = {styles.touchView}
                onPress = {() => this.goTo(rowData)}>
                <Image
                  style = {styles.userImage}
                  source = {{uri: profilePicture}}
                />
                <View style = {styles.descriptionView}>
                  <Text style = {styles.description}>
                    {nameText} commented on your event. "{commentText}"
                  </Text>
                </View>
              </TouchableOpacity>
            </View>
          );
        }
      }
      else if (rowData.type == "posts"){
        if (rowData.action == "comment") //This is when someone comments on your post
        {
          var nameText;
          var profilePicture;
          var commentText;
          database.child("users/" + rowData.who).once("value", function(snapshot){
            nameText = snapshot.val().firstName + " " + snapshot.val().lastName;
            profilePicture = snapshot.val().profilePic.uri;
          });
          commentText = rowData.details;
          return (
            <View style = {styles.container}>
              <TouchableOpacity
                style = {styles.touchView}
                onPress = {() => this.goTo(rowData)}>
                <Image
                  style = {styles.userImage}
                  source = {{uri: profilePicture}}
                />
                <View style = {styles.descriptionView}>
                  <Text style = {styles.description}>
                    {nameText} commented on your post. "{commentText}"
                  </Text>
                </View>
              </TouchableOpacity>
            </View>
          );
        }
        else if (rowData.action == "like") //This is when someone 'likes' your post
        {
          var nameText;
          var profilePicture;
          database.child("users/" + rowData.who).once("value", function(snapshot){
            nameText = snapshot.val().firstName + " " + snapshot.val().lastName;
            profilePicture = snapshot.val().profilePic.uri;
          });
          return (
            <View style = {styles.container}>
              <TouchableOpacity
                style = {styles.touchView}
                onPress = {() => this.goTo(rowData)}>
                <Image
                  style = {styles.userImage}
                  source = {{uri: profilePicture}}
                />
                <View style = {styles.descriptionView}>
                  <Text style = {styles.description}>
                    {nameText} liked your post.
                  </Text>
                </View>
              </TouchableOpacity>
            </View>
          );
        }
      }
      else if (rowData.type == "users"){
        var nameText;
        var profilePicture;
        database.child("users/" + rowData.who).once("value", function(snapshot){
          nameText = snapshot.val().firstName + " " + snapshot.val().lastName;
          profilePicture = snapshot.val().profilePic.uri;
        });
        var message =
          rowData.action === "friendRequest" ? "sent you a friend request." :
          rowData.action === "following" ? "is following you." :
          rowData.action === "friendAccept" ? "accepted your friend request." :
          "";
        return (
          <View style = {styles.container}>
            <TouchableOpacity
              style = {styles.touchView}
              onPress = {() => this.goTo(rowData)}>
              <Image
                style = {styles.userImage}
                source = {{uri: profilePicture}}
              />
              <View style = {styles.descriptionView}>
                <Text style = {styles.description}>
                  {nameText} {message}
                </Text>
              </View>
            </TouchableOpacity>
          </View>
        );
      }
      return (
        <View><Text>{rowData.object}</Text></View>
      );
  }

  queryData(){

  }

  render() {
    return (
      <View style = {{flex: 1}}>
        <TitleBar
          navigator = {this.props.navigator}
          text = "Notification"
        />
        <GridView
          dataSource = {this.state.dataSource}
          onRefresh = {this.queryData.bind(this)}
          renderRow = {this.renderRow.bind(this)}
        />
      </View>
    );
  }

  goTo(rowData){
    const navigator = this.props.navigator;
    switch(rowData.type){
      case "events":
        database.child("events/" + rowData.object).once("value", function(snapshot){
          navigator.push({component: EventDetails, state: snapshot});
        });
        break;
      case "posts":
        database.child("posts/" + rowData.object).once("value", function(snapshot){
          navigator.push({component: PostDetails, state: snapshot});
        });
      case "users":
        navigator.push({component: Profile, state: rowData.object});
        break;
    }
  }
}

const styles = StyleSheet.create({
  container: {
    width: Dimensions.get("window").width,
    borderBottomWidth: 1,
    borderColor: 'gray',
  },
  userImage: {
    width: 25,
    height: 25,
    margin: 10,
  },
  touchView: {
    flexDirection: 'row',
  },
  descriptionView: {
    flex: 1,
    padding: 10,
  },
  description: {
  }
});

module.exports = Notification;
<commit_msg>Fixed notification for posts.<commit_after>'use strict';

import React, {
  AsyncStorage,
  Component,
  Dimensions,
  Image,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';

import Firebase from 'firebase';
import Icon from 'react-native-vector-icons/FontAwesome';
import Share from 'react-native-share';

import EventDetails from './event-details';
import PostDetails from './post-details';
import Profile from './profile';
import GridView from '../components/grid-view';
import Button from '../components/button';
import TextStyles from '../styles/text-styles';
import TitleBar from '../components/title-bar';

let database = new Firebase("poopapp1.firebaseio.com/");

class Notification extends Component {
  constructor(props) {
    super(props);
    /*new ListView.DataSource({
      rowHasChanged: (row1, row2) => row1 !== row2,
    })*/
    this.state = {
      dataSource: []
    };
  }

  componentDidMount() {
    var self = this;
    var loggedUserId;
    AsyncStorage.getItem('user_data', (error, result) => {
      loggedUserId = JSON.parse(result).uid;

      self.setState({
        userId: loggedUserId,
      });

      var notifications = database.child("users/" + loggedUserId + "/notifications");
      notifications.on("child_added", function(notificationSnapshot){
        let item = {
          who: notificationSnapshot.val().userID,
          type: notificationSnapshot.val().type,
          object: notificationSnapshot.val().objectID,
          action: notificationSnapshot.val().action,
          details: notificationSnapshot.val().textDetails,
          date: notificationSnapshot.val().date,
        };
        self.state.dataSource.unshift(item);
        self.forceUpdate();
      });
    });
  }

  renderRow(rowData){
      if (rowData.type == "events") //If the notification is for an event
      {
        if (rowData.action == "comment") //This is when someone comments on your event
        {
          var nameText;
          var profilePicture;
          var commentText;
          database.child("users/" + rowData.who).once("value", function(snapshot){
            nameText = snapshot.val().firstName + " " + snapshot.val().lastName;
            profilePicture = snapshot.val().profilePic.uri;
          });
          commentText = rowData.details;
          return (
            <View style = {styles.container}>
              <TouchableOpacity
                style = {styles.touchView}
                onPress = {() => this.goTo(rowData)}>
                <Image
                  style = {styles.userImage}
                  source = {{uri: profilePicture}}
                />
                <View style = {styles.descriptionView}>
                  <Text style = {styles.description}>
                    {nameText} commented on your event. "{commentText}"
                  </Text>
                </View>
              </TouchableOpacity>
            </View>
          );
        }
      }
      else if (rowData.type == "posts"){
        if (rowData.action == "comment") //This is when someone comments on your post
        {
          var nameText;
          var profilePicture;
          var commentText;
          database.child("users/" + rowData.who).once("value", function(snapshot){
            nameText = snapshot.val().firstName + " " + snapshot.val().lastName;
            profilePicture = snapshot.val().profilePic.uri;
          });
          commentText = rowData.details;
          return (
            <View style = {styles.container}>
              <TouchableOpacity
                style = {styles.touchView}
                onPress = {() => this.goTo(rowData)}>
                <Image
                  style = {styles.userImage}
                  source = {{uri: profilePicture}}
                />
                <View style = {styles.descriptionView}>
                  <Text style = {styles.description}>
                    {nameText} commented on your post. "{commentText}"
                  </Text>
                </View>
              </TouchableOpacity>
            </View>
          );
        }
        else if (rowData.action == "like") //This is when someone 'likes' your post
        {
          var nameText;
          var profilePicture;
          database.child("users/" + rowData.who).once("value", function(snapshot){
            nameText = snapshot.val().firstName + " " + snapshot.val().lastName;
            profilePicture = snapshot.val().profilePic.uri;
          });
          return (
            <View style = {styles.container}>
              <TouchableOpacity
                style = {styles.touchView}
                onPress = {() => this.goTo(rowData)}>
                <Image
                  style = {styles.userImage}
                  source = {{uri: profilePicture}}
                />
                <View style = {styles.descriptionView}>
                  <Text style = {styles.description}>
                    {nameText} liked your post.
                  </Text>
                </View>
              </TouchableOpacity>
            </View>
          );
        }
      }
      else if (rowData.type == "users"){
        var nameText;
        var profilePicture;
        database.child("users/" + rowData.who).once("value", function(snapshot){
          nameText = snapshot.val().firstName + " " + snapshot.val().lastName;
          profilePicture = snapshot.val().profilePic.uri;
        });
        var message =
          rowData.action === "friendRequest" ? "sent you a friend request." :
          rowData.action === "following" ? "is following you." :
          rowData.action === "friendAccept" ? "accepted your friend request." :
          "";
        return (
          <View style = {styles.container}>
            <TouchableOpacity
              style = {styles.touchView}
              onPress = {() => this.goTo(rowData)}>
              <Image
                style = {styles.userImage}
                source = {{uri: profilePicture}}
              />
              <View style = {styles.descriptionView}>
                <Text style = {styles.description}>
                  {nameText} {message}
                </Text>
              </View>
            </TouchableOpacity>
          </View>
        );
      }
      return (
        <View><Text>{rowData.object}</Text></View>
      );
  }

  queryData(){

  }

  render() {
    return (
      <View style = {{flex: 1}}>
        <TitleBar
          navigator = {this.props.navigator}
          text = "Notification"
        />
        <GridView
          dataSource = {this.state.dataSource}
          onRefresh = {this.queryData.bind(this)}
          renderRow = {this.renderRow.bind(this)}
        />
      </View>
    );
  }

  goTo(rowData){
    const navigator = this.props.navigator;
    switch(rowData.type){
      case "events":
        database.child("events/" + rowData.object).once("value", function(snapshot){
          navigator.push({component: EventDetails, state: snapshot});
        });
        break;
      case "posts":
        database.child("posts/" + rowData.object).once("value", function(snapshot){
          navigator.push({component: PostDetails, state: snapshot});
        });
        break;
      case "users":
        navigator.push({component: Profile, state: rowData.object});
        break;
    }
  }
}

const styles = StyleSheet.create({
  container: {
    width: Dimensions.get("window").width,
    borderBottomWidth: 1,
    borderColor: 'gray',
  },
  userImage: {
    width: 25,
    height: 25,
    margin: 10,
  },
  touchView: {
    flexDirection: 'row',
  },
  descriptionView: {
    flex: 1,
    padding: 10,
  },
  description: {
  }
});

module.exports = Notification;
<|endoftext|>


<commit_before>'use strict';

var React = require('react-native');
var Dimensions = require('Dimensions');
var {width, height} = Dimensions.get('window');
var dismissKeyboard = require('dismissKeyboard');
var {
    Animated,
    View,
    ScrollView,
    DeviceEventEmitter,
    } = React;

class CoreKeyboardAwareView extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      height: new Animated.Value(0)
    }
    this.debug = false;
  }

  componentDidMount() {
    DeviceEventEmitter.addListener('keyboardWillShow', this.onKeyboardWillShow.bind(this))
    DeviceEventEmitter.addListener('keyboardWillHide', this.onKeyboardWillHide.bind(this))
  }

  componentWillUnmount() {
    DeviceEventEmitter.removeAllListeners('keyboardWillShow');
    DeviceEventEmitter.removeAllListeners('keyboardWillHide');
  }

  debugLog() {
    if (this.debug) {
      console.log.apply(this, arguments);
    }
  }

  onKeyboardWillShow(e) {
    var endY = e.endCoordinates.screenY
    var startY = e.startCoordinates.screenY
    this.debugLog(e);

    requestAnimationFrame(() => {
      this.outerView.measure((ox, oy, width, height, px, py) => {
        this.debugLog(ox, oy, px, py);
        // target scrollView height should be :
        //   remaining height OR outerView height
        // = screen height - keyboard height OR outerView height
        var remainScreenMaxHeight = endY - py;
        var outerViewMaxHeight = height;
        var maxHeight = remainScreenMaxHeight;
        if (maxHeight > outerViewMaxHeight) {
          maxHeight = outerViewMaxHeight;
        }

        Animated.timing(
            this.state.height,
            {
              toValue: maxHeight,
              duration: this.props.animated ? 200 : 0,
            }
        ).start();

        this.debugLog("InnerView height should be ..." + maxHeight, remainScreenMaxHeight, outerViewMaxHeight);
        //requestAnimationFrame(() => {
        //  this.innerView.measure((ox, oy, width, height, px, py) => {
        //    this.debugLog("And it is... " + height);
        //  })
        //})
      });
    })
  }
  onKeyboardWillHide(e) {
    var endY = e.endCoordinates.screenY
    var startY = e.startCoordinates.screenY
    this.debugLog(e);

    requestAnimationFrame(() => {
      this.outerView.measure((ox, oy, width, height, px, py) => {
        this.debugLog(ox, oy, px, py);
        // target scrollView height should be :
        //   remaining height OR outerView height
        // = screen height - keyboard height OR outerView height
        var remainScreenMaxHeight = endY;
        var outerViewMaxHeight = height;
        var maxHeight = remainScreenMaxHeight;
        if (maxHeight > outerViewMaxHeight) {
          maxHeight = outerViewMaxHeight;
        }

        Animated.timing(
            this.state.height,
            {
              toValue: maxHeight,
              duration: this.props.animated ? 200 : 0,
            }
        ).start();

        this.debugLog("ScrollView height should be ..." + maxHeight);
      });
    })
  }

  render() {
    return (
        <View
            ref={(ref) => {this.outerView = ref;}}
            style={[{flex: 1}, this.props.style]}
            onLayout={(e) => { var {x, y, width, height} = e.nativeEvent.layout;
            Animated.timing(
            this.state.height,
            {
              toValue: height,
              duration: 0,
            }
        ).start();
            dismissKeyboard(); } }>
          <Animated.View
              ref={(ref) => {this.innerView = ref;}}
              style={[{height: this.state.height}, this.props.innerViewStyle]}
              onLayout={(e) => { var {x, y, width, height} = e.nativeEvent.layout; } }>
            {this.props.children}
          </Animated.View>
        </View>
    )
  }
}

module.exports = CoreKeyboardAwareView;<commit_msg>Fix dimension require fail<commit_after>'use strict';

var React = require('react-native');
var dismissKeyboard = require('dismissKeyboard');
var {
    Dimensions,
    Animated,
    View,
    ScrollView,
    DeviceEventEmitter,
    } = React;
var {width, height} = Dimensions.get('window');

class CoreKeyboardAwareView extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      height: new Animated.Value(0)
    }
    this.debug = false;
  }

  componentDidMount() {
    DeviceEventEmitter.addListener('keyboardWillShow', this.onKeyboardWillShow.bind(this))
    DeviceEventEmitter.addListener('keyboardWillHide', this.onKeyboardWillHide.bind(this))
  }

  componentWillUnmount() {
    DeviceEventEmitter.removeAllListeners('keyboardWillShow');
    DeviceEventEmitter.removeAllListeners('keyboardWillHide');
  }

  debugLog() {
    if (this.debug) {
      console.log.apply(this, arguments);
    }
  }

  onKeyboardWillShow(e) {
    var endY = e.endCoordinates.screenY
    var startY = e.startCoordinates.screenY
    this.debugLog(e);

    requestAnimationFrame(() => {
      this.outerView.measure((ox, oy, width, height, px, py) => {
        this.debugLog(ox, oy, px, py);
        // target scrollView height should be :
        //   remaining height OR outerView height
        // = screen height - keyboard height OR outerView height
        var remainScreenMaxHeight = endY - py;
        var outerViewMaxHeight = height;
        var maxHeight = remainScreenMaxHeight;
        if (maxHeight > outerViewMaxHeight) {
          maxHeight = outerViewMaxHeight;
        }

        Animated.timing(
            this.state.height,
            {
              toValue: maxHeight,
              duration: this.props.animated ? 200 : 0,
            }
        ).start();

        this.debugLog("InnerView height should be ..." + maxHeight, remainScreenMaxHeight, outerViewMaxHeight);
        //requestAnimationFrame(() => {
        //  this.innerView.measure((ox, oy, width, height, px, py) => {
        //    this.debugLog("And it is... " + height);
        //  })
        //})
      });
    })
  }
  onKeyboardWillHide(e) {
    var endY = e.endCoordinates.screenY
    var startY = e.startCoordinates.screenY
    this.debugLog(e);

    requestAnimationFrame(() => {
      this.outerView.measure((ox, oy, width, height, px, py) => {
        this.debugLog(ox, oy, px, py);
        // target scrollView height should be :
        //   remaining height OR outerView height
        // = screen height - keyboard height OR outerView height
        var remainScreenMaxHeight = endY;
        var outerViewMaxHeight = height;
        var maxHeight = remainScreenMaxHeight;
        if (maxHeight > outerViewMaxHeight) {
          maxHeight = outerViewMaxHeight;
        }

        Animated.timing(
            this.state.height,
            {
              toValue: maxHeight,
              duration: this.props.animated ? 200 : 0,
            }
        ).start();

        this.debugLog("ScrollView height should be ..." + maxHeight);
      });
    })
  }

  render() {
    return (
        <View
            ref={(ref) => {this.outerView = ref;}}
            style={[{flex: 1}, this.props.style]}
            onLayout={(e) => { var {x, y, width, height} = e.nativeEvent.layout;
            Animated.timing(
            this.state.height,
            {
              toValue: height,
              duration: 0,
            }
        ).start();
            dismissKeyboard(); } }>
          <Animated.View
              ref={(ref) => {this.innerView = ref;}}
              style={[{height: this.state.height}, this.props.innerViewStyle]}
              onLayout={(e) => { var {x, y, width, height} = e.nativeEvent.layout; } }>
            {this.props.children}
          </Animated.View>
        </View>
    )
  }
}

module.exports = CoreKeyboardAwareView;<|endoftext|>


<commit_before>var util = require('util'),
    twitter = require('twitter');
var twit;
var merge = require('merge');
var fs = require('fs')
var colors = require('colors');

var DUMMY_SEARCH = false;
var DUMMY_TWEET = false;
var WAIT_SECONDS = 120;
var QUERY = "";
var TWEET_CALLBACK = null;
var DB = null;

var COUNTDOWN_OUTPUT = false;

var TWITTER_ACCOUNT_NAME = "weathermcr";

var DEFAULT_STREAM_SLEEP_SECONDS = 5;

// --- SQL ---
var sql = [];
sql['createSeenTweets'] = 'CREATE TABLE IF NOT EXISTS seen_tweets ' +
                          '(id INTEGER PRIMARY KEY, time DATETIME DEFAULT current_timestamp, text TEXT, user_id INTEGER,' +
                          ' username TEXT, action_taken TEXT, streamed BOOLEAN)';
sql['createSentTweets'] = 'CREATE TABLE IF NOT EXISTS sent_tweets ' +
                          '(id INTEGER PRIMARY KEY AUTOINCREMENT, text TEXT, related_tweet_id INTEGER)';
sql['createAPILogin'] =   'CREATE TABLE IF NOT EXISTS api_login ' +
                          '(id INTEGER PRIMARY KEY AUTOINCREMENT, access_token_key TEXT, access_token_secret TEXT)';

sql['selectNewestAPI'] =     'SELECT * FROM api_login ORDER BY id DESC LIMIT 1';
sql['selectNewestTweet'] =   'SELECT id FROM seen_tweets WHERE streamed = 0 ORDER BY id DESC LIMIT 1';
sql['selectExistingTweet'] = "SELECT 1 as 'exist' FROM seen_tweets WHERE id = $tweet_id LIMIT 1";

sql['updateActionTaken'] = 'UPDATE seen_tweets SET action_taken = $action WHERE id = $id';

sql['insertSeenTweet'] = 'INSERT INTO seen_tweets (id, text, user_id, username, streamed) ' +
                         'VALUES ($id, $text, $user_id, $username, $streamed)';
sql['logSentTweet'] =    'INSERT INTO sent_tweets (text, related_tweet_id) VALUES ($text, $related_id)';
sql['insertAPILogin'] =  'INSERT INTO api_login (access_token_key, access_token_secret) VALUES ($key, $secret)';

// --- public
exports.config = function(config, wait_seconds, database) {
    twit = new twitter(config);
    WAIT_SECONDS = wait_seconds;
    DB = database;
}

exports.dummy = function(search, tweets) {
    DUMMY_SEARCH = search;
    DUMMY_TWEET = tweets;
    if(DUMMY_SEARCH)
      console.log("Using dummy twitter search");
    if(DUMMY_TWEET)
      console.log("Using dummy twitter tweet");
}

exports.start = function(query, tweet_callback, callback) {
    QUERY = query;
    TWEET_CALLBACK = tweet_callback;

    // Ensure the database is ready for use
    DB.serialize(function() {
      DB.run(sql['createSeenTweets']);
      DB.run(sql['createSentTweets']);
      DB.run(sql['createAPILogin']);
    });

    DB.get(sql['selectNewestAPI'], function(err, result) {

      if(result) {
          console.info("Using stored authentication");
          params = { 'since_id': (result.id - 1500) } // for some reason this needs to be done...

          twit.options.access_token_key = result.access_token_key;
          twit.options.access_token_secret = result.access_token_secret;

          start(callback);
      } else {
          console.info("Authentication is needed before bot can start.");
          requireAuthentication(function() {
              //reusable API access
              var insert = DB.prepare(sql['insertAPILogin']);
              insert.run({ $key: twit.options.access_token_key, $secret: twit.options.access_token_secret });

              start(callback);
          });

      }

    });
}

exports.updateActionTaken = function(tweet, actionTaken) {
    var update = DB.prepare(sql['updateActionTaken']);
    update.bind({$id: tweet.id, $action: actionTaken });
    update.run();
}

exports.sendReply = function(reply_to, message, callback, disable_dummy_tweet) {
    if(typeof disable_dummy_tweet === 'undefined')
        disable_dummy_tweet = false;

    // Must include @ for reply, else twitter rejects it
    if(reply_to.user.screen_name)
      message = "@" + reply_to.user.screen_name + " " + message;

    // Twitter rejects us if we provide an incorrect reply_to.id
    params = {}
    if(reply_to.id)
      params.in_reply_to_status_id = reply_to.id;

    if(message.length > 140)
        console.error("Message over 140 letters: " + message);

    console.log("Attempting to send", message);

    if(DUMMY_TWEET && !disable_dummy_tweet) {
      var dummy = { text: message };
      logSentTweet(dummy, params, false);
      callback(dummy);
    } else {
      twit.updateStatus(message, params, function(reply) {
          if(reply.id) {
            logSentTweet(reply, params);
            callback(reply);
          } else {
            console.error("Error sending tweet", reply);
          }
      });
    }

}

// --- private
function start(callback) {
    updateTweets();
    streamWeatherTweets();
    streamUserReplies();
    callback();
}

function requireAuthentication(callback) {
    var express = require('express');
    var app = express();
    var server;

    app.get('/', twit.gatekeeper('/login'), function(req, res){
      res.send('Authentification successfull');
      console.log("Auth complete, closing authentication server.");
      server.close();
      callback();
    });
    app.get('/twauth', twit.login());

    console.log('Listening on 1200 for auth requests to Twitter');
    server = app.listen(1200);
}

function logSentTweet(tweet, params, real) {
    if(typeof params === 'undefined')
      params = {};

    if(typeof real === 'undefined')
      real = true;

    var insert = DB.prepare(sql['logSentTweet']);
    insert.run({ $text: tweet.text, $related_id: params.in_reply_to_status_id });
    console.log("Tweet sent successfully" + (real ? "" : " (Mock)"));
}

function selectTweets(params, callback) {
    defaultParams = {
        'q': QUERY,
        'lang': 'en',
        'result_type': 'recent', //mixed, recent, popular
        'f': 'realtime',
        'include_entities': 'false',
        'count': 100
    };

    params = merge(defaultParams, params);

    if(DUMMY_SEARCH) callback();
    else twit.get('/search/tweets.json', params, callback);
}

function updateTweets() {
    console.log("Querying twitter for updates using polling");
    DB.get(sql['selectNewestTweet'], function(err, result) {
        if(result) params = { 'since_id': (result.id + 1)  }
        else params = {}

        selectTweets(params, function(data) {
            if(!data || !data.statuses) {
                console.warn("No data received from Twitter from search poll");
            }
            else
            {
                var count = data.statuses.length;
                if(count < 1) {
                    console.warn("No tweets received from Twitter from search poll");
                }

                for(i=0;i<count;i++) {
                    var tweet = data.statuses[i];
                    seenTweet(tweet);
                }
            }

            updateComplete();
        });
    });
}

// Twitter side
var weather_keywords = ['weather', 'forecast', 'sunny', 'weather', 'rain', 'sunshine',
                        'umbrella', 'snow', 'hail', 'warm', 'cold', 'brolly', 'boiling'];

// Local
var ignored_users = ['galgateweather', 'mennewsdesk', 'metoffice', 'chadWeather', 'myweather_man',
                     'uk_storms', 'wx_manchester', 'widdop_weather', 'weather', TWITTER_ACCOUNT_NAME];

var ignored_keywords = ['rt @', '[Manchester Weather] Your Weekend Forecast', 'weatherspoons',
                        'manchester, nh', '@virgintrains', 'train'];

function streamWeatherTweets(reconnect_sleep_seconds) {
  if(typeof reconnect_sleep_seconds === 'undefined')
      reconnectSleepSeconds = DEFAULT_STREAM_SLEEP_SECONDS;

    // Bounding boxes do not act as filters for other filter parameters.
    // For example track=twitter&locations=-122.75,36.8,-121.75,37.8 would match
    // any tweets containing the term Twitter (even non-geo tweets) OR coming from the San Francisco area.
    track = []

    for(i=0;i<weather_keywords.length;i++) {
      track.push(weather_keywords[i] + ' manchester');
      track.push(weather_keywords[i] + ' #mcr');
    }

    twit.stream('filter', {
      track: ["weather manchester", "rain manchester", "sunny manchester", "snow manchester"],
      locations: '-2.275,53.45,-2.2,53.5' // bottom right, top left - lon/lat
    }, function(stream) {
        console.info("Connected to twitter filter stream for Manchester");

        var resetStream = setTimeout(function() {
            console.info("Restarting manchester stream as it has been open for 30 minutes");
            stream.destroy();
        }, 30 * 60 * 1000);

        stream.on('data', function(data) {

            // reset done here as 'connect' fires even on rejection
            currentStreamSleepSeconds = DEFAULT_STREAM_SLEEP_SECONDS;

            // @todo should probably validate data, twitter might return a none tweet
            // the steam may contain "non weather" tweets we must filter first
            if(arrayInString(data.text, weather_keywords)
                && !arrayInString(data.user.screen_name, ignored_users)
                && !arrayInString(data.text, ignored_keywords)) {

              textWithMatches = data.text;
              for(i=0;i<weather_keywords.length;i++) {
                textWithMatches = textWithMatches.replace(new RegExp('(^|)(' + weather_keywords[i] + ')(|$)','ig'),
                                                          '$1' + "$2".red + '$3');
              }

              console.info("Matched streamed weather tweet @", data.user.screen_name, " ", textWithMatches);
              seenTweet(data, true);
            } else {
              fs.appendFile('ignoredTweets.txt', data.user.screen_name
                                                  + ":\t"
                                                  + data.text.replace(/(\r\n|\n|\r)/gm," \\ ")
                                                  + "\n");
            }

        });

        stream.on('error', function(error) {
            if(error.errorSource) console.error("Twitter Stream Error:", error);
            else console.error("Other Twitter stream error");
        });

        stream.on('end', function(end) {
            console.info("Stream ended, will attempt to reconnect in "+reconnectSleepSeconds+" seconds");
            clearTimeout(resetStream);
            setTimeout(function() {
              streamWeatherTweets(reconnectSleepSeconds * 2);
            }, reconnectSleepSeconds * 1000);
        });

    });
}

function streamUserReplies(reconnect_sleep_seconds) {
  if(typeof reconnect_sleep_seconds === 'undefined')
      reconnectSleepSeconds = DEFAULT_STREAM_SLEEP_SECONDS;

  twit.stream('user', {
      replies: 'all', // By default @replies are only sent if the current user follows both the sender and receiver
      with: 'users' // When set to "users", only messages targeted directly at a user will be delivered
    }, function(stream) {
        console.info("Connected to twitter user stream for McrWeather");

        var resetStream = setTimeout(function() {
            console.info("Restarting user stream as it has been open for 30 minutes");
            stream.destroy();
        }, 30 * 60 * 1000);

        stream.on('data', function(data) {
            // Upon establishing a User Stream connection Twitter will send
            // a preamble before starting regular message delivery
            if(data.friends) {
              // reset done here as 'connect' fires even on rejection
              reconnectSleepSeconds = DEFAULT_STREAM_SLEEP_SECONDS;
              return;
            }

            else if(data.text) {
              if(data.text.toLowerCase().indexOf(TWITTER_ACCOUNT_NAME) != -1) {

                  console.log("Recieved mention in user stream @", data.user.screen_name, data.text);

                  // Avoid loops, if we sent the message and it was a reply to US
                  if(data.in_reply_to_screen_name
                      && data.in_reply_to_screen_name.toLowerCase() == TWITTER_ACCOUNT_NAME
                      && data.user.screen_name.toLowerCase() == TWITTER_ACCOUNT_NAME) {
                      console.warn('Ignored self reply message');
                      return;
                  }

                  seenTweet(data, true, true);
              }
            }
        });

        stream.on('error', function(error) {
            if(error.errorSource) console.error("Twitter User Stream Error:", error);
            else console.error("Other Twitter User stream error");
        });

        stream.on('end', function(end) {
            console.info("User stream ended, will attempt to reconnect in "+reconnectSleepSeconds+" seconds");
            clearTimeout(resetStream);
            setTimeout(function() {
              streamUserReplies(reconnectSleepSeconds * 2);
            }, reconnectSleepSeconds * 1000);
        });

    });
}

function arrayInString(string, array) {
    if(typeof string !== 'string')
        throw new Error('The term to search must be a string');

    for(i=0;i<array.length;i++) {
        if(string.toLowerCase().indexOf(array[i].toLowerCase()) != -1) return true;
    }

    return false;

}

function seenTweet(tweet, streamed, mention) {
    if(typeof streamed === 'undefined')
        streamed = false;

    if(typeof mention === 'undefined')
        mention = tweet.text.toLowerCase().indexOf(TWITTER_ACCOUNT_NAME) != -1;

    var select = DB.prepare(sql['selectExistingTweet']);
    select.get({$tweet_id: tweet.id}, function(err, row) {
        if(!row) { // If the result set is empty, the second parameter is undefined
            var insert = DB.prepare(sql['insertSeenTweet']);
            insert.run({
              $id: tweet.id,
              $text: tweet.text,
              $user_id: tweet.user.id,
              $username: tweet.user.screen_name,
              $streamed: streamed ? 1 : 0  // 0/1 as SQLlite has no boolean support
            });
            TWEET_CALLBACK(tweet, mention);
            console.info("Logged", tweet.text, tweet.created_at);
        } else {
            console.info("Ignored duplicate", tweet.text, tweet.created_at);
            // @todo if streamed == false, I might need to mark this as non-streamed
            // to prevent the non-stream falling behind if the stream is capturing everything
        }
    });
}

function updateComplete() {
    console.info("\n"+'Update complete, waiting '+WAIT_SECONDS+' seconds before the next update');
    countdown(WAIT_SECONDS, updateTweets, "seconds until next search...");
}

function countdown(seconds, callback, message) {
    var countdownInterval;
    var countdownSecondsLeft;
    var countdownCallback;

    countdownInterval = setInterval(function(){
        if(COUNTDOWN_OUTPUT) {
            process.stdout.clearLine();  // clear current text
            process.stdout.cursorTo(0);  // move cursor to beginning of line
            process.stdout.write(countdownSecondsLeft-- + " " + message);
        }

        if(countdownSecondsLeft <= 0) {
            clearInterval(countdownInterval);
            process.stdout.write("\n");
            if(countdownCallback) {
                temp = countdownCallback;
                countdownCallback = null;
                temp();
            }
        }
    }, 1000);

    countdownSecondsLeft = seconds;
    if(typeof callback !== 'undefined') {
        countdownCallback = callback;
    }
}<commit_msg>Refactor the streams<commit_after>var util = require('util'),
    twitter = require('twitter');
var twit;
var merge = require('merge');
var fs = require('fs')
var colors = require('colors');

var DUMMY_SEARCH = false;
var DUMMY_TWEET = false;
var WAIT_SECONDS = 120;
var QUERY = "";
var TWEET_CALLBACK = null;
var DB = null;

var COUNTDOWN_OUTPUT = false;

var TWITTER_ACCOUNT_NAME = "weathermcr";

var DEFAULT_STREAM_SLEEP_SECONDS = 5;

// --- SQL ---
var sql = [];
sql['createSeenTweets'] = 'CREATE TABLE IF NOT EXISTS seen_tweets ' +
                          '(id INTEGER PRIMARY KEY, time DATETIME DEFAULT current_timestamp, text TEXT, user_id INTEGER,' +
                          ' username TEXT, action_taken TEXT, streamed BOOLEAN)';
sql['createSentTweets'] = 'CREATE TABLE IF NOT EXISTS sent_tweets ' +
                          '(id INTEGER PRIMARY KEY AUTOINCREMENT, text TEXT, related_tweet_id INTEGER)';
sql['createAPILogin'] =   'CREATE TABLE IF NOT EXISTS api_login ' +
                          '(id INTEGER PRIMARY KEY AUTOINCREMENT, access_token_key TEXT, access_token_secret TEXT)';

sql['selectNewestAPI'] =     'SELECT * FROM api_login ORDER BY id DESC LIMIT 1';
sql['selectNewestTweet'] =   'SELECT id FROM seen_tweets WHERE streamed = 0 ORDER BY id DESC LIMIT 1';
sql['selectExistingTweet'] = "SELECT 1 as 'exist' FROM seen_tweets WHERE id = $tweet_id LIMIT 1";

sql['updateActionTaken'] = 'UPDATE seen_tweets SET action_taken = $action WHERE id = $id';

sql['insertSeenTweet'] = 'INSERT INTO seen_tweets (id, text, user_id, username, streamed) ' +
                         'VALUES ($id, $text, $user_id, $username, $streamed)';
sql['logSentTweet'] =    'INSERT INTO sent_tweets (text, related_tweet_id) VALUES ($text, $related_id)';
sql['insertAPILogin'] =  'INSERT INTO api_login (access_token_key, access_token_secret) VALUES ($key, $secret)';

// --- public
exports.config = function(config, wait_seconds, database) {
    twit = new twitter(config);
    WAIT_SECONDS = wait_seconds;
    DB = database;
}

exports.dummy = function(search, tweets) {
    DUMMY_SEARCH = search;
    DUMMY_TWEET = tweets;
    if(DUMMY_SEARCH)
      console.log("Using dummy twitter search");
    if(DUMMY_TWEET)
      console.log("Using dummy twitter tweet");
}

exports.start = function(query, tweet_callback, callback) {
    QUERY = query;
    TWEET_CALLBACK = tweet_callback;

    // Ensure the database is ready for use
    DB.serialize(function() {
      DB.run(sql['createSeenTweets']);
      DB.run(sql['createSentTweets']);
      DB.run(sql['createAPILogin']);
    });

    DB.get(sql['selectNewestAPI'], function(err, result) {

      if(result) {
          console.info("Using stored authentication");
          params = { 'since_id': (result.id - 1500) } // for some reason this needs to be done...

          twit.options.access_token_key = result.access_token_key;
          twit.options.access_token_secret = result.access_token_secret;

          start(callback);
      } else {
          console.info("Authentication is needed before bot can start.");
          requireAuthentication(function() {
              //reusable API access
              var insert = DB.prepare(sql['insertAPILogin']);
              insert.run({ $key: twit.options.access_token_key, $secret: twit.options.access_token_secret });

              start(callback);
          });

      }

    });
}

exports.updateActionTaken = function(tweet, actionTaken) {
    var update = DB.prepare(sql['updateActionTaken']);
    update.bind({$id: tweet.id, $action: actionTaken });
    update.run();
}

exports.sendReply = function(reply_to, message, callback, disable_dummy_tweet) {
    if(typeof disable_dummy_tweet === 'undefined')
        disable_dummy_tweet = false;

    // Must include @ for reply, else twitter rejects it
    if(reply_to.user.screen_name)
      message = "@" + reply_to.user.screen_name + " " + message;

    // Twitter rejects us if we provide an incorrect reply_to.id
    params = {}
    if(reply_to.id)
      params.in_reply_to_status_id = reply_to.id;

    if(message.length > 140)
        console.error("Message over 140 letters: " + message);

    console.log("Attempting to send", message);

    if(DUMMY_TWEET && !disable_dummy_tweet) {
      var dummy = { text: message };
      logSentTweet(dummy, params, false);
      callback(dummy);
    } else {
      twit.updateStatus(message, params, function(reply) {
          if(reply.id) {
            logSentTweet(reply, params);
            callback(reply);
          } else {
            console.error("Error sending tweet", reply);
          }
      });
    }

}

// --- private
function start(callback) {
    updateTweets();
    streamWeatherTweets();
    streamUserReplies();
    callback();
}

function requireAuthentication(callback) {
    var express = require('express');
    var app = express();
    var server;

    app.get('/', twit.gatekeeper('/login'), function(req, res){
      res.send('Authentification successfull');
      console.log("Auth complete, closing authentication server.");
      server.close();
      callback();
    });
    app.get('/twauth', twit.login());

    console.log('Listening on 1200 for auth requests to Twitter');
    server = app.listen(1200);
}

function logSentTweet(tweet, params, real) {
    if(typeof params === 'undefined')
      params = {};

    if(typeof real === 'undefined')
      real = true;

    var insert = DB.prepare(sql['logSentTweet']);
    insert.run({ $text: tweet.text, $related_id: params.in_reply_to_status_id });
    console.log("Tweet sent successfully" + (real ? "" : " (Mock)"));
}

function selectTweets(params, callback) {
    defaultParams = {
        'q': QUERY,
        'lang': 'en',
        'result_type': 'recent', //mixed, recent, popular
        'f': 'realtime',
        'include_entities': 'false',
        'count': 100
    };

    params = merge(defaultParams, params);

    if(DUMMY_SEARCH) callback();
    else twit.get('/search/tweets.json', params, callback);
}

function updateTweets() {
    console.log("Querying twitter for updates using polling");
    DB.get(sql['selectNewestTweet'], function(err, result) {
        if(result) params = { 'since_id': (result.id + 1)  }
        else params = {}

        selectTweets(params, function(data) {
            if(!data || !data.statuses) {
                console.warn("No data received from Twitter from search poll");
            }
            else
            {
                var count = data.statuses.length;
                if(count < 1) {
                    console.warn("No tweets received from Twitter from search poll");
                }

                for(i=0;i<count;i++) {
                    var tweet = data.statuses[i];
                    seenTweet(tweet);
                }
            }

            updateComplete();
        });
    });
}

// Connect to a twitter stream
function streamTweets(type, params, dataCallback, reconnectSleepSeconds) {
    if(typeof reconnectSleepSeconds === 'undefined')
        reconnectSleepSeconds = DEFAULT_STREAM_SLEEP_SECONDS;

    twit.stream(type, params, function(stream) {
        console.info("Connected to twitter "+type+" stream");

        var resetStream = setTimeout(function() {
            console.info("Restarting "+type+" stream as it has been open for 30 minutes");
            stream.destroy();
        }, 30 * 60 * 1000);

        stream.on('data', function(data) {

            // reset done here as 'connect' fires even on rejection
            reconnectSleepSeconds = DEFAULT_STREAM_SLEEP_SECONDS;

            dataCallback(data);

        });

        stream.on('error', function(error) {
            if(error.errorSource) console.error("Twitter "+type+" stream error:", error);
            else console.error("Other Twitter "+type+" stream error");
        });

        stream.on('end', function(end) {
            console.info("Stream "+type+" ended, will attempt to reconnect in "+reconnectSleepSeconds+" seconds");
            clearTimeout(resetStream);
            setTimeout(function() {
              streamTweets(type, params, dataCallback, reconnectSleepSeconds * 2);
            }, reconnectSleepSeconds * 1000);
        });

    });

}

// Twitter side
var weather_keywords = ['weather', 'forecast', 'sunny', 'weather', 'rain', 'sunshine',
                        'umbrella', 'snow', 'hail', 'warm', 'cold', 'brolly', 'boiling'];

// Local
var ignored_users = ['galgateweather', 'mennewsdesk', 'metoffice', 'chadWeather', 'myweather_man',
                     'uk_storms', 'wx_manchester', 'widdop_weather', 'weather', TWITTER_ACCOUNT_NAME];

var ignored_keywords = ['rt @', '[Manchester Weather] Your Weekend Forecast', 'weatherspoons',
                        'manchester, nh', '@virgintrains', 'train'];

// Get tweets about the weather
function streamWeatherTweets() {

    // Bounding boxes do not act as filters for other filter parameters.
    // For example track=twitter&locations=-122.75,36.8,-121.75,37.8 would match
    // any tweets containing the term Twitter (even non-geo tweets) OR coming from the San Francisco area.
    track = []

    for(i=0;i<weather_keywords.length;i++) {
      track.push(weather_keywords[i] + ' manchester');
      track.push(weather_keywords[i] + ' #mcr');
    }

    streamTweets('filter',
        {
            track: track,
            locations: '-2.275,53.45,-2.2,53.5' // bottom right, top left - lon/lat
        },
        function(data) {

            // @todo should probably validate data, twitter might return a none tweet
            // the steam may contain "non weather" tweets we must filter first
            if(arrayInString(data.text, weather_keywords)
                && !arrayInString(data.user.screen_name, ignored_users)
                && !arrayInString(data.text, ignored_keywords)) {

                textWithMatches = data.text;
                for(i=0;i<weather_keywords.length;i++) {
                  textWithMatches = textWithMatches.replace(new RegExp('(^|)(' + weather_keywords[i] + ')(|$)','ig'),
                                                            '$1' + "$2".red + '$3');
                }

                console.info("Matched streamed weather tweet @", data.user.screen_name, " ", textWithMatches);
                seenTweet(data, true);

            } else {
                fs.appendFile('ignoredTweets.txt', data.user.screen_name
                                                    + ":\t"
                                                    + data.text.replace(/(\r\n|\n|\r)/gm," \\ ")
                                                    + "\n");
            }

        }
    );
}

function streamUserReplies() {
    streamTweets('user',
        {
            replies: 'all', // By default @replies are only sent if the current user follows the sender and receiver
            with: 'users' // When set to "users", only messages targeted directly at a user will be delivered
        },
        function(data) {
            // Upon establishing a User Stream connection Twitter will send
            // a preamble before starting regular message delivery
            if(data.friends) {
                return;
            }

            else if(data.text && data.text.toLowerCase().indexOf(TWITTER_ACCOUNT_NAME) != -1) {
                console.log("Recieved mention in user stream @", data.user.screen_name, data.text);

                // Avoid loops, if we sent the message and it was a reply to US
                if(data.in_reply_to_screen_name
                    && data.in_reply_to_screen_name.toLowerCase() == TWITTER_ACCOUNT_NAME
                    && data.user.screen_name.toLowerCase() == TWITTER_ACCOUNT_NAME) {
                    console.warn('Ignored self reply message');
                    return;
                }

                seenTweet(data, true, true);
            }
        }
    );
}

function arrayInString(string, array) {
    if(typeof string !== 'string')
        throw new Error('The term to search must be a string');

    for(i=0;i<array.length;i++) {
        if(string.toLowerCase().indexOf(array[i].toLowerCase()) != -1) return true;
    }

    return false;

}

function seenTweet(tweet, streamed, mention) {
    if(typeof streamed === 'undefined')
        streamed = false;

    if(typeof mention === 'undefined')
        mention = tweet.text.toLowerCase().indexOf(TWITTER_ACCOUNT_NAME) != -1;

    var select = DB.prepare(sql['selectExistingTweet']);
    select.get({$tweet_id: tweet.id}, function(err, row) {
        if(!row) { // If the result set is empty, the second parameter is undefined
            var insert = DB.prepare(sql['insertSeenTweet']);
            insert.run({
              $id: tweet.id,
              $text: tweet.text,
              $user_id: tweet.user.id,
              $username: tweet.user.screen_name,
              $streamed: streamed ? 1 : 0  // 0/1 as SQLlite has no boolean support
            });
            TWEET_CALLBACK(tweet, mention);
            console.info("Logged", tweet.text, tweet.created_at);
        } else {
            console.info("Ignored duplicate", tweet.text, tweet.created_at);
            // @todo if streamed == false, I might need to mark this as non-streamed
            // to prevent the non-stream falling behind if the stream is capturing everything
        }
    });
}

function updateComplete() {
    console.info("\n"+'Update complete, waiting '+WAIT_SECONDS+' seconds before the next update');
    countdown(WAIT_SECONDS, updateTweets, "seconds until next search...");
}

function countdown(seconds, callback, message) {
    var countdownInterval;
    var countdownSecondsLeft;
    var countdownCallback;

    countdownInterval = setInterval(function(){
        if(COUNTDOWN_OUTPUT) {
            process.stdout.clearLine();  // clear current text
            process.stdout.cursorTo(0);  // move cursor to beginning of line
            process.stdout.write(countdownSecondsLeft-- + " " + message);
        }

        if(countdownSecondsLeft <= 0) {
            clearInterval(countdownInterval);
            process.stdout.write("\n");
            if(countdownCallback) {
                temp = countdownCallback;
                countdownCallback = null;
                temp();
            }
        }
    }, 1000);

    countdownSecondsLeft = seconds;
    if(typeof callback !== 'undefined') {
        countdownCallback = callback;
    }
}<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
//  Copyright (C) 2011 The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// ToolBar
//============================================================================

var IPython = (function (IPython) {

    var MainToolBar = function (selector) {
        IPython.ToolBar.apply(this, arguments);
        this.construct();
        this.add_celltype_list();
        this.add_celltoolbar_list();
        this.bind_events();
    };

    MainToolBar.prototype = new IPython.ToolBar();

    MainToolBar.prototype.construct = function () {
        this.add_buttons_group([
                {
                    id : 'save_b',
                    label : 'Save',
                    icon : 'ui-icon-disk',
                    callback : function () {
                        IPython.notebook.save_notebook();
                        }
                }
            ]);
        this.add_buttons_group([
                {
                    id : 'cut_b',
                    label : 'Cut Cell',
                    icon : 'ui-icon-scissors',
                    callback : function () {
                        IPython.notebook.cut_cell();
                        }
                },
                {
                    id : 'copy_b',
                    label : 'Copy Cell',
                    icon : 'ui-icon-copy',
                    callback : function () {
                        IPython.notebook.copy_cell();
                        }
                },
                {
                    id : 'paste_b',
                    label : 'Paste Cell Below',
                    icon : 'ui-icon-clipboard',
                    callback : function () {
                        IPython.notebook.paste_cell_below();
                        }
                }
            ],'cut_copy_paste');

        this.add_buttons_group([
                {
                    id : 'move_up_b',
                    label : 'Move Cell Up',
                    icon : 'ui-icon-arrowthick-1-n',
                    callback : function () {
                        IPython.notebook.move_cell_up();
                        }
                },
                {
                    id : 'move_down_b',
                    label : 'Move Cell Down',
                    icon : 'ui-icon-arrowthick-1-s',
                    callback : function () {
                        IPython.notebook.move_cell_down();
                        }
                }
            ],'move_up_down');

        this.add_buttons_group([
                {
                    id : 'insert_above_b',
                    label : 'Insert Cell Above',
                    icon : 'ui-icon-arrowthickstop-1-n',
                    callback : function () {
                        IPython.notebook.insert_cell_above('code');
                        }
                },
                {
                    id : 'insert_below_b',
                    label : 'Insert Cell Below',
                    icon : 'ui-icon-arrowthickstop-1-s',
                    callback : function () {
                        IPython.notebook.insert_cell_below('code');
                        }
                }
            ],'insert_above_below');

        this.add_buttons_group([
                {
                    id : 'run_b',
                    label : 'Run Cell',
                    icon : 'ui-icon-play',
                    callback : function () {
                    IPython.notebook.execute_selected_cell();
                        }
                },
                {
                    id : 'interrupt_b',
                    label : 'Interrupt',
                    icon : 'ui-icon-stop',
                    callback : function () {
                        IPython.notebook.kernel.interrupt();
                        }
                }
            ],'run_int');
    };

    MainToolBar.prototype.add_celltype_list = function () {
        this.element
            .append($('<select/>')
                .attr('id','cell_type')
                .addClass('ui-widget ui-widget-content')
                .append($('<option/>').attr('value','code').text('Code'))
                .append($('<option/>').attr('value','markdown').text('Markdown'))
                .append($('<option/>').attr('value','raw').text('Raw Text'))
                .append($('<option/>').attr('value','heading1').text('Heading 1'))
                .append($('<option/>').attr('value','heading2').text('Heading 2'))
                .append($('<option/>').attr('value','heading3').text('Heading 3'))
                .append($('<option/>').attr('value','heading4').text('Heading 4'))
                .append($('<option/>').attr('value','heading5').text('Heading 5'))
                .append($('<option/>').attr('value','heading6').text('Heading 6'))
            );
    };

    MainToolBar.prototype.add_celltoolbar_list = function () {
        var label = $('<label/>').text('Cell Toolbar:');
        var select = $('<select/>')
            .addClass('ui-widget ui-widget-content')
            .attr('id', 'ctb_select')
            .append($('<option/>').attr('value', '').text('None'));
        this.element.append(label).append(select);
        select.change(function() {
                var val = $(this).val()
                if (val =='') {
                    IPython.CellToolbar.global_hide();
                } else {
                    IPython.CellToolbar.global_show();
                    IPython.CellToolbar.activate_preset(val);
                }
            });
        // Setup the currently registered presets.
        var presets = IPython.CellToolbar.list_presets();
        for (var i=0; i<presets.length; i++) {
            var name = presets[i];
            select.append($('<option/>').attr('value', name).text(name));
        }
        // Setup future preset registrations.
        $([IPython.events]).on('preset_added.CellToolbar', function (event, data) {
            var name = data.name;
            select.append($('<option/>').attr('value', name).text(name));
        });
    };

    MainToolBar.prototype.bind_events = function () {
        var that = this;

        this.element.find('#cell_type').change(function () {
            var cell_type = $(this).val();
            if (cell_type === 'code') {
                IPython.notebook.to_code();
            } else if (cell_type === 'markdown')  {
                IPython.notebook.to_markdown();
            } else if (cell_type === 'raw')  {
                IPython.notebook.to_raw();
            } else if (cell_type === 'heading1')  {
                IPython.notebook.to_heading(undefined, 1);
            } else if (cell_type === 'heading2')  {
                IPython.notebook.to_heading(undefined, 2);
            } else if (cell_type === 'heading3')  {
                IPython.notebook.to_heading(undefined, 3);
            } else if (cell_type === 'heading4')  {
                IPython.notebook.to_heading(undefined, 4);
            } else if (cell_type === 'heading5')  {
                IPython.notebook.to_heading(undefined, 5);
            } else if (cell_type === 'heading6')  {
                IPython.notebook.to_heading(undefined, 6);
            }
        });
        $([IPython.events]).on('selected_cell_type_changed.Notebook', function (event, data) {
            if (data.cell_type === 'heading') {
                that.element.find('#cell_type').val(data.cell_type+data.level);
            } else {
                that.element.find('#cell_type').val(data.cell_type);
            }
        });
    };

    IPython.MainToolBar = MainToolBar;

    return IPython;

}(IPython));
<commit_msg>Removing unneeded ui-widget class.<commit_after>//----------------------------------------------------------------------------
//  Copyright (C) 2011 The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// ToolBar
//============================================================================

var IPython = (function (IPython) {

    var MainToolBar = function (selector) {
        IPython.ToolBar.apply(this, arguments);
        this.construct();
        this.add_celltype_list();
        this.add_celltoolbar_list();
        this.bind_events();
    };

    MainToolBar.prototype = new IPython.ToolBar();

    MainToolBar.prototype.construct = function () {
        this.add_buttons_group([
                {
                    id : 'save_b',
                    label : 'Save',
                    icon : 'ui-icon-disk',
                    callback : function () {
                        IPython.notebook.save_notebook();
                        }
                }
            ]);
        this.add_buttons_group([
                {
                    id : 'cut_b',
                    label : 'Cut Cell',
                    icon : 'ui-icon-scissors',
                    callback : function () {
                        IPython.notebook.cut_cell();
                        }
                },
                {
                    id : 'copy_b',
                    label : 'Copy Cell',
                    icon : 'ui-icon-copy',
                    callback : function () {
                        IPython.notebook.copy_cell();
                        }
                },
                {
                    id : 'paste_b',
                    label : 'Paste Cell Below',
                    icon : 'ui-icon-clipboard',
                    callback : function () {
                        IPython.notebook.paste_cell_below();
                        }
                }
            ],'cut_copy_paste');

        this.add_buttons_group([
                {
                    id : 'move_up_b',
                    label : 'Move Cell Up',
                    icon : 'ui-icon-arrowthick-1-n',
                    callback : function () {
                        IPython.notebook.move_cell_up();
                        }
                },
                {
                    id : 'move_down_b',
                    label : 'Move Cell Down',
                    icon : 'ui-icon-arrowthick-1-s',
                    callback : function () {
                        IPython.notebook.move_cell_down();
                        }
                }
            ],'move_up_down');

        this.add_buttons_group([
                {
                    id : 'insert_above_b',
                    label : 'Insert Cell Above',
                    icon : 'ui-icon-arrowthickstop-1-n',
                    callback : function () {
                        IPython.notebook.insert_cell_above('code');
                        }
                },
                {
                    id : 'insert_below_b',
                    label : 'Insert Cell Below',
                    icon : 'ui-icon-arrowthickstop-1-s',
                    callback : function () {
                        IPython.notebook.insert_cell_below('code');
                        }
                }
            ],'insert_above_below');

        this.add_buttons_group([
                {
                    id : 'run_b',
                    label : 'Run Cell',
                    icon : 'ui-icon-play',
                    callback : function () {
                    IPython.notebook.execute_selected_cell();
                        }
                },
                {
                    id : 'interrupt_b',
                    label : 'Interrupt',
                    icon : 'ui-icon-stop',
                    callback : function () {
                        IPython.notebook.kernel.interrupt();
                        }
                }
            ],'run_int');
    };

    MainToolBar.prototype.add_celltype_list = function () {
        this.element
            .append($('<select/>')
                .attr('id','cell_type')
                .addClass('ui-widget-content')
                .append($('<option/>').attr('value','code').text('Code'))
                .append($('<option/>').attr('value','markdown').text('Markdown'))
                .append($('<option/>').attr('value','raw').text('Raw Text'))
                .append($('<option/>').attr('value','heading1').text('Heading 1'))
                .append($('<option/>').attr('value','heading2').text('Heading 2'))
                .append($('<option/>').attr('value','heading3').text('Heading 3'))
                .append($('<option/>').attr('value','heading4').text('Heading 4'))
                .append($('<option/>').attr('value','heading5').text('Heading 5'))
                .append($('<option/>').attr('value','heading6').text('Heading 6'))
            );
    };

    MainToolBar.prototype.add_celltoolbar_list = function () {
        var label = $('<label/>').text('Cell Toolbar:');
        var select = $('<select/>')
            .addClass('ui-widget-content')
            .attr('id', 'ctb_select')
            .append($('<option/>').attr('value', '').text('None'));
        this.element.append(label).append(select);
        select.change(function() {
                var val = $(this).val()
                if (val =='') {
                    IPython.CellToolbar.global_hide();
                } else {
                    IPython.CellToolbar.global_show();
                    IPython.CellToolbar.activate_preset(val);
                }
            });
        // Setup the currently registered presets.
        var presets = IPython.CellToolbar.list_presets();
        for (var i=0; i<presets.length; i++) {
            var name = presets[i];
            select.append($('<option/>').attr('value', name).text(name));
        }
        // Setup future preset registrations.
        $([IPython.events]).on('preset_added.CellToolbar', function (event, data) {
            var name = data.name;
            select.append($('<option/>').attr('value', name).text(name));
        });
    };

    MainToolBar.prototype.bind_events = function () {
        var that = this;

        this.element.find('#cell_type').change(function () {
            var cell_type = $(this).val();
            if (cell_type === 'code') {
                IPython.notebook.to_code();
            } else if (cell_type === 'markdown')  {
                IPython.notebook.to_markdown();
            } else if (cell_type === 'raw')  {
                IPython.notebook.to_raw();
            } else if (cell_type === 'heading1')  {
                IPython.notebook.to_heading(undefined, 1);
            } else if (cell_type === 'heading2')  {
                IPython.notebook.to_heading(undefined, 2);
            } else if (cell_type === 'heading3')  {
                IPython.notebook.to_heading(undefined, 3);
            } else if (cell_type === 'heading4')  {
                IPython.notebook.to_heading(undefined, 4);
            } else if (cell_type === 'heading5')  {
                IPython.notebook.to_heading(undefined, 5);
            } else if (cell_type === 'heading6')  {
                IPython.notebook.to_heading(undefined, 6);
            }
        });
        $([IPython.events]).on('selected_cell_type_changed.Notebook', function (event, data) {
            if (data.cell_type === 'heading') {
                that.element.find('#cell_type').val(data.cell_type+data.level);
            } else {
                that.element.find('#cell_type').val(data.cell_type);
            }
        });
    };

    IPython.MainToolBar = MainToolBar;

    return IPython;

}(IPython));
<|endoftext|>


<commit_before>'use strict';

const functionLoader = require;

class Lambda {

  constructor(path, handler) {
    this.path = path;
    this.handler = handler;
  }

  invoke(event, context, callback) {
    // Invalidate common.js cache
    delete functionLoader.cache[functionLoader.resolve(this.path)];

    functionLoader(this.path)[this.handler](event, context, callback);
  }

  buildEventFromRequest(request, apiStage) {
    const result = {
      resource: request.path,
      path: request.path,
      httpMethod: request.method.toUpperCase(),
      headers: [],
      queryStringParameters: Object.keys(request.query).length ? request.query : null,
      pathParameters: Object.keys(request.params).length ? request.params : null,
      stageVariables: null,
      requestContext: {
        accountId: '<Account id>',
        resourceId: '<Resource id>',
        stage: apiStage,
        requestId: '<Request id>',
        identity: null,
        resourcePath: request.path,
        httpMethod: request.method.toUpperCase(),
        apiId: '<API id>',
      },
      body: request.body,
    };

    // Camel-Case header names, as this is what APIG does
    Object.keys(request.headers).forEach((header) => {
      result.headers[this.camelizeHeader(header)] = request.headers[header];
    });

    return result;
  }

  buildContext() {
    return {};
  }

  camelizeHeader(str) {
    const arr = str.split('-');
    for (let i = 0; i < arr.length; i++) {
      arr[i] = arr[i][0].toUpperCase() + arr[i].slice(1);
    }
    return arr.join('-');
  }
}

module.exports = Lambda;
<commit_msg>fix object<commit_after>'use strict';

const functionLoader = require;

class Lambda {

  constructor(path, handler) {
    this.path = path;
    this.handler = handler;
  }

  invoke(event, context, callback) {
    // Invalidate common.js cache
    delete functionLoader.cache[functionLoader.resolve(this.path)];

    functionLoader(this.path)[this.handler](event, context, callback);
  }

  buildEventFromRequest(request, apiStage) {
    const result = {
      resource: request.path,
      path: request.path,
      httpMethod: request.method.toUpperCase(),
      headers: {},
      queryStringParameters: Object.keys(request.query).length ? request.query : null,
      pathParameters: Object.keys(request.params).length ? request.params : null,
      stageVariables: null,
      requestContext: {
        accountId: '<Account id>',
        resourceId: '<Resource id>',
        stage: apiStage,
        requestId: '<Request id>',
        identity: null,
        resourcePath: request.path,
        httpMethod: request.method.toUpperCase(),
        apiId: '<API id>',
      },
      body: request.body,
    };

    // Camel-Case header names, as this is what APIG does
    Object.keys(request.headers).forEach((header) => {
      result.headers[this.camelizeHeader(header)] = request.headers[header];
    });

    return result;
  }

  buildContext() {
    return {};
  }

  camelizeHeader(str) {
    const arr = str.split('-');
    for (let i = 0; i < arr.length; i++) {
      arr[i] = arr[i][0].toUpperCase() + arr[i].slice(1);
    }
    return arr.join('-');
  }
}

module.exports = Lambda;
<|endoftext|>