<commit_before>'use strict';
import React from 'react';
import ReactNative from 'react-native';
import RadioButtons from './';

const {
  Text,
  TouchableWithoutFeedback,
  View,
  Platform
} = ReactNative;

class SegmentedControls extends React.Component {

  render(){
    const config = this.getConfig();

    return (
      <RadioButtons {...this.props}
        renderOption={ this.renderOption.bind(this, config) }
        renderContainer={ this.renderContainer.bind(this, config) }
      />
    );
  }

  getConfig(){
    const tint = this.props.tint || DEFAULTS.tint;
    const backTint = this.props.backTint || DEFAULTS.backTint;
    const colors = {
      tint: tint,
      selectedTint: backTint,
      backgroundColor: backTint,
      selectedBackgroundColor: tint,
      containerBorderTint: tint,
      separatorTint: tint,
    };

    return {
      ...DEFAULTS,
      ...colors,
      ...this.props,
    };
  }

  renderContainer(config, options){
    var containerStyle = {
      flexDirection: config.direction,
      backgroundColor: config.backgroundColor,
      borderColor: config.containerBorderTint,
      borderWidth: config.containerBorderWidth,
      overflow: 'hidden',
      ...this.props.containerStyle,
    };

    // overflow hidden does not clip subviews: https://github.com/facebook/react-native/issues/3198
    if (Platform.OS !== "android") {
      containerStyle.borderRadius = config.containerBorderRadius;
    }

    return <View style={ containerStyle }>{options}</View>;
  }

  renderOption(config, option, selected, onSelect, index){

    const baseStyle = {
      textAlign: config.textAlign,
    };

    const selectedStyle = [baseStyle, this.props.optionStyle, {
      color: config.selectedTint,
      backgroundColor: config.selectedBackgroundColor,
    }];

    const baseColor = selected? config.selectedBackgroundColor: config.backgroundColor;

    const baseOptionContainerStyle = {
      paddingTop: config.paddingTop,
      paddingBottom: config.paddingBottom,
      backgroundColor: baseColor,
    };

    const normalStyle = [baseStyle, this.props.optionStyle, {
      color: config.tint,
      backgroundColor: config.backgroundColor
    }];

    const borderStyles = config.direction === 'row' ?
      {
        borderLeftWidth: config.separatorWidth,
        borderLeftColor: config.separatorTint,
      } : {
        borderTopWidth: config.separatorWidth,
        borderTopColor: config.separatorTint,
      };

    const separatorStyle = [baseOptionContainerStyle, borderStyles];

    const style = selected ? selectedStyle : normalStyle;

    const label = this.props.extractText ? this.props.extractText(option) : option;

    // Default to true for undefined - like RN currently does
    const scaleFont = (this.props.allowFontScaling === false) ? false : true;

    return (
      <TouchableWithoutFeedback onPress={onSelect} key={index}>
        <View style={[index > 0 ? separatorStyle : baseOptionContainerStyle, this.props.optionContainerStyle]}>
          {typeof this.props.renderOption === 'function' ? this.props.renderOption.call(this, option, selected) : (
            <Text allowFontScaling={scaleFont} style={style}>{label}</Text>
          )}
        </View>
      </TouchableWithoutFeedback>
    );
  }
}

const IOS_BLUE = '#007AFF';
const IOS_WHITE = '#ffffff';

const DEFAULTS = {
  direction: 'row',

  tint: IOS_BLUE,
  backTint: IOS_WHITE,

  paddingTop: 5,
  paddingBottom: 5,
  textAlign: 'center',

  selectedTint: IOS_WHITE,
  selectedBackgroundColor: IOS_WHITE,

  separatorTint: IOS_BLUE,
  separatorWidth: 1,

  containerBorderTint: IOS_BLUE,
  containerBorderWidth: 1,
  containerBorderRadius: 5,

};
export default SegmentedControls;
<commit_msg>Fixes strange style behavior in Android 0.31.0 <commit_after>'use strict';
import React from 'react';
import ReactNative from 'react-native';
import RadioButtons from './';

const {
  Text,
  TouchableWithoutFeedback,
  View,
  Platform
} = ReactNative;

class SegmentedControls extends React.Component {

  render(){
    const config = this.getConfig();

    return (
      <RadioButtons {...this.props}
        renderOption={ this.renderOption.bind(this, config) }
        renderContainer={ this.renderContainer.bind(this, config) }
      />
    );
  }

  getConfig(){
    const tint = this.props.tint || DEFAULTS.tint;
    const backTint = this.props.backTint || DEFAULTS.backTint;
    const colors = {
      tint: tint,
      selectedTint: backTint,
      backgroundColor: backTint,
      selectedBackgroundColor: tint,
      containerBorderTint: tint,
      separatorTint: tint,
    };

    return {
      ...DEFAULTS,
      ...colors,
      ...this.props,
    };
  }

  renderContainer(config, options){
    var containerStyle = {
      flexDirection: config.direction,
      backgroundColor: config.backgroundColor,
      borderColor: config.containerBorderTint,
      borderWidth: config.containerBorderWidth,
      overflow: 'hidden',
      ...this.props.containerStyle,
    };

    // overflow hidden does not clip subviews: https://github.com/facebook/react-native/issues/3198
    if (Platform.OS !== "android") {
      containerStyle.borderRadius = config.containerBorderRadius;
    }

    return <View style={ containerStyle }>{options}</View>;
  }

  renderOption(config, option, selected, onSelect, index){

    const baseStyle = {
      textAlign: config.textAlign,
    };

    const selectedStyle = [baseStyle, this.props.optionStyle, {
      color: config.selectedTint,
      backgroundColor: config.selectedBackgroundColor,
    }];

    const baseColor = selected? config.selectedBackgroundColor: config.backgroundColor;

    const baseOptionContainerStyle = {
      flex: 1,
      paddingTop: config.paddingTop,
      paddingBottom: config.paddingBottom,
      backgroundColor: baseColor,
    };

    const normalStyle = [baseStyle, this.props.optionStyle, {
      color: config.tint,
      backgroundColor: config.backgroundColor
    }];

    const borderStyles = config.direction === 'row' ?
      {
        borderLeftWidth: config.separatorWidth,
        borderLeftColor: config.separatorTint,
      } : {
        borderTopWidth: config.separatorWidth,
        borderTopColor: config.separatorTint,
      };

    const separatorStyle = [baseOptionContainerStyle, borderStyles];

    const style = selected ? selectedStyle : normalStyle;

    const label = this.props.extractText ? this.props.extractText(option) : option;

    // Default to true for undefined - like RN currently does
    const scaleFont = (this.props.allowFontScaling === false) ? false : true;

    return (
      <TouchableWithoutFeedback onPress={onSelect} key={index}>
        <View style={[index > 0 ? separatorStyle : baseOptionContainerStyle, this.props.optionContainerStyle]}>
          {typeof this.props.renderOption === 'function' ? this.props.renderOption.call(this, option, selected) : (
            <Text allowFontScaling={scaleFont} style={style}>{label}</Text>
          )}
        </View>
      </TouchableWithoutFeedback>
    );
  }
}

const IOS_BLUE = '#007AFF';
const IOS_WHITE = '#ffffff';

const DEFAULTS = {
  direction: 'row',

  tint: IOS_BLUE,
  backTint: IOS_WHITE,

  paddingTop: 5,
  paddingBottom: 5,
  textAlign: 'center',

  selectedTint: IOS_WHITE,
  selectedBackgroundColor: IOS_WHITE,

  separatorTint: IOS_BLUE,
  separatorWidth: 1,

  containerBorderTint: IOS_BLUE,
  containerBorderWidth: 1,
  containerBorderRadius: 5,

};
export default SegmentedControls;
<|endoftext|>


<commit_before>(function() {
    'use strict';

    var path            = require('path'),
        DIR             = path.resolve(__dirname + '/../../../') + '/',
        DIR_SERVER      = DIR + 'server/',
        pipe            = require(DIR_SERVER + 'pipe'),
        flop            = require(DIR_SERVER + 'flop'),
        Hash            = require(DIR_SERVER + 'hash'),
        CloudFunc       = require(DIR + 'cloudfunc'),
        Util            = require(DIR + 'util');

    exports.onGet = onGet;

    function onGet(query, name, callback) {
        var hash, error,
            func    = Util.exec.ret(callback);

        switch (query) {
        case 'size':
            flop.read(name, 'size', function(error, size) {
                if (!error)
                    size = CloudFunc.getShortSize(size);

                func(error, size);
            });
            break;

        case 'time':
            flop.read(name, 'time', func);
            break;

        case 'hash':
            hash = Hash.create();

            if (!hash) {
                error   = 'hash: not suported, try update node';
                func(new Error(error));
            } else
                pipe.create(name, hash, function (error) {
                    var hex;

                    if (!error)
                        hex = hash.get();

                    console.log(hex);

                    func(error, hex);
                });

            break;

        default:
            flop.read(name, func);
            break;
        }
    }
})();
<commit_msg>fix(get) rm CloudFunc.getShortSize<commit_after>(function() {
    'use strict';

    var path            = require('path'),
        DIR             = path.resolve(__dirname + '/../../../') + '/',
        DIR_SERVER      = DIR + 'server/',
        pipe            = require(DIR_SERVER + 'pipe'),
        flop            = require(DIR_SERVER + 'flop'),
        Hash            = require(DIR_SERVER + 'hash'),
        Util            = require(DIR + 'util');

    exports.onGet = onGet;

    function onGet(query, name, callback) {
        var hash, error,
            func    = Util.exec.ret(callback);

        switch (query) {
        case 'size':
            flop.read(name, 'size', func);
            break;

        case 'time':
            flop.read(name, 'time', func);
            break;

        case 'hash':
            hash = Hash.create();

            if (!hash) {
                error   = 'hash: not suported, try update node';
                func(new Error(error));
            } else
                pipe.create(name, hash, function (error) {
                    var hex;

                    if (!error)
                        hex = hash.get();

                    console.log(hex);

                    func(error, hex);
                });

            break;

        default:
            flop.read(name, func);
            break;
        }
    }
})();
<|endoftext|>


