<commit_before>var MongoClient = require('mongodb').MongoClient
var url = "mongodb://localhost:27017/JuicyData"

var apiKey = require('../config/apiKey.js')
var axios = require('axios')
var toaApi = axios.create({
	baseURL: 'http://theorangealliance.org/apiv2/',
	timeout: 10000,
	headers: {'X-Application-Origin': 'JuicyData', 'X-TOA-Key': apiKey}
})
var eventKeys = [
	'1718-NCAL-RWC',

	'1718-FIM-CMP1',	//team 5386
	'1718-FIM-MARY',
	'1718-FIM-GLBR'
	] //Currently ongoing events

module.exports = function() {
	getData()
}

function getData() {
	MongoClient.connect(url, function(err, db) {
		if (err) throw err
		let matchDatas = {}
		let gameDatas = {red: {}, blue: {}}
		let matchNumbers = {}
		for (let eventKey of eventKeys) {
			db.collection('events').findOne({'_id': eventKey}, function(err, data) {
				if (err) throw err
				let eventInformation = null
				if (data) {
					eventInformation = data._id
				} else {
					console.log('No event in database for TOA event key ' + eventKey)
				}
				toaApi.get('/event/' + eventKey + '/matches').then(function(response) {
					let matches = response.data
					matchNumbers[eventKey] = []
					let relevantMatches = {}
					matchDatas[eventKey] = {}
					gameDatas.red[eventKey] = {}
					gameDatas.blue[eventKey] = {}
					for (let match of matches) {
						let matchNumber = match.match_name.split('Quals ')[1]
						if (matchNumber) {
							if (!matchNumbers[eventKey].includes(matchNumber)) {
								matchNumbers[eventKey].push(Number(matchNumber))
							}
							relevantMatches[matchNumber] = match
						}
					}
					for (let matchNumber of matchNumbers[eventKey]) {
						let match = relevantMatches[matchNumber]
						toaApi.get('/match/' + match.match_key + '/stations').then(function(response) {
							let stations = response.data
							let teams = {
								red: [],
								blue: []
							}
							for (let station of stations) {
								allianceCode = station.station_key.charAt(station.station_key.length-2)
								if (allianceCode === 'R') {
									teams.red.push(Number(station.team_key))
								} else if (allianceCode === 'B') {
									teams.blue.push(Number(station.team_key))
								}
							}

							let matchData = {
								_id:{
									toaEventKey: eventKey,
									matchInformation:{
										matchNumber: Number(matchNumber),
										teams: {
											red1: teams.red[0],
											red2: teams.red[1],
											blue1: teams.blue[0],
											blue2: teams.blue[1]
										}
									}
								},
								resultInformation:{
									winner: match.red_score > match.blue_score ? 'red' : match.blue_score > match.red_score ? 'blue' : 'tie', //Pls check latter if "score" indlues penailtyes for this caluclation
									score:{
										auto:{
											red: match.red_auto_score,
											blue: match.blue_auto_score
										},
										driver:{
											red: match.red_tele_score,
											blue: match.blue_tele_score
										},
										end:{
											red: match.red_end_score,
											blue: match.blue_end_score
										},
										total:{
											// red: match.red_score - match.blue_penalty, //I think that blue penialty is the penailty blue gets
											// blue: match.blue_score - match.red_penalty //And score is their total (penailty + score)
											red: match.red_auto_score + match.red_tele_score + match.red_end_score,
											blue: match.blue_auto_score + match.blue_tele_score + match.blue_end_score
										},
										penalty:{
											red: match.red_penalty,
											blue: match.blue_penalty
										},
										final:{
											red: match.red_score,
											blue: match.blue_score
										}
									}
								}
							}
							saveMatchData(db, matchData, eventKey, matchNumber, eventKeys, matchNumbers, matchDatas, gameDatas)

							toaApi.get('/match/' + match.match_key + '/details').then(function(response) {
								let matchDetails = response.data[0]
								for (let alliance of ['red', 'blue']) {
									let gameData = {
										_id:{
											toaEventKey: eventKey,
											matchInformation:{
												matchNumber: matchNumber,
												robotAlliance: alliance, //blue or red; with lower case
												teams: teams[alliance]
											}
										},
										gameInformation:{	//CHECK IF ALL THSES TYPES ARE CORRECT AND ALSO HAVE COFRRECT MEANING!
											auto:{
												jewel: matchDetails[alliance+'_auto_jewel'],
												glyphs: matchDetails[alliance+'_auto_glyphs'],
												keys: matchDetails[alliance+'_auto_keys'],
												park: matchDetails[alliance+'_auto_park']
											},
											driver:{
												glyphs: matchDetails[alliance+'_tele_glyphs'],
												rows: matchDetails[alliance+'_tele_rows'],
												columns: matchDetails[alliance+'_tele_columns'],
												cypher: matchDetails[alliance+'_tele_cypher']
											},
											end:{
												relic1: matchDetails[alliance+'_end_relic_one'],	//Amount of relics in that zone
												relic2: matchDetails[alliance+'_end_relic_two'],
												relic3: matchDetails[alliance+'_end_relic_three'],
												relicsUp: matchDetails[alliance+'_end_relic_up'],	//Amount of relects standing up
												balanced: matchDetails[alliance+'_end_robot_bal']	//How many robots are balanced
											}
										}
									}
									saveGameData(db, gameData, alliance, eventKey, matchNumber, eventKeys, matchNumbers, matchDatas, gameDatas)
								}
							})
						})
					}
				})
			})
		}
	})
	// setTimeout(getData, 180000) Do it all again in 3 minutes
}

function saveMatchData(db, matchData, eventKey, matchNumber, eventKeys, matchNumbers, matchDatas, gameDatas) {
  	db.collection('matchData').save(matchData, function(err, res) {
    	if (err) throw err
    	matchDatas[eventKey][matchNumber] = matchData
    	finishIfDone(db, eventKeys, matchNumbers, matchDatas, gameDatas)
  	})
}

function saveGameData(db, gameData, alliance, eventKey, matchNumber, eventKeys, matchNumbers, matchDatas, gameDatas) {
  	db.collection('gameData').save(gameData, function(err, res) {
    	if (err) throw err
    	gameDatas[alliance][eventKey][matchNumber] = gameData
    	finishIfDone(db, eventKeys, matchNumbers, matchDatas, gameDatas)
  	})
}

function finishIfDone(db, eventKeys, matchNumbers, matchDatas, gameDatas) {
	for (let eventKey of eventKeys) {
		for (let matchNumber of matchNumbers[eventKey]) {
			if (!matchDatas[eventKey][matchNumber] || !gameDatas.red[eventKey][matchNumber] || !gameDatas.blue[eventKey][matchNumber]) {
				return
			}
		}
	}
	db.close()
	printDatas(eventKeys, matchNumbers, matchDatas, gameDatas)
}

function printDatas(eventKeys, matchNumbers, matchDatas, gameDatas) {
	for (let eventKey of eventKeys) {
		for (let matchNumber of matchNumbers[eventKey]) {
			console.log(eventKey + ' Match ' + matchNumber + ' matchData:')
			console.log(JSON.stringify(matchDatas[eventKey][matchNumber], null, 2))
			console.log()
			console.log(eventKey + ' Match ' + matchNumber + ' red gameData:')
			console.log(JSON.stringify(gameDatas.red[eventKey][matchNumber], null, 2))
			console.log()
			console.log(eventKey + ' Match ' + matchNumber + ' blue gameData:')
			console.log(JSON.stringify(gameDatas.blue[eventKey][matchNumber], null, 2))
			console.log()
			console.log()
		}
		console.log()
	}
}<commit_msg>Fixed HTTP request issues<commit_after>var MongoClient = require('mongodb').MongoClient
var url = "mongodb://localhost:27017/JuicyData"

var apiKey = require('../config/apiKey.js')
var axios = require('axios')
var toaApi = axios.create({
	baseURL: 'http://theorangealliance.org/apiv2/',
	timeout: 10000,
	headers: {'X-Application-Origin': 'JuicyData', 'X-TOA-Key': apiKey}
})
var eventKeys = [
	'1718-NCAL-RWC',

	'1718-FIM-CMP1',	//team 5386
	'1718-FIM-MARY',
	'1718-FIM-GLBR'
	] //Currently ongoing events

module.exports = function() {
	getData()
}