<commit_before>(function() {
    'use strict';

    var DIR         = '../../../',
        DIR_SERVER  = DIR + 'server/',

        path        = require('path'),
        fs          = require('fs'),

        CloudFunc   = require(DIR + 'cloudfunc'),
        Util        = require(DIR + 'util'),

        packer      = require(DIR_SERVER + 'packer'),

        tryRequire  = require(DIR_SERVER + 'tryRequire'),
        tryOptions  = {log: true, exit: true},

        flop        = tryRequire('flop', tryOptions),
        files       = tryRequire('files-io', tryOptions);

    module.exports  = function(query, name, readStream, callback) {
        var baseName    = path.basename(name),
            onDone      = function(msg, error) {
                if (!error)
                    msg     = CloudFunc.formatMsg(msg, baseName);

                callback(error, msg);
            },
            onSave      = Util.exec.with(onDone, 'save'),
            OnMakeDir   = Util.exec.with(onDone, 'make dir');

        Util.check(arguments, ['query', 'name', 'readStream', 'callback']);

        switch(query) {
        default:
            files.pipe(readStream, name, onSave);
            break;

        case 'dir':
            flop.create(name, 'dir', OnMakeDir);
            break;

        case 'file':
            fs.writeFile(name, '', callback);
            break;

        case 'unzip':
            packer.unpack(readStream, name, onSave);
            break;
        }
    };
})();
<commit_msg>feature(put) rm file<commit_after>(function() {
    'use strict';

    var DIR         = '../../../',
        DIR_SERVER  = DIR + 'server/',

        path        = require('path'),

        CloudFunc   = require(DIR + 'cloudfunc'),
        Util        = require(DIR + 'util'),

        packer      = require(DIR_SERVER + 'packer'),

        tryRequire  = require(DIR_SERVER + 'tryRequire'),
        tryOptions  = {log: true, exit: true},

        flop        = tryRequire('flop', tryOptions),
        files       = tryRequire('files-io', tryOptions);

    module.exports  = function(query, name, readStream, callback) {
        var baseName    = path.basename(name),
            onDone      = function(msg, error) {
                if (!error)
                    msg     = CloudFunc.formatMsg(msg, baseName);

                callback(error, msg);
            },
            onSave      = Util.exec.with(onDone, 'save'),
            OnMakeDir   = Util.exec.with(onDone, 'make dir');

        Util.check(arguments, ['query', 'name', 'readStream', 'callback']);

        switch(query) {
        default:
            files.pipe(readStream, name, onSave);
            break;

        case 'dir':
            flop.create(name, 'dir', OnMakeDir);
            break;

        case 'unzip':
            packer.unpack(readStream, name, onSave);
            break;
        }
    };
})();
<|endoftext|>


<commit_before>"use strict";

const Call = require("./Call");
const User = require("./User");

/**
* Represents a message
* @prop {String} id The ID of the message
* @prop {Channel} channel The channel the message is in
* @prop {Guild?} guild The guild the message channel is in. Alias to channel.guild
* @prop {Number} timestamp Timestamp of message creation
* @prop {User} author The message author
* @prop {Member?} member The message author with server-specific data
* @prop {User[]} mentions Array of mentioned users
* @prop {String} content Message content
* @prop {String?} cleanContent Message content with mentions replaced by names, and @everyone/@here escaped
* @prop {String[]} roleMentions Array of mentioned roles' ids
* @prop {String[]?} channelMentions Array of mentions channels' ids
* @prop {Number?} editedTimestamp Timestamp of latest message edit
* @prop {Boolean} tts Whether to play the message using TTS or not
* @prop {Boolean} mentionEveryone Whether the message mentions everyone/here or not
* @prop {Object[]} attachments Array of attachments
* @prop {Object[]} embeds Array of embeds
* @prop {Boolean} command True if message is a command, false if not (CommandClient only)
*/
class Message {
    constructor(data, client) {
        this.id = data.id;
        this._client = client;
        this.type = data.type;
        this.timestamp = Date.parse(data.timestamp);
        this.channel = client.getChannel(data.channel_id) || {
            id: data.channel_id
        };
        if(data.author) {
            this.author = new User(data.author, client);
            if(this.author.discriminator !== "0000") {
                client.users.add(this.author);
            }
            if(this.channel.guild) {
                this.member = this.channel.guild.members.get(this.author.id);
            }
        }
        if(this.type === 0 || this.type === undefined);
        else if(this.type === 1) {
            data.content = `${this.author.mention} added <@${data.mentions[0].id}>.`;
        } else if(this.type === 2) {
            if(this.author.id === data.mentions[0].id) {
                data.content = `@${this.author.username} left the group.`;
            } else {
                data.content = `${this.author.mention} removed @${data.mentions[0].username}.`;
            }
        } else if(this.type === 3) { // (╯°□°）╯︵ ┻━┻
            if(data.call.ended_timestamp) {
                if((!this.channel.lastCall || this.channel.lastCall.endedTimestamp < Date.parse(data.call.ended_timestamp))) {
                    data.call.id = this.id;
                    this.channel.lastCall = new Call(data.call, this.channel);
                }
                if(~data.call.participants.indexOf(client.user.id)) {
                    data.content = `You missed a call from ${this.author.mention}.`;
                } else {
                    data.content = `${this.author.mention} started a call.`;
                }
            } else {
                if(!this.channel.call) {
                    data.call.id = this.id;
                    this.channel.call = new Call(data.call, this.channel);
                }
                data.content = `${this.author.mention} started a call. — Join the call.`;
            }
        } else if(this.type === 4) {
            data.content = `${this.author.mention} changed the channel name: ${data.content}`;
        } else if(this.type === 5) {
            data.content = `${this.author.mention} changed the channel icon.`;
        } else if(this.type === 6) {
            data.content = `${this.author.mention} pinned a message to this channel. See all the pins.`;
        } else {
            throw new Error("Unhandled MESSAGE_CREATE type: " + JSON.stringify(data, null, 2));
        }
        this.update(data, client);
    }

    update(data, client) {
        if(this.type === 3) { // (╯°□°）╯︵ ┻━┻
            (this.channel.call || this.channel.lastCall).update(data.call);
        }

        if(data.content !== undefined) {
            this.content = data.content || "";
            this._cleanContent = null;
            this.mentionEveryone = !!data.mention_everyone;

            this.mentions = data.mentions.map((mention) => client.users.add(mention, client));

            this.roleMentions = data.mention_roles;
        }

        this.pinned = data.pinned !== undefined ? !!data.pinned : this.pinned;
        this.editedTimestamp = data.edited_timestamp !== undefined ? Date.parse(data.edited_timestamp) : this.editedTimestamp;
        this.tts = data.tts !== undefined ? data.tts : this.tts;
        this.attachments = data.attachments !== undefined ? data.attachments : this.attachments; // TODO parse attachments
        this.embeds = data.embeds !== undefined ? data.embeds : this.embeds; // TODO parse embeds
    }

    get cleanContent() {
        if(this._cleanContent) {
            return this._cleanContent;
        }

        this._cleanContent = this.content;

        this.mentions.map((mention) => {
            if(this.channel.guild) {
                var member = this.channel.guild.members.get(mention.id);
                if(member) {
                    this._cleanContent = this._cleanContent.replace(new RegExp(`<@\!${mention.id}>`, "g"), "@" + member.nick || mention.username);
                }
            }
            this._cleanContent = this._cleanContent.replace(new RegExp(`<@\!?${mention.id}>`, "g"), "@" + mention.username);
        });

        if(this.channel.guild) {
            for(var roleID of this.roleMentions) {
                this._cleanContent = this._cleanContent.replace(new RegExp(`<@&${roleID}>`, "g"), "@" + this.channel.guild.roles.get(roleID).name);
            }
        }

        this.channelMentions.forEach((id) => {
            var channel = this._client.getChannel(id);
            if(channel && channel.name && channel.mention) {
                this._cleanContent = this._cleanContent.replace(channel.mention, "#" + channel.name);
            }
        });

        return (this._cleanContent = this._cleanContent.replace(/@everyone/g, "@\u200beveryone").replace(/@here/g, "@\u200bhere"));
    }

    get guild() {
        return this.channel.guild;
    }

    get channelMentions() {
        if(this._channelMentions) {
            return this._channelMentions;
        }

        return (this._channelMentions = (this.content.match(/<#[0-9]+>/g) || []).map((mention) => mention.substring(2, mention.length - 1)));
    }

    /**
    * Edit the message
    * @arg {String} content The updated message content
    * @arg {Boolean} [disableEveryone] Whether to filter @everyone/@here or not (overrides default)
    * @returns {Promise<Message>}
    */
    edit(content, disableEveryone) {
        return this._client.editMessage.call(this._client, this.channel.id, this.id, content, disableEveryone);
    }

    /**
    * Pin the message
    * @returns {Promise}
    */
    pin() {
        return this._client.pinMessage.call(this._client, this.channel.id, this.id);
    }

    /**
    * Unpin the message
    * @returns {Promise}
    */
    unpin() {
        return this._client.unpinMessage.call(this._client, this.channel.id, this.id);
    }

    /**
    * Delete the message
    * @returns {Promise}
    */
    delete() {
        return this._client.deleteMessage.call(this._client, this.channel.id, this.id);
    }
}

module.exports = Message;
<commit_msg>Update user in Message constructor<commit_after>"use strict";

const Call = require("./Call");
const User = require("./User");

/**
* Represents a message
* @prop {String} id The ID of the message
* @prop {Channel} channel The channel the message is in
* @prop {Guild?} guild The guild the message channel is in. Alias to channel.guild
* @prop {Number} timestamp Timestamp of message creation
* @prop {User} author The message author
* @prop {Member?} member The message author with server-specific data
* @prop {User[]} mentions Array of mentioned users
* @prop {String} content Message content
* @prop {String?} cleanContent Message content with mentions replaced by names, and @everyone/@here escaped
* @prop {String[]} roleMentions Array of mentioned roles' ids
* @prop {String[]?} channelMentions Array of mentions channels' ids
* @prop {Number?} editedTimestamp Timestamp of latest message edit
* @prop {Boolean} tts Whether to play the message using TTS or not
* @prop {Boolean} mentionEveryone Whether the message mentions everyone/here or not
* @prop {Object[]} attachments Array of attachments
* @prop {Object[]} embeds Array of embeds
* @prop {Boolean} command True if message is a command, false if not (CommandClient only)
*/
class Message {
    constructor(data, client) {
        this.id = data.id;
        this._client = client;
        this.type = data.type;
        this.timestamp = Date.parse(data.timestamp);
        this.channel = client.getChannel(data.channel_id) || {
            id: data.channel_id
        };
        if(data.author) {
            if(data.author.discriminator !== "0000") {
                client.users.update(data.author);
            }
            this.author = new User(data.author, client);
            if(this.channel.guild) {
                this.member = this.channel.guild.members.get(this.author.id);
            }
        }
        if(this.type === 0 || this.type === undefined);
        else if(this.type === 1) {
            data.content = `${this.author.mention} added <@${data.mentions[0].id}>.`;
        } else if(this.type === 2) {
            if(this.author.id === data.mentions[0].id) {
                data.content = `@${this.author.username} left the group.`;
            } else {
                data.content = `${this.author.mention} removed @${data.mentions[0].username}.`;
            }
        } else if(this.type === 3) { // (╯°□°）╯︵ ┻━┻
            if(data.call.ended_timestamp) {
                if((!this.channel.lastCall || this.channel.lastCall.endedTimestamp < Date.parse(data.call.ended_timestamp))) {
                    data.call.id = this.id;
                    this.channel.lastCall = new Call(data.call, this.channel);
                }
                if(~data.call.participants.indexOf(client.user.id)) {
                    data.content = `You missed a call from ${this.author.mention}.`;
                } else {
                    data.content = `${this.author.mention} started a call.`;
                }
            } else {
                if(!this.channel.call) {
                    data.call.id = this.id;
                    this.channel.call = new Call(data.call, this.channel);
                }
                data.content = `${this.author.mention} started a call. — Join the call.`;
            }
        } else if(this.type === 4) {
            data.content = `${this.author.mention} changed the channel name: ${data.content}`;
        } else if(this.type === 5) {
            data.content = `${this.author.mention} changed the channel icon.`;
        } else if(this.type === 6) {
            data.content = `${this.author.mention} pinned a message to this channel. See all the pins.`;
        } else {
            throw new Error("Unhandled MESSAGE_CREATE type: " + JSON.stringify(data, null, 2));
        }
        this.update(data, client);
    }

    update(data, client) {
        if(this.type === 3) { // (╯°□°）╯︵ ┻━┻
            (this.channel.call || this.channel.lastCall).update(data.call);
        }

        if(data.content !== undefined) {
            this.content = data.content || "";
            this._cleanContent = null;
            this.mentionEveryone = !!data.mention_everyone;

            this.mentions = data.mentions.map((mention) => client.users.add(mention, client));

            this.roleMentions = data.mention_roles;
        }

        this.pinned = data.pinned !== undefined ? !!data.pinned : this.pinned;
        this.editedTimestamp = data.edited_timestamp !== undefined ? Date.parse(data.edited_timestamp) : this.editedTimestamp;
        this.tts = data.tts !== undefined ? data.tts : this.tts;
        this.attachments = data.attachments !== undefined ? data.attachments : this.attachments; // TODO parse attachments
        this.embeds = data.embeds !== undefined ? data.embeds : this.embeds; // TODO parse embeds
    }

    get cleanContent() {
        if(this._cleanContent) {
            return this._cleanContent;
        }

        this._cleanContent = this.content;

        this.mentions.map((mention) => {
            if(this.channel.guild) {
                var member = this.channel.guild.members.get(mention.id);
                if(member) {
                    this._cleanContent = this._cleanContent.replace(new RegExp(`<@\!${mention.id}>`, "g"), "@" + member.nick || mention.username);
                }
            }
            this._cleanContent = this._cleanContent.replace(new RegExp(`<@\!?${mention.id}>`, "g"), "@" + mention.username);
        });

        if(this.channel.guild) {
            for(var roleID of this.roleMentions) {
                this._cleanContent = this._cleanContent.replace(new RegExp(`<@&${roleID}>`, "g"), "@" + this.channel.guild.roles.get(roleID).name);
            }
        }

        this.channelMentions.forEach((id) => {
            var channel = this._client.getChannel(id);
            if(channel && channel.name && channel.mention) {
                this._cleanContent = this._cleanContent.replace(channel.mention, "#" + channel.name);
            }
        });

        return (this._cleanContent = this._cleanContent.replace(/@everyone/g, "@\u200beveryone").replace(/@here/g, "@\u200bhere"));
    }

    get guild() {
        return this.channel.guild;
    }

    get channelMentions() {
        if(this._channelMentions) {
            return this._channelMentions;
        }

        return (this._channelMentions = (this.content.match(/<#[0-9]+>/g) || []).map((mention) => mention.substring(2, mention.length - 1)));
    }

    /**
    * Edit the message
    * @arg {String} content The updated message content
    * @arg {Boolean} [disableEveryone] Whether to filter @everyone/@here or not (overrides default)
    * @returns {Promise<Message>}
    */
    edit(content, disableEveryone) {
        return this._client.editMessage.call(this._client, this.channel.id, this.id, content, disableEveryone);
    }

    /**
    * Pin the message
    * @returns {Promise}
    */
    pin() {
        return this._client.pinMessage.call(this._client, this.channel.id, this.id);
    }

    /**
    * Unpin the message
    * @returns {Promise}
    */
    unpin() {
        return this._client.unpinMessage.call(this._client, this.channel.id, this.id);
    }

    /**
    * Delete the message
    * @returns {Promise}
    */
    delete() {
        return this._client.deleteMessage.call(this._client, this.channel.id, this.id);
    }
}

module.exports = Message;
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var fs = require('fs-extra');
var shortid = require('shortid');
var archiver = require('archiver');
var jsonfile = require('jsonfile');
var commentParser = require('comment-parser');
var Promise = require('bluebird');
var path = require('path');
var express = require('express');
var bodyParser = require('body-parser');
var webpack = require('webpack');
var config = require('./webpack.config.dev');

var remove = Promise.promisify(fs.remove);
var mkdirs = Promise.promisify(fs.mkdirs);
var copy = Promise.promisify(fs.copy);
var readJson = Promise.promisify(fs.readJson);
var writeJson = Promise.promisify(fs.writeJson);

var app = express();
var compiler = webpack(config);

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'assets')));
app.use(express.static(path.join(__dirname, 'modules')));

app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true,
  publicPath: config.output.publicPath
}));
app.use(require('webpack-hot-middleware')(compiler));

app.post('/download', (req, res) => {
  let framework = req.body.framework;
  let appName = req.body.appName;

  prepare().then((uid) => {
    generateFramework(framework, appName, uid).then(() => {

    });
  });

});

app.get('*', function(req, res) {
  res.sendFile(path.join(__dirname, 'index.html'));
});

app.listen(3000, 'localhost', function(err) {
  if (err) {
    console.log(err);
    return;
  }

  console.log('Listening at http://localhost:3000');
});

function generateFramework(framework, appName, uid) {
  return new Promise((resolve, reject) => {
    let dest = path.join(__dirname, 'build', uid);

    switch (framework) {
      case 'express':
        let src = path.join(__dirname, 'modules', 'express');
        copy(src, dest).then(() => {
          let packageJson = path.join(dest, 'package.json');
          readJson(packageJson).then((packageObj) => {
            packageObj.name = appName;
            writeJson(packageJson, packageObj, { spaces: 2 }).then(() => {
              resolve();
            });
          });
        });
        break;
      case 'hapi':
        break;
      case 'sails':
        break;
      default:
        reject('Unsupported Framework');
    }
  });
}

function generateTemplateEngine(params) {
  return new Promise(function(resolve, reject) {
    switch (params.templateEngine) {
      case 'jade':
        if (params.framework === 'express') {
          fs.readFile(__dirname + '/modules/express/app.js', function (err, data) {
            if (err) throw err;
            console.log(data);
          });
          // open app.js
          // parse comments
          // open template-engine/jade
          var parsed = commentParser.parse(data);
          console.log(parsed);
        }
        break;
      case 'handlebars':
        break;
      case 'swig':
        break;
      case 'none':
        break;
      default:
        reject('Unsupported template engine');
    }
  });
}