function getData() {
	MongoClient.connect(url, function(err, db) {
		if (err) throw err
		let matchDatas = {}
		let gameDatas = {red: {}, blue: {}}
		let matchNumbers = {}
		for (let eventKey of eventKeys) {
			db.collection('events').findOne({'_id': eventKey}, function(err, data) {
				if (err) throw err
				let eventInformation = null
				if (data) {
					eventInformation = data._id
				} else {
					console.log('No event in database for TOA event key ' + eventKey)
				}
				let getStations = function() {
					toaApi.get('/event/' + eventKey + '/matches/stations').then(function(response) {
						let stations = response.data
						let teamsByMatch = {}
						for (let station of stations) {
							let matchNumber = station.match_name.split('Quals ')[1]
							if (matchNumber) {
								if (!teamsByMatch[matchNumber]) {
									teamsByMatch[matchNumber] = station.teams.split(',')
								}
							}
						}
						let getMatches = function() {
							toaApi.get('/event/' + eventKey + '/matches').then(function(response) {
								let matches = response.data
								matchNumbers[eventKey] = []
								let relevantMatches = {}
								matchDatas[eventKey] = {}
								gameDatas.red[eventKey] = {}
								gameDatas.blue[eventKey] = {}
								for (let match of matches) {
									let matchNumber = match.match_name.split('Quals ')[1]
									if (matchNumber) {
										if (!matchNumbers[eventKey].includes(matchNumber)) {
											matchNumbers[eventKey].push(Number(matchNumber))
										}
										relevantMatches[matchNumber] = match
									}
								}
								for (let matchNumber of matchNumbers[eventKey]) {
									let match = relevantMatches[matchNumber]
									let teams = {
										red: [
											Number(teamsByMatch[matchNumber][0]),
											Number(teamsByMatch[matchNumber][1])
										],
										blue: [
											Number(teamsByMatch[matchNumber][2]),
											Number(teamsByMatch[matchNumber][3])
										]
									}

									let matchData = {
										_id:{
											toaEventKey: eventKey,
											matchInformation:{
												matchNumber: Number(matchNumber),
												teams: {
													red1: teams.red[0],
													red2: teams.red[1],
													blue1: teams.blue[0],
													blue2: teams.blue[1]
												}
											}
										},
										resultInformation:{
											winner: match.red_score > match.blue_score ? 'red' : match.blue_score > match.red_score ? 'blue' : 'tie', //Pls check latter if "score" indlues penailtyes for this caluclation
											score:{
												auto:{
													red: match.red_auto_score,
													blue: match.blue_auto_score
												},
												driver:{
													red: match.red_tele_score,
													blue: match.blue_tele_score
												},
												end:{
													red: match.red_end_score,
													blue: match.blue_end_score
												},
												total:{
													// red: match.red_score - match.blue_penalty, //I think that blue penialty is the penailty blue gets
													// blue: match.blue_score - match.red_penalty //And score is their total (penailty + score)
													red: match.red_auto_score + match.red_tele_score + match.red_end_score,
													blue: match.blue_auto_score + match.blue_tele_score + match.blue_end_score
												},
												penalty:{
													red: match.red_penalty,
													blue: match.blue_penalty
												},
												final:{
													red: match.red_score,
													blue: match.blue_score
												}
											}
										}
									}
									saveMatchData(db, matchData, eventKey, matchNumber, eventKeys, matchNumbers, matchDatas, gameDatas)

									let getDetails = function() {
										toaApi.get('/match/' + match.match_key + '/details').then(function(response) {
											let matchDetails = response.data[0]
											for (let alliance of ['red', 'blue']) {
												let gameData = {
													_id:{
														toaEventKey: eventKey,
														matchInformation:{
															matchNumber: matchNumber,
															robotAlliance: alliance, //blue or red; with lower case
															teams: teams[alliance]
														}
													},
													gameInformation:{	//CHECK IF ALL THSES TYPES ARE CORRECT AND ALSO HAVE COFRRECT MEANING!
														auto:{
															jewel: matchDetails[alliance+'_auto_jewel'],
															glyphs: matchDetails[alliance+'_auto_glyphs'],
															keys: matchDetails[alliance+'_auto_keys'],
															park: matchDetails[alliance+'_auto_park']
														},
														driver:{
															glyphs: matchDetails[alliance+'_tele_glyphs'],
															rows: matchDetails[alliance+'_tele_rows'],
															columns: matchDetails[alliance+'_tele_columns'],
															cypher: matchDetails[alliance+'_tele_cypher']
														},
														end:{
															relic1: matchDetails[alliance+'_end_relic_one'],	//Amount of relics in that zone
															relic2: matchDetails[alliance+'_end_relic_two'],
															relic3: matchDetails[alliance+'_end_relic_three'],
															relicsUp: matchDetails[alliance+'_end_relic_up'],	//Amount of relects standing up
															balanced: matchDetails[alliance+'_end_robot_bal']	//How many robots are balanced
														}
													}
												}
												saveGameData(db, gameData, alliance, eventKey, matchNumber, eventKeys, matchNumbers, matchDatas, gameDatas)
											}
										}).catch(function(e) {
											console.log("Couldn't get details for " + eventKey + " match " + matchNumber + ", retrying: " + e)
											setTimeout(getDetails, 100)
										})
									}
									getDetails()
								}
							}).catch(function(e) {
								console.log("Couldn't get matches for " + eventKey + ", retrying: " + e)
								setTimeout(getMatches, 100)
							})
						}
						getMatches()
					}).catch(function(e) {
						console.log("Couldn't get stations for " + eventKey + ", retrying: " + e)
						setTimeout(getStations, 100)
					})
				}
				getStations()
			})
		}
	})
	// setTimeout(getData, 180000) Do it all again in 3 minutes
}

function saveMatchData(db, matchData, eventKey, matchNumber, eventKeys, matchNumbers, matchDatas, gameDatas) {
  	db.collection('matchData').save(matchData, function(err, res) {
    	if (err) throw err
    	matchDatas[eventKey][matchNumber] = matchData
    	finishIfDone(db, eventKeys, matchNumbers, matchDatas, gameDatas)
  	})
}

function saveGameData(db, gameData, alliance, eventKey, matchNumber, eventKeys, matchNumbers, matchDatas, gameDatas) {
  	db.collection('gameData').save(gameData, function(err, res) {
    	if (err) throw err
    	gameDatas[alliance][eventKey][matchNumber] = gameData
    	finishIfDone(db, eventKeys, matchNumbers, matchDatas, gameDatas)
  	})
}

function finishIfDone(db, eventKeys, matchNumbers, matchDatas, gameDatas) {
	for (let eventKey of eventKeys) {
		for (let matchNumber of matchNumbers[eventKey]) {
			if (!matchDatas[eventKey][matchNumber] || !gameDatas.red[eventKey][matchNumber] || !gameDatas.blue[eventKey][matchNumber]) {
				return
			}
		}
	}
	db.close()
	printDatas(eventKeys, matchNumbers, matchDatas, gameDatas)
	console.log('Completed Retrieval of Match and Game Data!')
}

function printDatas(eventKeys, matchNumbers, matchDatas, gameDatas) {
	for (let eventKey of eventKeys) {
		for (let matchNumber of matchNumbers[eventKey]) {
			console.log(eventKey + ' Match ' + matchNumber + ' matchData:')
			console.log(JSON.stringify(matchDatas[eventKey][matchNumber], null, 2))
			console.log()
			console.log(eventKey + ' Match ' + matchNumber + ' red gameData:')
			console.log(JSON.stringify(gameDatas.red[eventKey][matchNumber], null, 2))
			console.log()
			console.log(eventKey + ' Match ' + matchNumber + ' blue gameData:')
			console.log(JSON.stringify(gameDatas.blue[eventKey][matchNumber], null, 2))
			console.log()
			console.log()
		}
		console.log('-----------------------------------------------------------------')
	}
}<|endoftext|>


<commit_before>var Slack = require('../services/Slack')

module.exports = bookshelf.Model.extend({
  tableName: 'community',

  creator: function () {
    return this.belongsTo(User, 'created_by_id')
  },

  inactiveUsers: function () {
    return this.belongsToMany(User, 'users_community', 'community_id', 'user_id')
      .query({where: {'users_community.active': false}})
  },

  invitations: function () {
    return this.hasMany(Invitation)
  },

  leader: function () {
    return this.belongsTo(User, 'leader_id')
  },

  tagFollows: function () {
    return this.hasMany(TagFollow)
  },

  memberships: function () {
    return this.hasMany(Membership).query({where: {'users_community.active': true}})
  },

  moderators: function () {
    return this.belongsToMany(User, 'users_community', 'community_id', 'user_id')
      .query({where: {role: Membership.MODERATOR_ROLE}})
  },

  network: function () {
    return this.belongsTo(Network)
  },

  users: function () {
    return this.belongsToMany(User).through(Membership)
      .query({where: {'users_community.active': true, 'users.active': true}}).withPivot('role')
  },

  posts: function () {
    return this.belongsToMany(Post).through(PostMembership)
      .query({where: {'post.active': true}})
  },

  tags: function () {
    return this.belongsToMany(Tag).through(CommunityTag).withPivot('user_id')
  },

  comments: function () {
    // FIXME get this to use the model relation API
    // instead of the Collection API so that the use
    // of fetch vs. fetchAll isn't confusing.
    // as it is now, it uses "fetchAll" when all the
    // other relations use "fetch"
    var communityId = this.id
    return Comment.query(function (qb) {
      qb.where({
        'post_community.community_id': communityId,
        'comment.active': true
      }).leftJoin('post_community', function () {
        this.on('post_community.post_id', 'comment.post_id')
      })
    })
  },

  createStarterPosts: function (trx) {
    var self = this
    var now = new Date()
    var timeShift = {
      chat: 0,
      intention: 1,
      offer: 2,
      request: 3
    }
    return Community.find('starter-posts', {withRelated: ['posts', 'posts.followers']})
    .tap(c => {
      if (!c) throw new Error('Starter posts community not found')
    })
    .then(c => c.relations.posts.models)
    .then(posts => Promise.map(posts, post => {
      if (post.get('type') === 'welcome') return

      var newPost = post.copy()
      var time = new Date(now - timeShift[newPost.get('type')] * 1000)
      return newPost.save({created_at: time, updated_at: time}, {transacting: trx})
      .then(() => Promise.all(_.flatten([
        self.posts().attach(newPost, {transacting: trx}),
        post.relations.followers.map(u =>
          Follow.create(u.id, newPost.id, {transacting: trx}))
      ])))
    }))
  },

  createDefaultTags: function (userId, trx) {
    var self = this

    return Tag.defaultTags(trx)
    .then(defaultTags => {
      if (!defaultTags.every(i => i)) throw new Error('Default tags missing')
      return Promise.map(defaultTags, tag =>
        new CommunityTag({
          community_id: self.id,
          tag_id: tag.id,
          user_id: userId})
        .save({}, {transacting: trx}))
    })
  }

}, {
  find: function (id_or_slug, options) {
    if (isNaN(Number(id_or_slug))) {
      return Community.where({slug: id_or_slug}).fetch(options)
    }
    return Community.where({id: id_or_slug}).fetch(options)
  },

  findActive: function (id_or_slug, options) {
    if (isNaN(Number(id_or_slug))) {
      return Community.where({slug: id_or_slug, active: true}).fetch(options)
    }
    return Community.where({id: id_or_slug, active: true}).fetch(options)
  },

  canInvite: function (userId, communityId) {
    return Community.find(communityId).then(function (community) {
      if (community.get('settings').all_can_invite) return true
      return Membership.hasModeratorRole(userId, communityId)
    })
  },

  copyAssets: function (opts) {
    return Community.find(opts.communityId).then(c => Promise.join(
        AssetManagement.copyAsset(c, 'community', 'avatar_url'),
        AssetManagement.copyAsset(c, 'community', 'banner_url')
    ))
  },

  notifyAboutCreate: function (opts) {
    return Community.find(opts.communityId, {withRelated: ['creator']}).then(c => {
      var creator = c.relations.creator
      var recipient = process.env.ASANA_NEW_COMMUNITIES_EMAIL
      Email.sendRawEmail(recipient, {
        subject: c.get('name'),
        body: format(
          '%s
created by %s
%s
%s',
          Frontend.Route.community(c),
          creator.get('name'),
          creator.get('email'),
          Frontend.Route.profile(creator))
      }, {
        sender: {
          name: 'Hylobot',
          address: 'dev+bot@hylo.com'
        }
      })
    })
  },

  inNetworkWithUser: function (communityId, userId) {
    return Community.find(communityId)
    .then(community => community && community.get('network_id'))
    .then(networkId => networkId && Network.containsUser(networkId, userId))
  },

  sendSlackNotification: function (communityId, post) {
    return Community.find(communityId)
    .then(community => {
      if (!community || !community.get('slack_hook_url')) return
      var slackMessage = Slack.textForNewPost(post, community)
      return Slack.send(slackMessage, community.get('slack_hook_url'))
    })
  }
})
<commit_msg>add Tag.updateForPost line that breaks the method<commit_after>var Slack = require('../services/Slack')