function generateZip(req, res) {
  return new Promise(function(resolve, reject) {
    var archive = archiver('zip');

    archive.on('error', function(err) {
      res.status(500).send(err.message);
    });

    res.on('close', function() {
      console.log('closing...')
      console.log('Archive wrote %d bytes', archive.pointer());
      return res.status(200).send('OK').end();
    });

    res.attachment('megaboilerplate-express.zip');

    archive.pipe(res);

    var files = [
      __dirname + '/modules/express/app.js',
      __dirname + '/modules/express/package.json'
    ];

    for (var i in files) {
      archive.append(fs.createReadStream(files[i]), { name: path.basename(files[i]) });
    }

    archive.finalize();
  });
}

function cleanup(uid) {
  return new Promise((resolve, reject) => {
    let location = path.join(__dirname, 'build', uid);
    remove(location).then(() => {
      resolve();
    }).catch(() => {
      reject();
    });
  });
}

function prepare() {
  return new Promise((resolve, reject) => {
    let uid = shortid.generate();
    let location = path.join(__dirname, 'build', uid);
    mkdirs(location).then(() => {
      resolve(uid);
    }).catch((err) => {
      reject(err);
    });
  });
}
<commit_msg>Two promises for updating package.json and new dirs<commit_after>'use strict';

var _ = require('lodash');
var fs = require('fs-extra');
var shortid = require('shortid');
var archiver = require('archiver');
var jsonfile = require('jsonfile');
var commentParser = require('comment-parser');
var Promise = require('bluebird');
var path = require('path');
var express = require('express');
var bodyParser = require('body-parser');
var webpack = require('webpack');
var config = require('./webpack.config.dev');

var remove = Promise.promisify(fs.remove);
var mkdirs = Promise.promisify(fs.mkdirs);
var copy = Promise.promisify(fs.copy);
var readJson = Promise.promisify(fs.readJson);
var writeJson = Promise.promisify(fs.writeJson);

var app = express();
var compiler = webpack(config);

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'assets')));
app.use(express.static(path.join(__dirname, 'modules')));

app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true,
  publicPath: config.output.publicPath
}));
app.use(require('webpack-hot-middleware')(compiler));

app.post('/download', (req, res) => {
  let framework = req.body.framework;
  let appName = req.body.appName;

  prepare().then((uid) => {
    generateFramework(framework, appName, uid).then(() => {

    });
  });

});

app.get('*', function(req, res) {
  res.sendFile(path.join(__dirname, 'index.html'));
});

app.listen(3000, 'localhost', function(err) {
  if (err) {
    console.log(err);
    return;
  }

  console.log('Listening at http://localhost:3000');
});

function generateFramework(framework, appName, uid) {
  return new Promise((resolve, reject) => {
    let dest = path.join(__dirname, 'build', uid);
    switch (framework) {
      case 'express':
        let src = path.join(__dirname, 'modules', 'express');
        copy(src, dest).then(() => {
          let updatePackageJson = new Promise((resolve, reject) => {
            let packageJson = path.join(dest, 'package.json');
            readJson(packageJson).then((packageObj) => {
              packageObj.name = appName;
              writeJson(packageJson, packageObj, { spaces: 2 }).then(() => {
                resolve();
              });
            });
          });
          var createPublicDirs = new Promise((resolve, reject) => {
            mkdirs(path.join(dest, 'public', 'images')).then(() => {
              mkdirs(path.join(dest, 'public', 'javascripts')).then(() => {
                mkdirs(path.join(dest, 'public', 'stylesheets')).then(() => {
                  resolve();
                });
              });
            })
          });
          Promise.all([updatePackageJson, createPublicDirs]).then(() => {
            resolve();
          });
        });
        break;
      case 'hapi':
        break;
      case 'sails':
        break;
      default:
        reject('Unsupported Framework');
    }
  });
}

function generateTemplateEngine(params) {
  return new Promise(function(resolve, reject) {
    switch (params.templateEngine) {
      case 'jade':
        if (params.framework === 'express') {
          fs.readFile(__dirname + '/modules/express/app.js', function (err, data) {
            if (err) throw err;
            console.log(data);
          });
          // open app.js
          // parse comments
          // open template-engine/jade
          var parsed = commentParser.parse(data);
          console.log(parsed);
        }
        break;
      case 'handlebars':
        break;
      case 'swig':
        break;
      case 'none':
        break;
      default:
        reject('Unsupported template engine');
    }
  });
}

function generateZip(req, res) {
  return new Promise(function(resolve, reject) {
    var archive = archiver('zip');

    archive.on('error', function(err) {
      res.status(500).send(err.message);
    });

    res.on('close', function() {
      console.log('closing...')
      console.log('Archive wrote %d bytes', archive.pointer());
      return res.status(200).send('OK').end();
    });

    res.attachment('megaboilerplate-express.zip');

    archive.pipe(res);

    var files = [
      __dirname + '/modules/express/app.js',
      __dirname + '/modules/express/package.json'
    ];

    for (var i in files) {
      archive.append(fs.createReadStream(files[i]), { name: path.basename(files[i]) });
    }

    archive.finalize();
  });
}

function cleanup(uid) {
  return new Promise((resolve, reject) => {
    let location = path.join(__dirname, 'build', uid);
    remove(location).then(() => {
      resolve();
    }).catch(() => {
      reject();
    });
  });
}

function prepare() {
  return new Promise((resolve, reject) => {
    let uid = shortid.generate();
    let location = path.join(__dirname, 'build', uid);
    mkdirs(location).then(() => {
      resolve(uid);
    }).catch((err) => {
      reject(err);
    });
  });
}
<|endoftext|>


<commit_before>/*jshint quotmark: false*/

'use strict';

var fs           = require('fs');
var path         = require('path');
var chalk        = require('chalk');
var Promise      = require('ember-cli/lib/ext/promise');
var Task         = require('ember-cli/lib/models/task');
var stringUtils  = require('ember-cli/lib/utilities/string');
var recast       = require('recast');
var childProcess = require('child_process');
var walkSync     = require('walkdir').sync;
var SilentError  = require('silent-error');
var compact      = require('lodash/array/compact');
var filterByExt  = require('../utilities/filter-by-ext');
var projectRoot  = process.cwd();
var debug        = require('debug')('ember-cli:mv');
var detectModuleType      = require('../utilities/detect-module-type');
var detectModuleStructure = require('../utilities/detect-module-structure');
var detectModuleName      = require('../utilities/detect-module-name');
var execSync;
// if ^0.12 io.js
if (childProcess.execSync) {
  execSync = childProcess.execSync;
} else {
  execSync = require('execSync').exec;
}

module.exports = Task.extend({
  run: function(options) {
    var ui = this.ui;
    var sourcelist  = this.getProjectFileList(projectRoot);
    var podModulePrefix = this.project.config().podModulePrefix || '';
    var podPath         = podModulePrefix.substr(podModulePrefix.lastIndexOf('/') + 1);
    var sourcePath      = options.args[0];
    var sourceType      = detectModuleType(sourcePath);
    var sourceStructure = detectModuleStructure(sourcePath, sourceType);
    var destPath        = options.args[1];
    var destType        = detectModuleType(destPath);
    var destStructure   = detectModuleStructure(destPath, destType);

    var sourceName = detectModuleName(sourcePath,
      { type: sourceType,
        structure: sourceStructure,
        podModulePrefix: podModulePrefix,
        podPath: podPath
      });
    var destName = detectModuleName(destPath,
      { type: destType,
        structure: destStructure,
        podModulePrefix: podModulePrefix,
        podPath: podPath
      });

    // console.log(sourceType, sourceStructure, sourceName);
    // console.log(destType, destStructure, destName);
    var visitOptions = {
      projectRoot: projectRoot,
      source: options.args[0],
      dest: options.args[1],
      sourceName: sourceName,
      destName: destName,
      sourceNameVariations: this.getNameVariations(sourceName),
      destNameVariations: this.getNameVariations(destName)
    };

    var trees = sourcelist.js
      .map(this.getJSTree)
      .filter(this.filterEmptyTrees);

    var templates = sourcelist.hbs
      .map(this.getHBSTree)
      .filter(this.filterEmptyTrees);

    this.visitProjectTrees(trees,visitOptions)
      .forEach(function(tree) {
        if (tree) {
          var printed = recast.print(tree.ast).code;
          if (!options.dryRun) {
            fs.writeFileSync(tree.dest, printed);
          }
          ui.writeLine(chalk.green('  updating file ') + tree.dest);
        }
      });

    this.visitTemplates(templates, visitOptions)
      .forEach(function(tree) {
        if (tree) {
          if (!options.dryRun) {
            fs.writeFileSync(tree.filePath, tree.source);
          }
          ui.writeLine(chalk.green('  updating file ') + tree.filePath);
        }
      });
    if (options.dryRun) {
      ui.writeLine(chalk.yellow('Updating dry-run, no files were updated.'));
    }
    return Promise.resolve(true);
  },

  /*
  * Return an array of name variations that ember uses
  */
  getNameVariations: function(name) {
    var variations = [];
    var lastSegment = name.split('/').slice(-1)[0] || name;
    variations.push(stringUtils.camelize(name));
    variations.push(stringUtils.dasherize(name));
    variations.push(stringUtils.dasherize(name).split('-').join(' '));
    variations.push(stringUtils.classify(lastSegment));

    // console.log('variations:',variations);

    return variations;
  },

  /*
  * Return full list of files in your project
  */
  getProjectFileList: function(root) {
    var files;
    var ignored = ['node_modules/', 'bower_components/', 'dist/', 'tmp/'];
    files = walkSync(root).filter(function(file){
      return !ignored.map(function(i){
        return file.indexOf(i) !== -1;
      }).reduce(function(total,value){
        // if we have a true value, then don't include
        return total ? total : (value ? value : total);
      });
    });
    return {
      js: filterByExt(files,'.js'),
      hbs: filterByExt(files,'.hbs')
    };
  },

  getJSTree: function(filePath) {
    var source = fs.readFileSync(filePath, 'utf-8');
    debug(filePath, source);
    try{
      return {
        filePath: filePath,
        source:recast.parse(source)
      };
    } catch(e) {
       throw new SilentError(filePath + ' recast error: ', e);
    }
    return;
  },

  getHBSTree: function(filePath) {
    var source = fs.readFileSync(filePath, 'utf-8');
    return {
      filePath: filePath,
      source:source
    };
  },

  filterEmptyTrees: function(source) {
    return typeof source !== 'undefined';
  },

  visitProjectTrees: function(trees, options) {
    // console.log('options: ',options)
    return trees.map(function(tree) {
      var hasSourceRef = false;
      recast.visit(tree, {
        visitNode: function(path) {
          var node = path.node;

          // console.log(node);
            options.sourceNameVariations.forEach(function(variation,index){
              var variationIndex;
              var sourceRegexp = new RegExp(variation);
              var destReplacement = options.destNameVariations[index];
              // console.log('variation', variation, index, node.type, node.value);
              // if(node.type === 'MemberExpression' || node.type === 'Identifier') console.log(node)
              if (node.type === 'Literal') {
                if (typeof node.value === 'string') {
                  variationIndex = node.value.indexOf(variation);
                  if (variationIndex !== -1) {
                    // console.log(node.value.indexOf(variation))
                    // console.log('match: ',variation, destReplacement, node)
                    if (variationIndex === 0 || node.value.charAt(variationIndex - 1) === ' ') {
                      hasSourceRef = true;
                      // console.log(node.value.replace(sourceRegexp, destReplacement))
                      node.value = node.value.replace(sourceRegexp, destReplacement);
                    } else {
                      // console.log(variation + ' matched: ' + node.value + ', but was not first index');
                    }
                  }
                }
              }
              if (node.type === 'Identifier') {
                if(node.name.indexOf(variation) !== -1) {
                  hasSourceRef = true;
                  node.name = node.name.replace(sourceRegexp, destReplacement);
                }
              }
            });

          // }
          this.traverse(path);
        }
      });
      if(hasSourceRef){
        return {ast:tree.source, dest:tree.filePath, options:options};
      }
      return;
    });
  },

  visitTemplates: function(trees, options) {
    // console.log(trees);
    return trees.map(function(tree){
      var moustaches = tree.source.match(/{{\s?([^}]*)\s?}}/g);
      var reg = new RegExp('{{'+options.sourceName+'}}');
      // console.log(options.sourceName,moustaches);
      var matches = moustaches.filter(function(m){
        // console.log('actual',m.match(reg))
        return m.match(reg);
      });
      // console.log('check',String('{{'+options.sourceName+'}}').match(reg));
      if (matches.length > 0) {
        // console.log(matches);
        tree.source = tree.source.replace(reg, '{{'+options.destName+'}}');
        // console.log(tree.source);
        return tree;
      }
      return;
    });

  }

});<commit_msg>protect against parsing the project blueprints folder, and handle routes and components without matching templates<commit_after>/*jshint quotmark: false*/

'use strict';

var fs           = require('fs');
var path         = require('path');
var chalk        = require('chalk');
var Promise      = require('ember-cli/lib/ext/promise');
var Task         = require('ember-cli/lib/models/task');
var stringUtils  = require('ember-cli/lib/utilities/string');
var recast       = require('recast');
var childProcess = require('child_process');
var walkSync     = require('walkdir').sync;
var SilentError  = require('silent-error');
var compact      = require('lodash/array/compact');
var filterByExt  = require('../utilities/filter-by-ext');
var projectRoot  = process.cwd();
var debug        = require('debug')('ember-cli:mv');
var detectModuleType      = require('../utilities/detect-module-type');
var detectModuleStructure = require('../utilities/detect-module-structure');
var detectModuleName      = require('../utilities/detect-module-name');
var execSync;
// if ^0.12 io.js
if (childProcess.execSync) {
  execSync = childProcess.execSync;
} else {
  execSync = require('execSync').exec;
}

module.exports = Task.extend({
  run: function(options) {
    var ui = this.ui;
    var sourcelist  = this.getProjectFileList(projectRoot);
    var podModulePrefix = this.project.config().podModulePrefix || '';
    var podPath         = podModulePrefix.substr(podModulePrefix.lastIndexOf('/') + 1);
    var sourcePath      = options.args[0];
    var sourceType      = detectModuleType(sourcePath);
    var sourceStructure = detectModuleStructure(sourcePath, sourceType);
    var destPath        = options.args[1];
    var destType        = detectModuleType(destPath);
    var destStructure   = detectModuleStructure(destPath, destType);

    var sourceName = detectModuleName(sourcePath,
      { type: sourceType,
        structure: sourceStructure,
        podModulePrefix: podModulePrefix,
        podPath: podPath
      });
    var destName = detectModuleName(destPath,
      { type: destType,
        structure: destStructure,
        podModulePrefix: podModulePrefix,
        podPath: podPath
      });

    // console.log(sourceType, sourceStructure, sourceName);
    // console.log(destType, destStructure, destName);
    var visitOptions = {
      projectRoot: projectRoot,
      source: options.args[0],
      dest: options.args[1],
      sourceName: sourceName,
      destName: destName,
      sourceNameVariations: this.getNameVariations(sourceName),
      destNameVariations: this.getNameVariations(destName)
    };

    var trees = sourcelist.js
      .map(this.getJSTree)
      .filter(this.filterEmptyTrees);

    var templates = sourcelist.hbs
      .map(this.getHBSTree)
      .filter(this.filterEmptyTrees);

    this.visitProjectTrees(trees,visitOptions)
      .forEach(function(tree) {
        if (tree) {
          var printed = recast.print(tree.ast).code;
          if (!options.dryRun) {
            fs.writeFileSync(tree.dest, printed);
          }
          ui.writeLine(chalk.green('  updating file ') + tree.dest);
        }
      });

    this.visitTemplates(templates, visitOptions)
      .forEach(function(tree) {
        if (tree) {
          if (!options.dryRun) {
            fs.writeFileSync(tree.filePath, tree.source);
          }
          ui.writeLine(chalk.green('  updating file ') + tree.filePath);
        }
      });
    if (options.dryRun) {
      ui.writeLine(chalk.yellow('Updating dry-run, no files were updated.'));
    }
    return Promise.resolve(true);
  },

  /*
  * Return an array of name variations that ember uses
  */
  getNameVariations: function(name) {
    var variations = [];
    var lastSegment = name.split('/').slice(-1)[0] || name;
    variations.push(stringUtils.camelize(name));
    variations.push(stringUtils.dasherize(name));
    variations.push(stringUtils.dasherize(name).split('-').join(' '));
    variations.push(stringUtils.classify(lastSegment));

    // console.log('variations:',variations);

    return variations;
  },

  /*
  * Return full list of files in your project
  */
  getProjectFileList: function(root) {
    var files;
    var ignored = ['node_modules/', 'bower_components/', 'dist/', 'tmp/', 'blueprints/'];
    files = walkSync(root).filter(function(file){
      return !ignored.map(function(i){
        return file.indexOf(i) !== -1;
      }).reduce(function(total,value){
        // if we have a true value, then don't include
        return total ? total : (value ? value : total);
      });
    });
    return {
      js: filterByExt(files,'.js'),
      hbs: filterByExt(files,'.hbs')
    };
  },

  getJSTree: function(filePath) {
    var source = fs.readFileSync(filePath, 'utf-8');
    debug(filePath, source);
    try{
      return {
        filePath: filePath,
        source:recast.parse(source)
      };
    } catch(e) {
       throw new SilentError(filePath + ' recast error: ', e);
    }
    return;
  },

  getHBSTree: function(filePath) {
    var source = fs.readFileSync(filePath, 'utf-8');
    return {
      filePath: filePath,
      source:source
    };
  },

  filterEmptyTrees: function(source) {
    return typeof source !== 'undefined';
  },

  visitProjectTrees: function(trees, options) {
    // console.log('options: ',options)
    return trees.map(function(tree) {
      var hasSourceRef = false;
      recast.visit(tree, {
        visitNode: function(path) {
          var node = path.node;

          // console.log(node);
            options.sourceNameVariations.forEach(function(variation,index){
              var variationIndex;
              var sourceRegexp = new RegExp(variation);
              var destReplacement = options.destNameVariations[index];
              // console.log('variation', variation, index, node.type, node.value);
              // if(node.type === 'MemberExpression' || node.type === 'Identifier') console.log(node)
              if (node.type === 'Literal') {
                if (typeof node.value === 'string') {
                  variationIndex = node.value.indexOf(variation);
                  if (variationIndex !== -1) {
                    // console.log(node.value.indexOf(variation))
                    // console.log('match: ',variation, destReplacement, node)
                    if (variationIndex === 0 || node.value.charAt(variationIndex - 1) === ' ') {
                      hasSourceRef = true;
                      // console.log(node.value.replace(sourceRegexp, destReplacement))
                      node.value = node.value.replace(sourceRegexp, destReplacement);
                    } else {
                      // console.log(variation + ' matched: ' + node.value + ', but was not first index');
                    }
                  }
                }
              }
              if (node.type === 'Identifier') {
                if(node.name.indexOf(variation) !== -1) {
                  hasSourceRef = true;
                  node.name = node.name.replace(sourceRegexp, destReplacement);
                }
              }
            });

          // }
          this.traverse(path);
        }
      });
      if(hasSourceRef){
        return {ast:tree.source, dest:tree.filePath, options:options};
      }
      return;
    });
  },

  visitTemplates: function(trees, options) {
    // console.log(trees);
    return trees.map(function(tree){
      var matches = [];
      var moustaches = tree.source.match(/{{\s?([^}]*)\s?}}/g);
      var reg = new RegExp('{{'+options.sourceName+'}}');
      // console.log(options.sourceName,moustaches);
      if (moustaches) {
        matches = moustaches.filter(function(m){
          // console.log('actual',m.match(reg))
          return m.match(reg);
        });
      }
      // console.log('check',String('{{'+options.sourceName+'}}').match(reg));
      if (matches.length > 0) {
        // console.log(matches);
        tree.source = tree.source.replace(reg, '{{'+options.destName+'}}');
        // console.log(tree.source);
        return tree;
      }
      return;
    });

  }

});<|endoftext|>