module.exports = bookshelf.Model.extend({
  tableName: 'community',

  creator: function () {
    return this.belongsTo(User, 'created_by_id')
  },

  inactiveUsers: function () {
    return this.belongsToMany(User, 'users_community', 'community_id', 'user_id')
      .query({where: {'users_community.active': false}})
  },

  invitations: function () {
    return this.hasMany(Invitation)
  },

  leader: function () {
    return this.belongsTo(User, 'leader_id')
  },

  tagFollows: function () {
    return this.hasMany(TagFollow)
  },

  memberships: function () {
    return this.hasMany(Membership).query({where: {'users_community.active': true}})
  },

  moderators: function () {
    return this.belongsToMany(User, 'users_community', 'community_id', 'user_id')
      .query({where: {role: Membership.MODERATOR_ROLE}})
  },

  network: function () {
    return this.belongsTo(Network)
  },

  users: function () {
    return this.belongsToMany(User).through(Membership)
      .query({where: {'users_community.active': true, 'users.active': true}}).withPivot('role')
  },

  posts: function () {
    return this.belongsToMany(Post).through(PostMembership)
      .query({where: {'post.active': true}})
  },

  tags: function () {
    return this.belongsToMany(Tag).through(CommunityTag).withPivot('user_id')
  },

  comments: function () {
    // FIXME get this to use the model relation API
    // instead of the Collection API so that the use
    // of fetch vs. fetchAll isn't confusing.
    // as it is now, it uses "fetchAll" when all the
    // other relations use "fetch"
    var communityId = this.id
    return Comment.query(function (qb) {
      qb.where({
        'post_community.community_id': communityId,
        'comment.active': true
      }).leftJoin('post_community', function () {
        this.on('post_community.post_id', 'comment.post_id')
      })
    })
  },

  createStarterPosts: function (trx) {
    var self = this
    var now = new Date()
    var timeShift = {
      chat: 0,
      intention: 1,
      offer: 2,
      request: 3
    }
    return Community.find('starter-posts', {withRelated: ['posts', 'posts.followers']})
    .tap(c => {
      if (!c) throw new Error('Starter posts community not found')
    })
    .then(c => c.relations.posts.models)
    .then(posts => Promise.map(posts, post => {
      if (post.get('type') === 'welcome') return

      var newPost = post.copy()
      var time = new Date(now - timeShift[newPost.get('type')] * 1000)
      return newPost.save({created_at: time, updated_at: time}, {transacting: trx})
      .then(() => Promise.all(_.flatten([
        self.posts().attach(newPost, {transacting: trx}),
        Tag.updateForPost(newPost, newPost.get('type'), trx),
        post.relations.followers.map(u =>
          Follow.create(u.id, newPost.id, {transacting: trx}))
      ])))
    }))
  },

  createDefaultTags: function (userId, trx) {
    var self = this

    return Tag.defaultTags(trx)
    .then(defaultTags => {
      if (!defaultTags.every(i => i)) throw new Error('Default tags missing')
      return Promise.map(defaultTags, tag =>
        new CommunityTag({
          community_id: self.id,
          tag_id: tag.id,
          user_id: userId})
        .save({}, {transacting: trx}))
    })
  }

}, {
  find: function (id_or_slug, options) {
    if (isNaN(Number(id_or_slug))) {
      return Community.where({slug: id_or_slug}).fetch(options)
    }
    return Community.where({id: id_or_slug}).fetch(options)
  },

  findActive: function (id_or_slug, options) {
    if (isNaN(Number(id_or_slug))) {
      return Community.where({slug: id_or_slug, active: true}).fetch(options)
    }
    return Community.where({id: id_or_slug, active: true}).fetch(options)
  },

  canInvite: function (userId, communityId) {
    return Community.find(communityId).then(function (community) {
      if (community.get('settings').all_can_invite) return true
      return Membership.hasModeratorRole(userId, communityId)
    })
  },

  copyAssets: function (opts) {
    return Community.find(opts.communityId).then(c => Promise.join(
        AssetManagement.copyAsset(c, 'community', 'avatar_url'),
        AssetManagement.copyAsset(c, 'community', 'banner_url')
    ))
  },

  notifyAboutCreate: function (opts) {
    return Community.find(opts.communityId, {withRelated: ['creator']}).then(c => {
      var creator = c.relations.creator
      var recipient = process.env.ASANA_NEW_COMMUNITIES_EMAIL
      Email.sendRawEmail(recipient, {
        subject: c.get('name'),
        body: format(
          '%s
created by %s
%s
%s',
          Frontend.Route.community(c),
          creator.get('name'),
          creator.get('email'),
          Frontend.Route.profile(creator))
      }, {
        sender: {
          name: 'Hylobot',
          address: 'dev+bot@hylo.com'
        }
      })
    })
  },

  inNetworkWithUser: function (communityId, userId) {
    return Community.find(communityId)
    .then(community => community && community.get('network_id'))
    .then(networkId => networkId && Network.containsUser(networkId, userId))
  },

  sendSlackNotification: function (communityId, post) {
    return Community.find(communityId)
    .then(community => {
      if (!community || !community.get('slack_hook_url')) return
      var slackMessage = Slack.textForNewPost(post, community)
      return Slack.send(slackMessage, community.get('slack_hook_url'))
    })
  }
})
<|endoftext|>


<commit_before>// @flow
import { DOM as dom } from "react";
import isString from "lodash/isString";
import get from "lodash/get";

import { getPauseReason } from "../../../utils/pause";
import type { Pause } from "debugger-html";

import "./WhyPaused.css";

function renderExceptionSummary(exception) {
  if (isString(exception)) {
    return exception;
  }

  const message = get(exception, "preview.message");
  const name = get(exception, "preview.name");

  return `${name}: ${message}`;
}

function renderMessage(pauseInfo: Pause) {
  if (!pauseInfo) {
    return null;
  }

  const message = get(pauseInfo, "why.message");
  if (message) {
    return dom.div({ className: "message" }, message);
  }

  const exception = get(pauseInfo, "why.exception");
  if (exception) {
    return dom.div(
      { className: "message warning" },
      renderExceptionSummary(exception)
    );
  }

  return null;
}

export default function renderWhyPaused({ pause }: { pause: Pause }) {
  const reason = getPauseReason(pause);

  if (!reason) {
    return null;
  }

  return dom.div(
    { className: "pane why-paused" },
    dom.div(null, L10N.getStr(reason)),
    renderMessage(pause)
  );
}
<commit_msg>#3506 WhyPaused to JSX (#3579)<commit_after>// @flow
import React from "react";
import isString from "lodash/isString";
import get from "lodash/get";

import { getPauseReason } from "../../../utils/pause";
import type { Pause } from "debugger-html";

import "./WhyPaused.css";

function renderExceptionSummary(exception) {
  if (isString(exception)) {
    return exception;
  }

  const message = get(exception, "preview.message");
  const name = get(exception, "preview.name");

  return `${name}: ${message}`;
}

function renderMessage(pauseInfo: Pause) {
  if (!pauseInfo) {
    return null;
  }

  const message = get(pauseInfo, "why.message");
  if (message) {
    return (

        {message}

    );
  }

  const exception = get(pauseInfo, "why.exception");
  if (exception) {
    return (

        {renderExceptionSummary(exception)}

    );
  }

  return null;
}
renderMessage.displayName = "whyMessage";

export default function renderWhyPaused({ pause }: { pause: Pause }) {
  const reason = getPauseReason(pause);

  if (!reason) {
    return null;
  }

  return (

        {L10N.getStr(reason)}

      {renderMessage(pause)}

  );
}
renderWhyPaused.displayName = "whyPaused";
<|endoftext|>


<commit_before>import { Observable } from 'rx';
import { curry, converge, prop, path, pipe, defaultTo } from 'ramda';
import { watch, readToStr } from '../../util/FileUtil';
import { DEFAULT_CONFIG } from '../../CONST';
import {
  getJsGlobPattern,
  getCssGlobPattern,
  getHtmlGlobPattern,
  getJsRender,
  getCssRender,
  getHtmlRender,
  getPostProcessorForCss
} from '../../util/AssetUtil';

const getLocalsFromPlayground = converge(
  (title, cssBase, stylesheets, scripts) => ({title, cssBase, stylesheets, scripts}),
  [
    pipe(prop('title'), defaultTo(DEFAULT_CONFIG.title)),
    pipe(path(['css', 'base']), defaultTo(null)),
    pipe(path(['css', 'external']), defaultTo(null)),
    pipe(path(['js', 'external']), defaultTo(null))
  ]
);

export const setLocals = curry(function (serveAssets, config) {
  pipe(getLocalsFromPlayground, serveAssets.setLocals)(config);
});