<commit_before>module.exports = function(gulp, config) {

	return function(done) {
		var c = require('better-console')
		c.info('watch reload')

		var browsersync = require('browser-sync')
		var fs = require('fs')
		var watch = require('gulp-watch')
		var filter = require('gulp-filter')

		var options = {}

		if(config.proxy) {
			options.proxy = proxy
		} else {
			options.server = { baseDir: config.dist_folder }
		}

		browsersync(options)

		// create dist_folder if not exists
		if(!fs.existsSync(config.dist_folder)) {
			fs.mkdirSync(config.dist_folder)
		}

		// watch empty directory workaround
		if(fs.readdirSync(config.dist_folder).length === 0) {
			var foofile = config.dist_folder + '/mango.temp.css'
			fs.writeFileSync(foofile, '' + Math.random())
			setTimeout(function() {
				fs.unlink(foofile)
			}, 5000)
		}

		var glob = [config.dist_folder + '/**/*.*']
		if(config.watch) glob.concat(config.watch)

		var handleReloadFile = function(file) {
			// files only
			if(!fs.existsSync(file.path) || !fs.lstatSync(file.path).isFile()) {
				return false
			}
			c.log('- handling reload', file.path)
			browsersync.reload(file.path)
		}

		return watch(glob).pipe(filter(handleReloadFile))
	}
}<commit_msg>Fixed: now using object property instead of undefined variable<commit_after>module.exports = function(gulp, config) {

	return function(done) {
		var c = require('better-console')
		c.info('watch reload')

		var browsersync = require('browser-sync')
		var fs = require('fs')
		var watch = require('gulp-watch')
		var filter = require('gulp-filter')

		var options = {}

		if(config.proxy) {
			options.proxy = config.proxy
		} else {
			options.server = { baseDir: config.dist_folder }
		}

		browsersync(options)

		// create dist_folder if not exists
		if(!fs.existsSync(config.dist_folder)) {
			fs.mkdirSync(config.dist_folder)
		}

		// watch empty directory workaround
		if(fs.readdirSync(config.dist_folder).length === 0) {
			var foofile = config.dist_folder + '/mango.temp.css'
			fs.writeFileSync(foofile, '' + Math.random())
			setTimeout(function() {
				fs.unlink(foofile)
			}, 5000)
		}

		var glob = [config.dist_folder + '/**/*.*']
		if(config.watch) glob.concat(config.watch)

		var handleReloadFile = function(file) {
			// files only
			if(!fs.existsSync(file.path) || !fs.lstatSync(file.path).isFile()) {
				return false
			}
			c.log('- handling reload', file.path)
			browsersync.reload(file.path)
		}

		return watch(glob).pipe(filter(handleReloadFile))
	}
}
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import { FormattedMessage } from 'react-intl'

const MetaItem = (props) => {
  const dataAutomationId = props[ 'data-automation-id' ]
  const { label, content } = props

  return (

      <FormattedMessage {...label} />:
      {content}

  )
}

MetaItem.propTypes = {
  label: PropTypes.shape({
    id: PropTypes.string.isRequired,
    description: PropTypes.string.isRequired,
    defaultMessage: PropTypes.string.isRequired
  }).isRequired,
  content: PropTypes.oneOfType([ PropTypes.string, PropTypes.node ]).isRequired,
  'data-automation-id': PropTypes.string
}

export default MetaItem
<commit_msg>patron-client: Remove proptype from metaitem<commit_after>import React, { PropTypes } from 'react'
import { FormattedMessage } from 'react-intl'

const MetaItem = (props) => {
  const dataAutomationId = props[ 'data-automation-id' ]
  const { label, content } = props

  return (

      <FormattedMessage {...label} />:
      {content}

  )
}

MetaItem.propTypes = {
  label: PropTypes.shape({
    id: PropTypes.string.isRequired,
    defaultMessage: PropTypes.string.isRequired
  }).isRequired,
  content: PropTypes.oneOfType([ PropTypes.string, PropTypes.node ]).isRequired,
  'data-automation-id': PropTypes.string
}

export default MetaItem
<|endoftext|>


<commit_before>import _ from 'lodash';
import classNames from 'classNames';
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as appActions from '../actions/app';
import * as tweetActions from '../actions/tweet';
import * as mediaActions from '../actions/media';
import keyStringDetector from '../registries/keyStringDetector';
import Tweet from '../../domain/models/Tweet';
import Media from '../../domain/models/Media';
import { Accounts } from '../../domain/models/Accounts'
import * as dialogService from '../registries/dialogService';

class NewTweetContainer extends Component {

  constructor(props) {
    super(props);
    this.state = this.initialState();
  }

  onTextareaChanged(event) {
    const text = event.target.value;
    this.setState({ text: text }, () => {
      const isExceededLimitCharLength = this.getRestTextLength() < 0;
      this.setState({ isExceededLimitCharLength: isExceededLimitCharLength });
    });
  }

  onTextareaKeyDown(event) {
    if (keyStringDetector.detect(event) === 'Return') {
      event.preventDefault();
      this.onTweetSubmitted();
    }
  }

  onTweetSubmitted() {
    if (this.state.isExceededLimitCharLength) {
      return;
    }

    const { account, mediaToTweet } = this.props;
    const { postTweet } = this.props.actions;

    postTweet(this.state.text, account.credential, mediaToTweet.mediaId);
    this.setState(this.initialState()); // TODO: init text area if succeed to tweet
  }

  onChooseImage() {
    dialogService.chooseImageFile({ extensions: Media.IMAGE_FILE_EXTENSIONS }, (filePaths) => {
      if (_.isUndefined(filePaths)) return;
      const media = Media.build(filePaths[0]);
      const { uploadToTweet } = this.props.actions;
      uploadToTweet(media);
    });
  }

  getRestTextLength() {
    return Tweet.LIMIT_CHARA_LENGTH - this.state.text.length;
  }

  initialState() {
    return { text: '', isExceededLimitCharLength: false };
  }

  get tweetCounterClassName() {
    return classNames({
      'NewTweet-main-tweetCounter': true,
      'is-overLimit': this.state.isExceededLimitCharLength
    });
  }

  get tweetLabelClassName() {
    return classNames({
      'NewTweet-footer-tweetLabel': true,
      'is-active': this.state.text.length > 0,
      'is-overLimit': this.state.isExceededLimitCharLength
    });
  }

  decodeImage(media) {
    if (media === null) return;
    const base64 = media.toBase64();
    const extension = media.extension;
    return `data:image/${extension};base64,${base64}`;
  }

  render() {
    const { account, mediaToTweet } = this.props;

    // TODO: render place

    return (

            <textarea
              autoFocus
              className="Editor-textarea"
              onChange={this.onTextareaChanged.bind(this)}
              onKeyDown={this.onTextareaKeyDown.bind(this)}
              value={this.state.text}>
            </textarea>

            {this.getRestTextLength()}

            Image

            Tweet

    );
  }
}

NewTweetContainer.propTypes = {
  actions: PropTypes.object.isRequired,
  account: PropTypes.object.isRequired
};

function mapDispatchToProps(dispatch) {
  const actions = _.assign({}, appActions, tweetActions, mediaActions);
  return {
    actions: bindActionCreators(actions, dispatch)
  };
}

function mapStateToProps(state) {
  const { accounts, mediaToTweet } = state;
  const account = Accounts.fromObjects(accounts).primary;

  return {
    account: account,
    mediaToTweet: mediaToTweet,
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(NewTweetContainer);
<commit_msg>Render preview element only if media exists<commit_after>import _ from 'lodash';
import classNames from 'classNames';
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as appActions from '../actions/app';
import * as tweetActions from '../actions/tweet';
import * as mediaActions from '../actions/media';
import keyStringDetector from '../registries/keyStringDetector';
import Tweet from '../../domain/models/Tweet';
import Media from '../../domain/models/Media';
import { Accounts } from '../../domain/models/Accounts'
import * as dialogService from '../registries/dialogService';

class NewTweetContainer extends Component {

  constructor(props) {
    super(props);
    this.state = this.initialState();
  }

  onTextareaChanged(event) {
    const text = event.target.value;
    this.setState({ text: text }, () => {
      const isExceededLimitCharLength = this.getRestTextLength() < 0;
      this.setState({ isExceededLimitCharLength: isExceededLimitCharLength });
    });
  }

  onTextareaKeyDown(event) {
    if (keyStringDetector.detect(event) === 'Return') {
      event.preventDefault();
      this.onTweetSubmitted();
    }
  }

  onTweetSubmitted() {
    if (this.state.isExceededLimitCharLength) {
      return;
    }

    const { account, mediaToTweet } = this.props;
    const { postTweet } = this.props.actions;

    postTweet(this.state.text, account.credential, mediaToTweet.mediaId);
    this.setState(this.initialState()); // TODO: init text area if succeed to tweet
  }

  onChooseImage() {
    dialogService.chooseImageFile({ extensions: Media.IMAGE_FILE_EXTENSIONS }, (filePaths) => {
      if (_.isUndefined(filePaths)) return;
      const media = Media.build(filePaths[0]);
      const { uploadToTweet } = this.props.actions;
      uploadToTweet(media);
    });
  }

  getRestTextLength() {
    return Tweet.LIMIT_CHARA_LENGTH - this.state.text.length;
  }

  initialState() {
    return { text: '', isExceededLimitCharLength: false };
  }

  get tweetCounterClassName() {
    return classNames({
      'NewTweet-main-tweetCounter': true,
      'is-overLimit': this.state.isExceededLimitCharLength
    });
  }

  get tweetLabelClassName() {
    return classNames({
      'NewTweet-footer-tweetLabel': true,
      'is-active': this.state.text.length > 0,
      'is-overLimit': this.state.isExceededLimitCharLength
    });
  }

  decodeImage(media) {
    if (media === null) return;
    const base64 = media.toBase64();
    const extension = media.extension;
    return `data:image/${extension};base64,${base64}`;
  }

  render() {
    const { account, mediaToTweet } = this.props;

    // TODO: render place

    return (

            <textarea
              autoFocus
              className="Editor-textarea"
              onChange={this.onTextareaChanged.bind(this)}
              onKeyDown={this.onTextareaKeyDown.bind(this)}
              value={this.state.text}>
            </textarea>

          { mediaToTweet.media && (

          )}

            {this.getRestTextLength()}

            Image

            Tweet

    );
  }
}

NewTweetContainer.propTypes = {
  actions: PropTypes.object.isRequired,
  account: PropTypes.object.isRequired
};

function mapDispatchToProps(dispatch) {
  const actions = _.assign({}, appActions, tweetActions, mediaActions);
  return {
    actions: bindActionCreators(actions, dispatch)
  };
}

function mapStateToProps(state) {
  const { accounts, mediaToTweet } = state;
  const account = Accounts.fromObjects(accounts).primary;

  return {
    account: account,
    mediaToTweet: mediaToTweet,
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(NewTweetContainer);
<|endoftext|>


<commit_before>import _ from 'lodash';
import classNames from 'classNames';
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as appActions from '../actions/app';
import * as tweetActions from '../actions/tweet';
import keyStringDetector from '../registries/keyStringDetector';
import Tweet from '../../domain/models/Tweet';

class NewTweetContainer extends Component {

  componentWillMount() {
    const { setUp } = this.props.actions;
    setUp();

    this.state = this.initialState();
  }

  onTextareaChanged(event) {
    const text = event.target.value;
    this.setState({ text: text }, () => {
      const isExceededLimitCharLength = this.getRestTextLength() < 0;
      this.setState({ isExceededLimitCharLength: isExceededLimitCharLength });
    });
  }

  onTextareaKeyDown(event) {
    if (keyStringDetector.detect(event) === 'Return') {
      event.preventDefault();
      this.onTweetSubmitted();
    }
  }

  onTweetSubmitted() {
    if (this.state.isExceededLimitCharLength) {
      return;
    }

    const { postTweet } = this.props.actions;

    postTweet(this.state.text);
    this.setState(this.initialState()); // TODO: init text area if succeed to tweet
  }

  getRestTextLength() {
    return Tweet.LIMIT_CHARA_LENGTH - this.state.text.length;
  }

  initialState() {
    return { text: '', isExceededLimitCharLength: false };
  }

  get tweetCounterClassName() {
    return classNames({
      'NewTweet-main-tweetCounter': true,
      'is-overLimit': this.state.isExceededLimitCharLength
    });
  }

  get tweetLabelClassName() {
    return classNames({
      'NewTweet-footer-tweetLabel': true,
      'is-active': this.state.text.length > 0,
      'is-overLimit': this.state.isExceededLimitCharLength
    });
  }

  render() {
    const { account } = this.props;

    // TODO: render place
    // TODO: post image

    return (

            <textarea
              className="Editor-textarea"
              onChange={this.onTextareaChanged.bind(this)}
              onKeyDown={this.onTextareaKeyDown.bind(this)}
              placeholder="What's happening?"
              value={this.state.text}>
            </textarea>

            {this.getRestTextLength()}

            Tweet

    );
  }
}

NewTweetContainer.propTypes = {
  actions: PropTypes.object.isRequired,
  account: PropTypes.object.isRequired
};

function mapDispatchToProps(dispatch) {
  const actions = _.assign({}, appActions, tweetActions);
  return {
    actions: bindActionCreators(actions, dispatch)
  };
}

function mapStateToProps(state) {
  const { account } = state;
  return {
    account: account
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(NewTweetContainer);
<commit_msg>Remove setUp action from NewTweetContainer<commit_after>import _ from 'lodash';
import classNames from 'classNames';
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as appActions from '../actions/app';
import * as tweetActions from '../actions/tweet';
import keyStringDetector from '../registries/keyStringDetector';
import Tweet from '../../domain/models/Tweet';

class NewTweetContainer extends Component {

  constructor(props) {
    super(props);
    this.state = this.initialState();
  }

  onTextareaChanged(event) {
    const text = event.target.value;
    this.setState({ text: text }, () => {
      const isExceededLimitCharLength = this.getRestTextLength() < 0;
      this.setState({ isExceededLimitCharLength: isExceededLimitCharLength });
    });
  }

  onTextareaKeyDown(event) {
    if (keyStringDetector.detect(event) === 'Return') {
      event.preventDefault();
      this.onTweetSubmitted();
    }
  }

  onTweetSubmitted() {
    if (this.state.isExceededLimitCharLength) {
      return;
    }

    const { postTweet } = this.props.actions;

    postTweet(this.state.text);
    this.setState(this.initialState()); // TODO: init text area if succeed to tweet
  }

  getRestTextLength() {
    return Tweet.LIMIT_CHARA_LENGTH - this.state.text.length;
  }

  initialState() {
    return { text: '', isExceededLimitCharLength: false };
  }

  get tweetCounterClassName() {
    return classNames({
      'NewTweet-main-tweetCounter': true,
      'is-overLimit': this.state.isExceededLimitCharLength
    });
  }

  get tweetLabelClassName() {
    return classNames({
      'NewTweet-footer-tweetLabel': true,
      'is-active': this.state.text.length > 0,
      'is-overLimit': this.state.isExceededLimitCharLength
    });
  }

  render() {
    const { account } = this.props;

    // TODO: render place
    // TODO: post image

    return (

            <textarea
              className="Editor-textarea"
              onChange={this.onTextareaChanged.bind(this)}
              onKeyDown={this.onTextareaKeyDown.bind(this)}
              placeholder="What's happening?"
              value={this.state.text}>
            </textarea>

            {this.getRestTextLength()}

            Tweet

    );
  }
}

NewTweetContainer.propTypes = {
  actions: PropTypes.object.isRequired,
  account: PropTypes.object.isRequired
};

function mapDispatchToProps(dispatch) {
  const actions = _.assign({}, appActions, tweetActions);
  return {
    actions: bindActionCreators(actions, dispatch)
  };
}

function mapStateToProps(state) {
  const { account } = state;
  return {
    account: account
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(NewTweetContainer);
<|endoftext|>


<commit_before>var http         = require('http'),
    query        = require('querystring'),
    Parser       = require('./parser'),
    EventEmitter = require('events').EventEmitter,
    Buffer       = require('buffer').Buffer;

// process.mixin is gone, a function for replacement
function extend(a, b) {
  Object.keys(b).forEach(function (key) {
    a[key] = b[key];
  });
  return a;
}

// Creates a streaming connection with twitter, and pushes any incoming
// statuses to a tweet event.
//
// options - optional Object that specifies custom configuration values.
//
// Valid option keys:
//
// port      - Integer of proxy port
// host      - String or ip address of the proxy server.  Defaults to 'stream.twitter.com'.
// path      - String of the base path for the request.
// action    - String part of the URL that specifies what to query for.
// track     - Array of keywords to filter.  See track()
// following - Array of userIDs to filter.  See follow()
// locations - Array of lat/long tuples.  See location()
// params    - Extra HTTP params Object to send with the request.
// user      - String Twitter login name or email.
// password  - String Twitter password.
//
// Returns TwitterNode instance.
var TwitterNode = exports.TwitterNode = function(options) {
  EventEmitter.call(this);
  if(!options) options = {};
  var self           = this;
  this.port          = options.port      || 80;
  this.host          = options.host      || 'stream.twitter.com';
  this.path          = options.path      || '/1/statuses/';
  this.action        = options.action    || 'filter';
  this.trackKeywords = options.track     || [];
  this.following     = options.follow    || [];
  this.locations     = options.locations || [];
  this.params        = options.params    || {};
  this.user          = options.user;
  this.password      = options.password;
  this.headers       = { "User-Agent": 'Twitter-Node' };
  this.debug         = false;
  this.parser        = new Parser();
  this.parser.addListener('object', processJSONObject(this));
  this.parser.addListener('error', function (error) {
    self.emit('error', new Error('TwitterNode parser error: ' + error.message));
  });
  if (options.headers) {
    extend(this.headers, options.headers);
  }
}

TwitterNode.prototype = Object.create(EventEmitter.prototype);

// Track the following keyword.  If called multiple times, all words are sent
// as a comma-separated parameter to Twitter.
//
// See: http://apiwiki.twitter.com/Streaming-API-Documentation#track
//
// word - String word to track.
//
// Returns nothing.
TwitterNode.prototype.track = function track(word) {
  this.trackKeywords.push(word);
  return this;
};

// Follow the given twitter user (specified by their userID, not screen name)
// If called multiple times, all userIDs are sent as a comma-separated
// parameter to Twitter.
//
// See: http://apiwiki.twitter.com/Streaming-API-Documentation#follow
//
// userID - Integer userID to track.
//
// Returns nothing.
TwitterNode.prototype.follow = function follow(userId) {
  this.following.push(userId);
  return this;
};

// Match tweets in the given bounding box.
//
// See: http://apiwiki.twitter.com/Streaming-API-Documentation#locations
//
// Example: location(-122.75, 36.8, -121.75, 37.8) // SF
//
// lng1, lat1 - southwest corner of the bounding box.
// lng2, lat2 - northeast corner.
//
// Returns nothing.
TwitterNode.prototype.location = function location(lng1, lat1, lng2, lat2) {
  this.locations.push(lng1, lat1, lng2, lat2)
  return this;
};

TwitterNode.prototype.stream = function stream() {
  if (this._clientResponse && this._clientResponse.connection) {
    this._clientResponse.socket.end();
  }

  if (this.action === 'filter' && this.buildParams() === '') return;

  var client  = this._createClient(this.port, this.host),
      headers = extend({}, this.headers),
      twit    = this,
      request;

  headers['Host'] = this.host;

  if (this.user) {
    headers['Authorization'] = basicAuth(this.user, this.password);
  }

  request = client.request("GET", this.requestUrl(), headers);

  request.addListener('response', function(response) {
    twit._clientResponse = response;

    response.addListener('data', function(chunk) {
      twit._receive(chunk);
    });

    response.addListener('end', function() {
      twit.emit('end', this);
      twit.emit('close', this);
    });
  });
  request.end();
  return this;
};

// UTILITY METHODS

// Passes the received data to the streaming JSON parser.
//
// chunk - String data received from the HTTP stream.
//
// Returns nothing.
TwitterNode.prototype._receive = function(chunk) {
  this.parser.receive(chunk);
  return this;
};

// Creates the HTTP client object for the stream connection.  Override this
// to pass in your own client if needed.
//
// port - Integer port number to connect to.
// host - String host name to connect to.
//
// returns Http Client instance.
TwitterNode.prototype._createClient = function(port, host) {
  return http.createClient(port, host)
};

// Builds the URL for the streaming request.
//
// Returns a String absolute URL.
TwitterNode.prototype.requestUrl = function() {
  return this.path + this.action + ".json" + this.buildParams();
};

// Builds the GET params for the streaming request.
//
// Returns URI encoded string: "?track=LOST"
TwitterNode.prototype.buildParams = function() {
  var options = {};
  extend(options, this.params);
  if (this.trackKeywords.length > 0) options.track = this.trackKeywords.join(",");
  if (this.following.length > 0)     options.follow = this.following.join(",");
  if (this.locations.length > 0)     options.locations = this.locations.join(",");
  if (options.track || options.follow || options.locations) {
    return "?" + query.stringify(options);
  }
  return "";
};

// Base64 encodes the given username and password.
//
// user - String Twitter screen name or email.
// pass - String password.
//
// Returns a Basic Auth header fit for HTTP.
var basicAuth = function basicAuth(user, pass) {
  return "Basic " + new Buffer(user + ":" + pass).toString('base64');
};

// Creates a callback for the object Event of the JSON Parser.
//
// twit - an instance of this TwitterNode.
//
// Returns a function to be passed to the addListener call on the parser.
var processJSONObject = function processJSONObject(twit) {
  return function(tweet) {
    if (tweet.limit) {
      twit.emit('limit', tweet.limit);
    } else if (tweet['delete']) {
      twit.emit('delete', tweet['delete']);
    } else {
      twit.emit('tweet', tweet);
    }
  };
};
<commit_msg>updated to use ssl<commit_after>var https        = require('https'),
    query        = require('querystring'),
    Parser       = require('./parser'),
    EventEmitter = require('events').EventEmitter,
    Buffer       = require('buffer').Buffer;

// process.mixin is gone, a function for replacement
function extend(a, b) {
  Object.keys(b).forEach(function (key) {
    a[key] = b[key];
  });
  return a;
}

// Creates a streaming connection with twitter, and pushes any incoming
// statuses to a tweet event.
//
// options - optional Object that specifies custom configuration values.
//
// Valid option keys:
//
// port      - Integer of proxy port
// host      - String or ip address of the proxy server.  Defaults to 'stream.twitter.com'.
// path      - String of the base path for the request.
// action    - String part of the URL that specifies what to query for.
// track     - Array of keywords to filter.  See track()
// following - Array of userIDs to filter.  See follow()
// locations - Array of lat/long tuples.  See location()
// params    - Extra HTTP params Object to send with the request.
// user      - String Twitter login name or email.
// password  - String Twitter password.
//
// Returns TwitterNode instance.
var TwitterNode = exports.TwitterNode = function(options) {
  EventEmitter.call(this);
  if(!options) options = {};
  var self           = this;
  this.port          = options.port      || 443;
  this.host          = options.host      || 'stream.twitter.com';
  this.path          = options.path      || '/1/statuses/';
  this.action        = options.action    || 'filter';
  this.trackKeywords = options.track     || [];
  this.following     = options.follow    || [];
  this.locations     = options.locations || [];
  this.params        = options.params    || {};
  this.user          = options.user;
  this.password      = options.password;
  this.headers       = { "User-Agent": 'Twitter-Node' };
  this.debug         = false;
  this.parser        = new Parser();
  this.parser.addListener('object', processJSONObject(this));
  this.parser.addListener('error', function (error) {
    self.emit('error', new Error('TwitterNode parser error: ' + error.message));
  });
  if (options.headers) {
    extend(this.headers, options.headers);
  }
}

TwitterNode.prototype = Object.create(EventEmitter.prototype);

// Track the following keyword.  If called multiple times, all words are sent
// as a comma-separated parameter to Twitter.
//
// See: http://apiwiki.twitter.com/Streaming-API-Documentation#track
//
// word - String word to track.
//
// Returns nothing.
TwitterNode.prototype.track = function track(word) {
  this.trackKeywords.push(word);
  return this;
};

// Follow the given twitter user (specified by their userID, not screen name)
// If called multiple times, all userIDs are sent as a comma-separated
// parameter to Twitter.
//
// See: http://apiwiki.twitter.com/Streaming-API-Documentation#follow
//
// userID - Integer userID to track.
//
// Returns nothing.
TwitterNode.prototype.follow = function follow(userId) {
  this.following.push(userId);
  return this;
};

// Match tweets in the given bounding box.
//
// See: http://apiwiki.twitter.com/Streaming-API-Documentation#locations
//
// Example: location(-122.75, 36.8, -121.75, 37.8) // SF
//
// lng1, lat1 - southwest corner of the bounding box.
// lng2, lat2 - northeast corner.
//
// Returns nothing.
TwitterNode.prototype.location = function location(lng1, lat1, lng2, lat2) {
  this.locations.push(lng1, lat1, lng2, lat2)
  return this;
};

TwitterNode.prototype.stream = function stream() {
  if (this._clientResponse && this._clientResponse.connection) {
    this._clientResponse.socket.end();
  }

  if (this.action === 'filter' && this.buildParams() === '') return;

  var headers = extend({}, this.headers),
      twit    = this,
      request;

  headers['Host'] = this.host;

  if (this.user) {
    headers['Authorization'] = basicAuth(this.user, this.password);
  }

  var requestOptions = {
    host: this.host,
    port: this.port,
    path: this.requestUrl(),
    method: 'POST',
    headers: headers
  };

  request = https.request(requestOptions, function(response) {
    twit._clientResponse = response;

    response.on('data', function(chunk){
      twit._receive(chunk);
    });

    response.on('end', function() {
      twit.emit('end', this);
      twit.emit('close', this);
    });
  });

  request.end();

  return this;
};

// UTILITY METHODS

// Passes the received data to the streaming JSON parser.
//
// chunk - String data received from the HTTP stream.
//
// Returns nothing.
TwitterNode.prototype._receive = function(chunk) {
  this.parser.receive(chunk);
  return this;
};

// Builds the URL for the streaming request.
//
// Returns a String absolute URL.
TwitterNode.prototype.requestUrl = function() {
  return this.path + this.action + ".json" + this.buildParams();
};

// Builds the GET params for the streaming request.
//
// Returns URI encoded string: "?track=LOST"
TwitterNode.prototype.buildParams = function() {
  var options = {};
  extend(options, this.params);
  if (this.trackKeywords.length > 0) options.track = this.trackKeywords.join(",");
  if (this.following.length > 0)     options.follow = this.following.join(",");
  if (this.locations.length > 0)     options.locations = this.locations.join(",");
  if (options.track || options.follow || options.locations) {
    return "?" + query.stringify(options);
  }
  return "";
};

// Base64 encodes the given username and password.
//
// user - String Twitter screen name or email.
// pass - String password.
//
// Returns a Basic Auth header fit for HTTP.
var basicAuth = function basicAuth(user, pass) {
  return "Basic " + new Buffer(user + ":" + pass).toString('base64');
};

// Creates a callback for the object Event of the JSON Parser.
//
// twit - an instance of this TwitterNode.
//
// Returns a function to be passed to the addListener call on the parser.
var processJSONObject = function processJSONObject(twit) {
  return function(tweet) {
    if (tweet.limit) {
      twit.emit('limit', tweet.limit);
    } else if (tweet['delete']) {
      twit.emit('delete', tweet['delete']);
    } else {
      twit.emit('tweet', tweet);
    }
  };
};
<|endoftext|>