function processHtmlFile({targetDir}, serveAssets, config) {
  return watch(getHtmlGlobPattern(targetDir, config))
    .debounce(100)
    .flatMap(readToStr)
    .flatMap(getHtmlRender(config))
    .startWith('

')
    .retry()
    .doOnNext(serveAssets.updateAsset('html'));
}

function processJsFile({targetDir}, serveAssets, config) {
  return watch(getJsGlobPattern(targetDir, config))
    .debounce(100)
    .flatMap(readToStr)
    .flatMap(getJsRender(config))
    .startWith("try {\n  document.getElementById('playground').innerHTML = 'hello, playground!';\n} catch (err) {}")
    .retry()
    .doOnNext(serveAssets.updateAsset('js'));
}

function processCssFile({targetDir}, serveAssets, config) {
  return watch(getCssGlobPattern(targetDir, config))
    .debounce(100)
    .flatMap(readToStr)
    .flatMap(getCssRender(config))
    .flatMap(getPostProcessorForCss(config))
    .startWith('#playground {\n  color: rebeccapurple;\n}')
    .retry()
    .doOnNext(serveAssets.updateAsset('css'));
}

export const processAssetFiles = curry(function (opts, serveAssets, config) {
  return Observable.combineLatest(
    processJsFile(opts, serveAssets, config),
    processCssFile(opts, serveAssets, config),
    processHtmlFile(opts, serveAssets, config)
  );
});
<commit_msg>Improve retry<commit_after>import { Observable } from 'rx';
import { curry, converge, prop, path, pipe, defaultTo } from 'ramda';
import { watch, readToStr } from '../../util/FileUtil';
import { DEFAULT_CONFIG } from '../../CONST';
import {
  getJsGlobPattern,
  getCssGlobPattern,
  getHtmlGlobPattern,
  getJsRender,
  getCssRender,
  getHtmlRender,
  getPostProcessorForCss
} from '../../util/AssetUtil';

const getLocalsFromPlayground = converge(
  (title, cssBase, stylesheets, scripts) => ({title, cssBase, stylesheets, scripts}),
  [
    pipe(prop('title'), defaultTo(DEFAULT_CONFIG.title)),
    pipe(path(['css', 'base']), defaultTo(null)),
    pipe(path(['css', 'external']), defaultTo(null)),
    pipe(path(['js', 'external']), defaultTo(null))
  ]
);

export const setLocals = curry(function (serveAssets, config) {
  pipe(getLocalsFromPlayground, serveAssets.setLocals)(config);
});

function processHtmlFile({targetDir}, serveAssets, config) {
  return watch(getHtmlGlobPattern(targetDir, config))
    .debounce(100)
    .flatMap(readToStr)
    .retry()
    .flatMap(getHtmlRender(config))
    .startWith('

')
    .doOnNext(serveAssets.updateAsset('html'));
}

function processJsFile({targetDir}, serveAssets, config) {
  return watch(getJsGlobPattern(targetDir, config))
    .debounce(100)
    .flatMap(readToStr)
    .retry()
    .flatMap(getJsRender(config))
    .startWith("try {\n  document.getElementById('playground').innerHTML = 'hello, playground!';\n} catch (err) {}")
    .doOnNext(serveAssets.updateAsset('js'));
}

function processCssFile({targetDir}, serveAssets, config) {
  return watch(getCssGlobPattern(targetDir, config))
    .debounce(100)
    .flatMap(readToStr)
    .retry()
    .flatMap(getCssRender(config))
    .flatMap(getPostProcessorForCss(config))
    .startWith('#playground {\n  color: rebeccapurple;\n}')
    .doOnNext(serveAssets.updateAsset('css'));
}

export const processAssetFiles = curry(function (opts, serveAssets, config) {
  return Observable.combineLatest(
    processJsFile(opts, serveAssets, config),
    processCssFile(opts, serveAssets, config),
    processHtmlFile(opts, serveAssets, config)
  );
});
<|endoftext|>


<commit_before>/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

export default () => {
  const mobileBtn = document.querySelector(".-js-vertical-tab-mobile-heading");
  const styleProps = getComputedStyle(mobileBtn, null);
  const inMobileState = (styleProps.getPropertyValue("display") === "block");
  const btnClassName = inMobileState ? ".-js-vertical-tab-mobile-heading" : ".-js-vertical-tab";
  const activeClass = "vertical-tabs__tab--is-active";
  const getBtnByHref = (id) => document.querySelector(`${btnClassName}[href="#${id}"]`);
  const toggleTab = (clickedBtn, event) => {
    if (event) {
      event.preventDefault();
      history.pushState(null, "", clickedBtn.getAttribute("href"));
    }
    let id = clickedBtn.getAttribute("href").replace("#", "");
    // toggle display setting for the content related to the button
    for (var elem of document.querySelectorAll(".-js-vertical-tab-content")) {
      var btn = getBtnByHref(elem.id);
      if (elem.id === id) {
        elem.style.display = "block";
        btn.classList.add(activeClass);
      } else {
        elem.style.display = "none";
        btn.classList.remove(activeClass);
      }
    }
  };

  for (var btn of document.querySelectorAll(btnClassName)) {
    btn.addEventListener("click", toggleTab.bind(null, btn), false);
  }

  var initialContentId = location.hash ? location.hash.replace("#", "") : "description";
  var initialBtn = getBtnByHref(initialContentId);
  toggleTab(initialBtn);

  // I'm not sure if this is needed?
  window.addEventListener("hashchange", () => {
    var btn = getBtnByHref(location.hash.replace("#", ""));
    toggleTab(btn);
  }, false);

};
<commit_msg>Fix error when mobileBtn doesn't exist (#2798)<commit_after>/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

export default () => {
  const mobileBtn = document.querySelector(".-js-vertical-tab-mobile-heading");
  let inMobileState = false;
  if (mobileBtn) {
    const styleProps = getComputedStyle(mobileBtn, null);
    inMobileState = (styleProps.getPropertyValue("display") === "block");
  }
  const btnClassName = inMobileState ? ".-js-vertical-tab-mobile-heading" : ".-js-vertical-tab";
  const activeClass = "vertical-tabs__tab--is-active";
  const getBtnByHref = (id) => document.querySelector(`${btnClassName}[href="#${id}"]`);
  const toggleTab = (clickedBtn, event) => {
    if (event) {
      event.preventDefault();
      history.pushState(null, "", clickedBtn.getAttribute("href"));
    }
    let id = clickedBtn.getAttribute("href").replace("#", "");
    // toggle display setting for the content related to the button
    for (var elem of document.querySelectorAll(".-js-vertical-tab-content")) {
      var btn = getBtnByHref(elem.id);
      if (elem.id === id) {
        elem.style.display = "block";
        btn.classList.add(activeClass);
      } else {
        elem.style.display = "none";
        btn.classList.remove(activeClass);
      }
    }
  };

  for (var btn of document.querySelectorAll(btnClassName)) {
    btn.addEventListener("click", toggleTab.bind(null, btn), false);
  }

  var initialContentId = location.hash ? location.hash.replace("#", "") : "description";
  var initialBtn = getBtnByHref(initialContentId);
  toggleTab(initialBtn);

  // I'm not sure if this is needed?
  window.addEventListener("hashchange", () => {
    var btn = getBtnByHref(location.hash.replace("#", ""));
    toggleTab(btn);
  }, false);

};
<|endoftext|>


<commit_before>// Utility functions used across DocuSign NPM package

var fs = require('fs'); // core
var util = require('util');
var Bluebird = require('bluebird');
var request = require('request');
var temp = require('temp');
var stream = require('stream');
var uuid = require('uuid');
var assign = require('lodash.assign');
var isPlainObject = require('lodash.isplainobject');

exports.DocuSignError = DocuSignError;
function DocuSignError (message, errorDetails) {
  errorDetails = errorDetails || {};
  /* istanbul ignore if */
  if (message instanceof DocuSignError) {
    return message;
  }
  this.message = message;
  this.name = 'DocuSignError';
  assign(this, errorDetails);
  Error.captureStackTrace(this, DocuSignError);
}
DocuSignError.prototype = Object.create(Error.prototype);
DocuSignError.prototype.constrcutor = DocuSignError;

/**
 * General logging function for debugging use
 *
 * @memberOf Utils
 * @private
 * @function
 */
exports.log = debugLog;
function debugLog () {
  var isDebugLogEnabled = process.env.dsDebug === 'true' || /docusign/ig.test(process.env.DEBUG);
  if (isDebugLogEnabled) {
    var timestamp = '[' + new Date().toISOString() + ']';
    console.log.apply(console, [timestamp].concat(arguments));
  }
}

/**
 * Creates guids for use with when creating new users
 *
 * @memberOf Utils
 * @private
 * @function
 * @returns {string}
 */
exports.generateNewGuid = uuid;

/**
 * Provides an environment specific URL for the highest level API calls
 *
 * @memberOf Utils
 * @private
 * @function
 * @returns {string}
 */
exports.getApiUrl = function () {
  var env = process.env.targetEnv;
  return 'https://' + env + '.docusign.net/restapi/v2';
};

/**
 * Formats and return an authorization header with the given oAuth token
 *
 * @memberOf Utils
 * @private
 * @function
 * @param token
 * @returns {{Authorization: string}}
 */
exports.getHeaders = function (token) {
  return {
    Authorization: 'bearer ' + token
  };
};

/**
 * Helper function for making web requests to DocuSign
 *
 * @memberOf Utils
 * @private
 * @function
 * @param apiName - name of the API to be requested
 * @param options - options for the request
 * @param callback
 * @returns {Promise} - A thenable bluebird Promise; If callback is given it is called before the promise is resolved
 */
exports.makeRequest = function (apiName, options, callback) {
  var makeRequestAsync = new Bluebird(function (resolve, reject) {
    var data;
    if ('json' in options) {
      data = JSON.stringify(options.json);
    } else {
      data = '';
    }

    exports.log(util.format('DS API %s Request:\n  %s %s\t  %s\nHeaders: %s', apiName, options.method, options.url, data, util.inspect(options.headers, {depth: null})));

    request(options, function (error, response, body) {
      if (error) {
        return reject(error);
      }

      var json, err, errMsg;
      try {
        json = JSON.parse(body);
      } catch (_) {
        if (isPlainObject(body)) {
          json = body;
        } else {
          json = null;
        }
      }

      if (json === null) { // successful request; no json in response body
        resolve(body);
      } else if ('errorCode' in json) {
        errMsg = util.format('DS API %s (Error Code: %s) Error:\n  %s', apiName, json.errorCode, json.message);
        err = new DocuSignError(errMsg);
        reject(err);
      } else if ('error' in json) {
        errMsg = util.format('DS API %s Error:\n  %s \n\nDescription: %s', apiName, json.error, json.error_description);
        err = new DocuSignError(errMsg);
        reject(err);
      } else { // no error
        exports.log(util.format('DS API %s Response:\n  %s', apiName, JSON.stringify(json)));
        resolve(json);
      }
    });
  });
  return makeRequestAsync.asCallback(callback).catch(DocuSignError, function (error) {
    exports.log(error.message);
    throw error;
  });
};

/**
 *
 *  This function constructs and sends a multipart request.
 *
 * `mpUrl` is a string containing the URL where the multipart request
 * will be made to.
 *
 * `mpHeaders` is an object that contains HTTP headers for the whole
 * request. These will be combined with the appropriate Content-Type (CT)
 * header, so providing the CT header is not required.
 *
 * `parts` is a list of objects of structure { headers, body }
 * -> where `headers` is an object of HTTP headers and values.
 * -> where `body` is a string or Node.js stream object.
 *
 * Returns into `callback` with the expected `request` parameters of
 * structure { error, request, body }.
 *
 *
 * @memberOf Utils
 * @private
 * @function
 * @param mpUrl
 * @param mpHeaders
 * @param parts
 * @param callback
 */

exports.sendMultipart = function (mpUrl, mpHeaders, parts, callback) {
  var crlf = '\r\n';

  var tempPath = temp.path('docusign');
  var multipart = fs.createWriteStream(tempPath);

  var boundary = exports.generateNewGuid();
  mpHeaders['Content-Type'] = 'multipart/form-data; boundary=' + boundary;

  exports.log('mpHeaders', mpHeaders);

  var buildMultipartBody = parts.reduce(function (lastPromise, part) {
    return lastPromise.then(function () {
      return new Bluebird(function (resolve, reject) {
        var headers = Object.keys(part.headers).map(function (key) {
          return key + ': ' + part.headers[key];
        }).join(crlf);
        exports.log('part.headers', part.headers);

        multipart.write('--' + boundary + crlf);
        multipart.write(headers);
        multipart.write(crlf + crlf);

        var body = (Buffer.isBuffer(part.body) || typeof part.body === 'string')
          ? _createStringStream(part.body) : part.body;

        body.on('data', function (chunk) {
          multipart.write(chunk);
        });
        body.on('end', function () {
          multipart.write(crlf);
          resolve();
        });
        body.resume();
      });
    });
  }, Bluebird.resolve());

  return new Bluebird(function (resolve, reject) {
    buildMultipartBody.then(function () { // called when all is done
      multipart.write('--' + boundary + '--');
      var endAsync = Bluebird.promisify(multipart.end, multipart);

      return endAsync().then(function () {
        fs.createReadStream(tempPath).pipe(request({
          method: 'POST',
          url: mpUrl,
          headers: mpHeaders
        }, function (error, response, body) {
          try {
            fs.unlinkSync(tempPath);
          } catch (e) {
            exports.log('Failed to fs.unlink', e);
          }
          if (error) {
            return reject(error);
          }
          exports.log('sendMultipart response body', body);
          resolve([response, body]);
        }));
      })
      .catch(function (err) {
        exports.log('sendMultipart error', err);
        reject(err);
      });
    });
  }).asCallback(callback, { spread: true });
};

function _createStringStream (str) {
  var s = new stream.Readable();
  s.pause();
  s.push(str);
  s.push(null);
  return s;
}
<commit_msg>use util.inspect instead of stringify for cleaner output<commit_after>// Utility functions used across DocuSign NPM package

var fs = require('fs'); // core
var util = require('util');
var Bluebird = require('bluebird');
var request = require('request');
var temp = require('temp');
var stream = require('stream');
var uuid = require('uuid');
var assign = require('lodash.assign');
var isPlainObject = require('lodash.isplainobject');

exports.DocuSignError = DocuSignError;
function DocuSignError (message, errorDetails) {
  errorDetails = errorDetails || {};
  /* istanbul ignore if */
  if (message instanceof DocuSignError) {
    return message;
  }
  this.message = message;
  this.name = 'DocuSignError';
  assign(this, errorDetails);
  Error.captureStackTrace(this, DocuSignError);
}
DocuSignError.prototype = Object.create(Error.prototype);
DocuSignError.prototype.constrcutor = DocuSignError;

/**
 * General logging function for debugging use
 *
 * @memberOf Utils
 * @private
 * @function
 */
exports.log = debugLog;
function debugLog () {
  var isDebugLogEnabled = process.env.dsDebug === 'true' || /docusign/ig.test(process.env.DEBUG);
  if (isDebugLogEnabled) {
    var timestamp = '[' + new Date().toISOString() + ']';
    console.log.apply(console, [timestamp].concat(arguments));
  }
}

/**
 * Creates guids for use with when creating new users
 *
 * @memberOf Utils
 * @private
 * @function
 * @returns {string}
 */
exports.generateNewGuid = uuid;

/**
 * Provides an environment specific URL for the highest level API calls
 *
 * @memberOf Utils
 * @private
 * @function
 * @returns {string}
 */
exports.getApiUrl = function () {
  var env = process.env.targetEnv;
  return 'https://' + env + '.docusign.net/restapi/v2';
};

/**
 * Formats and return an authorization header with the given oAuth token
 *
 * @memberOf Utils
 * @private
 * @function
 * @param token
 * @returns {{Authorization: string}}
 */
exports.getHeaders = function (token) {
  return {
    Authorization: 'bearer ' + token
  };
};

/**
 * Helper function for making web requests to DocuSign
 *
 * @memberOf Utils
 * @private
 * @function
 * @param apiName - name of the API to be requested
 * @param options - options for the request
 * @param callback
 * @returns {Promise} - A thenable bluebird Promise; If callback is given it is called before the promise is resolved
 */
exports.makeRequest = function (apiName, options, callback) {
  var makeRequestAsync = new Bluebird(function (resolve, reject) {
    var data;
    if ('json' in options) {
      data = options.json;
    } else {
      data = '';
    }

    exports.log(util.format('DS API %s Request:\n  %s %s\t  %s\nHeaders: %s', apiName, options.method, options.url, util.inspect(data, {depth: null}), util.inspect(options.headers, {depth: null})));

    request(options, function (error, response, body) {
      if (error) {
        return reject(error);
      }

      var json, err, errMsg;
      try {
        json = JSON.parse(body);
      } catch (_) {
        if (isPlainObject(body)) {
          json = body;
        } else {
          json = null;
        }
      }

      if (json === null) { // successful request; no json in response body
        resolve(body);
      } else if ('errorCode' in json) {
        errMsg = util.format('DS API %s (Error Code: %s) Error:\n  %s', apiName, json.errorCode, json.message);
        err = new DocuSignError(errMsg);
        reject(err);
      } else if ('error' in json) {
        errMsg = util.format('DS API %s Error:\n  %s \n\nDescription: %s', apiName, json.error, json.error_description);
        err = new DocuSignError(errMsg);
        reject(err);
      } else { // no error
        exports.log(util.format('DS API %s Response:\n  %s', apiName, JSON.stringify(json)));
        resolve(json);
      }
    });
  });
  return makeRequestAsync.asCallback(callback).catch(DocuSignError, function (error) {
    exports.log(error.message);
    throw error;
  });
};

/**
 *
 *  This function constructs and sends a multipart request.
 *
 * `mpUrl` is a string containing the URL where the multipart request
 * will be made to.
 *
 * `mpHeaders` is an object that contains HTTP headers for the whole
 * request. These will be combined with the appropriate Content-Type (CT)
 * header, so providing the CT header is not required.
 *
 * `parts` is a list of objects of structure { headers, body }
 * -> where `headers` is an object of HTTP headers and values.
 * -> where `body` is a string or Node.js stream object.
 *
 * Returns into `callback` with the expected `request` parameters of
 * structure { error, request, body }.
 *
 *
 * @memberOf Utils
 * @private
 * @function
 * @param mpUrl
 * @param mpHeaders
 * @param parts
 * @param callback
 */

exports.sendMultipart = function (mpUrl, mpHeaders, parts, callback) {
  var crlf = '\r\n';

  var tempPath = temp.path('docusign');
  var multipart = fs.createWriteStream(tempPath);

  var boundary = exports.generateNewGuid();
  mpHeaders['Content-Type'] = 'multipart/form-data; boundary=' + boundary;

  exports.log('mpHeaders', mpHeaders);

  var buildMultipartBody = parts.reduce(function (lastPromise, part) {
    return lastPromise.then(function () {
      return new Bluebird(function (resolve, reject) {
        var headers = Object.keys(part.headers).map(function (key) {
          return key + ': ' + part.headers[key];
        }).join(crlf);
        exports.log('part.headers', part.headers);

        multipart.write('--' + boundary + crlf);
        multipart.write(headers);
        multipart.write(crlf + crlf);

        var body = (Buffer.isBuffer(part.body) || typeof part.body === 'string')
          ? _createStringStream(part.body) : part.body;

        body.on('data', function (chunk) {
          multipart.write(chunk);
        });
        body.on('end', function () {
          multipart.write(crlf);
          resolve();
        });
        body.resume();
      });
    });
  }, Bluebird.resolve());

  return new Bluebird(function (resolve, reject) {
    buildMultipartBody.then(function () { // called when all is done
      multipart.write('--' + boundary + '--');
      var endAsync = Bluebird.promisify(multipart.end, multipart);

      return endAsync().then(function () {
        fs.createReadStream(tempPath).pipe(request({
          method: 'POST',
          url: mpUrl,
          headers: mpHeaders
        }, function (error, response, body) {
          try {
            fs.unlinkSync(tempPath);
          } catch (e) {
            exports.log('Failed to fs.unlink', e);
          }
          if (error) {
            return reject(error);
          }
          exports.log('sendMultipart response body', body);
          resolve([response, body]);
        }));
      })
      .catch(function (err) {
        exports.log('sendMultipart error', err);
        reject(err);
      });
    });
  }).asCallback(callback, { spread: true });
};

function _createStringStream (str) {
  var s = new stream.Readable();
  s.pause();
  s.push(str);
  s.push(null);
  return s;
}
<|endoftext|>


<commit_before>var elFinder = {};

define([
    "require",
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/_base/config",
    "dojo/window",
    "dijit/registry",
    "../_include/_PageMixin",
    "jquery/jquery.min",
    "jquery-ui/jquery-ui.min",
    "../../config/elfinder_config",
    "elfinder/js/elfinder.full",
    "elfinder/js/i18n/elfinder.de",
    "dijit/layout/TabContainer",
    "dijit/layout/ContentPane",
    "../../AuthToken",
    "../../locale/Dictionary",
    "dojo/text!./template/BrowsePage.html",
    "dojo/domReady!"
], function (
    require,
    declare,
    lang,
    config,
    win,
    registry,
    _Page,
    jQuery,
    jQueryUi,
    elFinderConfig,
    elFinder,
    i18n_elfinderDe,
    TabContainer,
    ContentPane,
    AuthToken,
    Dict,
    template
) {
    return declare([_Page], {

        templateString: lang.replace(template, Dict.tplTranslate),
        contextRequire: require,
        title: Dict.translate('Media'),

        elfinderInstance: null,

        constructor: function(params) {
            declare.safeMixin(this, params);
            // get package locations
            var packageLocations = {};
            for(var i=0, count=config.packages.length; i<count; i++) {
                var curPackage = config.packages[i];
                packageLocations[curPackage.name] = curPackage.location;
            }
            // add elfinder css
            this.setCss(packageLocations['jquery-ui']+'/themes/smoothness/jquery-ui.min.css', 'all');
            this.setCss(packageLocations['elfinder']+'/css/elfinder.min.css', 'all');
            this.setCss(packageLocations['elfinder']+'/css/theme.css', 'all');
        },

        postCreate: function() {
            this.inherited(arguments);

            // tab navigation
            registry.byId("tabContainer").watch("selectedChildWidget", lang.hitch(this, function(name, oval, nval){
                if (nval.id === "contentTab") {
                    window.location.assign(config.app.pathPrefix+'link?'+this.request.getQueryString());
                }
            }));

            var directory = this.request.getQueryParam("directory");
            var customHeaders = {};
            customHeaders[AuthToken.name] = AuthToken.get();
            lang.mixin(elfinderConfig, {
                lang: config.app.uiLanguage,
                url: config.app.backendUrl+'media/files?directory='+directory,
                rememberLastDir: true,
                resizable: false,
                width: '100%',
                height: win.getBox().h - 40,
                getFileCallback: lang.hitch(this, function(file) {
                    this.onItemClick(file);
                }),
                customHeaders: customHeaders
            });

            setTimeout(function() {
                this.elfinderInstance = $("#elfinder").elfinder(elfinderConfig).elfinder('instance');
            }, 500);
        },

        onItemClick: function(item) {
            var funcNum = this.request.getQueryParam('CKEditorFuncNum');
            var cleanupFuncNum = this.request.getQueryParam('CKEditorCleanUpFuncNum');
            var callback = this.request.getQueryParam('callback');
            var isWindow = window.opener;

            var value = this.getItemUrl(item);
            var ckeditor = isWindow ? window.opener.CKEDITOR : parent.CKEDITOR;
            if (ckeditor && funcNum) {
                ckeditor.tools.callFunction(funcNum, value, function() {
                    // callback executed in the scope of the button that called the file browser
                    // see: http://docs.ckeditor.com/#!/guide/dev_file_browser_api Example 4
                });
                if (!isWindow && cleanupFuncNum) {
                    ckeditor.tools.callFunction(cleanupFuncNum);
                }
            }
            else if (callback) {
                var cb = isWindow ? window.opener[callback] : parent[callback];
                if (typeof cb === 'function') {
                    cb(value);
                }
            }
            if (isWindow) {
                window.close();
            }
        },

        getItemUrl: function(item) {
            item = decodeURIComponent(item.url);
            return config.app.mediaSavePath+item.replace(config.app.mediaBaseUrl, '');
        }
    });
});<commit_msg>Improved directory selection in elfinder calls<commit_after>var elFinder = {};

define([
    "require",
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/_base/config",
    "dojo/window",
    "dijit/registry",
    "../_include/_PageMixin",
    "jquery/jquery.min",
    "jquery-ui/jquery-ui.min",
    "../../config/elfinder_config",
    "elfinder/js/elfinder.full",
    "elfinder/js/i18n/elfinder.de",
    "dijit/layout/TabContainer",
    "dijit/layout/ContentPane",
    "../../AuthToken",
    "../../locale/Dictionary",
    "dojo/text!./template/BrowsePage.html",
    "dojo/domReady!"
], function (
    require,
    declare,
    lang,
    config,
    win,
    registry,
    _Page,
    jQuery,
    jQueryUi,
    elFinderConfig,
    elFinder,
    i18n_elfinderDe,
    TabContainer,
    ContentPane,
    AuthToken,
    Dict,
    template
) {
    return declare([_Page], {

        templateString: lang.replace(template, Dict.tplTranslate),
        contextRequire: require,
        title: Dict.translate('Media'),

        elfinderInstance: null,

        constructor: function(params) {
            declare.safeMixin(this, params);
            // get package locations
            var packageLocations = {};
            for(var i=0, count=config.packages.length; i<count; i++) {
                var curPackage = config.packages[i];
                packageLocations[curPackage.name] = curPackage.location;
            }
            // add elfinder css
            this.setCss(packageLocations['jquery-ui']+'/themes/smoothness/jquery-ui.min.css', 'all');
            this.setCss(packageLocations['elfinder']+'/css/elfinder.min.css', 'all');
            this.setCss(packageLocations['elfinder']+'/css/theme.css', 'all');
        },

        postCreate: function() {
            this.inherited(arguments);

            // tab navigation
            registry.byId("tabContainer").watch("selectedChildWidget", lang.hitch(this, function(name, oval, nval){
                if (nval.id === "contentTab") {
                    window.location.assign(config.app.pathPrefix+'link?'+this.request.getQueryString());
                }
            }));

            var directory = this.request.getQueryParam("directory");
            var customHeaders = {};
            customHeaders[AuthToken.name] = AuthToken.get();
            lang.mixin(elfinderConfig, {
                lang: config.app.uiLanguage,
                url: config.app.backendUrl+'media/files'+(directory ? '?directory='+directory : ''),
                rememberLastDir: !directory,
                resizable: false,
                width: '100%',
                height: win.getBox().h - 40,
                getFileCallback: lang.hitch(this, function(file) {
                    this.onItemClick(file);
                }),
                customHeaders: customHeaders
            });

            setTimeout(function() {
                this.elfinderInstance = $("#elfinder").elfinder(elfinderConfig).elfinder('instance');
            }, 500);
        },

        onItemClick: function(item) {
            var funcNum = this.request.getQueryParam('CKEditorFuncNum');
            var cleanupFuncNum = this.request.getQueryParam('CKEditorCleanUpFuncNum');
            var callback = this.request.getQueryParam('callback');
            var isWindow = window.opener;

            var value = this.getItemUrl(item);
            var ckeditor = isWindow ? window.opener.CKEDITOR : parent.CKEDITOR;
            if (ckeditor && funcNum) {
                ckeditor.tools.callFunction(funcNum, value, function() {
                    // callback executed in the scope of the button that called the file browser
                    // see: http://docs.ckeditor.com/#!/guide/dev_file_browser_api Example 4
                });
                if (!isWindow && cleanupFuncNum) {
                    ckeditor.tools.callFunction(cleanupFuncNum);
                }
            }
            else if (callback) {
                var cb = isWindow ? window.opener[callback] : parent[callback];
                if (typeof cb === 'function') {
                    cb(value);
                }
            }
            if (isWindow) {
                window.close();
            }
        },

        getItemUrl: function(item) {
            item = decodeURIComponent(item.url);
            return config.app.mediaSavePath+item.replace(config.app.mediaBaseUrl, '');
        }
    });
});<|endoftext|>


<commit_before>import {bindable, inject, customElement, LogManager} from 'aurelia-framework';
import {Catalogues} from '../../services/catalogues';
import {Stamps} from '../../services/stamps';
import {CatalogueNumbers} from '../../services/catalogueNumbers';
import {Preferences} from '../../services/preferences';
import {Condition} from '../../util/common-models';
import {I18N} from 'aurelia-i18next';

import _ from 'lodash';
import bootbox from 'bootbox';

import 'resources/styles/components/catalogue-numbers/cn-references.css!';

const logger = LogManager.getLogger('cn-references');

@customElement('catalogue-number-references')
@bindable('model')
@inject(Element, I18N, Catalogues, CatalogueNumbers, Stamps, Preferences)
export class CatalogueNumberReferences {

    modelCopy;
    updateTemplate;
    editSlot;
    catalogues = [];

    defaultCondition = -1;
    defaultCatalogue = null;

    conditions = Condition.symbols();
    number;

    constructor(element, i18next, catalogueService, catalogueNumberService, stampService, preferenceService) {
        this.element = $(element);
        this.i18next = i18next;
        this.catalogueService = catalogueService;
        this.catalogueNumberService = catalogueNumberService;
        this.stampService = stampService;
        this.preferenceService = preferenceService;
    }

    bind() {
        let self = this;
        return Promise.all([
            self.catalogueService.find(self.catalogueService.getDefaultSearchOptions()).then(results => {
                self.catalogues = results.models;
            }),
            self.preferenceService.find(self.preferenceService.getDefaultSearchOptions()).then(results => {
                let prefs = results.models;
                let cond = self.preferenceService.getByNameAndCategory('condition', 'stamps');
                if( cond ) {
                    self.defaultCondition = +cond.value;
                }
                let cat = self.preferenceService.getByNameAndCategory('catalogueRef', 'stamps');
                if( cat ) {
                    self.defaultCatalogue = +cat.value;
                }
            })
        ]);
    }

    modelChanged(newModel) {
        if (newModel) {
            let self = this;
            this.modelCopy = _.clone(newModel, true);
            this.modelCopy.catalogueNumbers.forEach(catNum => {
                catNum.currencyCode = self.determineCurrencyCode(catNum.catalogueRef);
            });
        }
    }

    determineCurrencyCode(catalogueRef) {
        let code = 'USD';
        let cat = this.catalogueService.getById(catalogueRef);
        if (cat) {
            code = cat.code;
        }
        return code;
    }

    edit(num, index) { //eslint-disable-line no-unused-vars
        num.editing = true;
    }

    cancel(num) {
        let inlineRow = $(this.element.find('.editing-row'));
        if (num.id === 0) {
            inlineRow.remove();
            let index = _.findIndex(this.modelCopy.catalogueNumbers, {id: 0});
            if (index >= 0) {
                this.modelCopy.catalogueNumbers.splice(1, index);
            }
        }
        num.editing = false;
    }

    save(num) { //eslint-disable-line no-unused-vars
        let self = this;
        self.stampService.save(this.modelCopy).then( stamp => {
            self.modelChanged(stamp);
        });
    }

    add() {
        let num = {
            id: 0,
            active: false,
            catalogueRef: this.defaultCatalogue,
            condition: this.defaultCondition,
            number: "",
            value: 0
        };
        num.editing = true;
        this.modelCopy.catalogueNumbers.push(num);
    }

    remove(num) {
        let self = this;
        let _remove = function(m) {
            self.catalogueNumberService.remove(m).then( result => {
                if( result === true ) {
                    let index = _.findIndex(self.modelCopy.catalogueNumbers, { id: m.id });
                    self.modelCopy.catalogueNumbers.splice(index, 1);
                }
            }).catch( err => {
                logger.debug("Error removing", err);
            });
        };
        bootbox.confirm({
            size: 'small',
            message: self.i18next.tr("prompts.delete-catalogue-number", { number: num.number } ),
            callback: function (result) {
                if (result === true) {
                    _remove.call(self, num);

                }
            }
        });

    }

    makeActive(num) {
        let activeNum;
        for( let i = 0; i < this.modelCopy.catalogueNumbers.length; i++ ) {
            let cn = this.modelCopy.catalogueNumbers[i];
            if( cn.active === true ) {
                activeNum = cn;
                break;
            }
        }
        if( activeNum.id === num.id ) {
            throw new Error("Can not set active as active!");
        } else {
            this.catalogueNumberService.makeActive(num.id).then( stamp => { //eslint-disable-line no-unused-vars
                activeNum.active = false;
                num.active = true;
            }).catch( err => {
                logger.error(err);
            });
        }
    }
}
<commit_msg>Small cleanup<commit_after>import {bindable, inject, customElement, LogManager} from 'aurelia-framework';
import {Catalogues} from '../../services/catalogues';
import {Stamps} from '../../services/stamps';
import {CatalogueNumbers} from '../../services/catalogueNumbers';
import {Preferences} from '../../services/preferences';
import {Condition} from '../../util/common-models';
import {I18N} from 'aurelia-i18next';

import _ from 'lodash';
import bootbox from 'bootbox';

import 'resources/styles/components/catalogue-numbers/cn-references.css!';

const logger = LogManager.getLogger('cn-references');

@customElement('catalogue-number-references')
@bindable('model')
@inject(Element, I18N, Catalogues, CatalogueNumbers, Stamps, Preferences)
export class CatalogueNumberReferences {

    modelCopy;
    updateTemplate;
    editSlot;
    catalogues = [];

    defaultCondition = -1;
    defaultCatalogue = null;

    conditions = Condition.symbols();
    number;

    constructor(element, i18next, catalogueService, catalogueNumberService, stampService, preferenceService) {
        this.element = $(element);
        this.i18next = i18next;
        this.catalogueService = catalogueService;
        this.catalogueNumberService = catalogueNumberService;
        this.stampService = stampService;
        this.preferenceService = preferenceService;
    }

    bind() {
        let self = this;
        return Promise.all([
            self.catalogueService.find(self.catalogueService.getDefaultSearchOptions()).then(results => {
                self.catalogues = results.models;
            }),
            self.preferenceService.find(self.preferenceService.getDefaultSearchOptions()).then(results => {
                let cond = self.preferenceService.getByNameAndCategory('condition', 'stamps');
                if( cond ) {
                    self.defaultCondition = +cond.value;
                }
                let cat = self.preferenceService.getByNameAndCategory('catalogueRef', 'stamps');
                if( cat ) {
                    self.defaultCatalogue = +cat.value;
                }
            })
        ]);
    }

    modelChanged(newModel) {
        if (newModel) {
            let self = this;
            this.modelCopy = _.clone(newModel, true);
            this.modelCopy.catalogueNumbers.forEach(catNum => {
                catNum.currencyCode = self.determineCurrencyCode(catNum.catalogueRef);
            });
        }
    }

    determineCurrencyCode(catalogueRef) {
        let code = 'USD';
        let cat = this.catalogueService.getById(catalogueRef);
        if (cat) {
            code = cat.code;
        }
        return code;
    }

    edit(num, index) { //eslint-disable-line no-unused-vars
        num.editing = true;
    }

    cancel(num) {
        let inlineRow = $(this.element.find('.editing-row'));
        if (num.id === 0) {
            inlineRow.remove();
            let index = _.findIndex(this.modelCopy.catalogueNumbers, {id: 0});
            if (index >= 0) {
                this.modelCopy.catalogueNumbers.splice(1, index);
            }
        }
        num.editing = false;
    }

    save(num) { //eslint-disable-line no-unused-vars
        let self = this;
        self.stampService.save(this.modelCopy).then( stamp => {
            self.modelChanged(stamp);
        });
    }

    add() {
        let num = {
            id: 0,
            active: false,
            catalogueRef: this.defaultCatalogue,
            condition: this.defaultCondition,
            number: "",
            value: 0
        };
        num.editing = true;
        this.modelCopy.catalogueNumbers.push(num);
    }

    remove(num) {
        let self = this;
        let _remove = function(m) {
            self.catalogueNumberService.remove(m).then( result => {
                if( result === true ) {
                    let index = _.findIndex(self.modelCopy.catalogueNumbers, { id: m.id });
                    self.modelCopy.catalogueNumbers.splice(index, 1);
                }
            }).catch( err => {
                logger.debug("Error removing", err);
            });
        };
        bootbox.confirm({
            size: 'small',
            message: self.i18next.tr("prompts.delete-catalogue-number", { number: num.number } ),
            callback: function (result) {
                if (result === true) {
                    _remove.call(self, num);

                }
            }
        });

    }

    makeActive(num) {
        let activeNum;
        for( let i = 0; i < this.modelCopy.catalogueNumbers.length; i++ ) {
            let cn = this.modelCopy.catalogueNumbers[i];
            if( cn.active === true ) {
                activeNum = cn;
                break;
            }
        }
        if( activeNum.id === num.id ) {
            throw new Error("Can not set active as active!");
        } else {
            this.catalogueNumberService.makeActive(num.id).then( stamp => { //eslint-disable-line no-unused-vars
                activeNum.active = false;
                num.active = true;
            }).catch( err => {
                logger.error(err);
            });
        }
    }
}
<|endoftext|>


<commit_before>'use strict'

let co = require('co')
let cli = require('heroku-cli-util')
const {flags} = require('cli-engine-heroku')
const {BuildpackCompletion, RegionComletion, RemoteCompletion, SpaceCompletion, StackCompletion} = require('cli-engine-heroku/lib/completions')

function * run (context, heroku) {
  let git = require('../../git')(context)
  let name = context.flags.app || context.args.app || process.env.HEROKU_APP

  function createApp () {
    let params = {
      name,
      organization: context.org || context.team || context.flags.team,
      region: context.flags.region,
      space: context.flags.space,
      stack: context.flags.stack,
      kernel: context.flags.kernel,
      locked: context.flags.locked
    }

    return heroku.request({
      method: 'POST',
      path: (params.space || params.organization) ? '/organizations/apps' : '/apps',
      body: params
    }).then(app => {
      let status = name ? 'done' : `done, ${cli.color.app(app.name)}`
      if (context.flags.region) status += `, region is ${cli.color.yellow(app.region.name)}`
      if (context.flags.stack) status += `, stack is ${cli.color.yellow(app.stack.name)}`
      cli.action.done(status)
      return app
    })
  }

  let addAddons = co.wrap(function * (app, addons) {
    for (let addon of addons) {
      addon = addon.trim()
      let request = heroku.post(`/apps/${app.name}/addons`, {body: {plan: addon}})
      yield cli.action(`Adding ${cli.color.green(addon)}`, request)
    }
  })

  function addBuildpack (app, buildpack) {
    return cli.action(`Setting buildpack to ${cli.color.cyan(buildpack)}`, heroku.request({
      method: 'PUT',
      path: `/apps/${app.name}/buildpack-installations`,
      headers: {Range: ''},
      body: {updates: [{buildpack: buildpack}]}
    }))
  }

  function createText (name, space) {
    let text = `Creating ${name ? cli.color.app(name) : 'app'}`
    if (space) {
      text += ` in space ${space}`
    }
    return text
  }

  let app = yield cli.action(createText(name, context.flags.space), {success: false}, createApp())

  if (context.flags.addons) yield addAddons(app, context.flags.addons.split(','))
  if (context.flags.buildpack) yield addBuildpack(app, context.flags.buildpack)

  let remoteUrl = context.flags['ssh-git'] ? git.sshGitUrl(app.name) : git.gitUrl(app.name)
  if (git.inGitRepo() && !context.flags['no-remote']) yield git.createRemote(context.flags.remote || 'heroku', remoteUrl)
  if (context.flags.json) {
    cli.styledJSON(app)
  } else {
    cli.log(`${cli.color.cyan(app.web_url)} | ${cli.color.green(remoteUrl)}`)
  }
}

let cmd = {
  description: 'creates a new app',
  help: `Examples:

    $ heroku apps:create
    Creating app... done, stack is cedar-14
    https://floating-dragon-42.heroku.com/ | https://git.heroku.com/floating-dragon-42.git

    # or just
    $ heroku create

    # specify a buildpack
    $ heroku apps:create --buildpack https://github.com/some/buildpack.git

    # specify a name
    $ heroku apps:create example

    # create a staging app
    $ heroku apps:create example-staging --remote staging

    # create an app in the eu region
    $ heroku apps:create --region eu
 `,
  needsAuth: true,
  wantsOrg: true,
  args: [{name: 'app', optional: true, description: 'name of app to create'}],
  flags: [
    {name: 'app', char: 'a', hasValue: true, hidden: true},
    {name: 'addons', hasValue: true, description: 'comma-delimited list of addons to install'},
    {name: 'buildpack', char: 'b', hasValue: true, description: 'buildpack url to use for this app', completion: BuildpackCompletion},
    {name: 'no-remote', char: 'n', description: 'do not create a git remote'},
    {name: 'remote', char: 'r', hasValue: true, description: 'the git remote to create, default "heroku"', completion: RemoteCompletion},
    {name: 'stack', char: 's', hasValue: true, description: 'the stack to create the app on', completion: StackCompletion},
    {name: 'space', hasValue: true, description: 'the private space to create the app in', completion: SpaceCompletion},
    {name: 'region', hasValue: true, description: 'specify region for the app to run in', completion: RegionComletion},
    {name: 'ssh-git', description: 'use SSH git protocol for local git remote'},
    {name: 'kernel', hidden: true, hasValue: true},
    {name: 'locked', hidden: true},
    {name: 'json', description: 'output in json format'},
    // flags.org({name: 'org', hasValue: true}),
    flags.team({name: 'team', hasValue: true})
  ],
  run: cli.command(co.wrap(run))
}

module.exports = [
  Object.assign({topic: 'apps', command: 'create'}, cmd),
  Object.assign({hidden: true, topic: 'create'}, cmd)
]
<commit_msg>fix RegionCompletion require<commit_after>'use strict'

let co = require('co')
let cli = require('heroku-cli-util')
const {flags} = require('cli-engine-heroku')
const {BuildpackCompletion, RegionCompletion, RemoteCompletion, SpaceCompletion, StackCompletion} = require('cli-engine-heroku/lib/completions')

function * run (context, heroku) {
  let git = require('../../git')(context)
  let name = context.flags.app || context.args.app || process.env.HEROKU_APP

  function createApp () {
    let params = {
      name,
      organization: context.org || context.team || context.flags.team,
      region: context.flags.region,
      space: context.flags.space,
      stack: context.flags.stack,
      kernel: context.flags.kernel,
      locked: context.flags.locked
    }

    return heroku.request({
      method: 'POST',
      path: (params.space || params.organization) ? '/organizations/apps' : '/apps',
      body: params
    }).then(app => {
      let status = name ? 'done' : `done, ${cli.color.app(app.name)}`
      if (context.flags.region) status += `, region is ${cli.color.yellow(app.region.name)}`
      if (context.flags.stack) status += `, stack is ${cli.color.yellow(app.stack.name)}`
      cli.action.done(status)
      return app
    })
  }

  let addAddons = co.wrap(function * (app, addons) {
    for (let addon of addons) {
      addon = addon.trim()
      let request = heroku.post(`/apps/${app.name}/addons`, {body: {plan: addon}})
      yield cli.action(`Adding ${cli.color.green(addon)}`, request)
    }
  })

  function addBuildpack (app, buildpack) {
    return cli.action(`Setting buildpack to ${cli.color.cyan(buildpack)}`, heroku.request({
      method: 'PUT',
      path: `/apps/${app.name}/buildpack-installations`,
      headers: {Range: ''},
      body: {updates: [{buildpack: buildpack}]}
    }))
  }

  function createText (name, space) {
    let text = `Creating ${name ? cli.color.app(name) : 'app'}`
    if (space) {
      text += ` in space ${space}`
    }
    return text
  }

  let app = yield cli.action(createText(name, context.flags.space), {success: false}, createApp())

  if (context.flags.addons) yield addAddons(app, context.flags.addons.split(','))
  if (context.flags.buildpack) yield addBuildpack(app, context.flags.buildpack)

  let remoteUrl = context.flags['ssh-git'] ? git.sshGitUrl(app.name) : git.gitUrl(app.name)
  if (git.inGitRepo() && !context.flags['no-remote']) yield git.createRemote(context.flags.remote || 'heroku', remoteUrl)
  if (context.flags.json) {
    cli.styledJSON(app)
  } else {
    cli.log(`${cli.color.cyan(app.web_url)} | ${cli.color.green(remoteUrl)}`)
  }
}

let cmd = {
  description: 'creates a new app',
  help: `Examples:

    $ heroku apps:create
    Creating app... done, stack is cedar-14
    https://floating-dragon-42.heroku.com/ | https://git.heroku.com/floating-dragon-42.git

    # or just
    $ heroku create

    # specify a buildpack
    $ heroku apps:create --buildpack https://github.com/some/buildpack.git

    # specify a name
    $ heroku apps:create example

    # create a staging app
    $ heroku apps:create example-staging --remote staging

    # create an app in the eu region
    $ heroku apps:create --region eu
 `,
  needsAuth: true,
  wantsOrg: true,
  args: [{name: 'app', optional: true, description: 'name of app to create'}],
  flags: [
    {name: 'app', char: 'a', hasValue: true, hidden: true},
    {name: 'addons', hasValue: true, description: 'comma-delimited list of addons to install'},
    {name: 'buildpack', char: 'b', hasValue: true, description: 'buildpack url to use for this app', completion: BuildpackCompletion},
    {name: 'no-remote', char: 'n', description: 'do not create a git remote'},
    {name: 'remote', char: 'r', hasValue: true, description: 'the git remote to create, default "heroku"', completion: RemoteCompletion},
    {name: 'stack', char: 's', hasValue: true, description: 'the stack to create the app on', completion: StackCompletion},
    {name: 'space', hasValue: true, description: 'the private space to create the app in', completion: SpaceCompletion},
    {name: 'region', hasValue: true, description: 'specify region for the app to run in', completion: RegionCompletion},
    {name: 'ssh-git', description: 'use SSH git protocol for local git remote'},
    {name: 'kernel', hidden: true, hasValue: true},
    {name: 'locked', hidden: true},
    {name: 'json', description: 'output in json format'},
    // flags.org({name: 'org', hasValue: true}),
    flags.team({name: 'team', hasValue: true})
  ],
  run: cli.command(co.wrap(run))
}

module.exports = [
  Object.assign({topic: 'apps', command: 'create'}, cmd),
  Object.assign({hidden: true, topic: 'create'}, cmd)
]
<|endoftext|>


<commit_before>import Ember from 'ember';
import ajax from 'ic-ajax';
import config from '../../config/environment';

export default Ember.Route.extend({

	beforeModel: function(transition) {
		return ajax({
			type: 'PUT',
			url: '/' + this.get('session-config.apiNamespace') + '/authentication/signout'
		}).then(function(response) {
		    window.location.href = this.get('session-config.baseURL') + 'authentication';
		}.bind(this), function(reason) {
			this.replaceWith('authentication/signout-failed');
		}).bind(this);
	}

});
<commit_msg>Bug fix.<commit_after>import Ember from 'ember';
import ajax from 'ic-ajax';
import config from '../../config/environment';

export default Ember.Route.extend({

	beforeModel: function(transition) {
		return ajax({
			type: 'PUT',
			url: '/' + this.get('session-config.apiNamespace') + '/authentication/signout'
		}).then(function(response) {
		    window.location.href = this.get('session-config.baseURL') + 'authentication';
		}.bind(this), function(reason) {
			this.replaceWith('authentication/signout-failed');
		}.bind(this));
	}

});
<|endoftext|>


<commit_before>var vscode = require('vscode');
var ux = require('../ux');
var config = require('../config');
var constants = config.getConstants();

var provider = "Microsoft.Batch";
var resourceType = "batchAccounts";

exports.createCommand = function createCommand(state) {
    vscode.commands.registerCommand('createBatchAccount', function () {
        ux.isLoggedIn(state).then(() => {
            vscode.window.showInputBox({
                prompt: constants.promptNewBatchAccount
            }).then(function (newBatchAccountName) {
                if (!newBatchAccountName || newBatchAccountName === "") return;

                state.batchAccountName = newBatchAccountName;
                state.resourceGroupToUse = state.newBatchAccountName + 'Resources';
                ux.getRegionsForResource(state, provider, resourceType)
                	.then((result) => {
                    	state.batchAccountRegions = result.filter(x =>
                        	x.namespace === provider)[0].resourceTypes.filter(x =>
                            	x.resourceType === resourceType)[0].locations;
                        ux.showNewOrExistingResourceGroupMenu(state).then(() => {
                            ux.ifBatchAccountNameIsAvailable(state)
                                .then(() => {
                                    vscode.window.showQuickPick(state.batchAccountRegions)
                                        .then(selectedRegion => {
                                            if (!selectedRegion || selectedRegion === "") return;
                                            state.selectedRegion = selectedRegion;
                                            ux.createBatchAccount(state);
                                        });
                                });
                        });
   	              });
            });
        });
    });
};<commit_msg>Added a catch exception in the Batch Command<commit_after>var vscode = require('vscode');
var ux = require('../ux');
var config = require('../config');
var constants = config.getConstants();

var provider = "Microsoft.Batch";
var resourceType = "batchAccounts";

exports.createCommand = function createCommand(state) {
    vscode.commands.registerCommand('createBatchAccount', function () {
        ux.isLoggedIn(state).then(() => {
            vscode.window.showInputBox({
                prompt: constants.promptNewBatchAccount
            }).then(function (newBatchAccountName) {
                if (!newBatchAccountName || newBatchAccountName === "") return;

                state.batchAccountName = newBatchAccountName;
                state.resourceGroupToUse = state.newBatchAccountName + 'Resources';
                ux.getRegionsForResource(state, provider, resourceType)
                	.then((result) => {
                    	state.batchAccountRegions = result.filter(x =>
                        	x.namespace === provider)[0].resourceTypes.filter(x =>
                            	x.resourceType === resourceType)[0].locations;
                        ux.showNewOrExistingResourceGroupMenu(state).then(() => {
                            ux.ifBatchAccountNameIsAvailable(state)
                                .then(() => {
                                    vscode.window.showQuickPick(state.batchAccountRegions)
                                        .then(selectedRegion => {
                                            if (!selectedRegion || selectedRegion === "") return;
                                            state.selectedRegion = selectedRegion;
                                            ux.createBatchAccount(state);
                                        });
                                });
                        });
   	              });
            })
            .catch(function (message) {
                    vscode.window.showErrorMessage(message);
            });
        });
    });
};<|endoftext|>